diff_json 0.1.2 → 1.1.0

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: cfe2f853f14295b632d6c9797e8d5fa6d033abdb4a2121882c89e89dea454b70
4
- data.tar.gz: e20ffe297ef15903842062ff4678e9555a0c0b878c814e2457d877f1dec0ffb9
3
+ metadata.gz: '08af726b4ce91a316f8143a343d18ee82207d95afda7ccd08ad22f9f416cb913'
4
+ data.tar.gz: 39a56823c4a9ea78ba38f418a3242fc998ae394adaca7e72f09c7b86f07fe306
5
5
  SHA512:
6
- metadata.gz: 24c881ce5a6b3f08c2c3f4e83055abb897f3b1b0c895e2ccf98f97e184bfa18a4896aa9c167652a447bf17a909a166fc990e622432aa201c72e539d8007c2e9b
7
- data.tar.gz: d9321212b669d051d7c60e2b8b105bc05c0f7a2cb4fccfcba1f00c7d7fe54724c1337c79e2183ace4a0888a5a4b46c351ddce79fb4b0443acc99e68ac7a44795
6
+ metadata.gz: 93fb867871e15cd864b7558dfe7b6211ce5f1e59c4659c3d4f2f5efb0f2a37d8c041b2a041785d36ec375a7dddf2233030f014ccf1c31b7164985707ad81efbf
7
+ data.tar.gz: 56e4b5053dca4018508a458fb359075c2e8e3ad738b8ef929843a9430c2f84a7eca6d3377f71493e880f2156b303ab758985e71356d60f454d655bf1179d6f66
data/lib/diff_json.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'json'
2
-
3
- require_relative './diff_json/undefined_value'
2
+ require 'logger'
3
+ require 'require_all'
4
4
  require_relative './diff_json/diff'
5
- require_relative './diff_json/html_output'
5
+ require_rel './diff_json/output'
@@ -1,505 +1,103 @@
1
- module DiffJson
2
- class Diff
3
- def initialize(old_json, new_json, **opts)
4
- @old_json = old_json
5
- @new_json = new_json
6
- @opts = {
7
- :debug => false,
8
- :diff_count_filter => {
9
- :only => ['$**'],
10
- :except => []
11
- },
12
- :ignore_object_keys => [],
13
- :generate_object_sub_diffs => {}
14
- }.merge(opts)
15
- @filtered = @opts[:diff_count_filter] != {
16
- :only => ['$**'],
17
- :except => []
18
- }
19
- @diff = {
20
- :count => {
21
- :all => 0,
22
- :insert => 0,
23
- :update => 0,
24
- :delete => 0,
25
- :move => 0
26
- },
27
- :full_diff => {
28
- :old => [],
29
- :new => []
30
- },
31
- :sub_diffs => {}
32
- }
33
-
34
- calculate
35
- end
36
-
37
- def diff
38
- return @diff[:full_diff]
39
- end
40
-
41
- def sub_diffs
42
- return @diff[:sub_diffs]
43
- end
44
-
45
- def change_count(operation = :all)
46
- return @diff[:count][operation] || 0
47
- end
48
-
49
- def retrieve_output(output_type = :stdout, **output_opts)
50
- case output_type
51
- when :stdout
52
- when :file
53
- when :html
54
- html_output = HtmlOutput.new(self, **output_opts)
55
- return html_output
56
- end
57
- end
58
-
59
- private
60
-
61
- def calculate
62
- @diff[:full_diff][:old], @diff[:full_diff][:new] = compare_elements(@old_json, @new_json)
63
-
64
- @diff[:sub_diffs].each do |key, sub_diffs|
65
- sub_diffs.each do |value, diff|
66
- diff[:old] = [] unless diff.key?(:old)
67
- diff[:new] = [] unless diff.key?(:new)
68
-
69
- diff[:old], diff[:new] = add_blank_lines(diff[:old], diff[:new])
70
- end
71
- end
72
- end
73
-
74
- def compare_elements(old_element, new_element, indent_step = 0, path = '$')
75
- debug([
76
- 'ENTER compare_elements',
77
- "Diffing #{path}"
78
- ])
79
-
80
- old_element_lines, new_element_lines = [], []
1
+ require_rel './diff'
81
2
 
