composite_primary_keys 10.0.5 → 11.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +5 -5
  2. data/History.rdoc +2 -15
  3. data/README.rdoc +2 -1
  4. data/lib/composite_primary_keys.rb +7 -7
  5. data/lib/composite_primary_keys/arel/to_sql.rb +12 -6
  6. data/lib/composite_primary_keys/associations/association.rb +12 -14
  7. data/lib/composite_primary_keys/associations/association_scope.rb +7 -2
  8. data/lib/composite_primary_keys/associations/collection_association.rb +14 -5
  9. data/lib/composite_primary_keys/associations/foreign_association.rb +15 -0
  10. data/lib/composite_primary_keys/associations/has_many_association.rb +3 -15
  11. data/lib/composite_primary_keys/associations/has_many_through_association.rb +56 -58
  12. data/lib/composite_primary_keys/associations/join_dependency.rb +69 -71
  13. data/lib/composite_primary_keys/associations/preloader/association.rb +92 -75
  14. data/lib/composite_primary_keys/attribute_methods.rb +4 -6
  15. data/lib/composite_primary_keys/attribute_methods/primary_key.rb +20 -23
  16. data/lib/composite_primary_keys/attribute_methods/read.rb +16 -18
  17. data/lib/composite_primary_keys/attribute_methods/write.rb +31 -33
  18. data/lib/composite_primary_keys/composite_arrays.rb +1 -1
  19. data/lib/composite_primary_keys/composite_predicates.rb +3 -0
  20. data/lib/composite_primary_keys/connection_adapters/abstract_adapter.rb +10 -10
  21. data/lib/composite_primary_keys/core.rb +40 -45
  22. data/lib/composite_primary_keys/fixtures.rb +17 -19
  23. data/lib/composite_primary_keys/locking/optimistic.rb +46 -38
  24. data/lib/composite_primary_keys/nested_attributes.rb +58 -60
  25. data/lib/composite_primary_keys/persistence.rb +72 -44
  26. data/lib/composite_primary_keys/reflection.rb +20 -0
  27. data/lib/composite_primary_keys/relation.rb +33 -79
  28. data/lib/composite_primary_keys/relation/batches.rb +7 -28
  29. data/lib/composite_primary_keys/relation/calculations.rb +28 -28
  30. data/lib/composite_primary_keys/relation/finder_methods.rb +34 -56
  31. data/lib/composite_primary_keys/relation/predicate_builder/association_query_value.rb +18 -0
  32. data/lib/composite_primary_keys/relation/query_methods.rb +23 -11
  33. data/lib/composite_primary_keys/relation/where_clause.rb +13 -22
  34. data/lib/composite_primary_keys/sanitization.rb +0 -2
  35. data/lib/composite_primary_keys/version.rb +3 -3
  36. data/scripts/console.rb +48 -48
  37. data/scripts/txt2html +76 -76
  38. data/scripts/txt2js +65 -65
  39. data/tasks/website.rake +18 -18
  40. data/test/README_tests.rdoc +56 -56
  41. data/test/connections/databases.yml +30 -40
  42. data/test/db_test.rb +52 -52
  43. data/test/fixtures/articles.yml +6 -6
  44. data/test/fixtures/capitol.rb +3 -3
  45. data/test/fixtures/capitols.yml +16 -16
  46. data/test/fixtures/comments.yml +15 -15
  47. data/test/fixtures/department.rb +5 -5
  48. data/test/fixtures/departments.yml +15 -15
  49. data/test/fixtures/dorms.yml +4 -4
  50. data/test/fixtures/group.rb +2 -2
  51. data/test/fixtures/groups.yml +6 -6
  52. data/test/fixtures/hack.rb +4 -4
  53. data/test/fixtures/hacks.yml +2 -2
  54. data/test/fixtures/membership_status.rb +2 -2
  55. data/test/fixtures/product.rb +9 -9
  56. data/test/fixtures/product_tariff.rb +5 -5
  57. data/test/fixtures/products.yml +11 -11
  58. data/test/fixtures/reading.rb +4 -4
  59. data/test/fixtures/readings.yml +10 -10
  60. data/test/fixtures/reference_code_using_composite_key_alias.rb +8 -8
  61. data/test/fixtures/reference_code_using_simple_key_alias.rb +8 -8
  62. data/test/fixtures/reference_codes.yml +28 -28
  63. data/test/fixtures/reference_types.yml +9 -9
  64. data/test/fixtures/restaurant.rb +9 -9
  65. data/test/fixtures/restaurants.yml +14 -14
  66. data/test/fixtures/restaurants_suburbs.yml +10 -10
  67. data/test/fixtures/room.rb +11 -11
  68. data/test/fixtures/room_assignment.rb +13 -13
  69. data/test/fixtures/room_assignments.yml +24 -24
  70. data/test/fixtures/room_attribute.rb +2 -2
  71. data/test/fixtures/room_attribute_assignment.rb +4 -4
  72. data/test/fixtures/room_attribute_assignments.yml +4 -4
  73. data/test/fixtures/room_attributes.yml +2 -2
  74. data/test/fixtures/rooms.yml +12 -12
  75. data/test/fixtures/seat.rb +5 -5
  76. data/test/fixtures/seats.yml +8 -8
  77. data/test/fixtures/street.rb +2 -2
  78. data/test/fixtures/streets.yml +16 -16
  79. data/test/fixtures/student.rb +3 -3
  80. data/test/fixtures/students.yml +15 -15
  81. data/test/fixtures/suburbs.yml +14 -14
  82. data/test/fixtures/tariffs.yml +1 -1
  83. data/test/plugins/pagination.rb +405 -405
  84. data/test/plugins/pagination_helper.rb +135 -135
  85. data/test/setup.rb +50 -50
  86. data/test/test_aliases.rb +18 -18
  87. data/test/test_associations.rb +6 -20
  88. data/test/test_composite_arrays.rb +24 -24
  89. data/test/test_counter_cache.rb +30 -30
  90. data/test/test_delete.rb +146 -146
  91. data/test/test_dup.rb +37 -37
  92. data/test/test_exists.rb +39 -39
  93. data/test/test_find.rb +1 -1
  94. data/test/test_miscellaneous.rb +32 -32
  95. data/test/test_pagination.rb +35 -35
  96. data/test/test_preload.rb +0 -7
  97. data/test/test_validations.rb +13 -13
  98. metadata +10 -17
  99. data/lib/composite_primary_keys/arel/in.rb +0 -6
  100. data/lib/composite_primary_keys/associations/join_dependency/join_association.rb +0 -24
  101. data/lib/composite_primary_keys/associations/preloader/belongs_to.rb +0 -19
  102. data/lib/composite_primary_keys/relation/predicate_builder/association_query_handler.rb +0 -33
