cql-rb 1.1.3 → 1.2.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,273 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require 'spec_helper'
4
+
5
+
6
+ module Cql
7
+ module Protocol
8
+ describe RowsResultResponse do
9
+ describe '.decode!' do
10
+ context 'with rows from the same table' do
11
+ let :response do
12
+ described_class.decode!(ByteBuffer.new("\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"))
13
+ end
14
+
15
+ it 'decodes the rows as hashes of column name => column value' do
16
+ response.rows.should == [
17
+ {'user_name' => 'phil', 'email' => 'phil@heck.com', 'password' => nil},
18
+ {'user_name' => 'sue', 'email' => 'sue@inter.net', 'password' => nil}
19
+ ]
20
+ end
21
+
22
+ it 'decodes column metadata' do
23
+ response.metadata.should == [
24
+ ['cql_rb_126', 'users', 'user_name', :varchar],
25
+ ['cql_rb_126', 'users', 'email', :varchar],
26
+ ['cql_rb_126', 'users', 'password', :varchar]
27
+ ]
28
+ end
29
+
30
+ it 'is not void' do
31
+ response.should_not be_void
32
+ end
33
+ end
34
+
35
+ context 'with rows from different keyspaces' do
36
+ let :response do
37
+ # TODO: not sure if this is really how it would be for real
38
+ # this frame was constructed from the spec not from an actual result
39
+ buffer = ByteBuffer.new
40
+ buffer << "\x00\x00\x00\x00"
41
+ buffer << "\x00\x00\x00\x03"
42
+ buffer << "\x00\ncql_rb_126\x00\x06users1\x00\tuser_name\x00\r"
43
+ buffer << "\x00\ncql_rb_127\x00\x06users2\x00\x05email\x00\r"
44
+ buffer << "\x00\ncql_rb_128\x00\x06users3\x00\bpassword\x00\r"
45
+ buffer << "\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"
46
+ described_class.decode!(buffer)
47
+ end
48
+
49
+ it 'decodes the rows' do
50
+ response.rows.should == [
51
+ {'user_name' => 'phil', 'email' => 'phil@heck.com', 'password' => nil},
52
+ {'user_name' => 'sue', 'email' => 'sue@inter.net', 'password' => nil}
53
+ ]
54
+ end
55
+
56
+ it 'decodes the column metadata' do
57
+ response.metadata.should == [
58
+ ['cql_rb_126', 'users1', 'user_name', :varchar],
59
+ ['cql_rb_127', 'users2', 'email', :varchar],
60
+ ['cql_rb_128', 'users3', 'password', :varchar]
61
+ ]
62
+ end
63
+ end
64
+
65
+ context 'with different column types' do
66
+ let :response do
67
+ # The following test was created by intercepting the frame for the
68
+ # SELECT statement in this CQL exchange
69
+ #
70
+ # CREATE TABLE lots_of_types (
71
+ # ascii_column ASCII,
72
+ # bigint_column BIGINT,
73
+ # blob_column BLOB,
74
+ # boolean_column BOOLEAN,
75
+ # decimal_column DECIMAL,
76
+ # double_column DOUBLE,
77
+ # float_column FLOAT,
78
+ # int_column INT,
79
+ # text_column TEXT,
80
+ # timestamp_column TIMESTAMP,
81
+ # uuid_column UUID,
82
+ # varchar_column VARCHAR,
83
+ # varint_column VARINT,
84
+ # timeuuid_column TIMEUUID,
85
+ # inet_column INET,
86
+ # list_column LIST<ASCII>,
87
+ # map_column MAP<TEXT, BOOLEAN>,
88
+ # set_column SET<BLOB>,
89
+ #
90
+ # PRIMARY KEY (ascii_column)
91
+ # );
92
+ #
93
+ # 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)
94
+ # VALUES (
95
+ # 'hello',
96
+ # 1012312312414123,
97
+ # 'fab45e3456',
98
+ # true,
99
+ # 1042342234234.123423435647768234,
100
+ # 10000.123123123,
101
+ # 12.13,
102
+ # 12348098,
103
+ # 'hello world',
104
+ # 1358013521.123,
105
+ # cfd66ccc-d857-4e90-b1e5-df98a3d40cd6,
106
+ # 'foo',
107
+ # 1231312312331283012830129382342342412123,
108
+ # a4a70900-24e1-11df-8924-001ff3591711,
109
+ # 167772418,
110
+ # ['foo', 'foo', 'bar'],
111
+ # {'foo': true, 'hello': false},
112
+ # {'ab4321', 'afd87ecd'}
113
+ # );
114
+ #
115
+ # SELECT * FROM lots_of_types WHERE ascii_column = 'hello';
116
+
117
+ described_class.decode!(ByteBuffer.new("\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["))
118
+ end
119
+
120
+ it 'decodes ASCII as an ASCII encoded string' do
121
+ response.rows.first['ascii_column'].should == 'hello'
122
+ response.rows.first['ascii_column'].encoding.should == ::Encoding::ASCII
123
+ end
124
+
125
+ it 'decodes BIGINT as a number' do
126
+ response.rows.first['bigint_column'].should == 1012312312414123
127
+ end
128
+
129
+ it 'decodes BLOB as a ASCII-8BIT string' do
130
+ response.rows.first['blob_column'].should == "\xfa\xb4\x5e\x34\x56"
131
+ response.rows.first['blob_column'].encoding.should == ::Encoding::BINARY
132
+ end
133
+
134
+ it 'decodes BOOLEAN as a boolean' do
135
+ response.rows.first['boolean_column'].should equal(true)
136
+ end
137
+
138
+ it 'decodes DECIMAL as a number' do
139
+ response.rows.first['decimal_column'].should == BigDecimal.new('1042342234234.123423435647768234')
140
+ end
141
+
142
+ it 'decodes DOUBLE as a number' do
143
+ response.rows.first['double_column'].should == 10000.123123123
144
+ end
145
+
146
+ it 'decodes FLOAT as a number' do
147
+ response.rows.first['float_column'].should be_within(0.001).of(12.13)
148
+ end
149
+
150
+ it 'decodes INT as a number' do
151
+ response.rows.first['int_column'].should == 12348098
152
+ end
153
+
154
+ it 'decodes TEXT as a UTF-8 encoded string' do
155
+ response.rows.first['text_column'].should == 'hello world'
156
+ response.rows.first['text_column'].encoding.should == ::Encoding::UTF_8
157
+ end
158
+
159
+ it 'decodes TIMESTAMP as a Time' do
160
+ response.rows.first['timestamp_column'].should == Time.at(1358013521.123)
161
+ end
162
+
163
+ it 'decodes UUID as a Uuid' do
164
+ response.rows.first['uuid_column'].should == Uuid.new('cfd66ccc-d857-4e90-b1e5-df98a3d40cd6')
165
+ end
166
+
167
+ it 'decodes VARCHAR as a UTF-8 encoded string' do
168
+ response.rows.first['varchar_column'].should == 'foo'
169
+ response.rows.first['varchar_column'].encoding.should == ::Encoding::UTF_8
170
+ end
171
+
172
+ it 'decodes VARINT as a number' do
173
+ response.rows.first['varint_column'].should == 1231312312331283012830129382342342412123
174
+ end
175
+
176
+ it 'decodes TIMEUUID as a TimeUuid' do
177
+ response.rows.first['timeuuid_column'].should == TimeUuid.new('a4a70900-24e1-11df-8924-001ff3591711')
178
+ end
179
+
180
+ it 'decodes INET as a IPAddr' do
181
+ response.rows.first['inet_column'].should == IPAddr.new('10.0.1.2')
182
+ end
183
+
184
+ it 'decodes LIST<ASCII> as an array of ASCII strings' do
185
+ response.rows.first['list_column'].should == ['foo', 'foo', 'bar'].map { |s| s.force_encoding(::Encoding::ASCII) }
186
+ end
187
+
188
+ it 'decodes MAP<TEXT, BOOLEAN> as a hash of UTF-8 strings to booleans' do
189
+ response.rows.first['map_column'].should == {'foo' => true, 'hello' => false}
190
+ end
191
+
192
+ it 'decodes SET<BLOB> as a set of binary strings' do
193
+ response.rows.first['set_column'].should == Set.new(["\xab\x43\x21", "\xaf\xd8\x7e\xcd"].map { |s| s.force_encoding(::Encoding::BINARY) })
194
+ end
195
+ end
196
+
197
+ context 'with null values' do
198
+ it 'decodes nulls' do
199
+ response = described_class.decode!(ByteBuffer.new("\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"))
200
+ response.rows.first.should eql(
201
+ 'id' => 3,
202
+ 'ascii_column' => nil,
203
+ 'bigint_column' => nil,
204
+ 'blob_column' => nil,
205
+ 'boolean_column' => nil,
206
+ 'decimal_column' => nil,
207
+ 'double_column' => nil,
208
+ 'float_column' => nil,
209
+ 'int_column' => nil,
210
+ 'text_column' => nil,
211
+ 'timestamp_column' => nil,
212
+ 'uuid_column' => nil,
213
+ 'varchar_column' => nil,
214
+ 'varint_column' => nil,
215
+ 'timeuuid_column' => nil,
216
+ 'inet_column' => nil,
217
+ 'list_column' => nil,
218
+ 'map_column' => nil,
219
+ 'set_column' => nil,
220
+ )
221
+ end
222
+ end
223
+
224
+ context 'with COUNTER columns' do
225
+ it 'decodes COUNTER as a number' do
226
+ response = described_class.decode!(ByteBuffer.new("\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"))
227
+ response.rows.first['c1'].should == 3
228
+ end
229
+
230
+ it 'decodes a null COUNTER as nil' do
231
+ response = described_class.decode!(ByteBuffer.new("\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"))
232
+ response.rows.first['counter2'].should be_nil
233
+ end
234
+ end
235
+
236
+ context 'with an INET column' do
237
+ let :response do
238
+ described_class.decode!(ByteBuffer.new("\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"))
239
+ end
240
+
241
+ it 'decodes IPv4 values' do
242
+ response.rows[0]['inet_column'].should == IPAddr.new('127.0.0.1')
243
+ end
244
+
245
+ it 'decodes IPv6 values' do
246
+ response.rows[1]['inet_column'].should == IPAddr.new('::1')
247
+ end
248
+ end
249
+
250
+ context 'with an unknown column type' do
251
+ it 'raises an error when encountering an unknown column type' do
252
+ buffer = ByteBuffer.new("\x00\x00\x00\x01\x00\x00\x00\x03\x00\ncql_rb_328\x00\x05users\x00\tuser_name\x00\xff\x00\x05email\x00\r\x00\bpassword\x00\r\x00\x00\x00\x00")
253
+ expect { described_class.decode!(buffer) }.to raise_error(UnsupportedColumnTypeError)
254
+ end
255
+ end
256
+ end
257
+
258
+ describe '#void?' do
259
+ it 'is not void' do
260
+ response = RowsResultResponse.new([{'col' => 'foo'}], [['ks', 'tbl', 'col', :varchar]], nil)
261
+ response.should_not be_void
262
+ end
263
+ end
264
+
265
+ describe '#to_s' do
266
+ it 'returns a string with metadata and rows' do
267
+ response = RowsResultResponse.new([{'col' => 'foo'}], [['ks', 'tbl', 'col', :varchar]], nil)
268
+ response.to_s.should == 'RESULT ROWS [["ks", "tbl", "col", :varchar]] [{"col"=>"foo"}]'
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require 'spec_helper'
4
+
5
+
6
+ module Cql
7
+ module Protocol
8
+ describe SchemaChangeEventResponse do
9
+ describe '.decode!' do
10
+ let :response do
11
+ described_class.decode!(ByteBuffer.new("\x00\aDROPPED\x00\ncql_rb_609\x00\x05users"))
12
+ end
13
+
14
+ it 'decodes the change' do
15
+ response.change.should == 'DROPPED'
16
+ end
17
+
18
+ it 'decodes the keyspace' do
19
+ response.keyspace.should == 'cql_rb_609'
20
+ end
21
+
22
+ it 'decodes the table' do
23
+ response.table.should == 'users'
24
+ end
25
+ end
26
+
27
+ describe '#to_s' do
28
+ it 'returns a string with the change, keyspace and table' do
29
+ response = described_class.new('DROPPED', 'ks', 'tbl')
30
+ response.to_s.should == 'EVENT SCHEMA_CHANGE DROPPED "ks" "tbl"'
31
+ end
32
+ end
33
+
34
+ describe '#eql?' do
35
+ it 'is equal to an identical response' do
36
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
37
+ r2 = described_class.new('DELETED', 'keyspace_name', 'table_name')
38
+ r1.should eql(r2)
39
+ end
40
+
41
+ it 'is not equal when the change is different' do
42
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
43
+ r2 = described_class.new('CREATED', 'keyspace_name', 'table_name')
44
+ r1.should_not eql(r2)
45
+ end
46
+
47
+ it 'is not equal when the keyspace is different' do
48
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
49
+ r2 = described_class.new('DELETED', 'eman_ecapsyek', 'table_name')
50
+ r1.should_not eql(r2)
51
+ end
52
+
53
+ it 'is not equal when the table is different' do
54
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
55
+ r2 = described_class.new('DELETED', 'keyspace_name', 'eman_elbat')
56
+ r1.should_not eql(r2)
57
+ end
58
+
59
+ it 'is aliased as ==' do
60
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
61
+ r2 = described_class.new('DELETED', 'keyspace_name', 'table_name')
62
+ r1.should == r2
63
+ end
64
+ end
65
+
66
+ describe '#hash' do
67
+ it 'is the same for an identical response' do
68
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
69
+ r2 = described_class.new('DELETED', 'keyspace_name', 'table_name')
70
+ r1.hash.should == r2.hash
71
+ end
72
+
73
+ it 'is not the same when the change is different' do
74
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
75
+ r2 = described_class.new('CREATED', 'keyspace_name', 'table_name')
76
+ r1.hash.should_not == r2.hash
77
+ end
78
+
79
+ it 'is not the same when the keyspace is different' do
80
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
81
+ r2 = described_class.new('DELETED', 'eman_ecapsyek', 'table_name')
82
+ r1.hash.should_not == r2.hash
83
+ end
84
+
85
+ it 'is not the same when the table is different' do
86
+ r1 = described_class.new('DELETED', 'keyspace_name', 'table_name')
87
+ r2 = described_class.new('DELETED', 'keyspace_name', 'eman_elbat')
88
+ r1.hash.should_not == r2.hash
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -6,35 +6,67 @@ require 'spec_helper'
6
6
  module Cql
