tiny_tds 2.1.2 → 2.1.7

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.
data/test/result_test.rb CHANGED
@@ -80,7 +80,7 @@ class ResultTest < TinyTds::TestCase
80
80
  @client.execute("DELETE FROM [datatypes]").do
81
81
  @client.execute("INSERT INTO [datatypes] ([char_10], [varchar_50]) VALUES ('1', '2')").do
82
82
  result = @client.execute("SELECT TOP (1) [char_10] + 'test' + [varchar_50] AS [test] FROM [datatypes]").each.first['test']
83
- result.must_equal "1 test2"
83
+ _(result).must_equal "1 test2"
84
84
  end
85
85
  end
86
86
 
@@ -135,10 +135,10 @@ class ResultTest < TinyTds::TestCase
135
135
  text = 'test affected rows sql'
136
136
  @client.execute("DELETE FROM [datatypes]").do
137
137
  afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
138
- ['Fixnum', 'Integer'].must_include afrows.class.name
138
+ _(['Fixnum', 'Integer']).must_include afrows.class.name
139
139
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
140
140
  pk1 = @client.execute(@client.identity_sql).each.first['Ident']
141
- ['Fixnum', 'Integer'].must_include pk1.class.name, 'we it be able to CAST to bigint'
141
+ _(['Fixnum', 'Integer']).must_include pk1.class.name, 'we it be able to CAST to bigint'
142
142
  @client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
143
143
  afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
144
144
  assert_equal 1, afrows
@@ -215,34 +215,34 @@ class ResultTest < TinyTds::TestCase
215
215
  @client.execute("DELETE FROM [datatypes]").do
216
216
  @client.execute("ROLLBACK TRANSACTION").do
217
217
  count = @client.execute("SELECT COUNT(*) AS [count] FROM [datatypes]").each.first['count']
218
- 0.wont_equal count
218
+ _(count).wont_equal 0
219
219
  end
220
220
 
221
221
  it 'has a #fields accessor with logic default and valid outcome' do
222
222
  result = @client.execute(@query1)
223
- result.fields.must_equal ['one']
223
+ _(result.fields).must_equal ['one']
224
224
  result.each
225
- result.fields.must_equal ['one']
225
+ _(result.fields).must_equal ['one']
226
226
  end
227
227
 
228
228
  it 'always returns an array for fields for all sql' do
229
229
  result = @client.execute("USE [tinytdstest]")
230
- result.fields.must_equal []
230
+ _(result.fields).must_equal []
231
231
  result.do
232
- result.fields.must_equal []
232
+ _(result.fields).must_equal []
233
233
  end
234
234
 
235
235
  it 'returns fields even when no results are found' do
236
236
  no_results_query = "SELECT [id], [varchar_50] FROM [datatypes] WHERE [varchar_50] = 'NOTFOUND'"
237
237
  # Fields before each.
238
238
  result = @client.execute(no_results_query)
239
- result.fields.must_equal ['id','varchar_50']
239
+ _(result.fields).must_equal ['id','varchar_50']
240
240
  result.each
241
- result.fields.must_equal ['id','varchar_50']
241
+ _(result.fields).must_equal ['id','varchar_50']
242
242
  # Each then fields
243
243
  result = @client.execute(no_results_query)
244
244
  result.each
245
- result.fields.must_equal ['id','varchar_50']
245
+ _(result.fields).must_equal ['id','varchar_50']
246
246
  end
247
247
 
248
248
  it 'allows the result to be canceled before reading' do
@@ -254,27 +254,27 @@ class ResultTest < TinyTds::TestCase
254
254
  it 'works in tandem with the client when needing to find out if client has sql sent and result is canceled or not' do
255
255
  # Default state.
256
256
  @client = TinyTds::Client.new(connection_options)
257
- @client.sqlsent?.must_equal false
258
- @client.canceled?.must_equal false
257
+ _(@client.sqlsent?).must_equal false
258
+ _(@client.canceled?).must_equal false
259
259
  # With active result before and after cancel.
260
260
  result = @client.execute(@query1)
261
- @client.sqlsent?.must_equal true
262
- @client.canceled?.must_equal false
261
+ _(@client.sqlsent?).must_equal true
262
+ _(@client.canceled?).must_equal false
263
263
  result.cancel