82
- if old_element == new_element
83
- debug('Equal elements, no diff required')
84
-
85
- old_element_lines = JSON.pretty_generate(old_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| [' ', "#{indentation(indent_step)}#{el}"]}
86
- new_element_lines = JSON.pretty_generate(new_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| [' ', "#{indentation(indent_step)}#{el}"]}
87
- else
88
- unless value_type(old_element) == value_type(new_element)
89
- debug('Opposite type element, no diff required')
90
-
91
- increment_diff_count(path, :insert)
92
- increment_diff_count(path, :delete)
93
- old_element_lines, new_element_lines = add_blank_lines(
94
- JSON.pretty_generate(old_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| ['-', "#{indentation(indent_step)}#{el}"]},
95
- JSON.pretty_generate(new_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| ['+', "#{indentation(indent_step)}#{el}"]}
96
- )
97
- else
98
- debug("Found #{value_type(old_element)}, diffing")
99
-
100
- increment_diff_count(path, :update)
101
- old_element_lines, new_element_lines = self.send("#{value_type(old_element)}_diff", old_element, new_element, indent_step, path)
102
- end
103
- end
104
-
105
- return old_element_lines, new_element_lines
106
- end
107
-
108
- def array_diff(old_array, new_array, indent_step, base_path)
109
- debug('ENTER array_diff')
110
-
111
- oal, nal = old_array.length, new_array.length
112
- sal = oal < nal ? oal : nal
113
- lal = oal > nal ? oal : nal
114
- old_array_lines, new_array_lines = [[' ', "#{indentation(indent_step)}["]], [[' ', "#{indentation(indent_step)}["]]
115
- next_step = indent_step + 1
116
- operations = {
117
- 'none' => [],
118
- 'arr_add_index' => [],
119
- 'arr_drop_index' => [],
120
- 'arr_send_move' => [],
121
- 'arr_receive_move' => []
122
- }
123
-
124
- # Find indices that were added or dropped, if any
125
- if oal < nal
126
- operations['arr_add_index'] += (oal..(nal - 1)).to_a
127
- elsif oal > nal
128
- operations['arr_drop_index'] += (nal..(oal - 1)).to_a
129
- end
130
-
131
- # Find 'none' and 'move_value' operations
132
- (old_array | new_array).each do |v|
133
- # For a given value, find all indices of each array that corresponds
134
- old_indices, new_indices = array_indices(old_array, v), array_indices(new_array, v)
135
- # Same index, same value, no diff necessary
136
- operations['none'] += (old_indices & new_indices)
137
-
138
- # Pull the skipped indices before calculating movements
139
- old_indices -= operations['none']
140
- new_indices -= operations['none']
141
-
142
- # Find values that were moved from one index to another
143
- if !old_indices.empty? and !new_indices.empty?
144
- max_moves = old_indices.length < new_indices.length ? old_indices.length : new_indices.length
145
- possible_moves = []
146
- # Make pairs of possible moves
147
- old_indices.each do |oi|
148
- new_indices.each do |ni|
149
- possible_moves << [(oi - ni).abs, [oi, ni]]
150
- end
151
- end
152
- # For the sake of simplicity, we'll arbitrarily decide to use the shortest moves
153
- possible_moves.sort!{|x,y| x[0] <=> y[0]}
154
- # Take the first (max_moves) moves and add their operations
155
- possible_moves[0..(max_moves - 1)].each do |move|
156
- operations['arr_send_move'] << move[1][0]
157
- operations['arr_receive_move'] << move[1][1]
158
- end
159
- end
160
- end
161
-
162
- # Add base diff for each index
163
- (0..(lal - 1)).each do |i|
164
- debug("PROCESS INDEX #{i}")
165
-
166
- item_path = "#{base_path}[#{i}]"
167
- old_item_lines, new_item_lines = [], []
168
- item_diff_operations = []
169
- last_loop = (i == (lal - 1))
170
-
171
- # Assign current known operations to each index
172
- (operations.keys).each do |operation|
173
- if operations[operation].include?(i)
174
- item_diff_operations << operation
175
- end
176
- end
177
-
178
- # Add arr_change_value, arr_add_value, and arr_drop_value operations
179
- if item_diff_operations.empty?
180
- item_diff_operations << 'arr_change_value'
181
- elsif (
182
- item_diff_operations.include?('arr_send_move') and
183
- !item_diff_operations.include?('arr_receive_move') and
184
- !item_diff_operations.include?('arr_drop_index')
185
- )
186
- item_diff_operations << 'arr_add_value'
187
- elsif (
188
- !item_diff_operations.include?('arr_send_move') and
189
- item_diff_operations.include?('arr_receive_move') and
190
- !item_diff_operations.include?('arr_add_index')
191
- )
192
- item_diff_operations << 'arr_drop_value'
193
- end
194
-
195
- # Call compare_elements for sub-elements if necessary
196
- if (!(item_diff_operations & ['none', 'arr_change_value']).empty? and
197
- is_json_element?(old_array[i]) and is_json_element?(new_array[i])
198
- )
199
- old_item_lines, new_item_lines = compare_elements(old_array[i], new_array[i], next_step, item_path)
200
- else
201
- # Grab old and new items
202
- # UndefinedValue class is here to represent the difference between explicit null and non-existent
203
- old_item = item_diff_operations.include?('arr_add_index') ? UndefinedValue.new : old_array[i]
204
- new_item = item_diff_operations.include?('arr_drop_index') ? UndefinedValue.new : new_array[i]
205
-
206
- # Figure out operators for left and right
207
- if item_diff_operations.include?('none')
208
- old_operator, new_operator = ' ', ' '
209
- elsif item_diff_operations.include?('arr_change_value')
210
- increment_diff_count(item_path, :update)
211
- old_operator, new_operator = '-', '+'
212
- elsif (item_diff_operations & ['arr_send_move', 'arr_receive_move']).length == 2
213
- increment_diff_count(item_path, :move)
214
- old_operator, new_operator = 'M', 'M'
215
- elsif item_diff_operations.include?('arr_add_value')
216
- increment_diff_count(item_path, :insert)
217
- old_operator, new_operator = 'M', '+'
218
- elsif item_diff_operations.include?('arr_drop_value')
219
- increment_diff_count(item_path, :delete)
220
- old_operator, new_operator = '-', 'M'
221
- elsif item_diff_operations.include?('arr_drop_index')
222
- if item_diff_operations.include?('arr_send_move')
223
- increment_diff_count(item_path, :move)
224
- old_operator, new_operator = 'M', ' '
225
- else
226
- increment_diff_count(item_path, :delete)
227
- old_operator, new_operator = '-', ' '
228
- end
229
- elsif item_diff_operations.include?('arr_add_index')
230
- if item_diff_operations.include?('arr_receive_move')
231
- old_operator, new_operator = ' ', 'M'
232
- else
233
- increment_diff_count(item_path, :insert)
234
- old_operator, new_operator = ' ', '+'
235
- end
236
- end
237
-
238
- # Gather lines
239
- if old_item.is_a?(UndefinedValue)
240
- new_item_lines = JSON.pretty_generate(new_item, max_nesting: false, quirks_mode: true).split("\n").map{|il| [new_operator, "#{indentation(next_step)}#{il}"]}
241
-
242
- (0..(new_item_lines.length - 1)).each do |i|
243
- old_item_lines << [' ', '']
244
- end
245
- else
246
- old_item_lines = JSON.pretty_generate(old_item, max_nesting: false, quirks_mode: true).split("\n").map{|il| [old_operator, "#{indentation(next_step)}#{il}"]}
247
- end
248
-
249
- if new_item.is_a?(UndefinedValue)
250
- (0..(old_item_lines.length - 1)).each do |i|
251
- new_item_lines << [' ', '']
252
- end
253
- else
254
- new_item_lines = JSON.pretty_generate(new_item, max_nesting: false, quirks_mode: true).split("\n").map{|il| [new_operator, "#{indentation(next_step)}#{il}"]}
255
- end
256
- end
257
-
258
- unless old_item_lines.empty?
259
- old_item_lines.last[1] = "#{old_item_lines.last[1]}," if !last_loop and (old_item_lines.last[1].match(/[^\s]/))
260
- end
261
- unless new_item_lines.empty?
262
- new_item_lines.last[1] = "#{new_item_lines.last[1]}," if !last_loop and (new_item_lines.last[1].match(/[^\s]/))
263
- end
264
-
265
- add_object_sub_diff_if_required(item_path, old_item, old_item_lines) if old_item.is_a?(Hash) and old_operator == '-'
266
- add_object_sub_diff_if_required(item_path, new_item, new_item_lines, :new) if new_item.is_a?(Hash) and new_operator == '+'
267
-
268
- old_item_lines, new_item_lines = add_blank_lines(old_item_lines, new_item_lines)
269
-
270
- old_array_lines += old_item_lines
271
- new_array_lines += new_item_lines
272
- end
273
-
274
- old_array_lines << [' ', "#{indentation(indent_step)}]"]
275
- new_array_lines << [' ', "#{indentation(indent_step)}]"]
276
-
277
- return old_array_lines, new_array_lines
278
- end
279
-
280
- def object_diff(old_object, new_object, indent_step, base_path)
281
- debug('ENTER object_diff')
282
-
283
- keys = {
284
- 'all' => (old_object.keys | new_object.keys),
285
- 'common' => (old_object.keys & new_object.keys),
286
- 'add' => (new_object.keys - old_object.keys),
287
- 'drop' => (old_object.keys - new_object.keys)
288
- }
289
- old_object_lines, new_object_lines = [[' ', "#{indentation(indent_step)}{"]], [[' ', "#{indentation(indent_step)}{"]]
290
- next_step = indent_step + 1
291
-
292
- # For objects, we're taking a much simpler approach, so no movements
293
- keys['all'].each do |k|
294
- debug("PROCESS KEY #{k}")
295
-
296
- item_path = "#{base_path}{#{k}}"
297
- key_string = "#{JSON.pretty_generate(k, max_nesting: false, quirks_mode: true)}: "
298
- old_item_lines, new_item_lines = [], []
299
- last_loop = (k == keys['all'].last)
300
-
301
- if keys['common'].include?(k)
302
- if is_json_element?(old_object[k]) and is_json_element?(new_object[k]) and !@opts[:ignore_object_keys].include?(k)
303
- old_item_lines, new_item_lines = compare_elements(old_object[k], new_object[k], next_step, item_path)
304
- else
305
- if old_object[k] == new_object[k] or @opts[:ignore_object_keys].include?(k)
306
- old_item_lines = JSON.pretty_generate(old_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [' ', "#{indentation(next_step)}#{il}"]}
307
- new_item_lines = JSON.pretty_generate(new_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [' ', "#{indentation(next_step)}#{il}"]}
308
- else
309
- increment_diff_count(item_path, :update)
310
- old_item_lines = JSON.pretty_generate(old_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| ['-', "#{indentation(next_step)}#{il}"]}
311
- new_item_lines = JSON.pretty_generate(new_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| ['+', "#{indentation(next_step)}#{il}"]}
312
- end
313
- end
314
- else
315
- if keys['drop'].include?(k)
316
- increment_diff_count(item_path, :delete) unless @opts[:ignore_object_keys].include?(k)
317
- old_item_lines = JSON.pretty_generate(old_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [@opts[:ignore_object_keys].include?(k) ? ' ' : '-', "#{indentation(next_step)}#{il}"]}
318
- new_item_lines = []
319
-
320
- (0..(old_item_lines.length - 1)).each do |i|
321
- new_item_lines << [' ', '']
322
- end
323
- elsif keys['add'].include?(k)
324
- increment_diff_count(item_path, :insert) unless @opts[:ignore_object_keys].include?(k)
325
- new_item_lines = JSON.pretty_generate(new_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [@opts[:ignore_object_keys].include?(k) ? ' ' : '+', "#{indentation(next_step)}#{il}"]}
326
- old_item_lines = []
3
+ module DiffJson
4
+ def self.diff(old_json, new_json, return_type, diff_opts = {}, output_opts = {})
5
+ completed_diff = Diff.new(old_json, new_json, **diff_opts)
327
6
 
