extlib 0.9.8 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of extlib might be problematic. Click here for more details.

Files changed (54) hide show
  1. data/History.txt +22 -0
  2. data/LICENSE +1 -1
  3. data/README +0 -0
  4. data/Rakefile +17 -12
  5. data/lib/extlib.rb +1 -1
  6. data/lib/extlib/blank.rb +51 -21
  7. data/lib/extlib/boolean.rb +1 -1
  8. data/lib/extlib/class.rb +12 -12
  9. data/lib/extlib/datetime.rb +20 -2
  10. data/lib/extlib/dictionary.rb +2 -2
  11. data/lib/extlib/hash.rb +57 -34
  12. data/lib/extlib/inflection.rb +0 -1
  13. data/lib/extlib/lazy_array.rb +327 -36
  14. data/lib/extlib/logger.rb +8 -8
  15. data/lib/extlib/mash.rb +45 -45
  16. data/lib/extlib/module.rb +1 -1
  17. data/lib/extlib/nil.rb +1 -1
  18. data/lib/extlib/numeric.rb +1 -1
  19. data/lib/extlib/object.rb +8 -21
  20. data/lib/extlib/object_space.rb +3 -3
  21. data/lib/extlib/pathname.rb +10 -0
  22. data/lib/extlib/pooling.rb +9 -17
  23. data/lib/extlib/rubygems.rb +7 -7
  24. data/lib/extlib/simple_set.rb +35 -8
  25. data/lib/extlib/string.rb +85 -42
  26. data/lib/extlib/struct.rb +10 -1
  27. data/lib/extlib/symbol.rb +11 -7
  28. data/lib/extlib/time.rb +31 -9
  29. data/lib/extlib/version.rb +1 -1
  30. data/lib/extlib/virtual_file.rb +1 -1
  31. data/spec/blank_spec.rb +85 -0
  32. data/spec/class_spec.rb +141 -0
  33. data/spec/datetime_spec.rb +22 -0
  34. data/spec/hash_spec.rb +537 -0
  35. data/spec/hook_spec.rb +1198 -0
  36. data/spec/inflection/plural_spec.rb +564 -0
  37. data/spec/inflection/singular_spec.rb +497 -0
  38. data/spec/inflection_extras_spec.rb +93 -0
  39. data/spec/lazy_array_spec.rb +1869 -0
  40. data/spec/mash_spec.rb +286 -0
  41. data/spec/module_spec.rb +58 -0
  42. data/spec/object_space_spec.rb +9 -0
  43. data/spec/object_spec.rb +114 -0
  44. data/spec/pooling_spec.rb +499 -0
  45. data/spec/simple_set_spec.rb +57 -0
  46. data/spec/spec_helper.rb +7 -0
  47. data/spec/string_spec.rb +220 -0
  48. data/spec/struct_spec.rb +12 -0
  49. data/spec/symbol_spec.rb +8 -0
  50. data/spec/time_spec.rb +22 -0
  51. data/spec/try_dup_spec.rb +45 -0
  52. data/spec/virtual_file_spec.rb +21 -0
  53. metadata +51 -26
  54. data/README.txt +0 -3