@@ -1,24 +1,24 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class CompositeArraysTest < ActiveSupport::TestCase
4
-
5
- def test_new_primary_keys
6
- keys = CompositePrimaryKeys::CompositeKeys.new
7
- assert_not_nil keys
8
- assert_equal '', keys.to_s
9
- assert_equal '', "#{keys}"
10
- end
11
-
12
- def test_initialize_primary_keys
13
- keys = CompositePrimaryKeys::CompositeKeys.new([1,2,3])
14
- assert_not_nil keys
15
- assert_equal '1,2,3', keys.to_s
16
- assert_equal '1,2,3', "#{keys}"
17
- end
18
-
19
- def test_to_composite_keys
20
- keys = [1,2,3].to_composite_keys
21
- assert_equal CompositePrimaryKeys::CompositeKeys, keys.class
22
- assert_equal '1,2,3', keys.to_s
23
- end
24
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class CompositeArraysTest < ActiveSupport::TestCase
4
+
5
+ def test_new_primary_keys
6
+ keys = CompositePrimaryKeys::CompositeKeys.new
7
+ assert_not_nil keys
8
+ assert_equal '', keys.to_s
9
+ assert_equal '', "#{keys}"
10
+ end
11
+
12
+ def test_initialize_primary_keys
13
+ keys = CompositePrimaryKeys::CompositeKeys.new([1,2,3])
14
+ assert_not_nil keys
15
+ assert_equal '1,2,3', keys.to_s
16
+ assert_equal '1,2,3', "#{keys}"
17
+ end
18
+
19
+ def test_to_composite_keys
20
+ keys = [1,2,3].to_composite_keys
21
+ assert_equal CompositePrimaryKeys::CompositeKeys, keys.class
22
+ assert_equal '1,2,3', keys.to_s
23
+ end
24
+ end
@@ -1,31 +1,31 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestCalculations < ActiveSupport::TestCase
4
- fixtures :tariffs
5
-
6
- def test_update_counter
7
- tariff = tariffs(:flat)
8
- assert_equal(50, tariff.amount)
9
- Tariff.update_counters(tariff.id, :amount => 1)
10
- tariff.reload
11
- assert_equal(51, tariff.amount)
12
- end
13
-
14
- def test_increment_counter
15
- tariff = tariffs(:flat)
16
- assert_equal(50, tariff.amount)
17
- Tariff.increment_counter(:amount, tariff.id)
18
-
19
- tariff.reload
20
- assert_equal(51, tariff.amount)
21
- end
22
-
23
- def test_decrement_counter
24
- tariff = tariffs(:flat)
25
- assert_equal(50, tariff.amount)
26
- Tariff.decrement_counter(:amount, tariff.id)
27
-
28
- tariff.reload
29
- assert_equal(49, tariff.amount)
30
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestCalculations < ActiveSupport::TestCase
4
+ fixtures :tariffs
5
+
6
+ def test_update_counter
7
+ tariff = tariffs(:flat)
8
+ assert_equal(50, tariff.amount)
9
+ Tariff.update_counters(tariff.id, :amount => 1)
10
+ tariff.reload
11
+ assert_equal(51, tariff.amount)
12
+ end
13
+
14
+ def test_increment_counter
15
+ tariff = tariffs(:flat)
16
+ assert_equal(50, tariff.amount)
17
+ Tariff.increment_counter(:amount, tariff.id)
18
+
19
+ tariff.reload
20
+ assert_equal(51, tariff.amount)
21
+ end
22
+
23
+ def test_decrement_counter
24
+ tariff = tariffs(:flat)
25
+ assert_equal(50, tariff.amount)
26
+ Tariff.decrement_counter(:amount, tariff.id)
27
+
28
+ tariff.reload
29
+ assert_equal(49, tariff.amount)
30
+ end
31
31
  end