264
- @client.sqlsent?.must_equal false
265
- @client.canceled?.must_equal true
264
+ _(@client.sqlsent?).must_equal false
265
+ _(@client.canceled?).must_equal true
266
266
  assert result.cancel, 'must be safe to call again'
267
267
  # With each and no block.
268
268
  @client.execute(@query1).each
269
- @client.sqlsent?.must_equal false
270
- @client.canceled?.must_equal false
269
+ _(@client.sqlsent?).must_equal false
270
+ _(@client.canceled?).must_equal false
271
271
  # With each and block.
272
272
  @client.execute(@query1).each do |row|
273
- @client.sqlsent?.must_equal true, 'when iterating over each row in a block'
274
- @client.canceled?.must_equal false
273
+ _(@client.sqlsent?).must_equal true, 'when iterating over each row in a block'
274
+ _(@client.canceled?).must_equal false
275
275
  end
276
- @client.sqlsent?.must_equal false
277
- @client.canceled?.must_equal false
276
+ _(@client.sqlsent?).must_equal false
277
+ _(@client.canceled?).must_equal false
278
278
  # With each and block canceled half way thru.
279
279
  count = @client.execute("SELECT COUNT([id]) AS [count] FROM [datatypes]").each[0]['count']
280
280
  assert count > 10, 'since we want to cancel early for test'
@@ -284,25 +284,25 @@ class ResultTest < TinyTds::TestCase
284
284
  break if index > 10
285
285
  index += 1
286
286
  end
287
- @client.sqlsent?.must_equal true
288
- @client.canceled?.must_equal false
287
+ _(@client.sqlsent?).must_equal true
288
+ _(@client.canceled?).must_equal false
289
289
  result.cancel
290
- @client.sqlsent?.must_equal false
291
- @client.canceled?.must_equal true
290
+ _(@client.sqlsent?).must_equal false
291
+ _(@client.canceled?).must_equal true
292
292
  # With do method.
293
293
  @client.execute(@query1).do
294
- @client.sqlsent?.must_equal false
295
- @client.canceled?.must_equal true
294
+ _(@client.sqlsent?).must_equal false
295
+ _(@client.canceled?).must_equal true
296
296
  # With insert method.
297
297
  rollback_transaction(@client) do
298
298
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('test')").insert
299
- @client.sqlsent?.must_equal false
300
- @client.canceled?.must_equal true
299
+ _(@client.sqlsent?).must_equal false
300
+ _(@client.canceled?).must_equal true
301
301
  end
302
302
  # With first
303
303
  @client.execute("SELECT [id] FROM [datatypes]").each(:first => true)
304
- @client.sqlsent?.must_equal false
305
- @client.canceled?.must_equal true
304
+ _(@client.sqlsent?).must_equal false
305
+ _(@client.canceled?).must_equal true
306
306
  end
307
307
 
308
308
  it 'use same string object for hash keys' do
@@ -337,7 +337,7 @@ class ResultTest < TinyTds::TestCase
337
337
 
338
338
  it 'with LOGINPROPERTY function' do
339
339
  v = @client.execute("SELECT LOGINPROPERTY('sa', 'IsLocked') as v").first['v']
340
- v.must_equal 0
340
+ _(v).must_equal 0
341
341
  end
342
342
 
343
343
  describe 'with multiple result sets' do
@@ -652,6 +652,48 @@ class ResultTest < TinyTds::TestCase
652
652
  assert_equal 1, messages.length, 'there should be one message after one print statement'
653
653
  assert_equal msg, m.message, 'message text'
654
654
  end
