cql-rb 2.0.0.pre0 → 2.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -2
  3. data/lib/cql.rb +8 -3
  4. data/lib/cql/client.rb +21 -356
  5. data/lib/cql/client/authenticators.rb +70 -0
  6. data/lib/cql/client/batch.rb +54 -0
  7. data/lib/cql/client/{asynchronous_client.rb → client.rb} +241 -6
  8. data/lib/cql/client/connector.rb +3 -2
  9. data/lib/cql/client/{asynchronous_prepared_statement.rb → prepared_statement.rb} +103 -0
  10. data/lib/cql/protocol.rb +1 -2
  11. data/lib/cql/protocol/cql_byte_buffer.rb +285 -0
  12. data/lib/cql/protocol/cql_protocol_handler.rb +3 -3
  13. data/lib/cql/protocol/frame_decoder.rb +3 -3
  14. data/lib/cql/protocol/frame_encoder.rb +2 -2
  15. data/lib/cql/protocol/request.rb +0 -2
  16. data/lib/cql/protocol/requests/auth_response_request.rb +2 -2
  17. data/lib/cql/protocol/requests/batch_request.rb +10 -10
  18. data/lib/cql/protocol/requests/credentials_request.rb +2 -2
  19. data/lib/cql/protocol/requests/execute_request.rb +13 -13
  20. data/lib/cql/protocol/requests/options_request.rb +2 -2
  21. data/lib/cql/protocol/requests/prepare_request.rb +2 -2
  22. data/lib/cql/protocol/requests/query_request.rb +13 -13
  23. data/lib/cql/protocol/requests/register_request.rb +2 -2
  24. data/lib/cql/protocol/requests/startup_request.rb +2 -2
  25. data/lib/cql/protocol/response.rb +2 -4
  26. data/lib/cql/protocol/responses/auth_challenge_response.rb +2 -2
  27. data/lib/cql/protocol/responses/auth_success_response.rb +2 -2
  28. data/lib/cql/protocol/responses/authenticate_response.rb +2 -2
  29. data/lib/cql/protocol/responses/detailed_error_response.rb +15 -15
  30. data/lib/cql/protocol/responses/error_response.rb +4 -4
  31. data/lib/cql/protocol/responses/event_response.rb +3 -3
  32. data/lib/cql/protocol/responses/prepared_result_response.rb +4 -4
  33. data/lib/cql/protocol/responses/raw_rows_result_response.rb +1 -1
  34. data/lib/cql/protocol/responses/ready_response.rb +1 -1
  35. data/lib/cql/protocol/responses/result_response.rb +3 -3
  36. data/lib/cql/protocol/responses/rows_result_response.rb +22 -22
  37. data/lib/cql/protocol/responses/schema_change_event_response.rb +2 -2
  38. data/lib/cql/protocol/responses/schema_change_result_response.rb +2 -2
  39. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +2 -2
  40. data/lib/cql/protocol/responses/status_change_event_response.rb +2 -2
  41. data/lib/cql/protocol/responses/supported_response.rb +2 -2
  42. data/lib/cql/protocol/responses/void_result_response.rb +1 -1
  43. data/lib/cql/protocol/type_converter.rb +78 -81
  44. data/lib/cql/time_uuid.rb +6 -0
  45. data/lib/cql/uuid.rb +2 -1
  46. data/lib/cql/version.rb +1 -1
  47. data/spec/cql/client/batch_spec.rb +8 -8
  48. data/spec/cql/client/{asynchronous_client_spec.rb → client_spec.rb} +162 -0
  49. data/spec/cql/client/connector_spec.rb +13 -3
  50. data/spec/cql/client/{asynchronous_prepared_statement_spec.rb → prepared_statement_spec.rb} +148 -1
  51. data/spec/cql/client/request_runner_spec.rb +2 -2
  52. data/spec/cql/protocol/cql_byte_buffer_spec.rb +895 -0
  53. data/spec/cql/protocol/cql_protocol_handler_spec.rb +1 -1
  54. data/spec/cql/protocol/frame_decoder_spec.rb +14 -14
  55. data/spec/cql/protocol/frame_encoder_spec.rb +7 -7
  56. data/spec/cql/protocol/requests/auth_response_request_spec.rb +4 -4
  57. data/spec/cql/protocol/requests/batch_request_spec.rb +21 -21
  58. data/spec/cql/protocol/requests/credentials_request_spec.rb +2 -2
  59. data/spec/cql/protocol/requests/execute_request_spec.rb +13 -13
  60. data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
  61. data/spec/cql/protocol/requests/prepare_request_spec.rb +2 -2
  62. data/spec/cql/protocol/requests/query_request_spec.rb +13 -13
  63. data/spec/cql/protocol/requests/register_request_spec.rb +2 -2
  64. data/spec/cql/protocol/requests/startup_request_spec.rb +4 -4
  65. data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +5 -5
  66. data/spec/cql/protocol/responses/auth_success_response_spec.rb +5 -5
  67. data/spec/cql/protocol/responses/authenticate_response_spec.rb +3 -3
  68. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +15 -15
  69. data/spec/cql/protocol/responses/error_response_spec.rb +5 -5
  70. data/spec/cql/protocol/responses/event_response_spec.rb +8 -8
  71. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +7 -7
  72. data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +1 -1
  73. data/spec/cql/protocol/responses/ready_response_spec.rb +2 -2
  74. data/spec/cql/protocol/responses/result_response_spec.rb +16 -16
  75. data/spec/cql/protocol/responses/rows_result_response_spec.rb +21 -21
  76. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +3 -3
  77. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +3 -3
  78. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +2 -2
  79. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +3 -3
  80. data/spec/cql/protocol/responses/supported_response_spec.rb +3 -3
  81. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +3 -3
  82. data/spec/cql/protocol/responses/void_result_response_spec.rb +2 -2
  83. data/spec/cql/protocol/type_converter_spec.rb +25 -13
  84. data/spec/cql/time_uuid_spec.rb +17 -4
  85. data/spec/cql/uuid_spec.rb +5 -1
  86. data/spec/integration/protocol_spec.rb +48 -42
  87. data/spec/spec_helper.rb +0 -1
  88. metadata +27 -39
  89. data/lib/cql/byte_buffer.rb +0 -177
  90. data/lib/cql/client/synchronous_client.rb +0 -79
  91. data/lib/cql/client/synchronous_prepared_statement.rb +0 -63
  92. data/lib/cql/future.rb +0 -515
  93. data/lib/cql/io.rb +0 -15
  94. data/lib/cql/io/connection.rb +0 -220
  95. data/lib/cql/io/io_reactor.rb +0 -349
  96. data/lib/cql/protocol/decoding.rb +0 -187
  97. data/lib/cql/protocol/encoding.rb +0 -114
  98. data/spec/cql/byte_buffer_spec.rb +0 -337
  99. data/spec/cql/client/synchronous_client_spec.rb +0 -170
  100. data/spec/cql/client/synchronous_prepared_statement_spec.rb +0 -155
  101. data/spec/cql/future_spec.rb +0 -737
  102. data/spec/cql/io/connection_spec.rb +0 -484
  103. data/spec/cql/io/io_reactor_spec.rb +0 -402
  104. data/spec/cql/protocol/decoding_spec.rb +0 -547
  105. data/spec/cql/protocol/encoding_spec.rb +0 -386
  106. data/spec/integration/io_spec.rb +0 -283
  107. data/spec/support/fake_server.rb +0 -106
