dm-core 1.1.0.rc2 → 1.1.0.rc3
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.
- data/Gemfile +1 -8
- data/VERSION +1 -1
- data/dm-core.gemspec +24 -15
- data/lib/dm-core.rb +9 -48
- data/lib/dm-core/adapters.rb +1 -1
- data/lib/dm-core/adapters/abstract_adapter.rb +2 -1
- data/lib/dm-core/associations/many_to_many.rb +3 -3
- data/lib/dm-core/associations/many_to_one.rb +15 -4
- data/lib/dm-core/associations/one_to_many.rb +1 -1
- data/lib/dm-core/associations/relationship.rb +7 -6
- data/lib/dm-core/collection.rb +7 -2
- data/lib/dm-core/core_ext/pathname.rb +0 -14
- data/lib/dm-core/ext/array.rb +41 -0
- data/lib/dm-core/ext/blank.rb +24 -0
- data/lib/dm-core/ext/hash.rb +67 -0
- data/lib/dm-core/ext/module.rb +49 -0
- data/lib/dm-core/ext/object.rb +57 -0
- data/lib/dm-core/ext/singleton_class.rb +8 -0
- data/lib/dm-core/ext/string.rb +24 -0
- data/lib/dm-core/ext/try_dup.rb +12 -0
- data/lib/dm-core/model.rb +2 -1
- data/lib/dm-core/model/property.rb +3 -2
- data/lib/dm-core/property.rb +1 -1
- data/lib/dm-core/property/class.rb +1 -1
- data/lib/dm-core/property/date.rb +3 -3
- data/lib/dm-core/property/date_time.rb +3 -3
- data/lib/dm-core/property/time.rb +3 -3
- data/lib/dm-core/property/typecast/time.rb +2 -2
- data/lib/dm-core/property_set.rb +1 -1
- data/lib/dm-core/query.rb +9 -12
- data/lib/dm-core/resource.rb +2 -2
- data/lib/dm-core/spec/lib/counter_adapter.rb +1 -1
- data/lib/dm-core/spec/lib/spec_helper.rb +1 -1
- data/lib/dm-core/spec/shared/resource_spec.rb +2 -1
- data/lib/dm-core/support/equalizer.rb +1 -1
- data/lib/dm-core/support/hook.rb +0 -15
- data/lib/dm-core/support/inflections.rb +60 -0
- data/lib/dm-core/support/inflector.rb +3 -0
- data/lib/dm-core/support/inflector/inflections.rb +211 -0
- data/lib/dm-core/support/inflector/methods.rb +151 -0
- data/lib/dm-core/support/lazy_array.rb +4 -4
- data/lib/dm-core/support/mash.rb +176 -0
- data/lib/dm-core/support/subject.rb +1 -1
- data/lib/dm-core/version.rb +1 -1
- data/spec/public/model/relationship_spec.rb +2 -1
- data/spec/public/shared/collection_shared_spec.rb +5 -2
- data/spec/public/shared/finder_shared_spec.rb +10 -6
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +1 -1
- data/spec/semipublic/query_spec.rb +2 -2
- data/spec/semipublic/resource/state/immutable_spec.rb +2 -1
- data/spec/semipublic/resource/state_spec.rb +1 -3
- data/spec/semipublic/shared/resource_state_shared_spec.rb +2 -1
- data/spec/semipublic/shared/subject_shared_spec.rb +1 -1
- data/spec/support/core_ext/hash.rb +10 -0
- data/spec/support/core_ext/inheritable_attributes.rb +46 -0
- data/spec/unit/array_spec.rb +8 -20
- data/spec/unit/blank_spec.rb +62 -0
- data/spec/unit/data_mapper/ordered_set/hash_spec.rb +1 -1
- data/spec/unit/hash_spec.rb +8 -16
- data/spec/unit/lazy_array_spec.rb +3 -14
- data/spec/unit/mash_spec.rb +312 -0
- data/spec/unit/module_spec.rb +15 -15
- data/spec/unit/object_spec.rb +9 -9
- data/spec/unit/try_dup_spec.rb +8 -8
- metadata +32 -39
- data/lib/dm-core/core_ext/array.rb +0 -36
- data/lib/dm-core/core_ext/hash.rb +0 -30
- data/lib/dm-core/core_ext/module.rb +0 -46
- data/lib/dm-core/core_ext/object.rb +0 -31
- data/lib/dm-core/core_ext/string.rb +0 -22
- data/lib/dm-core/core_ext/try_dup.rb +0 -44
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm-core/ext/blank'
|
3
|
+
|
4
|
+
describe 'DataMapper::Ext.blank?', Object do
|
5
|
+
it 'should be blank if it is nil' do
|
6
|
+
object = Object.new
|
7
|
+
class << object
|
8
|
+
def nil?; true end
|
9
|
+
end
|
10
|
+
DataMapper::Ext.blank?(object).should == true
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be blank if it is empty' do
|
14
|
+
DataMapper::Ext.blank?({}).should == true
|
15
|
+
DataMapper::Ext.blank?([]).should == true
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should not be blank if not nil or empty' do
|
19
|
+
DataMapper::Ext.blank?(Object.new).should == false
|
20
|
+
DataMapper::Ext.blank?([nil]).should == false
|
21
|
+
DataMapper::Ext.blank?({ nil => 0 }).should == false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'DataMapper::Ext.blank?', Numeric do
|
26
|
+
it 'should never be blank' do
|
27
|
+
DataMapper::Ext.blank?(1).should == false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'DataMapper::Ext.blank?', NilClass do
|
32
|
+
it 'should always be blank' do
|
33
|
+
DataMapper::Ext.blank?(nil).should == true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'DataMapper::Ext.blank?', TrueClass do
|
38
|
+
it 'should never be blank' do
|
39
|
+
DataMapper::Ext.blank?(true).should == false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'DataMapper::Ext.blank?', FalseClass do
|
44
|
+
it 'should always be blank' do
|
45
|
+
DataMapper::Ext.blank?(false).should == true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'DataMapper::Ext.blank?', String do
|
50
|
+
it 'should be blank if empty' do
|
51
|
+
DataMapper::Ext.blank?('').should == true
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should be blank if it only contains whitespace' do
|
55
|
+
DataMapper::Ext.blank?(' ').should == true
|
56
|
+
DataMapper::Ext.blank?(" \r \n \t ").should == true
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should not be blank if it contains non-whitespace' do
|
60
|
+
DataMapper::Ext.blank?(' a ').should == false
|
61
|
+
end
|
62
|
+
end
|
data/spec/unit/hash_spec.rb
CHANGED
@@ -1,25 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'dm-core/
|
2
|
+
require 'dm-core/ext/hash'
|
3
|
+
require 'dm-core/support/mash'
|
3
4
|
|
4
|
-
|
5
|
-
require 'active_support/hash_with_indifferent_access'
|
6
|
-
unless defined?(Mash)
|
7
|
-
Mash = ActiveSupport::HashWithIndifferentAccess
|
8
|
-
end
|
9
|
-
rescue LoadError
|
10
|
-
require 'extlib/mash'
|
11
|
-
end
|
12
|
-
|
13
|
-
describe Hash, "only" do
|
5
|
+
describe DataMapper::Ext::Hash, "only" do
|
14
6
|
before do
|
15
7
|
@hash = { :one => 'ONE', 'two' => 'TWO', 3 => 'THREE', 4 => nil }
|
16
8
|
end
|
17
9
|
|
18
10
|
it "should return a hash with only the given key(s)" do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
11
|
+
DataMapper::Ext::Hash.only(@hash, :not_in_there).should == {}
|
12
|
+
DataMapper::Ext::Hash.only(@hash, 4).should == {4 => nil}
|
13
|
+
DataMapper::Ext::Hash.only(@hash, :one).should == { :one => 'ONE' }
|
14
|
+
DataMapper::Ext::Hash.only(@hash, :one, 3).should == { :one => 'ONE', 3 => 'THREE' }
|
23
15
|
end
|
24
16
|
end
|
25
17
|
|
@@ -30,7 +22,7 @@ describe Hash, 'to_mash' do
|
|
30
22
|
end
|
31
23
|
|
32
24
|
it "copies default Hash value to Mash" do
|
33
|
-
@mash = @hash
|
25
|
+
@mash = DataMapper::Ext::Hash.to_mash(@hash)
|
34
26
|
@mash[:merb].should == 10
|
35
27
|
end
|
36
28
|
end
|
@@ -6,15 +6,15 @@ require 'dm-core/support/lazy_array'
|
|
6
6
|
module LazyArraySpec
|
7
7
|
module GroupMethods
|
8
8
|
def self.extended(base)
|
9
|
-
base.class_inheritable_accessor :loaded
|
9
|
+
base.class_inheritable_accessor :loaded
|
10
10
|
end
|
11
11
|
|
12
12
|
def subject(&block)
|
13
|
-
|
13
|
+
let(:subject, &block)
|
14
14
|
end
|
15
15
|
|
16
16
|
def action(&block)
|
17
|
-
|
17
|
+
let(:action, &block)
|
18
18
|
end
|
19
19
|
|
20
20
|
def should_respond_to(method)
|
@@ -111,22 +111,11 @@ module LazyArraySpec
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
115
|
-
module Methods
|
116
|
-
def subject
|
117
|
-
@subject ||= instance_eval(&self.class.subject_block)
|
118
|
-
end
|
119
|
-
|
120
|
-
def action
|
121
|
-
instance_eval(&self.class.action_block)
|
122
|
-
end
|
123
|
-
end
|
124
114
|
end
|
125
115
|
|
126
116
|
[ false, true ].each do |loaded|
|
127
117
|
describe LazyArray do
|
128
118
|
extend LazyArraySpec::GroupMethods
|
129
|
-
include LazyArraySpec::Methods
|
130
119
|
|
131
120
|
self.loaded = loaded
|
132
121
|
|
@@ -0,0 +1,312 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dm-core/support/mash'
|
3
|
+
|
4
|
+
class AwesomeHash < Hash
|
5
|
+
end
|
6
|
+
|
7
|
+
describe DataMapper::Mash do
|
8
|
+
before(:each) do
|
9
|
+
@hash = { "mash" => "indifferent", :hash => "different" }
|
10
|
+
@sub = AwesomeHash.new("mash" => "indifferent", :hash => "different")
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#initialize" do
|
14
|
+
it 'converts all keys into strings when param is a Hash' do
|
15
|
+
mash = DataMapper::Mash.new(@hash)
|
16
|
+
|
17
|
+
mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'converts all pure Hash values into Mashes if param is a Hash' do
|
21
|
+
mash = DataMapper::Mash.new :hash => @hash
|
22
|
+
|
23
|
+
mash["hash"].should be_an_instance_of(DataMapper::Mash)
|
24
|
+
# sanity check
|
25
|
+
mash["hash"]["hash"].should == "different"
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'doesn not convert Hash subclass values into Mashes' do
|
29
|
+
mash = DataMapper::Mash.new :sub => @sub
|
30
|
+
mash["sub"].should be_an_instance_of(AwesomeHash)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'converts all value items if value is an Array' do
|
34
|
+
mash = DataMapper::Mash.new :arry => { :hash => [@hash] }
|
35
|
+
|
36
|
+
mash["arry"].should be_an_instance_of(DataMapper::Mash)
|
37
|
+
# sanity check
|
38
|
+
mash["arry"]["hash"].first["hash"].should == "different"
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'delegates to superclass constructor if param is not a Hash' do
|
43
|
+
mash = DataMapper::Mash.new("dash berlin")
|
44
|
+
|
45
|
+
mash["unexisting key"].should == "dash berlin"
|
46
|
+
end
|
47
|
+
end # describe "#initialize"
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
describe "#update" do
|
52
|
+
it 'converts all keys into strings when param is a Hash' do
|
53
|
+
mash = DataMapper::Mash.new(@hash)
|
54
|
+
mash.update("starry" => "night")
|
55
|
+
|
56
|
+
mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'converts all Hash values into Mashes if param is a Hash' do
|
60
|
+
mash = DataMapper::Mash.new :hash => @hash
|
61
|
+
mash.update(:hash => { :hash => "is buggy in Ruby 1.8.6" })
|
62
|
+
|
63
|
+
mash["hash"].should be_an_instance_of(DataMapper::Mash)
|
64
|
+
end
|
65
|
+
end # describe "#update"
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
describe "#[]=" do
|
70
|
+
it 'converts key into string' do
|
71
|
+
mash = DataMapper::Mash.new(@hash)
|
72
|
+
mash[:hash] = { "starry" => "night" }
|
73
|
+
|
74
|
+
mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'converts all Hash value into Mash' do
|
78
|
+
mash = DataMapper::Mash.new :hash => @hash
|
79
|
+
mash[:hash] = { :hash => "is buggy in Ruby 1.8.6" }
|
80
|
+
|
81
|
+
mash["hash"].should be_an_instance_of(DataMapper::Mash)
|
82
|
+
end
|
83
|
+
end # describe "#[]="
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
describe "#key?" do
|
88
|
+
before(:each) do
|
89
|
+
@mash = DataMapper::Mash.new(@hash)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'converts key before lookup' do
|
93
|
+
@mash.key?("mash").should be(true)
|
94
|
+
@mash.key?(:mash).should be(true)
|
95
|
+
|
96
|
+
@mash.key?("hash").should be(true)
|
97
|
+
@mash.key?(:hash).should be(true)
|
98
|
+
|
99
|
+
@mash.key?(:rainclouds).should be(false)
|
100
|
+
@mash.key?("rainclouds").should be(false)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'is aliased as include?' do
|
104
|
+
@mash.include?("mash").should be(true)
|
105
|
+
@mash.include?(:mash).should be(true)
|
106
|
+
|
107
|
+
@mash.include?("hash").should be(true)
|
108
|
+
@mash.include?(:hash).should be(true)
|
109
|
+
|
110
|
+
@mash.include?(:rainclouds).should be(false)
|
111
|
+
@mash.include?("rainclouds").should be(false)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'is aliased as member?' do
|
115
|
+
@mash.member?("mash").should be(true)
|
116
|
+
@mash.member?(:mash).should be(true)
|
117
|
+
|
118
|
+
@mash.member?("hash").should be(true)
|
119
|
+
@mash.member?(:hash).should be(true)
|
120
|
+
|
121
|
+
@mash.member?(:rainclouds).should be(false)
|
122
|
+
@mash.member?("rainclouds").should be(false)
|
123
|
+
end
|
124
|
+
end # describe "#key?"
|
125
|
+
|
126
|
+
|
127
|
+
describe "#dup" do
|
128
|
+
it 'returns instance of Mash' do
|
129
|
+
DataMapper::Mash.new(@hash).dup.should be_an_instance_of(DataMapper::Mash)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'preserves keys' do
|
133
|
+
mash = DataMapper::Mash.new(@hash)
|
134
|
+
dup = mash.dup
|
135
|
+
|
136
|
+
mash.keys.sort.should == dup.keys.sort
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'preserves value' do
|
140
|
+
mash = DataMapper::Mash.new(@hash)
|
141
|
+
dup = mash.dup
|
142
|
+
|
143
|
+
mash.values.sort.should == dup.values.sort
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
describe "#to_hash" do
|
150
|
+
it 'returns instance of Mash' do
|
151
|
+
DataMapper::Mash.new(@hash).to_hash.should be_an_instance_of(Hash)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'preserves keys' do
|
155
|
+
mash = DataMapper::Mash.new(@hash)
|
156
|
+
converted = mash.to_hash
|
157
|
+
|
158
|
+
mash.keys.sort.should == converted.keys.sort
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'preserves value' do
|
162
|
+
mash = DataMapper::Mash.new(@hash)
|
163
|
+
converted = mash.to_hash
|
164
|
+
|
165
|
+
mash.values.sort.should == converted.values.sort
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
describe "#symbolize_keys" do
|
172
|
+
it 'returns instance of Mash' do
|
173
|
+
DataMapper::Mash.new(@hash).symbolize_keys.should be_an_instance_of(Hash)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'converts keys to symbols' do
|
177
|
+
mash = DataMapper::Mash.new(@hash)
|
178
|
+
converted = mash.symbolize_keys
|
179
|
+
|
180
|
+
converted_keys = converted.keys.sort{|k1, k2| k1.to_s <=> k2.to_s}
|
181
|
+
orig_keys = mash.keys.map{|k| k.to_sym}.sort{|i1, i2| i1.to_s <=> i2.to_s}
|
182
|
+
|
183
|
+
converted_keys.should == orig_keys
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'preserves value' do
|
187
|
+
mash = DataMapper::Mash.new(@hash)
|
188
|
+
converted = mash.symbolize_keys
|
189
|
+
|
190
|
+
mash.values.sort.should == converted.values.sort
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
describe "#delete" do
|
197
|
+
it 'converts Symbol key into String before deleting' do
|
198
|
+
mash = DataMapper::Mash.new(@hash)
|
199
|
+
|
200
|
+
mash.delete(:hash)
|
201
|
+
mash.key?("hash").should be(false)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'works with String keys as well' do
|
205
|
+
mash = DataMapper::Mash.new(@hash)
|
206
|
+
|
207
|
+
mash.delete("mash")
|
208
|
+
mash.key?("mash").should be(false)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
describe "#except" do
|
215
|
+
it "converts Symbol key into String before calling super" do
|
216
|
+
mash = DataMapper::Mash.new(@hash)
|
217
|
+
|
218
|
+
hashless_mash = mash.except(:hash)
|
219
|
+
hashless_mash.key?("hash").should be(false)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "works with String keys as well" do
|
223
|
+
mash = DataMapper::Mash.new(@hash)
|
224
|
+
|
225
|
+
mashless_mash = mash.except("mash")
|
226
|
+
mashless_mash.key?("mash").should be(false)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "works with multiple keys" do
|
230
|
+
mash = DataMapper::Mash.new(@hash)
|
231
|
+
|
232
|
+
mashless = mash.except("hash", :mash)
|
233
|
+
mashless.key?(:hash).should be(false)
|
234
|
+
mashless.key?("mash").should be(false)
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should return a mash" do
|
238
|
+
mash = DataMapper::Mash.new(@hash)
|
239
|
+
|
240
|
+
hashless_mash = mash.except(:hash)
|
241
|
+
hashless_mash.class.should be(DataMapper::Mash)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
describe "#merge" do
|
248
|
+
before(:each) do
|
249
|
+
@mash = DataMapper::Mash.new(@hash).merge(:no => "in between")
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'returns instance of Mash' do
|
253
|
+
@mash.should be_an_instance_of(DataMapper::Mash)
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'merges in give Hash' do
|
257
|
+
@mash["no"].should == "in between"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
describe "#fetch" do
|
264
|
+
before(:each) do
|
265
|
+
@mash = DataMapper::Mash.new(@hash).merge(:no => "in between")
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'converts key before fetching' do
|
269
|
+
@mash.fetch("no").should == "in between"
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'returns alternative value if key lookup fails' do
|
273
|
+
@mash.fetch("flying", "screwdriver").should == "screwdriver"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
describe "#default" do
|
279
|
+
before(:each) do
|
280
|
+
@mash = DataMapper::Mash.new(:yet_another_technical_revolution)
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'returns default value unless key exists in mash' do
|
284
|
+
@mash.default("peak oil is now behind, baby").should == :yet_another_technical_revolution
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'returns existing value if key is Symbol and exists in mash' do
|
288
|
+
@mash.update(:no => "in between")
|
289
|
+
@mash.default(:no).should == "in between"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
describe "#values_at" do
|
295
|
+
before(:each) do
|
296
|
+
@mash = DataMapper::Mash.new(@hash).merge(:no => "in between")
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'is indifferent to whether keys are strings or symbols' do
|
300
|
+
@mash.values_at("hash", :mash, :no).should == ["different", "indifferent", "in between"]
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
|
305
|
+
describe "#stringify_keys!" do
|
306
|
+
it 'returns the mash itself' do
|
307
|
+
mash = DataMapper::Mash.new(@hash)
|
308
|
+
|
309
|
+
mash.stringify_keys!.object_id.should == mash.object_id
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|