655
+
656
+ it 'must raise an error preceded by a `print` message' do
657
+ messages.clear
658
+ action = lambda { @client.execute("EXEC tinytds_TestPrintWithError").do }
659
+ assert_raise_tinytds_error(action) do |e|
660
+ assert_equal 'hello', messages.first.message, 'message text'
661
+
662
+ assert_equal "Error following print", e.message
663
+ assert_equal 16, e.severity
664
+ assert_equal 50000, e.db_error_number
665
+ end
666
+ end
667
+
668
+ it 'calls the provided message handler for each of a series of `print` messages' do
669
+ messages.clear
670
+ @client.execute("EXEC tinytds_TestSeveralPrints").do
671
+ assert_equal ['hello 1', 'hello 2', 'hello 3'], messages.map { |e| e.message }, 'message list'
672
+ end
673
+
674
+ it 'should flush info messages before raising error in cases of timeout' do
675
+ @client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
676
+ action = lambda { @client.execute("print 'hello'; waitfor delay '00:00:02'").do }
677
+ messages.clear
678
+ assert_raise_tinytds_error(action) do |e|
679
+ assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
680
+ assert_equal 6, e.severity
681
+ assert_equal 20003, e.db_error_number
682
+ assert_equal 'hello', messages.first&.message, 'message text'
683
+ end
684
+ end
685
+
686
+ it 'should print info messages before raising error in cases of timeout' do
687
+ @client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
688
+ action = lambda { @client.execute("raiserror('hello', 1, 1) with nowait; waitfor delay '00:00:02'").do }
689
+ messages.clear
690
+ assert_raise_tinytds_error(action) do |e|
691
+ assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
692
+ assert_equal 6, e.severity
693
+ assert_equal 20003, e.db_error_number
694
+ assert_equal 'hello', messages.first&.message, 'message text'
695
+ end
696
+ end
655
697
  end
656
698
 
657
699
  it 'must not raise an error when severity is 10 or less' do
@@ -684,7 +726,7 @@ class ResultTest < TinyTds::TestCase
684
726
  end
685
727
 
686
728
  it 'throws an error when you execute another query with other results pending' do
687
- result1 = @client.execute(@query1)
729
+ @client.execute(@query1)
688
730
  action = lambda { @client.execute(@query1) }
689
731
  assert_raise_tinytds_error(action) do |e|
690
732
  assert_match %r|with results pending|i, e.message
@@ -717,22 +759,22 @@ class ResultTest < TinyTds::TestCase
717
759
  it 'must not error at all from reading non-convertable charcters and just use ? marks' do
718
760
  close_client
719
761
  @client = new_connection :encoding => 'ASCII'
720
- @client.charset.must_equal 'ASCII'
721
- find_value(202, :nvarchar_50).must_equal 'test nvarchar_50 ??'
762
+ _(@client.charset).must_equal 'ASCII'
763
+ _(find_value(202, :nvarchar_50)).must_equal 'test nvarchar_50 ??'
722
764
  end
723
765
 
724
766
  it 'must error gracefully from writing non-convertable characters' do
725
767
  close_client
726
768
  @client = new_connection :encoding => 'ASCII'
727
- @client.charset.must_equal 'ASCII'
769
+ _(@client.charset).must_equal 'ASCII'
728
770
  rollback_transaction(@client) do
729
771
  text = 'Test ✓'
730
772
  @client.execute("DELETE FROM [datatypes] WHERE [nvarchar_50] IS NOT NULL").do
731
773
  action = lambda { @client.execute("INSERT INTO [datatypes] ([nvarchar_50]) VALUES ('#{text}')").do }
732
774
  assert_raise_tinytds_error(action) do |e|
733
- e.message.must_match %r{Unclosed quotation mark}i
734
- e.severity.must_equal 15
735
- e.db_error_number.must_equal 105
775
+ _(e.message).must_match %r{Unclosed quotation mark}i
776
+ _(e.severity).must_equal 15
777
+ _(e.db_error_number).must_equal 105
736
778
  end
737
779
  assert_followup_query
738
780
  end
@@ -770,4 +812,3 @@ class ResultTest < TinyTds::TestCase
770
812
  end
771
813
 
772
814
  end
773
-
data/test/schema_test.rb CHANGED
@@ -14,7 +14,7 @@ class SchemaTest < TinyTds::TestCase
14
14
  describe 'for shared types' do
15
15
 
16
16
  it 'casts bigint' do
17
- assert_equal -9223372036854775807, find_value(11, :bigint)
17
+ assert_equal (-9223372036854775807), find_value(11, :bigint)
18
18
  assert_equal 9223372036854775806, find_value(12, :bigint)
19
19
  end
20
20
 
@@ -96,7 +96,7 @@ class SchemaTest < TinyTds::TestCase
96
96
  end
97
97
 
98
98
  it 'casts int' do