7
7
  module Protocol
8
8
  describe SchemaChangeResultResponse do
9
+ describe '.decode!' do
10
+ let :response do
11
+ described_class.decode!(ByteBuffer.new("\x00\aUPDATED\x00\ncql_rb_973\x00\x05users"))
12
+ end
13
+
14
+ it 'decodes the description' do
15
+ response.change.should == 'UPDATED'
16
+ end
17
+
18
+ it 'decodes the keyspace' do
19
+ response.keyspace.should == 'cql_rb_973'
20
+ end
21
+
22
+ it 'decodes the table' do
23
+ response.table.should == 'users'
24
+ end
25
+ end
26
+
27
+ describe '#void?' do
28
+ it 'is not void' do
29
+ response = described_class.new('CREATED', 'ks', 'tbl', nil)
30
+ response.should_not be_void
31
+ end
32
+ end
33
+
34
+ describe '#to_s' do
35
+ it 'returns a string with the description, keyspace and table' do
36
+ response = described_class.new('CREATED', 'ks', 'tbl', nil)
37
+ response.to_s.should == 'RESULT SCHEMA_CHANGE CREATED "ks" "tbl"'
38
+ end
39
+ end
40
+
9
41
  describe '#eql?' do
10
42
  it 'is equal to another response with the same change, keyspace and table names' do
