sequel 5.18.0 → 5.20.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +40 -0
  3. data/doc/opening_databases.rdoc +5 -2
  4. data/doc/release_notes/5.19.0.txt +28 -0
  5. data/doc/release_notes/5.20.0.txt +89 -0
  6. data/doc/sharding.rdoc +12 -0
  7. data/doc/transactions.rdoc +38 -0
  8. data/lib/sequel/adapters/jdbc.rb +7 -2
  9. data/lib/sequel/adapters/mysql2.rb +2 -2
  10. data/lib/sequel/adapters/shared/postgres.rb +8 -8
  11. data/lib/sequel/adapters/shared/sqlite.rb +3 -1
  12. data/lib/sequel/adapters/sqlanywhere.rb +33 -17
  13. data/lib/sequel/adapters/sqlite.rb +20 -13
  14. data/lib/sequel/connection_pool.rb +0 -5
  15. data/lib/sequel/database/misc.rb +10 -9
  16. data/lib/sequel/database/query.rb +1 -1
  17. data/lib/sequel/database/schema_generator.rb +1 -1
  18. data/lib/sequel/database/transactions.rb +57 -5
  19. data/lib/sequel/dataset/actions.rb +6 -5
  20. data/lib/sequel/dataset/graph.rb +2 -2
  21. data/lib/sequel/dataset/placeholder_literalizer.rb +4 -1
  22. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  23. data/lib/sequel/dataset/query.rb +1 -1
  24. data/lib/sequel/extensions/constraint_validations.rb +14 -0
  25. data/lib/sequel/extensions/pg_enum.rb +23 -15
  26. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  27. data/lib/sequel/model/associations.rb +38 -12
  28. data/lib/sequel/model/base.rb +1 -1
  29. data/lib/sequel/model/plugins.rb +104 -0
  30. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  31. data/lib/sequel/plugins/association_pks.rb +14 -4
  32. data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
  33. data/lib/sequel/plugins/composition.rb +13 -9
  34. data/lib/sequel/plugins/finder.rb +2 -2
  35. data/lib/sequel/plugins/hook_class_methods.rb +17 -5
  36. data/lib/sequel/plugins/inverted_subsets.rb +2 -2
  37. data/lib/sequel/plugins/json_serializer.rb +3 -3
  38. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  39. data/lib/sequel/plugins/pg_array_associations.rb +8 -4
  40. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +61 -32
  41. data/lib/sequel/plugins/prepared_statements.rb +1 -1
  42. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
  43. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  44. data/lib/sequel/plugins/validation_class_methods.rb +5 -3
  45. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  46. data/lib/sequel/sql.rb +1 -1
  47. data/lib/sequel/version.rb +1 -1
  48. data/spec/adapters/postgres_spec.rb +40 -0
  49. data/spec/core/database_spec.rb +73 -2
  50. data/spec/core/schema_spec.rb +7 -1
  51. data/spec/extensions/class_table_inheritance_spec.rb +30 -8
  52. data/spec/extensions/constraint_validations_spec.rb +20 -2
  53. data/spec/extensions/core_refinements_spec.rb +1 -1
  54. data/spec/extensions/hook_class_methods_spec.rb +22 -0
  55. data/spec/extensions/migration_spec.rb +13 -0
  56. data/spec/extensions/pg_auto_constraint_validations_spec.rb +8 -0
  57. data/spec/extensions/pg_enum_spec.rb +5 -0
  58. data/spec/extensions/s_spec.rb +1 -1
  59. data/spec/extensions/schema_dumper_spec.rb +4 -2
  60. data/spec/integration/plugin_test.rb +15 -0
  61. data/spec/integration/transaction_test.rb +50 -0
  62. data/spec/model/associations_spec.rb +84 -4
  63. data/spec/model/plugins_spec.rb +111 -0
  64. metadata +7 -3
@@ -195,6 +195,19 @@ describe "Reversible Migrations with Sequel.migration{change{}}" do
195
195
  [:drop_table, :a, {:foo=>:bar}]]