99
- assert_equal -2147483647, find_value(151, :int)
99
+ assert_equal (-2147483647), find_value(151, :int)
100
100
  assert_equal 2147483646, find_value(152, :int)
101
101
  end
102
102
 
@@ -170,7 +170,7 @@ class SchemaTest < TinyTds::TestCase
170
170
  end
171
171
 
172
172
  it 'casts smallint' do
173
- assert_equal -32767, find_value(241, :smallint)
173
+ assert_equal (-32767), find_value(241, :smallint)
174
174
  assert_equal 32766, find_value(242, :smallint)
175
175
  end
176
176
 
@@ -396,15 +396,15 @@ class SchemaTest < TinyTds::TestCase
396
396
  if @client.tds_73?
397
397
  assertions = lambda {
398
398
  assert_instance_of Time, v
399
- assert_equal 1984, v.year, 'Year'
400
- assert_equal 1, v.month, 'Month'
401
- assert_equal 24, v.day, 'Day'
402
- assert_equal 4, v.hour, 'Hour'
403
- assert_equal 20, v.min, 'Minute'
404
- assert_equal 59, v.sec, 'Second'
405
- assert_equal 123456, v.usec, 'Microseconds'
406
- assert_equal 123456700, v.nsec, 'Nanoseconds'
407
- assert_equal -28800, v.utc_offset, 'Offset'
399
+ assert_equal 1984, v.year, 'Year'
400
+ assert_equal 1, v.month, 'Month'
401
+ assert_equal 24, v.day, 'Day'
402
+ assert_equal 4, v.hour, 'Hour'
403
+ assert_equal 20, v.min, 'Minute'
404
+ assert_equal 59, v.sec, 'Second'
405
+ assert_equal 123456, v.usec, 'Microseconds'
406
+ assert_equal 123456700, v.nsec, 'Nanoseconds'
407
+ assert_equal (-28800), v.utc_offset, 'Offset'
408
408
  }
409
409
  assertions.call
410
410
  v = find_value 84, :datetimeoffset_7, timezone: :local
@@ -0,0 +1,18 @@
1
+ :ON ERROR EXIT
2
+
3
+ PRINT 'RUNNING DB-CREATE.SQL, CREATING TINYTDS TEST DATABASE';
4
+ IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'tinytdstest')
5
+ BEGIN
6
+ CREATE DATABASE [tinytdstest];
7
+ END
8
+ GO
9
+
10
+ IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name LIKE 'tinytdstest')
11
+ BEGIN
12
+ PRINT 'TINY TDS TEST DB SUCCESSFULY CREATED';
13
+ END
14
+ ELSE
15
+ BEGIN
16
+ THROW 51000, 'TINY TDS TEST DB CREATION FAILED', 1;
17
+ END
18
+ GO
@@ -0,0 +1,38 @@
1
+ :ON ERROR EXIT
2
+
3
+ PRINT 'RUNNING DB-LOGIN.SQL';
4
+
5
+ PRINT 'CREATING TINYTDS TEST LOGIN';
6
+ IF NOT EXISTS (select name from sys.server_principals where name like 'tinytds')
7
+ BEGIN
8
+ CREATE LOGIN [tinytds] WITH PASSWORD = '', CHECK_POLICY = OFF, DEFAULT_DATABASE = [tinytdstest];
9
+ END
10
+ GO
11
+
12
+ IF EXISTS (select name from sys.server_principals where name like 'tinytds')
13
+ BEGIN
14
+ PRINT 'TINY TDS TEST LOGIN SUCCESSFULY CREATED';
15
+ END
16
+ ELSE
17
+ BEGIN
18
+ THROW 51000, 'TINY TDS TEST LOGIN CREATION FAILED', 1;
19
+ END
20
+ GO
21
+
22
+ USE [tinytdstest];
23
+ IF NOT EXISTS (select name from sys.database_principals where name LIKE 'tinytds')
24
+ BEGIN
25
+ CREATE USER [tinytds] FOR LOGIN [tinytds];
26
+ EXEC sp_addrolemember N'db_owner', N'tinytds';
27
+ END
28
+ GO
29
+
30
+ IF EXISTS (select name from sys.database_principals where name LIKE 'tinytds')
31
+ BEGIN
32
+ PRINT 'TINY TDS TEST USER SUCCESSFULY CREATED';
33
+ END
34
+ ELSE
35
+ BEGIN
36
+ THROW 51000, 'TINY TDS TEST USER CREATION FAILED', 1;
37
+ END
38
+ GO
data/test/test_helper.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'bundler' ; Bundler.require :development, :test
3
3
  require 'tiny_tds'