11
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
12
- response2 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
43
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
44
+ response2 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
13
45
  response1.should eql(response2)
14
46
  end
15
47
 
16
48
  it 'is not equal to another response with another change' do
17
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
18
- response2 = described_class.new('CREATED', 'some_keyspace', 'a_table')
49
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
50
+ response2 = described_class.new('CREATED', 'some_keyspace', 'a_table', nil)
19
51
  response1.should_not eql(response2)
20
52
  end
21
53
 
22
54
  it 'is not equal to another response with another keyspace name' do
23
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
24
- response2 = described_class.new('DROPPED', 'another_keyspace', 'a_table')
55
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
56
+ response2 = described_class.new('DROPPED', 'another_keyspace', 'a_table', nil)
25
57
  response1.should_not eql(response2)
26
58
  end
27
59
 
28
60
  it 'is not equal to another response with another table name' do
29
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
30
- response2 = described_class.new('DROPPED', 'some_keyspace', 'another_table')
61
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
62
+ response2 = described_class.new('DROPPED', 'some_keyspace', 'another_table', nil)
31
63
  response1.should_not eql(response2)
32
64
  end
33
65
 
34
66
  it 'is aliased as ==' do
35
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
36
- response2 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
37
- response3 = described_class.new('DROPPED', 'some_keyspace', 'another_table')
67
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
68
+ response2 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
69
+ response3 = described_class.new('DROPPED', 'some_keyspace', 'another_table', nil)
38
70
  response1.should == response2
