dm-core 1.1.0.rc2 → 1.1.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Gemfile +1 -8
  2. data/VERSION +1 -1
  3. data/dm-core.gemspec +24 -15
  4. data/lib/dm-core.rb +9 -48
  5. data/lib/dm-core/adapters.rb +1 -1
  6. data/lib/dm-core/adapters/abstract_adapter.rb +2 -1
  7. data/lib/dm-core/associations/many_to_many.rb +3 -3
  8. data/lib/dm-core/associations/many_to_one.rb +15 -4
  9. data/lib/dm-core/associations/one_to_many.rb +1 -1
  10. data/lib/dm-core/associations/relationship.rb +7 -6
  11. data/lib/dm-core/collection.rb +7 -2
  12. data/lib/dm-core/core_ext/pathname.rb +0 -14
  13. data/lib/dm-core/ext/array.rb +41 -0
  14. data/lib/dm-core/ext/blank.rb +24 -0
  15. data/lib/dm-core/ext/hash.rb +67 -0
  16. data/lib/dm-core/ext/module.rb +49 -0
  17. data/lib/dm-core/ext/object.rb +57 -0
  18. data/lib/dm-core/ext/singleton_class.rb +8 -0
  19. data/lib/dm-core/ext/string.rb +24 -0
  20. data/lib/dm-core/ext/try_dup.rb +12 -0
  21. data/lib/dm-core/model.rb +2 -1
  22. data/lib/dm-core/model/property.rb +3 -2
  23. data/lib/dm-core/property.rb +1 -1
  24. data/lib/dm-core/property/class.rb +1 -1
  25. data/lib/dm-core/property/date.rb +3 -3
  26. data/lib/dm-core/property/date_time.rb +3 -3
  27. data/lib/dm-core/property/time.rb +3 -3
  28. data/lib/dm-core/property/typecast/time.rb +2 -2
  29. data/lib/dm-core/property_set.rb +1 -1
  30. data/lib/dm-core/query.rb +9 -12
  31. data/lib/dm-core/resource.rb +2 -2
  32. data/lib/dm-core/spec/lib/counter_adapter.rb +1 -1
  33. data/lib/dm-core/spec/lib/spec_helper.rb +1 -1
  34. data/lib/dm-core/spec/shared/resource_spec.rb +2 -1
  35. data/lib/dm-core/support/equalizer.rb +1 -1
  36. data/lib/dm-core/support/hook.rb +0 -15
  37. data/lib/dm-core/support/inflections.rb +60 -0
  38. data/lib/dm-core/support/inflector.rb +3 -0
  39. data/lib/dm-core/support/inflector/inflections.rb +211 -0
  40. data/lib/dm-core/support/inflector/methods.rb +151 -0
  41. data/lib/dm-core/support/lazy_array.rb +4 -4
  42. data/lib/dm-core/support/mash.rb +176 -0
  43. data/lib/dm-core/support/subject.rb +1 -1
  44. data/lib/dm-core/version.rb +1 -1
  45. data/spec/public/model/relationship_spec.rb +2 -1
  46. data/spec/public/shared/collection_shared_spec.rb +5 -2
  47. data/spec/public/shared/finder_shared_spec.rb +10 -6
  48. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +1 -1
  49. data/spec/semipublic/query_spec.rb +2 -2
  50. data/spec/semipublic/resource/state/immutable_spec.rb +2 -1
  51. data/spec/semipublic/resource/state_spec.rb +1 -3
  52. data/spec/semipublic/shared/resource_state_shared_spec.rb +2 -1
  53. data/spec/semipublic/shared/subject_shared_spec.rb +1 -1
  54. data/spec/support/core_ext/hash.rb +10 -0
  55. data/spec/support/core_ext/inheritable_attributes.rb +46 -0
  56. data/spec/unit/array_spec.rb +8 -20
  57. data/spec/unit/blank_spec.rb +62 -0
  58. data/spec/unit/data_mapper/ordered_set/hash_spec.rb +1 -1
  59. data/spec/unit/hash_spec.rb +8 -16
  60. data/spec/unit/lazy_array_spec.rb +3 -14
  61. data/spec/unit/mash_spec.rb +312 -0
  62. data/spec/unit/module_spec.rb +15 -15
  63. data/spec/unit/object_spec.rb +9 -9
  64. data/spec/unit/try_dup_spec.rb +8 -8
  65. metadata +32 -39
  66. data/lib/dm-core/core_ext/array.rb +0 -36
  67. data/lib/dm-core/core_ext/hash.rb +0 -30
  68. data/lib/dm-core/core_ext/module.rb +0 -46
  69. data/lib/dm-core/core_ext/object.rb +0 -31
  70. data/lib/dm-core/core_ext/string.rb +0 -22
  71. 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
@@ -8,5 +8,5 @@ describe 'DataMapper::OrderedSet#hash' do
8
8
  let(:ordered_set) { DataMapper::OrderedSet.new([ entry ]) }
9
9
 
10
10
  it { should be_kind_of(Integer) }
11
- it { should == ordered_set.entries.hash }
11
+ it { should == ordered_set.class.hash ^ ordered_set.entries.hash }
12
12
  end
@@ -1,25 +1,17 @@
1
1
  require 'spec_helper'
2
- require 'dm-core/core_ext/hash'
2
+ require 'dm-core/ext/hash'
3
+ require 'dm-core/support/mash'
3
4
 
4
- begin
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
- @hash.only(:not_in_there).should == {}
20
- @hash.only(4).should == {4 => nil}
21
- @hash.only(:one).should == { :one => 'ONE' }
22
- @hash.only(:one, 3).should == { :one => 'ONE', 3 => 'THREE' }
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.to_mash
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, :subject_block, :action_block
9
+ base.class_inheritable_accessor :loaded
10
10
  end
11
11
 
12
12
  def subject(&block)
13
- self.subject_block = block
13
+ let(:subject, &block)
14
14
  end
15
15
 
16
16
  def action(&block)
17
- self.action_block = block
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