4
4
  require 'minitest/autorun'
5
+ require 'toxiproxy'
5
6
 
6
7
  TINYTDS_SCHEMAS = ['sqlserver_2000', 'sqlserver_2005', 'sqlserver_2008', 'sqlserver_2014', 'sqlserver_azure', 'sybase_ase'].freeze
7
8
 
@@ -93,7 +94,7 @@ module TinyTds
93
94
  end
94
95
 
95
96
  def assert_client_works(client)
96
- client.execute("SELECT 'client_works' as [client_works]").each.must_equal [{'client_works' => 'client_works'}]
97
+ _(client.execute("SELECT 'client_works' as [client_works]").each).must_equal [{'client_works' => 'client_works'}]
97
98
  end
98
99
 
99
100
  def assert_new_connections_work
@@ -153,6 +154,8 @@ module TinyTds
153
154
  loader.execute(drop_sql).do
154
155
  loader.execute(schema_sql).do
155
156
  loader.execute(sp_sql).do
157
+ loader.execute(sp_error_sql).do
158
+ loader.execute(sp_several_prints_sql).do
156
159
  loader.close
157
160
  true
158
161
  end
@@ -167,7 +170,16 @@ module TinyTds
167
170
  ) DROP TABLE datatypes
168
171
  IF EXISTS(
169
172
  SELECT 1 FROM sysobjects WHERE type = 'P' AND name = 'tinytds_TestReturnCodes'
170
- ) DROP PROCEDURE tinytds_TestReturnCodes|
173
+ ) DROP PROCEDURE tinytds_TestReturnCodes
174
+ IF EXISTS(
175
+ SELECT 1 FROM sysobjects WHERE type = 'P' AND name = 'tinytds_TestPrintWithError'
176
+ ) DROP PROCEDURE tinytds_TestPrintWithError
177
+ IF EXISTS(
178
+ SELECT 1 FROM sysobjects WHERE type = 'P' AND name = 'tinytds_TestPrintWithError'
179
+ ) DROP PROCEDURE tinytds_TestPrintWithError
180
+ IF EXISTS(
181
+ SELECT 1 FROM sysobjects WHERE type = 'P' AND name = 'tinytds_TestSeveralPrints'
182
+ ) DROP PROCEDURE tinytds_TestSeveralPrints|
171
183
  end
172
184
 
173
185
  def drop_sql_microsoft
@@ -181,7 +193,15 @@ module TinyTds
181
193
  IF EXISTS (
182
194
  SELECT name FROM sysobjects
183
195
  WHERE name = 'tinytds_TestReturnCodes' AND type = 'P'
184
- ) DROP PROCEDURE tinytds_TestReturnCodes|
196
+ ) DROP PROCEDURE tinytds_TestReturnCodes
197
+ IF EXISTS (
198
+ SELECT name FROM sysobjects
199
+ WHERE name = 'tinytds_TestPrintWithError' AND type = 'P'
200
+ ) DROP PROCEDURE tinytds_TestPrintWithError
201
+ IF EXISTS (
202
+ SELECT name FROM sysobjects
203
+ WHERE name = 'tinytds_TestSeveralPrints' AND type = 'P'
204
+ ) DROP PROCEDURE tinytds_TestSeveralPrints|
185
205
  end
186
206
 
187
207
  def sp_sql
@@ -191,6 +211,21 @@ module TinyTds
191
211
  RETURN(420) |
192
212
  end
193
213
 
214
+ def sp_error_sql
215
+ %|CREATE PROCEDURE tinytds_TestPrintWithError
216
+ AS
217
+ PRINT 'hello'
218
+ RAISERROR('Error following print', 16, 1)|
219
+ end
220
+
221
+ def sp_several_prints_sql
222
+ %|CREATE PROCEDURE tinytds_TestSeveralPrints
223
+ AS
224
+ PRINT 'hello 1'
225
+ PRINT 'hello 2'
226
+ PRINT 'hello 3'|
227
+ end
228
+
194
229
  def find_value(id, column, query_options={})
