active_snapshot 0.3.0 → 0.3.1

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -4
  3. data/README.md +1 -1
  4. data/Rakefile +1 -36
  5. data/lib/active_snapshot/models/snapshot.rb +1 -1
  6. data/lib/active_snapshot/models/snapshot_item.rb +1 -1
  7. data/lib/active_snapshot/version.rb +1 -1
  8. data/lib/active_snapshot.rb +20 -17
  9. metadata +4 -84
  10. data/test/dummy_app/Rakefile +0 -7
  11. data/test/dummy_app/app/assets/config/manifest.js +0 -3
  12. data/test/dummy_app/app/assets/javascripts/application.js +0 -0
  13. data/test/dummy_app/app/assets/stylesheets/application.css +0 -3
  14. data/test/dummy_app/app/controllers/application_controller.rb +0 -3
  15. data/test/dummy_app/app/models/application_record.rb +0 -3
  16. data/test/dummy_app/app/models/comment.rb +0 -5
  17. data/test/dummy_app/app/models/note.rb +0 -5
  18. data/test/dummy_app/app/models/parent_without_children.rb +0 -5
  19. data/test/dummy_app/app/models/post.rb +0 -16
  20. data/test/dummy_app/app/models/sub_post.rb +0 -11
  21. data/test/dummy_app/app/models/volatile_post.rb +0 -5
  22. data/test/dummy_app/app/views/layouts/application.html.erb +0 -14
  23. data/test/dummy_app/config/application.rb +0 -50
  24. data/test/dummy_app/config/boot.rb +0 -10
  25. data/test/dummy_app/config/database.yml +0 -20
  26. data/test/dummy_app/config/environment.rb +0 -5
  27. data/test/dummy_app/config/environments/test.rb +0 -41
  28. data/test/dummy_app/config/initializers/backtrace_silencers.rb +0 -7
  29. data/test/dummy_app/config/initializers/inflections.rb +0 -10
  30. data/test/dummy_app/config/initializers/mime_types.rb +0 -5
  31. data/test/dummy_app/config/initializers/secret_token.rb +0 -11
  32. data/test/dummy_app/config/initializers/session_store.rb +0 -8
  33. data/test/dummy_app/config/initializers/wrap_parameters.rb +0 -14
  34. data/test/dummy_app/config/locales/en.yml +0 -5
  35. data/test/dummy_app/config/routes.rb +0 -6
  36. data/test/dummy_app/config/secrets.yml +0 -22
  37. data/test/dummy_app/config.ru +0 -4
  38. data/test/dummy_app/db/migrate/20210128155312_set_up_test_tables.rb +0 -27
  39. data/test/dummy_app/db/migrate/20210306100122_create_snapshots_tables.rb +0 -33
  40. data/test/dummy_app/db/test.sqlite3 +0 -0
  41. data/test/dummy_app/log/test.log +0 -37780
  42. data/test/generators/active_snapshot/install_generator_test.rb +0 -31
  43. data/test/models/snapshot_item_test.rb +0 -75
  44. data/test/models/snapshot_test.rb +0 -148
  45. data/test/models/snapshots_concern_test.rb +0 -143
  46. data/test/test_helper.rb +0 -95
  47. data/test/unit/active_snapshot_test.rb +0 -57
  48. data/test/unit/config_test.rb +0 -66
  49. data/test/unit/errors_test.rb +0 -12
