paper_trail 6.0.2 → 7.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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +20 -0
  3. data/.rubocop.yml +30 -2
  4. data/.rubocop_todo.yml +20 -0
  5. data/.travis.yml +3 -5
  6. data/Appraisals +5 -6
  7. data/CHANGELOG.md +33 -0
  8. data/README.md +43 -81
  9. data/Rakefile +1 -1
  10. data/doc/bug_report_template.rb +4 -2
  11. data/gemfiles/ar_4.0.gemfile +7 -0
  12. data/gemfiles/ar_4.2.gemfile +0 -1
  13. data/lib/generators/paper_trail/templates/create_version_associations.rb +1 -1
  14. data/lib/generators/paper_trail/templates/create_versions.rb +1 -1
  15. data/lib/paper_trail.rb +7 -9
  16. data/lib/paper_trail/config.rb +0 -15
  17. data/lib/paper_trail/frameworks/rspec.rb +8 -2
  18. data/lib/paper_trail/model_config.rb +6 -2
  19. data/lib/paper_trail/record_trail.rb +3 -1
  20. data/lib/paper_trail/reifier.rb +43 -354
  21. data/lib/paper_trail/reifiers/belongs_to.rb +48 -0
  22. data/lib/paper_trail/reifiers/has_and_belongs_to_many.rb +50 -0
  23. data/lib/paper_trail/reifiers/has_many.rb +110 -0
  24. data/lib/paper_trail/reifiers/has_many_through.rb +90 -0
  25. data/lib/paper_trail/reifiers/has_one.rb +76 -0
  26. data/lib/paper_trail/serializers/yaml.rb +2 -25
  27. data/lib/paper_trail/version_concern.rb +5 -5
  28. data/lib/paper_trail/version_number.rb +7 -3
  29. data/paper_trail.gemspec +7 -34
  30. data/spec/controllers/articles_controller_spec.rb +1 -1
  31. data/spec/generators/install_generator_spec.rb +40 -34
  32. data/spec/models/animal_spec.rb +50 -25
  33. data/spec/models/boolit_spec.rb +8 -7
  34. data/spec/models/callback_modifier_spec.rb +13 -13
  35. data/spec/models/document_spec.rb +21 -0
  36. data/spec/models/gadget_spec.rb +35 -39
  37. data/spec/models/joined_version_spec.rb +4 -4
  38. data/spec/models/json_version_spec.rb +14 -15
  39. data/spec/models/not_on_update_spec.rb +1 -1
  40. data/spec/models/post_with_status_spec.rb +2 -2
  41. data/spec/models/skipper_spec.rb +4 -4
  42. data/spec/models/thing_spec.rb +1 -1
  43. data/spec/models/truck_spec.rb +1 -1
  44. data/spec/models/vehicle_spec.rb +1 -1
  45. data/spec/models/version_spec.rb +152 -168
  46. data/spec/models/widget_spec.rb +170 -196
  47. data/spec/modules/paper_trail_spec.rb +3 -3
  48. data/spec/modules/version_concern_spec.rb +5 -8
  49. data/spec/modules/version_number_spec.rb +11 -36
  50. data/spec/paper_trail/cleaner_spec.rb +152 -0
  51. data/spec/paper_trail/config_spec.rb +1 -1
  52. data/spec/paper_trail/serializers/custom_yaml_serializer_spec.rb +45 -0
  53. data/spec/paper_trail/serializers/json_spec.rb +57 -0
  54. data/spec/paper_trail/version_limit_spec.rb +55 -0
  55. data/spec/paper_trail_spec.rb +45 -32
  56. data/spec/requests/articles_spec.rb +4 -4
  57. data/test/dummy/app/models/custom_primary_key_record.rb +4 -2
  58. data/test/dummy/app/models/document.rb +1 -1
  59. data/test/dummy/app/models/not_on_update.rb +1 -1
  60. data/test/dummy/app/models/on/create.rb +6 -0
  61. data/test/dummy/app/models/on/destroy.rb +6 -0
  62. data/test/dummy/app/models/on/empty_array.rb +6 -0
  63. data/test/dummy/app/models/on/update.rb +6 -0
  64. data/test/dummy/app/models/person.rb +1 -0
  65. data/test/dummy/app/models/song.rb +19 -28
  66. data/test/dummy/config/application.rb +10 -43
  67. data/test/dummy/config/routes.rb +1 -1
  68. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +25 -51
  69. data/test/dummy/db/schema.rb +29 -19
  70. data/test/test_helper.rb +0 -16
  71. data/test/unit/associations_test.rb +81 -81
  72. data/test/unit/model_test.rb +48 -131
  73. data/test/unit/serializer_test.rb +34 -45
  74. data/test/unit/serializers/mixin_json_test.rb +3 -1
  75. data/test/unit/serializers/yaml_test.rb +1 -5
  76. metadata +44 -19
  77. data/lib/paper_trail/frameworks/sinatra.rb +0 -40
  78. data/test/functional/modular_sinatra_test.rb +0 -46
  79. data/test/functional/sinatra_test.rb +0 -51
  80. data/test/unit/cleaner_test.rb +0 -151
  81. data/test/unit/inheritance_column_test.rb +0 -41
  82. data/test/unit/serializers/json_test.rb +0 -95
  83. data/test/unit/serializers/mixin_yaml_test.rb +0 -53
