archival_record 2.0.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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rubocop.yml +74 -0
  4. data/.rubocop_todo.yml +14 -0
  5. data/.travis.yml +23 -0
  6. data/Appraisals +18 -0
  7. data/CHANGELOG.md +96 -0
  8. data/Gemfile +2 -0
  9. data/Gemfile.lock +69 -0
  10. data/LICENSE +56 -0
  11. data/README.md +209 -0
  12. data/Rakefile +16 -0
  13. data/archival_record.gemspec +51 -0
  14. data/gemfiles/rails_5.0.gemfile +8 -0
  15. data/gemfiles/rails_5.1.gemfile +8 -0
  16. data/gemfiles/rails_5.2.gemfile +8 -0
  17. data/gemfiles/rails_6.0.gemfile +7 -0
  18. data/init.rb +3 -0
  19. data/lib/archival_record.rb +19 -0
  20. data/lib/archival_record/version.rb +5 -0
  21. data/lib/archival_record_core/archival_record.rb +164 -0
  22. data/lib/archival_record_core/archival_record_active_record_methods.rb +45 -0
  23. data/lib/archival_record_core/association_operation/archive.rb +21 -0
  24. data/lib/archival_record_core/association_operation/base.rb +54 -0
  25. data/lib/archival_record_core/association_operation/unarchive.rb +17 -0
  26. data/script/setup +9 -0
  27. data/test/ambiguous_table_test.rb +16 -0
  28. data/test/application_record_test.rb +20 -0
  29. data/test/associations_test.rb +104 -0
  30. data/test/basic_test.rb +66 -0
  31. data/test/callbacks_test.rb +41 -0
  32. data/test/column_test.rb +17 -0
  33. data/test/deep_nesting_test.rb +35 -0
  34. data/test/deprecated_warning_archival_test.rb +11 -0
  35. data/test/fixtures/another_polys_holder.rb +11 -0
  36. data/test/fixtures/application_record.rb +5 -0
  37. data/test/fixtures/application_record_row.rb +8 -0
  38. data/test/fixtures/archival.rb +19 -0
  39. data/test/fixtures/archival_grandkid.rb +10 -0
  40. data/test/fixtures/archival_kid.rb +11 -0
  41. data/test/fixtures/archival_table_name.rb +10 -0
  42. data/test/fixtures/callback_archival_4.rb +19 -0
  43. data/test/fixtures/callback_archival_5.rb +23 -0
  44. data/test/fixtures/deprecated_warning_archival.rb +9 -0
  45. data/test/fixtures/exploder.rb +10 -0
  46. data/test/fixtures/independent_archival.rb +11 -0
  47. data/test/fixtures/missing_archive_number.rb +7 -0
  48. data/test/fixtures/missing_archived_at.rb +7 -0
  49. data/test/fixtures/plain.rb +7 -0
  50. data/test/fixtures/poly.rb +11 -0
  51. data/test/fixtures/readonly_when_archived.rb +8 -0
  52. data/test/polymorphic_test.rb +50 -0
  53. data/test/readonly_when_archived_test.rb +24 -0
  54. data/test/relations_test.rb +63 -0
  55. data/test/responds_test.rb +15 -0
  56. data/test/schema.rb +96 -0
  57. data/test/scope_test.rb +92 -0
  58. data/test/test_helper.rb +91 -0
  59. data/test/through_association_test.rb +27 -0
  60. data/test/transaction_test.rb +31 -0
  61. metadata +254 -0
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+ set -e
3
+ cd "`dirname \"$0\"`/.."
4
+
5
+ echo "\n---=== Bundling ===---"
6
+ bundle install
7
+
8
+ echo "\n---=== Setting up various rails versions for testing ===---"
9
+ bundle exec appraisal install
@@ -0,0 +1,16 @@
1
+ require_relative "test_helper"
2
+
3
+ class AmbiguousTableTest < ActiveSupport::TestCase
4
+
5
+ test "no ambiguous table problem" do
6
+ archival = Archival.create!
7
+ child = archival.archivals.create!
8
+ child.archive!
9
+
10
+ # this is a bug fix for a problem wherein table names weren't being
11
+ # namespaced, so if a table joined against itself, incorrect SQL was
12
+ # generated
13
+ assert_equal 1, Archival.unarchived.joins(:archivals).count
14
+ end
15
+
16
+ end
@@ -0,0 +1,20 @@
1
+ require_relative "test_helper"
2
+
3
+ # Rails 5 introduced a new base class, and this is gonna test that
4
+ if defined?(ApplicationRecord)
5
+ class ApplicationRecordTest < ActiveSupport::TestCase
6
+
7
+ test "archive archives the record" do
8
+ archival = ApplicationRecordRow.create!
9
+ archival.archive!
10
+ assert archival.reload.archived?
11
+ end
12
+
13
+ test "unarchive unarchives archival records" do
14
+ archival = ApplicationRecordRow.create!(archived_at: Time.now, archive_number: 1)
15
+ archival.unarchive!
16
+ assert_not archival.reload.archived?
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,104 @@
1
+ require_relative "test_helper"
2
+
3
+ class AssociationsTest < ActiveSupport::TestCase
4
+
5
+ test "archive archives 'has_' associated archival objects that are dependent destroy" do
6
+ archival = Archival.create!
7
+ child = archival.archivals.create!
8
+ archival.archive!
9
+
10
+ assert archival.reload.archived?
11
+ assert child.reload.archived?
12
+ end
13
+
14
+ test "archive acts on all objects in the 'has_' relationship" do
15
+ archival = Archival.create!
16
+ children = [archival.archivals.create!, archival.archivals.create!]
17
+ archival.archive!
18
+
19
+ assert archival.reload.archived?
20
+ assert children.map(&:reload).all?(&:archived?)
21
+ end
22
+
23
+ test "archive does not act on already archived objects" do
24
+ archival = Archival.create!
25
+ archival.archivals.create!
26
+ prearchived_child = archival.archivals.create!
27
+ prearchived_child.archive!
28
+ archival.archive!
29
+
30
+ assert_not_equal archival.archive_number, prearchived_child.reload.archive_number
31
+ end
32
+
33
+ test "archive does not archive 'has_' associated archival objects that are not dependent destroy" do
34
+ archival = Archival.create!
35
+ non_dependent_child = archival.independent_archivals.create!
36
+ archival.archive!
37
+
38
+ assert archival.reload.archived?
39
+ assert_not non_dependent_child.reload.archived?
40
+ end
41
+
42
+ test "archive doesn't do anything to associated dependent destroy models that are non-archival" do
43
+ archival = Archival.create!
44
+ plain = archival.plains.create!
45
+ archival.archive!
46
+
47
+ assert archival.archived?
48
+ assert plain.reload
49
+ end
50
+
51
+ test "archive sets the object hierarchy to all have the same archive_number" do
52
+ archival = Archival.create!
53
+ child = archival.archivals.create!
54
+ archival.archive!
55
+ expected_digest = Digest::MD5.hexdigest("Archival#{archival.id}")
56
+
57
+ assert_equal expected_digest, archival.archive_number
58
+ assert_equal expected_digest, child.reload.archive_number
59
+ end
60
+
61
+ test "unarchive acts on child objects" do
62
+ archival = Archival.create!
63
+ child = archival.archivals.create!
64
+ archival.archive!
65
+ archival.unarchive!
66
+
67
+ assert_not archival.archived?
68
+ assert_not child.reload.archived?
69
+ end
70
+
71
+ test "unarchive does not act on already archived objects" do
72
+ archival = Archival.create!
73
+ child = archival.archivals.create!
74
+ prearchived_child = archival.archivals.create!
75
+ prearchived_child.archive!
76
+ archival.archive!
77
+ archival.unarchive!
78
+
79
+ assert_not archival.archived?
80
+ assert_not child.reload.archived?
81
+ assert prearchived_child.reload.archived?
82
+ end
83
+
84
+ test "unarchive acts on 'has_' associated non-dependent_destroy objects" do
85
+ archival = Archival.create!
86
+ independent = archival.independent_archivals.create!
87
+ archival.archive!
88
+ independent.archive!(archival.archive_number)
89
+ archival.unarchive!
90
+
91
+ assert_not archival.reload.archived?
92
+ assert_not independent.reload.archived?
93
+ end
94
+
95
+ test "unarchive doesn't unarchive associated objects if the head object is already unarchived" do
96
+ archival = Archival.create!
97
+ prearchived_child = archival.archivals.create!
98
+ prearchived_child.archive!
99
+ archival.unarchive!
100
+
101
+ assert prearchived_child.reload.archived?
102
+ end
103
+
104
+ end
@@ -0,0 +1,66 @@
1
+ require_relative "test_helper"
2
+
3
+ class BasicTest < ActiveSupport::TestCase
4
+
5
+ test "archive archives the record" do
6
+ archival = Archival.create!
7
+ archival.archive!
8
+ assert_equal true, archival.reload.archived?
9
+ end
10
+
11
+ test "unarchive unarchives archival records" do
12
+ archival = Archival.create!(archived_at: Time.now, archive_number: 1)
13
+ archival.unarchive!
14
+ assert_equal false, archival.reload.archived?
15
+ end
16
+
17
+ test "archive returns true on success" do
18
+ normal = Archival.create!
19
+ assert_equal true, normal.archive!
20
+ end
21
+
22
+ test "archive returns false on failure" do
23
+ readonly = Archival.create!
24
+ readonly.readonly!
25
+ assert_equal false, readonly.archive!
26
+ end
27
+
28
+ test "unarchive returns true on success" do
29
+ normal = Archival.create!(archived_at: Time.now, archive_number: "1")
30
+ assert_equal true, normal.unarchive!
31
+ end
32
+
33
+ test "unarchive returns false on failure" do
34
+ readonly = Archival.create!(archived_at: Time.now, archive_number: "1")
35
+ readonly.readonly!
36
+ assert_equal false, readonly.unarchive!
37
+ end
38
+
39
+ test "archive sets archived_at to the time of archiving" do
40
+ archival = Archival.create!
41
+ before = DateTime.now
42
+ sleep(0.001)
43
+ archival.archive!
44
+ sleep(0.001)
45
+ after = DateTime.now
46
+ assert before < archival.archived_at.to_datetime
47
+ assert after > archival.archived_at.to_datetime
48
+ end
49
+
50
+ test "archive sets the archive number to the md5 hexdigest for the model and id that is archived" do
51
+ archival = Archival.create!
52
+ archival.archive!
53
+ expected_digest = Digest::MD5.hexdigest("#{archival.class.name}#{archival.id}")
54
+ assert_equal expected_digest, archival.archive_number
55
+ end
56
+
57
+ test "archive on archived object doesn't alter the archive_number" do
58
+ archived = Archival.create
59
+ archived.archive!
60
+ initial_number = archived.archive_number
61
+ archived.reload.archive!
62
+ second_number = archived.archive_number
63
+ assert_equal initial_number, second_number
64
+ end
65
+
66
+ end
@@ -0,0 +1,41 @@
1
+ require_relative "test_helper"
2
+
3
+ class CallbacksTest < ActiveSupport::TestCase
4
+
5
+ if defined?(ApplicationRecord)
6
+ test "can set a value as part of archiving" do
7
+ archival = CallbackArchival5.create
8
+ archival.set_this_value = "a test string"
9
+ assert_nil archival.settable_field
10
+ archival.archive!
11
+ assert_equal "a test string", archival.reload.settable_field
12
+ end
13
+
14
+ test "can be halted" do
15
+ archival = CallbackArchival5.create
16
+ archival.set_this_value = "a test string"
17
+ archival.pass_callback = false
18
+ assert_nil archival.settable_field
19
+ archival.archive!
20
+ assert_nil archival.reload.settable_field
21
+ end
22
+ else
23
+ test "can set a value as part of archiving" do
24
+ archival = CallbackArchival4.create
25
+ archival.set_this_value = "a test string"
26
+ assert_nil archival.settable_field
27
+ archival.archive!
28
+ assert_equal "a test string", archival.reload.settable_field
29
+ end
30
+
31
+ test "can be halted" do
32
+ archival = CallbackArchival4.create
33
+ archival.set_this_value = "a test string"
34
+ archival.pass_callback = false
35
+ assert_nil archival.settable_field
36
+ archival.archive!
37
+ assert_nil archival.reload.settable_field
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "test_helper"
2
+
3
+ class ColumnTest < ActiveSupport::TestCase
4
+
5
+ test "archival_record raises during create if missing archived_at column" do
6
+ assert_raises(ArchivalRecordCore::ArchivalRecord::MissingArchivalColumnError) do
7
+ MissingArchivedAt.create!(name: "foo-foo")
8
+ end
9
+ end
10
+
11
+ test "archival_record raises during create if missing archive_number column" do
12
+ assert_raises(ArchivalRecordCore::ArchivalRecord::MissingArchivalColumnError) do
13
+ MissingArchiveNumber.create!(name: "rover")
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "test_helper"
2
+
3
+ class DeepNestingTest < ActiveSupport::TestCase
4
+
5
+ test "archiving deeply nested items" do
6
+ archival = Archival.create!
7
+ child = archival.archivals.create!
8
+ grandchild = child.archivals.create!
9
+
10
+ archival.archive!
11
+
12
+ assert archival.reload.archived?
13
+ assert child.reload.archived?
14
+ assert grandchild.reload.archived?
15
+ assert_equal archival.archive_number, child.archive_number
16
+ assert_equal archival.archive_number, grandchild.archive_number
17
+ end
18
+
19
+ test "unarchiving deeply nested items doesn't blow up" do
20
+ archival_attributes = {
21
+ archived_at: Time.now,
22
+ archive_number: "test"
23
+ }
24
+ archival = Archival.create!(archival_attributes)
25
+ child = archival.archivals.create!(archival_attributes)
26
+ grandchild = child.archivals.create!(archival_attributes)
27
+
28
+ archival.unarchive!
29
+
30
+ assert_not archival.reload.archived?
31
+ assert_not child.reload.archived?
32
+ assert_not grandchild.reload.archived?
33
+ end
34
+
35
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "test_helper"
2
+
3
+ class DeprecatedWarningArchivalTest < ActiveSupport::TestCase
4
+
5
+ test "models with 'acts_as_archival' instead of 'archival_record' can still archive a record" do
6
+ archival = DeprecatedWarningArchival.create!
7
+ archival.archive!
8
+ assert_equal true, archival.reload.archived?
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ # name - string
2
+ # archival_id - integer
3
+ # archive_number - string
4
+ # archived_at - datetime
5
+ class AnotherPolysHolder < ActiveRecord::Base
6
+
7
+ archival_record
8
+
9
+ has_many :polys, dependent: :destroy, as: :archiveable
10
+
11
+ end
@@ -0,0 +1,5 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+
3
+ self.abstract_class = true
4
+
5
+ end
@@ -0,0 +1,8 @@
1
+ # Rails 5 introduced a new base class, and this is gonna be used in the tests of that
2
+ if defined?(ApplicationRecord)
3
+ class ApplicationRecordRow < ApplicationRecord
4
+
5
+ archival_record
6
+
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ # name - string
2
+ # archival_id - integer
3
+ # archive_number - string
4
+ # archived_at - datetime
5
+ class Archival < ActiveRecord::Base
6
+
7
+ archival_record
8
+
9
+ has_many :archivals, dependent: :destroy
10
+ has_many :archival_kids, dependent: :destroy
11
+ has_many :archival_grandkids, dependent: :destroy, through: :archival_kids
12
+ has_many :exploders, dependent: :destroy
13
+ has_many :plains, dependent: :destroy
14
+ has_many :polys, dependent: :destroy, as: :archiveable
15
+ has_many :independent_archivals
16
+
17
+ scope :bobs, -> { where(name: %w[Bob Bobby Robert]) }
18
+
19
+ end
@@ -0,0 +1,10 @@
1
+ # archival_kid_id - integer
2
+ # archive_number - string
3
+ # archived_at - datetime
4
+ class ArchivalGrandkid < ActiveRecord::Base
5
+
6
+ archival_record
7
+
8
+ belongs_to :archival_kid
9
+
10
+ end
@@ -0,0 +1,11 @@
1
+ # archival_id - integer
2
+ # archive_number - string
3
+ # archived_at - datetime
4
+ class ArchivalKid < ActiveRecord::Base
5
+
6
+ archival_record
7
+
8
+ belongs_to :archival
9
+ has_many :archival_grandkids, dependent: :destroy
10
+
11
+ end
@@ -0,0 +1,10 @@
1
+ # name - string
2
+ # archive_number - string
3
+ # archived_at - datetime
4
+ class ArchivalTableName < ActiveRecord::Base
5
+
6
+ self.table_name = "legacy"
7
+
8
+ archival_record
9
+
10
+ end
@@ -0,0 +1,19 @@
1
+ class CallbackArchival4 < ActiveRecord::Base
2
+
3
+ archival_record
4
+
5
+ attr_accessor :set_this_value,
6
+ :pass_callback
7
+
8
+ before_archive :set_value,
9
+ :conditional_callback_passer
10
+
11
+ private def set_value
12
+ self.settable_field = set_this_value
13
+ end
14
+
15
+ private def conditional_callback_passer
16
+ pass_callback || pass_callback.nil?
17
+ end
18
+
19
+ end
@@ -0,0 +1,23 @@
1
+ # necessary for ApplicationRecord
2
+ if defined?(ApplicationRecord)
3
+ class CallbackArchival5 < ApplicationRecord
4
+
5
+ archival_record
6
+
7
+ attr_accessor :set_this_value,
8
+ :pass_callback
9
+
10
+ before_archive :set_value,
11
+ :conditional_callback_passer
12
+
13
+ private def set_value
14
+ self.settable_field = set_this_value
15
+ end
16
+
17
+ private def conditional_callback_passer
18
+ # we want to throw only for the value false
19
+ throw(:abort) unless pass_callback || pass_callback.nil?
20
+ end
21
+
22
+ end
23
+ end