amqp 1.1.5 → 1.1.6
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/ChangeLog.md +29 -1
- data/lib/amqp/channel.rb +8 -65
- data/lib/amqp/channel_id_allocator.rb +58 -0
- data/lib/amqp/session.rb +2 -1
- data/lib/amqp/version.rb +1 -1
- data/spec/integration/automatic_recovery_predicate_spec.rb +1 -1
- data/spec/unit/amqp/channel_id_allocation_spec.rb +36 -16
- metadata +3 -4
- data/spec/unit/amqp/bit_set_spec.rb +0 -127
- data/spec/unit/amqp/int_allocator_spec.rb +0 -116
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 480856b9abfa322113dabee60f290c0763e80691
|
4
|
+
data.tar.gz: 20c5d50f24be734b8f45261d10c608aea26cb005
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3942ea6fea956c33bf53e531acab4c9fea1e6366e14483b935550c125b4db7217e45c677e650b85db67ed92810b77dcd730cdaf6c9b8e6ba2af1d1e725d398d4
|
7
|
+
data.tar.gz: ebf78c68c6a188c5d7583dd93c5213d52d82671845650b76b6dabf3743dd4b69b1c06257a85e6294bdc8df69a144539b74306e15c341b9a4737a6203b866e11d
|
data/.travis.yml
CHANGED
data/ChangeLog.md
CHANGED
@@ -1,6 +1,34 @@
|
|
1
|
+
## Changes Between 1.1.5 and 1.1.6
|
2
|
+
|
3
|
+
### 65535 Channels Per Connection
|
4
|
+
|
5
|
+
amqp gem now allows for 65535 channels per connection and
|
6
|
+
not Ruby process.
|
7
|
+
|
8
|
+
Contributed by Neo (http://neo.com) developers.
|
9
|
+
|
10
|
+
|
11
|
+
## Changes Between 1.1.4 and 1.1.5
|
12
|
+
|
13
|
+
### channel.close is Delayed Until After Channel is Open
|
14
|
+
|
15
|
+
This eliminates a race condition in some codebases that use
|
16
|
+
very short lived channels.
|
17
|
+
|
18
|
+
|
19
|
+
## Changes Between 1.1.3 and 1.1.4
|
20
|
+
|
21
|
+
### ConnectionClosedError is Back
|
22
|
+
|
23
|
+
`ConnectionClosedError` is now defined again.
|
24
|
+
|
25
|
+
|
1
26
|
## Changes Between 1.1.2 and 1.1.3
|
2
27
|
|
3
|
-
|
28
|
+
### Fixed Exception in AMQP::Exchange#handle_declare_ok
|
29
|
+
|
30
|
+
`AMQP::Exchange#handle_declare_ok` no longer raises an exception
|
31
|
+
about undefined method.
|
4
32
|
|
5
33
|
|
6
34
|
## Changes Between 1.1.1 and 1.1.2
|
data/lib/amqp/channel.rb
CHANGED
@@ -231,19 +231,19 @@ module AMQP
|
|
231
231
|
#
|
232
232
|
# @see AMQP::Channel#prefetch
|
233
233
|
# @api public
|
234
|
-
def initialize(connection = nil, id =
|
234
|
+
def initialize(connection = nil, id = nil, options = {}, &block)
|
235
235
|
raise 'AMQP can only be used from within EM.run {}' unless EM.reactor_running?
|
236
236
|
|
237
237
|
@connection = connection || AMQP.connection || AMQP.start
|
238
238
|
# this means 2nd argument is options
|
239
239
|
if id.kind_of?(Hash)
|
240
240
|
options = options.merge(id)
|
241
|
-
id =
|
241
|
+
id = @connection.next_channel_id
|
242
242
|
end
|
243
243
|
|
244
244
|
super(@connection)
|
245
245
|
|
246
|
-
@id = id
|
246
|
+
@id = id || @connection.next_channel_id
|
247
247
|
@exchanges = Hash.new
|
248
248
|
@queues = Hash.new
|
249
249
|
@consumers = Hash.new
|
@@ -264,8 +264,8 @@ module AMQP
|
|
264
264
|
65536
|
265
265
|
end
|
266
266
|
|
267
|
-
if channel_max != 0 && !(0..channel_max).include?(id)
|
268
|
-
raise ArgumentError.new("Max channel for the connection is #{channel_max}, given: #{id}")
|
267
|
+
if channel_max != 0 && !(0..channel_max).include?(@id)
|
268
|
+
raise ArgumentError.new("Max channel for the connection is #{channel_max}, given: #{@id}")
|
269
269
|
end
|
270
270
|
|
271
271
|
# we need this deferrable to mimic what AMQP gem 0.7 does to enable
|
@@ -344,7 +344,7 @@ module AMQP
|
|
344
344
|
# must release after we allocate a new id, otherwise we will end up
|
345
345
|
# with the same value. MK.
|
346
346
|
@id = self.class.next_channel_id
|
347
|
-
|
347
|
+
@connection.release_channel_id(old_id)
|
348
348
|
|
349
349
|
@channel_is_open_deferrable.fail
|
350
350
|
@channel_is_open_deferrable = AMQP::Deferrable.new
|
@@ -1174,67 +1174,10 @@ module AMQP
|
|
1174
1174
|
self.exec_callback_yielding_self(:after_connection_interruption)
|
1175
1175
|
self.reset_state!
|
1176
1176
|
|
1177
|
-
|
1177
|
+
@connection.release_channel_id(@id) unless auto_recovering?
|
1178
1178
|
@channel_is_open_deferrable = AMQP::Deferrable.new
|
1179
1179
|
end
|
1180
1180
|
|
1181
|
-
|
1182
|
-
# @private
|
1183
|
-
# @api private
|
1184
|
-
def self.channel_id_mutex
|
1185
|
-
@channel_id_mutex ||= Mutex.new
|
1186
|
-
end
|
1187
|
-
|
1188
|
-
# Returns next available channel id. This method is thread safe.
|
1189
|
-
#
|
1190
|
-
# @return [Fixnum]
|
1191
|
-
# @api public
|
1192
|
-
# @see Channel.release_channel_id
|
1193
|
-
# @see Channel.reset_channel_id_allocator
|
1194
|
-
def self.next_channel_id
|
1195
|
-
channel_id_mutex.synchronize do
|
1196
|
-
self.initialize_channel_id_allocator
|
1197
|
-
|
1198
|
-
@int_allocator.allocate
|
1199
|
-
end
|
1200
|
-
end
|
1201
|
-
|
1202
|
-
# Releases previously allocated channel id. This method is thread safe.
|
1203
|
-
#
|
1204
|
-
# @param [Fixnum] Channel id to release
|
1205
|
-
# @api public
|
1206
|
-
# @see Channel.next_channel_id
|
1207
|
-
# @see Channel.reset_channel_id_allocator
|
1208
|
-
def self.release_channel_id(i)
|
1209
|
-
channel_id_mutex.synchronize do
|
1210
|
-
self.initialize_channel_id_allocator
|
1211
|
-
|
1212
|
-
@int_allocator.release(i)
|
1213
|
-
end
|
1214
|
-
end # self.release_channel_id(i)
|
1215
|
-
|
1216
|
-
# Resets channel allocator. This method is thread safe.
|
1217
|
-
# @api public
|
1218
|
-
# @see Channel.next_channel_id
|
1219
|
-
# @see Channel.release_channel_id
|
1220
|
-
def self.reset_channel_id_allocator
|
1221
|
-
channel_id_mutex.synchronize do
|
1222
|
-
initialize_channel_id_allocator
|
1223
|
-
|
1224
|
-
@int_allocator.reset
|
1225
|
-
end
|
1226
|
-
end # self.reset_channel_id_allocator
|
1227
|
-
|
1228
|
-
|
1229
|
-
# @private
|
1230
|
-
def self.initialize_channel_id_allocator
|
1231
|
-
# TODO: ideally, this should be in agreement with agreed max number of channels of the connection,
|
1232
|
-
# but it is possible that value either not yet available. MK.
|
1233
|
-
max_channel = (1 << 16) - 1
|
1234
|
-
@int_allocator ||= IntAllocator.new(1, max_channel)
|
1235
|
-
end # self.initialize_channel_id_allocator
|
1236
|
-
|
1237
|
-
|
1238
1181
|
# @return [Boolean] true if this channel uses automatic recovery mode
|
1239
1182
|
def auto_recovering?
|
1240
1183
|
@auto_recovery
|
@@ -1534,7 +1477,7 @@ module AMQP
|
|
1534
1477
|
self.connection.clear_frames_on(self.id)
|
1535
1478
|
self.exec_callback_once_yielding_self(:close, close_ok)
|
1536
1479
|
|
1537
|
-
|
1480
|
+
@connection.release_channel_id(@id)
|
1538
1481
|
end
|
1539
1482
|
|
1540
1483
|
# @api plugin
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module AMQP
|
2
|
+
module ChannelIdAllocator
|
3
|
+
|
4
|
+
MAX_CHANNELS_PER_CONNECTION = (2**16)
|
5
|
+
|
6
|
+
# Resets channel allocator. This method is thread safe.
|
7
|
+
# @api public
|
8
|
+
# @see Channel.next_channel_id
|
9
|
+
# @see Channel.release_channel_id
|
10
|
+
def reset_channel_id_allocator
|
11
|
+
channel_id_mutex.synchronize do
|
12
|
+
int_allocator.reset
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Releases previously allocated channel id. This method is thread safe.
|
17
|
+
#
|
18
|
+
# @param [Fixnum] Channel id to release
|
19
|
+
# @api public
|
20
|
+
# @see Channel.next_channel_id
|
21
|
+
# @see Channel.reset_channel_id_allocator
|
22
|
+
def release_channel_id(i)
|
23
|
+
channel_id_mutex.synchronize do
|
24
|
+
int_allocator.release(i)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns next available channel id. This method is thread safe.
|
29
|
+
#
|
30
|
+
# @return [Fixnum]
|
31
|
+
# @api public
|
32
|
+
# @see Channel.release_channel_id
|
33
|
+
# @see Channel.reset_channel_id_allocator
|
34
|
+
def next_channel_id
|
35
|
+
channel_id_mutex.synchronize do
|
36
|
+
result = int_allocator.allocate
|
37
|
+
raise "No further channels available. Please open a new connection." if result < 0
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# @private
|
45
|
+
# @api private
|
46
|
+
def channel_id_mutex
|
47
|
+
@channel_id_mutex ||= Mutex.new
|
48
|
+
end
|
49
|
+
|
50
|
+
# @private
|
51
|
+
def int_allocator
|
52
|
+
# TODO: ideally, this should be in agreement with agreed max number of channels of the connection,
|
53
|
+
# but it is possible that value either not yet available. MK.
|
54
|
+
@int_allocator ||= IntAllocator.new(1, MAX_CHANNELS_PER_CONNECTION)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/amqp/session.rb
CHANGED
@@ -6,6 +6,7 @@ require "amqp/auth_mechanism_adapter"
|
|
6
6
|
require "amqp/broker"
|
7
7
|
|
8
8
|
require "amqp/channel"
|
9
|
+
require "amqp/channel_id_allocator"
|
9
10
|
|
10
11
|
module AMQP
|
11
12
|
# AMQP session represents connection to the broker. Session objects let you define callbacks for
|
@@ -33,7 +34,7 @@ module AMQP
|
|
33
34
|
#
|
34
35
|
# @api public
|
35
36
|
class Session < EM::Connection
|
36
|
-
|
37
|
+
include AMQP::ChannelIdAllocator
|
37
38
|
|
38
39
|
#
|
39
40
|
# Behaviours
|
data/lib/amqp/version.rb
CHANGED
@@ -46,7 +46,7 @@ describe AMQP::Channel, "options hash" do
|
|
46
46
|
|
47
47
|
|
48
48
|
it "can be passed as the 3rd constructor argument" do
|
49
|
-
ch = AMQP::Channel.new(AMQP.connection,
|
49
|
+
ch = AMQP::Channel.new(AMQP.connection, nil, :auto_recovery => true)
|
50
50
|
ch.auto_recovery.should be_true
|
51
51
|
ch.auto_recovery = false
|
52
52
|
ch.auto_recovery.should be_false
|
@@ -1,40 +1,60 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
|
+
describe AMQP::ChannelIdAllocator do
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
class ChannelAllocator
|
7
|
+
include AMQP::ChannelIdAllocator
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#next_channel_id" do
|
11
|
+
subject do
|
12
|
+
ChannelAllocator.new()
|
9
13
|
end
|
10
14
|
|
11
15
|
context "when there is a channel id available for allocation" do
|
12
16
|
it "returns that channel id" do
|
13
|
-
1024.times {
|
17
|
+
1024.times { subject.next_channel_id }
|
14
18
|
|
15
|
-
|
19
|
+
subject.next_channel_id.should == 1025
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
19
23
|
context "when THERE IS NOT channel id available for allocation" do
|
20
|
-
it "raises an exception"
|
24
|
+
it "raises an exception" do
|
25
|
+
(ChannelAllocator::MAX_CHANNELS_PER_CONNECTION - 1).times do
|
26
|
+
subject.next_channel_id
|
27
|
+
end
|
28
|
+
|
29
|
+
lambda { subject.next_channel_id }.should raise_error
|
30
|
+
end
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
24
34
|
|
25
|
-
|
26
35
|
describe ".release_channel_id" do
|
27
|
-
|
28
|
-
|
36
|
+
subject do
|
37
|
+
ChannelAllocator.new()
|
29
38
|
end
|
30
39
|
|
31
40
|
it "releases that channel id" do
|
32
|
-
1024.times {
|
33
|
-
|
41
|
+
1024.times { subject.next_channel_id }
|
42
|
+
subject.next_channel_id.should == 1025
|
43
|
+
|
44
|
+
subject.release_channel_id(128)
|
45
|
+
subject.next_channel_id.should == 128
|
46
|
+
subject.next_channel_id.should == 1026
|
47
|
+
end
|
48
|
+
end
|
34
49
|
|
35
|
-
|
36
|
-
|
37
|
-
|
50
|
+
describe "each instance gets its own channel IDs" do
|
51
|
+
it "has an allocator per instance" do
|
52
|
+
one = ChannelAllocator.new()
|
53
|
+
two = ChannelAllocator.new()
|
54
|
+
one.next_channel_id.should == 1
|
55
|
+
one.next_channel_id.should == 2
|
56
|
+
two.next_channel_id.should == 1
|
57
|
+
two.next_channel_id.should == 2
|
38
58
|
end
|
39
59
|
end
|
40
|
-
end
|
60
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amqp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aman Gupta
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-12-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: eventmachine
|
@@ -234,6 +234,7 @@ files:
|
|
234
234
|
- lib/amqp/broker.rb
|
235
235
|
- lib/amqp/callbacks.rb
|
236
236
|
- lib/amqp/channel.rb
|
237
|
+
- lib/amqp/channel_id_allocator.rb
|
237
238
|
- lib/amqp/compatibility/ruby187_patchlevel_check.rb
|
238
239
|
- lib/amqp/consumer.rb
|
239
240
|
- lib/amqp/consumer_tag_generator.rb
|
@@ -298,11 +299,9 @@ files:
|
|
298
299
|
- spec/integration/tx_commit_spec.rb
|
299
300
|
- spec/integration/tx_rollback_spec.rb
|
300
301
|
- spec/spec_helper.rb
|
301
|
-
- spec/unit/amqp/bit_set_spec.rb
|
302
302
|
- spec/unit/amqp/channel_id_allocation_spec.rb
|
303
303
|
- spec/unit/amqp/client_spec.rb
|
304
304
|
- spec/unit/amqp/connection_spec.rb
|
305
|
-
- spec/unit/amqp/int_allocator_spec.rb
|
306
305
|
homepage: http://rubyamqp.info
|
307
306
|
licenses:
|
308
307
|
- Ruby
|
@@ -1,127 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
require "amqp/bit_set"
|
6
|
-
|
7
|
-
|
8
|
-
describe AMQP::BitSet do
|
9
|
-
|
10
|
-
#
|
11
|
-
# Environment
|
12
|
-
#
|
13
|
-
|
14
|
-
let(:nbits) { (1 << 16) - 1 }
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
# Examples
|
19
|
-
#
|
20
|
-
|
21
|
-
describe "#get, #[]" do
|
22
|
-
describe "when bit at given position is set" do
|
23
|
-
subject do
|
24
|
-
o = described_class.new(nbits)
|
25
|
-
o.set(3)
|
26
|
-
o
|
27
|
-
end
|
28
|
-
|
29
|
-
it "returns true" do
|
30
|
-
subject.get(3).should be_true
|
31
|
-
end # it
|
32
|
-
end # describe
|
33
|
-
|
34
|
-
describe "when bit at given position is off" do
|
35
|
-
subject do
|
36
|
-
described_class.new(nbits)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "returns false" do
|
40
|
-
subject.get(5).should be_false
|
41
|
-
end # it
|
42
|
-
end # describe
|
43
|
-
end # describe
|
44
|
-
|
45
|
-
|
46
|
-
describe "#set" do
|
47
|
-
describe "when bit at given position is set" do
|
48
|
-
subject do
|
49
|
-
described_class.new(nbits)
|
50
|
-
end
|
51
|
-
|
52
|
-
it "has no effect" do
|
53
|
-
subject.set(3)
|
54
|
-
subject.get(3).should be_true
|
55
|
-
subject.set(3)
|
56
|
-
subject[3].should be_true
|
57
|
-
end # it
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "when bit at given position is off" do
|
61
|
-
subject do
|
62
|
-
described_class.new(nbits)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "sets that bit" do
|
66
|
-
subject.set(3)
|
67
|
-
subject.get(3).should be_true
|
68
|
-
|
69
|
-
subject.set(33)
|
70
|
-
subject.get(33).should be_true
|
71
|
-
|
72
|
-
subject.set(3387)
|
73
|
-
subject.get(3387).should be_true
|
74
|
-
end
|
75
|
-
end # describe
|
76
|
-
end # describe
|
77
|
-
|
78
|
-
|
79
|
-
describe "#unset" do
|
80
|
-
describe "when bit at a given position is set" do
|
81
|
-
subject do
|
82
|
-
described_class.new(nbits)
|
83
|
-
end
|
84
|
-
|
85
|
-
it "unsets that bit" do
|
86
|
-
subject.set(3)
|
87
|
-
subject.get(3).should be_true
|
88
|
-
subject.unset(3)
|
89
|
-
subject.get(3).should be_false
|
90
|
-
end # it
|
91
|
-
end # describe
|
92
|
-
|
93
|
-
|
94
|
-
describe "when bit at a given position is off" do
|
95
|
-
subject do
|
96
|
-
described_class.new(nbits)
|
97
|
-
end
|
98
|
-
|
99
|
-
it "has no effect" do
|
100
|
-
subject.get(3).should be_false
|
101
|
-
subject.unset(3)
|
102
|
-
subject.get(3).should be_false
|
103
|
-
end # it
|
104
|
-
end # describe
|
105
|
-
end # describe
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
describe "#clear" do
|
110
|
-
subject do
|
111
|
-
described_class.new(nbits)
|
112
|
-
end
|
113
|
-
|
114
|
-
it "clears all bits" do
|
115
|
-
subject.set(3)
|
116
|
-
subject.get(3).should be_true
|
117
|
-
|
118
|
-
subject.set(7668)
|
119
|
-
subject.get(7668).should be_true
|
120
|
-
|
121
|
-
subject.clear
|
122
|
-
|
123
|
-
subject.get(3).should be_false
|
124
|
-
subject.get(7668).should be_false
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require "amqp/int_allocator"
|
5
|
-
|
6
|
-
describe AMQP::IntAllocator do
|
7
|
-
|
8
|
-
#
|
9
|
-
# Environment
|
10
|
-
#
|
11
|
-
|
12
|
-
subject do
|
13
|
-
described_class.new(1, 5)
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
# ...
|
18
|
-
|
19
|
-
|
20
|
-
#
|
21
|
-
# Examples
|
22
|
-
#
|
23
|
-
|
24
|
-
describe "#number_of_bits" do
|
25
|
-
it "returns number of bits available for allocation" do
|
26
|
-
subject.number_of_bits.should == 4
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
describe "#hi" do
|
32
|
-
it "returns upper bound of the allocation range" do
|
33
|
-
subject.hi.should == 5
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe "#lo" do
|
38
|
-
it "returns lower bound of the allocation range" do
|
39
|
-
subject.lo.should == 1
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
describe "#allocate" do
|
45
|
-
context "when integer in the range is available" do
|
46
|
-
it "returns allocated integer" do
|
47
|
-
subject.allocate.should == 1
|
48
|
-
subject.allocate.should == 2
|
49
|
-
subject.allocate.should == 3
|
50
|
-
subject.allocate.should == 4
|
51
|
-
|
52
|
-
subject.allocate.should == -1
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context "when integer in the range IS NOT available" do
|
57
|
-
it "returns -1" do
|
58
|
-
4.times { subject.allocate }
|
59
|
-
|
60
|
-
subject.allocate.should == -1
|
61
|
-
subject.allocate.should == -1
|
62
|
-
subject.allocate.should == -1
|
63
|
-
subject.allocate.should == -1
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
describe "#free" do
|
70
|
-
context "when the integer WAS allocated" do
|
71
|
-
it "returns frees that integer" do
|
72
|
-
4.times { subject.allocate }
|
73
|
-
subject.allocate.should == -1
|
74
|
-
|
75
|
-
subject.free(1)
|
76
|
-
subject.allocate.should == 1
|
77
|
-
subject.allocate.should == -1
|
78
|
-
subject.free(2)
|
79
|
-
subject.allocate.should == 2
|
80
|
-
subject.allocate.should == -1
|
81
|
-
subject.free(3)
|
82
|
-
subject.allocate.should == 3
|
83
|
-
subject.allocate.should == -1
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
context "when the integer WAS NOT allocated" do
|
88
|
-
it "has no effect" do
|
89
|
-
32.times { subject.free(1) }
|
90
|
-
subject.allocate.should == 1
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
|
96
|
-
describe "#allocated?" do
|
97
|
-
context "when given position WAS allocated" do
|
98
|
-
it "returns true" do
|
99
|
-
3.times { subject.allocate }
|
100
|
-
|
101
|
-
subject.allocated?(1).should be_true
|
102
|
-
subject.allocated?(2).should be_true
|
103
|
-
subject.allocated?(3).should be_true
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
context "when given position WAS NOT allocated" do
|
108
|
-
it "returns false" do
|
109
|
-
2.times { subject.allocate }
|
110
|
-
|
111
|
-
subject.allocated?(3).should be_false
|
112
|
-
subject.allocated?(4).should be_false
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|