328
- (0..(new_item_lines.length - 1)).each do |i|
329
- old_item_lines << [' ', '']
330
- end
331
- end
332
- end
7
+ return case return_type
8
+ when :raw
9
+ completed_diff
10
+ when :patch
11
+ patch_operations = []
333
12
 
334
- unless old_item_lines.empty?
335
- old_item_lines[0][1].gsub!(/^(?<spaces>\s+)(?<content>.+)$/, "\\k<spaces>#{key_string}\\k<content>")
336
- old_item_lines.last[1] = "#{old_item_lines.last[1]}," if !last_loop and (old_item_lines.last[1].match(/[^\s]/))
337
- end
338
- unless new_item_lines.empty?
339
- new_item_lines[0][1].gsub!(/^(?<spaces>\s+)(?<content>.+)$/, "\\k<spaces>#{key_string}\\k<content>")
340
- new_item_lines.last[1] = "#{new_item_lines.last[1]}," if !last_loop and (new_item_lines.last[1].match(/[^\s]/))
13
+ completed_diff.diff.each do |path, operations|
14
+ operations.each do |op|
15
+ patch_operations << op if [:add, :replace, :remove].include?(op[:op]) or (op[:op] == :move and path == op[:from])
341
16
  end
342
-
343
- old_item_lines, new_item_lines = add_blank_lines(old_item_lines, new_item_lines)
344
-
345
- old_object_lines += old_item_lines
346
- new_object_lines += new_item_lines
347
17
  end
