monetdb 0.1.3 → 0.2.0

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.
@@ -0,0 +1,276 @@
1
+ require_relative "../../test_helper"
2
+
3
+ module Unit
4
+ module Connection
5
+ class TestQuery < MiniTest::Test
6
+
7
+ class Connection < SimpleConnection
8
+ include MonetDB::Connection::Messages
9
+ include MonetDB::Connection::Query
10
+ end
11
+
12
+ describe MonetDB::Connection::Query do
13
+ before do
14
+ @connection = Connection.new
15
+ end
16
+
17
+ describe "#extract_headers!" do
18
+ it "returns an array with delegated return values" do
19
+ response, foo, bar = mock, mock, mock
20
+
21
+ @connection.expects(:parse_query_header!).with(response).returns(foo)
22
+ @connection.expects(:parse_scheme_header!).with(response).returns(bar)
23
+
24
+ assert_equal [foo, bar], @connection.send(:extract_headers!, response)
25
+ end
26
+ end
27
+
28
+ describe "#parse_query_header!" do
29
+ describe "containing an error message" do
30
+ it "raises a query error" do
31
+ assert_raises MonetDB::QueryError do
32
+ @connection.send(:parse_query_header!, ["!epicfail", "foo"])
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "when absent in response" do
38
+ it "raises a query error" do
39
+ assert_raises MonetDB::QueryError do
40
+ @connection.send(:parse_query_header!, ["$money", "foo"])
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "when present in response" do
46
+ it "extracts the first line from the response and returns to_query_header_hash" do
47
+ response = [
48
+ "& 1 8 1982 0",
49
+ "% foo",
50
+ "% bar",
51
+ "[ 19, 82 ]",
52
+ "[ 20, 47 ]"
53
+ ]
54
+
55
+ @connection.expects(:to_query_header_hash).returns(hash = "hash")
56
+ assert_equal hash, @connection.send(:parse_query_header!, response)
57
+ assert_equal [
58
+ "% foo",
59
+ "% bar",
60
+ "[ 19, 82 ]",
61
+ "[ 20, 47 ]"
62
+ ], response
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "#to_query_header_hash" do
68
+ describe "when Q_TABLE header" do
69
+ it "returns a table header hash" do
70
+ assert_equal({
71
+ :type => "1",
72
+ :id => 0,
73
+ :rows => 1947,
74
+ :columns => 8,
75
+ :returned => 2014
76
+ }, @connection.send(:to_query_header_hash, "&1 0 1947 8 2014"))
77
+ end
78
+ end
79
+ describe "when Q_BLOCK header" do
80
+ it "returns a block header hash" do
81
+ assert_equal({
82
+ :type => "6",
83
+ :id => 0,
84
+ :columns => 10,
85
+ :remains => 179,
86
+ :offset => 100
87
+ }, @connection.send(:to_query_header_hash, "&6 0 10 179 100"))
88
+ end
89
+ end
90
+ describe "when unknown header" do
91
+ it "returns a simple hash with just the type" do
92
+ assert_equal({:type => "0"}, @connection.send(:to_query_header_hash, "&0 1 2 3"))
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "#parse_scheme_header!" do
98
+ describe "when present in response" do
99
+ it "extracts scheme related lines from the response and returns to_scheme_header_hash" do
100
+ response = [
101
+ "% foo",
102
+ "% bar",
103
+ "[ 19, 82 ]",
104
+ "[ 20, 47 ]"
105
+ ]
106
+
107
+ @connection.expects(:to_scheme_header_hash).returns(hash = "hash")
108
+ assert_equal hash, @connection.send(:parse_scheme_header!, response)
109
+ assert_equal [
110
+ "[ 19, 82 ]",
111
+ "[ 20, 47 ]"
112
+ ], response
113
+ end
114
+ end
115
+
116
+ describe "when absent in response" do
117
+ it "returns nil" do
118
+ response = [
119
+ "[ 19, 82 ]",
120
+ "% foo bar",
121
+ "[ 20, 47 ]"
122
+ ]
123
+ assert_nil @connection.send(:parse_scheme_header!, response)
124
+ assert_equal [
125
+ "[ 19, 82 ]",
126
+ "% foo bar",
127
+ "[ 20, 47 ]"
128
+ ], response
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "#to_scheme_header_hash" do
134
+ it "returns a frozen hash" do
135
+ header = [
136
+ %w(foo_bars baz_quxs paul_engels),
137
+ %w(foo bar baz qux),
138
+ %w(tinyint varchar integer float),
139
+ %w(1 9 8 2)
140
+ ]
141
+
142
+ hash = @connection.send(:to_scheme_header_hash, header)
143
+
144
+ assert_equal true, hash.frozen?
145
+ assert_equal({
146
+ :table_name => "foo_bars",
147
+ :column_names => %w(foo bar baz qux),
148
+ :column_types => [:tinyint, :varchar, :integer, :float],
149
+ :column_lengths => [1, 9, 8, 2]
150
+ }, hash)
151
+ end
152
+ end
153
+
154
+ describe "#parse_rows" do
155
+ it "returns an array of hashes" do
156
+ table_header = {
157
+ :column_types => [:varchar, :date, :double]
158
+ }
159
+
160
+ response = [
161
+ "[ \"Paul Engel\",\t1982-08-01,\t19.82\t]",
162
+ "[ \"Ken Adams\",\t1980-10-13,\t20.47\t]"
163
+ ].join("\n")
164
+
165
+ assert_equal [
166
+ ["Paul Engel", Date.parse("1982-08-01"), 19.82],
167
+ ["Ken Adams", Date.parse("1980-10-13"), 20.47]
168
+ ], @connection.send(:parse_rows, table_header, response)
169
+ end
170
+ end
171
+
172
+ describe "#parse_value" do
173
+ describe "when NULL" do
174
+ it "returns nil" do
175
+ assert_nil @connection.send(:parse_value, :varchar, "NULL")
176
+ assert_nil @connection.send(:parse_value, :text, "NULL")
177
+ assert_nil @connection.send(:parse_value, :int, "NULL")
178
+ assert_nil @connection.send(:parse_value, :smallint, "NULL")
179
+ assert_nil @connection.send(:parse_value, :bigint, "NULL")
180
+ assert_nil @connection.send(:parse_value, :double, "NULL")
181
+ assert_nil @connection.send(:parse_value, :float, "NULL")
182
+ assert_nil @connection.send(:parse_value, :real, "NULL")
183
+ assert_nil @connection.send(:parse_value, :date, "NULL")
184
+ assert_nil @connection.send(:parse_value, :timestamp, "NULL")
185
+ assert_nil @connection.send(:parse_value, :tinyint, "NULL")
186
+ end
187
+ end
188
+
189
+ describe "when not NULL" do
190
+ describe "when is type valid" do
191
+ it "delegates to the appropiate parse method" do
192
+ value = mock
193
+
194
+ @connection.expects(:parse_string_value).with(value)
195
+ @connection.send(:parse_value, :varchar, value)
196
+
197
+ @connection.expects(:parse_string_value).with(value)
198
+ @connection.send(:parse_value, :text, value)
199
+
200
+ @connection.expects(:parse_integer_value).with(value)
201
+ @connection.send(:parse_value, :int, value)
202
+
203
+ @connection.expects(:parse_integer_value).with(value)
204
+ @connection.send(:parse_value, :smallint, value)
205
+
206
+ @connection.expects(:parse_integer_value).with(value)
207
+ @connection.send(:parse_value, :bigint, value)
208
+
209
+ @connection.expects(:parse_float_value).with(value)
210
+ @connection.send(:parse_value, :float, value)
211
+
212
+ @connection.expects(:parse_float_value).with(value)
213
+ @connection.send(:parse_value, :real, value)
214
+
215
+ @connection.expects(:parse_date_value).with(value)
216
+ @connection.send(:parse_value, :date, value)
217
+
218
+ @connection.expects(:parse_date_time_value).with(value)
219
+ @connection.send(:parse_value, :timestamp, value)
220
+
221
+ @connection.expects(:parse_boolean_value).with(value)
222
+ @connection.send(:parse_value, :tinyint, value)
223
+ end
224
+ end
225
+
226
+ describe "when is type invalid" do
227
+ it "raises a not implemented error" do
228
+ assert_raises NotImplementedError do
229
+ @connection.send(:parse_value, :foo, mock)
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ describe "#parse_string_value" do
237
+ it "returns a string" do
238
+ assert_equal "Paul Engel", @connection.send(:parse_string_value, "\"Paul Engel\"")
239
+ end
240
+ end
241
+
242
+ describe "#parse_integer_value" do
243
+ it "returns an integer" do
244
+ assert_equal 1982, @connection.send(:parse_integer_value, "1982")
245
+ end
246
+ end
247
+
248
+ describe "#parse_float_value" do
249
+ it "returns a float" do
250
+ assert_equal 19.82, @connection.send(:parse_float_value, "19.82")
251
+ end
252
+ end
253
+
254
+ describe "#parse_date_value" do
255
+ it "returns a Date instance" do
256
+ assert_equal Date.parse("1982-08-01"), @connection.send(:parse_date_value, "1982-08-01")
257
+ end
258
+ end
259
+
260
+ describe "#parse_date_time_value" do
261
+ it "returns a Time instance" do
262
+ assert_equal Time.parse("1982-08-01 18:19:47"), @connection.send(:parse_date_time_value, "1982-08-01 18:19:47.0000")
263
+ end
264
+ end
265
+
266
+ describe "#parse_boolean_value" do
267
+ it "returns a boolean" do
268
+ assert_equal false, @connection.send(:parse_boolean_value, "0")
269
+ assert_equal true, @connection.send(:parse_boolean_value, "1")
270
+ end
271
+ end
272
+ end
273
+
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,364 @@
1
+ require_relative "../../test_helper"
2
+
3
+ module Unit
4
+ module Connection
5
+ class TestSetup < MiniTest::Test
6
+
7
+ class Connection < SimpleConnection
8
+ include MonetDB::Connection::Messages
9
+ include MonetDB::Connection::Setup
10
+ end
11
+
12
+ describe MonetDB::Connection::Setup do
13
+ before do
14
+ @connection = Connection.new
15
+ end
16
+
17
+ describe "#setup" do
18
+ it "obtains the server challenge, sets up the timezone and reply size" do
19
+ @connection.expects(:authenticate)
20
+ @connection.expects(:set_timezone_interval)
21
+ @connection.expects(:set_reply_size)
22
+ @connection.send(:setup)
23
+ end
24
+ end
25
+
26
+ describe "#authenticate" do
27
+ before do
28
+ @connection.expects(:obtain_server_challenge!)
29
+ @connection.expects(:authentication_string).returns(auth_string = "<authentication_string>")
30
+ @connection.expects(:write).with(auth_string)
31
+ end
32
+
33
+ describe "when success" do
34
+ it "returns true" do
35
+ @connection.expects(:read).returns("")
36
+ @connection.send(:authenticate)
37
+ end
38
+ end
39
+
40
+ describe "when redirect" do
41
+ it "authenticates using the redirect" do
42
+ @connection.expects(:read).returns(response = "^^mapi:redirect")
43
+ @connection.expects(:authentication_redirect).with(response)
44
+ @connection.send(:authenticate)
45
+ end
46
+ end
47
+
48
+ describe "when fail" do
49
+ it "raises an authentication error" do
50
+ @connection.expects(:read).returns("!epicfail")
51
+ assert_raises MonetDB::AuthenticationError do
52
+ @connection.send(:authenticate)
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#obtain_server_challenge!" do
59
+ it "updates the config and validates it" do
60
+ @connection.expects(:server_challenge).returns(:foo => "bar", :baz => "qux")
61
+ @connection.expects(:assert_supported_protocol!)
62
+ @connection.expects(:select_supported_auth_type!)
63
+
64
+ assert_equal({
65
+ :host => "localhost",
66
+ :port => 50000,
67
+ :username => "monetdb",
68
+ :password => "monetdb"
69
+ }, @connection.instance_variable_get(:@config))
70
+
71
+ @connection.send(:obtain_server_challenge!)
72
+
73
+ assert_equal({
74
+ :host => "localhost",
75
+ :port => 50000,
76
+ :username => "monetdb",
77
+ :password => "monetdb",
78
+ :foo => "bar",
79
+ :baz => "qux"
80
+ }, @connection.instance_variable_get(:@config))
81
+ end
82
+ end
83
+
84
+ describe "#server_challenge" do
85
+ it "returns the server challenge config" do
86
+ response = "<salt>:<server_name>:9:MD5,SHA512:<server_endianness>:SHA1"
87
+ @connection.expects(:read).returns(response)
88
+ assert_equal({
89
+ :salt => "<salt>",
90
+ :server_name => "<server_name>",
91
+ :protocol => "9",
92
+ :auth_types => "MD5,SHA512",
93
+ :server_endianness => "<server_endianness>",
94
+ :password_digest_method => "SHA1"
95
+ }, @connection.send(:server_challenge))
96
+ end
97
+ end
98
+
99
+ describe "#assert_supported_protocol!" do
100
+ describe "when supporting one of the server protocols" do
101
+ it "returns nil" do
102
+ @connection.instance_variable_get(:@config)[:protocol] = MonetDB::Connection::MAPI_V8
103
+ assert_nil @connection.send(:assert_supported_protocol!)
104
+ end
105
+ end
106
+
107
+ describe "when not supporting any of the server protocols" do
108
+ it "raises a protocol error" do
109
+ @connection.instance_variable_get(:@config)[:protocol] = "FOO"
110
+ assert_raises MonetDB::ProtocolError do
111
+ @connection.send(:assert_supported_protocol!)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "#select_supported_auth_type!" do
118
+ describe "when supporting one of the server authentication types" do
119
+ it "selects a supported authentication type" do
120
+ config = @connection.instance_variable_get(:@config)
121
+ auth_md5 = MonetDB::Connection::AUTH_MD5
122
+
123
+ config[:auth_types] = "FOO,#{auth_md5},BAR"
124
+ assert_nil config[:auth_type]
125
+
126
+ @connection.send(:select_supported_auth_type!)
127
+ assert_equal auth_md5, config[:auth_type]
128
+ end
129
+ end
130
+
131
+ describe "when not supporting any of the server authentication types" do
132
+ it "raises an authentication error" do
133
+ response = "<salt>:<server_name>:9:CRYPT:<server_endianness>:SHA1"
134
+ @connection.expects(:read).returns(response)
135
+ assert_raises MonetDB::AuthenticationError do
136
+ @connection.send(:obtain_server_challenge!)
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "#authentication_string" do
143
+ before do
144
+ @endianness = MonetDB::Connection::ENDIANNESS
145
+ @lang = MonetDB::Connection::LANG
146
+ @connection.instance_variable_set :@config, {
147
+ :database => "db",
148
+ :username => "paul",
149
+ :password => "mysecret",
150
+ :salt => "kitchen",
151
+ :password_digest_method => "MD5"
152
+ }
153
+ end
154
+
155
+ describe "MAPI V8 protocol" do
156
+ before do
157
+ @connection.instance_variable_get(:@config)[:protocol] = MonetDB::Connection::MAPI_V8
158
+ end
159
+
160
+ describe "when using digests" do
161
+ it "returns an authentication string with a digest hashsum" do
162
+ @connection.instance_variable_get(:@config)[:auth_type] = "MD5"
163
+ hashsum = "ec2c417dbdaa6fec77eef74e8c2524b9"
164
+ assert_equal "#{@endianness}:paul:{MD5}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
165
+
166
+ @connection.instance_variable_get(:@config)[:auth_type] = "SHA1"
167
+ hashsum = "10cbdc8ea82154bbfe64df5265a2f35118b51a18"
168
+ assert_equal "#{@endianness}:paul:{SHA1}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
169
+
170
+ @connection.instance_variable_get(:@config)[:auth_type] = "SHA512"
171
+ hashsum = "8527a8feaa8ea3e538b16a1a40e76176edb725b29bb8989ec4800de625f6b1d3569eb7fae49b0b54ae33bbf055e462a769582d0f02a18181e5dac1b106710d98"
172
+ assert_equal "#{@endianness}:paul:{SHA512}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
173
+ end
174
+ end
175
+
176
+ describe "when plain authentication type" do
177
+ it "returns an authentication string with a plain hashsum" do
178
+ @connection.instance_variable_get(:@config)[:auth_type] = "PLAIN"
179
+ assert_equal "#{@endianness}:paul:{PLAIN}mysecretkitchen:#{@lang}:db:", @connection.send(:authentication_string)
180
+ end
181
+ end
182
+
183
+ describe "when non-supported authentication type" do
184
+ it "returns an authentication string without hashsum" do
185
+ assert_equal "#{@endianness}:paul:{}:#{@lang}:db:", @connection.send(:authentication_string)
186
+ end
187
+ end
188
+ end
189
+
190
+ describe "MAPI V9 protocol" do
191
+ before do
192
+ @connection.instance_variable_get(:@config)[:protocol] = MonetDB::Connection::MAPI_V9
193
+ @connection.instance_variable_get(:@config)[:password_digest_method] = "MD5"
194
+ end
195
+
196
+ describe "when using digests" do
197
+ it "returns an authentication string with a digest hashsum" do
198
+ @connection.instance_variable_get(:@config)[:auth_type] = "MD5"
199
+ hashsum = "2c89f883c0a9e30f58585f15adeb0500"
200
+ assert_equal "#{@endianness}:paul:{MD5}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
201
+
202
+ @connection.instance_variable_get(:@config)[:auth_type] = "SHA1"
203
+ hashsum = "51f0d237aedd38ad10f3348ecaa95d1d9fc7d7fd"
204
+ assert_equal "#{@endianness}:paul:{SHA1}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
205
+
206
+ @connection.instance_variable_get(:@config)[:auth_type] = "SHA512"
207
+ hashsum = "cf623a200ef12a7413835745bd0287cba478f1eb275c57137f7bdcea20ec10897544ad7a45647c3b814ff9e9e2fb187e6277fe2f994b23bb7d09f2141f83fffa"
208
+ assert_equal "#{@endianness}:paul:{SHA512}#{hashsum}:#{@lang}:db:", @connection.send(:authentication_string)
209
+ end
210
+ end
211
+
212
+ describe "when plain authentication type" do
213
+ it "returns an authentication string with a plain hashsum" do
214
+ @connection.instance_variable_get(:@config)[:auth_type] = "PLAIN"
215
+ assert_equal "#{@endianness}:paul:{PLAIN}mysecretkitchen:#{@lang}:db:", @connection.send(:authentication_string)
216
+ end
217
+ end
218
+
219
+ describe "when non-supported authentication type" do
220
+ it "returns an authentication string without hashsum" do
221
+ assert_equal "#{@endianness}:paul:{}:#{@lang}:db:", @connection.send(:authentication_string)
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ describe "#hexdigest" do
228
+ it "returns the hexdigest using the passed method and value" do
229
+ assert_equal "acbd18db4cc2f85cedef654fccc4a4d8", @connection.send(:hexdigest, "MD5", "foo")
230
+ assert_equal "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", @connection.send(:hexdigest, "SHA1", "foo")
231
+ assert_equal "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7", @connection.send(:hexdigest, "SHA512", "foo")
232
+ end
233
+ end
234
+
235
+ describe "#authentication_redirect" do
236
+ describe "without a MAPI redirect" do
237
+ it "raises an authentication error" do
238
+ assert_raises MonetDB::AuthenticationError do
239
+ @connection.send(:authentication_redirect, "^foobar:bazqux")
240
+ end
241
+ end
242
+ end
243
+
244
+ describe "without a valid redirect URI" do
245
+ it "raises an authentication error" do
246
+ URI.expects(:split).raises(URI::InvalidURIError)
247
+ assert_raises MonetDB::AuthenticationError do
248
+ @connection.send(:authentication_redirect, "^mapi:foobar")
249
+ end
250
+ end
251
+ end
252
+
253
+ describe "with 'merovingian' scheme" do
254
+ it "retries to authenticate" do
255
+ @connection.expects(:authenticate)
256
+ @connection.send(:authentication_redirect, "^mapi:merovingian://foobar")
257
+ end
258
+
259
+ describe "when too many retries" do
260
+ it "raises an authentication error" do
261
+ @connection.expects(:obtain_server_challenge!).times(5)
262
+ @connection.expects(:write).times(5)
263
+ @connection.expects(:read).times(5).returns(response = "^mapi:merovingian://foobar")
264
+ assert_raises MonetDB::AuthenticationError do
265
+ @connection.send(:authentication_redirect, response)
266
+ end
267
+ end
268
+ end
269
+ end
270
+
271
+ describe "with 'monetdb' scheme" do
272
+ it "raises an authentication error" do
273
+ @connection.expects(:connect)
274
+ @connection.send(:authentication_redirect, "^mapi:monetdb://ghost:1982")
275
+ assert_equal "ghost", @connection.send(:config)[:host]
276
+ assert_equal "1982", @connection.send(:config)[:port]
277
+ end
278
+ end
279
+
280
+ describe "without a supported server name" do
281
+ it "raises an authentication error" do
282
+ assert_raises MonetDB::AuthenticationError do
283
+ @connection.send(:authentication_redirect, "^mapi:foobar")
284
+ end
285
+ end
286
+ end
287
+ end
288
+
289
+ describe "#set_timezone_interval" do
290
+ describe "when not already set" do
291
+ describe "when success" do
292
+ it "returns true" do
293
+ time = mock
294
+ time.expects(:gmt_offset).returns(7200)
295
+ Time.expects(:now).returns(time)
296
+
297
+ @connection.expects(:write).with("sSET TIME ZONE INTERVAL '+02:00' HOUR TO MINUTE;")
298
+ @connection.expects(:read).returns("")
299
+ assert_equal true, @connection.send(:set_timezone_interval)
300
+
301
+ @connection.instance_variable_set(:@timezone_interval_set, false)
302
+
303
+ time = mock
304
+ time.expects(:gmt_offset).returns(36000)
305
+ Time.expects(:now).returns(time)
306
+
307
+ @connection.expects(:write).with("sSET TIME ZONE INTERVAL '+10:00' HOUR TO MINUTE;")
308
+ @connection.expects(:read).returns("")
309
+ assert_equal true, @connection.send(:set_timezone_interval)
310
+ end
311
+ end
312
+
313
+ describe "when fail" do
314
+ it "raises a command error" do
315
+ @connection.expects(:write)
316
+ @connection.expects(:read).returns("!epicfail")
317
+ assert_raises MonetDB::CommandError do
318
+ @connection.send(:set_timezone_interval)
319
+ end
320
+ end
321
+ end
322
+ end
323
+
324
+ describe "when already set" do
325
+ it "returns false" do
326
+ @connection.instance_variable_set(:@timezone_interval_set, true)
327
+ assert_equal false, @connection.send(:set_timezone_interval)
328
+ end
329
+ end
330
+ end
331
+
332
+ describe "#set_reply_size" do
333
+ describe "when not already set" do
334
+ describe "when success" do
335
+ it "returns true" do
336
+ @connection.expects(:write).with("Xreply_size #{MonetDB::Connection::REPLY_SIZE}\n")
337
+ @connection.expects(:read).returns("")
338
+ assert_equal true, @connection.send(:set_reply_size)
339
+ end
340
+ end
341
+
342
+ describe "when fail" do
343
+ it "raises a command error" do
344
+ @connection.expects(:write)
345
+ @connection.expects(:read).returns("!epicfail")
346
+ assert_raises MonetDB::CommandError do
347
+ @connection.send(:set_reply_size)
348
+ end
349
+ end
350
+ end
351
+ end
352
+
353
+ describe "when already set" do
354
+ it "returns false" do
355
+ @connection.instance_variable_set(:@reply_size_set, true)
356
+ assert_equal false, @connection.send(:set_reply_size)
357
+ end
358
+ end
359
+ end
360
+ end
361
+
362
+ end
363
+ end
364
+ end