@@ -4,13 +4,13 @@ describe PaperTrail, type: :module, versioning: true do
4
4
  describe "#config" do
5
5
  it { is_expected.to respond_to(:config) }
6
6
 
7
- it "should allow for config values to be set" do
7
+ it "allows for config values to be set" do
8
8
  expect(subject.config.enabled).to eq(true)
9
9
  subject.config.enabled = false
10
10
  expect(subject.config.enabled).to eq(false)
11
11
  end
12
12
 
13
- it "should accept blocks and yield the config instance" do
13
+ it "accepts blocks and yield the config instance" do
14
14
  expect(subject.config.enabled).to eq(true)
15
15
  subject.config { |c| c.enabled = false }
16
16
  expect(subject.config.enabled).to eq(false)
@@ -20,7 +20,7 @@ describe PaperTrail, type: :module, versioning: true do
20
20
  describe "#configure" do
21
21
  it { is_expected.to respond_to(:configure) }
22
22
 
23
- it "should be an alias for the `config` method" do
23
+ it "is an alias for the `config` method" do
24
24
  expect(subject.method(:configure)).to eq(subject.method(:config))
25
25
  end
26
26
  end
@@ -18,14 +18,11 @@ describe PaperTrail::VersionConcern do
18
18
  end
19
19
 
20
20
  describe "persistence", versioning: true do
21
- before do
22
- @foo_doc = Foo::Document.create!(name: "foobar")
23
- @bar_doc = Bar::Document.create!(name: "raboof")
24
- end
25
-
26
- it "should store versions in the correct corresponding db location" do
27
- expect(@foo_doc.versions.first).to be_instance_of(Foo::Version)
28
- expect(@bar_doc.versions.first).to be_instance_of(Bar::Version)
21
+ it "stores versions in the correct corresponding db location" do
22
+ foo_doc = Foo::Document.create!(name: "foobar")
23
+ bar_doc = Bar::Document.create!(name: "raboof")
24
+ expect(foo_doc.versions.first).to be_instance_of(Foo::Version)
25
+ expect(bar_doc.versions.first).to be_instance_of(Bar::Version)
29
26
  end
30
27
  end
31
28
  end
@@ -1,43 +1,18 @@
1
1
  require "spec_helper"
2
2
 