348
18
 
349
- old_object_lines << [' ', "#{indentation(indent_step)}}"]
350
- new_object_lines << [' ', "#{indentation(indent_step)}}"]
351
-
352
- add_object_sub_diff_if_required(base_path, old_object, old_object_lines)
353
- add_object_sub_diff_if_required(base_path, new_object, new_object_lines, :new)
354
-
355
- return old_object_lines, new_object_lines
356
- end
357
-
358
- def debug(message)
359
- puts message if @opts[:debug]
360
- end
361
-
362
- def array_indices(array, value)
363
- indices = []
364
-
365
- array.each_with_index do |av,i|
366
- indices << i if av == value
367
- end
368
-
369
- return indices
19
+ return patch_operations
20
+ when :html
21
+ HtmlOutput.new(completed_diff, **output_opts)
370
22
  end
23
+ end
371
24
 
372
- def is_json_element?(object)
373
- return true if ['array', 'object'].include?(value_type(object))
374
- end
25
+ class Diff
26
+ include JsonMapping
27
+ include JsonDiffing
375
28
 
376
- def value_type(element)
377
- case class_name = element.class.name
378
- when 'Hash'
379
- return 'object'
380
- when 'NilClass'
381
- return 'null'
382
- when 'TrueClass', 'FalseClass'
383
- return 'boolean'
29
+ def initialize(old_json, new_json, **opts)
30
+ # Set config options
31
+ @opts = {
32
+ count_operations: {
33
+ '/**' => [:add, :replace, :remove, :move, :update]
34
+ },
35
+ ignore_paths: [],
36
+ path_sort: :sorted,
37
+ sub_diffs: {},
38
+ track_array_moves: true,
39
+ track_structure_updates: false,
40
+ replace_primitives_arrays: false,
41
+ logger: ::Logger.new(STDOUT),
42
+ log_level: :warn
43
+ }.merge(opts)
44
+ # Create map of both JSON objects
45
+ @old_map = map_json(old_json, '', 0)
46
+ @new_map = map_json(new_json, '', 0)
47
+ # Gather the full list of all paths in both JSON objects in a consistent order
48
+ @all_paths = gather_paths(@old_map.keys, @new_map.keys, @opts[:path_sort] == :sorted)
49
+ # Generate diff operations list
50
+ @diff = diff_check(old_json, new_json)
51
+ # Find difference counts
52
+ @counts = find_counts(@diff)
53
+ # Gather sub-diffs
54
+ @sub_diffs = generate_sub_diffs
55
+ end
56
+
57
+ def count(count_type = :all)
58
+ return case count_type
59
+ when :ignore, :add, :replace, :remove, :move, :update
60
+ @counts[count_type] || 0
61
+ when :total
62
+ @counts.values.sum
384
63
  else
