thorero 0.9.4 → 0.9.4.1
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.
- data/Rakefile +40 -34
- data/lib/extlib/tasks/release.rb +3 -5
- metadata +15 -71
- data/History.txt +0 -1
- data/Manifest +0 -45
- data/Manifest.txt +0 -29
- data/spec/blank_spec.rb +0 -85
- data/spec/hash_spec.rb +0 -524
- data/spec/hook_spec.rb +0 -1198
- data/spec/inflection_spec.rb +0 -50
- data/spec/lazy_array_spec.rb +0 -896
- data/spec/mash_spec.rb +0 -244
- data/spec/module_spec.rb +0 -58
- data/spec/object_space_spec.rb +0 -9
- data/spec/object_spec.rb +0 -98
- data/spec/pooling_spec.rb +0 -486
- data/spec/simple_set_spec.rb +0 -26
- data/spec/spec_helper.rb +0 -8
- data/spec/string_spec.rb +0 -200
- data/spec/struct_spec.rb +0 -12
- data/spec/time_spec.rb +0 -16
- data/spec/virtual_file_spec.rb +0 -21
- data/thorero.gemspec +0 -147
data/spec/mash_spec.rb
DELETED
@@ -1,244 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
|
3
|
-
describe Mash do
|
4
|
-
before(:each) do
|
5
|
-
@hash = { "mash" => "indifferent", :hash => "different" }
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "#initialize" do
|
9
|
-
it 'converts all keys into strings when param is a Hash' do
|
10
|
-
mash = Mash.new(@hash)
|
11
|
-
|
12
|
-
mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'converts all Hash values into Mashes if param is a Hash' do
|
16
|
-
mash = Mash.new :hash => @hash
|
17
|
-
|
18
|
-
mash["hash"].should be_an_instance_of(Mash)
|
19
|
-
# sanity check
|
20
|
-
mash["hash"]["hash"].should == "different"
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'converts all value items if value is an Array' do
|
24
|
-
mash = Mash.new :arry => { :hash => [@hash] }
|
25
|
-
|
26
|
-
mash["arry"].should be_an_instance_of(Mash)
|
27
|
-
# sanity check
|
28
|
-
mash["arry"]["hash"].first["hash"].should == "different"
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'delegates to superclass constructor if param is not a Hash' do
|
33
|
-
mash = Mash.new("dash berlin")
|
34
|
-
|
35
|
-
mash["unexisting key"].should == "dash berlin"
|
36
|
-
end
|
37
|
-
end # describe "#initialize"
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
describe "#update" do
|
42
|
-
it 'converts all keys into strings when param is a Hash' do
|
43
|
-
mash = Mash.new(@hash)
|
44
|
-
mash.update("starry" => "night")
|
45
|
-
|
46
|
-
mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'converts all Hash values into Mashes if param is a Hash' do
|
50
|
-
mash = Mash.new :hash => @hash
|
51
|
-
mash.update(:hash => { :hash => "is buggy in Ruby 1.8.6" })
|
52
|
-
|
53
|
-
mash["hash"].should be_an_instance_of(Mash)
|
54
|
-
end
|
55
|
-
end # describe "#update"
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
describe "#[]=" do
|
60
|
-
it 'converts key into string' do
|
61
|
-
mash = Mash.new(@hash)
|
62
|
-
mash[:hash] = { "starry" => "night" }
|
63
|
-
|
64
|
-
mash.keys.any? { |key| key.is_a?(Symbol) }.should be(false)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'converts all Hash value into Mash' do
|
68
|
-
mash = Mash.new :hash => @hash
|
69
|
-
mash[:hash] = { :hash => "is buggy in Ruby 1.8.6" }
|
70
|
-
|
71
|
-
mash["hash"].should be_an_instance_of(Mash)
|
72
|
-
end
|
73
|
-
end # describe "#[]="
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
describe "#key?" do
|
78
|
-
before(:each) do
|
79
|
-
@mash = Mash.new(@hash)
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'converts key before lookup' do
|
83
|
-
@mash.key?("mash").should be(true)
|
84
|
-
@mash.key?(:mash).should be(true)
|
85
|
-
|
86
|
-
@mash.key?("hash").should be(true)
|
87
|
-
@mash.key?(:hash).should be(true)
|
88
|
-
|
89
|
-
@mash.key?(:rainclouds).should be(false)
|
90
|
-
@mash.key?("rainclouds").should be(false)
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'is aliased as include?' do
|
94
|
-
@mash.include?("mash").should be(true)
|
95
|
-
@mash.include?(:mash).should be(true)
|
96
|
-
|
97
|
-
@mash.include?("hash").should be(true)
|
98
|
-
@mash.include?(:hash).should be(true)
|
99
|
-
|
100
|
-
@mash.include?(:rainclouds).should be(false)
|
101
|
-
@mash.include?("rainclouds").should be(false)
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'is aliased as member?' do
|
105
|
-
@mash.member?("mash").should be(true)
|
106
|
-
@mash.member?(:mash).should be(true)
|
107
|
-
|
108
|
-
@mash.member?("hash").should be(true)
|
109
|
-
@mash.member?(:hash).should be(true)
|
110
|
-
|
111
|
-
@mash.member?(:rainclouds).should be(false)
|
112
|
-
@mash.member?("rainclouds").should be(false)
|
113
|
-
end
|
114
|
-
end # describe "#key?"
|
115
|
-
|
116
|
-
|
117
|
-
describe "#dup" do
|
118
|
-
it 'returns instance of Mash' do
|
119
|
-
Mash.new(@hash).dup.should be_an_instance_of(Mash)
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'preserves keys' do
|
123
|
-
mash = Mash.new(@hash)
|
124
|
-
dup = mash.dup
|
125
|
-
|
126
|
-
mash.keys.sort.should == dup.keys.sort
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'preserves value' do
|
130
|
-
mash = Mash.new(@hash)
|
131
|
-
dup = mash.dup
|
132
|
-
|
133
|
-
mash.values.sort.should == dup.values.sort
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
describe "#to_hash" do
|
140
|
-
it 'returns instance of Mash' do
|
141
|
-
Mash.new(@hash).to_hash.should be_an_instance_of(Hash)
|
142
|
-
end
|
143
|
-
|
144
|
-
it 'preserves keys' do
|
145
|
-
mash = Mash.new(@hash)
|
146
|
-
converted = mash.to_hash
|
147
|
-
|
148
|
-
mash.keys.sort.should == converted.keys.sort
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'preserves value' do
|
152
|
-
mash = Mash.new(@hash)
|
153
|
-
converted = mash.to_hash
|
154
|
-
|
155
|
-
mash.values.sort.should == converted.values.sort
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
describe "#delete" do
|
162
|
-
it 'converts Symbol key into String before deleting' do
|
163
|
-
mash = Mash.new(@hash)
|
164
|
-
|
165
|
-
mash.delete(:hash)
|
166
|
-
mash.key?("hash").should be(false)
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'works with String keys as well' do
|
170
|
-
mash = Mash.new(@hash)
|
171
|
-
|
172
|
-
mash.delete("mash")
|
173
|
-
mash.key?("mash").should be(false)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
describe "#merge" do
|
180
|
-
before(:each) do
|
181
|
-
@mash = Mash.new(@hash).merge(:no => "in between")
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'returns instance of Mash' do
|
185
|
-
@mash.should be_an_instance_of(Mash)
|
186
|
-
end
|
187
|
-
|
188
|
-
it 'merges in give Hash' do
|
189
|
-
@mash["no"].should == "in between"
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
describe "#fetch" do
|
196
|
-
before(:each) do
|
197
|
-
@mash = Mash.new(@hash).merge(:no => "in between")
|
198
|
-
end
|
199
|
-
|
200
|
-
it 'converts key before fetching' do
|
201
|
-
@mash.fetch("no").should == "in between"
|
202
|
-
end
|
203
|
-
|
204
|
-
it 'returns alternative value if key lookup fails' do
|
205
|
-
@mash.fetch("flying", "screwdriver").should == "screwdriver"
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
|
210
|
-
describe "#default" do
|
211
|
-
before(:each) do
|
212
|
-
@mash = Mash.new(:yet_another_technical_revolution)
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'returns default value unless key exists in mash' do
|
216
|
-
@mash.default("peak oil is now behind, baby").should == :yet_another_technical_revolution
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'returns existing value if key is Symbol and exists in mash' do
|
220
|
-
@mash.update(:no => "in between")
|
221
|
-
@mash.default(:no).should == "in between"
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
|
226
|
-
describe "#values_at" do
|
227
|
-
before(:each) do
|
228
|
-
@mash = Mash.new(@hash).merge(:no => "in between")
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'is indifferent to whether keys are strings or symbols' do
|
232
|
-
@mash.values_at("hash", :mash, :no).should == ["different", "indifferent", "in between"]
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
|
237
|
-
describe "#stringify_keys!" do
|
238
|
-
it 'returns the mash itself' do
|
239
|
-
mash = Mash.new(@hash)
|
240
|
-
|
241
|
-
mash.stringify_keys!.object_id.should == mash.object_id
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
data/spec/module_spec.rb
DELETED
@@ -1,58 +0,0 @@
|
|
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 Bar
|
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::Bar').should == Foo::Bar
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should ignore get Constants from the Kernel namespace correctly" do
|
35
|
-
Object.find_const('::Foo::Bar').should == ::Foo::Bar
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should find relative constants" do
|
39
|
-
Foo.find_const('Bar').should == Foo::Bar
|
40
|
-
Foo.find_const('Baz').should == Baz
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should find sibling constants" do
|
44
|
-
Foo::Bar.find_const("Zed").should == Foo::Zed
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should find nested constants on nested constants" do
|
48
|
-
Foo::Bar.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_space_spec.rb
DELETED
data/spec/object_spec.rb
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
|
3
|
-
module HactiveSupport
|
4
|
-
class MemoizeConsideredUseless
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
class SymbolicDuck
|
9
|
-
def quack
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class ClassyDuck
|
14
|
-
end
|
15
|
-
|
16
|
-
describe Object do
|
17
|
-
|
18
|
-
describe "#full_const_get" do
|
19
|
-
it 'returns constant by FQ name in receiver namespace' do
|
20
|
-
Object.full_const_get("Extlib").should == Extlib
|
21
|
-
Object.full_const_get("Extlib::SimpleSet").should == Extlib::SimpleSet
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "#full_const_set" do
|
26
|
-
it 'sets constant value by FQ name in receiver namespace' do
|
27
|
-
Object.full_const_set("HactiveSupport::MCU", HactiveSupport::MemoizeConsideredUseless)
|
28
|
-
|
29
|
-
Object.full_const_get("HactiveSupport::MCU").should == HactiveSupport::MemoizeConsideredUseless
|
30
|
-
HactiveSupport.full_const_get("MCU").should == HactiveSupport::MemoizeConsideredUseless
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "#make_module" do
|
35
|
-
it 'creates a module from string FQ name' do
|
36
|
-
Object.make_module("Milano")
|
37
|
-
Object.make_module("Norway::Oslo")
|
38
|
-
|
39
|
-
defined?(Milano).should == "constant"
|
40
|
-
defined?(Norway::Oslo).should == "constant"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
describe "#quacks_like?" do
|
46
|
-
it 'returns true if duck is a Symbol and receiver responds to it' do
|
47
|
-
SymbolicDuck.new.quacks_like?(:quack).should be(true)
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'returns false if duck is a Symbol and receiver DOES NOT respond to it' do
|
51
|
-
SymbolicDuck.new.quacks_like?(:wtf).should be(false)
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'returns true if duck is a class and receiver is its instance' do
|
55
|
-
receiver = ClassyDuck.new
|
56
|
-
receiver.quacks_like?(ClassyDuck).should be(true)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'returns false if duck is a class and receiver IS NOT its instance' do
|
60
|
-
receiver = ClassyDuck.new
|
61
|
-
receiver.quacks_like?(SymbolicDuck).should be(false)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'returns true if duck is an array and at least one of its members quacks like this duck' do
|
65
|
-
receiver = ClassyDuck.new
|
66
|
-
ary = [ClassyDuck, SymbolicDuck]
|
67
|
-
|
68
|
-
receiver.quacks_like?(ary).should be(true)
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'returns false if duck is an array and none of its members quacks like this duck' do
|
72
|
-
receiver = ClassyDuck.new
|
73
|
-
ary = [SymbolicDuck.new, SymbolicDuck]
|
74
|
-
|
75
|
-
receiver.quacks_like?(ary).should be(false)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
describe "#in?" do
|
82
|
-
it 'returns true if object is included in collection' do
|
83
|
-
@ary = [1, 2, 3]
|
84
|
-
@set = Set.new([2, 3, 5])
|
85
|
-
|
86
|
-
1.in?(@ary).should be(true)
|
87
|
-
2.in?(@ary).should be(true)
|
88
|
-
3.in?(@ary).should be(true)
|
89
|
-
4.in?(@ary).should be(false)
|
90
|
-
|
91
|
-
1.in?(@set).should be(false)
|
92
|
-
2.in?(@set).should be(true)
|
93
|
-
3.in?(@set).should be(true)
|
94
|
-
4.in?(@set).should be(false)
|
95
|
-
5.in?(@set).should be(true)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
data/spec/pooling_spec.rb
DELETED
@@ -1,486 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
require 'timeout'
|
3
|
-
|
4
|
-
describe "Extlib::Pooling" do
|
5
|
-
before(:all) do
|
6
|
-
|
7
|
-
module Extlib::Pooling
|
8
|
-
def self.scavenger_interval
|
9
|
-
1
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class Person
|
14
|
-
include Extlib::Pooling
|
15
|
-
|
16
|
-
attr_accessor :name
|
17
|
-
|
18
|
-
def initialize(name)
|
19
|
-
@name = name
|
20
|
-
end
|
21
|
-
|
22
|
-
def dispose
|
23
|
-
@name = nil
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class Overwriter
|
28
|
-
|
29
|
-
def self.new(*args)
|
30
|
-
instance = allocate
|
31
|
-
instance.send(:initialize, *args)
|
32
|
-
instance.overwritten = true
|
33
|
-
instance
|
34
|
-
end
|
35
|
-
|
36
|
-
include Extlib::Pooling
|
37
|
-
|
38
|
-
attr_accessor :name
|
39
|
-
|
40
|
-
def initialize(name)
|
41
|
-
@name = name
|
42
|
-
@overwritten = false
|
43
|
-
end
|
44
|
-
|
45
|
-
def overwritten?
|
46
|
-
@overwritten
|
47
|
-
end
|
48
|
-
|
49
|
-
def overwritten=(value)
|
50
|
-
@overwritten = value
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.pool_size
|
54
|
-
pool_size = if RUBY_PLATFORM =~ /java/
|
55
|
-
20
|
56
|
-
else
|
57
|
-
2
|
58
|
-
end
|
59
|
-
pool_size
|
60
|
-
end
|
61
|
-
|
62
|
-
def dispose
|
63
|
-
@name = nil
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should track the initialized pools" do
|
69
|
-
bob = Person.new('Bob') # Ensure the pool is "primed"
|
70
|
-
bob.name.should == 'Bob'
|
71
|
-
bob.instance_variable_get(:@__pool).should_not be_nil
|
72
|
-
Person.__pools.size.should == 1
|
73
|
-
bob.release
|
74
|
-
Person.__pools.size.should == 1
|
75
|
-
|
76
|
-
Extlib::Pooling::pools.should_not be_empty
|
77
|
-
sleep(1.2)
|
78
|
-
Extlib::Pooling::pools.should be_empty
|
79
|
-
bob.name.should be_nil
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should maintain a size of 1" do
|
83
|
-
bob = Person.new('Bob')
|
84
|
-
fred = Person.new('Fred')
|
85
|
-
ted = Person.new('Ted')
|
86
|
-
|
87
|
-
Person.__pools.each do |args, pool|
|
88
|
-
pool.size.should == 1
|
89
|
-
end
|
90
|
-
|
91
|
-
bob.release
|
92
|
-
fred.release
|
93
|
-
ted.release
|
94
|
-
|
95
|
-
Person.__pools.each do |args, pool|
|
96
|
-
pool.size.should == 1
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
it "should allow you to overwrite Class#new" do
|
101
|
-
bob = Overwriter.new('Bob')
|
102
|
-
bob.should be_overwritten
|
103
|
-
bob.release
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should raise a ThreadStopError when the pool is exhausted in a single thread" do
|
107
|
-
lambda do
|
108
|
-
begin
|
109
|
-
bob = Person.new('Bob')
|
110
|
-
9.times { Person.new('Bob') }
|
111
|
-
ensure
|
112
|
-
bob.release
|
113
|
-
end
|
114
|
-
end.should raise_error(Extlib::Pooling::ThreadStopError)
|
115
|
-
end
|
116
|
-
|
117
|
-
it "should allow multiple threads to access the pool" do
|
118
|
-
t1 = Thread.new do
|
119
|
-
bob = Person.new('Bob')
|
120
|
-
sleep(0.1)
|
121
|
-
bob.release
|
122
|
-
end
|
123
|
-
|
124
|
-
lambda do
|
125
|
-
bob = Person.new('Bob')
|
126
|
-
t1.join
|
127
|
-
bob.release
|
128
|
-
end.should_not raise_error(Extlib::Pooling::ThreadStopError)
|
129
|
-
end
|
130
|
-
|
131
|
-
it "should allow you to flush a pool" do
|
132
|
-
bob = Overwriter.new('Bob')
|
133
|
-
Overwriter.new('Bob').release
|
134
|
-
bob.release
|
135
|
-
|
136
|
-
bob.name.should == 'Bob'
|
137
|
-
|
138
|
-
Overwriter.__pools[['Bob']].size.should == 2
|
139
|
-
Overwriter.__pools[['Bob']].flush!
|
140
|
-
Overwriter.__pools[['Bob']].size.should == 0
|
141
|
-
|
142
|
-
bob.name.should be_nil
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# describe Extlib::Pooling::ResourcePool do
|
147
|
-
# before :each do
|
148
|
-
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, :expiration_period => 50)
|
149
|
-
# end
|
150
|
-
#
|
151
|
-
# it "responds to flush!" do
|
152
|
-
# @pool.should respond_to(:flush!)
|
153
|
-
# end
|
154
|
-
#
|
155
|
-
# it "responds to aquire" do
|
156
|
-
# @pool.should respond_to(:aquire)
|
157
|
-
# end
|
158
|
-
#
|
159
|
-
# it "responds to release" do
|
160
|
-
# @pool.should respond_to(:release)
|
161
|
-
# end
|
162
|
-
#
|
163
|
-
# it "responds to :available?" do
|
164
|
-
# @pool.should respond_to(:available?)
|
165
|
-
# end
|
166
|
-
#
|
167
|
-
# it "has a size limit" do
|
168
|
-
# @pool.size_limit.should == 7
|
169
|
-
# end
|
170
|
-
#
|
171
|
-
# it "has initial size of zero" do
|
172
|
-
# @pool.size.should == 0
|
173
|
-
# end
|
174
|
-
#
|
175
|
-
# it "has a set of reserved resources" do
|
176
|
-
# @pool.instance_variable_get("@reserved").should be_empty
|
177
|
-
# end
|
178
|
-
#
|
179
|
-
# it "has a set of available resources" do
|
180
|
-
# @pool.instance_variable_get("@available").should be_empty
|
181
|
-
# end
|
182
|
-
#
|
183
|
-
# it "knows class of resources (objects) it works with" do
|
184
|
-
# @pool.class_of_resources.should == DisposableResource
|
185
|
-
# end
|
186
|
-
#
|
187
|
-
# it "raises exception when given anything but class for resources class" do
|
188
|
-
# lambda {
|
189
|
-
# @pool = Extlib::Pooling::ResourcePool.new(7, "Hooray!", {})
|
190
|
-
# }.should raise_error(ArgumentError, /class/)
|
191
|
-
# end
|
192
|
-
#
|
193
|
-
# it "requires class of resources (objects) it works with to have a dispose instance method" do
|
194
|
-
# lambda {
|
195
|
-
# @pool = Extlib::Pooling::ResourcePool.new(3, UndisposableResource, {})
|
196
|
-
# }.should raise_error(ArgumentError, /dispose/)
|
197
|
-
# end
|
198
|
-
#
|
199
|
-
# it "may take initialization arguments" do
|
200
|
-
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, { :initialization_args => ["paper"] })
|
201
|
-
# @pool.instance_variable_get("@initialization_args").should == ["paper"]
|
202
|
-
# end
|
203
|
-
#
|
204
|
-
# it "may take expiration period option" do
|
205
|
-
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, { :expiration_period => 100 })
|
206
|
-
# @pool.expiration_period.should == 100
|
207
|
-
# end
|
208
|
-
#
|
209
|
-
# it "has default expiration period of one minute" do
|
210
|
-
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, {})
|
211
|
-
# @pool.expiration_period.should == 60
|
212
|
-
# end
|
213
|
-
#
|
214
|
-
# it "spawns a thread to dispose objects haven't been used for a while" do
|
215
|
-
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, {})
|
216
|
-
# @pool.instance_variable_get("@pool_expiration_thread").should be_an_instance_of(Thread)
|
217
|
-
# end
|
218
|
-
# end
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
# describe "Aquire from contant size pool" do
|
223
|
-
# before :each do
|
224
|
-
# DisposableResource.initialize_pool(2)
|
225
|
-
# end
|
226
|
-
#
|
227
|
-
# after :each do
|
228
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
229
|
-
# end
|
230
|
-
#
|
231
|
-
# it "increased size of the pool" do
|
232
|
-
# @time = DisposableResource.pool.aquire
|
233
|
-
# DisposableResource.pool.size.should == 1
|
234
|
-
# end
|
235
|
-
#
|
236
|
-
# it "places initialized instance in the reserved set" do
|
237
|
-
# @time = DisposableResource.pool.aquire
|
238
|
-
# DisposableResource.pool.instance_variable_get("@reserved").size.should == 1
|
239
|
-
# end
|
240
|
-
#
|
241
|
-
# it "raises an exception when pool size limit is hit" do
|
242
|
-
# @t1 = DisposableResource.pool.aquire
|
243
|
-
# @t2 = DisposableResource.pool.aquire
|
244
|
-
#
|
245
|
-
# lambda { DisposableResource.pool.aquire }.should raise_error(RuntimeError)
|
246
|
-
# end
|
247
|
-
#
|
248
|
-
# it "returns last released resource" do
|
249
|
-
# @t1 = DisposableResource.pool.aquire
|
250
|
-
# @t2 = DisposableResource.pool.aquire
|
251
|
-
# DisposableResource.pool.release(@t1)
|
252
|
-
#
|
253
|
-
# DisposableResource.pool.aquire.should == @t1
|
254
|
-
# end
|
255
|
-
#
|
256
|
-
# it "really truly returns last released resource" do
|
257
|
-
# @t1 = DisposableResource.pool.aquire
|
258
|
-
# DisposableResource.pool.release(@t1)
|
259
|
-
#
|
260
|
-
# @t2 = DisposableResource.pool.aquire
|
261
|
-
# DisposableResource.pool.release(@t2)
|
262
|
-
#
|
263
|
-
# @t3 = DisposableResource.pool.aquire
|
264
|
-
# DisposableResource.pool.release(@t3)
|
265
|
-
#
|
266
|
-
# DisposableResource.pool.aquire.should == @t1
|
267
|
-
# @t1.should == @t3
|
268
|
-
# end
|
269
|
-
#
|
270
|
-
# it "sets allocation timestamp on resource instance" do
|
271
|
-
# @t1 = DisposableResource.new
|
272
|
-
# @t1.instance_variable_get("@__pool_aquire_timestamp").should be_close(Time.now, 2)
|
273
|
-
# end
|
274
|
-
# end
|
275
|
-
#
|
276
|
-
#
|
277
|
-
#
|
278
|
-
# describe "Releasing from contant size pool" do
|
279
|
-
# before :each do
|
280
|
-
# DisposableResource.initialize_pool(2)
|
281
|
-
# end
|
282
|
-
#
|
283
|
-
# after :each do
|
284
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
285
|
-
# end
|
286
|
-
#
|
287
|
-
# it "decreases size of the pool" do
|
288
|
-
# @t1 = DisposableResource.pool.aquire
|
289
|
-
# @t2 = DisposableResource.pool.aquire
|
290
|
-
# DisposableResource.pool.release(@t1)
|
291
|
-
#
|
292
|
-
# DisposableResource.pool.size.should == 1
|
293
|
-
# end
|
294
|
-
#
|
295
|
-
# it "raises an exception on attempt to releases object not in pool" do
|
296
|
-
# @t1 = DisposableResource.new
|
297
|
-
# @t2 = Set.new
|
298
|
-
#
|
299
|
-
# DisposableResource.pool.release(@t1)
|
300
|
-
# lambda { DisposableResource.pool.release(@t2) }.should raise_error(RuntimeError)
|
301
|
-
# end
|
302
|
-
#
|
303
|
-
# it "removes released object from reserved set" do
|
304
|
-
# @t1 = DisposableResource.pool.aquire
|
305
|
-
#
|
306
|
-
# lambda {
|
307
|
-
# DisposableResource.pool.release(@t1)
|
308
|
-
# }.should change(DisposableResource.pool.instance_variable_get("@reserved"), :size).by(-1)
|
309
|
-
# end
|
310
|
-
#
|
311
|
-
# it "returns released object back to available set" do
|
312
|
-
# @t1 = DisposableResource.pool.aquire
|
313
|
-
#
|
314
|
-
# lambda {
|
315
|
-
# DisposableResource.pool.release(@t1)
|
316
|
-
# }.should change(DisposableResource.pool.instance_variable_get("@available"), :size).by(1)
|
317
|
-
# end
|
318
|
-
#
|
319
|
-
# it "updates aquire timestamp on already allocated resource instance" do
|
320
|
-
# # aquire it once
|
321
|
-
# @t1 = DisposableResource.new
|
322
|
-
# # wait a bit
|
323
|
-
# sleep 3
|
324
|
-
#
|
325
|
-
# # check old timestamp
|
326
|
-
# @t1.instance_variable_get("@__pool_aquire_timestamp").should be_close(Time.now, 4)
|
327
|
-
#
|
328
|
-
# # re-aquire
|
329
|
-
# DisposableResource.pool.release(@t1)
|
330
|
-
# @t1 = DisposableResource.new
|
331
|
-
# # see timestamp is updated
|
332
|
-
# @t1.instance_variable_get("@__pool_aquire_timestamp").should be_close(Time.now, 2)
|
333
|
-
# end
|
334
|
-
# end
|
335
|
-
#
|
336
|
-
#
|
337
|
-
#
|
338
|
-
# describe Extlib::Pooling::ResourcePool, "#available?" do
|
339
|
-
# before :each do
|
340
|
-
# DisposableResource.initialize_pool(2)
|
341
|
-
# DisposableResource.new
|
342
|
-
# end
|
343
|
-
#
|
344
|
-
# after :each do
|
345
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
346
|
-
# end
|
347
|
-
#
|
348
|
-
# it "returns true when pool has available instances" do
|
349
|
-
# DisposableResource.pool.should be_available
|
350
|
-
# end
|
351
|
-
#
|
352
|
-
# it "returns false when pool is exhausted" do
|
353
|
-
# # aquires the last available resource
|
354
|
-
# DisposableResource.new
|
355
|
-
# DisposableResource.pool.should_not be_available
|
356
|
-
# end
|
357
|
-
# end
|
358
|
-
#
|
359
|
-
#
|
360
|
-
#
|
361
|
-
# describe "Flushing of contant size pool" do
|
362
|
-
# before :each do
|
363
|
-
# DisposableResource.initialize_pool(2)
|
364
|
-
#
|
365
|
-
# @t1 = DisposableResource.new
|
366
|
-
# @t2 = DisposableResource.new
|
367
|
-
#
|
368
|
-
# # sanity check
|
369
|
-
# DisposableResource.pool.instance_variable_get("@reserved").should_not be_empty
|
370
|
-
# end
|
371
|
-
#
|
372
|
-
# after :each do
|
373
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
374
|
-
# end
|
375
|
-
#
|
376
|
-
# it "disposes all pooled objects" do
|
377
|
-
# [@t1, @t2].each { |instance| instance.should_receive(:dispose) }
|
378
|
-
#
|
379
|
-
# DisposableResource.pool.flush!
|
380
|
-
# end
|
381
|
-
#
|
382
|
-
# it "empties reserved set" do
|
383
|
-
# DisposableResource.pool.flush!
|
384
|
-
#
|
385
|
-
# DisposableResource.pool.instance_variable_get("@reserved").should be_empty
|
386
|
-
# end
|
387
|
-
#
|
388
|
-
# it "returns all instances to available set" do
|
389
|
-
# DisposableResource.pool.flush!
|
390
|
-
#
|
391
|
-
# DisposableResource.pool.instance_variable_get("@available").size.should == 2
|
392
|
-
# end
|
393
|
-
# end
|
394
|
-
#
|
395
|
-
#
|
396
|
-
#
|
397
|
-
# describe "Poolable resource class" do
|
398
|
-
# before :each do
|
399
|
-
# DisposableResource.initialize_pool(3, :initialization_args => ["paper"])
|
400
|
-
# end
|
401
|
-
#
|
402
|
-
# after :each do
|
403
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
404
|
-
# end
|
405
|
-
#
|
406
|
-
# it "aquires new instances from pool" do
|
407
|
-
# @instance_one = DisposableResource.new
|
408
|
-
#
|
409
|
-
# DisposableResource.pool.aquired?(@instance_one).should be(true)
|
410
|
-
# end
|
411
|
-
#
|
412
|
-
# it "flushed existing pool on re-initialization" do
|
413
|
-
# DisposableResource.pool.should_receive(:flush!)
|
414
|
-
# DisposableResource.initialize_pool(5)
|
415
|
-
# end
|
416
|
-
#
|
417
|
-
# it "replaces pool on re-initialization" do
|
418
|
-
# DisposableResource.initialize_pool(5)
|
419
|
-
# DisposableResource.pool.size_limit.should == 5
|
420
|
-
# end
|
421
|
-
#
|
422
|
-
# it "passes initialization parameters to newly created resource instances" do
|
423
|
-
# DisposableResource.new.name.should == "paper"
|
424
|
-
# end
|
425
|
-
# end
|
426
|
-
#
|
427
|
-
#
|
428
|
-
#
|
429
|
-
# describe "Pooled object", "on initialization" do
|
430
|
-
# after :each do
|
431
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
432
|
-
# end
|
433
|
-
#
|
434
|
-
# it "does not flush pool" do
|
435
|
-
# # using pool here initializes the pool first
|
436
|
-
# # so we use instance variable directly
|
437
|
-
# DisposableResource.instance_variable_get("@__pool").should_not_receive(:flush!)
|
438
|
-
# DisposableResource.initialize_pool(23)
|
439
|
-
# end
|
440
|
-
#
|
441
|
-
# it "flushes pool first when re-initialized" do
|
442
|
-
# DisposableResource.initialize_pool(5)
|
443
|
-
# DisposableResource.pool.should_receive(:flush!)
|
444
|
-
# DisposableResource.initialize_pool(23)
|
445
|
-
# end
|
446
|
-
# end
|
447
|
-
#
|
448
|
-
#
|
449
|
-
#
|
450
|
-
# describe Extlib::Pooling::ResourcePool, "#time_to_dispose?" do
|
451
|
-
# before :each do
|
452
|
-
# DisposableResource.initialize_pool(7, :expiration_period => 2)
|
453
|
-
# end
|
454
|
-
#
|
455
|
-
# after :each do
|
456
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
457
|
-
# end
|
458
|
-
#
|
459
|
-
# it "returns true when object's last aquisition time is greater than limit" do
|
460
|
-
# @t1 = DisposableResource.new
|
461
|
-
# DisposableResource.pool.time_to_release?(@t1).should be(false)
|
462
|
-
#
|
463
|
-
# sleep 3
|
464
|
-
# DisposableResource.pool.time_to_release?(@t1).should be(true)
|
465
|
-
# end
|
466
|
-
# end
|
467
|
-
#
|
468
|
-
#
|
469
|
-
#
|
470
|
-
# describe Extlib::Pooling::ResourcePool, "#dispose_outdated" do
|
471
|
-
# before :each do
|
472
|
-
# DisposableResource.initialize_pool(7, :expiration_period => 2)
|
473
|
-
# end
|
474
|
-
#
|
475
|
-
# after :each do
|
476
|
-
# DisposableResource.instance_variable_set("@__pool", nil)
|
477
|
-
# end
|
478
|
-
#
|
479
|
-
# it "releases and thus disposes outdated instances" do
|
480
|
-
# @t1 = DisposableResource.new
|
481
|
-
# DisposableResource.pool.should_receive(:time_to_release?).with(@t1).and_return(true)
|
482
|
-
# DisposableResource.pool.should_receive(:release).with(@t1)
|
483
|
-
#
|
484
|
-
# DisposableResource.pool.dispose_outdated
|
485
|
-
# end
|
486
|
-
# end
|