@@ -1,187 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'bigdecimal'
4
-
5
-
6
- module Cql
7
- module Protocol
8
- module Decoding
9
- extend self
10
-
11
- def read_byte!(buffer)
12
- buffer.read_byte
13
- rescue RangeError => e
14
- raise DecodingError, e.message, e.backtrace
15
- end
16
-
17
- def read_varint!(buffer, length=buffer.length, signed=true)
18
- bytes = buffer.read(length)
19
- n = 0
20
- bytes.each_byte do |b|
21
- n = (n << 8) | b
22
- end
23
- if signed && bytes.getbyte(0) & 0x80 == 0x80
24
- n -= 2**(bytes.length * 8)
25
- end
26
- n
27
- rescue RangeError => e
28
- raise DecodingError, e.message, e.backtrace
29
- end
30
-
31
- def read_decimal!(buffer, length=buffer.length)
32
- size = read_int!(buffer)
33
- number_string = read_varint!(buffer, length - 4).to_s
34
- if number_string.length < size
35
- if number_string.start_with?(MINUS)
36
- number_string = number_string[1, number_string.length - 1]
37
- fraction_string = MINUS + ZERO << DECIMAL_POINT
38
- else
39
- fraction_string = ZERO + DECIMAL_POINT
40
- end
41
- (size - number_string.length).times { fraction_string << ZERO }
42
- fraction_string << number_string
43
- else
44
- fraction_string = number_string[0, number_string.length - size]
45
- fraction_string << DECIMAL_POINT
46
- fraction_string << number_string[number_string.length - size, number_string.length]
47
- end
48
- BigDecimal.new(fraction_string)
49
- rescue DecodingError => e
50
- raise DecodingError, e.message, e.backtrace
51
- end
52
-
53
- def read_long!(buffer)
54
- top, bottom = buffer.read(8).unpack(Formats::TWO_INTS_FORMAT)
55
- return (top << 32) | bottom if top <= 0x7fffffff
56
- top ^= 0xffffffff
57
- bottom ^= 0xffffffff
58
- -((top << 32) | bottom) - 1
59
- rescue RangeError => e
60
- raise DecodingError, e.message, e.backtrace
61
- end
62
-
63
- def read_double!(buffer)
64
- buffer.read(8).unpack(Formats::DOUBLE_FORMAT).first
65
- rescue RangeError => e
66
- raise DecodingError, "Not enough bytes available to decode a double: #{e.message}", e.backtrace
67
- end
68
-
69
- def read_float!(buffer)
70
- buffer.read(4).unpack(Formats::FLOAT_FORMAT).first
71
- rescue RangeError => e
72
- raise DecodingError, "Not enough bytes available to decode a float: #{e.message}", e.backtrace
73
- end
74
-
75
- def read_int!(buffer)
76
- n = buffer.read_int
77
- return n if n <= 0x7fffffff
78
- n - 0xffffffff - 1
79
- rescue RangeError => e
80
- raise DecodingError, "Not enough bytes available to decode an int: #{e.message}", e.backtrace
81
- end
82
-
83
- def read_short!(buffer)
84
- buffer.read_short
85
- rescue RangeError => e
86
- raise DecodingError, "Not enough bytes available to decode a short: #{e.message}", e.backtrace
87
- end
88
-
89
- def read_string!(buffer)
90
- length = read_short!(buffer)
91
- string = buffer.read(length)
92
- string.force_encoding(::Encoding::UTF_8)
93
- string
94
- rescue RangeError => e
95
- raise DecodingError, "Not enough bytes available to decode a string: #{e.message}", e.backtrace
96
- end
97
-
98
- def read_long_string!(buffer)
99
- length = read_int!(buffer)
100
- string = buffer.read(length)
101
- string.force_encoding(::Encoding::UTF_8)
102
- string
103
- rescue RangeError => e
104
- raise DecodingError, "Not enough bytes available to decode a long string: #{e.message}", e.backtrace
105
- end
106
-
107
- def read_uuid!(buffer, impl=Uuid)
108
- impl.new(read_varint!(buffer, 16, false))
109
- rescue DecodingError => e
110
- raise DecodingError, "Not enough bytes available to decode a UUID: #{e.message}", e.backtrace
111
- end
112
-
113
- def read_string_list!(buffer)
114
- size = read_short!(buffer)
115
- size.times.map do
116
- read_string!(buffer)
117
- end
118
- end
119
-
120
- def read_bytes!(buffer)
121
- size = read_int!(buffer)
122
- return nil if size & 0x80000000 == 0x80000000
123
- buffer.read(size)
124
- rescue RangeError => e
125
- raise DecodingError, "Not enough bytes available to decode a bytes: #{e.message}", e.backtrace
126
- end
127
-
128
- def read_short_bytes!(buffer)
129
- size = read_short!(buffer)
130
- return nil if size & 0x8000 == 0x8000
131
- buffer.read(size)
132
- rescue RangeError => e
133
- raise DecodingError, "Not enough bytes available to decode a short bytes: #{e.message}", e.backtrace
134
- end
135
-
136
- def read_option!(buffer)
137
- id = read_short!(buffer)
138
- value = nil
139
- if block_given?
140
- value = yield id, buffer
141
- end
142
- [id, value]
143
- end
144
-
145
- def read_inet!(buffer)
146
- size = read_byte!(buffer)
147
- ip_addr = IPAddr.new_ntoh(buffer.read(size))
148
- port = read_int!(buffer)
149
- [ip_addr, port]
150
- rescue RangeError => e
151
- raise DecodingError, "Not enough bytes available to decode an INET: #{e.message}", e.backtrace
152
- end
153
-
154
- def read_consistency!(buffer)
155
- index = read_short!(buffer)
156
- raise DecodingError, "Unknown consistency index #{index}" if index >= CONSISTENCIES.size || CONSISTENCIES[index].nil?
157
- CONSISTENCIES[index]
158
- end
159
-
160
- def read_string_map!(buffer)
161
- map = {}
162
- map_size = read_short!(buffer)
163
- map_size.times do
164
- key = read_string!(buffer)
165
- map[key] = read_string!(buffer)
166
- end
167
- map
168
- end
169
-
170
- def read_string_multimap!(buffer)
171
- map = {}
172
- map_size = read_short!(buffer)
173
- map_size.times do
174
- key = read_string!(buffer)
175
- map[key] = read_string_list!(buffer)
176
- end
177
- map
178
- end
179
-
180
- private
181
-
182
- MINUS = '-'.freeze
183
- ZERO = '0'.freeze
184
- DECIMAL_POINT = '.'.freeze
185
- end
186
- end
187
- end
@@ -1,114 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Cql
4
- module Protocol
5
- module Encoding
6
- extend self
7
-
8
- def write_int(buffer, n)
9
- buffer << [n].pack(Formats::INT_FORMAT)
10
- end
11
-
12
- def write_short(buffer, n)
13
- buffer << [n].pack(Formats::SHORT_FORMAT)
14
- end
15
-
16
- def write_string(buffer, str)
17
- str = str.to_s
18
- buffer << [str.bytesize].pack(Formats::SHORT_FORMAT)
19
- buffer << str
20
- buffer
21
- end
22
-
23
- def write_long_string(buffer, str)
24
- buffer << [str.bytesize].pack(Formats::INT_FORMAT)
25
- buffer << str
26
- buffer
27
- end
28
-
29
- def write_uuid(buffer, uuid)
30
- v = uuid.value
31
- write_int(buffer, (v >> 96) & 0xffffffff)
32
- write_int(buffer, (v >> 64) & 0xffffffff)
33
- write_int(buffer, (v >> 32) & 0xffffffff)
34
- write_int(buffer, v & 0xffffffff)
35
- end
36
-
37
- def write_string_list(buffer, strs)
38
- buffer << [strs.size].pack(Formats::SHORT_FORMAT)
39
- strs.each do |str|
40
- write_string(buffer, str)
41
- end
42
- buffer
43
- end
44
-
45
- def write_bytes(buffer, bytes)
46
- if bytes
47
- write_int(buffer, bytes.bytesize)
48
- buffer << bytes
49
- else
50
- write_int(buffer, -1)
51
- end
52
- buffer
53
- end
54
-
55
- def write_short_bytes(buffer, bytes)
56
- if bytes
57
- write_short(buffer, bytes.bytesize)
58
- buffer << bytes
59
- else
60
- write_short(buffer, -1)
61
- end
62
- buffer
63
- end
64
-
65
- def write_consistency(buffer, consistency)
66
- index = CONSISTENCIES.index(consistency)
67
- raise EncodingError, %(Unknown consistency "#{consistency}") if index.nil? || CONSISTENCIES[index].nil?
68
- write_short(buffer, index)
69
- end
70
-
71
- def write_string_map(buffer, map)
72
- buffer << [map.size].pack(Formats::SHORT_FORMAT)
73
- map.each do |key, value|
74
- write_string(buffer, key)
75
- write_string(buffer, value)
76
- end
77
- buffer
78
- end
79
-
80
- def write_long(buffer, n)
81
- top = n >> 32
82
- bottom = n & 0xffffffff
83
- write_int(buffer, top)
84
- write_int(buffer, bottom)
85
- end
86
-
87
- def write_varint(buffer, n)
88
- num = n
89
- bytes = []
90
- until num == 0 || num == -1
91
- bytes << (num & 0xff)
92
- num = num >> 8
93
- end
94
- buffer << bytes.reverse.pack(Formats::BYTES_FORMAT)
95
- end
96
-
97
- def write_decimal(buffer, n)
98
- sign, number_string, _, size = n.split
99
- num = number_string.to_i
100
- raw = write_varint('', num)
101
- write_int(buffer, number_string.length - size)
102
- buffer << raw
103
- end
104
-
105
- def write_double(buffer, n)
106
- buffer << [n].pack(Formats::DOUBLE_FORMAT)
107
- end
108
-
109
- def write_float(buffer, n)
110
- buffer << [n].pack(Formats::FLOAT_FORMAT)
111
- end
112
- end
113
- end
114
- end
@@ -1,337 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
-
6
- module Cql
7
- describe ByteBuffer do
8
- let :buffer do
9
- described_class.new
10
- end
11
-
12
- describe '#initialize' do
13
- it 'can be inititialized empty' do
14
- described_class.new.should be_empty
15
- end
16
-
17
- it 'can be initialized with bytes' do
18
- described_class.new('hello').length.should == 5
19
- end
20
- end
21
-
22
- describe '#length/#size/#bytesize' do
23
- it 'returns the number of bytes in the buffer' do
24
- buffer << 'foo'
25
- buffer.length.should == 3
26
- end
27
-
28
- it 'is zero initially' do
29
- buffer.length.should == 0
30
- end
31
-
32
- it 'is aliased as #size' do
33
- buffer << 'foo'
34
- buffer.size.should == 3
35
- end
36
-
37
- it 'is aliased as #bytesize' do
38
- buffer << 'foo'
39
- buffer.bytesize.should == 3
40
- end
41
- end
42
-
43
- describe '#empty?' do
44
- it 'is true initially' do
45
- buffer.should be_empty
46
- end
47
-
48
- it 'is false when there are bytes in the buffer' do
49
- buffer << 'foo'
50
- buffer.should_not be_empty
51
- end
52
- end
53
-
54
- describe '#append/#<<' do
55
- it 'adds bytes to the buffer' do
56
- buffer.append('foo')
57
- buffer.should_not be_empty
58
- end
59
-
60
- it 'can be used as <<' do
61
- buffer << 'foo'
62
- buffer.should_not be_empty
63
- end
64
-
65
- it 'returns itself' do
66
- buffer.append('foo').should eql(buffer)
67
- end
68
-
69
- it 'stores its bytes as binary' do
70
- buffer.append('hällö').length.should == 7
71
- buffer.to_s.encoding.should == ::Encoding::BINARY
72
- end
73
-
74
- it 'handles appending with multibyte strings' do
75
- buffer.append('hello')
76
- buffer.append('würld')
77
- buffer.to_s.should == 'hellowürld'.force_encoding(::Encoding::BINARY)
78
- end
79
-
80
- it 'handles appending with another byte buffer' do
81
- buffer.append('hello ').append(ByteBuffer.new('world'))
82
- buffer.to_s.should == 'hello world'
83
- end
84
- end
85
-
86
- describe '#eql?' do
87
- it 'is equal to another buffer with the same contents' do
88
- b1 = described_class.new
89
- b2 = described_class.new
90
- b1.append('foo')
91
- b2.append('foo')
92
- b1.should eql(b2)
93
- end
94
-
95
- it 'is not equal to another buffer with other contents' do
96
- b1 = described_class.new
97
- b2 = described_class.new
98
- b1.append('foo')
99
- b2.append('bar')
100
- b1.should_not eql(b2)
101
- end
102
-
103
- it 'is aliased as #==' do
104
- b1 = described_class.new
105
- b2 = described_class.new
106
- b1.append('foo')
107
- b2.append('foo')
108
- b1.should == b2
109
- end
110
-
111
- it 'is equal to another buffer when both are empty' do
112
- b1 = described_class.new
113
- b2 = described_class.new
114
- b1.should eql(b2)
115
- end
116
- end
117
-
118
- describe '#hash' do
119
- it 'has the same hash code as another buffer with the same contents' do
120
- b1 = described_class.new
121
- b2 = described_class.new
122
- b1.append('foo')
123
- b2.append('foo')
124
- b1.hash.should == b2.hash
125
- end
126
-
127
- it 'is not equal to the hash code of another buffer with other contents' do
128
- b1 = described_class.new
129
- b2 = described_class.new
130
- b1.append('foo')
131
- b2.append('bar')
132
- b1.hash.should_not == b2.hash
133
- end
134
-
135
- it 'is equal to the hash code of another buffer when both are empty' do
136
- b1 = described_class.new
137
- b2 = described_class.new
138
- b1.hash.should == b2.hash
139
- end
140
- end
141
-
142
- describe '#to_s' do
143
- it 'returns the bytes' do
144
- buffer.append('hello world').to_s.should == 'hello world'
145
- end
146
- end
147
-
148
- describe '#to_str' do
149
- it 'returns the bytes' do
150
- buffer.append('hello world').to_str.should == 'hello world'
151
- end
152
- end
153
-
154
- describe '#inspect' do
155
- it 'returns the bytes wrapped in ByteBuffer(...)' do
156
- buffer.append("\xca\xfe")
157
- buffer.inspect.should == '#<Cql::ByteBuffer: "\xCA\xFE">'
158
- end
159
- end
160
-
161
- describe '#discard' do
162
- it 'discards the specified number of bytes from the front of the buffer' do
163
- buffer.append('hello world')
164
- buffer.discard(4)
165
- buffer.should == ByteBuffer.new('o world')
166
- end
167
-
168
- it 'returns the byte buffer' do
169
- buffer.append('hello world')
170
- buffer.discard(4).should == ByteBuffer.new('o world')
171
- end
172
-
173
- it 'raises an error if the number of bytes in the buffer is fewer than the number to discard' do
174
- expect { buffer.discard(1) }.to raise_error(RangeError)
175
- buffer.append('hello')
176
- expect { buffer.discard(7) }.to raise_error(RangeError)
177
- end
178
- end
179
-
180
- describe '#read' do
181
- it 'returns the specified number of bytes, as a string' do
182
- buffer.append('hello')
183
- buffer.read(4).should == 'hell'
184
- end
185
-
186
- it 'removes the bytes from the buffer' do
187
- buffer.append('hello')
188
- buffer.read(3)
189
- buffer.should == ByteBuffer.new('lo')
190
- buffer.read(2).should == 'lo'
191
- end
192
-
193
- it 'raises an error if there are not enough bytes' do
194
- buffer.append('hello')
195
- expect { buffer.read(23423543) }.to raise_error(RangeError)
196
- expect { buffer.discard(5).read(1) }.to raise_error(RangeError)
197
- end
198
-
199
- it 'returns a string with binary encoding' do
200
- buffer.append('hello')
201
- buffer.read(4).encoding.should == ::Encoding::BINARY
202
- buffer.append('∆')
203
- buffer.read(2).encoding.should == ::Encoding::BINARY
204
- end
205
- end
206
-
207
- describe '#read_int' do
208
- it 'returns the first four bytes interpreted as an int' do
209
- buffer.append("\xca\xfe\xba\xbe\x01")
210
- buffer.read_int.should == 0xcafebabe
211
- end
212
-
213
- it 'removes the bytes from the buffer' do
214
- buffer.append("\xca\xfe\xba\xbe\x01")
215
- buffer.read_int
216
- buffer.should == ByteBuffer.new("\x01")
217
- end
218
-
219
- it 'raises an error if there are not enough bytes' do
220
- buffer.append("\xca\xfe\xba")
221
- expect { buffer.read_int }.to raise_error(RangeError)
222
- end
223
- end
224
-
225
- describe '#read_short' do
226
- it 'returns the first two bytes interpreted as a short' do
227
- buffer.append("\xca\xfe\x01")
228
- buffer.read_short.should == 0xcafe
229
- end
230
-
231
- it 'removes the bytes from the buffer' do
232
- buffer.append("\xca\xfe\x01")
233
- buffer.read_short
234
- buffer.should == ByteBuffer.new("\x01")
235
- end
236
-
237
- it 'raises an error if there are not enough bytes' do
238
- buffer.append("\xca")
239
- expect { buffer.read_short }.to raise_error(RangeError)
240
- end
241
- end
242
-
243
- describe '#read_byte' do
244
- it 'returns the first bytes interpreted as an int' do
245
- buffer.append("\x10\x01")
246
- buffer.read_byte.should == 0x10
247
- buffer.read_byte.should == 0x01
248
- end
249
-
250
- it 'removes the byte from the buffer' do
251
- buffer.append("\x10\x01")
252
- buffer.read_byte
253
- buffer.should == ByteBuffer.new("\x01")
254
- end
255
-
256
- it 'raises an error if there are no bytes' do
257
- expect { buffer.read_byte }.to raise_error(RangeError)
258
- end
259
-
260
- it 'can interpret the byte as signed' do
261
- buffer.append("\x81\x02")
262
- buffer.read_byte(true).should == -127
263
- buffer.read_byte(true).should == 2
264
- end
265
- end
266
-
267
- describe '#update' do
268
- it 'changes the bytes at the specified location' do
269
- buffer.append('foo bar')
270
- buffer.update(4, 'baz')
271
- buffer.to_s.should == 'foo baz'
272
- end
273
-
274
- it 'handles updates after a read' do
275
- buffer.append('foo bar')
276
- buffer.read(1)
277
- buffer.update(3, 'baz')
278
- buffer.to_s.should == 'oo baz'
279
- end
280
-
281
- it 'handles updates after multiple reads and appends' do
282
- buffer.append('foo bar')
283
- buffer.read(1)
284
- buffer.append('x')
285
- buffer.update(4, 'baz')
286
- buffer.append('yyyy')
287
- buffer.read(1)
288
- buffer.to_s.should == 'o bbazyyyy'
289
- end
290
- end
291
-
292
- describe '#dup' do
293
- it 'returns a copy' do
294
- buffer.append('hello world')
295
- copy = buffer.dup
296
- copy.should eql(buffer)
297
- end
298
-
299
- it 'returns a copy which can be modified without modifying the original' do
300
- buffer.append('hello world')
301
- copy = buffer.dup
302
- copy.append('goodbye')
303
- copy.should_not eql(buffer)
304
- end
305
- end
306
-
307
- describe '#cheap_peek' do
308
- it 'returns a prefix of the buffer' do
309
- buffer.append('foo')
310
- buffer.append('bar')
311
- buffer.read_byte
312
- buffer.append('hello')
313
- x = buffer.cheap_peek
314
- x.bytesize.should be > 0
315
- x.bytesize.should be <= buffer.bytesize
316
- buffer.to_str.should start_with(x)
317
- end
318
- end
319
-
320
- context 'when reading and appending' do
321
- it 'handles heavy churn' do
322
- 1000.times do
323
- buffer.append('x' * 6)
324
- buffer.read_byte
325
- buffer.append('y')
326
- buffer.read_int
327
- buffer.read_short
328
- buffer.append('z' * 4)
329
- buffer.read_byte
330
- buffer.append('z')
331
- buffer.read_int
332
- buffer.should be_empty
333
- end
334
- end
335
- end
336
- end
337
- end