@@ -1,31 +0,0 @@
1
- require "test_helper"
2
- require File.expand_path("../../../lib/generators/active_snapshot/install/install_generator", __dir__)
3
-
4
- class InstallGeneratorTest < Rails::Generators::TestCase
5
- tests ActiveSnapshot::InstallGenerator
6
- destination File.expand_path("tmp", __dir__)
7
-
8
- setup do
9
- prepare_destination # cleanup the tmp directory
10
- run_generator
11
- end
12
-
13
- teardown do
14
- ### Disable during debugging
15
- prepare_destination # cleanup the tmp directory
16
- end
17
-
18
- def test_should_add_migration
19
- run_generator
20
-
21
- relative_path = "db/migrate/create_snapshots_tables.rb"
22
-
23
- assert_migration(relative_path) do |content|
24
- assert_match(/create_table :snapshots/, content)
25
- assert_match(/create_table :snapshot_items/, content)
26
- end
27
-
28
- ### Test for syntax errors in file
29
- require send(:migration_file_name, relative_path)
30
- end
31
- end
@@ -1,75 +0,0 @@
1
- require "test_helper"
2
-
3
- class SnapshotItemTest < ActiveSupport::TestCase
4
-
5
- def setup
6
- @snapshot_klass = ActiveSnapshot::Snapshot
7
- @snapshot_item_klass = ActiveSnapshot::SnapshotItem
8
- end
9
-
10
- def teardown
11
- end
12
-
13
- def test_relationships
14
- instance = @snapshot_item_klass.new
15
-
16
- assert instance.snapshot.nil?
17
- assert instance.item.nil?
18
-
19
- assert_raises do
20
- instance.snapshot = instance
21
- end
22
-
23
- instance.snapshot = ActiveSnapshot::Snapshot.new
24
-
25
- instance.item = instance
26
-
27
- assert_not instance.snapshot.nil?
28
- assert_not instance.item.nil?
29
- end
30
-
31
- def test_validations
32
- instance = @snapshot_item_klass.new
33
-
34
- instance.valid?
35
-
36
- [:item_id, :item_type, :snapshot_id].each do |attr|
37
- assert instance.errors[attr].present? ### presence error
38
- end
39
-
40
- shared_post = DATA[:shared_post]
41
- snapshot = shared_post.snapshots.first
42
-
43
- instance = @snapshot_item_klass.new(item: snapshot.item, snapshot: snapshot)
44
-
45
- instance.valid?
46
-
47
- assert instance.errors[:item_id].present? ### uniq error
48
- assert instance.errors[:item_type].present? ### uniq error
49
-
50
- instance = @snapshot_item_klass.new(item_id: 1, item_type: 'Foobar', snapshot: snapshot)
51
-
52
- assert instance.valid?
53
- end
54
-
55
- def test_object
56
- @snapshot = @snapshot_klass.includes(:snapshot_items).first
57
-
58
- @snapshot_item = @snapshot.snapshot_items.first
59
-
60
- assert @snapshot_item.object.is_a?(Hash)
61
-
62
- @snapshot_item.object = {foo: :bar}
63
-
64
- assert 'bar', @snapshot_item.object['foo']
65
- end
66
-
67
- def test_restore_item!
68
- @snapshot = @snapshot_klass.includes(:snapshot_items).first
69
-
70
- @snapshot_item = @snapshot.snapshot_items.first
71
-
72
- @snapshot_item.restore_item!
73
- end
74
-
75
- end
@@ -1,148 +0,0 @@
1
- require "test_helper"
2
-
3
- class SnapshotTest < ActiveSupport::TestCase
4
-
5
- def setup
6
- @snapshot_klass = ActiveSnapshot::Snapshot
7
- end
8
-
9
- def teardown
10
- end
11
-
12
- def test_relationships
13
- shared_post = DATA[:shared_post]
14
-
15
- instance = @snapshot_klass.new
16
-
17
- assert instance.user.nil?
18
- assert instance.item.nil?
19
- assert instance.snapshot_items.empty?
20
-
21
- instance.user = instance
22
- instance.item = instance
23
-
24
- assert_raises do
25
- instance.snapshot_items << instance
26
- end
27
-
28
- instance.snapshot_items << ActiveSnapshot::SnapshotItem.new
29
-
30
- assert_not instance.user.nil?
31
- assert_not instance.item.nil?
32
- assert_not instance.snapshot_items.empty?
33
-
34
- instance = @snapshot_klass.new(item: shared_post, user: shared_post)
35
-
36
- assert instance.item.id, shared_post.id
37
- assert instance.user.id, shared_post.id
38
- end
39
-
40
- def test_validations
41
- shared_post = DATA[:shared_post]
42
- snapshot = shared_post.snapshots.first
43
-
44
- instance = @snapshot_klass.new
45
-
46
- instance.valid?
47
-
48
- [:item_id, :item_type].each do |attr|
49
- assert instance.errors[attr].present? ### presence error
50
- end
51
-
52
- instance = @snapshot_klass.new(item: snapshot.item, identifier: snapshot.identifier)
53
-
54
- instance.valid?
55
-
56
- assert instance.errors[:identifier].present? ### uniq error
57
-
58
- instance = @snapshot_klass.new(item: snapshot.item, identifier: 'random')
59
-
60
- assert instance.valid?
61
- end
62
-
63
- def test_metadata
64
- @snapshot = @snapshot_klass.first
65
-
66
- assert @snapshot.metadata.is_a?(Hash)
67
-
68
- @snapshot.metadata = {foo: :bar}
69
-
70
- assert_equal "bar", @snapshot.metadata['foo']
71
- end
72
-
73
- def test_build_snapshot_item
74
- @snapshot = @snapshot_klass.first
75
-
76
- snapshot_item = @snapshot.build_snapshot_item(Post.first)
77
-
78
- assert snapshot_item.is_a?(ActiveSnapshot::SnapshotItem)
79
-
80
- assert snapshot_item.new_record?
81
-
82
- assert_equal @snapshot.id, snapshot_item.snapshot_id
83
-
84
- @snapshot.build_snapshot_item(Post.first, child_group_name: :foobar)
85
- end
86
-
87
- def test_restore
88
- @snapshot = @snapshot_klass.first
89
-
90
- @snapshot.restore!
91
- end
92
-
93
- def test_fetch_reified_items
94
- @snapshot = @snapshot_klass.first
95
-
96
- reified_items = @snapshot.fetch_reified_items
97
-
98
- assert reified_items.is_a?(Array)
99
-
100
- assert reified_items.first.readonly?
101
-
102
- children_hash = reified_items.last
103
-
104
- assert children_hash.is_a?(Hash)
105
-
106
- assert children_hash.all?{|k,v| v.all?{|x| x.readonly?} }
107
- end
108
-
109
- def test_fetch_reified_items_with_sti_class
110
- post = SubPost.create!(a: 1, b: 2)
111
- comment_content = 'Example comment'
112
- post.comments.create!(content: comment_content)
113
- post.create_snapshot!(identifier: 'v1')
114
- snapshot = post.snapshots.first
115
- reified_items = snapshot.fetch_reified_items
116
-
117
- assert_equal post, reified_items.first
118
- assert reified_items.first.readonly?
119
- assert_equal comment_content, reified_items.second[:comments].first.content
120
- end
121
-
122
- def test_single_model_snapshots_without_children
123
- instance = ParentWithoutChildren.create!({a: 1, b: 2})
124
-
125
- prev_attrs = instance.attributes
126
-
127
- instance.create_snapshot!(identifier: 'v1')
128
-
129
- instance.update!(a: 9, b: 9)
130
-
131
- snapshot = instance.snapshots.first
132
-
133
- reified_items = snapshot.fetch_reified_items
134
-
135
- assert_equal [instance, {}], reified_items
136
-
137
- new_attrs = reified_items.first.attributes
138
-
139
- prev_time_attrs = prev_attrs.extract!("created_at","updated_at")
140
- new_time_attrs = new_attrs.extract!("created_at","updated_at")
141
-
142
- assert_equal new_time_attrs.values.map{|x| x.round(3)}, new_time_attrs.values
143
-
144
- ### rounding to 3 sometimes fails due to millisecond precision so we just test for 2 decimal places here
145
- assert_equal prev_time_attrs.values.map{|x| x.round(2)}, new_time_attrs.values.map{|x| x.round(2)}
146
- end
147
-
148
- end
@@ -1,143 +0,0 @@
1
- require "test_helper"
2
-
3
- class SnapshotsConcernTest < ActiveSupport::TestCase
4
-
5
- def setup
6
- end
7
-
8
- def teardown
9
- end
10
-
11
- def test_relationships
12
- instance = Post.new
13
-
14
- assert instance.snapshots.empty?
15
- assert instance.snapshot_items.empty?
16
-
17
- assert_raises do
18
- instance.snapshots << instance
19
- end
20
-
21
- instance.snapshots << ActiveSnapshot::Snapshot.new
22
-
23
- assert_raises do
24
- instance.snapshot_items << instance
25
- end
26
-
27
- instance.snapshot_items << ActiveSnapshot::SnapshotItem.new
28
-
29
- assert_not instance.snapshots.empty?
30
- assert_not instance.snapshot_items.empty?
31
- end
32
-
33
- def test_create_snapshot!
34
- @post = Post.first
35
-
36
- #@user = User.first
37
-
38
- snapshot = @post.create_snapshot!(identifier: "foobar 1", user: @user, metadata: {foo: :bar})
39
- assert_not snapshot.new_record?
40
-
41
- snapshot = @post.create_snapshot!(identifier: "foobar 2", user: @user)
42
- assert_not snapshot.new_record?
43
-
44
- snapshot = @post.create_snapshot!(identifier: "foobar 3")
45
- assert_not snapshot.new_record?
46
-
47
- assert_raise do
48
- @post.create_snapshot!(identifier: "foobar 3")
49
- end
50
- end
51
-
52
- def test_has_snapshot_children
53
- klass = VolatilePost
54
-
55
- assert_nil klass.has_snapshot_children
56
-
57
- klass.has_snapshot_children do
58
- {}
59
- end
60
-
61
- assert klass.instance_variable_get(:@snapshot_children_proc).is_a?(Proc)
62
-
63
- klass.new.children_to_snapshot
64
-
65
- invalid = [
66
- "foobar",
67
- true,
68
- false,
69
- nil,
70
- "",
71
- [],
72
- [:foobar, 123],
73
- {foo: :bar},
74
- {foo: {records: 'bar', delete_method: 'bar'}},
75
- ]
76
-
77
- invalid.each do |x|
78
- klass.has_snapshot_children do
79
- x
80
- end
81
-
82
- assert_raise ArgumentError do
83
- klass.new.children_to_snapshot
84
- end
85
- end
86
-
87
- valid = [
88
- {},
89
- {foo: []},
90
- {foo: {}},
91
- {foo: Post.limit(1)},
92
- {foo: [:foobar, 123]},
93
- {foo: {record: 'bar'}},
94
- {foo: {records: 'bar'}},
95
- {foo: {record: Post.limit(1) }},
96
- {foo: {records: Post.limit(1) }},
97
- {foo: {records: [], delete_method: ->(){} }},
98
- {foo: {records: [], delete_method: proc{} }},
99
- {foo: nil},
100
- {foo: {records: nil}},
101
- ]
102
-
103
- valid.each do |x|
104
- klass.has_snapshot_children do
105
- x
106
- end
107
-
108
- klass.new.children_to_snapshot
109
- end
110
-
111
- klass.has_snapshot_children do
112
- {foo: {records: 'bar'}, baz: {records: 'barbaz'}}
113
- end
114
-
115
- assert klass.new.children_to_snapshot.count == 2
116
- end
117
-
118
- def test_legacy_positional_identifier_argument
119
- call_count = 0
120
-
121
- allow_any_instance_of(ActiveSupport::Deprecation).to receive(:warn).and_wrap_original do |m, *args|
122
- if args.first == ActiveSnapshot::SnapshotsConcern::LEGACY_POSITIONAL_ARGUMENT_WARNING
123
- call_count += 1
124
- end
125
- end
126
-
127
- assert_difference ->{ ActiveSnapshot::Snapshot.count }, 1 do
128
- @snapshot = Post.first.create_snapshot!("snapshot-1")
129
- end
130
-
131
- assert_equal call_count, 1
132
- end
133
-
134
- def test_optional_identifier
135
- post = Post.first
136
-
137
- assert_difference ->{ ActiveSnapshot::Snapshot.count }, 2 do
138
- post.create_snapshot!
139
- post.create_snapshot!
140
- end
141
- end
142
-
143
- end
data/test/test_helper.rb DELETED
@@ -1,95 +0,0 @@
1
- #$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
2
- ENV["RAILS_ENV"] = "test"
3
-
4
- require "active_snapshot"
5
-
6
- if ENV["ACTIVE_SNAPSHOT_STORAGE_METHOD"].present?
7
- ActiveSnapshot.config.storage_method = ENV["ACTIVE_SNAPSHOT_STORAGE_METHOD"]
8
- end
9
-
10
- begin
11
- require 'warning'
12
-
13
- Warning.ignore(
14
- %r{mail/parsers/address_lists_parser}, ### Hide mail gem warnings
15
- )
16
- rescue LoadError
17
- # Do nothing
18
- end
19
-
20
- ### Instantiates Rails
21
- require File.expand_path("../dummy_app/config/environment.rb", __FILE__)
22
-
23
- require "rails/test_help"
24
-
25
- class ActiveSupport::TestCase
26
- # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
27
- fixtures :all
28
- end
29
-
30
- Rails.backtrace_cleaner.remove_silencers!
31
-
32
- require 'minitest-spec-rails' ### for describe blocks
33
-
34
- require 'minitest/reporters'
35
- Minitest::Reporters.use!(
36
- Minitest::Reporters::DefaultReporter.new,
37
- ENV,
38
- Minitest.backtrace_filter
39
- )
40
-
41
- require "minitest/autorun"
42
-
43
- # Run any available migration
44
- if ActiveRecord.gem_version >= Gem::Version.new("6.0")
45
- ActiveRecord::MigrationContext.new(File.expand_path("dummy_app/db/migrate/", __dir__), ActiveRecord::SchemaMigration).migrate
46
- elsif ActiveRecord.gem_version >= Gem::Version.new("5.2")
47
- ActiveRecord::MigrationContext.new(File.expand_path("dummy_app/db/migrate/", __dir__)).migrate
48
- else
49
- ActiveRecord::Migrator.migrate File.expand_path("dummy_app/db/migrate/", __dir__)
50
- end
51
-
52
- require 'rspec/mocks'
53
- module MinitestRSpecMocksIntegration
54
- include RSpec::Mocks::ExampleMethods
55
-
56
- def before_setup
57
- RSpec::Mocks.setup
58
- super
59
- end
60
-
61
- def after_teardown
62
- super
63
- RSpec::Mocks.verify
64
- ensure
65
- RSpec::Mocks.teardown
66
- end
67
- end
68
- Minitest::Test.send(:include, MinitestRSpecMocksIntegration)
69
-
70
- klasses = [
71
- Post,
72
- ActiveSnapshot::Snapshot,
73
- ActiveSnapshot::SnapshotItem,
74
- ]
75
-
76
- klasses.each do |klass|
77
- if klass.connection.adapter_name.downcase.include?("sqlite")
78
- ActiveRecord::Base.connection.execute("DELETE FROM #{klass.table_name};")
79
- ActiveRecord::Base.connection.execute("UPDATE `sqlite_sequence` SET `seq` = 0 WHERE `name` = '#{klass.table_name}';")
80
- else
81
- ActiveRecord::Base.connection.execute("TRUNCATE TABLE #{klass.table_name}")
82
- end
83
- end
84
-
85
- DATA = {}.with_indifferent_access
86
-
87
- DATA[:shared_post] = Post.find_or_create_by!(a: 1, b: 3)
88
- DATA[:shared_post].create_snapshot!(identifier: 'v1')
89
- DATA[:shared_post].update_columns(a: 2, b: 4)
90
- DATA[:shared_post].create_snapshot!(identifier: 'v2')
91
-
92
- def assert_time_match(a, b)
93
- format = "%d-%m-%Y %h:%M:%S.%L" ### MUST LIMIT THE MILLISECONDS TO 3 decimal places of accuracy, the rest are dropped
94
- assert_equal a.strftime(format), b.strftime(format)
95
- end
@@ -1,57 +0,0 @@
1
- require "test_helper"
2
-
3
- class ActiveSnapshotTest < ActiveSupport::TestCase
4
-
5
- def test_exposes_main_module
6
- assert ActiveSnapshot.is_a?(Module)
7
- end
8
-
9
- def test_exposes_version
10
- assert ActiveSnapshot::VERSION
11
- end
12
-
13
- def test_snapshot_lifecycle
14
- identifier = "snapshot-1"
15
-
16
- klass = Post
17
-
18
- parent = klass.first
19
-
20
- original_parent_updated_at = parent.updated_at
21
-
22
- child = parent.comments.create!(content: :foo)
23
- original_child_updated_at = child.updated_at
24
-
25
- assert_difference ->{ ActiveSnapshot::Snapshot.count }, 1 do
26
- assert_difference ->{ ActiveSnapshot::SnapshotItem.count }, 2 do
27
- @snapshot = parent.create_snapshot!(identifier: identifier)
28
- end
29
- end
30
-
31
- parent.update_columns(updated_at: 1.day.from_now)
32
-
33
- parent.update_columns(updated_at: 1.day.from_now)
34
-
35
- child.destroy!
36
-
37
- parent.comments.create!(content: :foo)
38
- parent.comments.create!(content: :bar)
39
-
40
- assert_no_difference ->{ ActiveSnapshot::Snapshot.count } do
41
- assert_no_difference ->{ ActiveSnapshot::SnapshotItem.count } do
42
- @snapshot.restore!
43
- end
44
- end
45
-
46
- assert_equal 1, ActiveSnapshot::Snapshot.where(identifier: identifier).count
47
-
48
- parent.reload
49
-
50
- assert_equal 1, parent.children_to_snapshot[:comments][:records].count
51
-
52
- ### Test Data Chang
53
- assert_time_match original_parent_updated_at, parent.updated_at
54
- assert_time_match original_child_updated_at, parent.children_to_snapshot[:comments][:records].first.updated_at
55
- end
56
-
57
- end
@@ -1,66 +0,0 @@
1
- require "test_helper"
2
-
3
- class ActiveSnapshot::ConfigTest < ActiveSupport::TestCase
4
-
5
- describe "storage_method" do
6
- def setup
7
- @orig_storage_method = ActiveSnapshot.config.storage_method
8
- end
9
-
10
- def teardown
11
- ActiveSnapshot.config.storage_method = @orig_storage_method
12
- end
13
-
14
- def test_defaults_to_serialized_json
15
- assert_equal 'serialized_json', ActiveSnapshot.config.storage_method
16
-
17
- assert_equal false, ActiveSnapshot.config.storage_method_yaml?
18
- assert_equal true, ActiveSnapshot.config.storage_method_json?
19
- assert_equal false, ActiveSnapshot.config.storage_method_native_json?
20
- end
21
-
22
- def test_accepts_to_serialized_json
23
- ActiveSnapshot.config.storage_method = 'serialized_json'
24
-
25
- assert_equal 'serialized_json', ActiveSnapshot.config.storage_method
26
-
27
- assert_equal false, ActiveSnapshot.config.storage_method_yaml?
28
- assert_equal true, ActiveSnapshot.config.storage_method_json?
29
- assert_equal false, ActiveSnapshot.config.storage_method_native_json?
30
- end
31
-
32
-
33
- def test_accepts_serialized_yaml
34
- ActiveSnapshot.config.storage_method = 'serialized_yaml'
35
-
36
- assert_equal 'serialized_yaml', ActiveSnapshot.config.storage_method
37
-
38
- assert_equal true, ActiveSnapshot.config.storage_method_yaml?
39
- assert_equal false, ActiveSnapshot.config.storage_method_json?
40
- assert_equal false, ActiveSnapshot.config.storage_method_native_json?
41
- end
42
-
43
- def test_accepts_native_json
44
- ActiveSnapshot.config.storage_method = "native_json"
45
-
46
- assert_equal "native_json", ActiveSnapshot.config.storage_method, "native_json"
47
-
48
- assert_equal false, ActiveSnapshot.config.storage_method_yaml?
49
- assert_equal false, ActiveSnapshot.config.storage_method_json?
50
- assert_equal true, ActiveSnapshot.config.storage_method_native_json?
51
- end
52
-
53
- def test_config_doesnt_accept_not_specified_storage_methods
54
- assert_raise do
55
- ActiveSnapshot.config.storage_method = 'foobar'
56
- end
57
- assert_equal "serialized_json", ActiveSnapshot.config.storage_method
58
- end
59
-
60
- def test_converts_symbol_to_string
61
- ActiveSnapshot.config.storage_method = "serialized_yaml"
62
- assert_equal "serialized_yaml", ActiveSnapshot.config.storage_method
63
- end
64
- end
65
-
66
- end
@@ -1,12 +0,0 @@
1
- require "test_helper"
2
-
3
- class ErrorsTest < ActiveSupport::TestCase
4
-
5
- setup do
6
- end
7
-
8
- teardown do
9
- end
10
-
11
-
12
- end