@@ -4,29 +4,29 @@ class TestDelete < ActiveSupport::TestCase
4
4
  fixtures :articles, :departments, :employees, :products, :tariffs, :product_tariffs,
5
5
  :reference_types, :reference_codes
6
6
 
7
- def test_delete_one
8
- assert_equal(5, ReferenceCode.count)
9
- ReferenceCode.first.delete
10
- assert_equal(4, ReferenceCode.count)
11
- end
12
-
13
- def test_delete_one_with_id
14
- assert_equal(5, ReferenceCode.count)
15
- ReferenceCode.delete(ReferenceCode.first.id)
16
- assert_equal(4, ReferenceCode.count)
17
- end
18
-
19
- def test_destroy_one
20
- assert_equal(5, ReferenceCode.count)
21
- ReferenceCode.first.destroy
22
- assert_equal(4, ReferenceCode.count)
23
- end
24
-
25
- def test_delete_all
26
- refute_empty(ReferenceCode.all)
27
- ReferenceCode.delete_all
28
- assert_empty(ReferenceCode.all)
29
- end
7
+ # def test_delete_one
8
+ # assert_equal(5, ReferenceCode.count)
9
+ # ReferenceCode.first.delete
10
+ # assert_equal(4, ReferenceCode.count)
11
+ # end
12
+ #
13
+ # def test_delete_one_with_id
14
+ # assert_equal(5, ReferenceCode.count)
15
+ # ReferenceCode.delete(ReferenceCode.first.id)
16
+ # assert_equal(4, ReferenceCode.count)
17
+ # end
18
+ #
19
+ # def test_destroy_one
20
+ # assert_equal(5, ReferenceCode.count)
21
+ # ReferenceCode.first.destroy
22
+ # assert_equal(4, ReferenceCode.count)
23
+ # end
24
+ #
25
+ # def test_delete_all
26
+ # refute_empty(ReferenceCode.all)
27
+ # ReferenceCode.delete_all
28
+ # assert_empty(ReferenceCode.all)
29
+ # end
30
30
 
31
31
  def test_delete_all_with_join
32
32
  department = departments(:accounting)
@@ -41,127 +41,127 @@ class TestDelete < ActiveSupport::TestCase
41
41
  assert_equal(3, Department.count)
42
42
  end
43
43
 