385
- return class_name.downcase
64
+ @counts
386
65
  end
387
66
  end
388
67
 
389
- def indentation(step)
390
- step = 0 if step < 0
391
- ' ' * step
68
+ def diff
69
+ return @diff
392
70
  end
393
71
 
394
- def add_blank_lines(left_lines, right_lines)
395
- if left_lines.length < right_lines.length
396
- (1..(right_lines.length - left_lines.length)).each do
397
- left_lines << [' ', '']
398
- end
399
- elsif left_lines.length > right_lines.length
400
- (1..(left_lines.length - right_lines.length)).each do
401
- right_lines << [' ', '']
402
- end
403
- end
404
-
405
- return left_lines, right_lines
72
+ def json_map(version = :old)
73
+ return (version == :old ? @old_map : @new_map)
406
74
  end
407
75
 
408
- def increment_diff_count(path, operation)
409
- unless @filtered
410
- @diff[:count][operation] += 1
76
+ def paths(version = :joint)
77
+ return case version
78
+ when :old
79
+ json_map(:old).keys
80
+ when :new
81
+ json_map(:new).keys
411
82
  else
412
- do_count = false
413
-
414
- # Any path prefixes in `only` that match?
415
- if (
416
- @opts[:diff_count_filter].key?(:only) and
417
- @opts[:diff_count_filter][:only].is_a?(Array) and
418
- !@opts[:diff_count_filter][:only].empty?
419
- )
420
- @opts[:diff_count_filter][:only].each do |only_path|
421
- unless ['none', 'lower'].include?(path_inclusion(path, only_path))
422
- do_count = true
423
- break
424
- else
425
- next
426
- end
427
- end
428
- else
429
- # If :only is empty or non-existent, count everything
430
- do_count = true
431
- end
432
-
433
- # Make sure the specific path is not excluded, if we've established that we should probably include it
434
- if (
435
- do_count and
436
- @opts[:diff_count_filter].key?(:except) and
437
- @opts[:diff_count_filter][:except].is_a?(Array) and
438
- !@opts[:diff_count_filter][:except].empty?
439
- )
440
- @opts[:diff_count_filter][:except].each do |except_path|
441
- unless ['none', 'lower'].include?(path_inclusion(path, except_path))
442
- do_count = false
443
- break
444
- else
445
- next
446
- end
447
- end
448
- end
449
-
450
- # Ensure this operation is allowed for counting
451
- if (
452
- do_count and
453
- @opts[:diff_count_filter].key?(:operations) and
454
- @opts[:diff_count_filter][:operations].is_a?(Array)
455
- )
456
- do_count = false if (
457
- !@opts[:diff_count_filter][:operations].empty? and
458
- !@opts[:diff_count_filter][:operations].include?(operation)
459
- )
460
- end
461
-
462
- debug("Post-operation, #{do_count}")
463
-
464
- @diff[:count][:all] += 1 if do_count
465
- @diff[:count][operation] += 1 if do_count
83
+ @all_paths
466
84
  end