196
196
  end
197
197
 
198
+ it "should reverse add_foreign_key with :type option" do
199
+ Sequel.migration{change{alter_table(:t){add_foreign_key :b, :c, :type=>:f}}}.apply(@db, :down)
200
+ actions = @db.actions
201
+ actions.must_equal [[:alter_table, [[:drop_foreign_key, :b, {:type=>:f}]]]]
202
+ @db.sqls
203
+ db = Sequel.mock
204
+ args = nil
205
+ db.define_singleton_method(:foreign_key_list){|*a| args = a; [{:name=>:fbc, :columns=>[:b]}]}
206
+ db.alter_table(:t){send(*actions[0][1][0])}
207
+ db.sqls.must_equal ["ALTER TABLE t DROP CONSTRAINT fbc", "ALTER TABLE t DROP COLUMN b"]
208
+ args.must_equal [:t]
209
+ end
210
+
198
211
  it "should reverse add_foreign_key with :foreign_key_constraint_name option" do
199
212
  Sequel.migration{change{alter_table(:t){add_foreign_key :b, :c, :foreign_key_constraint_name=>:f}}}.apply(@db, :down)
200
213
  actions = @db.actions
@@ -161,4 +161,12 @@ describe "pg_auto_constraint_validations plugin" do
161
161
  proc{o.save}.must_raise Sequel::ValidationFailed
162
162
  o.errors.must_equal(:i=>['is invalid'], :id=>['is invalid'])
163
163
  end
164
+
165
+ it "should handle overridden constraint failures as validation errors when updating" do
166
+ o = @c.load(:i=>3)
167
+ @c.pg_auto_constraint_validation_override(:items_i_ocheck, :i, "foo bar")
168
+ @set_error[Sequel::CheckConstraintViolation, :constraint=>'items_i_ocheck']
169
+ proc{o.update(:i=>12)}.must_raise Sequel::ValidationFailed
170
+ o.errors.must_equal(:i=>['foo bar'])
171
+ end
164
172
  end
@@ -49,6 +49,11 @@ describe "pg_enum extension" do
49
49
  @db.sqls.first.must_equal "ALTER TYPE sch.foo RENAME TO sch.bar"
50
50
  end
51
51
 
52
+ it "should support #rename_enum_value method for renameing an enum value" do
53
+ @db.rename_enum_value(:foo, :b, :x)
54
+ @db.sqls.first.must_equal "ALTER TYPE foo RENAME VALUE 'b' TO 'x'"
55
+ end
56
+
52
57
  it "should support #drop_enum method for dropping an enum" do
53
58
  @db.drop_enum(:foo)
54
59
  @db.sqls.first.must_equal "DROP TYPE foo"
@@ -29,7 +29,7 @@ describe "s extension as refinement" do
29
29
  end
30
30
 
31
31
 
32
- if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') # || (RUBY_VERSION >= '2.3.0' && RUBY_ENGINE == 'jruby')
32
+ if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') || (RUBY_ENGINE == 'jruby' && (JRUBY_VERSION >= '9.3' || (JRUBY_VERSION.match(/\A9\.2\.(\d+)/) && $1.to_i >= 7)))
33
33
  using Sequel::S
34
34
 
35
35
  describe "s extension as refinement" do
@@ -800,14 +800,16 @@ END_MIG
800
800
  it "should convert mysql types to ruby types" do
801
801
  def @d.schema(t, *o)
802
802
  i = 0
803
- ['double(15,2)', 'double(7,1) unsigned'].map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
803
+ ['float unsigned', 'double(15,2)', 'double(7,1) unsigned'].map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
804
804
  end
805
805
  @d.dump_table_schema(:x).must_equal((<<END_MIG).chomp)
806
806
  create_table(:x) do
807
807
  Float :c1
808
808
  Float :c2
809
+ Float :c3
809
810
 