@@ -0,0 +1,286 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ class AwesomeHash < Hash
4
+ end
5
+
6
+ describe Mash do
7
+ before(:each) do
8
+ @hash = { "mash" => "indifferent", :hash => "different" }
9
+ @sub = AwesomeHash.new("mash" => "indifferent", :hash => "different")
10
+ end
11
+
12
+ describe "#initialize" do
13
+ it 'converts all keys into strings when param is a Hash' do
14
+ mash = Mash.new(@hash)
15
+
16
+ mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
17
+ end
18
+
19
+ it 'converts all pure Hash values into Mashes if param is a Hash' do
20
+ mash = Mash.new :hash => @hash
21
+
22
+ mash["hash"].should be_an_instance_of(Mash)
23
+ # sanity check
24
+ mash["hash"]["hash"].should == "different"
25
+ end
26
+
27
+ it 'doesn not convert Hash subclass values into Mashes' do
28
+ mash = Mash.new :sub => @sub
29
+ mash["sub"].should be_an_instance_of(AwesomeHash)
30
+ end
31
+
32
+ it 'converts all value items if value is an Array' do
33
+ mash = Mash.new :arry => { :hash => [@hash] }
34
+
35
+ mash["arry"].should be_an_instance_of(Mash)
36
+ # sanity check
37
+ mash["arry"]["hash"].first["hash"].should == "different"
38
+
39
+ end
40
+
41
+ it 'delegates to superclass constructor if param is not a Hash' do
42
+ mash = Mash.new("dash berlin")
43
+
44
+ mash["unexisting key"].should == "dash berlin"
45
+ end
46
+ end # describe "#initialize"
47
+
48
+
49
+
50
+ describe "#update" do
51
+ it 'converts all keys into strings when param is a Hash' do
52
+ mash = Mash.new(@hash)
53
+ mash.update("starry" => "night")
54
+
55
+ mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
56
+ end
57
+
58
+ it 'converts all Hash values into Mashes if param is a Hash' do
59
+ mash = Mash.new :hash => @hash
60
+ mash.update(:hash => { :hash => "is buggy in Ruby 1.8.6" })
61
+
62
+ mash["hash"].should be_an_instance_of(Mash)
63
+ end
64
+ end # describe "#update"
65
+
66
+
67
+
68
+ describe "#[]=" do
69
+ it 'converts key into string' do
70
+ mash = Mash.new(@hash)
71
+ mash[:hash] = { "starry" => "night" }
72
+
73
+ mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
74
+ end
75
+
76
+ it 'converts all Hash value into Mash' do
77
+ mash = Mash.new :hash => @hash
78
+ mash[:hash] = { :hash => "is buggy in Ruby 1.8.6" }
79
+
80
+ mash["hash"].should be_an_instance_of(Mash)
81
+ end
82
+ end # describe "#[]="
83
+
84
+
85
+
86
+ describe "#key?" do
87
+ before(:each) do
88
+ @mash = Mash.new(@hash)
89
+ end
90
+
91
+ it 'converts key before lookup' do
92
+ @mash.key?("mash").should be(true)
93
+ @mash.key?(:mash).should be(true)
94
+
95
+ @mash.key?("hash").should be(true)
96
+ @mash.key?(:hash).should be(true)
97
+
98
+ @mash.key?(:rainclouds).should be(false)
99
+ @mash.key?("rainclouds").should be(false)
100
+ end
101
+
102
+ it 'is aliased as include?' do
103
+ @mash.include?("mash").should be(true)
104
+ @mash.include?(:mash).should be(true)
105
+
106
+ @mash.include?("hash").should be(true)
107
+ @mash.include?(:hash).should be(true)
108
+
109
+ @mash.include?(:rainclouds).should be(false)
110
+ @mash.include?("rainclouds").should be(false)
111
+ end
112
+
113
+ it 'is aliased as member?' do
114
+ @mash.member?("mash").should be(true)
115
+ @mash.member?(:mash).should be(true)
116
+
117
+ @mash.member?("hash").should be(true)
118
+ @mash.member?(:hash).should be(true)
119
+
120
+ @mash.member?(:rainclouds).should be(false)
121
+ @mash.member?("rainclouds").should be(false)
122
+ end
123
+ end # describe "#key?"
124
+
125
+
126
+ describe "#dup" do
127
+ it 'returns instance of Mash' do
128
+ Mash.new(@hash).dup.should be_an_instance_of(Mash)
129
+ end
130
+
131
+ it 'preserves keys' do
132
+ mash = Mash.new(@hash)
133
+ dup = mash.dup
134
+
135
+ mash.keys.sort.should == dup.keys.sort
136
+ end
137
+
138
+ it 'preserves value' do
139
+ mash = Mash.new(@hash)
140
+ dup = mash.dup
141
+
142
+ mash.values.sort.should == dup.values.sort
143
+ end
144
+ end
145
+
146
+
147
+
148
+ describe "#to_hash" do
149
+ it 'returns instance of Mash' do
150
+ Mash.new(@hash).to_hash.should be_an_instance_of(Hash)
151
+ end
152
+
153
+ it 'preserves keys' do
154
+ mash = Mash.new(@hash)
155
+ converted = mash.to_hash
156
+
157
+ mash.keys.sort.should == converted.keys.sort
158
+ end
159
+
160
+ it 'preserves value' do
161
+ mash = Mash.new(@hash)
162
+ converted = mash.to_hash
163
+
164
+ mash.values.sort.should == converted.values.sort
165
+ end
166
+ end
167
+
168
+
169
+
170
+ describe "#delete" do
171
+ it 'converts Symbol key into String before deleting' do
172
+ mash = Mash.new(@hash)
173
+
174
+ mash.delete(:hash)
175
+ mash.key?("hash").should be(false)
176
+ end
177
+
178
+ it 'works with String keys as well' do
179
+ mash = Mash.new(@hash)
180
+
181
+ mash.delete("mash")
182
+ mash.key?("mash").should be(false)
183
+ end
184
+ end
185
+
186
+
187
+
188
+ describe "#except" do
189
+ it "converts Symbol key into String before calling super" do
190
+ mash = Mash.new(@hash)
191
+
192
+ hashless_mash = mash.except(:hash)
193
+ hashless_mash.key?("hash").should be(false)
194
+ end
195
+
196
+ it "works with String keys as well" do
197
+ mash = Mash.new(@hash)
198
+
199
+ mashless_mash = mash.except("mash")
200
+ mashless_mash.key?("mash").should be(false)
201
+ end
202
+
203
+ it "works with multiple keys" do
204
+ mash = Mash.new(@hash)
205
+
206
+ mashless = mash.except("hash", :mash)
207
+ mashless.key?(:hash).should be(false)
208
+ mashless.key?("mash").should be(false)
209
+ end
210
+
211
+ it "should return a mash" do
212
+ mash = Mash.new(@hash)
213
+
214
+ hashless_mash = mash.except(:hash)
215
+ hashless_mash.class.should be(Mash)
216
+ end
217
+ end
218
+
219
+
220
+
221
+ describe "#merge" do
222
+ before(:each) do
223
+ @mash = Mash.new(@hash).merge(:no => "in between")
224
+ end
225
+
226
+ it 'returns instance of Mash' do
227
+ @mash.should be_an_instance_of(Mash)
228
+ end
229
+
230
+ it 'merges in give Hash' do
231
+ @mash["no"].should == "in between"
232
+ end
233
+ end
234
+
235
+
236
+
237
+ describe "#fetch" do
238
+ before(:each) do
239
+ @mash = Mash.new(@hash).merge(:no => "in between")
240
+ end
241
+
242
+ it 'converts key before fetching' do
243
+ @mash.fetch("no").should == "in between"
244
+ end
245
+
246
+ it 'returns alternative value if key lookup fails' do
247
+ @mash.fetch("flying", "screwdriver").should == "screwdriver"
248
+ end
249
+ end
250
+
251
+
252
+ describe "#default" do
253
+ before(:each) do
254
+ @mash = Mash.new(:yet_another_technical_revolution)
255
+ end
256
+
257
+ it 'returns default value unless key exists in mash' do
258
+ @mash.default("peak oil is now behind, baby").should == :yet_another_technical_revolution
259
+ end
260
+
261
+ it 'returns existing value if key is Symbol and exists in mash' do
262
+ @mash.update(:no => "in between")
263
+ @mash.default(:no).should == "in between"
264
+ end
265
+ end
266
+
267
+
268
+ describe "#values_at" do
269
+ before(:each) do
270
+ @mash = Mash.new(@hash).merge(:no => "in between")
271
+ end
272
+
273
+ it 'is indifferent to whether keys are strings or symbols' do
274
+ @mash.values_at("hash", :mash, :no).should == ["different", "indifferent", "in between"]
275
+ end
276
+ end
277
+
278
+
279
+ describe "#stringify_keys!" do
280
+ it 'returns the mash itself' do
281
+ mash = Mash.new(@hash)
282
+
283
+ mash.stringify_keys!.object_id.should == mash.object_id
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe Module do
4
+
5
+ before(:all) do
6
+ module Foo
7
+ module ModBar
8
+ module Noo
9
+ module Too
10
+ end
11
+ end
12
+ end
13
+
14
+ class Zed
15
+ end
16
+ end
17
+
18
+ class Baz
19
+ end
20
+
21
+ class Bar
22
+ end
23
+ end
24
+
25
+ it "should raise NameError for a missing constant" do
26
+ lambda { Foo.find_const('Moo') }.should raise_error(NameError)
27
+ lambda { Object.find_const('MissingConstant') }.should raise_error(NameError)
28
+ end
29
+
30
+ it "should be able to get a recursive constant" do
31
+ Object.find_const('Foo::ModBar').should == Foo::ModBar
32
+ end
33
+
34
+ it "should ignore get Constants from the Kernel namespace correctly" do
35
+ Object.find_const('::Foo::ModBar').should == ::Foo::ModBar
36
+ end
37
+
38
+ it "should find relative constants" do
39
+ Foo.find_const('ModBar').should == Foo::ModBar
40
+ Foo.find_const('Baz').should == Baz
41
+ end
42
+
43
+ it "should find sibling constants" do
44
+ Foo::ModBar.find_const("Zed").should == Foo::Zed
45
+ end
46
+
47
+ it "should find nested constants on nested constants" do
48
+ Foo::ModBar.find_const('Noo::Too')
49
+ end
50
+
51
+ it "should be able to deal with constants being added and removed" do
52
+ Object.find_const('Bar') # First we load Bar with find_const
53
+ Object.module_eval { remove_const('Bar') } # Now we delete it
54
+ module Bar; end; # Now we redefine it
55
+ Object.find_const('Bar').should == Bar
56
+ end
57
+
58
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe ObjectSpace, "#classes" do
4
+ it 'returns only classes, nothing else' do
5
+ ObjectSpace.classes.each do |klass|
6
+ Class.should === klass
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,114 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+ require "set"
3
+
4
+ module HactiveSupport
5
+ class MemoizeConsideredUseless
6
+ end
7
+ end
8
+
9
+ class SymbolicDuck
10
+ def quack
11
+ end
12
+ end
13
+
14
+ class ClassyDuck
15
+ end
16
+
17
+ module Foo
18
+ class Bar
19
+ end
20
+ end
21
+
22
+ class Oi
23
+ attr_accessor :foo
24
+ end
25
+
26
+ describe Object do
27
+
28
+ describe "#full_const_get" do
29
+ it 'returns constant by FQ name in receiver namespace' do
30
+ Object.full_const_get("Extlib").should == Extlib
31
+ Object.full_const_get("Extlib::SimpleSet").should == Extlib::SimpleSet
32
+ end
33
+ end
34
+
35
+ describe "#full_const_set" do
36
+ it 'sets constant value by FQ name in receiver namespace' do
37
+ Object.full_const_set("HactiveSupport::MCU", HactiveSupport::MemoizeConsideredUseless)
38
+
39
+ Object.full_const_get("HactiveSupport::MCU").should == HactiveSupport::MemoizeConsideredUseless
40
+ HactiveSupport.full_const_get("MCU").should == HactiveSupport::MemoizeConsideredUseless
41
+ end
42
+ end
43
+
44
+ describe "#make_module" do
45
+ it 'creates a module from string FQ name' do
46
+ Object.make_module("Milano")
47
+ Object.make_module("Norway::Oslo")
48
+
49
+ Object.const_defined?("Milano").should == true
50
+ Norway.const_defined?("Oslo").should == true
51
+ end
52
+
53
+ it "handles the case where we already have a class in the heirarchy" do
54
+ Object.make_module("Foo::Bar::Baz")
55
+ Object.const_defined?("Foo").should == true
56
+ Foo.const_defined?("Bar").should == true
57
+ Foo::Bar.const_defined?("Baz").should == true
58
+ Foo::Bar::Baz.should be_kind_of(Module)
59
+ end
60
+ end
61
+
62
+
63
+ describe "#quacks_like?" do
64
+ it 'returns true if duck is a Symbol and receiver responds to it' do
65
+ SymbolicDuck.new.quacks_like?(:quack).should be(true)
66
+ end
67
+
68
+ it 'returns false if duck is a Symbol and receiver DOES NOT respond to it' do
69
+ SymbolicDuck.new.quacks_like?(:wtf).should be(false)
70
+ end
71
+
72
+ it 'returns true if duck is a class and receiver is its instance' do
73
+ receiver = ClassyDuck.new
74
+ receiver.quacks_like?(ClassyDuck).should be(true)
75
+ end
76
+
77
+ it 'returns false if duck is a class and receiver IS NOT its instance' do
78
+ receiver = ClassyDuck.new
79
+ receiver.quacks_like?(SymbolicDuck).should be(false)
80
+ end
81
+
82
+ it 'returns true if duck is an array and at least one of its members quacks like this duck' do
83
+ receiver = ClassyDuck.new
84
+ ary = [ClassyDuck, SymbolicDuck]
85
+
86
+ receiver.quacks_like?(ary).should be(true)
87
+ end
88
+
89
+ it 'returns false if duck is an array and none of its members quacks like this duck' do
90
+ receiver = ClassyDuck.new
91
+ ary = [SymbolicDuck.new, SymbolicDuck]
92
+
93
+ receiver.quacks_like?(ary).should be(false)
94
+ end
95
+ end
96
+
97
+ describe "#in?" do
98
+ it 'returns true if object is included in collection' do
99
+ @ary = [1, 2, 3]
100
+ @set = Set.new([2, 3, 5])
101
+
102
+ 1.in?(@ary).should be(true)
103
+ 2.in?(@ary).should be(true)
104
+ 3.in?(@ary).should be(true)
105
+ 4.in?(@ary).should be(false)
106
+
107
+ 1.in?(@set).should be(false)
108
+ 2.in?(@set).should be(true)
109
+ 3.in?(@set).should be(true)
110
+ 4.in?(@set).should be(false)
111
+ 5.in?(@set).should be(true)
112
+ end
113
+ end
114
+ end