3
- describe PaperTrail::VERSION do
4
- describe "Constants" do
5
- subject { PaperTrail::VERSION }
6
-
7
- describe :MAJOR do
8
- it { is_expected.to be_const_defined(:MAJOR) }
9
- it { expect(subject::MAJOR).to be_a(Integer) }
10
- end
11
- describe :MINOR do
12
- it { is_expected.to be_const_defined(:MINOR) }
13
- it { expect(subject::MINOR).to be_a(Integer) }
14
- end
15
- describe :TINY do
16
- it { is_expected.to be_const_defined(:TINY) }
17
- it { expect(subject::TINY).to be_a(Integer) }
18
- end
19
- describe :PRE do
20
- it { is_expected.to be_const_defined(:PRE) }
21
- if PaperTrail::VERSION::PRE
22
- it { expect(subject::PRE).to be_instance_of(String) }
23
- end
24
- end
25
- describe :STRING do
26
- it { is_expected.to be_const_defined(:STRING) }
27
- it { expect(subject::STRING).to be_instance_of(String) }
28
-
29
- it "should join the numbers into a period separated string" do
30
- expect(subject::STRING).to eq(
31
- [subject::MAJOR, subject::MINOR, subject::TINY, subject::PRE].compact.join(".")
3
+ module PaperTrail
4
+ RSpec.describe VERSION do
5
+ describe "STRING" do
6
+ it "joins the numbers into a period separated string" do
7
+ expect(described_class::STRING).to eq(
8
+ [
9
+ described_class::MAJOR,
10
+ described_class::MINOR,
11
+ described_class::TINY,
12
+ described_class::PRE
13
+ ].compact.join(".")
32
14
  )
33
15
  end
34
16
  end
35
17
  end
36
18
  end
37
-
38
- describe PaperTrail do
39
- describe "#version" do
40
- it { is_expected.to respond_to(:version) }
41
- it { expect(subject.version).to eq(PaperTrail::VERSION::STRING) }
42
- end
43
- end
@@ -0,0 +1,152 @@
1
+ require "rails_helper"
2
+
3
+ module PaperTrail
4
+ RSpec.describe Cleaner, versioning: true do
5
+ describe "clean_versions!" do
6
+ let(:animal) { ::Animal.new }
7
+ let(:dog) { ::Dog.new }
8
+ let(:cat) { ::Cat.new }
9
+ let(:animals) { [animal, dog, cat] }
10
+
11
+ before do
12
+ animals.each do |animal|
13
+ 3.times do
14
+ animal.update_attribute(:name, FFaker::Name.name)
15
+ end
16
+ end
17
+ end
18
+
19
+ it "baseline test setup" do
20
+ expect(PaperTrail::Version.count).to(eq(9))
21
+ animals.each { |animal| expect(animal.versions.size).to(eq(3)) }
22
+ end
23
+
24
+ context "no options provided" do
25
+ it "removes extra versions for each item" do
26
+ PaperTrail.clean_versions!
27
+ expect(PaperTrail::Version.count).to(eq(3))
28
+ animals.each { |animal| expect(animal.versions.size).to(eq(1)) }
29
+ end
30
+
31
+ it "removes the earliest version(s)" do
32
+ before = animals.map { |animal| animal.versions.last.reify.name }
33
+ PaperTrail.clean_versions!
34
+ after = animals.map { |animal| animal.versions.last.reify.name }
35
+ expect(after).to(eq(before))
36
+ end
37
+ end
38
+
39
+ context "keeping 2" do
40
+ it "keeps two records, instead of the usual one" do
41
+ PaperTrail.clean_versions!(keeping: 2)
42
+ expect(PaperTrail::Version.all.count).to(eq(6))
43
+ animals.each { |animal| expect(animal.versions.size).to(eq(2)) }
44
+ end
45
+ end
46
+
47
+ context "with the :date option" do
48
+ it "only deletes versions created on the given date" do
49
+ animal.versions.each do |ver|
50
+ ver.update_attribute(:created_at, (ver.created_at - 1.day))
51
+ end
52
+ date = animal.versions.first.created_at.to_date
53
+ animal.update_attribute(:name, FFaker::Name.name)
54
+ expect(PaperTrail::Version.count).to(eq(10))
55
+ expect(animal.versions.size).to(eq(4))
56
+ expect(animal.paper_trail.versions_between(date, (date + 1.day)).size).to(eq(3))
57
+ PaperTrail.clean_versions!(date: date)
58
+ expect(PaperTrail::Version.count).to(eq(8))
59
+ expect(animal.versions.reload.size).to(eq(2))
60
+ expect(animal.versions.first.created_at.to_date).to(eq(date))
61
+ # Why use `equal?` here instead of something less strict?
62
+ # Doesn't `to_date` always produce a new date object?
63
+ expect(date.equal?(animal.versions.last.created_at.to_date)).to eq(false)
64
+ end
65
+ end
66
+
67
+ context "with the :item_id option" do
68
+ context "single ID received" do
69
+ it "only deletes the versions for the Item with that ID" do
70
+ PaperTrail.clean_versions!(item_id: animal.id)
71
+ expect(animal.versions.size).to(eq(1))
72
+ expect(PaperTrail::Version.count).to(eq(7))
73
+ end
74
+ end
75
+
76
+ context "collection of IDs received" do
77
+ it "only deletes versions for the Item(s) with those IDs" do
78
+ PaperTrail.clean_versions!(item_id: [animal.id, dog.id])
79
+ expect(animal.versions.size).to(eq(1))
80
+ expect(dog.versions.size).to(eq(1))
81
+ expect(PaperTrail::Version.count).to(eq(5))
82
+ end
83
+ end
84
+ end
85
+
86
+ context "options combinations" do
87
+ context ":date" do
88
+ before do
89
+ [animal, dog].each do |animal|
90
+ animal.versions.each do |ver|
91
+ ver.update_attribute(:created_at, (ver.created_at - 1.day))
92
+ end
93
+ animal.update_attribute(:name, FFaker::Name.name)
94
+ end
95
+ end
96
+
97
+ it "baseline test setup" do
98
+ date = animal.versions.first.created_at.to_date
99
+ expect(PaperTrail::Version.count).to(eq(11))
100
+ [animal, dog].each do |animal|
101
+ expect(animal.versions.size).to(eq(4))
102
+ expect(animal.versions.between(date, (date + 1.day)).size).to(eq(3))
103
+ end
104
+ end
105
+
106
+ context "and :keeping" do
107
+ it "restrict cleaning properly" do
108
+ date = animal.versions.first.created_at.to_date
109
+ PaperTrail.clean_versions!(date: date, keeping: 2)
110
+ [animal, dog].each do |animal|
111
+ animal.versions.reload
112
+ expect(animal.versions.size).to(eq(3))
113
+ expect(animal.versions.between(date, (date + 1.day)).size).to(eq(2))
114
+ end
115
+ expect(PaperTrail::Version.count).to(eq(9))
116
+ end
117
+ end
118
+
119
+ context "and :item_id" do
120
+ it "restrict cleaning properly" do
121
+ date = animal.versions.first.created_at.to_date
122
+ PaperTrail.clean_versions!(date: date, item_id: dog.id)
123
+ dog.versions.reload
124
+ expect(dog.versions.size).to(eq(2))
125
+ expect(dog.versions.between(date, (date + 1.day)).size).to(eq(1))
126
+ expect(PaperTrail::Version.count).to(eq(9))
127
+ end
128
+ end
129
+
130
+ context ", :item_id, and :keeping" do
131
+ it "restrict cleaning properly" do
132
+ date = animal.versions.first.created_at.to_date
133
+ PaperTrail.clean_versions!(date: date, item_id: dog.id, keeping: 2)
134
+ dog.versions.reload
135
+ expect(dog.versions.size).to(eq(3))
136
+ expect(dog.versions.between(date, (date + 1.day)).size).to(eq(2))
137
+ expect(PaperTrail::Version.count).to(eq(10))
138
+ end
139
+ end
140
+ end
141
+
142
+ context ":keeping and :item_id" do
143
+ it "restrict cleaning properly" do
144
+ PaperTrail.clean_versions!(keeping: 2, item_id: animal.id)
145
+ expect(animal.versions.size).to(eq(2))
146
+ expect(PaperTrail::Version.count).to(eq(8))
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -4,7 +4,7 @@ module PaperTrail
4
4
  RSpec.describe Config do
5
5
  describe ".instance" do
6
6
  it "returns the singleton instance" do
7
- expect { described_class.instance }.to_not raise_error
7
+ expect { described_class.instance }.not_to raise_error
8
8
  end
9
9
  end
10
10
 
@@ -0,0 +1,45 @@
1
+ require "rails_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
@@ -0,0 +1,57 @@
1
+ require "rails_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
@@ -0,0 +1,55 @@
1
+ require "rails_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,79 +1,92 @@
1
1
  require "rails_helper"
2
2
 
3
- describe PaperTrail do
3
+ RSpec.describe PaperTrail do
4
+ describe ".gem_version" do
5
+ it "returns a Gem::Version" do
6
+ v = described_class.gem_version
7
+ expect(v).to be_a(::Gem::Version)
8
+ expect(v.to_s).to eq(::PaperTrail::VERSION::STRING)
9
+ end
10
+ end
11
+
4
12
  context "when enabled" do
5
13
  it "affects all threads" do
6
- Thread.new { PaperTrail.enabled = false }.join
7
- assert_equal false, PaperTrail.enabled?
14
+ Thread.new { described_class.enabled = false }.join
15
+ assert_equal false, described_class.enabled?
8
16
  end
9
17
 
10
18
  after do
11
- PaperTrail.enabled = true
19
+ described_class.enabled = true
12
20
  end
13
21
  end
14
22
 
15
23
  context "default" do
16
- it "should have versioning off by default" do
17
- expect(PaperTrail).not_to be_enabled
24
+ it "has versioning off by default" do
25
+ expect(described_class).not_to be_enabled
18
26
  end
19
27
 
20
- it "should turn versioning on in a `with_versioning` block" do
21
- expect(PaperTrail).not_to be_enabled
28
+ it "has versioning on in a `with_versioning` block" do
29
+ expect(described_class).not_to be_enabled
22
30
  with_versioning do
23
- expect(PaperTrail).to be_enabled
31
+ expect(described_class).to be_enabled
24
32
  end
25
- expect(PaperTrail).not_to be_enabled
33
+ expect(described_class).not_to be_enabled
26
34
  end
27
35
 
28
36
  context "error within `with_versioning` block" do
29
- it "should revert the value of `PaperTrail.enabled?` to it's previous state" do
30
- expect(PaperTrail).not_to be_enabled
37
+ it "reverts the value of `PaperTrail.enabled?` to its previous state" do
38
+ expect(described_class).not_to be_enabled
31
39
  expect { with_versioning { raise } }.to raise_error(RuntimeError)
32
- expect(PaperTrail).not_to be_enabled
40
+ expect(described_class).not_to be_enabled
33
41
  end
34
42
  end
35
43
  end
36
44
 
37
45
  context "`versioning: true`", versioning: true do
38
- it "should have versioning on by default" do
39
- expect(PaperTrail).to be_enabled
46
+ it "has versioning on by default" do
47
+ expect(described_class).to be_enabled
40
48
  end
41
49
 
42
- it "should keep versioning on after a with_versioning block" do
43
- expect(PaperTrail).to be_enabled
50
+ it "keeps versioning on after a with_versioning block" do
51
+ expect(described_class).to be_enabled
44
52
  with_versioning do
45
- expect(PaperTrail).to be_enabled
53
+ expect(described_class).to be_enabled
46
54
  end
47
- expect(PaperTrail).to be_enabled
55
+ expect(described_class).to be_enabled
48
56
  end
49
57
  end
50
58
 
51
59
  context "`with_versioning` block at class level" do
52
- it { expect(PaperTrail).not_to be_enabled }
60
+ it { expect(described_class).not_to be_enabled }
53
61
 
54
62
  with_versioning do
55
- it "should have versioning on by default" do
56
- expect(PaperTrail).to be_enabled
63
+ it "has versioning on by default" do
64
+ expect(described_class).to be_enabled
57
65
  end
58
66
  end
59
- it "should not leak the `enabled?` state into successive tests" do
60
- expect(PaperTrail).not_to be_enabled
67
+ it "does not leak the `enabled?` state into successive tests" do
68
+ expect(described_class).not_to be_enabled
61
69
  end
62
70
  end
63
71
 
64
- describe :whodunnit do
65
- before(:all) { PaperTrail.whodunnit = "foobar" }
72
+ describe ".version" do
73
+ it { expect(described_class).to respond_to(:version) }
74
+ it { expect(described_class.version).to eq(described_class::VERSION::STRING) }
75
+ end
76
+
77
+ describe ".whodunnit" do
78
+ before(:all) { described_class.whodunnit = "foobar" }
66
79
 
67
- it "should get set to `nil` by default" do
68
- expect(PaperTrail.whodunnit).to be_nil
80
+ it "is nil by default" do
81
+ expect(described_class.whodunnit).to be_nil
69
82
  end
70
83
  end
71
84
 
72
- describe :controller_info do
73
- before(:all) { ::PaperTrail.controller_info = { foo: "bar" } }
85
+ describe ".controller_info" do
86
+ before(:all) { described_class.controller_info = { foo: "bar" } }
74
87
 
75
- it "should get set to an empty hash before each test" do
76
- expect(PaperTrail.controller_info).to eq({})
88
+ it "is set to an empty hash before each test" do
89
+ expect(described_class.controller_info).to eq({})
77
90
  end
78
91
  end
79
92
  end