diff_json 0.0.1 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 500b28225357427a86dabd6853d94896a4efcaccb9e6f9e8153d2b93535ce183
4
- data.tar.gz: de6dae135cebc7bb440239bf40a990c53c1849fc0fd0d2e26f867b083b231050
3
+ metadata.gz: 381de4c98d550d810fa415cc9a9259b746cae5323dc10b90e00f1b58ef9590a0
4
+ data.tar.gz: '068496e04aaacf8c3d595535be66864d478faa40efccf09e265c23b853589346'
5
5
  SHA512:
6
- metadata.gz: 8200a8a6996d6ab68ba6544d27172fd22e712aef12f9b6d62570084ca54e416cd495a4f13a73145532530609420b97540b80dbd89c772d95470df08d6dd80b75
7
- data.tar.gz: 912663025aa950e5ded31559b2d3106592e58a44f23129421ed11320302e11caa2b274335ac03d7da2f67757fde3e6d03138bc8b420457370b2dc0fc8169d853
6
+ metadata.gz: 1a3c0d1c5575e1f2dbe544cc7af9bad83cefecd17df789b3783311fa84ed64dc6996f874a7e8b00448bb309628ba3cab0062b8b3a76ae4e1d7399cc569da738b
7
+ data.tar.gz: a437d87e79ceceee111f1e7f0f2845e1e26622492d9dc639f0b599f55b57b390e53dfe2526cf4d64cd24d365fd61de277266d1586a3677d5b2bceb614b22b2f6
@@ -5,11 +5,12 @@ module DiffJson
5
5
  @new_json = new_json
6
6
  @opts = {
7
7
  :debug => false,
8
- :ignore_object_keys => [],
9
8
  :diff_count_filter => {
10
9
  :only => ['$**'],
11
10
  :except => []
12
- }
11
+ },
12
+ :ignore_object_keys => [],
13
+ :generate_object_sub_diffs => {}
13
14
  }.merge(opts)
14
15
  @filtered = @opts[:diff_count_filter] != {
15
16
  :only => ['$**'],
@@ -23,15 +24,26 @@ module DiffJson
23
24
  :delete => 0,
24
25
  :move => 0
25
26
  },
26
- :old => [],
27
- :new => []
27
+ :full_diff => {
28
+ :old => [],
29
+ :new => []
30
+ },
31
+ :sub_diffs => {}
28
32
  }
29
33
 
30
34
  calculate
31
35
  end
32
36
 
33
37
  def diff
34
- return @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
35
47
  end
36
48
 
37
49
  def retrieve_output(output_type = :stdout, **output_opts)
@@ -39,7 +51,7 @@ module DiffJson
39
51
  when :stdout
40
52
  when :file
41
53
  when :html
42
- html_output = HtmlOutput.new(@diff, **output_opts)
54
+ html_output = HtmlOutput.new(self, **output_opts)
43
55
  return html_output
44
56
  end
45
57
  end
@@ -47,8 +59,17 @@ module DiffJson
47
59
  private
48
60
 
49
61
  def calculate
50
- @diff[:old], @diff[:new] = compare_elements(@old_json, @new_json)
51
- @calculated = true
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
+ diff[:old].delete_if{|line| line == [' ', '']}
69
+ diff[:new].delete_if{|line| line == [' ', '']}
70
+ diff[:old], diff[:new] = add_blank_lines(diff[:old], diff[:new])
71
+ end
72
+ end
52
73
  end
53
74
 
54
75
  def compare_elements(old_element, new_element, indent_step = 0, path = '$')
@@ -244,6 +265,9 @@ module DiffJson
244
265
 
245
266
  old_item_lines, new_item_lines = add_blank_lines(old_item_lines, new_item_lines)
246
267
 
268
+ add_object_sub_diff_if_required(item_path, old_item, old_item_lines) if old_item.is_a?(Hash) and old_operator == '-'
269
+ add_object_sub_diff_if_required(item_path, new_item, new_item_lines, :new) if new_item.is_a?(Hash) and new_operator == '+'
270
+
247
271
  old_array_lines += old_item_lines
248
272
  new_array_lines += new_item_lines
249
273
  end
@@ -271,7 +295,7 @@ module DiffJson
271
295
  debug("PROCESS KEY #{k}")
272
296
 