810
- check Sequel::SQL::BooleanExpression.new(:>=, Sequel::SQL::Identifier.new(:c2), 0)
811
+ check Sequel::SQL::BooleanExpression.new(:>=, Sequel::SQL::Identifier.new(:c1), 0)
812
+ check Sequel::SQL::BooleanExpression.new(:>=, Sequel::SQL::Identifier.new(:c3), 0)
811
813
  end
812
814
  END_MIG
813
815
  end
@@ -30,6 +30,7 @@ describe "Class Table Inheritance Plugin" do
30
30
  end
31
31
  class ::Manager < Employee
32
32
  one_to_many :staff_members, :class=>:Staff
33
+ one_to_one :first_staff_member, :clone=>:staff_members, :order=>:id
33
34
  end
34
35
  class ::Executive < Manager
35
36
  end
@@ -150,6 +151,8 @@ describe "Class Table Inheritance Plugin" do
150
151
  m = Staff.first.manager
151
152
  m.must_equal Manager[@i4]
152
153
  m.must_be_kind_of(Executive)
154
+ Staff.first.update(:manager => Manager[@i3])
155
+ Staff.first.manager.must_equal Manager[@i3]
153
156
  end
154
157
 
155
158
  it "should handle eagerly loading many_to_one relationships" do
@@ -164,6 +167,18 @@ describe "Class Table Inheritance Plugin" do
164
167
 
165
168
  it "should handle one_to_many relationships" do
166
169
  Executive.first(:name=>'Ex').staff_members.must_equal [Staff[@i2]]
170
+ i6 = @db[:employees].insert(:name=>'S2', :kind=>'Staff')
171
+ @db[:staff].insert(:id=>i6, :manager_id=>@i4)
172
+ Executive.first(:name=>'Ex').add_staff_member(i6)
173
+ Executive.first(:name=>'Ex').staff_members{|ds| ds.order(:id)}.must_equal [Staff[@i2], Staff[i6]]
174
+ end
175
+
176
+ it "should handle one_to_many relationships" do
177
+ Executive.first(:name=>'Ex').first_staff_member.must_equal Staff[@i2]
178
+ i6 = @db[:employees].insert(:name=>'S2', :kind=>'Staff')
179
+ @db[:staff].insert(:id=>i6, :manager_id=>@i4)
180
+ Executive.first(:name=>'Ex').first_staff_member = Staff[i6]
181
+ Executive.first(:name=>'Ex').staff_members.must_equal [Staff[i6]]
167
182
  end
168
183
 
169
184
  it "should handle eagerly loading one_to_many relationships" do
@@ -496,6 +496,56 @@ describe "Database transactions" do
496
496
  @db.transaction{@db.transaction(:savepoint=>true){@db.after_rollback{c = 1}}; c.must_be_nil; raise Sequel::Rollback}
497
497
  c.must_equal 1
498
498
  end
