active_snapshot 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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