amqp 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|