paper_trail 7.1.0 → 7.1.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.
- checksums.yaml +4 -4
- data/lib/paper_trail/record_trail.rb +1 -1
- data/lib/paper_trail/version_number.rb +1 -1
- metadata +3 -274
- data/.github/CONTRIBUTING.md +0 -151
- data/.github/ISSUE_TEMPLATE.md +0 -13
- data/.gitignore +0 -23
- data/.rspec +0 -2
- data/.rubocop.yml +0 -135
- data/.rubocop_todo.yml +0 -41
- data/.travis.yml +0 -41
- data/Appraisals +0 -26
- data/CHANGELOG.md +0 -739
- data/Gemfile +0 -2
- data/MIT-LICENSE +0 -20
- data/README.md +0 -1613
- data/Rakefile +0 -38
- data/doc/bug_report_template.rb +0 -73
- data/doc/triage.md +0 -27
- data/doc/warning_about_not_setting_whodunnit.md +0 -33
- data/gemfiles/ar_4.0.gemfile +0 -7
- data/gemfiles/ar_4.2.gemfile +0 -7
- data/gemfiles/ar_5.0.gemfile +0 -8
- data/gemfiles/ar_5.1.gemfile +0 -8
- data/gemfiles/ar_master.gemfile +0 -9
- data/lib/generators/paper_trail/default_initializer.rb +0 -0
- data/paper_trail.gemspec +0 -49
- data/spec/controllers/articles_controller_spec.rb +0 -28
- data/spec/controllers/widgets_controller_spec.rb +0 -85
- data/spec/dummy_app/Rakefile +0 -7
- data/spec/dummy_app/app/controllers/application_controller.rb +0 -30
- data/spec/dummy_app/app/controllers/articles_controller.rb +0 -16
- data/spec/dummy_app/app/controllers/test_controller.rb +0 -5
- data/spec/dummy_app/app/controllers/widgets_controller.rb +0 -28
- data/spec/dummy_app/app/models/animal.rb +0 -4
- data/spec/dummy_app/app/models/article.rb +0 -25
- data/spec/dummy_app/app/models/authorship.rb +0 -5
- data/spec/dummy_app/app/models/bar_habtm.rb +0 -4
- data/spec/dummy_app/app/models/book.rb +0 -9
- data/spec/dummy_app/app/models/boolit.rb +0 -4
- data/spec/dummy_app/app/models/callback_modifier.rb +0 -45
- data/spec/dummy_app/app/models/car.rb +0 -3
- data/spec/dummy_app/app/models/cat.rb +0 -2
- data/spec/dummy_app/app/models/chapter.rb +0 -9
- data/spec/dummy_app/app/models/citation.rb +0 -5
- data/spec/dummy_app/app/models/custom_primary_key_record.rb +0 -15
- data/spec/dummy_app/app/models/customer.rb +0 -4
- data/spec/dummy_app/app/models/document.rb +0 -8
- data/spec/dummy_app/app/models/dog.rb +0 -2
- data/spec/dummy_app/app/models/editor.rb +0 -4
- data/spec/dummy_app/app/models/editorship.rb +0 -5
- data/spec/dummy_app/app/models/elephant.rb +0 -3
- data/spec/dummy_app/app/models/fluxor.rb +0 -3
- data/spec/dummy_app/app/models/foo_habtm.rb +0 -5
- data/spec/dummy_app/app/models/foo_widget.rb +0 -2
- data/spec/dummy_app/app/models/fruit.rb +0 -5
- data/spec/dummy_app/app/models/gadget.rb +0 -3
- data/spec/dummy_app/app/models/kitchen/banana.rb +0 -5
- data/spec/dummy_app/app/models/legacy_widget.rb +0 -6
- data/spec/dummy_app/app/models/line_item.rb +0 -4
- data/spec/dummy_app/app/models/not_on_update.rb +0 -4
- data/spec/dummy_app/app/models/on/create.rb +0 -6
- data/spec/dummy_app/app/models/on/destroy.rb +0 -6
- data/spec/dummy_app/app/models/on/empty_array.rb +0 -6
- data/spec/dummy_app/app/models/on/update.rb +0 -6
- data/spec/dummy_app/app/models/order.rb +0 -5
- data/spec/dummy_app/app/models/paragraph.rb +0 -5
- data/spec/dummy_app/app/models/person.rb +0 -39
- data/spec/dummy_app/app/models/post.rb +0 -3
- data/spec/dummy_app/app/models/post_with_status.rb +0 -7
- data/spec/dummy_app/app/models/quotation.rb +0 -5
- data/spec/dummy_app/app/models/section.rb +0 -6
- data/spec/dummy_app/app/models/skipper.rb +0 -3
- data/spec/dummy_app/app/models/song.rb +0 -37
- data/spec/dummy_app/app/models/thing.rb +0 -3
- data/spec/dummy_app/app/models/translation.rb +0 -11
- data/spec/dummy_app/app/models/truck.rb +0 -4
- data/spec/dummy_app/app/models/vehicle.rb +0 -4
- data/spec/dummy_app/app/models/whatchamajigger.rb +0 -4
- data/spec/dummy_app/app/models/widget.rb +0 -8
- data/spec/dummy_app/app/models/wotsit.rb +0 -8
- data/spec/dummy_app/app/versions/custom_primary_key_record_version.rb +0 -3
- data/spec/dummy_app/app/versions/joined_version.rb +0 -6
- data/spec/dummy_app/app/versions/json_version.rb +0 -3
- data/spec/dummy_app/app/versions/kitchen/banana_version.rb +0 -5
- data/spec/dummy_app/app/versions/post_version.rb +0 -3
- data/spec/dummy_app/config.ru +0 -4
- data/spec/dummy_app/config/application.rb +0 -39
- data/spec/dummy_app/config/boot.rb +0 -24
- data/spec/dummy_app/config/database.mysql.yml +0 -19
- data/spec/dummy_app/config/database.postgres.yml +0 -15
- data/spec/dummy_app/config/database.sqlite.yml +0 -15
- data/spec/dummy_app/config/environment.rb +0 -5
- data/spec/dummy_app/config/environments/development.rb +0 -36
- data/spec/dummy_app/config/environments/production.rb +0 -74
- data/spec/dummy_app/config/environments/test.rb +0 -46
- data/spec/dummy_app/config/initializers/backtrace_silencers.rb +0 -9
- data/spec/dummy_app/config/initializers/inflections.rb +0 -10
- data/spec/dummy_app/config/initializers/mime_types.rb +0 -5
- data/spec/dummy_app/config/initializers/paper_trail.rb +0 -1
- data/spec/dummy_app/config/initializers/secret_token.rb +0 -9
- data/spec/dummy_app/config/initializers/session_store.rb +0 -8
- data/spec/dummy_app/config/locales/en.yml +0 -5
- data/spec/dummy_app/config/routes.rb +0 -4
- data/spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb +0 -344
- data/spec/dummy_app/db/schema.rb +0 -298
- data/spec/generators/install_generator_spec.rb +0 -88
- data/spec/models/animal_spec.rb +0 -61
- data/spec/models/article_spec.rb +0 -186
- data/spec/models/boolit_spec.rb +0 -41
- data/spec/models/callback_modifier_spec.rb +0 -92
- data/spec/models/car_spec.rb +0 -13
- data/spec/models/custom_primary_key_record_spec.rb +0 -18
- data/spec/models/document_spec.rb +0 -57
- data/spec/models/gadget_spec.rb +0 -63
- data/spec/models/joined_version_spec.rb +0 -41
- data/spec/models/json_version_spec.rb +0 -101
- data/spec/models/kitchen/banana_spec.rb +0 -14
- data/spec/models/legacy_widget_spec.rb +0 -40
- data/spec/models/not_on_update_spec.rb +0 -22
- data/spec/models/on/create_spec.rb +0 -27
- data/spec/models/on/destroy_spec.rb +0 -27
- data/spec/models/on/empty_array_spec.rb +0 -30
- data/spec/models/on/update_spec.rb +0 -27
- data/spec/models/post_with_status_spec.rb +0 -46
- data/spec/models/skipper_spec.rb +0 -42
- data/spec/models/thing_spec.rb +0 -11
- data/spec/models/translation_spec.rb +0 -70
- data/spec/models/vehicle_spec.rb +0 -5
- data/spec/models/version_spec.rb +0 -282
- data/spec/models/widget_spec.rb +0 -338
- data/spec/modules/paper_trail_spec.rb +0 -27
- data/spec/modules/version_concern_spec.rb +0 -28
- data/spec/modules/version_number_spec.rb +0 -18
- data/spec/paper_trail/associations_spec.rb +0 -965
- data/spec/paper_trail/cleaner_spec.rb +0 -152
- data/spec/paper_trail/config_spec.rb +0 -45
- data/spec/paper_trail/model_spec.rb +0 -992
- data/spec/paper_trail/serializer_spec.rb +0 -85
- data/spec/paper_trail/serializers/custom_json_serializer_spec.rb +0 -18
- data/spec/paper_trail/serializers/custom_yaml_serializer_spec.rb +0 -45
- data/spec/paper_trail/serializers/json_spec.rb +0 -57
- data/spec/paper_trail/serializers/yaml_spec.rb +0 -42
- data/spec/paper_trail/thread_safety_spec.rb +0 -44
- data/spec/paper_trail/version_limit_spec.rb +0 -55
- data/spec/paper_trail/version_spec.rb +0 -96
- data/spec/paper_trail_spec.rb +0 -122
- data/spec/requests/articles_spec.rb +0 -34
- data/spec/spec_helper.rb +0 -78
- data/spec/support/alt_db_init.rb +0 -54
- data/spec/support/custom_json_serializer.rb +0 -13
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "support/custom_json_serializer"
|
|
3
|
-
|
|
4
|
-
RSpec.describe(PaperTrail, versioning: true) do
|
|
5
|
-
context "YAML serializer" do
|
|
6
|
-
it "saves the expected YAML in the object column" do
|
|
7
|
-
customer = Customer.create(name: "Some text.")
|
|
8
|
-
original_attributes = customer.paper_trail.attributes_before_change
|
|
9
|
-
customer.update(name: "Some more text.")
|
|
10
|
-
expect(customer.versions.length).to(eq(2))
|
|
11
|
-
expect(customer.versions[0].reify).to(be_nil)
|
|
12
|
-
expect(customer.versions[1].reify.name).to(eq("Some text."))
|
|
13
|
-
expect(YAML.load(customer.versions[1].object)).to(eq(original_attributes))
|
|
14
|
-
expect(customer.versions[1].object).to(eq(YAML.dump(original_attributes)))
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
context "JSON Serializer" do
|
|
19
|
-
before do
|
|
20
|
-
PaperTrail.configure do |config|
|
|
21
|
-
config.serializer = PaperTrail::Serializers::JSON
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
after do
|
|
26
|
-
PaperTrail.config.serializer = PaperTrail::Serializers::YAML
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "reify with JSON serializer" do
|
|
30
|
-
customer = Customer.create(name: "Some text.")
|
|
31
|
-
original_attributes = customer.paper_trail.attributes_before_change
|
|
32
|
-
customer.update(name: "Some more text.")
|
|
33
|
-
expect(customer.versions.length).to(eq(2))
|
|
34
|
-
expect(customer.versions[0].reify).to(be_nil)
|
|
35
|
-
expect(customer.versions[1].reify.name).to(eq("Some text."))
|
|
36
|
-
expect(ActiveSupport::JSON.decode(customer.versions[1].object)).to(eq(original_attributes))
|
|
37
|
-
expect(customer.versions[1].object).to(eq(ActiveSupport::JSON.encode(original_attributes)))
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe "#changeset" do
|
|
41
|
-
it "returns the expected hash" do
|
|
42
|
-
customer = Customer.create(name: "Some text.")
|
|
43
|
-
customer.update(name: "Some more text.")
|
|
44
|
-
initial_changeset = { "name" => [nil, "Some text."], "id" => [nil, customer.id] }
|
|
45
|
-
second_changeset = { "name" => ["Some text.", "Some more text."] }
|
|
46
|
-
expect(customer.versions[0].changeset).to(eq(initial_changeset))
|
|
47
|
-
expect(customer.versions[1].changeset).to(eq(second_changeset))
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
context "Custom Serializer" do
|
|
53
|
-
before do
|
|
54
|
-
PaperTrail.configure { |config| config.serializer = CustomJsonSerializer }
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
after do
|
|
58
|
-
PaperTrail.config.serializer = PaperTrail::Serializers::YAML
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "reify with custom serializer" do
|
|
62
|
-
customer = Customer.create
|
|
63
|
-
original_attributes = customer.paper_trail.attributes_before_change.reject { |_k, v| v.nil? }
|
|
64
|
-
customer.update(name: "Some more text.")
|
|
65
|
-
expect(customer.versions.length).to(eq(2))
|
|
66
|
-
expect(customer.versions[0].reify).to(be_nil)
|
|
67
|
-
expect(customer.versions[1].reify.name).to(be_nil)
|
|
68
|
-
expect(
|
|
69
|
-
ActiveSupport::JSON.decode(customer.versions[1].object)
|
|
70
|
-
).to eq(original_attributes)
|
|
71
|
-
expect(
|
|
72
|
-
customer.versions[1].object
|
|
73
|
-
).to eq(ActiveSupport::JSON.encode(original_attributes))
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
describe "#changeset" do
|
|
77
|
-
it "store object_changes" do
|
|
78
|
-
customer = Customer.create
|
|
79
|
-
customer.update(name: "banana")
|
|
80
|
-
expect(customer.versions[0].changeset).to eq("id" => [nil, customer.id])
|
|
81
|
-
expect(customer.versions[1].changeset).to eq("name" => [nil, "banana"])
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require_relative "../../support/custom_json_serializer"
|
|
3
|
-
|
|
4
|
-
RSpec.describe CustomJsonSerializer do
|
|
5
|
-
describe ".load" do
|
|
6
|
-
it "deserializes, removing pairs with blank keys or values" do
|
|
7
|
-
hash = { "key1" => "banana", "tkey" => nil, "" => "foo" }
|
|
8
|
-
expect(described_class.load(hash.to_json)).to(eq("key1" => "banana"))
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
describe ".dump" do
|
|
13
|
-
it "serializes to JSON, removing pairs with nil values" do
|
|
14
|
-
hash = { "key1" => "banana", "tkey" => nil, "" => "foo" }
|
|
15
|
-
expect(described_class.dump(hash)).to(eq('{"key1":"banana","":"foo"}'))
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
module CustomYamlSerializer
|
|
4
|
-
extend PaperTrail::Serializers::YAML
|
|
5
|
-
|
|
6
|
-
def self.load(string)
|
|
7
|
-
parsed_value = super(string)
|
|
8
|
-
if parsed_value.is_a?(Hash)
|
|
9
|
-
parsed_value.reject { |k, v| (k.blank? || v.blank?) }
|
|
10
|
-
else
|
|
11
|
-
parsed_value
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def self.dump(object)
|
|
16
|
-
object.is_a?(Hash) ? super(object.reject { |_k, v| v.nil? }) : super
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
RSpec.describe CustomYamlSerializer do
|
|
21
|
-
let(:word_hash) {
|
|
22
|
-
{
|
|
23
|
-
"key1" => ::FFaker::Lorem.word,
|
|
24
|
-
"key2" => nil,
|
|
25
|
-
"tkey" => nil,
|
|
26
|
-
"" => "foo"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
context(".load") do
|
|
31
|
-
it("deserializes YAML to Ruby, removing pairs with blank keys or values") do
|
|
32
|
-
expect(described_class.load(word_hash.to_yaml)).to eq(
|
|
33
|
-
word_hash.reject { |k, v| (k.blank? || v.blank?) }
|
|
34
|
-
)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
context(".dump") do
|
|
39
|
-
it("serializes Ruby to YAML, removing pairs with nil values") do
|
|
40
|
-
expect(described_class.dump(word_hash)).to eq(
|
|
41
|
-
word_hash.reject { |_k, v| v.nil? }.to_yaml
|
|
42
|
-
)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
module PaperTrail
|
|
4
|
-
module Serializers
|
|
5
|
-
::RSpec.describe JSON do
|
|
6
|
-
let(:word_hash) {
|
|
7
|
-
(1..4).each_with_object({}) { |i, a| a["key#{i}"] = ::FFaker::Lorem.word }
|
|
8
|
-
}
|
|
9
|
-
let(:word_array) { [].fill(0, rand(5) + 4) { ::FFaker::Lorem.word } }
|
|
10
|
-
|
|
11
|
-
describe ".load" do
|
|
12
|
-
it "deserialize JSON to Ruby" do
|
|
13
|
-
expect(described_class.load(word_hash.to_json)).to eq(word_hash)
|
|
14
|
-
expect(described_class.load(word_array.to_json)).to eq(word_array)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe ".dump" do
|
|
19
|
-
it "serializes Ruby to JSON" do
|
|
20
|
-
expect(described_class.dump(word_hash)).to eq(word_hash.to_json)
|
|
21
|
-
expect(described_class.dump(word_array)).to eq(word_array.to_json)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
describe ".where_object_condition" do
|
|
26
|
-
context "when value is a string" do
|
|
27
|
-
it "construct correct WHERE query" do
|
|
28
|
-
matches = described_class.
|
|
29
|
-
where_object_condition(PaperTrail::Version.arel_table[:object], :arg1, "Val 1")
|
|
30
|
-
expect(matches.instance_of?(Arel::Nodes::Matches)).to(eq(true))
|
|
31
|
-
expect(matches.right.val).to eq("%\"arg1\":\"Val 1\"%")
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context "when value is null" do
|
|
36
|
-
it "construct correct WHERE query" do
|
|
37
|
-
matches = described_class.
|
|
38
|
-
where_object_condition(PaperTrail::Version.arel_table[:object], :arg1, nil)
|
|
39
|
-
expect(matches.instance_of?(Arel::Nodes::Matches)).to(eq(true))
|
|
40
|
-
expect(matches.right.val).to(eq("%\"arg1\":null%"))
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
context "when value is a number" do
|
|
45
|
-
it "construct correct WHERE query" do
|
|
46
|
-
grouping = described_class.
|
|
47
|
-
where_object_condition(PaperTrail::Version.arel_table[:object], :arg1, -3.5)
|
|
48
|
-
expect(grouping.instance_of?(Arel::Nodes::Grouping)).to(eq(true))
|
|
49
|
-
matches = grouping.select { |v| v.instance_of?(Arel::Nodes::Matches) }
|
|
50
|
-
expect(matches.first.right.val).to eq("%\"arg1\":-3.5,%")
|
|
51
|
-
expect(matches.last.right.val).to eq("%\"arg1\":-3.5}%")
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
module PaperTrail
|
|
4
|
-
module Serializers
|
|
5
|
-
::RSpec.describe(YAML, versioning: true) do
|
|
6
|
-
let(:array) { ::Array.new(10) { ::FFaker::Lorem.word } }
|
|
7
|
-
let(:hash) {
|
|
8
|
-
{
|
|
9
|
-
alice: "bob",
|
|
10
|
-
binary: 0xdeadbeef,
|
|
11
|
-
octal_james_bond: 0o7,
|
|
12
|
-
int: 42,
|
|
13
|
-
float: 4.2
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
describe ".load" do
|
|
18
|
-
it "deserializes YAML to Ruby" do
|
|
19
|
-
expect(described_class.load(hash.to_yaml)).to eq(hash)
|
|
20
|
-
expect(described_class.load(array.to_yaml)).to eq(array)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe ".dump" do
|
|
25
|
-
it "serializes Ruby to YAML" do
|
|
26
|
-
expect(described_class.dump(hash)).to eq(hash.to_yaml)
|
|
27
|
-
expect(described_class.dump(array)).to eq(array.to_yaml)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
describe ".where_object" do
|
|
32
|
-
it "constructs the correct WHERE query" do
|
|
33
|
-
matches = described_class.where_object_condition(
|
|
34
|
-
::PaperTrail::Version.arel_table[:object], :arg1, "Val 1"
|
|
35
|
-
)
|
|
36
|
-
expect(matches.instance_of?(Arel::Nodes::Matches)).to(eq(true))
|
|
37
|
-
expect(matches.right.val).to eq("%\narg1: Val 1\n%")
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
RSpec.describe PaperTrail do
|
|
4
|
-
describe "#set_paper_trail_whodunnit" do
|
|
5
|
-
it "is thread-safe" do
|
|
6
|
-
blocked = true
|
|
7
|
-
slow_thread = Thread.new do
|
|
8
|
-
controller = TestController.new
|
|
9
|
-
controller.send(:set_paper_trail_whodunnit)
|
|
10
|
-
sleep(0.001) while blocked
|
|
11
|
-
described_class.whodunnit
|
|
12
|
-
end
|
|
13
|
-
fast_thread = Thread.new do
|
|
14
|
-
controller = TestController.new
|
|
15
|
-
controller.send(:set_paper_trail_whodunnit)
|
|
16
|
-
who = described_class.whodunnit
|
|
17
|
-
blocked = false
|
|
18
|
-
who
|
|
19
|
-
end
|
|
20
|
-
expect(fast_thread.value).not_to(eq(slow_thread.value))
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe "#without_versioning" do
|
|
25
|
-
it "is thread-safe" do
|
|
26
|
-
enabled = nil
|
|
27
|
-
slow_thread = Thread.new do
|
|
28
|
-
Widget.new.paper_trail.without_versioning do
|
|
29
|
-
sleep(0.01)
|
|
30
|
-
enabled = Widget.paper_trail.enabled?
|
|
31
|
-
sleep(0.01)
|
|
32
|
-
end
|
|
33
|
-
enabled
|
|
34
|
-
end
|
|
35
|
-
fast_thread = Thread.new do
|
|
36
|
-
sleep(0.005)
|
|
37
|
-
Widget.paper_trail.enabled?
|
|
38
|
-
end
|
|
39
|
-
expect(fast_thread.value).not_to(eq(slow_thread.value))
|
|
40
|
-
expect(Widget.paper_trail.enabled?).to(eq(true))
|
|
41
|
-
expect(described_class.enabled_for_model?(Widget)).to(eq(true))
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
module PaperTrail
|
|
4
|
-
::RSpec.describe Cleaner, versioning: true do
|
|
5
|
-
after do
|
|
6
|
-
PaperTrail.config.version_limit = nil
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
it "cleans up old versions" do
|
|
10
|
-
PaperTrail.config.version_limit = 10
|
|
11
|
-
widget = Widget.create
|
|
12
|
-
|
|
13
|
-
100.times do |i|
|
|
14
|
-
widget.update_attributes(name: "Name #{i}")
|
|
15
|
-
expect(Widget.find(widget.id).versions.count).to be <= 11
|
|
16
|
-
# 11 versions = 10 updates + 1 create.
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "deletes oldest versions, when the database returns them in a different order" do
|
|
21
|
-
epoch = DateTime.new(2017, 1, 1)
|
|
22
|
-
|
|
23
|
-
widget = Timecop.freeze(epoch) { Widget.create }
|
|
24
|
-
|
|
25
|
-
# Sometimes a database will returns records in a different order than
|
|
26
|
-
# they were inserted. That's hard to get the database to do, so we'll
|
|
27
|
-
# just create them out-of-order:
|
|
28
|
-
(1..5).to_a.shuffle.each do |n|
|
|
29
|
-
Timecop.freeze(epoch + n.hours) do
|
|
30
|
-
PaperTrail::Version.create!(
|
|
31
|
-
item: widget,
|
|
32
|
-
event: "update",
|
|
33
|
-
object: { "id" => widget.id, "name" => "Name #{n}" }.to_yaml
|
|
34
|
-
)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
expect(Widget.find(widget.id).versions.count).to eq(6) # 1 create + 5 updates
|
|
38
|
-
|
|
39
|
-
# Now, we've recreated the scenario where we can accidentally clean up
|
|
40
|
-
# the wrong versions. Re-enable the version_limit, and trigger the
|
|
41
|
-
# clean-up:
|
|
42
|
-
PaperTrail.config.version_limit = 3
|
|
43
|
-
widget.versions.last.send(:enforce_version_limit!)
|
|
44
|
-
|
|
45
|
-
# Verify that we have fewer versions:
|
|
46
|
-
expect(widget.reload.versions.count).to eq(4) # 1 create + 4 updates
|
|
47
|
-
|
|
48
|
-
# Exclude the create, because the create will return nil for `#reify`.
|
|
49
|
-
last_names = widget.versions.not_creates.map(&:reify).map(&:name)
|
|
50
|
-
expect(last_names).to eq(["Name 3", "Name 4", "Name 5"])
|
|
51
|
-
# No matter what order the version records are returned it, we should
|
|
52
|
-
# always keep the most-recent changes.
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
module PaperTrail
|
|
4
|
-
::RSpec.describe(Version, versioning: true) do
|
|
5
|
-
describe ".creates" do
|
|
6
|
-
it "returns only create events" do
|
|
7
|
-
animal = Animal.create(name: "Foo")
|
|
8
|
-
animal.update_attributes(name: "Bar")
|
|
9
|
-
expect(described_class.creates.pluck(:event)).to eq(["create"])
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
describe ".updates" do
|
|
14
|
-
it "returns only update events" do
|
|
15
|
-
animal = Animal.create
|
|
16
|
-
animal.update_attributes(name: "Animal")
|
|
17
|
-
expect(described_class.updates.pluck(:event)).to eq(["update"])
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe ".destroys" do
|
|
22
|
-
it "returns only destroy events" do
|
|
23
|
-
animal = Animal.create
|
|
24
|
-
animal.destroy
|
|
25
|
-
expect(described_class.destroys.pluck(:event)).to eq(["destroy"])
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
describe ".not_creates" do
|
|
30
|
-
it "returns all versions except create events" do
|
|
31
|
-
animal = Animal.create
|
|
32
|
-
animal.update_attributes(name: "Animal")
|
|
33
|
-
animal.destroy
|
|
34
|
-
expect(
|
|
35
|
-
described_class.not_creates.pluck(:event)
|
|
36
|
-
).to match_array(%w[update destroy])
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe ".subsequent" do
|
|
41
|
-
context "given a timestamp" do
|
|
42
|
-
it "returns all versions that were created after the timestamp" do
|
|
43
|
-
animal = Animal.create
|
|
44
|
-
2.times do
|
|
45
|
-
animal.update_attributes(name: FFaker::Lorem.word)
|
|
46
|
-
end
|
|
47
|
-
value = described_class.subsequent(1.hour.ago, true)
|
|
48
|
-
expect(value).to eq(animal.versions.to_a)
|
|
49
|
-
expect(value.to_sql).to match(
|
|
50
|
-
/ORDER BY #{described_class.arel_table[:created_at].asc.to_sql}/
|
|
51
|
-
)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context "given a Version" do
|
|
56
|
-
it "grab the timestamp from the version and use that as the value" do
|
|
57
|
-
animal = Animal.create
|
|
58
|
-
2.times do
|
|
59
|
-
animal.update_attributes(name: FFaker::Lorem.word)
|
|
60
|
-
end
|
|
61
|
-
expect(described_class.subsequent(animal.versions.first)).to eq(
|
|
62
|
-
animal.versions.to_a.drop(1)
|
|
63
|
-
)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
describe ".preceding" do
|
|
69
|
-
context "given a timestamp" do
|
|
70
|
-
it "returns all versions that were created before the timestamp" do
|
|
71
|
-
animal = Animal.create
|
|
72
|
-
2.times do
|
|
73
|
-
animal.update_attributes(name: FFaker::Lorem.word)
|
|
74
|
-
end
|
|
75
|
-
value = described_class.preceding(5.seconds.from_now, true)
|
|
76
|
-
expect(value).to eq(animal.versions.reverse)
|
|
77
|
-
expect(value.to_sql).to match(
|
|
78
|
-
/ORDER BY #{described_class.arel_table[:created_at].desc.to_sql}/
|
|
79
|
-
)
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
context "given a Version" do
|
|
84
|
-
it "grab the timestamp from the version and use that as the value" do
|
|
85
|
-
animal = Animal.create
|
|
86
|
-
2.times do
|
|
87
|
-
animal.update_attributes(name: FFaker::Lorem.word)
|
|
88
|
-
end
|
|
89
|
-
expect(described_class.preceding(animal.versions.last)).to eq(
|
|
90
|
-
animal.versions.to_a.tap(&:pop).reverse
|
|
91
|
-
)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|