467
85
  end
468
86
 
469
- def path_inclusion(current_path, check_path)
470
- check_path_base = check_path.gsub(/\*/, '')
471
- check_path_wildcard = check_path.gsub(/[^\*]/, '') || ''
472
- check = 'lower'
473
-
474
- if current_path == check_path_base
475
- check = 'exact' if check_path_wildcard == ''
476
- check = 'lower'
477
- elsif current_path.include?(check_path_base)
478
- current_path_remainder = current_path.gsub(check_path_base, '')
479
- current_path_remainder_steps = current_path_remainder.split(/(\]\[|\]\{|\}\[|\}\{)/)
480
-
481
- check = 'level' if (current_path_remainder_steps.length == 1 and check_path_wildcard == '*')
482
- check = 'recurse' if (current_path_remainder_steps.length > 0 and check_path_wildcard == '**')
483
- else
484
- check = 'none'
485
- end
486
-
487
- return check
87
+ def sub_diffs
88
+ return @sub_diffs
488
89
  end
489
90
 
490
- def add_object_sub_diff_if_required(object_path, object, lines, side = :old)
491
- if (
492
- @opts.key?(:generate_object_sub_diffs) and
493
- @opts[:generate_object_sub_diffs].is_a?(Hash) and
494
- !@opts[:generate_object_sub_diffs].empty?
495
- )
496
- @opts[:generate_object_sub_diffs].each do |k,v|
497
- unless ['none', 'lower'].include?(path_inclusion(object_path, k))
498
- @diff[:sub_diffs][v] = {} unless @diff[:sub_diffs].key?(v)
499
- @diff[:sub_diffs][v][object[v]] = {} unless @diff[:sub_diffs][v].key?(object[v])
500
- @diff[:sub_diffs][v][object[v]][side] = lines if object.key?(v)
501
- end
502
- end
91
+ def log_message(log_level, message)
92
+ log_levels = [
93
+ :debug,
94
+ :info,
95
+ :warn,
96
+ :error
97
+ ]
98
+
99
+ if (log_levels.index(log_level) || -1) >= (log_levels.index(@opts[:log_level]) || 0)
100
+ @opts[:logger].method(log_level).call((is_structure?(message) ? JSON.pretty_generate(message) : message))
503
101
  end
504
102
  end
505
103
  end