273
297
  item_path = "#{base_path}{#{k}}"
274
- key_string = "#{k}: "
298
+ key_string = "#{JSON.pretty_generate(k, max_nesting: false, quirks_mode: true)}: "
275
299
  old_item_lines, new_item_lines = [], []
276
300
  last_loop = (k == keys['all'].last)
277
301
 
@@ -326,6 +350,9 @@ module DiffJson
326
350
  old_object_lines << [' ', "#{indentation(indent_step)}}"]
327
351
  new_object_lines << [' ', "#{indentation(indent_step)}}"]
328
352
 
353
+ add_object_sub_diff_if_required(base_path, old_object, old_object_lines)
354
+ add_object_sub_diff_if_required(base_path, new_object, new_object_lines, :new)
355
+
329
356
  return old_object_lines, new_object_lines
330
357
  end
331
358
 
@@ -388,28 +415,19 @@ module DiffJson
388
415
  # Any path prefixes in `only` that match?
389
416
  if (
390
417
  @opts[:diff_count_filter].key?(:only) and
391
- @opts[:diff_count_filter][:only].is_a?(Array)
418
+ @opts[:diff_count_filter][:only].is_a?(Array) and
419
+ !@opts[:diff_count_filter][:only].empty?
392
420
  )
393
421
  @opts[:diff_count_filter][:only].each do |only_path|
394
- only_path_prefix = only_path.gsub(/\*/, '')
395
- only_path_wildcard = only_path.gsub(/[^\*]/, '')
396
-
397
- if path.include?(only_path_prefix)
398
- path_remainder = path.gsub(only_path_prefix, '').split(/(\]\[|\]\{|\}\[|\}\{)/)
399
-
400
- if (
401
- (path_remainder.length == 0 and only_path_wildcard.length == 0) or
402
- (path_remainder.length == 1 and only_path_wildcard.length > 0) or
403
- (path_remainder.length > 1 and only_path_wildcard.length > 1)
404
- )
405
- do_count = true
406
- break
407
- end
422
+ unless ['none', 'lower'].include?(path_inclusion(path, only_path))
423
+ do_count = true
424
+ break
408
425
  else
409
426
  next
410
427
  end
411
428
  end
412
429
  else
430
+ # If :only is empty or non-existent, count everything
413
431
  do_count = true
414
432
  end
415
433
 
@@ -417,23 +435,13 @@ module DiffJson
417
435
  if (
418
436
  do_count and
419
437
  @opts[:diff_count_filter].key?(:except) and
420
- @opts[:diff_count_filter][:except].is_a?(Array)
438
+ @opts[:diff_count_filter][:except].is_a?(Array) and
439
+ !@opts[:diff_count_filter][:except].empty?
421
440
  )
422
441
  @opts[:diff_count_filter][:except].each do |except_path|
423
- except_path_prefix = except_path.gsub(/\*/, '')
424
- except_path_wildcard = except_path.gsub(/[^\*]/, '') || ''
425
-
426
- if path.include?(except_path_prefix)
427
- path_remainder = path.gsub(except_path_prefix, '').split(/(\]\[|\]\{|\}\[|\}\{)/)
428
-
429
- if (
430
- (path_remainder.length == 0 and except_path_wildcard.length == 0) or
431
- (path_remainder.length == 1 and except_path_wildcard.length > 0) or
432
- (path_remainder.length > 1 and except_path_wildcard.length > 1)
433
- )
434
- do_count = false
435
- break
436
- end
442
+ unless ['none', 'lower'].include?(path_inclusion(path, except_path))
443
+ do_count = false
444
+ break
437
445
  else
438
446
  next
439
447
  end
@@ -452,9 +460,48 @@ module DiffJson
452
460
  )
453
461
  end
454
462
 
463
+ debug("Post-operation, #{do_count}")
464
+
455
465
  @diff[:count][:all] += 1 if do_count
456
466
  @diff[:count][operation] += 1 if do_count
457
467
  end
458
468
  end
