sundbp-extlib 0.9.14

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.
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