sequel 4.41.0 → 4.42.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.
- checksums.yaml +4 -4
- data/CHANGELOG +98 -0
- data/README.rdoc +23 -10
- data/doc/active_record.rdoc +4 -4
- data/doc/advanced_associations.rdoc +2 -2
- data/doc/association_basics.rdoc +5 -2
- data/doc/cheat_sheet.rdoc +3 -3
- data/doc/core_extensions.rdoc +2 -2
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/migration.rdoc +19 -1
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/release_notes/4.42.0.txt +221 -0
- data/doc/testing.rdoc +3 -1
- data/lib/sequel/adapters/ado/access.rb +0 -1
- data/lib/sequel/adapters/ado/mssql.rb +0 -1
- data/lib/sequel/adapters/do/mysql.rb +0 -1
- data/lib/sequel/adapters/do/postgres.rb +0 -1
- data/lib/sequel/adapters/do/sqlite3.rb +0 -1
- data/lib/sequel/adapters/ibmdb.rb +21 -25
- data/lib/sequel/adapters/jdbc.rb +8 -16
- data/lib/sequel/adapters/jdbc/as400.rb +0 -1
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
- data/lib/sequel/adapters/jdbc/db2.rb +0 -1
- data/lib/sequel/adapters/jdbc/derby.rb +0 -1
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
- data/lib/sequel/adapters/jdbc/h2.rb +0 -1
- data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
- data/lib/sequel/adapters/mock.rb +54 -12
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +11 -17
- data/lib/sequel/adapters/odbc/mssql.rb +0 -1
- data/lib/sequel/adapters/oracle.rb +8 -20
- data/lib/sequel/adapters/postgres.rb +11 -29
- data/lib/sequel/adapters/shared/access.rb +5 -12
- data/lib/sequel/adapters/shared/cubrid.rb +4 -13
- data/lib/sequel/adapters/shared/db2.rb +4 -2
- data/lib/sequel/adapters/shared/firebird.rb +2 -4
- data/lib/sequel/adapters/shared/informix.rb +4 -2
- data/lib/sequel/adapters/shared/mssql.rb +3 -5
- data/lib/sequel/adapters/shared/mysql.rb +4 -14
- data/lib/sequel/adapters/shared/oracle.rb +1 -3
- data/lib/sequel/adapters/shared/postgres.rb +16 -38
- data/lib/sequel/adapters/shared/progress.rb +0 -2
- data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
- data/lib/sequel/adapters/shared/sqlite.rb +20 -16
- data/lib/sequel/adapters/sqlite.rb +8 -20
- data/lib/sequel/adapters/swift/mysql.rb +0 -1
- data/lib/sequel/adapters/swift/postgres.rb +0 -1
- data/lib/sequel/adapters/swift/sqlite.rb +0 -1
- data/lib/sequel/adapters/tinytds.rb +4 -12
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
- data/lib/sequel/ast_transformer.rb +2 -2
- data/lib/sequel/database/dataset.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +0 -66
- data/lib/sequel/database/features.rb +6 -0
- data/lib/sequel/database/misc.rb +31 -17
- data/lib/sequel/database/query.rb +7 -4
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset.rb +8 -8
- data/lib/sequel/dataset/actions.rb +140 -46
- data/lib/sequel/dataset/features.rb +1 -5
- data/lib/sequel/dataset/graph.rb +7 -8
- data/lib/sequel/dataset/misc.rb +127 -56
- data/lib/sequel/dataset/mutation.rb +9 -20
- data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
- data/lib/sequel/dataset/prepared_statements.rb +102 -46
- data/lib/sequel/dataset/query.rb +155 -72
- data/lib/sequel/dataset/sql.rb +26 -9
- data/lib/sequel/extensions/columns_introspection.rb +3 -1
- data/lib/sequel/extensions/core_extensions.rb +5 -5
- data/lib/sequel/extensions/core_refinements.rb +5 -5
- data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
- data/lib/sequel/extensions/freeze_datasets.rb +69 -0
- data/lib/sequel/extensions/identifier_mangling.rb +196 -0
- data/lib/sequel/extensions/looser_typecasting.rb +11 -7
- data/lib/sequel/extensions/migration.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +5 -2
- data/lib/sequel/extensions/pagination.rb +42 -23
- data/lib/sequel/extensions/pg_enum.rb +3 -3
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
- data/lib/sequel/model/associations.rb +25 -8
- data/lib/sequel/model/base.rb +88 -29
- data/lib/sequel/model/dataset_module.rb +37 -0
- data/lib/sequel/plugins/association_pks.rb +4 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/constraint_validations.rb +1 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +8 -8
- data/lib/sequel/plugins/eager_each.rb +2 -2
- data/lib/sequel/plugins/instance_filters.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/list.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -4
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +13 -13
- data/lib/sequel/plugins/sharding.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +2 -2
- data/lib/sequel/sql.rb +69 -36
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +10 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +4 -5
- data/spec/adapters/mysql_spec.rb +9 -9
- data/spec/adapters/postgres_spec.rb +67 -68
- data/spec/adapters/spec_helper.rb +6 -1
- data/spec/adapters/sqlite_spec.rb +29 -15
- data/spec/core/connection_pool_spec.rb +14 -14
- data/spec/core/database_spec.rb +38 -180
- data/spec/core/dataset_mutation_spec.rb +253 -0
- data/spec/core/dataset_spec.rb +394 -537
- data/spec/core/expression_filters_spec.rb +34 -32
- data/spec/core/mock_adapter_spec.rb +27 -35
- data/spec/core/placeholder_literalizer_spec.rb +2 -4
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +1 -2
- data/spec/core_extensions_spec.rb +22 -29
- data/spec/extensions/active_model_spec.rb +6 -6
- data/spec/extensions/association_dependencies_spec.rb +2 -2
- data/spec/extensions/blacklist_security_spec.rb +3 -3
- data/spec/extensions/boolean_readers_spec.rb +12 -12
- data/spec/extensions/caching_spec.rb +13 -10
- data/spec/extensions/class_table_inheritance_spec.rb +38 -43
- data/spec/extensions/column_conflicts_spec.rb +1 -3
- data/spec/extensions/columns_introspection_spec.rb +2 -3
- data/spec/extensions/composition_spec.rb +5 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
- data/spec/extensions/constraint_validations_spec.rb +14 -8
- data/spec/extensions/core_refinements_spec.rb +22 -29
- data/spec/extensions/csv_serializer_spec.rb +7 -6
- data/spec/extensions/date_arithmetic_spec.rb +15 -15
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +1 -1
- data/spec/extensions/dirty_spec.rb +19 -10
- data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
- data/spec/extensions/eager_each_spec.rb +12 -16
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +4 -3
- data/spec/extensions/force_encoding_spec.rb +12 -12
- data/spec/extensions/freeze_datasets_spec.rb +31 -0
- data/spec/extensions/graph_each_spec.rb +6 -18
- data/spec/extensions/hook_class_methods_spec.rb +7 -7
- data/spec/extensions/identifier_mangling_spec.rb +307 -0
- data/spec/extensions/instance_filters_spec.rb +5 -6
- data/spec/extensions/instance_hooks_spec.rb +12 -12
- data/spec/extensions/json_serializer_spec.rb +12 -15
- data/spec/extensions/lazy_attributes_spec.rb +4 -4
- data/spec/extensions/list_spec.rb +19 -21
- data/spec/extensions/many_through_many_spec.rb +108 -163
- data/spec/extensions/meta_def_spec.rb +7 -2
- data/spec/extensions/migration_spec.rb +10 -12
- data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
- data/spec/extensions/named_timezones_spec.rb +4 -3
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +17 -12
- data/spec/extensions/optimistic_locking_spec.rb +4 -5
- data/spec/extensions/pagination_spec.rb +8 -10
- data/spec/extensions/pg_array_associations_spec.rb +28 -27
- data/spec/extensions/pg_array_ops_spec.rb +2 -1
- data/spec/extensions/pg_array_spec.rb +6 -2
- data/spec/extensions/pg_enum_spec.rb +5 -3
- data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
- data/spec/extensions/pg_hstore_spec.rb +7 -6
- data/spec/extensions/pg_inet_ops_spec.rb +2 -1
- data/spec/extensions/pg_inet_spec.rb +2 -1
- data/spec/extensions/pg_interval_spec.rb +2 -1
- data/spec/extensions/pg_json_ops_spec.rb +2 -1
- data/spec/extensions/pg_json_spec.rb +6 -3
- data/spec/extensions/pg_loose_count_spec.rb +1 -0
- data/spec/extensions/pg_range_ops_spec.rb +3 -1
- data/spec/extensions/pg_range_spec.rb +9 -5
- data/spec/extensions/pg_row_ops_spec.rb +2 -1
- data/spec/extensions/pg_row_plugin_spec.rb +4 -6
- data/spec/extensions/pg_row_spec.rb +5 -3
- data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
- data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +12 -11
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +8 -5
- data/spec/extensions/rcte_tree_spec.rb +39 -39
- data/spec/extensions/round_timestamps_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +3 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +1 -2
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
- data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
- data/spec/extensions/serialization_spec.rb +15 -13
- data/spec/extensions/set_overrides_spec.rb +14 -8
- data/spec/extensions/sharding_spec.rb +9 -18
- data/spec/extensions/shared_caching_spec.rb +3 -4
- data/spec/extensions/single_table_inheritance_spec.rb +11 -11
- data/spec/extensions/skip_create_refresh_spec.rb +2 -1
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/extensions/split_values_spec.rb +2 -2
- data/spec/extensions/sql_comments_spec.rb +6 -0
- data/spec/extensions/static_cache_spec.rb +7 -9
- data/spec/extensions/string_agg_spec.rb +30 -29
- data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
- data/spec/extensions/thread_local_timezones_spec.rb +2 -2
- data/spec/extensions/timestamps_spec.rb +28 -3
- data/spec/extensions/to_dot_spec.rb +1 -2
- data/spec/extensions/tree_spec.rb +33 -29
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -0
- data/spec/extensions/update_primary_key_spec.rb +11 -7
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +0 -1
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +10 -10
- data/spec/extensions/validation_helpers_spec.rb +10 -10
- data/spec/extensions/xml_serializer_spec.rb +7 -3
- data/spec/integration/associations_test.rb +31 -31
- data/spec/integration/dataset_test.rb +17 -19
- data/spec/integration/eager_loader_test.rb +24 -24
- data/spec/integration/model_test.rb +6 -6
- data/spec/integration/plugin_test.rb +43 -43
- data/spec/integration/prepared_statement_test.rb +6 -6
- data/spec/integration/schema_test.rb +63 -52
- data/spec/integration/spec_helper.rb +6 -1
- data/spec/integration/transaction_test.rb +13 -13
- data/spec/model/association_reflection_spec.rb +17 -17
- data/spec/model/associations_spec.rb +101 -96
- data/spec/model/base_spec.rb +175 -49
- data/spec/model/class_dataset_methods_spec.rb +5 -9
- data/spec/model/dataset_methods_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +209 -235
- data/spec/model/hooks_spec.rb +15 -15
- data/spec/model/model_spec.rb +28 -21
- data/spec/model/plugins_spec.rb +4 -5
- data/spec/model/record_spec.rb +59 -57
- data/spec/model/spec_helper.rb +1 -1
- data/spec/model/validations_spec.rb +6 -6
- data/spec/spec_config.rb +1 -1
- metadata +10 -2
|
@@ -11,9 +11,14 @@ describe "Sequel::Metaprogramming" do
|
|
|
11
11
|
o = Sequel::Database.new
|
|
12
12
|
o.meta_def(:foo){4}
|
|
13
13
|
o.foo.must_equal 4
|
|
14
|
+
|
|
14
15
|
o = o[:a]
|
|
15
|
-
|
|
16
|
-
o.
|
|
16
|
+
# SEQUEL5: Remove
|
|
17
|
+
unless o.frozen?
|
|
18
|
+
o.meta_def(:foo){5}
|
|
19
|
+
o.foo.must_equal 5
|
|
20
|
+
end
|
|
21
|
+
|
|
17
22
|
o = Sequel::Model.new
|
|
18
23
|
o.meta_def(:foo){6}
|
|
19
24
|
o.foo.must_equal 6
|
|
@@ -54,8 +54,8 @@ describe "Migration.apply" do
|
|
|
54
54
|
|
|
55
55
|
it "should have default up and down actions that do nothing" do
|
|
56
56
|
m = Class.new(Sequel::Migration)
|
|
57
|
-
m.apply(@db, :up).
|
|
58
|
-
m.apply(@db, :down).
|
|
57
|
+
m.apply(@db, :up).must_be_nil
|
|
58
|
+
m.apply(@db, :down).must_be_nil
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
it "should respond to the methods the database responds to" do
|
|
@@ -89,8 +89,8 @@ describe "SimpleMigration#apply" do
|
|
|
89
89
|
|
|
90
90
|
it "should have default up and down actions that do nothing" do
|
|
91
91
|
m = Sequel.migration{}
|
|
92
|
-
m.apply(@db, :up).
|
|
93
|
-
m.apply(@db, :down).
|
|
92
|
+
m.apply(@db, :up).must_be_nil
|
|
93
|
+
m.apply(@db, :down).must_be_nil
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -252,15 +252,13 @@ describe "Sequel::IntegerMigrator" do
|
|
|
252
252
|
end
|
|
253
253
|
|
|
254
254
|
def dataset
|
|
255
|
-
|
|
256
|
-
ds.extend(Module.new do
|
|
255
|
+
super.with_extend do
|
|
257
256
|
def count; 1; end
|
|
258
257
|
def columns; db.columns_created end
|
|
259
258
|
def insert(h); db.versions.merge!(h); db.run insert_sql(h) end
|
|
260
259
|
def update(h); db.versions.merge!(h); db.run update_sql(h) end
|
|
261
260
|
def fetch_rows(sql); db.execute(sql); yield(db.versions) unless db.versions.empty? end
|
|
262
|
-
end
|
|
263
|
-
ds
|
|
261
|
+
end
|
|
264
262
|
end
|
|
265
263
|
|
|
266
264
|
def table_exists?(name)
|
|
@@ -513,7 +511,6 @@ describe "Sequel::TimestampMigrator" do
|
|
|
513
511
|
end
|
|
514
512
|
dbc = Class.new(Sequel::Mock::Database) do
|
|
515
513
|
self::Tables = tables= {}
|
|
516
|
-
define_method(:dataset){|*a| dsc.new(self, *a)}
|
|
517
514
|
def create_table(name, *args, &block)
|
|
518
515
|
super
|
|
519
516
|
self.class::Tables[name.to_sym] = true
|
|
@@ -522,6 +519,7 @@ describe "Sequel::TimestampMigrator" do
|
|
|
522
519
|
define_method(:table_exists?){|name| super(name); tables.has_key?(name.to_sym)}
|
|
523
520
|
end
|
|
524
521
|
@db = dbc.new
|
|
522
|
+
@db.dataset_class = dsc
|
|
525
523
|
@m = Sequel::Migrator
|
|
526
524
|
end
|
|
527
525
|
|
|
@@ -739,9 +737,9 @@ describe "Sequel::TimestampMigrator" do
|
|
|
739
737
|
|
|
740
738
|
it "should return nil" do
|
|
741
739
|
@dir = 'spec/files/timestamped_migrations'
|
|
742
|
-
@m.apply(@db, @dir, 1273253850).
|
|
743
|
-
@m.apply(@db, @dir, 0).
|
|
744
|
-
@m.apply(@db, @dir).
|
|
740
|
+
@m.apply(@db, @dir, 1273253850).must_be_nil
|
|
741
|
+
@m.apply(@db, @dir, 0).must_be_nil
|
|
742
|
+
@m.apply(@db, @dir).must_be_nil
|
|
745
743
|
end
|
|
746
744
|
|
|
747
745
|
it "should use TimestampMigrator if TimestampMigrator.apply is called even for integer migrations directory" do
|
|
@@ -3,7 +3,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
|
|
|
3
3
|
describe "MSSSQL optimistic locking plugin" do
|
|
4
4
|
before do
|
|
5
5
|
@db = Sequel.mock(:host=>'mssql')
|
|
6
|
-
@
|
|
6
|
+
@ds = @db[:items].with_quote_identifiers(false).with_extend{def input_identifier(v); v.to_s end}
|
|
7
|
+
@c = Class.new(Sequel::Model(@ds))
|
|
7
8
|
@c.columns :id, :name, :timestamp
|
|
8
9
|
@c.plugin :mssql_optimistic_locking
|
|
9
10
|
@o = @c.load(:id=>1, :name=>'a', :timestamp=>'1234')
|
|
@@ -49,7 +50,7 @@ describe "MSSSQL optimistic locking plugin" do
|
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
it "should allow changing the lock column via model.lock_column=" do
|
|
52
|
-
@c = Class.new(Sequel::Model(@
|
|
53
|
+
@c = Class.new(Sequel::Model(@ds))
|
|
53
54
|
@c.columns :id, :name, :lv
|
|
54
55
|
@c.plugin :mssql_optimistic_locking
|
|
55
56
|
@c.lock_column = :lv
|
|
@@ -66,7 +67,7 @@ describe "MSSSQL optimistic locking plugin" do
|
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
it "should allow changing the lock column via plugin option" do
|
|
69
|
-
@c = Class.new(Sequel::Model(@
|
|
70
|
+
@c = Class.new(Sequel::Model(@ds))
|
|
70
71
|
@c.columns :id, :name, :lv
|
|
71
72
|
@c.plugin :mssql_optimistic_locking, :lock_column=>:lv
|
|
72
73
|
@o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
|
|
@@ -44,9 +44,10 @@ describe "Sequel named_timezones extension" do
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it "should convert datetimes going into the database to named database_timezone" do
|
|
47
|
-
ds = @db[:a]
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
ds = @db[:a].with_extend do
|
|
48
|
+
def supports_timestamp_timezones?; true; end
|
|
49
|
+
def supports_timestamp_usecs?; false; end
|
|
50
|
+
end
|
|
50
51
|
ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,-7/24.0), DateTime.civil(2009,6,1,6,20,30,-1/6.0)])
|
|
51
52
|
@db.sqls.must_equal ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
|
|
52
53
|
end
|
|
@@ -326,7 +326,7 @@ describe "NestedAttributes plugin" do
|
|
|
326
326
|
ar.set(:albums_attributes=>[{:id=>10, :_remove=>'t'}])
|
|
327
327
|
ar.associations[:albums].must_equal []
|
|
328
328
|
@db.sqls.must_equal []
|
|
329
|
-
@Album.dataset
|
|
329
|
+
@Album.dataset = @Album.dataset.with_fetch(:id=>1)
|
|
330
330
|
ar.save
|
|
331
331
|
check_sql_array("SELECT 1 AS one FROM albums WHERE ((albums.artist_id = 20) AND (id = 10)) LIMIT 1",
|
|
332
332
|
["UPDATE albums SET artist_id = NULL, name = 'Al' WHERE (id = 10)", "UPDATE albums SET name = 'Al', artist_id = NULL WHERE (id = 10)"],
|
|
@@ -350,7 +350,7 @@ describe "NestedAttributes plugin" do
|
|
|
350
350
|
ar.associations[:concerts] = [co]
|
|
351
351
|
ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_remove=>'t'}])
|
|
352
352
|
@db.sqls.must_equal []
|
|
353
|
-
@Concert.dataset
|
|
353
|
+
@Concert.dataset = @Concert.dataset.with_fetch(:id=>1)
|
|
354
354
|
ar.save
|
|
355
355
|
check_sql_array(["SELECT 1 AS one FROM concerts WHERE ((concerts.artist_id = 10) AND (tour = 'To') AND (date = '2004-04-05')) LIMIT 1", "SELECT 1 AS one FROM concerts WHERE ((concerts.artist_id = 10) AND (date = '2004-04-05') AND (tour = 'To')) LIMIT 1"],
|
|
356
356
|
["UPDATE concerts SET artist_id = NULL, playlist = 'Pl' WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET playlist = 'Pl', artist_id = NULL WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET artist_id = NULL, playlist = 'Pl' WHERE ((date = '2004-04-05') AND (tour = 'To'))", "UPDATE concerts SET playlist = 'Pl', artist_id = NULL WHERE ((date = '2004-04-05') AND (tour = 'To'))"],
|
|
@@ -17,12 +17,12 @@ describe "null_dataset extension" do
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
it "should make fetch_rows be a noop" do
|
|
20
|
-
@ds.fetch_rows("SELECT 1", &@pr).
|
|
20
|
+
@ds.fetch_rows("SELECT 1", &@pr).must_be_nil
|
|
21
21
|
@i.must_equal 0
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it "should make insert be a noop" do
|
|
25
|
-
@ds.insert(1).
|
|
25
|
+
@ds.insert(1).must_be_nil
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it "should make update be a noop" do
|
|
@@ -34,19 +34,21 @@ describe "null_dataset extension" do
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it "should make truncate be a noop" do
|
|
37
|
-
@ds.truncate.
|
|
37
|
+
@ds.truncate.must_be_nil
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "should make execute_* be a noop" do
|
|
41
|
-
@ds.send(:execute_ddl,'FOO').
|
|
42
|
-
@ds.send(:execute_insert,'FOO').
|
|
43
|
-
@ds.send(:execute_dui,'FOO').
|
|
44
|
-
@ds.send(:execute,'FOO').
|
|
41
|
+
@ds.send(:execute_ddl,'FOO').must_be_nil
|
|
42
|
+
@ds.send(:execute_insert,'FOO').must_be_nil
|
|
43
|
+
@ds.send(:execute_dui,'FOO').must_be_nil
|
|
44
|
+
@ds.send(:execute,'FOO').must_be_nil
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "should have working columns" do
|
|
48
48
|
@skip_check = true
|
|
49
|
-
|
|
49
|
+
2.times do
|
|
50
|
+
@ds.columns.must_equal [:id]
|
|
51
|
+
end
|
|
50
52
|
@db.sqls.must_equal ['SELECT * FROM table LIMIT 1']
|
|
51
53
|
end
|
|
52
54
|
|
|
@@ -59,7 +61,7 @@ describe "null_dataset extension" do
|
|
|
59
61
|
end
|
|
60
62
|
|
|
61
63
|
it "should make import a noop" do
|
|
62
|
-
@ds.import([:id], [[1], [2], [3]]).
|
|
64
|
+
@ds.import([:id], [[1], [2], [3]]).must_be_nil
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
it "should have nullify method returned modified receiver" do
|
|
@@ -73,9 +75,12 @@ describe "null_dataset extension" do
|
|
|
73
75
|
|
|
74
76
|
it "should have nullify! method modify receiver" do
|
|
75
77
|
ds = @db[:table]
|
|
76
|
-
|
|
77
|
-
ds.
|
|
78
|
-
|
|
78
|
+
# SEQUEL5: Remove
|
|
79
|
+
unless ds.frozen?
|
|
80
|
+
ds.nullify!.must_be_same_as(ds)
|
|
81
|
+
ds.each(&@pr)
|
|
82
|
+
@i.must_equal 0
|
|
83
|
+
end
|
|
79
84
|
end
|
|
80
85
|
|
|
81
86
|
it "should work with method chaining" do
|
|
@@ -6,7 +6,7 @@ describe "optimistic_locking plugin" do
|
|
|
6
6
|
end
|
|
7
7
|
h = {1=>{:id=>1, :name=>'John', :lock_version=>2}}
|
|
8
8
|
lv = @lv = "lock_version".dup
|
|
9
|
-
@c.
|
|
9
|
+
@c.dataset = @c.dataset.with_numrows(proc do |sql|
|
|
10
10
|
case sql
|
|
11
11
|
when /UPDATE people SET (name|#{lv}) = ('Jim'|'Bob'|\d+), (?:name|#{lv}) = ('Jim'|'Bob'|\d+) WHERE \(\(id = (\d+)\) AND \(#{lv} = (\d+)\)\)/
|
|
12
12
|
name, nlv = $1 == 'name' ? [$2, $3] : [$3, $2]
|
|
@@ -36,13 +36,12 @@ describe "optimistic_locking plugin" do
|
|
|
36
36
|
else
|
|
37
37
|
puts sql
|
|
38
38
|
end
|
|
39
|
-
end
|
|
40
|
-
@c.instance_dataset._fetch = @c.dataset._fetch = proc do |sql|
|
|
39
|
+
end).with_fetch(proc do |sql|
|
|
41
40
|
m = h[1].dup
|
|
42
41
|
v = m.delete(:lock_version)
|
|
43
42
|
m[lv.to_sym] = v
|
|
44
43
|
m
|
|
45
|
-
end
|
|
44
|
+
end)
|
|
46
45
|
@c.columns :id, :name, :lock_version
|
|
47
46
|
@c.plugin :optimistic_locking
|
|
48
47
|
end
|
|
@@ -118,7 +117,7 @@ describe "optimistic_locking plugin" do
|
|
|
118
117
|
end
|
|
119
118
|
|
|
120
119
|
it "should not increment the lock column when the update fails" do
|
|
121
|
-
@c.
|
|
120
|
+
@c.dataset = @c.dataset.with_extend{def update(_) raise end}
|
|
122
121
|
p1 = @c[1]
|
|
123
122
|
p1.modified!
|
|
124
123
|
lv = p1.lock_version
|
|
@@ -2,9 +2,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "A paginated dataset" do
|
|
4
4
|
before do
|
|
5
|
-
@
|
|
6
|
-
@d.
|
|
7
|
-
|
|
5
|
+
count = @count = [153]
|
|
6
|
+
@d = Sequel.mock.dataset.extension(:pagination).with_extend{define_method(:count){count.first}}
|
|
8
7
|
@paginated = @d.paginate(1, 20)
|
|
9
8
|
end
|
|
10
9
|
|
|
@@ -24,7 +23,7 @@ describe "A paginated dataset" do
|
|
|
24
23
|
@paginated.page_count.must_equal 8
|
|
25
24
|
@d.paginate(1, 50).page_count.must_equal 4
|
|
26
25
|
|
|
27
|
-
@
|
|
26
|
+
@count[0] = 0
|
|
28
27
|
@d.paginate(1, 50).page_count.must_equal 1
|
|
29
28
|
end
|
|
30
29
|
|
|
@@ -35,11 +34,11 @@ describe "A paginated dataset" do
|
|
|
35
34
|
|
|
36
35
|
it "should return the next page number or nil if we're on the last" do
|
|
37
36
|
@paginated.next_page.must_equal 2
|
|
38
|
-
@d.paginate(4, 50).next_page.
|
|
37
|
+
@d.paginate(4, 50).next_page.must_be_nil
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
it "should return the previous page number or nil if we're on the first" do
|
|
42
|
-
@paginated.prev_page.
|
|
41
|
+
@paginated.prev_page.must_be_nil
|
|
43
42
|
@d.paginate(4, 50).prev_page.must_equal 3
|
|
44
43
|
end
|
|
45
44
|
|
|
@@ -67,7 +66,7 @@ describe "A paginated dataset" do
|
|
|
67
66
|
@d.paginate(5, 30).last_page?.must_equal false
|
|
68
67
|
@d.paginate(6, 30).last_page?.must_equal true
|
|
69
68
|
|
|
70
|
-
@
|
|
69
|
+
@count[0] = 0
|
|
71
70
|
@d.paginate(1, 30).last_page?.must_equal true
|
|
72
71
|
@d.paginate(2, 30).last_page?.must_equal false
|
|
73
72
|
end
|
|
@@ -80,15 +79,14 @@ describe "A paginated dataset" do
|
|
|
80
79
|
|
|
81
80
|
it "should work with fixed sql" do
|
|
82
81
|
ds = @d.clone(:sql => 'select * from blah')
|
|
83
|
-
|
|
82
|
+
@count[0] = 150
|
|
84
83
|
ds.paginate(2, 50).sql.must_equal 'SELECT * FROM (select * from blah) AS t1 LIMIT 50 OFFSET 50'
|
|
85
84
|
end
|
|
86
85
|
end
|
|
87
86
|
|
|
88
87
|
describe "Dataset#each_page" do
|
|
89
88
|
before do
|
|
90
|
-
@d = Sequel.mock
|
|
91
|
-
@d.meta_def(:count) {153}
|
|
89
|
+
@d = Sequel.mock[:items].extension(:pagination).with_extend{def count; 153 end}
|
|
92
90
|
end
|
|
93
91
|
|
|
94
92
|
it "should raise an error if the dataset already has a limit" do
|
|
@@ -3,6 +3,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
3
3
|
describe Sequel::Model, "pg_array_associations" do
|
|
4
4
|
before do
|
|
5
5
|
@db = Sequel.mock(:numrows=>1)
|
|
6
|
+
@db.extend_datasets{def quote_identifiers?; false end}
|
|
6
7
|
class ::Artist < Sequel::Model(@db)
|
|
7
8
|
attr_accessor :yyy
|
|
8
9
|
columns :id, :tag_ids
|
|
@@ -21,8 +22,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
21
22
|
end
|
|
22
23
|
@c1 = Artist
|
|
23
24
|
@c2 = Tag
|
|
24
|
-
@c1.dataset
|
|
25
|
-
@c2.dataset
|
|
25
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
26
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2)
|
|
26
27
|
@o1 = @c1.first
|
|
27
28
|
@o2 = @c2.first
|
|
28
29
|
@n1 = @c1.new
|
|
@@ -223,8 +224,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
223
224
|
it "should support a :uniq option that removes duplicates from the association" do
|
|
224
225
|
@c1.pg_array_to_many :tags, :clone=>:tags, :uniq=>true
|
|
225
226
|
@c2.many_to_pg_array :artists, :clone=>:artists, :uniq=>true
|
|
226
|
-
@c1.dataset
|
|
227
|
-
@c2.dataset
|
|
227
|
+
@c1.dataset = @c1.dataset.with_fetch([{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}])
|
|
228
|
+
@c2.dataset = @c1.dataset.with_fetch([{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}])
|
|
228
229
|
@o1.tags.must_equal [@c2.load(:id=>20), @c2.load(:id=>30)]
|
|
229
230
|
@o2.artists.must_equal [@c1.load(:id=>20), @c1.load(:id=>30)]
|
|
230
231
|
end
|
|
@@ -312,8 +313,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
312
313
|
@c1.pg_array_to_many :tags2, :clone=>:tags, :eager_graph=>:artists, :key=>:tag_ids
|
|
313
314
|
@c2.many_to_pg_array :artists2, :clone=>:artists, :eager_graph=>:tags
|
|
314
315
|
|
|
315
|
-
@c2.dataset
|
|
316
|
-
@c1.dataset
|
|
316
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
317
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
317
318
|
|
|
318
319
|
@o1.tags2.must_equal [@o2]
|
|
319
320
|
@db.sqls.first.must_match(/SELECT tags\.id, artists\.id AS artists_id, artists\.tag_ids FROM tags LEFT OUTER JOIN artists ON \(artists.tag_ids @> ARRAY\[tags.id\]\) WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
|
|
@@ -325,8 +326,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
325
326
|
@o2.artists2.first.tags.must_equal [@o2]
|
|
326
327
|
@db.sqls.must_equal []
|
|
327
328
|
|
|
328
|
-
@c2.dataset
|
|
329
|
-
@c1.dataset
|
|
329
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
330
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
330
331
|
|
|
331
332
|
a = @c1.eager(:tags2).all
|
|
332
333
|
sqls = @db.sqls
|
|
@@ -337,8 +338,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
337
338
|
a.first.tags2.first.artists.must_equal [@o1]
|
|
338
339
|
@db.sqls.must_equal []
|
|
339
340
|
|
|
340
|
-
@c2.dataset
|
|
341
|
-
@c1.dataset
|
|
341
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2)
|
|
342
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
342
343
|
|
|
343
344
|
a = @c2.eager(:artists2).all
|
|
344
345
|
@db.sqls.must_equal ["SELECT * FROM tags", "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
|
|
@@ -349,7 +350,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
349
350
|
end
|
|
350
351
|
|
|
351
352
|
it "should respect the :limit option when eager loading" do
|
|
352
|
-
@c2.dataset
|
|
353
|
+
@c2.dataset = @c2.dataset.with_fetch([{:id=>1},{:id=>2}, {:id=>3}])
|
|
353
354
|
|
|
354
355
|
@c1.pg_array_to_many :tags, :clone=>:tags, :limit=>2
|
|
355
356
|
a = @c1.eager(:tags).all
|
|
@@ -378,8 +379,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
378
379
|
a.first.tags.must_equal [@c2.load(:id=>2), @c2.load(:id=>3)]
|
|
379
380
|
@db.sqls.length.must_equal 0
|
|
380
381
|
|
|
381
|
-
@c2.dataset
|
|
382
|
-
@c1.dataset
|
|
382
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2)
|
|
383
|
+
@c1.dataset = @c1.dataset.with_fetch([{:id=>5, :tag_ids=>Sequel.pg_array([1,2,3])},{:id=>6, :tag_ids=>Sequel.pg_array([2,3])}, {:id=>7, :tag_ids=>Sequel.pg_array([1,2])}])
|
|
383
384
|
|
|
384
385
|
@c2.many_to_pg_array :artists, :clone=>:artists, :limit=>2
|
|
385
386
|
a = @c2.eager(:artists).all
|
|
@@ -414,8 +415,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
414
415
|
end
|
|
415
416
|
|
|
416
417
|
it "should eagerly graph associations" do
|
|
417
|
-
@c2.dataset
|
|
418
|
-
@c1.dataset
|
|
418
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
419
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
419
420
|
|
|
420
421
|
a = @c1.eager_graph(:tags).all
|
|
421
422
|
@db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
|
|
@@ -431,8 +432,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
431
432
|
end
|
|
432
433
|
|
|
433
434
|
it "should allow cascading of eager graphing for associations of associated models" do
|
|
434
|
-
@c2.dataset
|
|
435
|
-
@c1.dataset
|
|
435
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2)
|
|
436
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3]))
|
|
436
437
|
|
|
437
438
|
a = @c1.eager_graph(:tags=>:artists).all
|
|
438
439
|
@db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id, artists_0.id AS artists_0_id, artists_0.tag_ids AS artists_0_tag_ids FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) LEFT OUTER JOIN artists AS artists_0 ON (artists_0.tag_ids @> ARRAY[tags.id])"]
|
|
@@ -454,8 +455,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
454
455
|
@c1.pg_array_to_many :tags, :clone=>:tags, :primary_key=>Sequel.*(:id, 3), :primary_key_method=>:id3, :key=>:tag3_ids, :key_column=>Sequel.pg_array(:tag_ids)[1..2]
|
|
455
456
|
@c2.many_to_pg_array :artists, :clone=>:artists, :primary_key=>:id3, :key=>:tag3_ids, :key_column=>Sequel.pg_array(:tag_ids)[1..2]
|
|
456
457
|
|
|
457
|
-
@c2.dataset
|
|
458
|
-
@c1.dataset
|
|
458
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2)
|
|
459
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3]))
|
|
459
460
|
|
|
460
461
|
a = @c1.eager_graph(:tags).all
|
|
461
462
|
a.must_equal [@o1]
|
|
@@ -474,8 +475,8 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
474
475
|
@c1.pg_array_to_many :tags, :clone=>:tags, :graph_select=>:id2
|
|
475
476
|
@c2.many_to_pg_array :artists, :clone=>:artists, :graph_select=>:id
|
|
476
477
|
|
|
477
|
-
@c2.dataset
|
|
478
|
-
@c1.dataset
|
|
478
|
+
@c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1)
|
|
479
|
+
@c1.dataset = @c1.dataset.with_fetch(:id=>1, :id2=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
|
|
479
480
|
|
|
480
481
|
a = @c1.eager_graph(:tags).all
|
|
481
482
|
@db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id2 FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
|
|
@@ -606,7 +607,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
606
607
|
|
|
607
608
|
v = @c1.load(:id=>1)
|
|
608
609
|
v.remove_tag(@c2.load(:id=>4))
|
|
609
|
-
v.tag_ids.
|
|
610
|
+
v.tag_ids.must_be_nil
|
|
610
611
|
@db.sqls.must_equal []
|
|
611
612
|
v.save_changes
|
|
612
613
|
@db.sqls.must_equal []
|
|
@@ -616,7 +617,7 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
616
617
|
|
|
617
618
|
v = @c1.load(:id=>1)
|
|
618
619
|
v.remove_all_tags
|
|
619
|
-
v.tag_ids.
|
|
620
|
+
v.tag_ids.must_be_nil
|
|
620
621
|
@db.sqls.must_equal []
|
|
621
622
|
v.save_changes
|
|
622
623
|
@db.sqls.must_equal []
|
|
@@ -720,17 +721,17 @@ describe Sequel::Model, "pg_array_associations" do
|
|
|
720
721
|
t = @c2.load(:id=>2)
|
|
721
722
|
def a.validate() errors.add(:id, 'foo') end
|
|
722
723
|
a.associations[:tags] = []
|
|
723
|
-
a.add_tag(t).
|
|
724
|
+
a.add_tag(t).must_be_nil
|
|
724
725
|
a.tags.must_equal []
|
|
725
726
|
a.associations[:tags] = [t]
|
|
726
|
-
a.remove_tag(t).
|
|
727
|
+
a.remove_tag(t).must_be_nil
|
|
727
728
|
a.tags.must_equal [t]
|
|
728
729
|
|
|
729
730
|
t.associations[:artists] = []
|
|
730
|
-
t.add_artist(a).
|
|
731
|
+
t.add_artist(a).must_be_nil
|
|
731
732
|
t.artists.must_equal []
|
|
732
733
|
t.associations[:artists] = [a]
|
|
733
|
-
t.remove_artist(a).
|
|
734
|
+
t.remove_artist(a).must_be_nil
|
|
734
735
|
t.artists.must_equal [a]
|
|
735
736
|
end
|
|
736
737
|
end
|