44
- def test_clear_association
45
- department = Department.find([1,1])
46
- assert_equal(2, department.employees.size, "Before clear employee count should be 2.")
47
-
48
- department.employees.clear
49
- assert_equal(0, department.employees.size, "After clear employee count should be 0.")
50
-
51
- department.reload
52
- assert_equal(0, department.employees.size, "After clear and a reload from DB employee count should be 0.")
53
- end
54
-
55
- def test_delete_association
56
- department = Department.find([1,1])
57
- assert_equal 2, department.employees.size , "Before delete employee count should be 2."
58
- first_employee = department.employees[0]
59
- department.employees.delete(first_employee)
60
- assert_equal 1, department.employees.size, "After delete employee count should be 1."
61
- department.reload
62
- assert_equal 1, department.employees.size, "After delete and a reload from DB employee count should be 1."
63
- end
64
-
65
- def test_has_many_replace
66
- tariff = tariffs(:flat)
67
- assert_equal(1, tariff.product_tariffs.length)
68
-
69
- tariff.product_tariffs = [product_tariffs(:first_free), product_tariffs(:second_free)]
70
- tariff.reload
71
-
72
- assert_equal(2, tariff.product_tariffs.length)
73
- refute(tariff.product_tariffs.include?(tariff))
74
- end
75
-
76
- def test_destroy_has_one
77
- # In this case the association is a has_one with
78
- # dependent set to :destroy
79
- department = departments(:engineering)
80
- assert_not_nil(department.head)
81
-
82
- # Get head employee id
83
- head_id = department.head.id
84
-
85
- # Delete department - should delete the head
86
- department.destroy
87
-
88
- # Verify the head is also
89
- assert_raise(ActiveRecord::RecordNotFound) do
90
- Employee.find(head_id)
91
- end
92
- end
93
-
94
- def test_destroy_has_and_belongs_to_many_on_non_cpk
95
- steve = employees(:steve)
96
- records_before = ActiveRecord::Base.connection.execute('select * from employees_groups')
97
- steve.destroy
98
- records_after = ActiveRecord::Base.connection.execute('select * from employees_groups')
99
- if records_before.respond_to?(:count)
100
- assert_equal records_after.count, records_before.count - steve.groups.count
101
- elsif records_before.respond_to?(:row_count) # OCI8:Cursor for oracle adapter
102
- assert_equal records_after.row_count, records_before.row_count - steve.groups.count
103
- end
104
- end
105
-
106
- def test_create_destroy_has_and_belongs_to_many_on_non_cpk
107
- records_before = ActiveRecord::Base.connection.execute('select * from employees_groups')
108
- employee = Employee.create
109
- employee.groups << Group.create(name: 'test')
110
- employee.destroy!
111
- records_after = ActiveRecord::Base.connection.execute('select * from employees_groups')
112
- if records_before.respond_to?(:count)
113
- assert_equal records_before.count, records_after.count
114
- elsif records_before.respond_to?(:row_count) # OCI8:Cursor for oracle adapter
115
- assert_equal records_before.row_count, records_after.row_count
116
- end
117
- end
118
-
119
- def test_delete_not_destroy_on_cpk
120
- tariff = Tariff.where(tariff_id: 2).first
121
- tariff.delete
122
- assert !tariff.persisted?
123
- end
124
-
125
- def test_delete_not_destroy_on_non_cpk
126
- article = Article.first
127
- article.delete
128
- assert !article.persisted?
129
- end
130
-
131
- def test_destroy_has_many_delete_all
132
- # In this case the association is a has_many composite key with
133
- # dependent set to :delete_all
134
- product = Product.find(1)
135
- assert_equal(2, product.product_tariffs.length)
136
-
137
- # Get product_tariff length
138
- product_tariff_size = ProductTariff.count
139
-
140
- # Delete product - should delete 2 product tariffs
141
- product.destroy
142
-
143
- # Verify product_tariff are deleted
144
- assert_equal(product_tariff_size - 2, ProductTariff.count)
145
- end
146
-
147
- def test_delete_cpk_association
148
- product = Product.find(1)
149
- assert_equal(2, product.product_tariffs.length)
150
-
151
- product_tariff = product.product_tariffs.first
152
- product.product_tariffs.delete(product_tariff)
153
-
154
- product.reload
155
- assert_equal(1, product.product_tariffs.length)
156
- end
157
-
158
- def test_delete_records_for_has_many_association_with_composite_primary_key
159
- reference_type = ReferenceType.find(1)
160
- codes_to_delete = reference_type.reference_codes[0..1]
161
- assert_equal(3, reference_type.reference_codes.size, "Before deleting records reference_code count should be 3.")
162
-
163
- reference_type.reference_codes.delete(codes_to_delete)
164
- reference_type.reload
165
- assert_equal(1, reference_type.reference_codes.size, "After deleting 2 records and a reload from DB reference_code count should be 1.")
166
- end
44
+ # def test_clear_association
45
+ # department = Department.find([1,1])
46
+ # assert_equal(2, department.employees.size, "Before clear employee count should be 2.")
47
+ #
48
+ # department.employees.clear
49
+ # assert_equal(0, department.employees.size, "After clear employee count should be 0.")
50
+ #
51
+ # department.reload
52
+ # assert_equal(0, department.employees.size, "After clear and a reload from DB employee count should be 0.")
53
+ # end
54
+ #
55
+ # def test_delete_association
56
+ # department = Department.find([1,1])
57
+ # assert_equal 2, department.employees.size , "Before delete employee count should be 2."
58
+ # first_employee = department.employees[0]
59
+ # department.employees.delete(first_employee)
60
+ # assert_equal 1, department.employees.size, "After delete employee count should be 1."
61
+ # department.reload
62
+ # assert_equal 1, department.employees.size, "After delete and a reload from DB employee count should be 1."
63
+ # end
64
+ #
65
+ # def test_has_many_replace
66
+ # tariff = tariffs(:flat)
67
+ # assert_equal(1, tariff.product_tariffs.length)
68
+ #
69
+ # tariff.product_tariffs = [product_tariffs(:first_free), product_tariffs(:second_free)]
70
+ # tariff.reload
71
+ #
72
+ # assert_equal(2, tariff.product_tariffs.length)
73
+ # refute(tariff.product_tariffs.include?(tariff))
74
+ # end
75
+ #
76
+ # def test_destroy_has_one
77
+ # # In this case the association is a has_one with
78
+ # # dependent set to :destroy
79
+ # department = departments(:engineering)
80
+ # assert_not_nil(department.head)
81
+ #
82
+ # # Get head employee id
83
+ # head_id = department.head.id
84
+ #
85
+ # # Delete department - should delete the head
86
+ # department.destroy
87
+ #
88
+ # # Verify the head is also
89
+ # assert_raise(ActiveRecord::RecordNotFound) do
90
+ # Employee.find(head_id)
91
+ # end
92
+ # end
93
+ #
94
+ # def test_destroy_has_and_belongs_to_many_on_non_cpk
95
+ # steve = employees(:steve)
96
+ # records_before = ActiveRecord::Base.connection.execute('select * from employees_groups')
97
+ # steve.destroy
98
+ # records_after = ActiveRecord::Base.connection.execute('select * from employees_groups')
99
+ # if records_before.respond_to?(:count)
100
+ # assert_equal records_after.count, records_before.count - steve.groups.count
101
+ # elsif records_before.respond_to?(:row_count) # OCI8:Cursor for oracle adapter
102
+ # assert_equal records_after.row_count, records_before.row_count - steve.groups.count
103
+ # end
104
+ # end
105
+ #
106
+ # def test_create_destroy_has_and_belongs_to_many_on_non_cpk
107
+ # records_before = ActiveRecord::Base.connection.execute('select * from employees_groups')
108
+ # employee = Employee.create
109
+ # employee.groups << Group.create(name: 'test')
110
+ # employee.destroy!
111
+ # records_after = ActiveRecord::Base.connection.execute('select * from employees_groups')
112
+ # if records_before.respond_to?(:count)
113
+ # assert_equal records_before.count, records_after.count
114
+ # elsif records_before.respond_to?(:row_count) # OCI8:Cursor for oracle adapter
115
+ # assert_equal records_before.row_count, records_after.row_count
116
+ # end
117
+ # end
118
+ #
119
+ # def test_delete_not_destroy_on_cpk
120
+ # tariff = Tariff.where(tariff_id: 2).first
121
+ # tariff.delete
122
+ # assert !tariff.persisted?
123
+ # end
124
+ #
125
+ # def test_delete_not_destroy_on_non_cpk
126
+ # article = Article.first
127
+ # article.delete
128
+ # assert !article.persisted?
129
+ # end
130
+ #
131
+ # def test_destroy_has_many_delete_all
132
+ # # In this case the association is a has_many composite key with
133
+ # # dependent set to :delete_all
134
+ # product = Product.find(1)
135
+ # assert_equal(2, product.product_tariffs.length)
136
+ #
137
+ # # Get product_tariff length
138
+ # product_tariff_size = ProductTariff.count
139
+ #
140
+ # # Delete product - should delete 2 product tariffs
141
+ # product.destroy
142
+ #
143
+ # # Verify product_tariff are deleted
144
+ # assert_equal(product_tariff_size - 2, ProductTariff.count)
145
+ # end
146
+ #
147
+ # def test_delete_cpk_association
148
+ # product = Product.find(1)
149
+ # assert_equal(2, product.product_tariffs.length)
150
+ #
151
+ # product_tariff = product.product_tariffs.first
152
+ # product.product_tariffs.delete(product_tariff)
153
+ #
154
+ # product.reload
155
+ # assert_equal(1, product.product_tariffs.length)
156
+ # end
157
+ #
158
+ # def test_delete_records_for_has_many_association_with_composite_primary_key
159
+ # reference_type = ReferenceType.find(1)
160
+ # codes_to_delete = reference_type.reference_codes[0..1]
161
+ # assert_equal(3, reference_type.reference_codes.size, "Before deleting records reference_code count should be 3.")
162
+ #
163
+ # reference_type.reference_codes.delete(codes_to_delete)
164
+ # reference_type.reload
165
+ # assert_equal(1, reference_type.reference_codes.size, "After deleting 2 records and a reload from DB reference_code count should be 1.")
166
+ # end
167
167
  end