39
71
  response2.should_not == response3
40
72
  end
@@ -42,26 +74,26 @@ module Cql
42
74
 
43
75
  describe '#hash' do
44
76
  it 'is the same when the change, keyspace and table names are the same' do
45
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
46
- response2 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
77
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
78
+ response2 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
47
79
  response1.hash.should == response2.hash
48
80
  end
49
81
 
50
82
  it 'is not the same when the change is different' do
51
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
52
- response2 = described_class.new('CREATED', 'some_keyspace', 'a_table')
83
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
84
+ response2 = described_class.new('CREATED', 'some_keyspace', 'a_table', nil)
53
85
  response1.hash.should_not == response2.hash
54
86
  end
55
87
 
56
88
  it 'is not the same when the keyspace name is different' do
57
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
58
- response2 = described_class.new('DROPPED', 'another_keyspace', 'a_table')
89
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
90
+ response2 = described_class.new('DROPPED', 'another_keyspace', 'a_table', nil)
59
91
  response1.hash.should_not == response2.hash
60
92
  end
61
93
 
62
94
  it 'is not the same when the table name is different' do
63
- response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table')
64
- response2 = described_class.new('DROPPED', 'some_keyspace', 'another_table')
95
+ response1 = described_class.new('DROPPED', 'some_keyspace', 'a_table', nil)
96
+ response2 = described_class.new('DROPPED', 'some_keyspace', 'another_table', nil)
65
97
  response1.hash.should_not == response2.hash
66
98
  end
67
99
  end