499
+
500
+ it "should support after_commit inside savepoints with :savepoint_option" do
501
+ c = nil
502
+ @db.transaction{@db.transaction(:savepoint=>true){@db.after_commit(:savepoint=>true){c = 1}}; c.must_be_nil}
503
+ c.must_equal 1
504
+
505
+ c = nil
506
+ @db.transaction{@db.transaction(:savepoint=>true){@db.transaction(:savepoint=>true){@db.after_commit(:savepoint=>true){c = 1}}}; c.must_be_nil}
507
+ c.must_equal 1
508
+
509
+ c = nil
510
+ @db.transaction{@db.transaction(:savepoint=>true, :rollback=>:always){@db.after_commit(:savepoint=>true){c = 1}}}
511
+ c.must_be_nil
512
+
513
+ @db.transaction(:rollback=>:always){@db.transaction(:savepoint=>true){@db.after_commit(:savepoint=>true){c = 1}}}
514
+ c.must_be_nil
515
+
516
+ @db.transaction(:rollback=>:always){@db.transaction(:savepoint=>true){@db.transaction(:savepoint=>true){@db.after_commit(:savepoint=>true){c = 1}}}}
517
+ c.must_be_nil
518
+ end
519
+
520
+ it "should support after_rollback inside savepoints with :savepoint_option" do
521
+ c = nil
522
+ @db.transaction{@db.transaction(:savepoint=>true, :rollback=>:always){@db.after_rollback(:savepoint=>true){c = 1}; c.must_be_nil}; c.must_equal 1}
523
+ c.must_equal 1
524
+
525
+ c = nil
526
+ @db.transaction(:rollback=>:always){@db.transaction(:savepoint=>true){@db.after_rollback(:savepoint=>true){c = 1}}; c.must_be_nil}
527
+ c.must_equal 1
528
+
529
+ c = nil
530
+ @db.transaction(:rollback=>:always){@db.transaction(:savepoint=>true, :rollback=>:always){@db.after_rollback(:savepoint=>true){c = 1}; c.must_be_nil}; c.must_equal 1}
531
+ c.must_equal 1
532
+
533
+ c = nil
534
+ @db.transaction(:rollback=>:always){@db.transaction(:savepoint=>true){@db.after_rollback(:savepoint=>true){c = 1}}; c.must_be_nil}
535
+ c.must_equal 1
536
+
537
+ c = nil
538
+ @db.transaction(:rollback=>:always){@db.transaction(:savepoint=>true){@db.transaction(:savepoint=>true){@db.after_rollback(:savepoint=>true){c = 1}}; c.must_be_nil}}
539
+ c.must_equal 1
540
+
541
+ c = nil
542
+ @db.transaction(:rollback=>:always){@db.transaction(:savepoint=>true){@db.transaction(:savepoint=>true, :rollback=>:always){@db.after_rollback(:savepoint=>true){c = 1}; c.must_be_nil}; c.must_equal 1}}
543
+ c.must_equal 1
544
+
545
+ c = nil
546
+ @db.transaction{@db.transaction(:savepoint=>true, :rollback=>:always){@db.transaction(:savepoint=>true){@db.after_rollback(:savepoint=>true){c = 1}}; c.must_be_nil}; c.must_equal 1}
547
+ c.must_equal 1
548
+ end
499
549
  end
500
550
 
501
551
  if DB.supports_prepared_transactions?
@@ -99,13 +99,13 @@ describe Sequel::Model, "associate" do
99
99
  class ::ParParent < Sequel::Model; end
100
100
  klass = Class.new(Sequel::Model(:nodes))
101
101
 
102
- klass.many_to_one(:par_parent, :order=>:a){1}
103
- klass.one_to_many(:par_parent1s, :class=>'ParParent', :limit=>12){4}
104
- klass.many_to_many(:par_parent2s, :class=>:ParParent, :uniq=>true){2}
102
+ klass.many_to_one(:par_parent, :order=>:a){|ds| 1}
103
+ klass.one_to_many(:par_parent1s, :class=>'ParParent', :limit=>12){|ds| 4}
104
+ klass.many_to_many(:par_parent2s, :class=>:ParParent, :uniq=>true){|ds| 2}
105
105
 
106
106
  klass.many_to_one :par, :clone=>:par_parent, :select=>:b
107
107
  klass.one_to_many :par1s, :clone=>:par_parent1s, :order=>:b, :limit=>10, :block=>nil
108
- klass.many_to_many(:par2s, :clone=>:par_parent2s, :order=>:c){3}
108
+ klass.many_to_many(:par2s, :clone=>:par_parent2s, :order=>:c){|ds| 3}
109
109
  klass.many_to_one :par3, :clone=>:par
110
110
 
111
111
  klass.association_reflection(:par).associated_class.must_equal ParParent
@@ -861,6 +861,50 @@ describe Sequel::Model, "one_to_one" do
861
861
  "UPDATE attributes SET y = 5, node_id = 1234 WHERE (id = 3)"]
862
862
  end
863
863
 