195
230
  query_options[:timezone] ||= :utc
196
231
  sql = "SELECT [#{column}] FROM [datatypes] WHERE [id] = #{id}"
@@ -212,6 +247,34 @@ module TinyTds
212
247
  client.execute("ROLLBACK TRANSACTION").do
213
248
  end
214
249
 
250
+ def init_toxiproxy
251
+ # In order for toxiproxy to work for local docker instances of mssql, the containers must be on the same network
252
+ # and the host used below must match the mssql container name so toxiproxy knows where to proxy to.
253
+ # localhost from the perspective of toxiproxy's container is its own container an *not* the mssql container it needs to proxy to.
254
+ # docker-compose.yml handles this automatically for us. In instances where someone is using their own local mssql container they'll
255
+ # need to set up the networks manually and set TINYTDS_UNIT_HOST to their mssql container name
256
+ # For anything other than localhost just use the environment config
257
+ toxi_host = ENV['TOXIPROXY_HOST'] || 'localhost'
258
+ toxi_api_port = 8474
259
+ toxi_test_port = 1234
260
+ Toxiproxy.host = "http://#{toxi_host}:#{toxi_api_port}"
261
+
262
+ toxi_upstream_host = ENV['TINYTDS_UNIT_HOST_TEST'] || ENV['TINYTDS_UNIT_HOST'] || 'localhost'
263
+ toxi_upstream_port = ENV['TINYTDS_UNIT_PORT'] || 1433
264
+
265
+ puts "\n-------------------------"
266
+ puts "Toxiproxy api listener: #{toxi_host}:#{toxi_api_port}"
267
+ puts "Toxiproxy unit test listener: #{toxi_host}:#{toxi_test_port}"
268
+ puts "Toxiproxy upstream sqlserver: #{toxi_upstream_host}:#{toxi_upstream_port}"
269
+ puts '-------------------------'
270
+
271
+ Toxiproxy.populate([
272
+ {
273
+ name: "sqlserver_test",
274
+ listen: "#{toxi_host}:#{toxi_test_port}",
275
+ upstream: "#{toxi_upstream_host}:#{toxi_upstream_port}"
276
+ }
277
+ ])
278
+ end
215
279
  end
216
280
  end
217
-
data/test/thread_test.rb CHANGED
@@ -49,7 +49,7 @@ class ThreadTest < TinyTds::TestCase
49
49
  begin
50
50
  result = client.execute "select dbname()"
51
51
  result.each { |r| puts r }
52
- rescue Exception => e
52
+ rescue Exception => _e
53
53
  # We are throwing an error on purpose here since 0.6.1 would
54
54
  # segfault on errors thrown in threads
55
55
  end
data/tiny_tds.gemspec CHANGED
@@ -20,10 +20,12 @@ Gem::Specification.new do |s|
20
20
  s.license = 'MIT'
21
21
  s.required_ruby_version = '>= 2.0.0'
22
22
  s.metadata['msys2_mingw_dependencies'] = 'freetds'
23
- s.add_development_dependency 'mini_portile2', '~> 2.0'
24
- s.add_development_dependency 'rake', '~> 10.4'
25
- s.add_development_dependency 'rake-compiler', '~> 1.0'
26
- s.add_development_dependency 'rake-compiler-dock', '~> 0.6.3'
27
- s.add_development_dependency 'minitest', '~> 5.6'
28
- s.add_development_dependency 'connection_pool', '~> 2.2'
23
+ s.add_development_dependency 'mini_portile2', '~> 2.5.0'
24
+ s.add_development_dependency 'rake', '~> 13.0.0'
25
+ s.add_development_dependency 'rake-compiler', '~> 1.2'
26
+ s.add_development_dependency 'rake-compiler-dock', '~> 1.4.0'
27
+ s.add_development_dependency 'minitest', '~> 5.14.0'
28
+ s.add_development_dependency 'minitest-ci', '~> 3.4.0'
29
+ s.add_development_dependency 'connection_pool', '~> 2.2.0'
30
+ s.add_development_dependency 'toxiproxy', '~> 2.0.0'
29
31
  end