sundbp-extlib 0.9.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) 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 +146 -0
  9. data/lib/extlib.rb +50 -0
  10. data/lib/extlib/array.rb +36 -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 +177 -0
  16. data/lib/extlib/datetime.rb +29 -0
  17. data/lib/extlib/dictionary.rb +433 -0
  18. data/lib/extlib/hash.rb +442 -0
  19. data/lib/extlib/hook.rb +403 -0
  20. data/lib/extlib/inflection.rb +440 -0
  21. data/lib/extlib/lazy_array.rb +451 -0
  22. data/lib/extlib/lazy_module.rb +18 -0
  23. data/lib/extlib/logger.rb +198 -0
  24. data/lib/extlib/mash.rb +155 -0
  25. data/lib/extlib/module.rb +47 -0
  26. data/lib/extlib/nil.rb +5 -0
  27. data/lib/extlib/numeric.rb +5 -0
  28. data/lib/extlib/object.rb +175 -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 +43 -0
  38. data/lib/extlib/virtual_file.rb +10 -0
  39. data/spec/array_spec.rb +39 -0
  40. data/spec/blank_spec.rb +85 -0
  41. data/spec/byte_array_spec.rb +7 -0
  42. data/spec/class_spec.rb +157 -0
  43. data/spec/datetime_spec.rb +22 -0
  44. data/spec/hash_spec.rb +537 -0
  45. data/spec/hook_spec.rb +1234 -0
  46. data/spec/inflection/plural_spec.rb +564 -0
  47. data/spec/inflection/singular_spec.rb +497 -0
  48. data/spec/inflection_extras_spec.rb +110 -0
  49. data/spec/lazy_array_spec.rb +1957 -0
  50. data/spec/lazy_module_spec.rb +38 -0
  51. data/spec/mash_spec.rb +311 -0
  52. data/spec/module_spec.rb +70 -0
  53. data/spec/object_space_spec.rb +9 -0
  54. data/spec/object_spec.rb +114 -0
  55. data/spec/pooling_spec.rb +511 -0
  56. data/spec/rcov.opts +6 -0
  57. data/spec/simple_set_spec.rb +57 -0
  58. data/spec/spec.opts +4 -0
  59. data/spec/spec_helper.rb +10 -0
  60. data/spec/string_spec.rb +221 -0
  61. data/spec/struct_spec.rb +12 -0
  62. data/spec/symbol_spec.rb +8 -0
  63. data/spec/time_spec.rb +29 -0
  64. data/spec/try_call_spec.rb +73 -0
  65. data/spec/try_dup_spec.rb +45 -0
  66. data/spec/virtual_file_spec.rb +21 -0
  67. data/tasks/ci.rake +1 -0
  68. data/tasks/metrics.rake +36 -0
  69. data/tasks/spec.rake +25 -0
  70. data/tasks/yard.rake +9 -0
  71. data/tasks/yardstick.rake +19 -0
  72. metadata +180 -0
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '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,311 @@
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 "#symbolize_keys" do
171
+ it 'returns instance of Mash' do
172
+ Mash.new(@hash).symbolize_keys.should be_an_instance_of(Hash)
173
+ end
174
+
175
+ it 'converts keys to symbols' do
176
+ mash = Mash.new(@hash)
177
+ converted = mash.symbolize_keys
178
+
179
+ converted_keys = converted.keys.sort{|k1, k2| k1.to_s <=> k2.to_s}
180
+ orig_keys = mash.keys.map{|k| k.to_sym}.sort{|i1, i2| i1.to_s <=> i2.to_s}
181
+
182
+ converted_keys.should == orig_keys
183
+ end
184
+
185
+ it 'preserves value' do
186
+ mash = Mash.new(@hash)
187
+ converted = mash.symbolize_keys
188
+
189
+ mash.values.sort.should == converted.values.sort
190
+ end
191
+ end
192
+
193
+
194
+
195
+ describe "#delete" do
196
+ it 'converts Symbol key into String before deleting' do
197
+ mash = Mash.new(@hash)
198
+
199
+ mash.delete(:hash)
200
+ mash.key?("hash").should be_false
201
+ end
202
+
203
+ it 'works with String keys as well' do
204
+ mash = Mash.new(@hash)
205
+
206
+ mash.delete("mash")
207
+ mash.key?("mash").should be_false
208
+ end
209
+ end
210
+
211
+
212
+
213
+ describe "#except" do
214
+ it "converts Symbol key into String before calling super" do
215
+ mash = Mash.new(@hash)
216
+
217
+ hashless_mash = mash.except(:hash)
218
+ hashless_mash.key?("hash").should be_false
219
+ end
220
+
221
+ it "works with String keys as well" do
222
+ mash = Mash.new(@hash)
223
+
224
+ mashless_mash = mash.except("mash")
225
+ mashless_mash.key?("mash").should be_false
226
+ end
227
+
228
+ it "works with multiple keys" do
229
+ mash = Mash.new(@hash)
230
+
231
+ mashless = mash.except("hash", :mash)
232
+ mashless.key?(:hash).should be_false
233
+ mashless.key?("mash").should be_false
234
+ end
235
+
236
+ it "should return a mash" do
237
+ mash = Mash.new(@hash)
238
+
239
+ hashless_mash = mash.except(:hash)
240
+ hashless_mash.class.should be(Mash)
241
+ end
242
+ end
243
+
244
+
245
+
246
+ describe "#merge" do
247
+ before(:each) do
248
+ @mash = Mash.new(@hash).merge(:no => "in between")
249
+ end
250
+
251
+ it 'returns instance of Mash' do
252
+ @mash.should be_an_instance_of(Mash)
253
+ end
254
+
255
+ it 'merges in give Hash' do
256
+ @mash["no"].should == "in between"
257
+ end
258
+ end
259
+
260
+
261
+
262
+ describe "#fetch" do
263
+ before(:each) do
264
+ @mash = Mash.new(@hash).merge(:no => "in between")
265
+ end
266
+
267
+ it 'converts key before fetching' do
268
+ @mash.fetch("no").should == "in between"
269
+ end
270
+
271
+ it 'returns alternative value if key lookup fails' do
272
+ @mash.fetch("flying", "screwdriver").should == "screwdriver"
273
+ end
274
+ end
275
+
276
+
277
+ describe "#default" do
278
+ before(:each) do
279
+ @mash = Mash.new(:yet_another_technical_revolution)
280
+ end
281
+
282
+ it 'returns default value unless key exists in mash' do
283
+ @mash.default("peak oil is now behind, baby").should == :yet_another_technical_revolution
284
+ end
285
+
286
+ it 'returns existing value if key is Symbol and exists in mash' do
287
+ @mash.update(:no => "in between")
288
+ @mash.default(:no).should == "in between"
289
+ end
290
+ end
291
+
292
+
293
+ describe "#values_at" do
294
+ before(:each) do
295
+ @mash = Mash.new(@hash).merge(:no => "in between")
296
+ end
297
+
298
+ it 'is indifferent to whether keys are strings or symbols' do
299
+ @mash.values_at("hash", :mash, :no).should == ["different", "indifferent", "in between"]
300
+ end
301
+ end
302
+
303
+
304
+ describe "#stringify_keys!" do
305
+ it 'returns the mash itself' do
306
+ mash = Mash.new(@hash)
307
+
308
+ mash.stringify_keys!.object_id.should == mash.object_id
309
+ end
310
+ end
311
+ end
@@ -0,0 +1,70 @@
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
+ module Boo
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ class Zed
17
+ end
18
+ end
19
+
20
+ class ::Baz
21
+ end
22
+
23
+ class ::Bar
24
+ end
25
+ end
26
+
27
+ it "should raise NameError for a missing constant" do
28
+ lambda { Foo.find_const('Moo') }.should raise_error(NameError)
29
+ lambda { Object.find_const('MissingConstant') }.should raise_error(NameError)
30
+ end
31
+
32
+ it "should be able to get a recursive constant" do
33
+ Object.find_const('Foo::ModBar').should == Foo::ModBar
34
+ end
35
+
36
+ it "should ignore get Constants from the Kernel namespace correctly" do
37
+ Object.find_const('::Foo::ModBar').should == ::Foo::ModBar
38
+ end
39
+
40
+ it "should find relative constants" do
41
+ Foo.find_const('ModBar').should == Foo::ModBar
42
+ Foo.find_const('Baz').should == Baz
43
+ end
44
+
45
+ it "should find sibling constants" do
46
+ Foo::ModBar.find_const("Zed").should == Foo::Zed
47
+ end
48
+
49
+ it "should find nested constants on nested constants" do
50
+ Foo::ModBar.find_const('Noo::Too').should == Foo::ModBar::Noo::Too
51
+ end
52
+
53
+ it "should find constants outside of nested constants" do
54
+ Foo::ModBar::Noo::Too.find_const("Zed").should == Foo::Zed
55
+ end
56
+
57
+ it 'should be able to find past the second nested level' do
58
+ Foo::ModBar::Noo.find_const('Too').should == Foo::ModBar::Noo::Too
59
+ Foo::ModBar::Noo::Too.find_const('Boo').should == Foo::ModBar::Noo::Too::Boo
60
+ end
61
+
62
+
63
+ it "should be able to deal with constants being added and removed" do
64
+ Object.find_const('Bar') # First we load Bar with find_const
65
+ Object.module_eval { remove_const('Bar') } # Now we delete it
66
+ module ::Bar; end; # Now we redefine it
67
+ Object.find_const('Bar').should == Bar
68
+ end
69
+
70
+ 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