864
+ it "should have setter method handle associations to models with joined datasets" do
865
+ db = Sequel.mock
866
+ c = Class.new(Sequel::Model(db)) do
867
+ set_dataset(db[:attributes].join(:foo, :attribute_id=>:id))
868
+ def _insert_dataset
869
+ db[:attributes]
870
+ end
871
+ def _update_dataset
872
+ db[:attributes].where(pk_hash)
873
+ end
874
+ @instance_dataset = dataset.limit(1).naked.skip_limit_check
875
+ unrestrict_primary_key
876
+ columns :id, :node_id, :y
877
+ end
878
+
879
+ @c2.one_to_one :attribute, :class => c
880
+ attrib = c.new(:id=>3)
881
+
882
+ db.fetch = [[], {:id=>3}]
883
+ @c2.load(:id => 1234).attribute = attrib
884
+ DB.sqls.must_equal []
885
+ db.sqls.must_equal [
886
+ "SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes LIMIT 1",
887
+ "SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (node_id = 1234) LIMIT 1",
888
+ "INSERT INTO attributes (id, node_id) VALUES (3, 1234)",
889
+ "SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (id = 3) LIMIT 1"]
890
+
891
+ db.fetch = [[{:id=>4}], {:id=>3, :node_id=>1234}]
892
+ db.numrows = 1
893
+ @c2.load(:id => 1234).attribute = c.load(:id=>3)
894
+ db.sqls.must_equal [
895
+ "SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (node_id = 1234) LIMIT 1",
896
+ "UPDATE attributes SET node_id = NULL WHERE (id = 4)",
897
+ "UPDATE attributes SET node_id = 1234 WHERE (id = 3)"]
898
+
899
+ db.fetch = [[{:id=>4}], {:id=>3, :node_id=>1234}]
900
+ @c2.load(:id => 1234).attribute = c.new(:id=>3)
901
+ db.sqls.must_equal [
902
+ "SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (node_id = 1234) LIMIT 1",
903
+ "UPDATE attributes SET node_id = NULL WHERE (id = 4)",
904
+ "INSERT INTO attributes (id, node_id) VALUES (3, 1234)",
905
+ "SELECT * FROM (SELECT * FROM attributes INNER JOIN foo ON (foo.attribute_id = attributes.id)) AS attributes WHERE (id = 3) LIMIT 1"]
906
+ end
907
+
864
908
  it "should use implicit key if omitted" do
865
909
  @c2.dataset = @c2.dataset.with_fetch({})
866
910
  @c2.one_to_one :parent, :class => @c2
@@ -958,6 +1002,42 @@ describe Sequel::Model, "one_to_one" do
958
1002
  DB.sqls.must_equal ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
959
1003
  end
960
1004
 
1005
+ it "should support :dataset options with different types of arity" do
1006
+ @c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{model.filter(:parent_id=>pk)}
1007
+ @c2.load(:id => 100).child_20
1008
+ DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
1009
+
1010
+ @c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|_| model.filter(:parent_id=>pk)}
1011
+ @c2.load(:id => 100).child_20
1012
+ DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
1013
+
1014
+ @c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|_, *| model.filter(:parent_id=>pk)}
1015
+ @c2.load(:id => 100).child_20
1016
+ DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
1017
+
1018
+ @c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|*| model.filter(:parent_id=>pk)}
1019
+ @c2.load(:id => 100).child_20
1020
+ DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
1021
+ end
1022
+
1023
+ deprecated "should support :dataset option that requires multiple arguments" do
1024
+ @c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{|_, _| model.filter(:parent_id=>pk)}
1025
+ @c2.load(:id => 100).child_20
1026
+ DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100) LIMIT 1"]
1027
+ end
1028
+
1029
+ deprecated "should support association block requires no arguments" do
1030
+ @c2.one_to_one :child_20, :class => @c2, :key=>:id do model.filter(:parent_id=>pk) end
1031
+ @c2.load(:id => 100).child_20
1032
+ DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100)"]
1033
+ end
1034
+
1035
+ deprecated "should support association block requires multiple arguments" do
1036
+ @c2.one_to_one :child_20, :class => @c2, :key=>:id do |_, _| model.filter(:parent_id=>pk) end
1037
+ @c2.load(:id => 100).child_20
1038
+ DB.sqls.must_equal ["SELECT * FROM nodes WHERE (parent_id = 100)"]
1039
+ end
1040
+
961
1041
  it "should return nil if primary_key value is nil" do