469
+
470
+ def path_inclusion(current_path, check_path)
471
+ check_path_base = check_path.gsub(/\*/, '')
472
+ check_path_wildcard = check_path.gsub(/[^\*]/, '') || ''
473
+ check = 'lower'
474
+
475
+ if current_path == check_path_base
476
+ check = 'exact' if check_path_wildcard == ''
477
+ check = 'lower'
478
+ elsif current_path.include?(check_path_base)
479
+ current_path_remainder = current_path.gsub(check_path_base, '')
480
+ current_path_remainder_steps = current_path_remainder.split(/(\]\[|\]\{|\}\[|\}\{)/)
481
+
482
+ check = 'level' if (current_path_remainder_steps.length == 1 and check_path_wildcard == '*')
483
+ check = 'recurse' if (current_path_remainder_steps.length > 0 and check_path_wildcard == '**')
484
+ else
485
+ check = 'none'
486
+ end
487
+
488
+ return check
489
+ end
490
+
491
+ def add_object_sub_diff_if_required(object_path, object, lines, side = :old)
492
+ if (
493
+ @opts.key?(:generate_object_sub_diffs) and
494
+ @opts[:generate_object_sub_diffs].is_a?(Hash) and
495
+ !@opts[:generate_object_sub_diffs].empty?
496
+ )
497
+ @opts[:generate_object_sub_diffs].each do |k,v|
498
+ unless ['none', 'lower'].include?(path_inclusion(object_path, k))
499
+ @diff[:sub_diffs][v] = {} unless @diff[:sub_diffs].key?(v)
500
+ @diff[:sub_diffs][v][object[v]] = {} unless @diff[:sub_diffs][v].key?(object[v])
501
+ @diff[:sub_diffs][v][object[v]][side] = lines if object.key?(v)
502
+ end
503
+ end
504
+ end
505
+ end
459
506
  end
460
507
  end
@@ -4,65 +4,83 @@ module DiffJson
4
4
  def initialize(diff, **opts)
5
5
  @diff = diff
6
6
  @opts = {
7
- :split => false,
8
7
  :table_id_prefix => 'diff_json_view_0'
9
8
  }.merge(opts)
9
+ @output = {
10
+ :full_diff => {},
11
+ :sub_diffs => {}
12
+ }
10
13
 
11
14
  calculate
12
15
  end
13
16
 
14
- def output
15
- return @output
17
+ def full
18
+ return @output[:full_diff][:full]
16
19
  end
17
20
 
18
21
  def left
19
- return @output[:left] if @opts[:split]
20
-
21
- raise 'Method `#left` is only available for split output'
22
+ return @output[:full_diff][:left]
22
23
  end
23
24
 
24
25
  def right
25
- return @output[:right] if @opts[:split]
26
+ return @output[:full_diff][:right]
27
+ end
26
28
 
27
- raise 'Method `#right` is only available for split output'
29
+ def sub_diffs
30
+ return @output[:sub_diffs]
28
31
  end
29
32
 
30
33
  private
31
34
 
32
35
  def calculate
33
- if @opts[:split]
34
- @output = {
35
- :left => "<table id=\"#{@opts[:table_id_prefix]}_left\" class=\"diff-json-split-view-left\">\n",
36
- :right => "<table id=\"#{@opts[:table_id_prefix]}_right\" class=\"diff-json-split-view-right\">\n"
37
- }
36
+ @output[:full_diff] = table_markup(@opts[:table_id_prefix], @diff.diff)
38
37
 
39
- (0..(@diff[:old].length - 1)).each do |i|
40
- @output[:left] += "<tr class=\"diff-json-view-line\">\n"
41
- @output[:left] += "<td class=\"diff-json-view-line-operator\">#{@diff[:old][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
42
- @output[:left] += "<td class=\"diff-json-view-line-content #{content_highlight_class(:left, @diff[:old][i][0])}\">#{@diff[:old][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
43
- @output[:left] += "</tr>\n"
44
- @output[:right] += "<tr class=\"diff-json-view-line\">\n"
45
- @output[:right] += "<td class=\"diff-json-view-line-operator\">#{@diff[:new][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
46
- @output[:right] += "<td class=\"diff-json-view-line-content #{content_highlight_class(:right, @diff[:new][i][0])}\">#{@diff[:new][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
47
- @output[:right] += "</tr>\n"
38
+ @diff.sub_diffs.each do |key, sub_diffs|
39
+ sub_diffs.each do |value, diff|
40
+ sub_key = "#{key}::#{value}"
41
+ table_key = "#{key}_#{value}"
42
+ @output[:sub_diffs][sub_key] = table_markup("#{@opts[:table_id_prefix]}_sub_diff_#{table_key}", diff)
48
43
  end
