mongoid-history 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84ee622b782d764b3a15ea31bfac94cbedf3fa023d8ae0302022562d6a5a6ec2
4
- data.tar.gz: abf09c6ed9db7126b9d7754f42a0f1b00317919ad6744f0486b4d970601eb3f4
3
+ metadata.gz: 7f7558f1c6033e5350cdeb3732e385d483c7abfa71ffc7f89acfbba22befff97
4
+ data.tar.gz: 71c5f5ab67e1bd040e14b040211b1acc5532449f048919c83adcb4e875f7eac4
5
5
  SHA512:
6
- metadata.gz: 484eb94fae5bba8b787ffda61403e65c95684f9e3a77c03daa56952e056c440d639d58d3a381760e7996ec1bec1415fe409f6688fab38ed24d6e0315f53c9369
7
- data.tar.gz: f66b6abc4dcf17696bafea67faddbcd0b97f194e8b8b36c48f32461a31987b9867a6dbf204a8604a391654ebace4c94c76b4b745ac2511b74db8df26f886d54a
6
+ metadata.gz: f528411205ca81444296803927b54c1bd1ef570611b2b4a9bb79f6e4165fb038c5b13ad5fb79c8adde96c62eaefa1142bf5f4c6b5f44d72a80743f38a0aa5d48
7
+ data.tar.gz: 4149122d3f6c474f5f0105772fa64a9fe237d299005e97ad021e887f42687d1a81ede778c589070231319704b9c71e2f99a5e660d04c2581a078178e965b0425
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-06-09 13:41:12 +0200 using RuboCop version 0.60.0.
3
+ # on 2020-04-10 17:25:32 -0500 using RuboCop version 0.48.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -8,19 +8,11 @@
8
8
 
9
9
  # Offense count: 7
10
10
  # Configuration parameters: Include.
11
- # Include: **/*.gemfile, **/Gemfile, **/gems.rb
11
+ # Include: **/Gemfile, **/gems.rb
12
12
  Bundler/DuplicatedGem:
13
13
  Exclude:
14
14
  - 'Gemfile'
15
15
 
16
- # Offense count: 1
17
- # Cop supports --auto-correct.
18
- # Configuration parameters: EnforcedStyleAlignWith, AutoCorrect, Severity.
19
- # SupportedStylesAlignWith: keyword, variable, start_of_line
20
- Layout/EndAlignment:
21
- Exclude:
22
- - 'lib/mongoid/history/options.rb'
23
-
24
16
  # Offense count: 3
25
17
  Lint/HandleExceptions:
26
18
  Exclude:
@@ -38,21 +30,26 @@ Metrics/AbcSize:
38
30
 
39
31
  # Offense count: 122
40
32
  # Configuration parameters: CountComments, ExcludedMethods.
41
- # ExcludedMethods: refine
42
33
  Metrics/BlockLength:
43
34
  Max: 837
44
35
 
45
36
  # Offense count: 1
46
37
  # Configuration parameters: CountComments.
47
38
  Metrics/ClassLength:
48
- Max: 125
39
+ Max: 120
49
40
 
50
41
  # Offense count: 6
51
42
  Metrics/CyclomaticComplexity:
52
43
  Max: 13
53
44
 
45
+ # Offense count: 412
46
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
47
+ # URISchemes: http, https
48
+ Metrics/LineLength:
49
+ Max: 688
50
+
54
51
  # Offense count: 17
55
- # Configuration parameters: CountComments, ExcludedMethods.
52
+ # Configuration parameters: CountComments.
56
53
  Metrics/MethodLength:
57
54
  Max: 23
58
55
 
@@ -65,15 +62,7 @@ Metrics/ModuleLength:
65
62
  Metrics/PerceivedComplexity:
66
63
  Max: 15
67
64
 
68
- # Offense count: 1
69
- # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
70
- # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
71
- Naming/FileName:
72
- Exclude:
73
- - 'Dangerfile'
74
- - 'lib/mongoid-history.rb'
75
-
76
- # Offense count: 12
65
+ # Offense count: 15
77
66
  Style/Documentation:
78
67
  Exclude:
79
68
  - 'spec/**/*'
@@ -86,6 +75,8 @@ Style/Documentation:
86
75
  - 'lib/mongoid/history/options.rb'
87
76
  - 'lib/mongoid/history/trackable.rb'