962
1042
  @c2.one_to_one :parent, :class => @c2, :primary_key=>:node_id
963
1043
 
@@ -316,3 +316,114 @@ describe "Sequel::Model.plugin" do
316
316
  a.must_equal ['sequel/plugins/something_or_other']
317
317
  end
318
318
  end
319
+
320
+ describe "Sequel::Plugins.def_sequel_method" do
321
+ before do
322
+ @m = Class.new
323
+ @scope = @m.new
324
+ end
325
+
326
+ it "should define methods using block" do
327
+ m0 = Sequel::Plugins.def_sequel_method(@m, "x", 0){1}
328
+ m0.must_be_kind_of Symbol
329
+ m0.must_match /\A_sequel_x_\d+\z/
330
+ @scope.send(m0).must_equal 1
331
+
332
+ m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|x| [x, 2]}
333
+ m1.must_be_kind_of Symbol
334
+ m1.must_match /\A_sequel_x_\d+\z/
335
+ @scope.send(m1, 3).must_equal [3, 2]
336
+ end
337
+
338
+ it "should define public methods" do
339
+ proc{@scope.public_send(Sequel::Plugins.def_sequel_method(@m, "x", 0){1})}.must_raise NoMethodError
340
+ end
341
+
342
+ it "should accept symbols as method name and return the same symbol" do
343
+ m0 = Sequel::Plugins.def_sequel_method(@m, :_roda_foo, 0){1}
344
+ m0.must_equal :_roda_foo
345
+ @scope.send(m0).must_equal 1
346
+ end
347
+
348
+ it "should handle optional arguments and splats for expected_arity 0" do
349
+ m2 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|*x| [x, 3]}
350
+ @scope.send(m2).must_equal [[], 3]
351
+
352
+ m3 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|x=5| [x, 4]}
353
+ @scope.send(m3).must_equal [5, 4]
354
+
355
+ m4 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|x=6, *y| [x, y, 5]}
356
+ @scope.send(m4).must_equal [6, [], 5]
357
+ end
358
+
359
+ it "should should optional arguments and splats for expected_arity 1" do
360
+ m2 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|y, *x| [y, x, 3]}
361
+ @scope.send(m2, :a).must_equal [:a, [], 3]
362
+
363
+ m3 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|y, x=5| [y, x, 4]}
364
+ @scope.send(m3, :b).must_equal [:b, 5, 4]
365
+
366
+ m4 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|y, x=6, *z| [y, x, z, 5]}
367
+ @scope.send(m4, :c).must_equal [:c, 6, [], 5]
368
+ end
369
+
370
+ deprecated "should handle differences in arity" do
371
+ m0 = Sequel::Plugins.def_sequel_method(@m, "x", 0){|x| [x, 1]}
372
+ @scope.send(m0).must_equal [nil, 1]
373
+
374
+ m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1){2}
375
+ @scope.send(m1, 3).must_equal 2
376
+
377
+ m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1){|x, y| [x, y]}
378
+ @scope.send(m1, 4).must_equal [4, nil]
379
+ end
380
+
381
+ it "should raise for unexpected expected_arity" do
382
+ proc{Sequel::Plugins.def_sequel_method(@m, "x", 2){|x|}}.must_raise Sequel::Error
383
+ end
384
+
385
+ it "should fail if a lambda with invalid arity is passed" do
386
+ m0 = Sequel::Plugins.def_sequel_method(@m, "x", 0, &lambda{|x| [x, 1]})
387
+ proc{@scope.send(m0)}.must_raise ArgumentError
388
+
389
+ m1 = Sequel::Plugins.def_sequel_method(@m, "x", 1, &lambda{2})
390
+ proc{@scope.send(m1, 1)}.must_raise ArgumentError
391
+ end
392
+
393
+ if RUBY_VERSION > '2.1'
394
+ it "should raise for required keyword arguments for expected_arity 0 or 1" do
395
+ proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|b:| [b, 1]}", binding)}.must_raise Sequel::Error
396
+ proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|c=1, b:| [c, b, 1]}", binding)}.must_raise Sequel::Error
397
+ proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, b:| [b, 1]}", binding)}.must_raise Sequel::Error
398
+ proc{eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, c=1, b:| [c, b, 1]}", binding)}.must_raise Sequel::Error
399
+ end
400
+
401
+ it "should ignore keyword arguments for expected_arity 0" do
402
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|b:2| [b, 1]}", binding)).must_equal [2, 1]
403
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|**b| [b, 1]}", binding)).must_equal [{}, 1]
404
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|c=1, b:2| [c, b, 1]}", binding)).must_equal [1, 2, 1]
405
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|c=1, **b| [c, b, 1]}", binding)).must_equal [1, {}, 1]
406
+ end
407
+
408
+ deprecated "should ignore keyword arguments for expected_arity 0 with invalid arity" do
409
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, b:2| [x, b, 1]}", binding)).must_equal [nil, 2, 1]
410
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, **b| [x, b, 1]}", binding)).must_equal [nil, {}, 1]
411
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, c=1, b:2| [x, c, b, 1]}", binding)).must_equal [nil, 1, 2, 1]
412
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 0){|x, c=1, **b| [x, c, b, 1]}", binding)).must_equal [nil, 1, {}, 1]
413
+ end
414
+
415
+ deprecated "should ignore keyword arguments for expected_arity 1 with invalid arity" do
416
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|b:2| [b, 1]}", binding), 3).must_equal [2, 1]
417
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|**b| [b, 1]}", binding), 3).must_equal [{}, 1]
418
+ end
419
+
420
+ it "should ignore keyword arguments for expected_arity 1" do
421
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|c=1, b:2| [c, b, 1]}", binding), 3).must_equal [3, 2, 1]
422
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|c=1, **b| [c, b, 1]}", binding), 3).must_equal [3, {}, 1]
423
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, b:2| [x, b, 1]}", binding), 3).must_equal [3, 2, 1]
424
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, **b| [x, b, 1]}", binding), 3).must_equal [3, {}, 1]
425
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, c=1, b:2| [x, c, b, 1]}", binding), 3).must_equal [3, 1, 2, 1]
426
+ @scope.send(eval("Sequel::Plugins.def_sequel_method(@m, 'x', 1){|x, c=1, **b| [x, c, b, 1]}", binding), 3).must_equal [3, 1, {}, 1]
427
+ end
428
+ end
429
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.18.0
4
+ version: 5.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-01 00:00:00.000000000 Z
11
+ date: 2019-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -202,6 +202,8 @@ extra_rdoc_files:
202
202
  - doc/release_notes/5.16.0.txt
203
203
  - doc/release_notes/5.17.0.txt
204
204
  - doc/release_notes/5.18.0.txt
205
+ - doc/release_notes/5.19.0.txt
206
+ - doc/release_notes/5.20.0.txt
205
207
  files:
206
208
  - CHANGELOG
207
209
  - MIT-LICENSE
@@ -290,7 +292,9 @@ files:
290
292
  - doc/release_notes/5.16.0.txt
291
293
  - doc/release_notes/5.17.0.txt
292
294
  - doc/release_notes/5.18.0.txt
295
+ - doc/release_notes/5.19.0.txt
293
296
  - doc/release_notes/5.2.0.txt
297
+ - doc/release_notes/5.20.0.txt
294
298
  - doc/release_notes/5.3.0.txt
295
299
  - doc/release_notes/5.4.0.txt
296
300
  - doc/release_notes/5.5.0.txt
@@ -845,7 +849,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
845
849
  - !ruby/object:Gem::Version
846
850
  version: '0'
847
851
  requirements: []
848
- rubygems_version: 3.0.1
852
+ rubygems_version: 3.0.3
849
853
  signing_key:
850
854
  specification_version: 4
851
855
  summary: The Database Toolkit for Ruby