44
+ end
45
+ end
49
46
 
50
- @output[:left] += "</table>\n"
51
- @output[:right] += "</table>\n"
52
- else
53
- @output = "<table id=\"#{@opts[:table_id_prefix]}_full\" class=\"diff-json-view\">\n"
47
+ def table_markup(table_id_prefix, lines)
48
+ markup = {
49
+ :full => "",
50
+ :left => "",
51
+ :right => ""
52
+ }
54
53
 
55
- (0..(@diff[:old].length - 1)).each do |i|
56
- @output += "<tr class=\"diff-json-view-line\">\n"
57
- @output += "<td class=\"diff-json-view-line-operator\">#{@diff[:old][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
58
- @output += "<td class=\"diff-json-view-line-content #{content_highlight_class(:left, @diff[:old][i][0])}\">#{@diff[:old][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
59
- @output += "<td class=\"diff-json-view-line-operator\">#{@diff[:new][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
60
- @output += "<td class=\"diff-json-view-line-content #{content_highlight_class(:right, @diff[:new][i][0])}\">#{@diff[:new][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
61
- @output += "</tr>\n"
62
- end
54
+ markup[:full] = "<table id=\"#{table_id_prefix}_full\" class=\"diff-json-full-view\">\n"
55
+ markup[:left] = "<table id=\"#{table_id_prefix}_left\" class=\"diff-json-split-view-left\">\n"
56
+ markup[:right] = "<table id=\"#{table_id_prefix}_right\" class=\"diff-json-split-view-right\">\n"
63
57
 
64
- @output += "</table>\n"
58
+ (0..(lines[:old].length - 1)).each do |i|
59
+ # Full, combined table output
60
+ markup[:full] += "<tr class=\"diff-json-view-line\">\n"
61
+ markup[:full] += "<td class=\"diff-json-view-line-operator\">#{lines[:old][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
62
+ markup[:full] += "<td class=\"diff-json-view-line-content #{content_highlight_class(:left, lines[:old][i][0])}\">#{lines[:old][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
63
+ markup[:full] += "<td class=\"diff-json-view-column-break\"></td>\n"
64
+ markup[:full] += "<td class=\"diff-json-view-line-operator\">#{lines[:new][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
65
+ markup[:full] += "<td class=\"diff-json-view-line-content #{content_highlight_class(:right, lines[:new][i][0])}\">#{lines[:new][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
66
+ markup[:full] += "</tr>\n"
67
+ # Split, left side output
68
+ markup[:left] += "<tr class=\"diff-json-view-line\">\n"
69
+ markup[:left] += "<td class=\"diff-json-view-line-operator\">#{lines[:old][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
70
+ markup[:left] += "<td class=\"diff-json-view-line-content #{content_highlight_class(:left, lines[:old][i][0])}\">#{lines[:old][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
71
+ markup[:left] += "</tr>\n"
72
+ # Split, right side output
73
+ markup[:right] += "<tr class=\"diff-json-view-line\">\n"
74
+ markup[:right] += "<td class=\"diff-json-view-line-operator\">#{lines[:new][i][0].gsub(/\s/, '&nbsp;')}</td>\n"
75
+ markup[:right] += "<td class=\"diff-json-view-line-content #{content_highlight_class(:right, lines[:new][i][0])}\">#{lines[:new][i][1].gsub(/\s/, '&nbsp;')}</td>\n"
76
+ markup[:right] += "</tr>\n"
65
77
  end
78
+
79
+ markup[:full] += "</table>\n"
80
+ markup[:left] += "</table>\n"
81
+ markup[:right] += "</table>\n"
82
+
83
+ return markup
66
84
  end
67
85
 
68
86
  def content_highlight_class(side, operator)
@@ -73,7 +91,7 @@ module DiffJson
73
91
  elsif operator == 'M'
74
92
  return side == :left ? 'diff-json-content-del' : 'diff-json-content-ins'
75
93
  else
76
- return nil
94
+ return ''
77
95
  end
78
96
  end
79
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diff_json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh MacLachlan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-13 00:00:00.000000000 Z
11
+ date: 2018-08-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Diffs two JSON objects and returns a left/right diff view, similar to
14
14
  the command line `diff` utility