88
77
  - 'lib/mongoid/history/tracker.rb'
78
+ - 'perf/benchmark_modified_attributes_for_create.rb'
79
+ - 'perf/gc_suite.rb'
89
80
 
90
81
  # Offense count: 3
91
82
  # Cop supports --auto-correct.
@@ -94,13 +85,15 @@ Style/EachWithObject:
94
85
  - 'lib/mongoid/history/trackable.rb'
95
86
  - 'lib/mongoid/history/tracker.rb'
96
87
 
88
+ # Offense count: 2
89
+ # Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
90
+ # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
91
+ Style/FileName:
92
+ Exclude:
93
+ - 'Dangerfile'
94
+ - 'lib/mongoid-history.rb'
95
+
97
96
  # Offense count: 1
98
97
  Style/MultilineBlockChain:
99
98
  Exclude:
100
99
  - 'lib/mongoid/history/tracker.rb'
101
-
102
- # Offense count: 404
103
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
104
- # URISchemes: http, https
105
- Metrics/LineLength:
106
- Max: 688
@@ -1,3 +1,11 @@
1
+ ### 0.8.3 (2020/05/17)
2
+
3
+ * [#236](https://github.com/mongoid/mongoid-history/pull/236): Fix Ruby 2.7 keyword argument warnings - [@vasilysn](https://github.com/vasilysn).
4
+ * [#237](https://github.com/mongoid/mongoid-history/pull/237): Fix tracking subclasses with additional fields - [@getaroom](https://github.com/getaroom).
5
+ * [#239](https://github.com/mongoid/mongoid-history/pull/239): Optimize `modified_attributes_for_create` 6-7x - [@getaroom](https://github.com/getaroom).
6
+ * [#240](https://github.com/mongoid/mongoid-history/pull/240): `Mongoid::History.disable` and `disable_tracking` now restore the original state - [@getaroom](https://github.com/getaroom).
7
+ * [#240](https://github.com/mongoid/mongoid-history/pull/240): Added `Mongoid::History.enable`, `Mongoid::History.enable!`, `Mongoid::History.disable!`, `enable_tracking`, `enable_tracking!`, and `disable_tracking!` - [@getaroom](https://github.com/getaroom).
8
+
1
9
  ### 0.8.2 (2019/12/02)
2
10
 
3
11
  * [#233](https://github.com/mongoid/mongoid-history/pull/233): Bug fix-Track ALL embedded relations when used with fields and filtered attributes on embedded objects - [@jagdeepsingh](https://github.com/jagdeepsingh).
data/Gemfile CHANGED
@@ -29,6 +29,7 @@ group :development, :test do
29
29
  end
30
30
 
31
31
  group :test do
32
+ gem 'benchmark-ips', require: false
32
33
  gem 'coveralls'
33
34
  gem 'gem-release'
34
35
  gem 'mongoid-danger', '~> 0.1.0', require: false
data/README.md CHANGED
@@ -149,11 +149,34 @@ Comment.disable_tracking do
149
149
  comment.update_attributes(:title => "Test 3")
150
150
  end
151
151
 
152
- # globally disable all history tracking
152
+ # disable tracking for comments by default
153
+ Comment.disable_tracking!
154
+
155
+ # enable tracking for comments within a block
156
+ Comment.enable_tracking do
157
+ comment.update_attributes(:title => "Test 3")
158
+ end
159
+
160
+ # renable tracking for comments by default
161
+ Comment.enable_tracking!
162
+
163
+ # globally disable all history tracking within a block
153
164
  Mongoid::History.disable do
154
165
  comment.update_attributes(:title => "Test 3")
155
166
  user.update_attributes(:name => "Eddie Van Halen")
156
167
  end
168
+
169
+ # globally disable all history tracking by default
170
+ Mongoid::History.disable!
171
+
172
+ # globally enable all history tracking within a block
173
+ Mongoid::History.enable do
174
+ comment.update_attributes(:title => "Test 3")
175
+ user.update_attributes(:name => "Eddie Van Halen")
176
+ end
177
+
178
+ # globally renable all history tracking by default
179
+ Mongoid::History.enable!
157
180
  ```
158
181
 
159
182
  You may want to track changes on all fields.
@@ -516,7 +539,7 @@ For more examples, check out [spec/integration/integration_spec.rb](spec/integra
516
539
 
517
540
  You can have different trackers for different classes like so.
518
541
 
519
- ```
542
+ ``` ruby
520
543
  class First
521
544
  include Mongoid::Document
522
545
  include Mongoid::History::Trackable
@@ -19,13 +19,25 @@ module Mongoid
19
19
  attr_accessor :modifier_class_name
20
20
  attr_accessor :current_user_method
21
21
 
22
- def disable(&_block)
22
+ def disable
23
+ original_flag = store[GLOBAL_TRACK_HISTORY_FLAG]
23
24
  store[GLOBAL_TRACK_HISTORY_FLAG] = false
24
- yield
25
+ yield if block_given?
25
26
  ensure
27
+ store[GLOBAL_TRACK_HISTORY_FLAG] = original_flag if block_given?
28
+ end
29
+
30
+ def enable
31
+ original_flag = store[GLOBAL_TRACK_HISTORY_FLAG]
26
32
  store[GLOBAL_TRACK_HISTORY_FLAG] = true
33
+ yield if block_given?
34
+ ensure
35
+ store[GLOBAL_TRACK_HISTORY_FLAG] = original_flag if block_given?
27
36
  end
28
37
 
38
+ alias disable! disable
39
+ alias enable! enable
40
+
29
41
  def enabled?
30
42
  store[GLOBAL_TRACK_HISTORY_FLAG] != false
31
43
  end
@@ -4,14 +4,9 @@ module Mongoid
4
4
  class Create < ::Mongoid::History::Attributes::Base
5
5
  def attributes
6
6
  @attributes = {}
7
- trackable.attributes.each do |k, v|
7
+ changes.each do |k, v|
8
8
  next unless trackable_class.tracked_field?(k, :create)
9
- modified = if changes[k]
10
- changes[k].class == Array ? changes[k].last : changes[k]
11
- else
12
- v
13
- end
14
- @attributes[k] = [nil, format_field(k, modified)]
9
+ @attributes[k] = format_field(k, v)
15
10
  end
16
11
  insert_embeds_one_changes
17
12
  insert_embeds_many_changes
@@ -13,29 +13,28 @@ module Mongoid
13
13
  end
14
14
 
15
15
  def prepared
16
- @prepared ||= begin
17
- prepare_skipped_fields
18
- prepare_formatted_fields
19
- parse_tracked_fields_and_relations
20
- options
21
- end
16
+ return @prepared if @prepared
17
+ @prepared = options.dup
18
+ prepare_skipped_fields
19
+ prepare_formatted_fields
20
+ parse_tracked_fields_and_relations
21
+ @prepared
22
22
  end
23
23
 
24
24
  private
25
25
 
26
26
  def default_options
27
- @default_options ||=
28
- { on: :all,
29
- except: %i[created_at updated_at],
30
- tracker_class_name: nil,
31
- modifier_field: :modifier,
32
- version_field: :version,
33
- changes_method: :changes,
34
- scope: scope,
35
- track_create: true,
36
- track_update: true,
37
- track_destroy: true,
38
- format: nil }
27
+ { on: :all,
28
+ except: %i[created_at updated_at],
29
+ tracker_class_name: nil,
30
+ modifier_field: :modifier,
31
+ version_field: :version,
32
+ changes_method: :changes,
33
+ scope: scope,
34
+ track_create: true,
35
+ track_update: true,
36
+ track_destroy: true,
37
+ format: nil }
39
38
  end
40
39
 
41
40
  # Sets the :except attributes and relations in `options` to be an [ Array <String> ]
@@ -43,15 +42,15 @@ module Mongoid
43
42
  # Removes the `nil` and duplicate entries from skipped attributes/relations list
44
43
  def prepare_skipped_fields
45
44
  # normalize :except fields to an array of database field strings
46
- @options[:except] = Array(options[:except])
47
- @options[:except] = options[:except].map { |field| trackable.database_field_name(field) }.compact.uniq
45
+ @prepared[:except] = Array(@prepared[:except])
46
+ @prepared[:except] = @prepared[:except].map { |field| trackable.database_field_name(field) }.compact.uniq
48
47
  end
49
48
 
50
49
  def prepare_formatted_fields
51
50
  formats = {}
52
51
 
53
- if options[:format].class == Hash
54
- options[:format].each do |field, format|
52
+ if @prepared[:format].class == Hash
53
+ @prepared[:format].each do |field, format|
55
54
  next if field.nil?
56
55
 
57
56
  field = trackable.database_field_name(field)
@@ -68,7 +67,7 @@ module Mongoid
68
67
  end
69
68
  end
70
69
 
71
- options[:format] = formats
70
+ @prepared[:format] = formats
72
71
  end
73
72
 
74
73
  def parse_tracked_fields_and_relations
@@ -76,25 +75,25 @@ module Mongoid
76
75
  # when `posts: [:id, :title]`, then it will convert it to `[[:posts, [:id, :title]]]`
77
76
  # when `:foo`, then `[:foo]`
78
77
  # when `[:foo, { posts: [:id, :title] }]`, then return as is
79
- @options[:on] = Array(options[:on])
78
+ @prepared[:on] = Array(@prepared[:on])
80
79
 
81
- @options[:on] = options[:on].map { |opt| opt == :all ? :fields : opt }
80
+ @prepared[:on] = @prepared[:on].map { |opt| opt == :all ? :fields : opt }
82
81
 
83
- if options[:on].include?(:fields)
84
- @options[:on] = options[:on].reject { |opt| opt == :fields }
85
- @options[:on] = options[:on] | trackable.fields.keys.map(&:to_sym) - reserved_fields.map(&:to_sym)
82
+ if @prepared[:on].include?(:fields)
83
+ @prepared[:on] = @prepared[:on].reject { |opt| opt == :fields }
84
+ @prepared[:on] = @prepared[:on] | trackable.fields.keys.map(&:to_sym) - reserved_fields.map(&:to_sym)
86
85
  end
87
86
 
88
- if options[:on].include?(:embedded_relations)
89
- @options[:on] = options[:on].reject { |opt| opt == :embedded_relations }
90
- @options[:on] = options[:on] | trackable.embedded_relations.keys
87
+ if @prepared[:on].include?(:embedded_relations)
88
+ @prepared[:on] = @prepared[:on].reject { |opt| opt == :embedded_relations }
89
+ @prepared[:on] = @prepared[:on] | trackable.embedded_relations.keys
91
90
  end
92
91
 
93
- @options[:fields] = []
94
- @options[:dynamic] = []
95
- @options[:relations] = { embeds_one: {}, embeds_many: {} }
92
+ @prepared[:fields] = []
93
+ @prepared[:dynamic] = []
94
+ @prepared[:relations] = { embeds_one: {}, embeds_many: {} }
96
95
 
97
- options[:on].each do |option|
96
+ @prepared[:on].each do |option|
98
97
  if option.is_a?(Hash)
99
98
  option.each { |k, v| split_and_categorize(k => v) }
100
99
  else
@@ -145,7 +144,7 @@ module Mongoid
145
144
  # @param [ String ] field The database field name of field or relation to track
146
145
  # @param [ nil | Array <String | Symbol> ] field_options The tracked fields for embedded relations
147
146
  def categorize_tracked_option(field, field_options = nil)
148
- return if options[:except].include?(field)
147
+ return if @prepared[:except].include?(field)
149
148
  return if reserved_fields.include?(field)
150
149
 
151
150
  field_options = Array(field_options)
@@ -155,23 +154,23 @@ module Mongoid
155
154
  elsif trackable.embeds_many?(field)
156
155
  track_relation(field, :embeds_many, field_options)
157
156
  elsif trackable.fields.keys.include?(field)
158
- @options[:fields] << field
157
+ @prepared[:fields] << field
159
158
  else
160
- @options[:dynamic] << field
159
+ @prepared[:dynamic] << field
161
160
  end
162
161
  end
163
162
 
164
163
  def track_relation(field, kind, field_options)
165
164
  relation_class = trackable.relation_class_of(field)
166
- @options[:relations][kind][field] = if field_options.blank?
167
- relation_class.fields.keys
168
- else
169
- %w[_id] | field_options.map { |opt| relation_class.database_field_name(opt) }
170
- end
165
+ @prepared[:relations][kind][field] = if field_options.blank?
166
+ relation_class.fields.keys
167
+ else
168
+ %w[_id] | field_options.map { |opt| relation_class.database_field_name(opt) }
169
+ end
171
170
  end
172
171
 
173
172
  def reserved_fields
174
- @reserved_fields ||= ['_id', '_type', options[:version_field].to_s, "#{options[:modifier_field]}_id"]
173
+ @reserved_fields ||= ['_id', '_type', @prepared[:version_field].to_s, "#{@prepared[:modifier_field]}_id"]
175
174
  end
176
175
  end
177
176
  end
@@ -25,9 +25,9 @@ module Mongoid
25
25
  delegate :track_history?, to: 'self.class'
26
26
 
27
27
  callback_options = history_options.options.slice(:if, :unless)
28
- around_update :track_update, callback_options if history_options.options[:track_update]
29
- around_create :track_create, callback_options if history_options.options[:track_create]
30
- around_destroy :track_destroy, callback_options if history_options.options[:track_destroy]
28
+ around_update :track_update, **callback_options if history_options.options[:track_update]
29
+ around_create :track_create, **callback_options if history_options.options[:track_create]
30
+ around_destroy :track_destroy, **callback_options if history_options.options[:track_destroy]
31
31
 
32
32
  unless respond_to? :mongoid_history_options
33
33
  class_attribute :mongoid_history_options, instance_accessor: false
@@ -52,13 +52,25 @@ module Mongoid
52
52
  Mongoid::Compatibility::Version.mongoid3? || (self < Mongoid::Attributes::Dynamic).present?
53
53
  end
54
54
 
55
- def disable_tracking(&_block)
55
+ def disable_tracking
56
+ original_flag = Mongoid::History.store[track_history_flag]
56
57
  Mongoid::History.store[track_history_flag] = false
57
- yield
58
+ yield if block_given?
58
59
  ensure
60
+ Mongoid::History.store[track_history_flag] = original_flag if block_given?
61
+ end
62
+
63
+ def enable_tracking
64
+ original_flag = Mongoid::History.store[track_history_flag]
59
65
  Mongoid::History.store[track_history_flag] = true
66
+ yield if block_given?
67
+ ensure
68
+ Mongoid::History.store[track_history_flag] = original_flag if block_given?
60
69
  end
61
70
 
71
+ alias disable_tracking! disable_tracking
72
+ alias enable_tracking! enable_tracking
73
+
62
74
  def track_history_flag
63
75
  "mongoid_history_#{name.underscore}_trackable_enabled".to_sym
64
76
  end
@@ -559,7 +571,11 @@ module Mongoid
559
571
  @tracked_fields = nil
560
572
  @tracked_embeds_one = nil
561
573
  @tracked_embeds_many = nil
562
- @obfuscated_fields = nil
574
+ end
575
+
576
+ def inherited(subclass)
577
+ super
578
+ subclass.mongoid_history_options = Mongoid::History::Options.new(subclass, mongoid_history_options.options)
563
579
  end
564
580
  end
565
581
  end
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module History
3
- VERSION = '0.8.2'.freeze
3
+ VERSION = '0.8.3'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,65 @@
1
+ $LOAD_PATH.push File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'mongoid'
4
+ require 'mongoid/history'
5
+
6
+ require 'benchmark/ips'
7
+ require './perf/gc_suite'
8
+
9
+ Mongoid.connect_to('mongoid_history_perf_test')
10
+ Mongo::Logger.logger.level = ::Logger::FATAL
11
+ Mongoid.purge!
12
+
13
+ Attributes = Mongoid::History::Attributes
14
+
15
+ module ZeroPointEight
16
+ class Create < Attributes::Create
17
+ def attributes
18
+ @attributes = {}
19
+ trackable.attributes.each do |k, v|
20
+ next unless trackable_class.tracked_field?(k, :create)
21
+ modified = if changes[k]
22
+ changes[k].class == Array ? changes[k].last : changes[k]
23
+ else
24
+ v
25
+ end
26
+ @attributes[k] = [nil, format_field(k, modified)]
27
+ end
28
+ insert_embeds_one_changes
29
+ insert_embeds_many_changes
30
+ @attributes
31
+ end
32
+ end
33
+ end
34
+
35
+ class Person
36
+ include Mongoid::Document
37
+ include Mongoid::History::Trackable
38
+
39
+ field :first_name, type: String
40
+ field :last_name, type: String
41
+ field :birth_date, type: Date
42
+ field :title, type: String
43
+
44
+ track_history on: %i[first_name last_name birth_date]
45
+ end
46
+
47
+ new_person = Person.new(first_name: 'Eliot', last_name: 'Horowitz', birth_date: '1981-05-01', title: 'CTO')
48
+
49
+ Benchmark.ips do |bm|
50
+ bm.config(suite: GCSuite.new)
51
+
52
+ bm.report('HEAD') do
53
+ Attributes::Create.new(new_person).attributes
54
+ end
55
+
56
+ bm.report('v0.8.2') do
57
+ ZeroPointEight::Create.new(new_person).attributes
58
+ end
59
+
60
+ bm.report('v0.5.0') do
61
+ new_person.attributes.each_with_object({}) { |(k, v), h| h[k] = [nil, v] }.select { |k, _| new_person.class.tracked_field?(k, :create) }
62
+ end
63
+
64
+ bm.compare!
65
+ end
@@ -0,0 +1,21 @@
1
+ class GCSuite
2
+ def warming(*)
3
+ run_gc
4
+ end
5
+
6
+ def running(*)
7
+ run_gc
8
+ end
9
+
10
+ def warmup_stats(*); end
11
+
12
+ def add_report(*); end
13
+
14
+ private
15
+
16
+ def run_gc
17
+ GC.enable
18
+ GC.start
19
+ GC.disable
20
+ end
21
+ end
@@ -7,12 +7,16 @@ describe Mongoid::History::Tracker do
7
7
  include Mongoid::Timestamps
8
8
  include Mongoid::History::Trackable
9
9
 
10
+ track_history
11
+
10
12
  field :body
11
13
 
12
- track_history on: [:body]
14
+ # force preparation of options
15
+ history_trackable_options
13
16
  end
14
17
 
15
18
  class Prompt < Element
19
+ field :head
16
20
  end
17
21
 
18
22
  class User
@@ -31,11 +35,13 @@ describe Mongoid::History::Tracker do
31
35
  it 'tracks subclass create and update' do
32
36
  prompt = Prompt.new(modifier: user)
33
37
  expect { prompt.save! }.to change(Tracker, :count).by(1)
34
- expect { prompt.update_attributes!(body: 'one') }.to change(Tracker, :count).by(1)
38
+ expect { prompt.update_attributes!(body: 'one', head: 'two') }.to change(Tracker, :count).by(1)
35
39
  prompt.undo! user
36
40
  expect(prompt.body).to be_blank
41
+ expect(prompt.head).to be_blank
37
42
  prompt.redo! user, 2
38
43
  expect(prompt.body).to eq('one')
44
+ expect(prompt.head).to eq('two')
39
45
  expect { prompt.destroy }.to change(Tracker, :count).by(1)
40
46
  end
41
47
  end
@@ -84,6 +84,12 @@ describe Mongoid::History::Options do
84
84
  end
85
85
 
86
86
  describe '#parse' do
87
+ it 'does not mutate the original options' do
88
+ original_options = service.options.dup
89
+ service.prepared
90
+ expect(service.options).to eq original_options
91
+ end
92
+
87
93
  describe '#default_options' do
88
94
  let(:expected_options) do
89
95
  {
@@ -270,6 +270,11 @@ describe Mongoid::History::Trackable do
270
270
 
271
271
  describe '#track_history?' do
272
272
  shared_examples_for 'history tracking' do
273
+ after do
274
+ Mongoid::History.store[Mongoid::History::GLOBAL_TRACK_HISTORY_FLAG] = true
275
+ Mongoid::History.store[MyModel.track_history_flag] = true
276
+ end
277
+
273
278
  context 'when tracking is globally enabled' do
274
279
  it 'should be enabled on the current thread' do
275
280
  expect(Mongoid::History.enabled?).to eq(true)
@@ -283,7 +288,40 @@ describe Mongoid::History::Trackable do
283
288
  end
284
289
  end
285
290
 
286
- it 'should be rescued if an exception occurs' do
291
+ it 'should be enabled within enable_tracking' do
292
+ MyModel.disable_tracking do
293
+ MyModel.enable_tracking do
294
+ expect(Mongoid::History.enabled?).to eq(true)
295
+ expect(MyModel.new.track_history?).to eq(true)
296
+ end
297
+ end
298
+ end
299
+
300
+ it 'should still be disabled after completing a nested disable_tracking' do
301
+ MyModel.disable_tracking do
302
+ MyModel.disable_tracking {}
303
+ expect(Mongoid::History.enabled?).to eq(true)
304
+ expect(MyModel.new.track_history?).to eq(false)
305
+ end
306
+ end
307
+
308
+ it 'should still be enabled after completing a nested enable_tracking' do
309
+ MyModel.enable_tracking do
310
+ MyModel.enable_tracking {}
311
+ expect(Mongoid::History.enabled?).to eq(true)
312
+ expect(MyModel.new.track_history?).to eq(true)
313
+ end
314
+ end
315
+
316
+ it 'should restore the original state after completing enable_tracking' do
317
+ MyModel.disable_tracking do
318
+ MyModel.enable_tracking {}
319
+ expect(Mongoid::History.enabled?).to eq(true)
320
+ expect(MyModel.new.track_history?).to eq(false)
321
+ end
322
+ end
323
+
324
+ it 'should be rescued if an exception occurs in disable_tracking' do
287
325
  begin
288
326
  MyModel.disable_tracking do
289
327
  raise 'exception'
@@ -294,6 +332,33 @@ describe Mongoid::History::Trackable do
294
332
  expect(MyModel.new.track_history?).to eq(true)
295
333
  end
296
334
 
335
+ it 'should be rescued if an exception occurs in enable_tracking' do
336
+ MyModel.disable_tracking do
337
+ begin
338
+ MyModel.enable_tracking do
339
+ raise 'exception'
340
+ end
341
+ rescue
342
+ end
343
+ expect(Mongoid::History.enabled?).to eq(true)
344
+ expect(MyModel.new.track_history?).to eq(false)
345
+ end
346
+ end
347
+
348
+ it 'should stay disabled if disable_tracking called without a block' do
349
+ MyModel.disable_tracking!
350
+ expect(Mongoid::History.enabled?).to eq(true)
351
+ expect(MyModel.new.track_history?).to eq(false)
352
+ end
353
+
354
+ it 'should stay enabled if enable_tracking called without a block' do
355
+ MyModel.disable_tracking do
356
+ MyModel.enable_tracking!
357
+ expect(Mongoid::History.enabled?).to eq(true)
358
+ expect(MyModel.new.track_history?).to eq(true)
359
+ end
360
+ end
361
+
297
362
  context 'with multiple classes' do
298
363
  before :each do
299
364
  class MyModel2
@@ -317,7 +382,7 @@ describe Mongoid::History::Trackable do
317
382
  end
318
383
  end
319
384
 
320
- context 'when tracking is globally disabled' do
385
+ context 'when changing global tracking' do
321
386
  it 'should be disabled by the global disablement' do
322
387
  Mongoid::History.disable do
323
388
  expect(Mongoid::History.enabled?).to eq(false)
@@ -325,6 +390,41 @@ describe Mongoid::History::Trackable do
325
390
  end
326
391
  end
327
392
 
393
+ it 'should be enabled by the global enablement' do
394
+ Mongoid::History.disable do
395
+ Mongoid::History.enable do
396
+ expect(Mongoid::History.enabled?).to eq(true)
397
+ expect(MyModel.new.track_history?).to eq(true)
398
+ end
399
+ end
400
+ end
401
+
402
+ it 'should restore the original state after completing enable' do
403
+ Mongoid::History.disable do
404
+ Mongoid::History.enable {}
405
+ expect(Mongoid::History.enabled?).to eq(false)
406
+ expect(MyModel.new.track_history?).to eq(false)
407
+ end
408
+ end
409
+
410
+ it 'should still be disabled after completing a nested disable' do
411
+ Mongoid::History.disable do
412
+ Mongoid::History.disable {}
413
+ expect(Mongoid::History.enabled?).to eq(false)
414
+ expect(MyModel.new.track_history?).to eq(false)
415
+ end
416
+ end
417
+
418
+ it 'should still be enabled after completing a nested enable' do
419
+ Mongoid::History.disable do
420
+ Mongoid::History.enable do
421
+ Mongoid::History.enable {}
422
+ expect(Mongoid::History.enabled?).to eq(true)
423
+ expect(MyModel.new.track_history?).to eq(true)
424
+ end
425
+ end
426
+ end
427
+
328
428
  it 'should be disabled within disable_tracking' do
329
429
  Mongoid::History.disable do
330
430
  MyModel.disable_tracking do
@@ -334,7 +434,7 @@ describe Mongoid::History::Trackable do
334
434
  end
335
435
  end
336
436
 
337
- it 'should be rescued if an exception occurs' do
437
+ it 'should be rescued if an exception occurs in disable' do
338
438
  Mongoid::History.disable do
339
439
  begin
340
440
  MyModel.disable_tracking do
@@ -347,6 +447,33 @@ describe Mongoid::History::Trackable do
347
447
  end
348
448
  end
349
449
 
450
+ it 'should be rescued if an exception occurs in enable' do
451
+ Mongoid::History.disable do
452
+ begin
453
+ Mongoid::History.enable do
454
+ raise 'exception'
455
+ end
456
+ rescue
457
+ end
458
+ expect(Mongoid::History.enabled?).to eq(false)
459
+ expect(MyModel.new.track_history?).to eq(false)
460
+ end
461
+ end
462
+
463
+ it 'should stay disabled if disable called without a block' do
464
+ Mongoid::History.disable!
465
+ expect(Mongoid::History.enabled?).to eq(false)
466
+ expect(MyModel.new.track_history?).to eq(false)
467
+ end
468
+
469
+ it 'should stay enabled if enable called without a block' do
470
+ Mongoid::History.disable do
471
+ Mongoid::History.enable!
472
+ expect(Mongoid::History.enabled?).to eq(true)
473
+ expect(MyModel.new.track_history?).to eq(true)
474
+ end
475
+ end
476
+
350
477
  context 'with multiple classes' do
351
478
  before :each do
352
479
  class MyModel2
@@ -361,7 +488,7 @@ describe Mongoid::History::Trackable do
361
488
  Object.send(:remove_const, :MyModel2)
362
489
  end
363
490
 
364
- it 'should be disabled only for the class that calls disable_tracking' do
491
+ it 'should be disabled for all classes' do
365
492
  Mongoid::History.disable do
366
493
  MyModel.disable_tracking do
367
494
  expect(Mongoid::History.enabled?).to eq(false)
@@ -412,7 +539,7 @@ describe Mongoid::History::Trackable do
412
539
  track_history on: :key, changes_method: :my_changes, track_create: true
413
540
 
414
541
  def my_changes
415
- changes.merge('key' => "Save history-#{key}")
542
+ changes.merge('key' => ["Save history-#{key}", "Save history-#{key}"])
416
543
  end
417
544
  end
418
545
  end
@@ -813,7 +940,7 @@ describe Mongoid::History::Trackable do
813
940
  track_history on: :key, changes_method: :my_changes, track_create: true
814
941
 
815
942
  def my_changes
816
- changes.merge('key' => "Save history-#{key}")
943
+ changes.merge('key' => ["Save history-#{key}", "Save history-#{key}"])
817
944
  end
818
945
  end
819
946
 
@@ -836,4 +963,25 @@ describe Mongoid::History::Trackable do
836
963
  m.save!
837
964
  end
838
965
  end
966
+
967
+ context "subclassing a #{described_class}" do
968
+ before :each do
969
+ MyModel.track_history(track_destroy: false)
970
+
971
+ class MySubclassModel < MyModel
972
+ end
973
+ end
974
+
975
+ after :each do
976
+ Object.send(:remove_const, :MySubclassModel)
977
+ end
978
+
979
+ describe '.inherited' do
980
+ it 'creates new history options for the subclass' do
981
+ options = MySubclassModel.mongoid_history_options
982
+ expect(options.trackable).to eq MySubclassModel
983
+ expect(options.options).to eq MyModel.mongoid_history_options.options
984
+ end
985
+ end
986
+ end
839
987
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-history
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Qian
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-12-02 00:00:00.000000000 Z
13
+ date: 2020-06-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: easy_diff
@@ -112,6 +112,8 @@ files:
112
112
  - lib/mongoid/history/tracker.rb
113
113
  - lib/mongoid/history/version.rb
114
114
  - mongoid-history.gemspec
115
+ - perf/benchmark_modified_attributes_for_create.rb
116
+ - perf/gc_suite.rb
115
117
  - spec/integration/embedded_in_polymorphic_spec.rb
116
118
  - spec/integration/integration_spec.rb
117
119
  - spec/integration/multi_relation_spec.rb
@@ -158,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
160
  - !ruby/object:Gem::Version
159
161
  version: '0'
160
162
  requirements: []
161
- rubygems_version: 3.0.3
163
+ rubygems_version: 3.1.3
162
164
  signing_key:
163
165
  specification_version: 4
164
166
  summary: Track and audit, undo and redo changes on Mongoid documents.