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.
- data/History.txt +22 -0
- data/LICENSE +1 -1
- data/README +0 -0
- data/Rakefile +17 -12
- data/lib/extlib.rb +1 -1
- data/lib/extlib/blank.rb +51 -21
- data/lib/extlib/boolean.rb +1 -1
- data/lib/extlib/class.rb +12 -12
- data/lib/extlib/datetime.rb +20 -2
- data/lib/extlib/dictionary.rb +2 -2
- data/lib/extlib/hash.rb +57 -34
- data/lib/extlib/inflection.rb +0 -1
- data/lib/extlib/lazy_array.rb +327 -36
- data/lib/extlib/logger.rb +8 -8
- data/lib/extlib/mash.rb +45 -45
- data/lib/extlib/module.rb +1 -1
- data/lib/extlib/nil.rb +1 -1
- data/lib/extlib/numeric.rb +1 -1
- data/lib/extlib/object.rb +8 -21
- data/lib/extlib/object_space.rb +3 -3
- data/lib/extlib/pathname.rb +10 -0
- data/lib/extlib/pooling.rb +9 -17
- data/lib/extlib/rubygems.rb +7 -7
- data/lib/extlib/simple_set.rb +35 -8
- data/lib/extlib/string.rb +85 -42
- data/lib/extlib/struct.rb +10 -1
- data/lib/extlib/symbol.rb +11 -7
- data/lib/extlib/time.rb +31 -9
- data/lib/extlib/version.rb +1 -1
- data/lib/extlib/virtual_file.rb +1 -1
- data/spec/blank_spec.rb +85 -0
- data/spec/class_spec.rb +141 -0
- data/spec/datetime_spec.rb +22 -0
- data/spec/hash_spec.rb +537 -0
- data/spec/hook_spec.rb +1198 -0
- data/spec/inflection/plural_spec.rb +564 -0
- data/spec/inflection/singular_spec.rb +497 -0
- data/spec/inflection_extras_spec.rb +93 -0
- data/spec/lazy_array_spec.rb +1869 -0
- data/spec/mash_spec.rb +286 -0
- data/spec/module_spec.rb +58 -0
- data/spec/object_space_spec.rb +9 -0
- data/spec/object_spec.rb +114 -0
- data/spec/pooling_spec.rb +499 -0
- data/spec/simple_set_spec.rb +57 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/string_spec.rb +220 -0
- data/spec/struct_spec.rb +12 -0
- data/spec/symbol_spec.rb +8 -0
- data/spec/time_spec.rb +22 -0
- data/spec/try_dup_spec.rb +45 -0
- data/spec/virtual_file_spec.rb +21 -0
- metadata +51 -26
- data/README.txt +0 -3
data/spec/mash_spec.rb
ADDED
@@ -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
|
data/spec/module_spec.rb
ADDED
@@ -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
|
data/spec/object_spec.rb
ADDED
@@ -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
|