@@ -1,38 +1,38 @@
1
- require File.expand_path('../abstract_unit', __FILE__)
2
-
3
- class TestClone < ActiveSupport::TestCase
4
- fixtures :reference_types, :reference_codes
5
-
6
- CLASSES = {
7
- :single => {
8
- :class => ReferenceType,
9
- :primary_keys => :reference_type_id,
10
- },
11
- :dual => {
12
- :class => ReferenceCode,
13
- :primary_keys => [:reference_type_id, :reference_code],
14
- },
15
- }
16
-
17
- def setup
18
- self.class.classes = CLASSES
19
- end
20
-
21
- def test_dup
22
- testing_with do
23
- clone = @first.dup
24
-
25
- remove_keys = Array(@klass.primary_key).map(&:to_s)
26
- remove_keys << Array(@klass.primary_key) # Rails 4 adds the PK to the attributes, so we want to remove it as well
27
- assert_equal(@first.attributes.except(*remove_keys), clone.attributes.except(*remove_keys))
28
-
29
- if composite?
30
- @klass.primary_key.each do |key|
31
- assert_nil(clone[key], "Primary key '#{key}' should be nil")
32
- end
33
- else
34
- assert_nil(clone[@klass.primary_key], "Sole primary key should be nil")
35
- end
36
- end
37
- end
1
+ require File.expand_path('../abstract_unit', __FILE__)
2
+
3
+ class TestClone < ActiveSupport::TestCase
4
+ fixtures :reference_types, :reference_codes
5
+
6
+ CLASSES = {
7
+ :single => {
8
+ :class => ReferenceType,
9
+ :primary_keys => :reference_type_id,
10
+ },
11
+ :dual => {
12
+ :class => ReferenceCode,
13
+ :primary_keys => [:reference_type_id, :reference_code],
14
+ },
15
+ }
16
+
17
+ def setup
18
+ self.class.classes = CLASSES
19
+ end
20
+
21
+ def test_dup
22
+ testing_with do
23
+ clone = @first.dup
24
+
25
+ remove_keys = Array(@klass.primary_key).map(&:to_s)
26
+ remove_keys << Array(@klass.primary_key) # Rails 4 adds the PK to the attributes, so we want to remove it as well
27
+ assert_equal(@first.attributes.except(*remove_keys), clone.attributes.except(*remove_keys))
28
+
29
+ if composite?
30
+ @klass.primary_key.each do |key|
31
+ assert_nil(clone[key], "Primary key '#{key}' should be nil")
32
+ end
33
+ else
34
+ assert_nil(clone[@klass.primary_key], "Sole primary key should be nil")
35
+ end
36
+ end
37
+ end
38
38
  end