cql-rb 1.1.3 → 1.2.0.pre0

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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -11
  3. data/lib/cql.rb +1 -0
  4. data/lib/cql/client.rb +41 -9
  5. data/lib/cql/client/asynchronous_client.rb +9 -4
  6. data/lib/cql/client/asynchronous_prepared_statement.rb +2 -2
  7. data/lib/cql/client/connection_helper.rb +43 -20
  8. data/lib/cql/client/execute_options_decoder.rb +4 -1
  9. data/lib/cql/client/query_result.rb +7 -3
  10. data/lib/cql/client/query_trace.rb +46 -0
  11. data/lib/cql/client/request_runner.rb +7 -2
  12. data/lib/cql/client/void_result.rb +42 -0
  13. data/lib/cql/compression.rb +53 -0
  14. data/lib/cql/compression/snappy_compressor.rb +42 -0
  15. data/lib/cql/io/io_reactor.rb +9 -4
  16. data/lib/cql/protocol.rb +5 -3
  17. data/lib/cql/protocol/cql_protocol_handler.rb +14 -9
  18. data/lib/cql/protocol/frame_decoder.rb +106 -0
  19. data/lib/cql/protocol/frame_encoder.rb +31 -0
  20. data/lib/cql/protocol/request.rb +7 -11
  21. data/lib/cql/protocol/requests/execute_request.rb +2 -2
  22. data/lib/cql/protocol/requests/options_request.rb +4 -0
  23. data/lib/cql/protocol/requests/prepare_request.rb +2 -2
  24. data/lib/cql/protocol/requests/query_request.rb +2 -2
  25. data/lib/cql/protocol/requests/startup_request.rb +12 -5
  26. data/lib/cql/protocol/response.rb +13 -2
  27. data/lib/cql/protocol/responses/authenticate_response.rb +5 -1
  28. data/lib/cql/protocol/responses/detailed_error_response.rb +2 -2
  29. data/lib/cql/protocol/responses/error_response.rb +7 -2
  30. data/lib/cql/protocol/responses/event_response.rb +4 -2
  31. data/lib/cql/protocol/responses/prepared_result_response.rb +20 -4
  32. data/lib/cql/protocol/responses/ready_response.rb +5 -1
  33. data/lib/cql/protocol/responses/result_response.rb +10 -2
  34. data/lib/cql/protocol/responses/rows_result_response.rb +5 -4
  35. data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
  36. data/lib/cql/protocol/responses/schema_change_result_response.rb +5 -4
  37. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +4 -3
  38. data/lib/cql/protocol/responses/{status_change_event_result_response.rb → status_change_event_response.rb} +1 -1
  39. data/lib/cql/protocol/responses/supported_response.rb +5 -1
  40. data/lib/cql/protocol/responses/{topology_change_event_result_response.rb → topology_change_event_response.rb} +0 -0
  41. data/lib/cql/protocol/responses/void_result_response.rb +2 -2
  42. data/lib/cql/version.rb +1 -1
  43. data/spec/cql/client/asynchronous_client_spec.rb +52 -31
  44. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +16 -2
  45. data/spec/cql/client/connection_helper_spec.rb +90 -12
  46. data/spec/cql/client/query_trace_spec.rb +138 -0
  47. data/spec/cql/client/request_runner_spec.rb +44 -7
  48. data/spec/cql/client/void_result_spec.rb +43 -0
  49. data/spec/cql/compression/compression_common.rb +59 -0
  50. data/spec/cql/compression/snappy_compressor_spec.rb +23 -0
  51. data/spec/cql/io/io_reactor_spec.rb +8 -1
  52. data/spec/cql/protocol/cql_protocol_handler_spec.rb +40 -0
  53. data/spec/cql/protocol/frame_decoder_spec.rb +132 -0
  54. data/spec/cql/protocol/frame_encoder_spec.rb +105 -0
  55. data/spec/cql/protocol/requests/credentials_request_spec.rb +2 -4
  56. data/spec/cql/protocol/requests/execute_request_spec.rb +5 -5
  57. data/spec/cql/protocol/requests/options_request_spec.rb +10 -4
  58. data/spec/cql/protocol/requests/prepare_request_spec.rb +3 -3
  59. data/spec/cql/protocol/requests/query_request_spec.rb +10 -5
  60. data/spec/cql/protocol/requests/register_request_spec.rb +3 -3
  61. data/spec/cql/protocol/requests/startup_request_spec.rb +11 -5
  62. data/spec/cql/protocol/responses/authenticate_response_spec.rb +27 -0
  63. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +78 -0
  64. data/spec/cql/protocol/responses/error_response_spec.rb +36 -0
  65. data/spec/cql/protocol/responses/event_response_spec.rb +40 -0
  66. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +108 -0
  67. data/spec/cql/protocol/responses/ready_response_spec.rb +39 -0
  68. data/spec/cql/protocol/responses/result_response_spec.rb +57 -0
  69. data/spec/cql/protocol/responses/rows_result_response_spec.rb +273 -0
  70. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +93 -0
  71. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +51 -19
  72. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +34 -0
  73. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +35 -0
  74. data/spec/cql/protocol/responses/supported_response_spec.rb +27 -0
  75. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +35 -0
  76. data/spec/cql/protocol/responses/void_result_response_spec.rb +29 -0
  77. data/spec/integration/client_spec.rb +45 -0
  78. data/spec/integration/protocol_spec.rb +46 -0
  79. data/spec/spec_helper.rb +2 -1
  80. data/spec/support/fake_io_reactor.rb +1 -1
  81. metadata +51 -10
  82. data/lib/cql/protocol/response_frame.rb +0 -129
  83. data/spec/cql/protocol/request_spec.rb +0 -45
  84. data/spec/cql/protocol/response_frame_spec.rb +0 -811
