From 63e9a1fd654dd3fdf170480ff256f417850333c5 Mon Sep 17 00:00:00 2001 From: Duologic Date: Sun, 16 Apr 2023 13:35:24 +0200 Subject: [PATCH 1/3] feat(inspect): add diff function --- docs/inspect.md | 38 +++++++++++++++++++ inspect.libsonnet | 96 +++++++++++++++++++++++++++++++++++++++++++++++ test.jsonnet | 68 +++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) diff --git a/docs/inspect.md b/docs/inspect.md index 88fbbf6..6670923 100644 --- a/docs/inspect.md +++ b/docs/inspect.md @@ -12,10 +12,48 @@ local inspect = import "github.com/jsonnet-libs/xtd/inspect.libsonnet" ## Index +* [`fn diff(input1, input2)`](#fn-diff) * [`fn inspect(object, maxDepth)`](#fn-inspect) ## Fields +### fn diff + +```ts +diff(input1, input2) +``` + +`diff` returns a JSON object describing the differences between two inputs. It +attemps to show diffs in nested objects and arrays too. + +Simple example: + +```jsonnet +{ + local input1 = { + same: 'same', + change: 'this', + remove: 'removed', + }, + local input2 = { + same: 'same', + change: 'changed', + add: 'added', + }, + output: diff(input1, input2), +} +``` + +Output: +```json +"output": { + "add +": "added", + "change ~": "~[ this , changed ]", + "remove -": "removed" +} +``` + + ### fn inspect ```ts diff --git a/inspect.libsonnet b/inspect.libsonnet index 7302700..fc22209 100644 --- a/inspect.libsonnet +++ b/inspect.libsonnet @@ -47,4 +47,100 @@ local d = import 'doc-util/main.libsonnet'; std.objectFieldsAll(object), {} ), + + '#diff':: d.fn( + ||| + `diff` returns a JSON object describing the differences between two inputs. It + attemps to show diffs in nested objects and arrays too. + + Simple example: + + ```jsonnet + { + local input1 = { + same: 'same', + change: 'this', + remove: 'removed', + }, + local input2 = { + same: 'same', + change: 'changed', + add: 'added', + }, + output: diff(input1, input2), + } + ``` + + Output: + ```json + "output": { + "add +": "added", + "change ~": "~[ this , changed ]", + "remove -": "removed" + } + ``` + |||, + [ + d.arg('input1', d.T.any), + d.arg('input2', d.T.any), + ] + ), + + diff(input1, input2):: + if input1 == input2 + then '' + else if std.isArray(input1) && std.isArray(input2) + then + [ + if input1[i] != input2[i] + then + this.diff( + input1[i], + input2[i] + ) + else input2[i] + for i in std.range(0, std.length(input2) - 1) + if std.length(input1) > i + ] + + (if std.length(input1) < std.length(input2) + then [ + '+ ' + input2[i] + for i in std.range(std.length(input1), std.length(input2) - 1) + ] + else []) + + (if std.length(input1) > std.length(input2) + then [ + '- ' + input1[i] + for i in std.range(std.length(input2), std.length(input1) - 1) + ] + else []) + + else if std.isObject(input1) && std.isObject(input2) + then std.foldl( + function(acc, k) + acc + ( + if k in input1 && input1[k] != input2[k] + then { + [k + ' ~']: + this.diff( + input1[k], + input2[k] + ), + } + else if !(k in input1) + then { + [k + ' +']: input2[k], + } + else {} + ), + std.objectFields(input2), + {}, + ) + + { + [l + ' -']: input1[l] + for l in std.objectFields(input1) + if !(l in input2) + } + + else '~[ %s ]' % std.join(' , ', [std.toString(input1), std.toString(input2)]), } diff --git a/test.jsonnet b/test.jsonnet index abc4dad..67eb862 100644 --- a/test.jsonnet +++ b/test.jsonnet @@ -170,6 +170,73 @@ local TestInspect = : name('maxRecursionDepth'); true; + +local TestDiff = + local name(case) = 'TestDiff:%s failed' % case; + + assert ( + xtd.inspect.diff('', '') + == '' + ) : name('noDiff'); + + assert ( + xtd.inspect.diff('string', true) + == '~[ string , true ]' + ) : name('typeDiff'); + + assert ( + local input1 = { + same: 'same', + change: 'this', + remove: 'removed', + }; + local input2 = { + same: 'same', + change: 'changed', + add: 'added', + }; + xtd.inspect.diff(input1, input2) + == { + 'add +': 'added', + 'change ~': '~[ this , changed ]', + 'remove -': 'removed', + } + ) : name('objectDiff'); + + assert ( + local input1 = [ + 'same', + 'this', + [ + 'same', + 'this', + ], + 'remove', + ]; + local input2 = [ + 'same', + 'changed', + [ + 'same', + 'changed', + 'added', + ], + ]; + xtd.inspect.diff(input1, input2) + == [ + 'same', + '~[ this , changed ]', + [ + 'same', + '~[ this , changed ]', + '+ added', + ], + '- remove', + ] + ) : name('arrayDiff'); + + true; + local TestIsLeapYear = local name(case) = 'TestIsLeapYear:%s failed' % case; @@ -249,6 +316,7 @@ true && TestEncodeQuery && TestCamelCaseSplit && TestInspect +&& TestDiff && TestIsLeapYear && TestDayOfWeek && TestDayOfYear From 6c015e231a871bd62275298fff3e6e1b5fbaa842 Mon Sep 17 00:00:00 2001 From: Duologic Date: Sun, 16 Apr 2023 13:42:38 +0200 Subject: [PATCH 2/3] docs: omit output key --- docs/inspect.md | 28 ++++++++++++++-------------- inspect.libsonnet | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/inspect.md b/docs/inspect.md index 6670923..244b94d 100644 --- a/docs/inspect.md +++ b/docs/inspect.md @@ -29,24 +29,24 @@ attemps to show diffs in nested objects and arrays too. Simple example: ```jsonnet -{ - local input1 = { - same: 'same', - change: 'this', - remove: 'removed', - }, - local input2 = { - same: 'same', - change: 'changed', - add: 'added', - }, - output: diff(input1, input2), -} +local input1 = { + same: 'same', + change: 'this', + remove: 'removed', +}; + +local input2 = { + same: 'same', + change: 'changed', + add: 'added', +}; + +diff(input1, input2), ``` Output: ```json -"output": { +{ "add +": "added", "change ~": "~[ this , changed ]", "remove -": "removed" diff --git a/inspect.libsonnet b/inspect.libsonnet index fc22209..f0d4f63 100644 --- a/inspect.libsonnet +++ b/inspect.libsonnet @@ -56,24 +56,24 @@ local d = import 'doc-util/main.libsonnet'; Simple example: ```jsonnet - { - local input1 = { - same: 'same', - change: 'this', - remove: 'removed', - }, - local input2 = { - same: 'same', - change: 'changed', - add: 'added', - }, - output: diff(input1, input2), - } + local input1 = { + same: 'same', + change: 'this', + remove: 'removed', + }; + + local input2 = { + same: 'same', + change: 'changed', + add: 'added', + }; + + diff(input1, input2), ``` Output: ```json - "output": { + { "add +": "added", "change ~": "~[ this , changed ]", "remove -": "removed" From fa60256a7f037e7014336d308dc6116f2ac4c37a Mon Sep 17 00:00:00 2001 From: Duologic Date: Sun, 16 Apr 2023 13:43:19 +0200 Subject: [PATCH 3/3] docs: reduce spaces --- docs/inspect.md | 6 +++--- inspect.libsonnet | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/inspect.md b/docs/inspect.md index 244b94d..1ec3605 100644 --- a/docs/inspect.md +++ b/docs/inspect.md @@ -47,9 +47,9 @@ diff(input1, input2), Output: ```json { - "add +": "added", - "change ~": "~[ this , changed ]", - "remove -": "removed" + "add +": "added", + "change ~": "~[ this , changed ]", + "remove -": "removed" } ``` diff --git a/inspect.libsonnet b/inspect.libsonnet index f0d4f63..051ed0d 100644 --- a/inspect.libsonnet +++ b/inspect.libsonnet @@ -74,9 +74,9 @@ local d = import 'doc-util/main.libsonnet'; Output: ```json { - "add +": "added", - "change ~": "~[ this , changed ]", - "remove -": "removed" + "add +": "added", + "change ~": "~[ this , changed ]", + "remove -": "removed" } ``` |||,