robsharp-extlib 0.9.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.autotest +21 -0
  2. data/.document +5 -0
  3. data/.gitignore +22 -0
  4. data/LICENSE +47 -0
  5. data/README.rdoc +17 -0
  6. data/Rakefile +28 -0
  7. data/VERSION +1 -0
  8. data/extlib.gemspec +147 -0
  9. data/lib/extlib.rb +50 -0
  10. data/lib/extlib/array.rb +38 -0
  11. data/lib/extlib/assertions.rb +8 -0
  12. data/lib/extlib/blank.rb +89 -0
  13. data/lib/extlib/boolean.rb +11 -0
  14. data/lib/extlib/byte_array.rb +6 -0
  15. data/lib/extlib/class.rb +179 -0
  16. data/lib/extlib/datetime.rb +29 -0
  17. data/lib/extlib/dictionary.rb +433 -0
  18. data/lib/extlib/hash.rb +450 -0
  19. data/lib/extlib/hook.rb +407 -0
  20. data/lib/extlib/inflection.rb +442 -0
  21. data/lib/extlib/lazy_array.rb +453 -0
  22. data/lib/extlib/lazy_module.rb +18 -0
  23. data/lib/extlib/logger.rb +198 -0
  24. data/lib/extlib/mash.rb +157 -0
  25. data/lib/extlib/module.rb +51 -0
  26. data/lib/extlib/nil.rb +5 -0
  27. data/lib/extlib/numeric.rb +5 -0
  28. data/lib/extlib/object.rb +178 -0
  29. data/lib/extlib/object_space.rb +13 -0
  30. data/lib/extlib/pathname.rb +20 -0
  31. data/lib/extlib/pooling.rb +235 -0
  32. data/lib/extlib/rubygems.rb +38 -0
  33. data/lib/extlib/simple_set.rb +66 -0
  34. data/lib/extlib/string.rb +176 -0
  35. data/lib/extlib/struct.rb +17 -0
  36. data/lib/extlib/symbol.rb +21 -0
  37. data/lib/extlib/time.rb +44 -0
  38. data/lib/extlib/try_dup.rb +44 -0
  39. data/lib/extlib/virtual_file.rb +10 -0
  40. data/spec/array_spec.rb +40 -0
  41. data/spec/blank_spec.rb +86 -0
  42. data/spec/byte_array_spec.rb +8 -0
  43. data/spec/class_spec.rb +158 -0
  44. data/spec/datetime_spec.rb +22 -0
  45. data/spec/hash_spec.rb +536 -0
  46. data/spec/hook_spec.rb +1235 -0
  47. data/spec/inflection/plural_spec.rb +565 -0
  48. data/spec/inflection/singular_spec.rb +498 -0
  49. data/spec/inflection_extras_spec.rb +111 -0
  50. data/spec/lazy_array_spec.rb +1961 -0
  51. data/spec/lazy_module_spec.rb +38 -0
  52. data/spec/mash_spec.rb +312 -0
  53. data/spec/module_spec.rb +71 -0
  54. data/spec/object_space_spec.rb +10 -0
  55. data/spec/object_spec.rb +114 -0
  56. data/spec/pooling_spec.rb +511 -0
  57. data/spec/rcov.opts +6 -0
  58. data/spec/simple_set_spec.rb +58 -0
  59. data/spec/spec.opts +4 -0
  60. data/spec/spec_helper.rb +7 -0
  61. data/spec/string_spec.rb +222 -0
  62. data/spec/struct_spec.rb +13 -0
  63. data/spec/symbol_spec.rb +9 -0
  64. data/spec/time_spec.rb +31 -0
  65. data/spec/try_call_spec.rb +74 -0
  66. data/spec/try_dup_spec.rb +46 -0
  67. data/spec/virtual_file_spec.rb +22 -0
  68. data/tasks/ci.rake +1 -0
  69. data/tasks/metrics.rake +36 -0
  70. data/tasks/spec.rake +25 -0
  71. data/tasks/yard.rake +9 -0
  72. data/tasks/yardstick.rake +19 -0
  73. metadata +198 -0
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'extlib/lazy_module'
3
+
4
+ describe LazyModule do
5
+ describe "instantiated with a block" do
6
+ it "defers block body evaluation" do
7
+ lambda do
8
+ LazyModule.new do
9
+ raise "Will only be evaluated when mixed in"
10
+ end
11
+ end.should_not raise_error
12
+ end
13
+ end
14
+
15
+
16
+ describe "included into hosting class" do
17
+ before :all do
18
+ KlazzyLazyModule = LazyModule.new do
19
+ def self.klassy
20
+ "Klazz"
21
+ end
22
+
23
+ def instancy
24
+ "Instanzz"
25
+ end
26
+ end
27
+
28
+ @klass = Class.new do
29
+ include KlazzyLazyModule
30
+ end
31
+ end
32
+
33
+ it "class evals block body" do
34
+ @klass.klassy.should == "Klazz"
35
+ @klass.new.instancy.should == "Instanzz"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,312 @@
1
+ require 'spec_helper'
2
+ require 'extlib/mash'
3
+
4
+ class AwesomeHash < Hash
5
+ end
6
+
7
+ describe 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 = 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 = Mash.new :hash => @hash
22
+
23
+ mash["hash"].should be_an_instance_of(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 = 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 = Mash.new :arry => { :hash => [@hash] }
35
+
36
+ mash["arry"].should be_an_instance_of(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 = 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 = 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 = 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(Mash)
64
+ end
65
+ end # describe "#update"
66
+
67
+
68
+
69
+ describe "#[]=" do
70
+ it 'converts key into string' do
71
+ mash = 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 = Mash.new :hash => @hash
79
+ mash[:hash] = { :hash => "is buggy in Ruby 1.8.6" }
80
+
81
+ mash["hash"].should be_an_instance_of(Mash)
82
+ end
83
+ end # describe "#[]="
84
+
85
+
86
+
87
+ describe "#key?" do
88
+ before(:each) do
89
+ @mash = 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
+ Mash.new(@hash).dup.should be_an_instance_of(Mash)
130
+ end
131
+
132
+ it 'preserves keys' do
133
+ mash = 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 = 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
+ Mash.new(@hash).to_hash.should be_an_instance_of(Hash)
152
+ end
153
+
154
+ it 'preserves keys' do
155
+ mash = 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 = 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
+ Mash.new(@hash).symbolize_keys.should be_an_instance_of(Hash)
174
+ end
175
+
176
+ it 'converts keys to symbols' do
177
+ mash = 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 = 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 = 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 = 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 = 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 = 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 = 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 = Mash.new(@hash)
239
+
240
+ hashless_mash = mash.except(:hash)
241
+ hashless_mash.class.should be(Mash)
242
+ end
243
+ end
244
+
245
+
246
+
247
+ describe "#merge" do
248
+ before(:each) do
249
+ @mash = Mash.new(@hash).merge(:no => "in between")
250
+ end
251
+
252
+ it 'returns instance of Mash' do
253
+ @mash.should be_an_instance_of(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 = 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 = 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 = 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 = Mash.new(@hash)
308
+
309
+ mash.stringify_keys!.object_id.should == mash.object_id
310
+ end
311
+ end
312
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'extlib/module'
3
+
4
+ describe Module do
5
+
6
+ before(:all) do
7
+ module ::Foo
8
+ module ModBar
9
+ module Noo
10
+ module Too
11
+ module Boo
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ class Zed
18
+ end
19
+ end
20
+
21
+ class ::Baz
22
+ end
23
+
24
+ class ::Bar
25
+ end
26
+ end
27
+
28
+ it "should raise NameError for a missing constant" do
29
+ lambda { Foo.find_const('Moo') }.should raise_error(NameError)
30
+ lambda { Object.find_const('MissingConstant') }.should raise_error(NameError)
31
+ end
32
+
33
+ it "should be able to get a recursive constant" do
34
+ Object.find_const('Foo::ModBar').should == Foo::ModBar
35
+ end
36
+
37
+ it "should ignore get Constants from the Kernel namespace correctly" do
38
+ Object.find_const('::Foo::ModBar').should == ::Foo::ModBar
39
+ end
40
+
41
+ it "should find relative constants" do
42
+ Foo.find_const('ModBar').should == Foo::ModBar
43
+ Foo.find_const('Baz').should == Baz
44
+ end
45
+
46
+ it "should find sibling constants" do
47
+ Foo::ModBar.find_const("Zed").should == Foo::Zed
48
+ end
49
+
50
+ it "should find nested constants on nested constants" do
51
+ Foo::ModBar.find_const('Noo::Too').should == Foo::ModBar::Noo::Too
52
+ end
53
+
54
+ it "should find constants outside of nested constants" do
55
+ Foo::ModBar::Noo::Too.find_const("Zed").should == Foo::Zed
56
+ end
57
+
58
+ it 'should be able to find past the second nested level' do
59
+ Foo::ModBar::Noo.find_const('Too').should == Foo::ModBar::Noo::Too
60
+ Foo::ModBar::Noo::Too.find_const('Boo').should == Foo::ModBar::Noo::Too::Boo
61
+ end
62
+
63
+
64
+ it "should be able to deal with constants being added and removed" do
65
+ Object.find_const('Bar') # First we load Bar with find_const
66
+ Object.module_eval { remove_const('Bar') } # Now we delete it
67
+ module ::Bar; end; # Now we redefine it
68
+ Object.find_const('Bar').should == Bar
69
+ end
70
+
71
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ require 'extlib/object_space'
3
+
4
+ describe ObjectSpace, "#classes" do
5
+ it 'returns only classes, nothing else' do
6
+ ObjectSpace.classes.each do |klass|
7
+ Class.should === klass
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+ require 'extlib/object'
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("Oi").should == Oi
31
+ Object.full_const_get("Foo::Bar").should == Foo::Bar
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