historiographer 4.0.0 → 4.1.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.
- checksums.yaml +4 -4
- data/README.md +115 -39
- data/{Gemfile → Users/brettshollenberger/programming/historiographer/Gemfile} +0 -1
- data/Users/brettshollenberger/programming/historiographer/Gemfile.lock +341 -0
- data/Users/brettshollenberger/programming/historiographer/Guardfile +4 -0
- data/Users/brettshollenberger/programming/historiographer/LICENSE.txt +20 -0
- data/Users/brettshollenberger/programming/historiographer/README.md +298 -0
- data/Users/brettshollenberger/programming/historiographer/historiographer-4.1.0.gem +0 -0
- data/{historiographer.gemspec → Users/brettshollenberger/programming/historiographer/historiographer.gemspec} +2 -43
- data/Users/brettshollenberger/programming/historiographer/lib/historiographer/configuration.rb +36 -0
- data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/history.rb +9 -2
- data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/history_migration.rb +9 -6
- data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/relation.rb +1 -1
- data/Users/brettshollenberger/programming/historiographer/lib/historiographer/version.rb +3 -0
- data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer.rb +176 -11
- data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/database.yml +5 -3
- data/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20241109182017_create_comments.rb +13 -0
- data/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20241109182020_create_comment_histories.rb +9 -0
- data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/schema.rb +80 -41
- data/Users/brettshollenberger/programming/historiographer/spec/examples.txt +40 -0
- data/{spec → Users/brettshollenberger/programming/historiographer/spec}/historiographer_spec.rb +265 -40
- data/{spec → Users/brettshollenberger/programming/historiographer/spec}/spec_helper.rb +8 -4
- metadata +41 -39
- data/.document +0 -5
- data/.rspec +0 -1
- data/.ruby-version +0 -1
- data/.standalone_migrations +0 -6
- data/Gemfile.lock +0 -289
- data/Guardfile +0 -70
- data/VERSION +0 -1
- data/spec/examples.txt +0 -32
- /data/{Rakefile → Users/brettshollenberger/programming/historiographer/Rakefile} +0 -0
- /data/{init.rb → Users/brettshollenberger/programming/historiographer/init.rb} +0 -0
- /data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/history_migration_mysql.rb +0 -0
- /data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/mysql_migration.rb +0 -0
- /data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/postgres_migration.rb +0 -0
- /data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/safe.rb +0 -0
- /data/{lib → Users/brettshollenberger/programming/historiographer/lib}/historiographer/silent.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20161121212228_create_posts.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20161121212229_create_post_histories.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20161121212230_create_authors.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20161121212231_create_author_histories.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20161121212232_create_users.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20171011194624_create_safe_posts.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20171011194715_create_safe_post_histories.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20191024142304_create_thing_with_compound_index.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20191024142352_create_thing_with_compound_index_history.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20191024203106_create_thing_without_history.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20221018204220_create_silent_posts.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/db/migrate/20221018204255_create_silent_post_histories.rb +0 -0
- /data/{spec → Users/brettshollenberger/programming/historiographer/spec}/factories/post.rb +0 -0
data/{spec → Users/brettshollenberger/programming/historiographer/spec}/historiographer_spec.rb
RENAMED
@@ -2,12 +2,41 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
+
# Helper method to handle Rails error expectations
|
6
|
+
def expect_rails_errors(errors, expected_errors)
|
7
|
+
actual_errors = errors.respond_to?(:to_hash) ? errors.to_hash : errors.to_h
|
8
|
+
# Ensure all error messages are arrays for compatibility
|
9
|
+
actual_errors.each { |key, value| actual_errors[key] = Array(value) }
|
10
|
+
expected_errors.each { |key, value| expected_errors[key] = Array(value) }
|
11
|
+
expect(actual_errors).to eq(expected_errors)
|
12
|
+
end
|
13
|
+
|
5
14
|
class Post < ActiveRecord::Base
|
6
15
|
include Historiographer
|
7
16
|
acts_as_paranoid
|
17
|
+
has_many :comments
|
18
|
+
|
19
|
+
def summary
|
20
|
+
"This is a summary of the post."
|
21
|
+
end
|
22
|
+
|
23
|
+
def formatted_title
|
24
|
+
"Title: #{title}"
|
25
|
+
end
|
8
26
|
end
|
9
27
|
|
10
|
-
class PostHistory <
|
28
|
+
class PostHistory < Post
|
29
|
+
self.table_name = "post_histories"
|
30
|
+
end
|
31
|
+
|
32
|
+
class Comment < ActiveRecord::Base
|
33
|
+
include Historiographer
|
34
|
+
belongs_to :post
|
35
|
+
belongs_to :author
|
36
|
+
end
|
37
|
+
|
38
|
+
class CommentHistory < Comment
|
39
|
+
self.table_name = "comment_histories"
|
11
40
|
end
|
12
41
|
|
13
42
|
class SafePost < ActiveRecord::Base
|
@@ -15,7 +44,8 @@ class SafePost < ActiveRecord::Base
|
|
15
44
|
acts_as_paranoid
|
16
45
|
end
|
17
46
|
|
18
|
-
class SafePostHistory <
|
47
|
+
class SafePostHistory < SafePost
|
48
|
+
self.table_name = "safe_post_histories"
|
19
49
|
end
|
20
50
|
|
21
51
|
class SilentPost < ActiveRecord::Base
|
@@ -23,14 +53,18 @@ class SilentPost < ActiveRecord::Base
|
|
23
53
|
acts_as_paranoid
|
24
54
|
end
|
25
55
|
|
26
|
-
class SilentPostHistory <
|
56
|
+
class SilentPostHistory < SilentPost
|
57
|
+
self.table_name = "silent_post_histories"
|
27
58
|
end
|
28
59
|
|
29
60
|
class Author < ActiveRecord::Base
|
30
61
|
include Historiographer
|
62
|
+
has_many :comments
|
63
|
+
has_many :posts
|
31
64
|
end
|
32
65
|
|
33
|
-
class AuthorHistory <
|
66
|
+
class AuthorHistory < Author
|
67
|
+
self.table_name = "author_histories"
|
34
68
|
end
|
35
69
|
|
36
70
|
class User < ActiveRecord::Base
|
@@ -40,16 +74,34 @@ class ThingWithCompoundIndex < ActiveRecord::Base
|
|
40
74
|
include Historiographer
|
41
75
|
end
|
42
76
|
|
43
|
-
class ThingWithCompoundIndexHistory <
|
77
|
+
class ThingWithCompoundIndexHistory < ThingWithCompoundIndex
|
78
|
+
self.table_name = "thing_with_compound_index_histories"
|
44
79
|
end
|
45
80
|
|
46
81
|
class ThingWithoutHistory < ActiveRecord::Base
|
47
82
|
end
|
48
83
|
|
84
|
+
class Comment < ActiveRecord::Base
|
85
|
+
include Historiographer
|
86
|
+
belongs_to :post
|
87
|
+
belongs_to :author
|
88
|
+
end
|
89
|
+
|
90
|
+
class CommentHistory < Comment
|
91
|
+
self.table_name = "comment_histories"
|
92
|
+
end
|
93
|
+
|
49
94
|
describe Historiographer do
|
50
|
-
before(:
|
95
|
+
before(:each) do
|
51
96
|
@now = Timecop.freeze
|
52
97
|
end
|
98
|
+
after(:each) do
|
99
|
+
Timecop.return
|
100
|
+
end
|
101
|
+
|
102
|
+
before(:all) do
|
103
|
+
Historiographer::Configuration.mode = :histories
|
104
|
+
end
|
53
105
|
|
54
106
|
after(:all) do
|
55
107
|
Timecop.return
|
@@ -77,6 +129,10 @@ describe Historiographer do
|
|
77
129
|
)
|
78
130
|
end
|
79
131
|
|
132
|
+
before(:each) do
|
133
|
+
Historiographer::Configuration.mode = :histories
|
134
|
+
end
|
135
|
+
|
80
136
|
describe 'History counting' do
|
81
137
|
it 'creates history on creation of primary model record' do
|
82
138
|
expect do
|
@@ -88,7 +144,6 @@ describe Historiographer do
|
|
88
144
|
|
89
145
|
it 'appends new history on update' do
|
90
146
|
post = create_post
|
91
|
-
|
92
147
|
expect do
|
93
148
|
post.update(title: 'Better Title')
|
94
149
|
end.to change {
|
@@ -108,6 +163,7 @@ describe Historiographer do
|
|
108
163
|
end
|
109
164
|
|
110
165
|
describe 'History recording' do
|
166
|
+
|
111
167
|
it 'records all fields from the parent' do
|
112
168
|
post = create_post
|
113
169
|
post_history = post.histories.first
|
@@ -116,7 +172,7 @@ describe Historiographer do
|
|
116
172
|
expect(post_history.body).to eq post.body
|
117
173
|
expect(post_history.author_id).to eq post.author_id
|
118
174
|
expect(post_history.post_id).to eq post.id
|
119
|
-
expect(post_history.history_started_at
|
175
|
+
expect(post_history.history_started_at).to be_within(1.second).of(@now.in_time_zone(Historiographer::UTC))
|
120
176
|
expect(post_history.history_ended_at).to be_nil
|
121
177
|
expect(post_history.history_user_id).to eq user.id
|
122
178
|
|
@@ -125,7 +181,7 @@ describe Historiographer do
|
|
125
181
|
first_history = post_histories.first
|
126
182
|
second_history = post_histories.second
|
127
183
|
|
128
|
-
expect(first_history.history_ended_at
|
184
|
+
expect(first_history.history_ended_at).to be_within(1.second).of(@now.in_time_zone(Historiographer::UTC))
|
129
185
|
expect(second_history.history_ended_at).to be_nil
|
130
186
|
end
|
131
187
|
|
@@ -135,7 +191,9 @@ describe Historiographer do
|
|
135
191
|
body: 'Great post',
|
136
192
|
author_id: 1
|
137
193
|
)
|
138
|
-
|
194
|
+
|
195
|
+
# Use the helper method for error expectation
|
196
|
+
expect_rails_errors(post.errors, history_user_id: ['must be an integer'])
|
139
197
|
|
140
198
|
expect do
|
141
199
|
post.send(:record_history)
|
@@ -189,11 +247,6 @@ describe Historiographer do
|
|
189
247
|
thing2 = ThingWithoutHistory.create(name: 'Thing 2')
|
190
248
|
|
191
249
|
ThingWithoutHistory.all.update_all(name: 'Thing 3')
|
192
|
-
|
193
|
-
expect(ThingWithoutHistory.all.map(&:name)).to all(eq 'Thing 3')
|
194
|
-
expect(ThingWithoutHistory.all).to_not respond_to :has_histories?
|
195
|
-
expect(ThingWithoutHistory.all).to_not respond_to :update_all_without_history
|
196
|
-
expect(ThingWithoutHistory.all).to_not respond_to :delete_all_without_history
|
197
250
|
end
|
198
251
|
|
199
252
|
it 'respects safety' do
|
@@ -246,12 +299,12 @@ describe Historiographer do
|
|
246
299
|
Timecop.freeze
|
247
300
|
posts = FactoryBot.create_list(:post, 3, history_user_id: 1)
|
248
301
|
Post.delete_all(history_user_id: 1)
|
249
|
-
expect(PostHistory.count).to eq 6
|
250
|
-
expect(PostHistory.current.count).to eq 3
|
251
|
-
expect(PostHistory.current.map(&:deleted_at)).to all(eq Time.now)
|
252
|
-
expect(PostHistory.current.map(&:history_user_id)).to all(eq 1)
|
253
|
-
expect(PostHistory.where(deleted_at: nil).where.not(history_ended_at: nil).count).to eq 3
|
254
|
-
expect(PostHistory.where(history_ended_at: nil).count).to eq 3
|
302
|
+
expect(PostHistory.unscoped.count).to eq 6
|
303
|
+
expect(PostHistory.unscoped.current.count).to eq 3
|
304
|
+
expect(PostHistory.unscoped.current.map(&:deleted_at)).to all(eq Time.now)
|
305
|
+
expect(PostHistory.unscoped.current.map(&:history_user_id)).to all(eq 1)
|
306
|
+
expect(PostHistory.unscoped.where(deleted_at: nil).where.not(history_ended_at: nil).count).to eq 3
|
307
|
+
expect(PostHistory.unscoped.where(history_ended_at: nil).count).to eq 3
|
255
308
|
expect(Post.count).to eq 0
|
256
309
|
Timecop.return
|
257
310
|
end
|
@@ -271,12 +324,12 @@ describe Historiographer do
|
|
271
324
|
Timecop.freeze
|
272
325
|
posts = FactoryBot.create_list(:post, 3, history_user_id: 1)
|
273
326
|
Post.destroy_all(history_user_id: 1)
|
274
|
-
expect(PostHistory.count).to eq 6
|
275
|
-
expect(PostHistory.current.count).to eq 3
|
276
|
-
expect(PostHistory.current.map(&:deleted_at)).to all(eq Time.now)
|
277
|
-
expect(PostHistory.current.map(&:history_user_id)).to all(eq 1)
|
278
|
-
expect(PostHistory.where(deleted_at: nil).where.not(history_ended_at: nil).count).to eq 3
|
279
|
-
expect(PostHistory.where(history_ended_at: nil).count).to eq 3
|
327
|
+
expect(PostHistory.unscoped.count).to eq 6
|
328
|
+
expect(PostHistory.unscoped.current.count).to eq 3
|
329
|
+
expect(PostHistory.unscoped.current.map(&:deleted_at)).to all(eq Time.now)
|
330
|
+
expect(PostHistory.unscoped.current.map(&:history_user_id)).to all(eq 1)
|
331
|
+
expect(PostHistory.unscoped.where(deleted_at: nil).where.not(history_ended_at: nil).count).to eq 3
|
332
|
+
expect(PostHistory.unscoped.where(history_ended_at: nil).count).to eq 3
|
280
333
|
expect(Post.count).to eq 0
|
281
334
|
Timecop.return
|
282
335
|
end
|
@@ -302,7 +355,7 @@ describe Historiographer do
|
|
302
355
|
body: 'Great post',
|
303
356
|
author_id: 1
|
304
357
|
)
|
305
|
-
|
358
|
+
expect_rails_errors(post.errors, {})
|
306
359
|
expect(post).to be_persisted
|
307
360
|
expect(post.histories.count).to eq 1
|
308
361
|
expect(post.histories.first.history_user_id).to be_nil
|
@@ -317,7 +370,7 @@ describe Historiographer do
|
|
317
370
|
author_id: 1,
|
318
371
|
history_user_id: user.id
|
319
372
|
)
|
320
|
-
|
373
|
+
expect_rails_errors(post.errors, {})
|
321
374
|
expect(post).to be_persisted
|
322
375
|
expect(post.histories.count).to eq 1
|
323
376
|
expect(post.histories.first.history_user_id).to eq user.id
|
@@ -345,7 +398,8 @@ describe Historiographer do
|
|
345
398
|
body: 'Great post',
|
346
399
|
author_id: 1
|
347
400
|
)
|
348
|
-
|
401
|
+
|
402
|
+
expect_rails_errors(post.errors, {})
|
349
403
|
expect(post).to be_persisted
|
350
404
|
expect(post.histories.count).to eq 1
|
351
405
|
expect(post.histories.first.history_user_id).to be_nil
|
@@ -364,7 +418,7 @@ describe Historiographer do
|
|
364
418
|
author_id: 1,
|
365
419
|
history_user_id: user.id
|
366
420
|
)
|
367
|
-
|
421
|
+
expect_rails_errors(post.errors, {})
|
368
422
|
expect(post).to be_persisted
|
369
423
|
expect(post.histories.count).to eq 1
|
370
424
|
expect(post.histories.first.history_user_id).to eq user.id
|
@@ -494,13 +548,13 @@ describe Historiographer do
|
|
494
548
|
expect do
|
495
549
|
post.destroy(history_user_id: 2)
|
496
550
|
end.to change {
|
497
|
-
PostHistory.count
|
551
|
+
PostHistory.unscoped.count
|
498
552
|
}.by 1
|
499
553
|
|
500
554
|
expect(Post.unscoped.where.not(deleted_at: nil).count).to eq 1
|
501
555
|
expect(Post.unscoped.where(deleted_at: nil).count).to eq 0
|
502
|
-
expect(PostHistory.where.not(deleted_at: nil).count).to eq 1
|
503
|
-
expect(PostHistory.last.history_user_id).to eq 2
|
556
|
+
expect(PostHistory.unscoped.where.not(deleted_at: nil).count).to eq 1
|
557
|
+
expect(PostHistory.unscoped.last.history_user_id).to eq 2
|
504
558
|
end
|
505
559
|
|
506
560
|
it 'works with Historiographer::Safe' do
|
@@ -510,10 +564,10 @@ describe Historiographer do
|
|
510
564
|
post.destroy
|
511
565
|
end.to_not raise_error
|
512
566
|
|
513
|
-
expect(SafePost.count).to eq
|
567
|
+
expect(SafePost.unscoped.count).to eq 1
|
514
568
|
expect(post.deleted_at).to_not be_nil
|
515
|
-
expect(SafePostHistory.count).to eq 2
|
516
|
-
expect(SafePostHistory.current.last.deleted_at).to eq post.deleted_at
|
569
|
+
expect(SafePostHistory.unscoped.count).to eq 2
|
570
|
+
expect(SafePostHistory.unscoped.current.last.deleted_at).to eq post.deleted_at
|
517
571
|
|
518
572
|
post2 = SafePost.create(title: 'HELLO', body: 'YO', author_id: 1)
|
519
573
|
|
@@ -523,8 +577,8 @@ describe Historiographer do
|
|
523
577
|
|
524
578
|
expect(SafePost.count).to eq 0
|
525
579
|
expect(post2.deleted_at).to_not be_nil
|
526
|
-
expect(SafePostHistory.count).to eq 4
|
527
|
-
expect(SafePostHistory.current.where(safe_post_id: post2.id).last.deleted_at).to eq post2.deleted_at
|
580
|
+
expect(SafePostHistory.unscoped.count).to eq 4
|
581
|
+
expect(SafePostHistory.unscoped.current.where(safe_post_id: post2.id).last.deleted_at).to eq post2.deleted_at
|
528
582
|
end
|
529
583
|
end
|
530
584
|
|
@@ -585,4 +639,175 @@ describe Historiographer do
|
|
585
639
|
expect(indexes).to include(['thing_with_compound_index_id'])
|
586
640
|
end
|
587
641
|
end
|
588
|
-
|
642
|
+
|
643
|
+
describe 'Reified Histories' do
|
644
|
+
let(:post) { create_post }
|
645
|
+
let(:post_history) { post.histories.first }
|
646
|
+
let(:author) { Author.create(full_name: 'Commenter Jones', history_user_id: user.id) }
|
647
|
+
let(:comment) { Comment.create(post: post, author: author, history_user_id: user.id) }
|
648
|
+
|
649
|
+
it 'responds to methods defined on the original class' do
|
650
|
+
expect(post_history).to respond_to(:summary)
|
651
|
+
expect(post_history.summary).to eq('This is a summary of the post.')
|
652
|
+
end
|
653
|
+
|
654
|
+
it 'behaves like the original class for attribute methods' do
|
655
|
+
expect(post_history.title).to eq(post.title)
|
656
|
+
expect(post_history.body).to eq(post.body)
|
657
|
+
end
|
658
|
+
|
659
|
+
it 'supports custom instance methods' do
|
660
|
+
expect(post_history).to respond_to(:formatted_title)
|
661
|
+
expect(post_history.formatted_title).to eq("Title: #{post.title}")
|
662
|
+
end
|
663
|
+
|
664
|
+
it "does not do things histories shouldn't do" do
|
665
|
+
post_history.update(title: "new title")
|
666
|
+
expect(post_history.reload.title).to eq "Post 1"
|
667
|
+
|
668
|
+
post_history.destroy
|
669
|
+
expect(post_history.reload.title).to eq "Post 1"
|
670
|
+
end
|
671
|
+
|
672
|
+
end
|
673
|
+
|
674
|
+
describe 'Snapshots' do
|
675
|
+
let(:post) { create_post }
|
676
|
+
let(:author) { Author.create(full_name: 'Commenter Jones', history_user_id: user.id) }
|
677
|
+
let(:comment) { Comment.create(body: "Mean comment! I hate you!", post: post, author: author, history_user_id: user.id) }
|
678
|
+
|
679
|
+
it 'creates a snapshot of the post and its associations' do
|
680
|
+
# Take a snapshot
|
681
|
+
comment # Make sure all records are created
|
682
|
+
post.snapshot
|
683
|
+
|
684
|
+
# Verify snapshot
|
685
|
+
snapshot_post = PostHistory.where.not(snapshot_id: nil).last
|
686
|
+
expect(snapshot_post.title).to eq post.title
|
687
|
+
expect(snapshot_post.formatted_title).to eq post.formatted_title
|
688
|
+
|
689
|
+
snapshot_comment = snapshot_post.comments.first
|
690
|
+
expect(snapshot_comment.body).to eq comment.body
|
691
|
+
expect(snapshot_comment.post_id).to eq post.id
|
692
|
+
expect(snapshot_comment.class.name).to eq "CommentHistory"
|
693
|
+
|
694
|
+
snapshot_author = snapshot_comment.author
|
695
|
+
expect(snapshot_author.full_name).to eq author.full_name
|
696
|
+
expect(snapshot_author.class.name).to eq "AuthorHistory"
|
697
|
+
|
698
|
+
# Snapshots do not allow change
|
699
|
+
expect(snapshot_post.update(title: "My title")).to eq false
|
700
|
+
expect(snapshot_post.reload.title).to eq post.title
|
701
|
+
end
|
702
|
+
|
703
|
+
it "returns the latest snapshot" do
|
704
|
+
Timecop.freeze(Time.now)
|
705
|
+
# Take a snapshot
|
706
|
+
comment # Make sure all records are created
|
707
|
+
post.snapshot(history_user_id: user.id)
|
708
|
+
comment.destroy(history_user_id: user.id)
|
709
|
+
post.comments.create!(post: post, author: author, history_user_id: user.id, body: "Sorry man, didn't mean to post that")
|
710
|
+
|
711
|
+
expect(PostHistory.count).to eq 1
|
712
|
+
expect(CommentHistory.count).to eq 2
|
713
|
+
expect(AuthorHistory.count).to eq 1
|
714
|
+
|
715
|
+
Timecop.freeze(Time.now + 5.minutes)
|
716
|
+
post.snapshot(history_user_id: user.id)
|
717
|
+
|
718
|
+
expect(PostHistory.count).to eq 2
|
719
|
+
expect(CommentHistory.count).to eq 2
|
720
|
+
expect(AuthorHistory.count).to eq 2
|
721
|
+
|
722
|
+
# Verify snapshot
|
723
|
+
snapshot_post = Post.latest_snapshot
|
724
|
+
expect(snapshot_post.title).to eq post.title
|
725
|
+
expect(snapshot_post.formatted_title).to eq post.formatted_title
|
726
|
+
|
727
|
+
snapshot_comment = snapshot_post.comments.first
|
728
|
+
expect(snapshot_post.comments.count).to eq 1
|
729
|
+
expect(snapshot_comment.body).to eq "Sorry man, didn't mean to post that"
|
730
|
+
expect(snapshot_comment.post_id).to eq post.id
|
731
|
+
expect(snapshot_comment.class.name).to eq "CommentHistory"
|
732
|
+
|
733
|
+
snapshot_author = snapshot_comment.author
|
734
|
+
expect(snapshot_author.full_name).to eq author.full_name
|
735
|
+
expect(snapshot_author.class.name).to eq "AuthorHistory"
|
736
|
+
|
737
|
+
# Snapshots do not allow change
|
738
|
+
expect(snapshot_post.update(title: "My title")).to eq false
|
739
|
+
expect(snapshot_post.reload.title).to eq post.title
|
740
|
+
|
741
|
+
Timecop.return
|
742
|
+
end
|
743
|
+
|
744
|
+
it "uses snapshot_only mode" do
|
745
|
+
Historiographer::Configuration.mode = :snapshot_only
|
746
|
+
|
747
|
+
comment # Make sure all records are created
|
748
|
+
post
|
749
|
+
expect(PostHistory.count).to eq 0
|
750
|
+
expect(CommentHistory.count).to eq 0
|
751
|
+
expect(AuthorHistory.count).to eq 0
|
752
|
+
|
753
|
+
post.snapshot
|
754
|
+
expect(PostHistory.count).to eq 1
|
755
|
+
expect(CommentHistory.count).to eq 1
|
756
|
+
expect(AuthorHistory.count).to eq 1
|
757
|
+
|
758
|
+
comment.destroy(history_user_id: user.id)
|
759
|
+
post.comments.create!(post: post, author: author, history_user_id: user.id, body: "Sorry man, didn't mean to post that")
|
760
|
+
|
761
|
+
expect(PostHistory.count).to eq 1
|
762
|
+
expect(CommentHistory.count).to eq 1
|
763
|
+
expect(AuthorHistory.count).to eq 1
|
764
|
+
|
765
|
+
Timecop.freeze(Time.now + 5.minutes)
|
766
|
+
post.snapshot
|
767
|
+
|
768
|
+
expect(PostHistory.count).to eq 2
|
769
|
+
expect(CommentHistory.count).to eq 2
|
770
|
+
expect(AuthorHistory.count).to eq 2
|
771
|
+
end
|
772
|
+
|
773
|
+
end
|
774
|
+
|
775
|
+
describe 'Class-level mode setting' do
|
776
|
+
before(:each) do
|
777
|
+
Historiographer::Configuration.mode = :histories
|
778
|
+
end
|
779
|
+
|
780
|
+
it "uses class-level snapshot_only mode" do
|
781
|
+
class Post < ActiveRecord::Base
|
782
|
+
historiographer_mode :snapshot_only
|
783
|
+
end
|
784
|
+
|
785
|
+
author = Author.create(full_name: 'Commenter Jones', history_user_id: user.id)
|
786
|
+
post = Post.create(title: 'Snapshot Only Post', body: 'Test', author_id: 1, history_user_id: user.id)
|
787
|
+
comment = Comment.create(post: post, author: author, history_user_id: user.id, body: "Initial comment")
|
788
|
+
|
789
|
+
expect(PostHistory.count).to eq 0
|
790
|
+
expect(CommentHistory.count).to eq 1 # Comment still uses default :histories mode
|
791
|
+
|
792
|
+
post.snapshot
|
793
|
+
expect(PostHistory.count).to eq 1
|
794
|
+
expect(CommentHistory.count).to eq 1
|
795
|
+
|
796
|
+
post.update(title: 'Updated Snapshot Only Post', history_user_id: user.id)
|
797
|
+
expect(PostHistory.count).to eq 1 # No new history created for update
|
798
|
+
expect(CommentHistory.count).to eq 1
|
799
|
+
|
800
|
+
Timecop.freeze(Time.now + 5.minutes)
|
801
|
+
post.snapshot
|
802
|
+
|
803
|
+
expect(PostHistory.count).to eq 2
|
804
|
+
expect(CommentHistory.count).to eq 2 # Comment creates a new history
|
805
|
+
|
806
|
+
Timecop.return
|
807
|
+
|
808
|
+
class Post < ActiveRecord::Base
|
809
|
+
historiographer_mode nil
|
810
|
+
end
|
811
|
+
end
|
812
|
+
end
|
813
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
ENV["
|
1
|
+
ENV["HISTORIOGRAPHER_ENV"] = "test"
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
2
3
|
|
3
4
|
require_relative "../init.rb"
|
4
5
|
require "ostruct"
|
@@ -34,12 +35,15 @@ RSpec.configure do |config|
|
|
34
35
|
config.before(:suite) do
|
35
36
|
DatabaseCleaner.strategy = :transaction
|
36
37
|
DatabaseCleaner.clean_with(:truncation)
|
38
|
+
ActiveRecord::Migration.maintain_test_schema!
|
37
39
|
end
|
38
40
|
|
39
41
|
config.around(:each) do |example|
|
40
|
-
DatabaseCleaner.
|
41
|
-
|
42
|
-
|
42
|
+
DatabaseCleaner.strategy = :transaction
|
43
|
+
DatabaseCleaner.start
|
44
|
+
example.run
|
45
|
+
DatabaseCleaner.clean
|
46
|
+
DatabaseCleaner.clean_with(:truncation)
|
43
47
|
end
|
44
48
|
|
45
49
|
config.before(:each, :logsql) do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: historiographer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- brettshollenberger
|
@@ -228,46 +228,48 @@ extra_rdoc_files:
|
|
228
228
|
- LICENSE.txt
|
229
229
|
- README.md
|
230
230
|
files:
|
231
|
-
- "
|
232
|
-
- ".
|
233
|
-
- "
|
234
|
-
- ".
|
235
|
-
-
|
236
|
-
-
|
237
|
-
-
|
231
|
+
- "/Users/brettshollenberger/programming/historiographer/Gemfile"
|
232
|
+
- "/Users/brettshollenberger/programming/historiographer/Gemfile.lock"
|
233
|
+
- "/Users/brettshollenberger/programming/historiographer/Guardfile"
|
234
|
+
- "/Users/brettshollenberger/programming/historiographer/LICENSE.txt"
|
235
|
+
- "/Users/brettshollenberger/programming/historiographer/README.md"
|
236
|
+
- "/Users/brettshollenberger/programming/historiographer/Rakefile"
|
237
|
+
- "/Users/brettshollenberger/programming/historiographer/historiographer-4.1.0.gem"
|
238
|
+
- "/Users/brettshollenberger/programming/historiographer/historiographer.gemspec"
|
239
|
+
- "/Users/brettshollenberger/programming/historiographer/init.rb"
|
240
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer.rb"
|
241
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/configuration.rb"
|
242
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/history.rb"
|
243
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/history_migration.rb"
|
244
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/history_migration_mysql.rb"
|
245
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/mysql_migration.rb"
|
246
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/postgres_migration.rb"
|
247
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/relation.rb"
|
248
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/safe.rb"
|
249
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/silent.rb"
|
250
|
+
- "/Users/brettshollenberger/programming/historiographer/lib/historiographer/version.rb"
|
251
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/database.yml"
|
252
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20161121212228_create_posts.rb"
|
253
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20161121212229_create_post_histories.rb"
|
254
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20161121212230_create_authors.rb"
|
255
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20161121212231_create_author_histories.rb"
|
256
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20161121212232_create_users.rb"
|
257
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20171011194624_create_safe_posts.rb"
|
258
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20171011194715_create_safe_post_histories.rb"
|
259
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20191024142304_create_thing_with_compound_index.rb"
|
260
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20191024142352_create_thing_with_compound_index_history.rb"
|
261
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20191024203106_create_thing_without_history.rb"
|
262
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20221018204220_create_silent_posts.rb"
|
263
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20221018204255_create_silent_post_histories.rb"
|
264
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20241109182017_create_comments.rb"
|
265
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/migrate/20241109182020_create_comment_histories.rb"
|
266
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/db/schema.rb"
|
267
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/examples.txt"
|
268
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/factories/post.rb"
|
269
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/historiographer_spec.rb"
|
270
|
+
- "/Users/brettshollenberger/programming/historiographer/spec/spec_helper.rb"
|
238
271
|
- LICENSE.txt
|
239
272
|
- README.md
|
240
|
-
- Rakefile
|
241
|
-
- VERSION
|
242
|
-
- historiographer.gemspec
|
243
|
-
- init.rb
|
244
|
-
- lib/historiographer.rb
|
245
|
-
- lib/historiographer/history.rb
|
246
|
-
- lib/historiographer/history_migration.rb
|
247
|
-
- lib/historiographer/history_migration_mysql.rb
|
248
|
-
- lib/historiographer/mysql_migration.rb
|
249
|
-
- lib/historiographer/postgres_migration.rb
|
250
|
-
- lib/historiographer/relation.rb
|
251
|
-
- lib/historiographer/safe.rb
|
252
|
-
- lib/historiographer/silent.rb
|
253
|
-
- spec/db/database.yml
|
254
|
-
- spec/db/migrate/20161121212228_create_posts.rb
|
255
|
-
- spec/db/migrate/20161121212229_create_post_histories.rb
|
256
|
-
- spec/db/migrate/20161121212230_create_authors.rb
|
257
|
-
- spec/db/migrate/20161121212231_create_author_histories.rb
|
258
|
-
- spec/db/migrate/20161121212232_create_users.rb
|
259
|
-
- spec/db/migrate/20171011194624_create_safe_posts.rb
|
260
|
-
- spec/db/migrate/20171011194715_create_safe_post_histories.rb
|
261
|
-
- spec/db/migrate/20191024142304_create_thing_with_compound_index.rb
|
262
|
-
- spec/db/migrate/20191024142352_create_thing_with_compound_index_history.rb
|
263
|
-
- spec/db/migrate/20191024203106_create_thing_without_history.rb
|
264
|
-
- spec/db/migrate/20221018204220_create_silent_posts.rb
|
265
|
-
- spec/db/migrate/20221018204255_create_silent_post_histories.rb
|
266
|
-
- spec/db/schema.rb
|
267
|
-
- spec/examples.txt
|
268
|
-
- spec/factories/post.rb
|
269
|
-
- spec/historiographer_spec.rb
|
270
|
-
- spec/spec_helper.rb
|
271
273
|
homepage: http://github.com/brettshollenberger/historiographer
|
272
274
|
licenses:
|
273
275
|
- MIT
|
data/.document
DELETED
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--color
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
3.0.2
|