@@ -1,129 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Cql
4
- module Protocol
5
- class ResponseFrame
6
- def initialize(buffer=ByteBuffer.new)
7
- @headers = FrameHeaders.new(buffer)
8
- check_complete!
9
- end
10
-
11
- def stream_id
12
- @headers && @headers.stream_id
13
- end
14
-
15
- def header_length
16
- 8
17
- end
18
-
19
- def body_length
20
- @headers && @headers.length
21
- end
22
-
23
- def body
24
- @body.response
25
- end
26
-
27
- def complete?
28
- @body && @body.complete?
29
- end
30
-
31
- def <<(str)
32
- if @body
33
- @body << str
34
- else
35
- @headers << str
36
- check_complete!
37
- end
38
- end
39
-
40
- private
41
-
42
- def check_complete!
43
- if @headers.complete?
44
- @body = create_body
45
- end
46
- end
47
-
48
- def create_body
49
- body_type = begin
50
- case @headers.opcode
51
- when 0x00 then ErrorResponse
52
- when 0x02 then ReadyResponse
53
- when 0x03 then AuthenticateResponse
54
- when 0x06 then SupportedResponse
55
- when 0x08 then ResultResponse
56
- when 0x0c then EventResponse
57
- else
58
- raise UnsupportedOperationError, "The operation #{@headers.opcode} is not supported"
59
- end
60
- end
61
- FrameBody.new(@headers.buffer, @headers.length, body_type)
62
- end
63
-
64
- class FrameHeaders
65
- attr_reader :buffer, :protocol_version, :stream_id, :opcode, :length
66
-
67
- def initialize(buffer)
68
- @buffer = buffer
69
- check_complete!
70
- end
71
-
72
- def <<(str)
73
- @buffer << str
74
- check_complete!
75
- end
76
-
77
- def complete?
78
- !!@protocol_version
79
- end
80
-
81
- private
82
-
83
- def check_complete!
84
- if @buffer.length >= 8
85
- @protocol_version = @buffer.read_byte(true)
86
- @flags = @buffer.read_byte(true)
87
- @stream_id = @buffer.read_byte(true)
88
- @opcode = @buffer.read_byte(true)
89
- @length = @buffer.read_int
90
- raise UnsupportedFrameTypeError, 'Request frames are not supported' if @protocol_version > 0
91
- @protocol_version &= 0x7f
92
- end
93
- end
94
- end
95
-
96
- class FrameBody
97
- attr_reader :response, :buffer
98
-
99
- def initialize(buffer, length, type)
100
- @buffer = buffer
101
- @length = length
102
- @type = type
103
- check_complete!
104
- end
105
-
106
- def <<(str)
107
- @buffer << str
108
- check_complete!
109
- end
110
-
111
- def complete?
112
- !!@response
113
- end
114
-
115
- private
116
-
117
- def check_complete!
118
- if @buffer.length >= @length
119
- extra_length = @buffer.length - @length
120
- @response = @type.decode!(@buffer)
121
- if @buffer.length > extra_length
122
- @buffer.discard(@buffer.length - extra_length)
123
- end
124
- end
125
- end
126
- end
127
- end
128
- end
129
- end
@@ -1,45 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- require 'spec_helper'
4
-
5
-
6
- module Cql
7
- module Protocol
8
- describe Request do
9
- describe '#encode_frame' do
10
- it 'returns a rendered request frame for the specified channel' do
11
- encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3)
12
- encoded_frame.to_s.should == "\x01\x00\x03\x09\x00\x00\x00\x18\x00\x00\x00\x14SELECT * FROM things"
13
- end
14
-
15
- it 'appends a rendered request frame to the specified buffer' do
16
- buffer = ByteBuffer.new('hello')
17
- encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3, buffer)
18
- buffer.to_s.should == "hello\x01\x00\x03\x09\x00\x00\x00\x18\x00\x00\x00\x14SELECT * FROM things"
19
- end
20
-
21
- it 'returns the specified buffer' do
22
- buffer = ByteBuffer.new('hello')
23
- encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3, buffer)
24
- encoded_frame.should equal(buffer)
25
- end
26
- end
27
-
28
- describe '.change_stream_id' do
29
- it 'changes the stream ID byte' do
30
- buffer = ByteBuffer.new("\x01\x00\x03\x02\x00\x00\x00\x00")
31
- described_class.change_stream_id(99, buffer)
32
- buffer.discard(2)
33
- buffer.read_byte.should == 99
34
- end
35
-
36
- it 'changes the stream ID byte of the frame starting at the specified offset' do
37
- buffer = ByteBuffer.new("hello foo\x01\x00\x03\x02\x00\x00\x00\x00")
38
- described_class.change_stream_id(99, buffer, 9)
39
- buffer.discard(11)
40
- buffer.read_byte.should == 99
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,811 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- require 'spec_helper'
4
-
5
-
6
- module Cql
7
- module Protocol
8
- describe ResponseFrame do
9
- let :frame do
10
- described_class.new
11
- end
12
-
13
- context 'when fed no data' do
14
- it 'has a header length' do
15
- frame.header_length.should == 8
16
- end
17
-
18
- it 'has no body length' do
19
- frame.body_length.should be_nil
20
- end
21
-
22
- it 'is not complete' do
23
- frame.should_not be_complete
24
- end
25
- end
26
-
27
- context 'when fed a header' do
28
- before do
29
- frame << "\x81\x00\x00\x02\x00\x00\x00\x16"
30
- end
31
-
32
- it 'knows the frame body length' do
33
- frame.body_length.should == 22
34
- end
35
- end
36
-
37
- context 'when fed a header in pieces' do
38
- before do
39
- frame << "\x81\x00"
40
- frame << "\x00\x02\x00\x00\x00"
41
- frame << "\x16"
42
- end
43
-
44
- it 'knows the body length' do
45
- frame.body_length.should == 22
46
- end
47
-
48
- it 'knows the stream ID' do
49
- frame.stream_id.should == 0
50
- end
51
- end
52
-
53
- context 'when fed a header with a non-zero stream ID' do
54
- before do
55
- frame << "\x81\x00\x20\x02\x00\x00\x00\x16"
56
- end
57
-
58
- it 'knows the stream ID' do
59
- frame.stream_id.should == 0x20
60
- end
61
- end
62
-
63
- context 'when fed a header with the stream ID -1' do
64
- before do
65
- frame << "\x81\x00\xff\x02\x00\x00\x00\x16"
66
- end
67
-
68
- it 'knows the stream ID' do
69
- frame.stream_id.should == -1
70
- end
71
- end
72
-
73
- context 'when fed a request frame header' do
74
- it 'raises an UnsupportedFrameTypeError' do
75
- expect { frame << "\x01\x00\x00\x00\x00\x00\x00\x00" }.to raise_error(UnsupportedFrameTypeError)
76
- end
77
- end
78
-
79
- context 'when fed a request frame header' do
80
- it 'raises an UnsupportedFrameTypeError' do
81
- expect { frame << "\x01\x00\x00\x00\x00\x00\x00\x00" }.to raise_error(UnsupportedFrameTypeError)
82
- end
83
- end
84
-
85
- context 'when fed a header and a partial body' do
86
- before do
87
- frame << "\x81\x00"
88
- frame << "\x00\x06"
89
- frame << "\x00\x00\x00\x16"
90
- frame << [rand(255), rand(255), rand(255), rand(255), rand(255), rand(255), rand(255), rand(255)].pack('C')
91
- end
92
-
93
- it 'knows the body length' do
94
- frame.body_length.should == 22
95
- end
96
-
97
- it 'is not complete' do
98
- frame.should_not be_complete
99
- end
100
- end
101
-
102
- context 'when fed a complete ERROR frame' do
103
- before do
104
- frame << "\x81\x00\x00\x00\x00\x00\x00V\x00\x00\x00\n\x00PProvided version 4.0.0 is not supported by this server (supported: 2.0.0, 3.0.0)"
105
- end
106
-
107
- it 'is complete' do
108
- frame.should be_complete
109
- end
110
-
111
- it 'has an error code' do
112
- frame.body.code.should == 10
113
- end
114
-
115
- it 'has an error message' do
116
- frame.body.message.should == 'Provided version 4.0.0 is not supported by this server (supported: 2.0.0, 3.0.0)'
117
- end
118
-
119
- it 'has a pretty #to_s representation' do
120
- frame.body.to_s.should == 'ERROR 10 "Provided version 4.0.0 is not supported by this server (supported: 2.0.0, 3.0.0)"'
121
- end
122
- end
123
-
124
- context 'when fed an ERROR frame with details' do
125
- it 'has more details for a unavailable error' do
126
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x10\x00\x00\x0cUnavailable!\x00\x05\x00\x00\x00\x03\x00\x00\x00\x02"))
127
- frame.body.details.should == {
128
- :cl => :all,
129
- :required => 3,
130
- :alive => 2
131
- }
132
- end
133
-
134
- it 'has more details for a write_timeout error' do
135
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00K\x00\x00\x11\x00\x000Operation timed out - received only 0 responses.\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\tBATCH_LOG"))
136
- frame.body.details.should == {
137
- :cl => :one,
138
- :received => 0,
139
- :blockfor => 1,
140
- :write_type => 'BATCH_LOG'
141
- }
142
- end
143
-
144
- it 'has more details for a read_timeout error' do
145
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00\x25\x00\x00\x12\x00\x00\x14Operation timed out.\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01"))
146
- frame.body.details.should == {
147
- :cl => :one,
148
- :received => 0,
149
- :blockfor => 1,
150
- :data_present => true
151
- }
152
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00\x25\x00\x00\x12\x00\x00\x14Operation timed out.\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00"))
153
- frame.body.details.should == {
154
- :cl => :one,
155
- :received => 0,
156
- :blockfor => 1,
157
- :data_present => false
158
- }
159
- end
160
-
161
- it 'has more details for an already_exists error with a keyspace' do
162
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x24\x00\x00\x10Keyspace exists!\x00\x05stuff\x00\x00"))
163
- frame.body.details.should == {
164
- :ks => 'stuff',
165
- :table => '',
166
- }
167
- end
168
-
169
- it 'has more details for an already_exists error with a keyspace and table' do
170
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00\x24\x00\x00\x24\x00\x00\x10Keyspace exists!\x00\x05stuff\x00\x06things"))
171
- frame.body.details.should == {
172
- :ks => 'stuff',
173
- :table => 'things',
174
- }
175
- end
176
-
177
- it 'has more details for an unprepared error' do
178
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00\x33\x00\x00\x25\x00\x00\x1bUnknown prepared statement!\x00\x10\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/"))
179
- frame.body.details.should == {
180
- :id => "\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/"
181
- }
182
- end
183
-
184
- it 'has a pretty #to_s representation' do
185
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\x00\x00\x00\x00\x33\x00\x00\x25\x00\x00\x1bUnknown prepared statement!\x00\x10\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/"))
186
- frame.body.to_s.should match(/^ERROR 9472 "Unknown prepared statement!" \{:id=>".+?"\}$/)
187
- end
188
- end
189
-
190
- context 'when fed a complete READY frame' do
191
- before do
192
- frame << [0x81, 0, 0, 0x02, 0].pack('C4N')
193
- end
194
-
195
- it 'is complete' do
196
- frame.should be_complete
197
- end
198
-
199
- it 'has a pretty #to_s representation' do
200
- frame.body.to_s.should == 'READY'
201
- end
202
- end
203
-
204
- context 'when fed a complete AUTHENTICATE frame' do
205
- before do
206
- frame << "\x81\x00\x00\x03\x00\x00\x001\x00/org.apache.cassandra.auth.PasswordAuthenticator"
207
- end
208
-
209
- it 'is complete' do
210
- frame.should be_complete
211
- end
212
-
213
- it 'has an authentication class' do
214
- frame.body.authentication_class.should == 'org.apache.cassandra.auth.PasswordAuthenticator'
215
- end
216
-
217
- it 'has a pretty #to_s representation' do
218
- frame.body.to_s.should == 'AUTHENTICATE org.apache.cassandra.auth.PasswordAuthenticator'
219
- end
220
- end
221
-
222
- context 'when fed a complete SUPPORTED frame' do
223
- before do
224
- frame << "\x81\x00\x00\x06\x00\x00\x00\x27"
225
- frame << "\x00\x02\x00\x0bCQL_VERSION\x00\x01\x00\x053.0.0\x00\x0bCOMPRESSION\x00\x00"
226
- end
227
-
228
- it 'is complete' do
229
- frame.should be_complete
230
- end
231
-
232
- it 'has options' do
233
- frame.body.options.should == {'CQL_VERSION' => ['3.0.0'], 'COMPRESSION' => []}
234
- end
235
-
236
- it 'has a pretty #to_s representation' do
237
- frame.body.to_s.should == 'SUPPORTED {"CQL_VERSION"=>["3.0.0"], "COMPRESSION"=>[]}'
238
- end
239
- end
240
-
241
- context 'when fed a complete RESULT frame' do
242
- context 'when it\'s a set_keyspace' do
243
- before do
244
- frame << "\x81\x00\x00\b\x00\x00\x00\f"
245
- frame << "\x00\x00\x00\x03\x00\x06system"
246
- end
247
-
248
- it 'has a keyspace' do
249
- frame.body.keyspace.should == 'system'
250
- end
251
-
252
- it 'is not void' do
253
- frame.body.should_not be_void
254
- end
255
-
256
- it 'has a pretty #to_s representation' do
257
- frame.body.to_s.should == 'RESULT SET_KEYSPACE "system"'
258
- end
259
- end
260
-
261
- context 'when it\'s a schema_change' do
262
- context 'when it\'s a keyspace change' do
263
- before do
264
- frame << "\x81\x00\x00\b\x00\x00\x00\e\x00\x00\x00\x05\x00\aCREATED\x00\ncql_rb_477\x00\x00"
265
- end
266
-
267
- it 'has a change description' do
268
- frame.body.change.should == 'CREATED'
269
- end
270
-
271
- it 'has a keyspace' do
272
- frame.body.keyspace.should == 'cql_rb_477'
273
- end
274
-
275
- it 'has no table' do
276
- frame.body.table.should be_empty
277
- end
278
-
279
- it 'is not void' do
280
- frame.body.should_not be_void
281
- end
282
-
283
- it 'has a pretty #to_s representation' do
284
- frame.body.to_s.should == 'RESULT SCHEMA_CHANGE CREATED "cql_rb_477" ""'
285
- end
286
- end
287
-
288
- context 'when it\'s a table change' do
289
- before do
290
- frame << "\x81\x00\x00\b\x00\x00\x00 \x00\x00\x00\x05\x00\aUPDATED\x00\ncql_rb_973\x00\x05users"
291
- end
292
-
293
- it 'has a change description' do
294
- frame.body.change.should == 'UPDATED'
295
- end
296
-
297
- it 'has a keyspace' do
298
- frame.body.keyspace.should == 'cql_rb_973'
299
- end
300
-
301
- it 'has a table' do
302
- frame.body.table.should == 'users'
303
- end
304
-
305
- it 'is not void' do
306
- frame.body.should_not be_void
307
- end
308
-
309
- it 'has a pretty #to_s representation' do
310
- frame.body.to_s.should == 'RESULT SCHEMA_CHANGE UPDATED "cql_rb_973" "users"'
311
- end
312
- end
313
- end
314
-
315
- context 'when it\'s a void' do
316
- before do
317
- frame << "\x81\x00\x00\b\x00\x00\x00\x04\x00\x00\x00\x01"
318
- end
319
-
320
- it 'is has a body' do
321
- frame.body.should_not be_nil
322
- end
323
-
324
- it 'is void' do
325
- frame.body.should be_void
326
- end
327
-
328
- it 'has a pretty #to_s representation' do
329
- frame.body.to_s.should == 'RESULT VOID'
330
- end
331
- end
332
-
333
- context 'when it\'s rows' do
334
- before do
335
- frame << "\x81\x00\x00\b\x00\x00\x00~\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\ncql_rb_126\x00\x05users\x00\tuser_name\x00\r\x00\x05email\x00\r\x00\bpassword\x00\r\x00\x00\x00\x02\x00\x00\x00\x04phil\x00\x00\x00\rphil@heck.com\xFF\xFF\xFF\xFF\x00\x00\x00\x03sue\x00\x00\x00\rsue@inter.net\xFF\xFF\xFF\xFF"
336
- end
337
-
338
- it 'has rows that are hashes of column name => column value' do
339
- frame.body.rows.should == [
340
- {'user_name' => 'phil', 'email' => 'phil@heck.com', 'password' => nil},
341
- {'user_name' => 'sue', 'email' => 'sue@inter.net', 'password' => nil}
342
- ]
343
- end
344
-
345
- it 'has column metadata' do
346
- frame.body.metadata.should == [
347
- ['cql_rb_126', 'users', 'user_name', :varchar],
348
- ['cql_rb_126', 'users', 'email', :varchar],
349
- ['cql_rb_126', 'users', 'password', :varchar]
350
- ]
351
- end
352
-
353
- it 'is not void' do
354
- frame.body.should_not be_void
355
- end
356
-
357
- it 'has a pretty #to_s representation' do
358
- frame.body.to_s.should == 'RESULT ROWS [["cql_rb_126", "users", "user_name", :varchar], ["cql_rb_126", "users", "email", :varchar], ["cql_rb_126", "users", "password", :varchar]] [{"user_name"=>"phil", "email"=>"phil@heck.com", "password"=>nil}, {"user_name"=>"sue", "email"=>"sue@inter.net", "password"=>nil}]'
359
- end
360
- end
361
-
362
- context 'when it\'s rows from different keyspaces' do
363
- before do
364
- # TODO: not sure if this is really how it would be for real
365
- # this frame was constructed from the spec not from an actual result
366
- frame << "\x81\x00\x00\b\x00\x00\x00\xa7"
367
- frame << "\x00\x00\x00\x02"
368
- frame << "\x00\x00\x00\x00"
369
- frame << "\x00\x00\x00\x03"
370
- frame << "\x00\ncql_rb_126\x00\x06users1\x00\tuser_name\x00\r"
371
- frame << "\x00\ncql_rb_127\x00\x06users2\x00\x05email\x00\r"
372
- frame << "\x00\ncql_rb_128\x00\x06users3\x00\bpassword\x00\r"
373
- frame << "\x00\x00\x00\x02\x00\x00\x00\x04phil\x00\x00\x00\rphil@heck.com\xFF\xFF\xFF\xFF\x00\x00\x00\x03sue\x00\x00\x00\rsue@inter.net\xFF\xFF\xFF\xFF"
374
- end
375
-
376
- it 'has rows that are hashes of column name => column value' do
377
- frame.body.rows.should == [
378
- {'user_name' => 'phil', 'email' => 'phil@heck.com', 'password' => nil},
379
- {'user_name' => 'sue', 'email' => 'sue@inter.net', 'password' => nil}
380
- ]
381
- end
382
-
383
- it 'has column metadata' do
384
- frame.body.metadata.should == [
385
- ['cql_rb_126', 'users1', 'user_name', :varchar],
386
- ['cql_rb_127', 'users2', 'email', :varchar],
387
- ['cql_rb_128', 'users3', 'password', :varchar]
388
- ]
389
- end
390
- end
391
-
392
- context 'when it\'s a prepared' do
393
- before do
394
- frame << "\x81\x00\x00\b\x00\x00\x00>"
395
- frame << "\x00\x00\x00\x04\x00\x10\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/\x00\x00\x00\x01\x00\x00\x00\x01\x00\ncql_rb_911\x00\x05users\x00\tuser_name\x00\r"
396
- end
397
-
398
- it 'has an id' do
399
- frame.body.id.should == "\xCAH\x7F\x1Ez\x82\xD2<N\x8A\xF35Qq\xA5/"
400
- end
401
-
402
- it 'has column metadata' do
403
- frame.body.metadata.should == [['cql_rb_911', 'users', 'user_name', :varchar]]
404
- end
405
-
406
- it 'has a pretty #to_s representation' do
407
- frame.body.to_s.should match(/^RESULT PREPARED [0-9a-f]{32} \[\["cql_rb_911", "users", "user_name", :varchar\]\]$/)
408
- end
409
- end
410
-
411
- context 'with different column types' do
412
- before do
413
- # The following test was created by intercepting the frame for the
414
- # SELECT statement in this CQL exchange
415
- #
416
- # CREATE TABLE lots_of_types (
417
- # ascii_column ASCII,
418
- # bigint_column BIGINT,
419
- # blob_column BLOB,
420
- # boolean_column BOOLEAN,
421
- # decimal_column DECIMAL,
422
- # double_column DOUBLE,
423
- # float_column FLOAT,
424
- # int_column INT,
425
- # text_column TEXT,
426
- # timestamp_column TIMESTAMP,
427
- # uuid_column UUID,
428
- # varchar_column VARCHAR,
429
- # varint_column VARINT,
430
- # timeuuid_column TIMEUUID,
431
- # inet_column INET,
432
- # list_column LIST<ASCII>,
433
- # map_column MAP<TEXT, BOOLEAN>,
434
- # set_column SET<BLOB>,
435
- #
436
- # PRIMARY KEY (ascii_column)
437
- # );
438
- #
439
- # INSERT INTO lots_of_types (ascii_column, bigint_column, blob_column, boolean_column, decimal_column, double_column, float_column, int_column, text_column, timestamp_column, uuid_column, varchar_column, varint_column, timeuuid_column, inet_column, list_column, map_column, set_column)
440
- # VALUES (
441
- # 'hello',
442
- # 1012312312414123,
443
- # 'fab45e3456',
444
- # true,
445
- # 1042342234234.123423435647768234,
446
- # 10000.123123123,
447
- # 12.13,
448
- # 12348098,
449
- # 'hello world',
450
- # 1358013521.123,
451
- # cfd66ccc-d857-4e90-b1e5-df98a3d40cd6,
452
- # 'foo',
453
- # 1231312312331283012830129382342342412123,
454
- # a4a70900-24e1-11df-8924-001ff3591711,
455
- # 167772418,
456
- # ['foo', 'foo', 'bar'],
457
- # {'foo': true, 'hello': false},
458
- # {'ab4321', 'afd87ecd'}
459
- # );
460
- #
461
- # SELECT * FROM lots_of_types WHERE ascii_column = 'hello';
462
-
463
- frame << "\x81\x00\x00\b\x00\x00\x02K"
464
- frame << "\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x12\x00\x04test\x00\rlots_of_types\x00\fascii_column\x00\x01\x00\rbigint_column\x00\x02\x00\vblob_column\x00\x03\x00\x0Eboolean_column\x00\x04\x00\x0Edecimal_column\x00\x06\x00\rdouble_column\x00\a\x00\ffloat_column\x00\b\x00\vinet_column\x00\x10\x00\nint_column\x00\t\x00\vlist_column\x00 \x00\x01\x00\nmap_column\x00!\x00\r\x00\x04\x00\nset_column\x00\"\x00\x03\x00\vtext_column\x00\r\x00\x10timestamp_column\x00\v\x00\x0Ftimeuuid_column\x00\x0F\x00\vuuid_column\x00\f\x00\x0Evarchar_column\x00\r\x00\rvarint_column\x00\x0E\x00\x00\x00\x01\x00\x00\x00\x05hello\x00\x00\x00\b\x00\x03\x98\xB1S\xC8\x7F\xAB\x00\x00\x00\x05\xFA\xB4^4V\x00\x00\x00\x01\x01\x00\x00\x00\x11\x00\x00\x00\x12\r'\xFDI\xAD\x80f\x11g\xDCfV\xAA\x00\x00\x00\b@\xC3\x88\x0F\xC2\x7F\x9DU\x00\x00\x00\x04AB\x14{\x00\x00\x00\x04\n\x00\x01\x02\x00\x00\x00\x04\x00\xBCj\xC2\x00\x00\x00\x11\x00\x03\x00\x03foo\x00\x03foo\x00\x03bar\x00\x00\x00\x14\x00\x02\x00\x03foo\x00\x01\x01\x00\x05hello\x00\x01\x00\x00\x00\x00\r\x00\x02\x00\x03\xABC!\x00\x04\xAF\xD8~\xCD\x00\x00\x00\vhello world\x00\x00\x00\b\x00\x00\x01</\xE9\xDC\xE3\x00\x00\x00\x10\xA4\xA7\t\x00$\xE1\x11\xDF\x89$\x00\x1F\xF3Y\x17\x11\x00\x00\x00\x10\xCF\xD6l\xCC\xD8WN\x90\xB1\xE5\xDF\x98\xA3\xD4\f\xD6\x00\x00\x00\x03foo\x00\x00\x00\x11\x03\x9EV \x15\f\x03\x9DK\x18\xCDI\\$?\a["
465
- end
466
-
467
- it 'decodes ASCII as an ASCII encoded string' do
468
- frame.body.rows.first['ascii_column'].should == 'hello'
469
- frame.body.rows.first['ascii_column'].encoding.should == ::Encoding::ASCII
470
- end
471
-
472
- it 'decodes BIGINT as a number' do
473
- frame.body.rows.first['bigint_column'].should == 1012312312414123
474
- end
475
-
476
- it 'decodes BLOB as a ASCII-8BIT string' do
477
- frame.body.rows.first['blob_column'].should == "\xfa\xb4\x5e\x34\x56"
478
- frame.body.rows.first['blob_column'].encoding.should == ::Encoding::BINARY
479
- end
480
-
481
- it 'decodes BOOLEAN as a boolean' do
482
- frame.body.rows.first['boolean_column'].should equal(true)
483
- end
484
-
485
- it 'decodes DECIMAL as a number' do
486
- frame.body.rows.first['decimal_column'].should == BigDecimal.new('1042342234234.123423435647768234')
487
- end
488
-
489
- it 'decodes DOUBLE as a number' do
490
- frame.body.rows.first['double_column'].should == 10000.123123123
491
- end
492
-
493
- it 'decodes FLOAT as a number' do
494
- frame.body.rows.first['float_column'].should be_within(0.001).of(12.13)
495
- end
496
-
497
- it 'decodes INT as a number' do
498
- frame.body.rows.first['int_column'].should == 12348098
499
- end
500
-
501
- it 'decodes TEXT as a UTF-8 encoded string' do
502
- frame.body.rows.first['text_column'].should == 'hello world'
503
- frame.body.rows.first['text_column'].encoding.should == ::Encoding::UTF_8
504
- end
505
-
506
- it 'decodes TIMESTAMP as a Time' do
507
- frame.body.rows.first['timestamp_column'].should == Time.at(1358013521.123)
508
- end
509
-
510
- it 'decodes UUID as a Uuid' do
511
- frame.body.rows.first['uuid_column'].should == Uuid.new('cfd66ccc-d857-4e90-b1e5-df98a3d40cd6')
512
- end
513
-
514
- it 'decodes VARCHAR as a UTF-8 encoded string' do
515
- frame.body.rows.first['varchar_column'].should == 'foo'
516
- frame.body.rows.first['varchar_column'].encoding.should == ::Encoding::UTF_8
517
- end
518
-
519
- it 'decodes VARINT as a number' do
520
- frame.body.rows.first['varint_column'].should == 1231312312331283012830129382342342412123
521
- end
522
-
523
- it 'decodes TIMEUUID as a TimeUuid' do
524
- frame.body.rows.first['timeuuid_column'].should == TimeUuid.new('a4a70900-24e1-11df-8924-001ff3591711')
525
- end
526
-
527
- it 'decodes INET as a IPAddr' do
528
- frame.body.rows.first['inet_column'].should == IPAddr.new('10.0.1.2')
529
- end
530
-
531
- it 'decodes LIST<ASCII> as an array of ASCII strings' do
532
- frame.body.rows.first['list_column'].should == ['foo', 'foo', 'bar'].map { |s| s.force_encoding(::Encoding::ASCII) }
533
- end
534
-
535
- it 'decodes MAP<TEXT, BOOLEAN> as a hash of UTF-8 strings to booleans' do
536
- frame.body.rows.first['map_column'].should == {'foo' => true, 'hello' => false}
537
- end
538
-
539
- it 'decodes SET<BLOB> as a set of binary strings' do
540
- frame.body.rows.first['set_column'].should == Set.new(["\xab\x43\x21", "\xaf\xd8\x7e\xcd"].map { |s| s.force_encoding(::Encoding::BINARY) })
541
- end
542
-
543
- it 'decodes nulls' do
544
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\b\x00\x00\x01\xB6\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x13\x00\x12cql_rb_client_spec\x00\rlots_of_types\x00\x02id\x00\t\x00\fascii_column\x00\x01\x00\rbigint_column\x00\x02\x00\vblob_column\x00\x03\x00\x0Eboolean_column\x00\x04\x00\x0Edecimal_column\x00\x06\x00\rdouble_column\x00\a\x00\ffloat_column\x00\b\x00\vinet_column\x00\x10\x00\nint_column\x00\t\x00\vlist_column\x00 \x00\x01\x00\nmap_column\x00!\x00\r\x00\x04\x00\nset_column\x00\"\x00\x03\x00\vtext_column\x00\r\x00\x10timestamp_column\x00\v\x00\x0Ftimeuuid_column\x00\x0F\x00\vuuid_column\x00\f\x00\x0Evarchar_column\x00\r\x00\rvarint_column\x00\x0E\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"))
545
- row = frame.body.rows.first
546
- row.should eql(
547
- 'id' => 3,
548
- 'ascii_column' => nil,
549
- 'bigint_column' => nil,
550
- 'blob_column' => nil,
551
- 'boolean_column' => nil,
552
- 'decimal_column' => nil,
553
- 'double_column' => nil,
554
- 'float_column' => nil,
555
- 'int_column' => nil,
556
- 'text_column' => nil,
557
- 'timestamp_column' => nil,
558
- 'uuid_column' => nil,
559
- 'varchar_column' => nil,
560
- 'varint_column' => nil,
561
- 'timeuuid_column' => nil,
562
- 'inet_column' => nil,
563
- 'list_column' => nil,
564
- 'map_column' => nil,
565
- 'set_column' => nil,
566
- )
567
- end
568
-
569
- it 'decodes COUNTER as a number' do
570
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\b\x00\x00\x00N\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\x04test\x00\x04cnts\x00\x02id\x00\r\x00\x02c1\x00\x05\x00\x02c2\x00\x05\x00\x00\x00\x01\x00\x00\x00\x04theo\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x01"))
571
- frame.body.rows.first['c1'].should == 3
572
- end
573
-
574
- it 'decodes a null COUNTER as nil' do
575
- frame = described_class.new(ByteBuffer.new("\x81\x00\x00\b\x00\x00\x00V\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x12cql_rb_client_spec\x00\bcounters\x00\bcounter1\x00\x05\x00\bcounter2\x00\x05\x00\x00\x00\x01\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x01\xFF\xFF\xFF\xFF"))
576
- frame.body.rows.first['counter2'].should be_nil
577
- end
578
-
579
- it 'raises an error when encountering an unknown column type' do
580
- frame = described_class.new
581
- frame << "\x81\x00\x00\b\x00\x00\x00E"
582
- frame << "\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\ncql_rb_328\x00\x05users"
583
- expect { frame << "\x00\tuser_name\x00\xff\x00\x05email\x00\r\x00\bpassword\x00\r\x00\x00\x00\x00" }.to raise_error(UnsupportedColumnTypeError)
584
- end
585
- end
586
-
587
- context 'when decoding an INET column' do
588
- let :rows do
589
- frame = described_class.new
590
- frame << "\x81\x00\x00\b\x00\x00\x00V\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\ntest_types\x00\rlots_of_types\x00\vinet_column\x00\x10\x00\x00\x00\x02\x00\x00\x00\x04\x7F\x00\x00\x01\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
591
- frame.body.rows.to_a
592
- end
593
-
594
- it 'decodes IPv4 values' do
595
- rows[0]['inet_column'].should == IPAddr.new('127.0.0.1')
596
- end
597
-
598
- it 'decodes IPv6 values' do
599
- rows[1]['inet_column'].should == IPAddr.new('::1')
600
- end
601
- end
602
-
603
- context 'when it\'s an unknown type' do
604
- it 'raises an error' do
605
- expect { frame << "\x81\x00\x00\b\x00\x00\x00\x05\x00\x00\x00\xffhello" }.to raise_error(UnsupportedResultKindError)
606
- end
607
- end
608
- end
609
-
610
- context 'when fed a SCHEMA_CHANGE EVENT frame' do
611
- before do
612
- frame << "\x81\x00\xFF\f\x00\x00\x00+\x00\rSCHEMA_CHANGE\x00\aDROPPED\x00\ncql_rb_609\x00\x05users"
613
- end
614
-
615
- it 'has the stream ID -1' do
616
- frame.stream_id.should == -1
617
- end
618
-
619
- it 'has an event type' do
620
- frame.body.type.should == 'SCHEMA_CHANGE'
621
- end
622
-
623
- it 'has a change' do
624
- frame.body.change.should == 'DROPPED'
625
- end
626
-
627
- it 'has a keyspace' do
628
- frame.body.keyspace.should == 'cql_rb_609'
629
- end
630
-
631
- it 'has a table' do
632
- frame.body.table.should == 'users'
633
- end
634
-
635
- it 'has a pretty #to_s representation' do
636
- frame.body.to_s.should == 'EVENT SCHEMA_CHANGE DROPPED "cql_rb_609" "users"'
637
- end
638
- end
639
-
640
- context 'when fed a STATUS_CHANGE EVENT frame' do
641
- before do
642
- frame << "\x81\x00\xFF\f\x00\x00\x00\x1E\x00\rSTATUS_CHANGE\x00\x04DOWN\x04\x00\x00\x00\x00\x00\x00#R"
643
- end
644
-
645
- it 'has the stream ID -1' do
646
- frame.stream_id.should == -1
647
- end
648
-
649
- it 'has an event type' do
650
- frame.body.type.should == 'STATUS_CHANGE'
651
- end
652
-
653
- it 'has a change' do
654
- frame.body.change.should == 'DOWN'
655
- end
656
-
657
- it 'has an address' do
658
- frame.body.address.should == IPAddr.new('0.0.0.0')
659
- end
660
-
661
- it 'has a port' do
662
- frame.body.port.should == 9042
663
- end
664
-
665
- it 'has a pretty #to_s representation' do
666
- frame.body.to_s.should == 'EVENT STATUS_CHANGE DOWN 0.0.0.0:9042'
667
- end
668
- end
669
-
670
- context 'when fed a TOPOLOGY_CHANGE EVENT frame' do
671
- before do
672
- frame << "\x81\x00\xFF\f\x00\x00\x00(\x00\x0FTOPOLOGY_CHANGE\x00\fREMOVED_NODE\x04\x00\x00\x00\x00\x00\x00#R"
673
- end
674
-
675
- it 'has the stream ID -1' do
676
- frame.stream_id.should == -1
677
- end
678
-
679
- it 'has an event type' do
680
- frame.body.type.should == 'TOPOLOGY_CHANGE'
681
- end
682
-
683
- it 'has a change' do
684
- frame.body.change.should == 'REMOVED_NODE'
685
- end
686
-
687
- it 'has an address' do
688
- frame.body.address.should == IPAddr.new('0.0.0.0')
689
- end
690
-
691
- it 'has a port' do
692
- frame.body.port.should == 9042
693
- end
694
-
695
- it 'has a pretty #to_s representation' do
696
- frame.body.to_s.should == 'EVENT TOPOLOGY_CHANGE REMOVED_NODE 0.0.0.0:9042'
697
- end
698
- end
699
-
700
- context 'when fed an unsupported event type' do
701
- it 'raises an exception' do
702
- bytes = ByteBuffer.new("\x81\x00\xFF\f\x00\x00\x00\x06\x00\x04PING")
703
- expect { described_class.new(bytes) }.to raise_error(UnsupportedEventTypeError, /PING/)
704
- end
705
- end
706
-
707
- context 'when fed an non-existent opcode' do
708
- it 'raises an UnsupportedOperationError' do
709
- expect { frame << "\x81\x00\x00\x99\x00\x00\x00\x39" }.to raise_error(UnsupportedOperationError)
710
- end
711
- end
712
-
713
- context 'when fed more bytes than needed' do
714
- it 'it consumes its bytes, leaving the rest' do
715
- buffer = ByteBuffer.new("\x81\x00\x00\x06\x00\x00\x00\x27\x00\x02\x00\x0bCQL_VERSION\x00\x01\x00\x053.0.0\x00\x0bCOMPRESSION\x00\x00")
716
- buffer << "\x81\x00\x00\x00"
717
- described_class.new(buffer)
718
- buffer.should eql_bytes("\x81\x00\x00\x00")
719
- end
720
- end
721
-
722
- context 'when fed a frame that is longer than the specification specifies' do
723
- it 'it consumes the body length, leaving the rest' do
724
- buffer = ByteBuffer.new("\x81\x00\x00\x06\x00\x00\x00\x2a")
725
- buffer << "\x00\x02\x00\x0bCQL_VERSION\x00\x01\x00\x053.0.0\x00\x0bCOMPRESSION\x00\x00"
726
- buffer << "\xab\xcd\xef\x99"
727
- described_class.new(buffer)
728
- buffer.should eql_bytes("\x99")
729
- end
730
- end
731
-
732
- describe ReadyResponse do
733
- describe '#eql?' do
734
- it 'is equal to all other ready responses' do
735
- ReadyResponse.new.should eql(ReadyResponse.new)
736
- end
737
-
738
- it 'aliased as ==' do
739
- ReadyResponse.new.should == ReadyResponse.new
740
- end
741
- end
742
-
743
- describe '#hash' do
744
- it 'has the same hash code as all other ready responses' do
745
- ReadyResponse.new.hash.should == ReadyResponse.new.hash
746
- end
747
- end
748
- end
749
-
750
- describe SchemaChangeEventResponse do
751
- describe '#eql?' do
752
- it 'is equal to an identical response' do
753
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
754
- r2 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
755
- r1.should eql(r2)
756
- end
757
-
758
- it 'is not equal when the change is different' do
759
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
760
- r2 = SchemaChangeEventResponse.new('CREATED', 'keyspace_name', 'table_name')
761
- r1.should_not eql(r2)
762
- end
763
-
764
- it 'is not equal when the keyspace is different' do
765
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
766
- r2 = SchemaChangeEventResponse.new('DELETED', 'eman_ecapsyek', 'table_name')
767
- r1.should_not eql(r2)
768
- end
769
-
770
- it 'is not equal when the table is different' do
771
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
772
- r2 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'eman_elbat')
773
- r1.should_not eql(r2)
774
- end
775
-
776
- it 'is aliased as ==' do
777
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
778
- r2 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
779
- r1.should == r2
780
- end
781
- end
782
-
783
- describe '#hash' do
784
- it 'is the same for an identical response' do
785
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
786
- r2 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
787
- r1.hash.should == r2.hash
788
- end
789
-
790
- it 'is not the same when the change is different' do
791
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
792
- r2 = SchemaChangeEventResponse.new('CREATED', 'keyspace_name', 'table_name')
793
- r1.hash.should_not == r2.hash
794
- end
795
-
796
- it 'is not the same when the keyspace is different' do
797
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
798
- r2 = SchemaChangeEventResponse.new('DELETED', 'eman_ecapsyek', 'table_name')
799
- r1.hash.should_not == r2.hash
800
- end
801
-
802
- it 'is not the same when the table is different' do
803
- r1 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'table_name')
804
- r2 = SchemaChangeEventResponse.new('DELETED', 'keyspace_name', 'eman_elbat')
805
- r1.hash.should_not == r2.hash
806
- end
807
- end
808
- end
809
- end
810
- end
811
- end