From 27215a30ad0e7ae0581a5ea4d765586d929e1604 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Thu, 7 Dec 2023 16:50:39 +0000 Subject: [PATCH 01/23] plug ChangeView component into bulk update preview --- package-lock.json | 68 +- packages/compass-crud/package.json | 5 +- .../src/components/bulk-update-dialog.tsx | 35 +- .../src/components/change-view/bson-utils.ts | 37 ++ .../components/change-view/change-view.tsx | 617 ++++++++++++++++++ .../src/components/change-view/index.ts | 1 + .../src/components/change-view/shape-utils.ts | 16 + .../change-view/unified-document.ts | 524 +++++++++++++++ 8 files changed, 1282 insertions(+), 21 deletions(-) create mode 100644 packages/compass-crud/src/components/change-view/bson-utils.ts create mode 100644 packages/compass-crud/src/components/change-view/change-view.tsx create mode 100644 packages/compass-crud/src/components/change-view/index.ts create mode 100644 packages/compass-crud/src/components/change-view/shape-utils.ts create mode 100644 packages/compass-crud/src/components/change-view/unified-document.ts diff --git a/package-lock.json b/package-lock.json index 047894c2b45..ca39452d906 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,6 @@ "configs/*", "scripts" ], - "dependencies": { - "electron": "^25.9.8" - }, "devDependencies": { "@babel/core": "7.16.0", "@babel/parser": "7.16.0", @@ -20228,6 +20225,12 @@ "node": ">=0.3.1" } }, + "node_modules/diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", + "dev": true + }, "node_modules/diff-sequences": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", @@ -28068,6 +28071,35 @@ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, + "node_modules/jsondiffpatch": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.5.0.tgz", + "integrity": "sha512-Quz3MvAwHxVYNXsOByL7xI5EB2WYOeFswqaHIA3qOK3isRWTxiplBEocmmru6XmxDB2L7jDNYtYA4FyimoAFEw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-match-patch": "^1.0.0" + }, + "bin": { + "jsondiffpatch": "bin/jsondiffpatch" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/jsondiffpatch/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -44948,6 +44980,7 @@ "enzyme": "^3.11.0", "eslint": "^7.25.0", "hadron-app": "^5.16.1", + "jsondiffpatch": "^0.5.0", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-instance-model": "^12.16.2", @@ -59395,6 +59428,7 @@ "hadron-app-registry": "^9.1.1", "hadron-document": "^8.4.4", "hadron-type-checker": "^7.1.1", + "jsondiffpatch": "*", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-data-service": "^22.16.1", @@ -75143,6 +75177,12 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", + "dev": true + }, "diff-sequences": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", @@ -82609,6 +82649,28 @@ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, + "jsondiffpatch": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.5.0.tgz", + "integrity": "sha512-Quz3MvAwHxVYNXsOByL7xI5EB2WYOeFswqaHIA3qOK3isRWTxiplBEocmmru6XmxDB2L7jDNYtYA4FyimoAFEw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-match-patch": "^1.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", diff --git a/packages/compass-crud/package.json b/packages/compass-crud/package.json index 26b8bc458b4..ff039b3920e 100644 --- a/packages/compass-crud/package.json +++ b/packages/compass-crud/package.json @@ -60,8 +60,8 @@ "@mongodb-js/compass-components": "^1.20.1", "@mongodb-js/compass-editor": "^0.19.1", "@mongodb-js/compass-logging": "^1.2.7", - "@mongodb-js/my-queries-storage": "^0.3.1", "@mongodb-js/explain-plan-helper": "^1.1.5", + "@mongodb-js/my-queries-storage": "^0.3.1", "bson": "^6.2.0", "compass-preferences-model": "^2.16.0", "hadron-app-registry": "^9.1.1", @@ -92,11 +92,12 @@ "enzyme": "^3.11.0", "eslint": "^7.25.0", "hadron-app": "^5.16.1", + "jsondiffpatch": "^0.5.0", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-instance-model": "^12.16.2", - "mongodb-query-parser": "^4.0.0", "mongodb-ns": "^2.4.0", + "mongodb-query-parser": "^4.0.0", "nyc": "^15.1.0", "prop-types": "^15.7.2", "react": "^17.0.2", diff --git a/packages/compass-crud/src/components/bulk-update-dialog.tsx b/packages/compass-crud/src/components/bulk-update-dialog.tsx index 338f0eea893..c1a398bcec3 100644 --- a/packages/compass-crud/src/components/bulk-update-dialog.tsx +++ b/packages/compass-crud/src/components/bulk-update-dialog.tsx @@ -1,6 +1,6 @@ import React, { useMemo, useState, useEffect, useCallback } from 'react'; import type { UpdatePreview } from 'mongodb-data-service'; -import HadronDocument from 'hadron-document'; +import type { Document } from 'bson'; import { toJSString } from 'mongodb-query-parser'; import { css, @@ -24,15 +24,14 @@ import { InteractivePopover, TextInput, useId, + DocumentIcon, } from '@mongodb-js/compass-components'; import type { Annotation } from '@mongodb-js/compass-editor'; import { CodemirrorMultilineEditor } from '@mongodb-js/compass-editor'; -import Document from './document'; import type { BSONObject } from '../stores/crud-store'; - +import { ChangeView } from './change-view'; import { ReadonlyFilter } from './readonly-filter'; -import { DocumentIcon } from '@mongodb-js/compass-components'; const columnsStyles = css({ marginTop: spacing[4], @@ -252,12 +251,6 @@ const BulkUpdatePreview: React.FunctionComponent = ({ count, preview, }) => { - const previewDocuments = useMemo(() => { - return preview.changes.map( - (change) => new HadronDocument(change.after as Record) - ); - }, [preview]); - // show a preview for the edge case where the count is undefined, not the // empty state if (count === 0) { @@ -294,12 +287,13 @@ const BulkUpdatePreview: React.FunctionComponent = ({
- {previewDocuments.map((doc: HadronDocument, index: number) => { + {preview.changes.map(({ before, after }, index: number) => { return ( ); })} @@ -483,16 +477,25 @@ export default function BulkUpdateDialog({ ); } +const previewCardStyles = css({ + padding: `${spacing[3]}px 0`, +}); + function UpdatePreviewDocument({ - doc, + before, + after, ...props }: { 'data-testid': string; - doc: HadronDocument; + before: Document; + after: Document; }) { return ( - - + + ); } diff --git a/packages/compass-crud/src/components/change-view/bson-utils.ts b/packages/compass-crud/src/components/change-view/bson-utils.ts new file mode 100644 index 00000000000..ea4d5bd0596 --- /dev/null +++ b/packages/compass-crud/src/components/change-view/bson-utils.ts @@ -0,0 +1,37 @@ +import { EJSON } from 'bson'; + +import { isSimpleObject } from './shape-utils'; + +export function stringifyBSON(value: any) { + if (value?.inspect) { + // TODO: This is a temporary hack - we'd use our existing formatters to + // output colourful/rich previews of values, not just plain text and we + // don't need this behaviour in unBSON() anyway - it doesn't matter that + // jsondiffpatch sees `new ` when diffing. + const s = value.inspect(); + if (s.startsWith('new ')) { + return s.slice(4); + } + return s; + } + if (value?.toISOString) { + return value.toISOString(); + } + return EJSON.stringify(value); +} + +export function unBSON(value: any | any[]): any | any[] { + if (Array.isArray(value)) { + return value.map(unBSON); + } else if (isSimpleObject(value)) { + const mapped: Record = {}; + for (const [k, v] of Object.entries(value)) { + mapped[k] = unBSON(v); + } + return mapped; + } else if (value?._bsontype) { + return stringifyBSON(value); + } else { + return value; + } +} diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx new file mode 100644 index 00000000000..0f5fd016b5c --- /dev/null +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -0,0 +1,617 @@ +import React, { useState, useContext, createContext } from 'react'; +import { type Document } from 'bson'; +import TypeChecker from 'hadron-type-checker'; + +import { + BSONValue, + Icon, + css, + cx, + palette, + spacing, + fontFamilies, + useDarkMode, +} from '@mongodb-js/compass-components'; + +import { getImplicitChangeType, unifyDocuments } from './unified-document'; +import type { + ObjectPath, + UnifiedBranch, + ObjectBranch, + ArrayBranch, + PropertyBranch, + ObjectPropertyBranch, + ArrayPropertyBranch, + ItemBranch, + ObjectItemBranch, + ArrayItemBranch, + Branch, +} from './unified-document'; +import { isSimpleObject, getValueShape } from './shape-utils'; + +type LeftRightContextType = { + left: Document; + right: Document; +}; + +const expandButton = css({ + margin: 0, + padding: 0, + border: 'none', + background: 'none', + '&:hover': { + cursor: 'pointer', + }, + display: 'flex', + alignSelf: 'center', + color: 'inherit', +}); + +const addedStylesDark = css({ + backgroundColor: palette.green.dark2, +}); + +const addedStylesLight = css({ + backgroundColor: palette.green.light1, +}); + +const removedStylesDark = css({ + backgroundColor: palette.red.dark3, +}); + +const removedStylesLight = css({ + backgroundColor: palette.red.light2, +}); + +function getObjectKey(obj: UnifiedBranch) { + const path = (obj.right ?? obj.left).path; + + const parts: string[] = []; + for (const part of path) { + if (typeof part === 'string') { + // not actually sure about escaping here. only really matters if we ever + // want to parse this again which is unlikely + parts.push(`["${part.replace(/"/g, '\\')}"]`); + } else { + parts.push(`[${part}]`); + } + } + return parts.join('') + '_' + obj.changeType; +} + +const changeArrayItemStyles = css({ + display: 'flex', + flexDirection: 'column', + marginTop: '1px', // make sure adjacent red/green blocks don't touch +}); + +const changeKeyIndexStyles = css({ + fontWeight: 'bold', + padding: `0 ${spacing[1]}px`, + alignSelf: 'flex-start', +}); + +const changeSummaryStyles = css({ + display: 'inline-flex', + alignItems: 'flex-start', +}); + +function getChangeSummaryClass(obj: UnifiedBranch, darkMode?: boolean) { + const changeType = getChangeType(obj); + if (changeType === 'unchanged' || changeType === 'changed') { + return undefined; + } + + if (changeType === 'added') { + return darkMode ? addedStylesDark : addedStylesLight; + } else { + return darkMode ? removedStylesDark : removedStylesLight; + } +} + +function ChangeArrayItemArray({ item }: { item: ItemBranch }) { + const [isOpen, setIsOpen] = useState( + !!item.delta || item.changeType !== 'unchanged' + ); + + const toggleIsOpen = function () { + setIsOpen(!isOpen); + }; + + const text = 'Array'; + + const darkMode = useDarkMode(); + const summaryClass = getChangeSummaryClass(item, darkMode); + + return ( +
+
+ +
+ {item.index}: +
+
{text}
+
+ +
+ ); +} + +function ChangeArrayItemObject({ item }: { item: ObjectItemBranch }) { + const [isOpen, setIsOpen] = useState( + !!item.delta || item.changeType !== 'unchanged' + ); + + const toggleIsOpen = function () { + setIsOpen(!isOpen); + }; + + const text = 'Object'; + + const darkMode = useDarkMode(); + const summaryClass = getChangeSummaryClass(item, darkMode); + + return ( +
+
+ +
+ {item.index}: +
+
{text}
+
+ +
+ ); +} + +const changeLeafStyles = css({ + paddingLeft: spacing[1] + spacing[2] /* line up with expand/collapse */, +}); + +function ChangeArrayItemLeaf({ item }: { item: ItemBranch }) { + const darkMode = useDarkMode(); + const summaryClass = getChangeSummaryClass(item, darkMode); + + return ( +
+
+
+ {item.index}: +
+
+ +
+
+
+ ); +} + +function ChangeArrayItem({ item }: { item: ItemBranch }) { + const value = + item.changeType === 'added' ? item.right.value : item.left.value; + if (Array.isArray(value)) { + // array summary followed by array items if expanded + return ; + } else if (isSimpleObject(value)) { + // object summary followed by object properties if expanded + return ; + } + + // simple/bson value only + return ; +} + +const sepStyles = css({ + marginRight: spacing[1], +}); + +function Sep() { + return , ; +} + +const changeArrayStyles = css({ + display: 'flex', + flexDirection: 'column', + paddingLeft: spacing[3], +}); + +const changeArrayInlineWrapStyles = css({ + marginTop: '1px', // don't touch the previous item +}); + +const changeArrayInlineStyles = css({ + marginLeft: spacing[4] + spacing[1], + display: + 'inline-flex' /* so the green/red background colour doesn't stretch all the way to the end */, + flexWrap: 'wrap', +}); + +function ChangeArray({ obj, isOpen }: { obj: ArrayBranch; isOpen: boolean }) { + if (isOpen) { + // TODO: this would be even nicer in place of the "Array" text and then we + // don't even have to make the object key expandable or not + + const implicitChangeType = getImplicitChangeType(obj); + + // TODO: we might want to go further and only do this for simple values like + // strings, numbers, booleans, nulls, etc. ie. not bson types because some + // of those might take up a lot of space? + if ( + obj.items.every( + (item) => + getValueShape( + item.changeType === 'added' ? item.right.value : item.left.value + ) === 'leaf' + ) + ) { + // if it is an array containing just leaf values then we can special-case it and output it all on one line + const classes = [changeArrayInlineStyles]; + + if (implicitChangeType === 'added') { + classes.push('change-array-inline-added'); + } + + if (implicitChangeType === 'removed') { + classes.push('change-array-inline-removed'); + } + + return ( +
+
+ [ + {obj.items.map((item, index) => { + const key = getObjectKey(item); + return ( +
+ + {index !== obj.items.length - 1 && } +
+ ); + })} + ] +
+
+ ); + } + + return ( +
+ {obj.items.map((item) => { + const key = getObjectKey(item); + return ; + })} +
+ ); + } + + return null; +} + +function ChangeObjectPropertyObject({ + property, +}: { + property: ObjectPropertyBranch; +}) { + const [isOpen, setIsOpen] = useState( + !!property.delta || property.changeType !== 'unchanged' + ); + + const toggleIsOpen = function () { + setIsOpen(!isOpen); + }; + + const text = 'Object'; + + const darkMode = useDarkMode(); + const summaryClass = getChangeSummaryClass(property, darkMode); + + return ( +
+
+ +
+ {property.objectKey}: +
+
{text}
+
+ +
+ ); +} + +const changeObjectPropertyStyles = css({ + display: 'flex', + flexDirection: 'column', + marginTop: '1px', // stop the red/green blocks touching +}); + +function ChangeObjectPropertyArray({ property }: { property: PropertyBranch }) { + const [isOpen, setIsOpen] = useState( + !!property.delta || property.changeType !== 'unchanged' + ); + + const toggleIsOpen = function () { + setIsOpen(!isOpen); + }; + + const text = 'Array'; + + const darkMode = useDarkMode(); + const summaryClass = getChangeSummaryClass(property, darkMode); + + return ( +
+
+ +
+ {property.objectKey}: +
+
{text}
+
+ +
+ ); +} + +function ChangeObjectPropertyLeaf({ property }: { property: PropertyBranch }) { + const darkMode = useDarkMode(); + const summaryClass = getChangeSummaryClass(property, darkMode); + + return ( +
+
+
+ {property.objectKey}: +
+
+ +
+
+
+ ); +} + +function ChangeObjectProperty({ property }: { property: PropertyBranch }) { + const value = + property.changeType === 'added' + ? property.right.value + : property.left.value; + if (Array.isArray(value)) { + // array summary followed by array items if expanded + return ( + + ); + } else if (isSimpleObject(value)) { + // object summary followed by object properties if expanded + return ( + + ); + } + + // simple/bson value only + return ; +} + +const changeObjectStyles = css({ + display: 'flex', + flexDirection: 'column', + paddingLeft: spacing[3] /* indent all nested properties*/, +}); + +const rootChangeObjectStyles = css({ + // don't indent the top-level object + paddingLeft: 0, +}); + +function ChangeObject({ + obj, + isOpen, + isRoot, +}: { + obj: ObjectBranch; + isOpen: boolean; + isRoot?: boolean; +}) { + // A sample object / sub-document. ie. not an array and not a leaf. + if (isOpen) { + return ( +
+ {obj.properties.map((property) => { + const key = getObjectKey(property); + return ; + })} +
+ ); + } + + return null; +} + +function getLeftClassName(obj: UnifiedBranch, darkMode?: boolean) { + const addedClass = darkMode ? addedStylesDark : addedStylesLight; + const removedClass = darkMode ? removedStylesDark : removedStylesLight; + + if (obj.implicitChangeType === 'removed') { + return removedClass; + } + + if (obj.implicitChangeType === 'added') { + return addedClass; + } + + if (obj.changeType === 'unchanged') { + return undefined; + } + + if (obj.changeType === 'removed') { + return removedClass; + } + + return obj.changeType === 'changed' ? removedClass : addedClass; +} + +function getRightClassName(obj: UnifiedBranch, darkMode?: boolean) { + return darkMode ? addedStylesDark : addedStylesLight; +} + +function getChangeType(obj: UnifiedBranch) { + // TODO: I can't remember why I made it possible for obj.changeType to be + // different from obj.implicitChangeType. Once a branch is added then + // everything below that is also added, right? Might have been some styling + // aid.. + if (['added', 'removed'].includes(obj.implicitChangeType)) { + // these are "sticky" as we descend + return obj.implicitChangeType; + } + + return obj.changeType; +} + +function lookupValue(path: ObjectPath, value: any): any { + const [head, ...rest] = path; + if (rest.length) { + return lookupValue(rest, value[head]); + } + return value[head]; +} + +const changeValueStyles = css({ + display: 'inline-flex', + flexWrap: 'wrap', + columnGap: spacing[1], // when removed and added are next to each other + rowGap: '1px', // when removed & added wrapped +}); + +function ChangeLeaf({ obj }: { obj: UnifiedBranch }) { + // Anything that is not an object or array. This includes simple javascript + // values like strings, numbers, booleans and undefineds, but also dates or + // bson values. + const { left, right } = useContext(LeftRightContext) as LeftRightContextType; + + const changeType = getChangeType(obj); + // We could be showing the left value (unchanged, removed), right value + // (added) or both (changed). Furthermore the left one could have no colour or + // it could be red and the right one is always green. + const includeLeft = ['unchanged', 'changed', 'removed'].includes(changeType); + const includeRight = ['changed', 'added'].includes(changeType); + + const darkMode = useDarkMode(); + + const leftValue = includeLeft + ? lookupValue((obj.left as Branch).path, left) + : undefined; + const rightValue = includeRight + ? lookupValue((obj.right as Branch).path, right) + : undefined; + + // TODO: BSONValue does not always show the bson type, so you can't spot bson type changes + return ( +
+ {includeLeft && ( +
+ {} +
+ )} + {includeRight && ( +
+ {} +
+ )} +
+ ); +} + +const LeftRightContext = createContext(null); + +const changeViewStyles = css({ + overflow: 'auto', + fontFamily: fontFamilies.code, + + // match our Document component + fontSize: '12px', + lineHeight: '16px', +}); + +const changeViewStylesDark = css({ + color: palette.gray.light2, +}); + +const changeViewStylesLight = css({ + color: palette.gray.dark2, +}); + +export function ChangeView({ + name, + before, + after, +}: { + name: string; + before: Document; + after: Document; +}) { + const obj = unifyDocuments(before, after); + + const darkMode = useDarkMode(); + + // Keep the left and right values in context so that the ChangeLeaf component + // can easily find them again to lookup the original BSON values. Otherwise + // we'd have to pass references down through every component. + return ( + +
+ +
+
+ ); +} diff --git a/packages/compass-crud/src/components/change-view/index.ts b/packages/compass-crud/src/components/change-view/index.ts new file mode 100644 index 00000000000..6cbb15bec28 --- /dev/null +++ b/packages/compass-crud/src/components/change-view/index.ts @@ -0,0 +1 @@ +export { ChangeView } from './change-view'; diff --git a/packages/compass-crud/src/components/change-view/shape-utils.ts b/packages/compass-crud/src/components/change-view/shape-utils.ts new file mode 100644 index 00000000000..c57db771c0e --- /dev/null +++ b/packages/compass-crud/src/components/change-view/shape-utils.ts @@ -0,0 +1,16 @@ +export function isSimpleObject(value: any) { + return ( + Object.prototype.toString.call(value) === '[object Object]' && + !value._bsontype + ); +} + +export function getValueShape(value: any) { + if (Array.isArray(value)) { + return 'array'; + } + if (isSimpleObject(value)) { + return 'object'; + } + return 'leaf'; +} diff --git a/packages/compass-crud/src/components/change-view/unified-document.ts b/packages/compass-crud/src/components/change-view/unified-document.ts new file mode 100644 index 00000000000..e0de34ad4cb --- /dev/null +++ b/packages/compass-crud/src/components/change-view/unified-document.ts @@ -0,0 +1,524 @@ +import assert from 'assert'; +import type { Delta } from 'jsondiffpatch'; +import * as jsondiffpatch from 'jsondiffpatch'; + +import { type Document } from 'bson'; + +import { stringifyBSON, unBSON } from './bson-utils'; +import { isSimpleObject, getValueShape } from './shape-utils'; + +const differ = jsondiffpatch.create({ + arrays: { + // Array moves are really complicated to visualise both technically and also + // usability-wise. (see jsondiffpatch's demo). With this set to false array + // changes will be separate removes and adds. + detectMove: false, + }, + textDiff: { + // Technically this doesn't matter anymore now that we look up the value out + // of before/after docs, but there are nicer ways to diff larger blocks of + // text. Although we probably won't bother with diffing text fields for our + // use case. + minLength: Infinity, // don't do a text diff on bson values + }, + objectHash: function (obj: any) { + // Probably not the most efficient, but gets the job done. This is used by + // jsondiffpatch when diffing arrays that contain objects to be able to + // determine which objects in the left and right docs are the same ones. + return stringifyBSON(obj); + }, +}); + +export type ObjectPath = (string | number)[]; + +type ChangeType = 'unchanged' | 'changed' | 'added' | 'removed'; + +export type UnifiedBranch = { + implicitChangeType: ChangeType; + delta: Delta | null; +} & ( + | { left: Branch; right: Branch; changeType: 'changed' | 'unchanged' } + | { left?: never; right: Branch; changeType: 'added' } + | { left: Branch; right?: never; changeType: 'removed' } +); + +// Only the root object, really. otherwise it will be ObjectPropertyBranch +// or ObjectItemBranch +export type ObjectBranch = UnifiedBranch & { + properties: PropertyBranch[]; +}; + +// Either an ArrayPropertyBranch or an ArrayItemBranch +// { foo: [ /* this */ ] } +// { foo: [[ /* this */ ]] } +export type ArrayBranch = UnifiedBranch & { + items: ItemBranch[]; +}; + +// Either an ObjectPropertyBranch or an ArrayPropertyBranch ir just a PropertyBranch +// { foo: { /* this */ }} +// { foo: [ /* this */ ]} +// { foo: /* any simple value here */ } +export type PropertyBranch = UnifiedBranch & { + objectKey: string; +}; + +// { foo: { /* this */ } } +export type ObjectPropertyBranch = UnifiedBranch & { + objectKey: string; + properties: PropertyBranch[]; +}; + +// { foo: [ /* this */ ] } +export type ArrayPropertyBranch = UnifiedBranch & { + objectKey: string; + items: ItemBranch[]; +}; + +// Either an ObjectItemBranch or an ArrayItemBranch or just an ItemBranch +// { foo: [{ /* this */ }]} +// { foo: [[ /* this */ ]]} +// { foo: [/* any simple value here */ ]} +export type ItemBranch = UnifiedBranch & { + index: number; +}; + +// { foo: [{ /* this */ }]} +export type ObjectItemBranch = UnifiedBranch & { + index: number; + properties: PropertyBranch[]; +}; + +// { foo: [[ /* this */ ]]} +export type ArrayItemBranch = UnifiedBranch & { + index: number; + items: ItemBranch[]; +}; + +export type Branch = { + path: ObjectPath; + value: any | any[]; +}; + +export type BranchesWithChanges = { + delta: Delta | null; // delta is null for unchanged branches + implicitChangeType: ChangeType; +} & ( + | { left: Branch; right: Branch } // changed | unchanged + | { left?: never; right: Branch } // added + | { left: Branch; right?: never } +); // removed + +function propertiesWithChanges({ + left, + right, + delta, + implicitChangeType, +}: BranchesWithChanges) { + // For unchanged, changed or removed objects we use the left value, otherwise + // we use the right value because that's the only one available. ie. we + // descend down a branch of green added stuff and render that even though + // there's no "left/before" data matching it. For red removed branches we + // still use the left/before data. + const value = + implicitChangeType === 'added' + ? (right as Branch).value + : (left as Branch).value; + + const properties = Object.entries(value).map( + ([objectKey, leftValue]): PropertyBranch => { + const prop = { + implicitChangeType, + objectKey, + // We'll fill in delta below if this is an unchanged object with changes + // somewhere inside it. + // ie. { foo: {} } => foo: { bar: 'baz' }. foo's value is "unchanged" + // itself, but it has a delta because bar inside it changed. + delta: null, + }; + + // For both of these: if there is a left/right path we use that. Otherwise + // we're in an added/removed branch so there is no corresponding left/right + // path. (So you can have left or right or both) + const newLeft: Branch | undefined = left + ? { + path: [...left.path, objectKey], + value: leftValue, + } + : undefined; + + // This is just the case where the value was unchanged. changed, added and + // removed get handled below, overriding these values. + const newRight: Branch | undefined = right + ? { + path: [...right.path, objectKey], + value: right.value[objectKey], + } + : undefined; + + if (newLeft && newRight) { + return { + ...prop, + changeType: 'unchanged', // might change to changed below + left: newLeft, + right: newRight, + }; + } else if (newLeft) { + return { + ...prop, + changeType: 'removed', + left: newLeft, + }; + } else if (newRight) { + return { + ...prop, + changeType: 'added', + right: newRight, + }; + } else { + throw new Error('left or right required or both'); + } + } + ); + + if (delta) { + assert(isSimpleObject(delta), 'delta should be a simple object'); + for (const [key, change] of Object.entries(delta)) { + /* + delta = { + property1: [ rightValue1 ], // obj[property1] = rightValue1 + property2: [ leftValue2, rightValue2 ], // obj[property2] = rightValue2 (and previous value was leftValue2) + property5: [ leftValue5, 0, 0 ] // delete obj[property5] (and previous value was leftValue5) + } + */ + if (Array.isArray(change)) { + if (change.length === 1) { + // add + properties.push({ + implicitChangeType, + changeType: 'added', + objectKey: key, + // NOTE: no leftValue or leftPath + right: { + path: [...(right as Branch).path, key], // right must exist because we're adding + value: change[0], + }, + delta: null, + }); + } else if (change.length === 2) { + // update + const existingProperty = properties.find((p) => p.objectKey === key); + if (existingProperty) { + // This assignment might be pointless because we already initialised + // the property with the right value above, but just keep it for + // completeness' sake. + // 0 is the old (left) value, 1 is the new (right) value + (existingProperty.right as Branch).value = change[1]; // right must exist because this is a change + existingProperty.changeType = 'changed'; + } else { + assert(false, `property with key "${key} does not exist"`); + } + } else if (change.length === 3) { + // delete + const existingProperty = properties.find((p) => p.objectKey === key); + if (existingProperty) { + existingProperty.changeType = 'removed'; + delete existingProperty.right; + } else { + assert(false, `property with key "${key} does not exist"`); + } + } else { + assert(false, 'unexpected change length'); + } + } else { + assert(isSimpleObject(change), 'change should be a simple object'); + // unchanged, so we pass the delta along as there are changes deeper in + // the branch + const existingProperty = properties.find((p) => p.objectKey === key); + if (existingProperty) { + existingProperty.delta = change; + } else { + assert(false, `property with key "${key} does not exist"`); + } + } + } + } + + // Turn changes where the "shape" (ie. array, object or leaf) changed into + // remove followed by add because we can't easily visualise it on one line + // TODO: we might be able to roll this in above and not need a separate pass + let changed = true; + while (changed) { + changed = false; + const index = properties.findIndex((property) => { + if (property.changeType === 'changed') { + const beforeType = getValueShape(property.left.value); + const afterType = getValueShape(property.right.value); + if (beforeType !== afterType) { + return true; + } + } + return false; + }); + if (index !== -1) { + const property = properties[index]; + changed = true; + const deleteProperty = { + implicitChangeType, + changeType: 'removed' as const, + objectKey: property.objectKey, + left: property.left as Branch, + delta: null, + }; + + const addProperty = { + implicitChangeType, + changeType: 'added' as const, + objectKey: property.objectKey, + right: { + // both exist because we just checked it above + path: (property.left as Branch).path, + value: (property.right as Branch).value, + }, + delta: null, + }; + properties.splice(index, 1, deleteProperty, addProperty); + } + } + + for (const property of properties) { + const value = + property.changeType === 'added' + ? property.right.value + : property.left.value; + if (Array.isArray(value)) { + (property as ArrayPropertyBranch).items = itemsWithChanges({ + left: property.left ?? undefined, + right: property.right ?? undefined, + delta: property.delta, + implicitChangeType: getImplicitChangeType(property), + } as BranchesWithChanges); + } else if (isSimpleObject(value)) { + (property as ObjectPropertyBranch).properties = propertiesWithChanges({ + left: property.left ?? undefined, + right: property.right ?? undefined, + delta: property.delta, + implicitChangeType: getImplicitChangeType(property), + } as BranchesWithChanges); + } + } + + return properties; +} + +function itemsWithChanges({ + left, + right, + delta, + implicitChangeType, +}: BranchesWithChanges) { + // Same reasoning here as for propertiesWithChanges + const value = ( + implicitChangeType === 'added' + ? (right as Branch).value + : (left as Branch).value + ) as any[]; + + const items = value.map((leftValue, index): ItemBranch => { + const item = { + implicitChangeType, + index, + // Array changes don't work like object changes where it is possible for a + // property to have changes that are deeper down. All changes are adds or + // removes, so no delta to pass down to lower levels. + delta: null, + }; + + // For both of these: if there is a left/right path we use that. Otherwise + // we're in an added/removed branch so there is no corresponding left/right + // path. (So you can have left or right or both) + const newLeft: Branch | undefined = left + ? { + path: [...left.path, index], + value: leftValue, + } + : undefined; + + // This is just the case where the value was unchanged. changed, added and + // removed get handled below, overriding these values. + const newRight: Branch | undefined = right + ? { + path: [...right.path, index], + // assume the value is unchanged, fix below if it was removed. Arrays + // don't have changes. + value: left?.value, + } + : undefined; + + if (newLeft && newRight) { + return { + ...item, + changeType: 'unchanged', + left: newLeft, + right: newRight, + }; + } else if (newLeft) { + return { + ...item, + changeType: 'removed', + left: newLeft, + }; + } else if (newRight) { + return { + ...item, + changeType: 'added', + right: newRight, + }; + } else { + throw new Error('left or right required or both'); + } + }); + + if (delta) { + /* + delta = { + _t: 'a', + index1: innerDelta1, + index2: innerDelta2, + index5: innerDelta5, + }; + */ + assert(delta._t === 'a', 'delta._t is not a'); + const toRemove = Object.keys(delta) + .filter((key) => key.startsWith('_') && key !== '_t') + .map((key) => key.slice(1) as unknown as number); + + // Removed indexes refer to the original (left) which is why we remove in a + // separate pass before updating/adding + for (const index of toRemove) { + // removed + const existingItem = items[index]; + if (existingItem) { + existingItem.changeType = 'removed'; + delete existingItem.right; + } else { + assert(false, `item with index "${index}" does not exist`); + } + + // adjust the indexes of all items after this one + for (const item of items) { + if (item.index > index) { + item.index = item.index - 1; + } + } + } + + for (const [_index, change] of Object.entries(delta)) { + if (_index.startsWith('_')) { + // already handled + continue; + } else { + // Non-removed indexes refer to the final (right) array which is why we + // update/add in a separate pass after removing + + const index = _index as unknown as number; + assert(Array.isArray(change), 'unexpected non-array'); + assert(change.length !== 3, 'array moves are not supported'); + assert(change.length !== 2, 'array changes are not supported'); // always add and remove + + // added + + // adjust the indexes of all items after this one + for (const item of items) { + if (item.index >= index && item.changeType !== 'removed') { + item.index = item.index + 1; + } + } + + items.splice(index, 0, { + implicitChangeType, + changeType: 'added', + index, + // NOTE: no leftValue or leftPath + right: { + // TODO: make sure there's a unit test for both of these paths + path: [...(right ?? left).path, index], + value: change[0], + }, + delta: null, + }); + } + } + } + + for (const item of items) { + const value = + item.changeType === 'added' ? item.right.value : item.left.value; + if (Array.isArray(value)) { + (item as ArrayItemBranch).items = itemsWithChanges({ + left: item.left ?? undefined, + right: item.right ?? undefined, + delta: item.delta, + implicitChangeType: getImplicitChangeType(item), + } as BranchesWithChanges); + } else if (isSimpleObject(value)) { + (item as ObjectItemBranch).properties = propertiesWithChanges({ + left: item.left ?? undefined, + right: item.right ?? undefined, + delta: item.delta, + implicitChangeType: getImplicitChangeType(item), + } as BranchesWithChanges); + } + } + + return items; +} + +export function getImplicitChangeType(obj: UnifiedBranch) { + if (['added', 'removed'].includes(obj.implicitChangeType)) { + // these are "sticky" as we descend + return obj.implicitChangeType; + } + + return obj.changeType; +} + +export function unifyDocuments( + before: Document, + after: Document +): ObjectBranch { + // The idea here is to format BSON leaf values as text (shell syntax) so that + // jsondiffpatch can easily diff them. Because we calculate the left and right + // path for every value we can easily look up the BSON leaf value again and + // use that when displaying if we choose to. + const left = unBSON(before); + const right = unBSON(after); + + const delta = differ.diff(left, right) ?? null; + + const obj: UnifiedBranch = { + left: { + path: [], + value: before, + }, + right: { + path: [], + value: after, + }, + delta, + implicitChangeType: 'unchanged', + changeType: 'unchanged', + }; + + const doc = { + ...obj, + properties: propertiesWithChanges({ + left: obj.left ?? undefined, + right: obj.right ?? undefined, + delta: obj.delta, + implicitChangeType: 'unchanged', + }), + }; + + return doc; +} From fdefe47103f5c78233e6ddd6c321d56e02d70f92 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 12:46:05 +0000 Subject: [PATCH 02/23] tests for unifyDocuments() --- .../change-view/unified-document.spec.ts | 182 ++ .../change-view/unified-document.ts | 11 +- .../test/before-after-fixtures.ts | 472 ++++ .../all_types_all_types_add.json | 461 ++++ .../all_types_all_types_changed.json | 757 +++++++ .../all_types_all_types_identical.json | 605 ++++++ .../all_types_all_types_remove.json | 473 ++++ .../all_types_small_change.json | 607 ++++++ .../array_changes_add_array_to_array.json | 95 + .../array_changes_add_object_to_array.json | 131 ++ ...ray_changes_add_simple_value_to_array.json | 95 + ...array_changes_remove_array_from_array.json | 95 + ...rray_changes_remove_object_from_array.json | 135 ++ ...hanges_remove_simple_value_from_array.json | 81 + .../array_changes_simple_array.json | 113 + .../fixture-results/bson_type_change.json | 35 + ...nges_nested_object_array_array_simple.json | 121 ++ ...ct_changes_nested_object_array_simple.json | 97 + ...d_object_changes_nested_object_simple.json | 63 + ...ys_add_number_next_to_object_in_array.json | 105 + ...in_arrays_object_inside_array_changed.json | 147 ++ ...rrays_object_value_nested_in_an_array.json | 129 ++ ...remove_number_next_to_object_in_array.json | 105 + .../shape_changes_array_to_object.json | 84 + .../shape_changes_array_to_simple.json | 63 + .../shape_changes_object_to_array.json | 84 + .../shape_changes_object_to_simple.json | 62 + .../shape_changes_simple_to_array.json | 63 + .../shape_changes_simple_to_object.json | 62 + .../fixture-results/simple_add_field.json | 46 + .../simple_different_simple_types.json | 35 + .../fixture-results/simple_remove_field.json | 46 + .../simple_same_simple_type.json | 35 + .../fixture-results/simple_simple_add.json | 29 + .../fixture-results/simple_simple_remove.json | 29 + .../fixture-results/stress_tests_airbnb.json | 1913 +++++++++++++++++ 36 files changed, 7663 insertions(+), 3 deletions(-) create mode 100644 packages/compass-crud/src/components/change-view/unified-document.spec.ts create mode 100644 packages/compass-crud/test/before-after-fixtures.ts create mode 100644 packages/compass-crud/test/fixture-results/all_types_all_types_add.json create mode 100644 packages/compass-crud/test/fixture-results/all_types_all_types_changed.json create mode 100644 packages/compass-crud/test/fixture-results/all_types_all_types_identical.json create mode 100644 packages/compass-crud/test/fixture-results/all_types_all_types_remove.json create mode 100644 packages/compass-crud/test/fixture-results/all_types_small_change.json create mode 100644 packages/compass-crud/test/fixture-results/array_changes_add_array_to_array.json create mode 100644 packages/compass-crud/test/fixture-results/array_changes_add_object_to_array.json create mode 100644 packages/compass-crud/test/fixture-results/array_changes_add_simple_value_to_array.json create mode 100644 packages/compass-crud/test/fixture-results/array_changes_remove_array_from_array.json create mode 100644 packages/compass-crud/test/fixture-results/array_changes_remove_object_from_array.json create mode 100644 packages/compass-crud/test/fixture-results/array_changes_remove_simple_value_from_array.json create mode 100644 packages/compass-crud/test/fixture-results/array_changes_simple_array.json create mode 100644 packages/compass-crud/test/fixture-results/bson_type_change.json create mode 100644 packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_array_simple.json create mode 100644 packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_simple.json create mode 100644 packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_simple.json create mode 100644 packages/compass-crud/test/fixture-results/objects_in_arrays_add_number_next_to_object_in_array.json create mode 100644 packages/compass-crud/test/fixture-results/objects_in_arrays_object_inside_array_changed.json create mode 100644 packages/compass-crud/test/fixture-results/objects_in_arrays_object_value_nested_in_an_array.json create mode 100644 packages/compass-crud/test/fixture-results/objects_in_arrays_remove_number_next_to_object_in_array.json create mode 100644 packages/compass-crud/test/fixture-results/shape_changes_array_to_object.json create mode 100644 packages/compass-crud/test/fixture-results/shape_changes_array_to_simple.json create mode 100644 packages/compass-crud/test/fixture-results/shape_changes_object_to_array.json create mode 100644 packages/compass-crud/test/fixture-results/shape_changes_object_to_simple.json create mode 100644 packages/compass-crud/test/fixture-results/shape_changes_simple_to_array.json create mode 100644 packages/compass-crud/test/fixture-results/shape_changes_simple_to_object.json create mode 100644 packages/compass-crud/test/fixture-results/simple_add_field.json create mode 100644 packages/compass-crud/test/fixture-results/simple_different_simple_types.json create mode 100644 packages/compass-crud/test/fixture-results/simple_remove_field.json create mode 100644 packages/compass-crud/test/fixture-results/simple_same_simple_type.json create mode 100644 packages/compass-crud/test/fixture-results/simple_simple_add.json create mode 100644 packages/compass-crud/test/fixture-results/simple_simple_remove.json create mode 100644 packages/compass-crud/test/fixture-results/stress_tests_airbnb.json diff --git a/packages/compass-crud/src/components/change-view/unified-document.spec.ts b/packages/compass-crud/src/components/change-view/unified-document.spec.ts new file mode 100644 index 00000000000..1e589ad6e89 --- /dev/null +++ b/packages/compass-crud/src/components/change-view/unified-document.spec.ts @@ -0,0 +1,182 @@ +/* eslint-disable no-console */ +import { expect } from 'chai'; +import { promises as fs } from 'fs'; +import path from 'path'; +import type { Document } from 'bson'; +import { ObjectId } from 'bson'; + +import type { + ObjectPath, + ObjectBranch, + ArrayBranch, + Branch, + UnifiedBranch, +} from './unified-document'; +import { unifyDocuments } from './unified-document'; +import { unBSON } from './bson-utils'; +import { fixtureGroups } from '../../../test/before-after-fixtures'; + +function lookupValue(path: ObjectPath, value: any): any { + const [head, ...rest] = path; + if (rest.length) { + return lookupValue(rest, value[head]); + } + return value[head]; +} + +function formatPath(path: ObjectPath) { + const bits = path.map((part) => + typeof part === 'string' ? `["${part}"]` : `[${part}]` + ); + return bits.join(''); +} + +function checkValue(branch: Branch, data: Document, side: string) { + const value = lookupValue(branch.path, data); + + // Because we ran unBSON() on the data before diffing, we have to unBSON the + // value we find again to check that it matches, otherwise we check the bson + // value we found when looking it up against that value stringified. + const valueToCheck = unBSON(value); + + expect(valueToCheck, `${formatPath(branch.path)} (${side})`).to.deep.equal( + branch.value + ); +} + +function getChangeType(obj: UnifiedBranch) { + if (['added', 'removed'].includes(obj.implicitChangeType)) { + // these are "sticky" as we descend + return obj.implicitChangeType; + } + + return obj.changeType; +} + +function checkAllPaths(obj: UnifiedBranch, before: Document, after: Document) { + if ('properties' in obj) { + for (const property of (obj as ObjectBranch).properties) { + checkAllPaths(property, before, after); + } + } else if ('items' in obj) { + for (const item of (obj as ArrayBranch).items) { + checkAllPaths(item, before, after); + } + } else { + // It is kinda non-sensical to look up a value on the left if it was added + // or right if it was removed. + const changeType = getChangeType(obj); + const includeLeft = ['unchanged', 'changed', 'removed'].includes( + changeType + ); + const includeRight = ['changed', 'added'].includes(changeType); + + if (includeLeft) { + expect(obj.left).to.exist; + checkValue(obj.left as Branch, before, 'left'); + } else { + expect(obj.left, changeType).to.not.exist; + } + + if (includeRight) { + expect(obj.right).to.exist; + checkValue(obj.right as Branch, after, 'right'); + } else if (changeType !== 'unchanged') { + expect(obj.right, changeType).to.not.exist; + } + } +} + +describe('unifyDocuments', function () { + it('merges before and after documents into one structure', function () { + const before = { a: new ObjectId('642d766b7300158b1f22e972') }; + const after = { b: new ObjectId('642d766c7300158b1f22e975') }; + + const result = unifyDocuments(before, after); + + // this assertion checks the basic structure of the result + expect(result).to.deep.equal({ + left: { path: [], value: { a: 'ObjectId("642d766b7300158b1f22e972")' } }, + right: { path: [], value: { b: 'ObjectId("642d766c7300158b1f22e975")' } }, + delta: { + a: ['ObjectId("642d766b7300158b1f22e972")', 0, 0], + b: ['ObjectId("642d766c7300158b1f22e975")'], + }, + implicitChangeType: 'unchanged', + changeType: 'unchanged', + properties: [ + { + implicitChangeType: 'unchanged', + objectKey: 'a', + delta: null, + changeType: 'removed', + left: { path: ['a'], value: 'ObjectId("642d766b7300158b1f22e972")' }, + }, + { + implicitChangeType: 'unchanged', + changeType: 'added', + objectKey: 'b', + right: { path: ['b'], value: 'ObjectId("642d766c7300158b1f22e975")' }, + delta: null, + }, + ], + }); + + checkAllPaths(result, before, after); + }); + + // These tests are only really useful as regression tests. Any change to the + // result structure will cause them all to fail and then we'd likely have to + // replace all the expected results. Assuming it was intended. + for (const group of fixtureGroups) { + context(group.name, function () { + for (const { name, before, after } of group.fixtures) { + it(name, async function () { + const result = unifyDocuments(before, after); + const json = JSON.stringify(result, null, 4); + + const filename = `${group.name} ${name}.json`.replace(/ /g, '_'); + const expectedPath = path.join( + __dirname, + '..', + '..', + '..', + 'test', + 'fixture-results', + filename + ); + + await fs.writeFile(expectedPath, json, 'utf8'); + + let expectedText: string; + try { + expectedText = await fs.readFile(expectedPath, 'utf8'); + } catch (err) { + // NOTE: If this fails it is probably because a new fixture was + // added. Check that this expected output makes sense and just add + // the file. Tip: If it fails for everything and that's expected, + // just remove the result files and temporarily write them from in + // here. + console.log(expectedPath); + console.log(json); + throw err; + } + + try { + expect(json).to.deep.equal(expectedText); + } catch (err) { + // NOTE: If this fails it is probably because we changed the + // structure. Check that the expected result makes sense and just + // replace the file. Tip: Focusing these tests and using --bail + // should really help. + console.log(expectedPath); + console.log(json); + throw err; + } + + checkAllPaths(result, before, after); + }); + } + }); + } +}); diff --git a/packages/compass-crud/src/components/change-view/unified-document.ts b/packages/compass-crud/src/components/change-view/unified-document.ts index e0de34ad4cb..30d03035073 100644 --- a/packages/compass-crud/src/components/change-view/unified-document.ts +++ b/packages/compass-crud/src/components/change-view/unified-document.ts @@ -351,7 +351,7 @@ function itemsWithChanges({ path: [...right.path, index], // assume the value is unchanged, fix below if it was removed. Arrays // don't have changes. - value: left?.value, + value: leftValue, } : undefined; @@ -496,14 +496,19 @@ export function unifyDocuments( const delta = differ.diff(left, right) ?? null; + // Use the un-bsoned left&right vs before&after so that we're consistent while + // building the result. Otherwise some parts come from the "un-bsoned" delta + // and some parts from before&after which still contains bson. As a nice + // side-effect it also means that the result is easily json serializable which + // is handy for tests. const obj: UnifiedBranch = { left: { path: [], - value: before, + value: left, }, right: { path: [], - value: after, + value: right, }, delta, implicitChangeType: 'unchanged', diff --git a/packages/compass-crud/test/before-after-fixtures.ts b/packages/compass-crud/test/before-after-fixtures.ts new file mode 100644 index 00000000000..c47803db96c --- /dev/null +++ b/packages/compass-crud/test/before-after-fixtures.ts @@ -0,0 +1,472 @@ +import _ from 'lodash'; +import { Buffer } from 'buffer'; +import { + EJSON, + BSONRegExp, + Binary, + Code, + DBRef, + Decimal128, + Double, + Int32, + Long, + MaxKey, + MinKey, + ObjectId, + Timestamp, + UUID, + BSONSymbol, +} from 'bson'; + +import type { Document } from 'bson'; + +export type Fixture = { + name: string; + before: Document; + after: Document; +}; + +export type FixtureGroup = { + name: string; + fixtures: Fixture[]; +}; + +const allTypesDoc: Document = { + _id: new ObjectId('642d766b7300158b1f22e972'), + double: new Double(1.2), // Double, 1, double + string: 'Hello, world!', // String, 2, string + object: { key: 'value' }, // Object, 3, object + array: [1, 2, 3], // Array, 4, array + binData: new Binary(Buffer.from([1, 2, 3])), // Binary data, 5, binData + // Undefined, 6, undefined (deprecated) + objectId: new ObjectId('642d766c7300158b1f22e975'), // ObjectId, 7, objectId + boolean: true, // Boolean, 8, boolean + date: new Date('2023-04-05T13:25:08.445Z'), // Date, 9, date + null: null, // Null, 10, null + regex: new BSONRegExp('pattern', 'i'), // Regular Expression, 11, regex + // DBPointer, 12, dbPointer (deprecated) + javascript: new Code('function() {}'), // JavaScript, 13, javascript + symbol: new BSONSymbol('symbol'), // Symbol, 14, symbol (deprecated) + javascriptWithScope: new Code('function() {}', { foo: 1, bar: 'a' }), // JavaScript code with scope 15 "javascriptWithScope" Deprecated in MongoDB 4.4. + int: new Int32(12345), // 32-bit integer, 16, "int" + timestamp: new Timestamp(new Long('7218556297505931265')), // Timestamp, 17, timestamp + long: new Long('123456789123456789'), // 64-bit integer, 18, long + decimal: new Decimal128( + Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) + ), // Decimal128, 19, decimal + minKey: new MinKey(), // Min key, -1, minKey + maxKey: new MaxKey(), // Max key, 127, maxKey + + binaries: { + generic: new Binary(Buffer.from([1, 2, 3]), 0), // 0 + functionData: new Binary(Buffer.from('//8='), 1), // 1 + binaryOld: new Binary(Buffer.from('//8='), 2), // 2 + uuidOld: new Binary(Buffer.from('c//SZESzTGmQ6OfR38A11A=='), 3), // 3 + uuid: new UUID('AAAAAAAA-AAAA-4AAA-AAAA-AAAAAAAAAAAA'), // 4 + md5: new Binary(Buffer.from('c//SZESzTGmQ6OfR38A11A=='), 5), // 5 + encrypted: new Binary(Buffer.from('c//SZESzTGmQ6OfR38A11A=='), 6), // 6 + compressedTimeSeries: new Binary( + Buffer.from('c//SZESzTGmQ6OfR38A11A=='), + 7 + ), // 7 + custom: new Binary(Buffer.from('//8='), 128), // 128 + }, + + dbRef: new DBRef('namespace', new ObjectId('642d76b4b7ebfab15d3c4a78')), // not actually a separate type, just a convention +}; + +const allTypesDocChanged: Document = { + _id: new ObjectId('6564759d220c47fd4c97379c'), + double: new Double(1.3), // Double, 1, double + string: 'oh no!', // String, 2, string + object: { foo: 'bar' }, // Object, 3, object + array: [1, 2, 3, 4], // Array, 4, array + binData: new Binary(Buffer.from([1, 2, 3, 4])), // Binary data, 5, binData + // Undefined, 6, undefined (deprecated) + objectId: new ObjectId('656475ac220c47fd4c97379d'), // ObjectId, 7, objectId + boolean: false, // Boolean, 8, boolean + date: new Date('2023-04-05T13:25:08.446Z'), // Date, 9, date + null: null, // Null, 10, null + regex: new BSONRegExp('patterns', 'i'), // Regular Expression, 11, regex + // DBPointer, 12, dbPointer (deprecated) + javascript: new Code('function() { /* woop */ }'), // JavaScript, 13, javascript + symbol: new BSONSymbol('symbols are deprecated'), // Symbol, 14, symbol (deprecated) + javascriptWithScope: new Code('function() {}', { foo: 'a', bar: '1' }), // JavaScript code with scope 15 "javascriptWithScope" Deprecated in MongoDB 4.4. + int: new Int32(123456), // 32-bit integer, 16, "int" + timestamp: new Timestamp(new Long('7218556297505931266')), // Timestamp, 17, timestamp + long: new Long('1234567891234567890'), // 64-bit integer, 18, long + decimal: new Decimal128( + Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17]) + ), // Decimal128, 19, decimal + minKey: new MinKey(), // Min key, -1, minKey + maxKey: new MaxKey(), // Max key, 127, maxKey + + binaries: { + generic: new Binary(Buffer.from([1, 2, 3, 4]), 0), // 0 + functionData: new Binary(Buffer.from('//8= '), 1), // 1 + binaryOld: new Binary(Buffer.from('//8= '), 2), // 2 + uuidOld: new Binary(Buffer.from('0123456789abcdef0123456789abcdef'), 3), // 3 + uuid: new UUID('0e1f691e-d3ed-45d8-a151-cb9c995c50ff'), // 4 + md5: new Binary(Buffer.from('0123456789abcdef0123456789abcdef'), 5), // 5 + encrypted: new Binary(Buffer.from('0123456789abcdef0123456789abcdef'), 6), // 6 + compressedTimeSeries: new Binary( + Buffer.from('0123456789abcdef0123456789abcdef'), + 7 + ), // 7 + custom: new Binary(Buffer.from('0123456789abcdef0123456789abcdef'), 128), // 128 + }, + + dbRef: new DBRef('namespace', new ObjectId('642d76b4b7ebfab15d3c4a79')), // not actually a separate type, just a convention +}; + +const smallChangeDoc: Document = _.clone(allTypesDoc); + +smallChangeDoc.string = 'oh no!'; + +const airbnb = EJSON.deserialize( + { + _id: { + $oid: '65648c68cf3ba12a2fcb9c1e', + }, + id: 13913, + listing_url: 'https://www.airbnb.com/rooms/13913', + scrape_id: { + $numberLong: '20220910194334', + }, + last_scraped: { + $date: '2022-09-11T00:00:00.000Z', + }, + source: 'city scrape', + name: 'Holiday London DB Room Let-on going', + description: + "My bright double bedroom with a large window has a relaxed feeling! It comfortably fits one or two and is centrally located just two blocks from Finsbury Park. Enjoy great restaurants in the area and easy access to easy transport tubes, trains and buses. Babies and children of all ages are welcome.

The space
Hello Everyone,

I'm offering my lovely double bedroom in Finsbury Park area (zone 2) for let in a shared apartment.
You will share the apartment with me and it is fully furnished with a self catering kitchen. Two people can easily sleep well as the room has a queen size bed. I also have a travel cot for a baby for guest with small children.

I will require a deposit up front as a security gesture on both our parts and will be given back to you when you return the keys.

I trust anyone who will be responding to this add would treat my home with care and respect .

Best Wishes

Alina

Gue", + neighborhood_overview: + 'Finsbury Park is a friendly melting pot community composed of Turkish, French, Spanish, Middle Eastern, Irish and English families.
We have a wonderful variety of international restaurants directly under us on Stroud Green Road. And there are many shops and large Tescos supermarket right next door.

But you can also venture up to Crouch End and along Greens Lanes where there will endless choice of Turkish and Middle Eastern cuisines.s', + picture_url: + 'https://a0.muscache.com/pictures/miso/Hosting-13913/original/d755aa6d-cebb-4464-80be-2722c921e8d5.jpeg', + host_id: 54730, + host_url: 'https://www.airbnb.com/users/show/54730', + host_name: 'Alina', + host_since: { + $date: '2009-11-16T00:00:00.000Z', + }, + host_location: 'London, United Kingdom', + host_about: + 'I am a Multi-Media Visual Artist and Creative Practitioner in Education. I live in London England with a Greek/Canadian origins and work internationally. \r\n\r\nI love everything there is to be enjoyed in life and travel is on top of my list!', + host_response_time: 'within a day', + host_response_rate: '80%', + host_acceptance_rate: '70%', + host_is_superhost: false, + host_thumbnail_url: + 'https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_small', + host_picture_url: + 'https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_x_medium', + host_neighbourhood: 'LB of Islington', + host_listings_count: 3, + host_total_listings_count: 4, + host_verifications: "['email', 'phone']", + host_has_profile_pic: true, + host_identity_verified: true, + neighbourhood: 'Islington, Greater London, United Kingdom', + neighbourhood_cleansed: 'Islington', + latitude: 51.56861, + longitude: -0.1127, + property_type: 'Private room in rental unit', + room_type: 'Private room', + accommodates: 1, + bathrooms_text: '1 shared bath', + bedrooms: 1, + beds: 1, + amenities: [ + 'Extra pillows and blankets', + 'Oven', + 'Fire extinguisher', + 'Hair dryer', + 'Hangers', + 'Crib', + 'Dishes and silverware', + 'Luggage dropoff allowed', + 'Essentials', + 'Outlet covers', + 'Patio or balcony', + 'Shampoo', + 'Free parking on premises', + 'TV with standard cable', + 'Free street parking', + 'Cooking basics', + 'Bed linens', + 'Babysitter recommendations', + 'Carbon monoxide alarm', + 'Bathtub', + 'Heating', + 'Wifi', + 'Building staff', + 'Children’s books and toys', + 'Coffee maker', + 'Long term stays allowed', + 'Pack ’n play/Travel crib', + 'Refrigerator', + 'Room-darkening shades', + 'Iron', + 'Kitchen', + 'Stove', + 'Lock on bedroom door', + 'Hot water', + 'Washer', + 'Paid parking off premises', + 'Children’s dinnerware', + 'Smoke alarm', + 'Ethernet connection', + 'Dryer', + 'Cable TV', + ], + price: '$50.00', + minimum_nights: 1, + maximum_nights: 29, + minimum_minimum_nights: 1, + maximum_minimum_nights: 1, + minimum_maximum_nights: 29, + maximum_maximum_nights: 29, + minimum_nights_avg_ntm: 1, + maximum_nights_avg_ntm: 29, + has_availability: true, + availability_30: 17, + availability_60: 38, + availability_90: 68, + availability_365: 343, + calendar_last_scraped: { + $date: '2022-09-11T00:00:00.000Z', + }, + number_of_reviews: 30, + number_of_reviews_ltm: 9, + number_of_reviews_l30d: 0, + first_review: { + $date: '2010-08-18T00:00:00.000Z', + }, + last_review: { + $date: '2022-07-15T00:00:00.000Z', + }, + review_scores_rating: 4.9, + review_scores_accuracy: 4.82, + review_scores_cleanliness: 4.89, + review_scores_checkin: 4.86, + review_scores_communication: 4.93, + review_scores_location: 4.75, + review_scores_value: 4.82, + instant_bookable: false, + calculated_host_listings_count: 2, + calculated_host_listings_count_entire_homes: 1, + calculated_host_listings_count_private_rooms: 1, + calculated_host_listings_count_shared_rooms: 0, + reviews_per_month: 0.2, + }, + { relaxed: false } +); + +export const fixtureGroups: FixtureGroup[] = [ + { + name: 'all types', + fixtures: [ + { + name: 'all types identical', + before: allTypesDoc, + after: _.clone(allTypesDoc), + }, + { + name: 'small change', + before: allTypesDoc, + after: smallChangeDoc, + }, + { + name: 'all types add', + before: {}, + after: allTypesDoc, + }, + { + name: 'all types remove', + before: allTypesDoc, + after: {}, + }, + { + name: 'all types changed', + before: allTypesDoc, + after: allTypesDocChanged, + }, + ], + }, + { + name: 'simple', + fixtures: [ + { + name: 'simple add', + before: {}, + after: { foo: 'bar' }, + }, + { + name: 'simple remove', + before: { foo: 'bar' }, + after: {}, + }, + { + name: 'same simple type', + before: { foo: 1 }, + after: { foo: 2 }, + }, + { + name: 'different simple types', + before: { foo: 1 }, + after: { foo: 'a' }, + }, + { + name: 'add field', + before: { foo: 'a' }, + after: { foo: 'a', bar: 'b' }, + }, + { + name: 'remove field', + before: { foo: 'a', bar: 'b' }, + after: { foo: 'a' }, + }, + ], + }, + { + name: 'nested object changes', + fixtures: [ + { + name: 'nested object simple', + before: { foo: { bar: 1 } }, + after: { foo: { bar: 'a' } }, + }, + { + name: 'nested object array simple', + before: { foo: { bar: [1] } }, + after: { foo: { bar: ['a'] } }, + }, + { + name: 'nested object array array simple', + before: { foo: { bar: [[1]] } }, + after: { foo: { bar: [['a']] } }, + }, + ], + }, + { + name: 'array changes', + fixtures: [ + { + name: 'simple array', + before: { foo: [1, 2, 3] }, + after: { foo: ['a', 'b', 'c'] }, + }, + { + name: 'add simple value to array', + before: { foo: [1, 2, 3] }, + after: { foo: [1, 2, 3, 4] }, + }, + { + name: 'add object to array', + before: { foo: [{ a: 1 }] }, + after: { foo: [{ a: 1 }, { bar: 'baz' }] }, + }, + { + name: 'add array to array', + before: { foo: [[1]] }, + after: { foo: [[1], [2]] }, + }, + { + name: 'remove simple value from array', + before: { foo: [1, 2, 3] }, + after: { foo: [1, 3] }, + }, + { + name: 'remove object from array', + before: { foo: [{ a: 1 }, { bar: 'baz' }] }, + after: { foo: [{ a: 1 }] }, + }, + { + name: 'remove array from array', + before: { foo: [[1], [2]] }, + after: { foo: [[1]] }, + }, + ], + }, + { + name: 'objects in arrays', + fixtures: [ + { + name: 'object value nested in an array', + before: { foo: [{ bar: 1 }] }, + after: { foo: [{ bar: 2 }] }, + }, + { + name: 'add number next to object in array', + before: { foo: [{ bar: 'baz' }] }, + after: { foo: [0, { bar: 'baz' }] }, + }, + { + name: 'remove number next to object in array', + before: { foo: [0, { bar: 'baz' }] }, + after: { foo: [{ bar: 'baz' }] }, + }, + { + name: 'object inside array changed', + before: { foo: [0, { bar: 'baz' }] }, + after: { foo: [0, { bar: 'bazz' }] }, + }, + ], + }, + { + name: 'shape changes', + fixtures: [ + { + name: 'simple to object', + before: { foo: 1 }, + after: { foo: { bar: 'baz' } }, + }, + { + name: 'simple to array', + before: { foo: 1 }, + after: { foo: [1, 2] }, + }, + { + name: 'object to array', + before: { foo: { bar: 'baz' } }, + after: { foo: [1, 2] }, + }, + { + name: 'object to simple', + before: { foo: { bar: 'baz' } }, + after: { foo: 1 }, + }, + { + name: 'array to object', + before: { foo: [1, 2] }, + after: { foo: { bar: 'baz' } }, + }, + { + name: 'array to simple', + before: { foo: [1, 2] }, + after: { foo: 1 }, + }, + ], + }, + { + name: 'bson', + fixtures: [ + { + name: 'type change', + before: { foo: new Double(1.2) }, + after: { foo: new Int32(1) }, + }, + ], + }, + { + name: 'stress tests', + fixtures: [ + { + name: 'airbnb', + before: airbnb, + after: _.clone(airbnb), + }, + ], + }, +]; diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_add.json b/packages/compass-crud/test/fixture-results/all_types_all_types_add.json new file mode 100644 index 00000000000..46974653880 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_add.json @@ -0,0 +1,461 @@ +{ + "left": { + "path": [], + "value": {} + }, + "right": { + "path": [], + "value": { + "_id": "ObjectId(\"642d766b7300158b1f22e972\")", + "double": "Double(1.2)", + "string": "Hello, world!", + "object": { + "key": "value" + }, + "array": [1, 2, 3], + "binData": "Binary.createFromBase64(\"AQID\", 0)", + "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "boolean": true, + "date": "2023-04-05T13:25:08.445Z", + "null": null, + "regex": "BSONRegExp(\"pattern\", \"i\")", + "javascript": "Code(\"function() {}\")", + "symbol": "BSONSymbol(\"symbol\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "Int32(12345)", + "timestamp": "Timestamp({ t: 1680701109, i: 1 })", + "long": "Long(\"123456789123456789\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + }, + "delta": { + "_id": ["ObjectId(\"642d766b7300158b1f22e972\")"], + "double": ["Double(1.2)"], + "string": ["Hello, world!"], + "object": [ + { + "key": "value" + } + ], + "array": [[1, 2, 3]], + "binData": ["Binary.createFromBase64(\"AQID\", 0)"], + "objectId": ["ObjectId(\"642d766c7300158b1f22e975\")"], + "boolean": [true], + "date": ["2023-04-05T13:25:08.445Z"], + "null": [null], + "regex": ["BSONRegExp(\"pattern\", \"i\")"], + "javascript": ["Code(\"function() {}\")"], + "symbol": ["BSONSymbol(\"symbol\")"], + "javascriptWithScope": [ + "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + ], + "int": ["Int32(12345)"], + "timestamp": ["Timestamp({ t: 1680701109, i: 1 })"], + "long": ["Long(\"123456789123456789\")"], + "decimal": ["Decimal128(\"5.477284286264328586719275128128001E-4088\")"], + "minKey": ["MinKey()"], + "maxKey": ["MaxKey()"], + "binaries": [ + { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + ], + "dbRef": [ + "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + ] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "_id", + "right": { + "path": ["_id"], + "value": "ObjectId(\"642d766b7300158b1f22e972\")" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "double", + "right": { + "path": ["double"], + "value": "Double(1.2)" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "string", + "right": { + "path": ["string"], + "value": "Hello, world!" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "object", + "right": { + "path": ["object"], + "value": { + "key": "value" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "added", + "objectKey": "key", + "delta": null, + "changeType": "added", + "right": { + "path": ["object", "key"], + "value": "value" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "array", + "right": { + "path": ["array"], + "value": [1, 2, 3] + }, + "delta": null, + "items": [ + { + "implicitChangeType": "added", + "index": 0, + "delta": null, + "changeType": "added", + "right": { + "path": ["array", 0], + "value": 1 + } + }, + { + "implicitChangeType": "added", + "index": 1, + "delta": null, + "changeType": "added", + "right": { + "path": ["array", 1], + "value": 2 + } + }, + { + "implicitChangeType": "added", + "index": 2, + "delta": null, + "changeType": "added", + "right": { + "path": ["array", 2], + "value": 3 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "binData", + "right": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "objectId", + "right": { + "path": ["objectId"], + "value": "ObjectId(\"642d766c7300158b1f22e975\")" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "boolean", + "right": { + "path": ["boolean"], + "value": true + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "date", + "right": { + "path": ["date"], + "value": "2023-04-05T13:25:08.445Z" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "null", + "right": { + "path": ["null"], + "value": null + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "regex", + "right": { + "path": ["regex"], + "value": "BSONRegExp(\"pattern\", \"i\")" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "javascript", + "right": { + "path": ["javascript"], + "value": "Code(\"function() {}\")" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "symbol", + "right": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbol\")" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "javascriptWithScope", + "right": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "int", + "right": { + "path": ["int"], + "value": "Int32(12345)" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "timestamp", + "right": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 1 })" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "long", + "right": { + "path": ["long"], + "value": "Long(\"123456789123456789\")" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "decimal", + "right": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "minKey", + "right": { + "path": ["minKey"], + "value": "MinKey()" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "maxKey", + "right": { + "path": ["maxKey"], + "value": "MaxKey()" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "binaries", + "right": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "added", + "objectKey": "generic", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + } + }, + { + "implicitChangeType": "added", + "objectKey": "functionData", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 1)" + } + }, + { + "implicitChangeType": "added", + "objectKey": "binaryOld", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 2)" + } + }, + { + "implicitChangeType": "added", + "objectKey": "uuidOld", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)" + } + }, + { + "implicitChangeType": "added", + "objectKey": "uuid", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "uuid"], + "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + } + }, + { + "implicitChangeType": "added", + "objectKey": "md5", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)" + } + }, + { + "implicitChangeType": "added", + "objectKey": "encrypted", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)" + } + }, + { + "implicitChangeType": "added", + "objectKey": "compressedTimeSeries", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)" + } + }, + { + "implicitChangeType": "added", + "objectKey": "custom", + "delta": null, + "changeType": "added", + "right": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "dbRef", + "right": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + }, + "delta": null + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_changed.json b/packages/compass-crud/test/fixture-results/all_types_all_types_changed.json new file mode 100644 index 00000000000..bd786587865 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_changed.json @@ -0,0 +1,757 @@ +{ + "left": { + "path": [], + "value": { + "_id": "ObjectId(\"642d766b7300158b1f22e972\")", + "double": "Double(1.2)", + "string": "Hello, world!", + "object": { + "key": "value" + }, + "array": [1, 2, 3], + "binData": "Binary.createFromBase64(\"AQID\", 0)", + "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "boolean": true, + "date": "2023-04-05T13:25:08.445Z", + "null": null, + "regex": "BSONRegExp(\"pattern\", \"i\")", + "javascript": "Code(\"function() {}\")", + "symbol": "BSONSymbol(\"symbol\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "Int32(12345)", + "timestamp": "Timestamp({ t: 1680701109, i: 1 })", + "long": "Long(\"123456789123456789\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + }, + "right": { + "path": [], + "value": { + "_id": "ObjectId(\"6564759d220c47fd4c97379c\")", + "double": "Double(1.3)", + "string": "oh no!", + "object": { + "foo": "bar" + }, + "array": [1, 2, 3, 4], + "binData": "Binary.createFromBase64(\"AQIDBA==\", 0)", + "objectId": "ObjectId(\"656475ac220c47fd4c97379d\")", + "boolean": false, + "date": "2023-04-05T13:25:08.446Z", + "null": null, + "regex": "BSONRegExp(\"patterns\", \"i\")", + "javascript": "Code(\"function() { /* woop */ }\")", + "symbol": "BSONSymbol(\"symbols are deprecated\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})", + "int": "Int32(123456)", + "timestamp": "Timestamp({ t: 1680701109, i: 2 })", + "long": "Long(\"1234567891234567890\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-3960\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQIDBA==\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PSA=\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PSA=\", 2)", + "uuidOld": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)", + "uuid": "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")", + "md5": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 5)", + "encrypted": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 7)", + "custom": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" + } + }, + "delta": { + "_id": [ + "ObjectId(\"642d766b7300158b1f22e972\")", + "ObjectId(\"6564759d220c47fd4c97379c\")" + ], + "double": ["Double(1.2)", "Double(1.3)"], + "string": ["Hello, world!", "oh no!"], + "object": { + "key": ["value", 0, 0], + "foo": ["bar"] + }, + "array": { + "3": [4], + "_t": "a" + }, + "binData": [ + "Binary.createFromBase64(\"AQID\", 0)", + "Binary.createFromBase64(\"AQIDBA==\", 0)" + ], + "objectId": [ + "ObjectId(\"642d766c7300158b1f22e975\")", + "ObjectId(\"656475ac220c47fd4c97379d\")" + ], + "boolean": [true, false], + "date": ["2023-04-05T13:25:08.445Z", "2023-04-05T13:25:08.446Z"], + "regex": [ + "BSONRegExp(\"pattern\", \"i\")", + "BSONRegExp(\"patterns\", \"i\")" + ], + "javascript": [ + "Code(\"function() {}\")", + "Code(\"function() { /* woop */ }\")" + ], + "symbol": [ + "BSONSymbol(\"symbol\")", + "BSONSymbol(\"symbols are deprecated\")" + ], + "javascriptWithScope": [ + "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})" + ], + "int": ["Int32(12345)", "Int32(123456)"], + "timestamp": [ + "Timestamp({ t: 1680701109, i: 1 })", + "Timestamp({ t: 1680701109, i: 2 })" + ], + "long": ["Long(\"123456789123456789\")", "Long(\"1234567891234567890\")"], + "decimal": [ + "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "Decimal128(\"5.477284286264328586719275128128001E-3960\")" + ], + "binaries": { + "generic": [ + "Binary.createFromBase64(\"AQID\", 0)", + "Binary.createFromBase64(\"AQIDBA==\", 0)" + ], + "functionData": [ + "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "Binary.createFromBase64(\"Ly84PSA=\", 1)" + ], + "binaryOld": [ + "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "Binary.createFromBase64(\"Ly84PSA=\", 2)" + ], + "uuidOld": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)" + ], + "uuid": [ + "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" + ], + "md5": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 5)" + ], + "encrypted": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 6)" + ], + "compressedTimeSeries": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 7)" + ], + "custom": [ + "Binary.createFromBase64(\"Ly84PQ==\", 128)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 128)" + ] + }, + "dbRef": [ + "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))", + "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" + ] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "_id", + "delta": null, + "changeType": "changed", + "left": { + "path": ["_id"], + "value": "ObjectId(\"642d766b7300158b1f22e972\")" + }, + "right": { + "path": ["_id"], + "value": "ObjectId(\"6564759d220c47fd4c97379c\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "double", + "delta": null, + "changeType": "changed", + "left": { + "path": ["double"], + "value": "Double(1.2)" + }, + "right": { + "path": ["double"], + "value": "Double(1.3)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "string", + "delta": null, + "changeType": "changed", + "left": { + "path": ["string"], + "value": "Hello, world!" + }, + "right": { + "path": ["string"], + "value": "oh no!" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "object", + "delta": { + "key": ["value", 0, 0], + "foo": ["bar"] + }, + "changeType": "unchanged", + "left": { + "path": ["object"], + "value": { + "key": "value" + } + }, + "right": { + "path": ["object"], + "value": { + "foo": "bar" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "key", + "delta": null, + "changeType": "removed", + "left": { + "path": ["object", "key"], + "value": "value" + } + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["object", "foo"], + "value": "bar" + }, + "delta": null + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "array", + "delta": { + "3": [4], + "_t": "a" + }, + "changeType": "unchanged", + "left": { + "path": ["array"], + "value": [1, 2, 3] + }, + "right": { + "path": ["array"], + "value": [1, 2, 3, 4] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 0], + "value": 1 + }, + "right": { + "path": ["array", 0], + "value": 1 + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 1], + "value": 2 + }, + "right": { + "path": ["array", 1], + "value": 2 + } + }, + { + "implicitChangeType": "unchanged", + "index": 2, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 2], + "value": 3 + }, + "right": { + "path": ["array", 2], + "value": 3 + } + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "3", + "right": { + "path": ["array", "3"], + "value": 4 + }, + "delta": null + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binData", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + }, + "right": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQIDBA==\", 0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "objectId", + "delta": null, + "changeType": "changed", + "left": { + "path": ["objectId"], + "value": "ObjectId(\"642d766c7300158b1f22e975\")" + }, + "right": { + "path": ["objectId"], + "value": "ObjectId(\"656475ac220c47fd4c97379d\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "boolean", + "delta": null, + "changeType": "changed", + "left": { + "path": ["boolean"], + "value": true + }, + "right": { + "path": ["boolean"], + "value": false + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "date", + "delta": null, + "changeType": "changed", + "left": { + "path": ["date"], + "value": "2023-04-05T13:25:08.445Z" + }, + "right": { + "path": ["date"], + "value": "2023-04-05T13:25:08.446Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "null", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["null"], + "value": null + }, + "right": { + "path": ["null"], + "value": null + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "regex", + "delta": null, + "changeType": "changed", + "left": { + "path": ["regex"], + "value": "BSONRegExp(\"pattern\", \"i\")" + }, + "right": { + "path": ["regex"], + "value": "BSONRegExp(\"patterns\", \"i\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascript", + "delta": null, + "changeType": "changed", + "left": { + "path": ["javascript"], + "value": "Code(\"function() {}\")" + }, + "right": { + "path": ["javascript"], + "value": "Code(\"function() { /* woop */ }\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "symbol", + "delta": null, + "changeType": "changed", + "left": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbol\")" + }, + "right": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbols are deprecated\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascriptWithScope", + "delta": null, + "changeType": "changed", + "left": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + }, + "right": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "int", + "delta": null, + "changeType": "changed", + "left": { + "path": ["int"], + "value": "Int32(12345)" + }, + "right": { + "path": ["int"], + "value": "Int32(123456)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "timestamp", + "delta": null, + "changeType": "changed", + "left": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 1 })" + }, + "right": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 2 })" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "long", + "delta": null, + "changeType": "changed", + "left": { + "path": ["long"], + "value": "Long(\"123456789123456789\")" + }, + "right": { + "path": ["long"], + "value": "Long(\"1234567891234567890\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "decimal", + "delta": null, + "changeType": "changed", + "left": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + }, + "right": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-3960\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minKey", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["minKey"], + "value": "MinKey()" + }, + "right": { + "path": ["minKey"], + "value": "MinKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maxKey", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["maxKey"], + "value": "MaxKey()" + }, + "right": { + "path": ["maxKey"], + "value": "MaxKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binaries", + "delta": { + "generic": [ + "Binary.createFromBase64(\"AQID\", 0)", + "Binary.createFromBase64(\"AQIDBA==\", 0)" + ], + "functionData": [ + "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "Binary.createFromBase64(\"Ly84PSA=\", 1)" + ], + "binaryOld": [ + "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "Binary.createFromBase64(\"Ly84PSA=\", 2)" + ], + "uuidOld": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)" + ], + "uuid": [ + "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" + ], + "md5": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 5)" + ], + "encrypted": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 6)" + ], + "compressedTimeSeries": [ + "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 7)" + ], + "custom": [ + "Binary.createFromBase64(\"Ly84PQ==\", 128)", + "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 128)" + ] + }, + "changeType": "unchanged", + "left": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + }, + "right": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQIDBA==\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PSA=\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PSA=\", 2)", + "uuidOld": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)", + "uuid": "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")", + "md5": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 5)", + "encrypted": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 7)", + "custom": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 128)" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "generic", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + }, + "right": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQIDBA==\", 0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "functionData", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 1)" + }, + "right": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PSA=\", 1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binaryOld", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 2)" + }, + "right": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PSA=\", 2)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "uuidOld", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)" + }, + "right": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "uuid", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "uuid"], + "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + }, + "right": { + "path": ["binaries", "uuid"], + "value": "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "md5", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)" + }, + "right": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 5)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "encrypted", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)" + }, + "right": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 6)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "compressedTimeSeries", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)" + }, + "right": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 7)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "custom", + "delta": null, + "changeType": "changed", + "left": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "right": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 128)" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "dbRef", + "delta": null, + "changeType": "changed", + "left": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + }, + "right": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_identical.json b/packages/compass-crud/test/fixture-results/all_types_all_types_identical.json new file mode 100644 index 00000000000..0b112775963 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_identical.json @@ -0,0 +1,605 @@ +{ + "left": { + "path": [], + "value": { + "_id": "ObjectId(\"642d766b7300158b1f22e972\")", + "double": "Double(1.2)", + "string": "Hello, world!", + "object": { + "key": "value" + }, + "array": [1, 2, 3], + "binData": "Binary.createFromBase64(\"AQID\", 0)", + "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "boolean": true, + "date": "2023-04-05T13:25:08.445Z", + "null": null, + "regex": "BSONRegExp(\"pattern\", \"i\")", + "javascript": "Code(\"function() {}\")", + "symbol": "BSONSymbol(\"symbol\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "Int32(12345)", + "timestamp": "Timestamp({ t: 1680701109, i: 1 })", + "long": "Long(\"123456789123456789\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + }, + "right": { + "path": [], + "value": { + "_id": "ObjectId(\"642d766b7300158b1f22e972\")", + "double": "Double(1.2)", + "string": "Hello, world!", + "object": { + "key": "value" + }, + "array": [1, 2, 3], + "binData": "Binary.createFromBase64(\"AQID\", 0)", + "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "boolean": true, + "date": "2023-04-05T13:25:08.445Z", + "null": null, + "regex": "BSONRegExp(\"pattern\", \"i\")", + "javascript": "Code(\"function() {}\")", + "symbol": "BSONSymbol(\"symbol\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "Int32(12345)", + "timestamp": "Timestamp({ t: 1680701109, i: 1 })", + "long": "Long(\"123456789123456789\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + }, + "delta": null, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "_id", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["_id"], + "value": "ObjectId(\"642d766b7300158b1f22e972\")" + }, + "right": { + "path": ["_id"], + "value": "ObjectId(\"642d766b7300158b1f22e972\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "double", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["double"], + "value": "Double(1.2)" + }, + "right": { + "path": ["double"], + "value": "Double(1.2)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "string", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["string"], + "value": "Hello, world!" + }, + "right": { + "path": ["string"], + "value": "Hello, world!" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "object", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["object"], + "value": { + "key": "value" + } + }, + "right": { + "path": ["object"], + "value": { + "key": "value" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "key", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["object", "key"], + "value": "value" + }, + "right": { + "path": ["object", "key"], + "value": "value" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "array", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array"], + "value": [1, 2, 3] + }, + "right": { + "path": ["array"], + "value": [1, 2, 3] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 0], + "value": 1 + }, + "right": { + "path": ["array", 0], + "value": 1 + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 1], + "value": 2 + }, + "right": { + "path": ["array", 1], + "value": 2 + } + }, + { + "implicitChangeType": "unchanged", + "index": 2, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 2], + "value": 3 + }, + "right": { + "path": ["array", 2], + "value": 3 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binData", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + }, + "right": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "objectId", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["objectId"], + "value": "ObjectId(\"642d766c7300158b1f22e975\")" + }, + "right": { + "path": ["objectId"], + "value": "ObjectId(\"642d766c7300158b1f22e975\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "boolean", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["boolean"], + "value": true + }, + "right": { + "path": ["boolean"], + "value": true + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "date", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["date"], + "value": "2023-04-05T13:25:08.445Z" + }, + "right": { + "path": ["date"], + "value": "2023-04-05T13:25:08.445Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "null", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["null"], + "value": null + }, + "right": { + "path": ["null"], + "value": null + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "regex", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["regex"], + "value": "BSONRegExp(\"pattern\", \"i\")" + }, + "right": { + "path": ["regex"], + "value": "BSONRegExp(\"pattern\", \"i\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascript", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["javascript"], + "value": "Code(\"function() {}\")" + }, + "right": { + "path": ["javascript"], + "value": "Code(\"function() {}\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "symbol", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbol\")" + }, + "right": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbol\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascriptWithScope", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + }, + "right": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "int", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["int"], + "value": "Int32(12345)" + }, + "right": { + "path": ["int"], + "value": "Int32(12345)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "timestamp", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 1 })" + }, + "right": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 1 })" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "long", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["long"], + "value": "Long(\"123456789123456789\")" + }, + "right": { + "path": ["long"], + "value": "Long(\"123456789123456789\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "decimal", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + }, + "right": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minKey", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["minKey"], + "value": "MinKey()" + }, + "right": { + "path": ["minKey"], + "value": "MinKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maxKey", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["maxKey"], + "value": "MaxKey()" + }, + "right": { + "path": ["maxKey"], + "value": "MaxKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binaries", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + }, + "right": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "generic", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + }, + "right": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "functionData", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 1)" + }, + "right": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binaryOld", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 2)" + }, + "right": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 2)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "uuidOld", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)" + }, + "right": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "uuid", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "uuid"], + "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + }, + "right": { + "path": ["binaries", "uuid"], + "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "md5", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)" + }, + "right": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "encrypted", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)" + }, + "right": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "compressedTimeSeries", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)" + }, + "right": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "custom", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "right": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "dbRef", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + }, + "right": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_remove.json b/packages/compass-crud/test/fixture-results/all_types_all_types_remove.json new file mode 100644 index 00000000000..da3113d79a7 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_remove.json @@ -0,0 +1,473 @@ +{ + "left": { + "path": [], + "value": { + "_id": "ObjectId(\"642d766b7300158b1f22e972\")", + "double": "Double(1.2)", + "string": "Hello, world!", + "object": { + "key": "value" + }, + "array": [1, 2, 3], + "binData": "Binary.createFromBase64(\"AQID\", 0)", + "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "boolean": true, + "date": "2023-04-05T13:25:08.445Z", + "null": null, + "regex": "BSONRegExp(\"pattern\", \"i\")", + "javascript": "Code(\"function() {}\")", + "symbol": "BSONSymbol(\"symbol\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "Int32(12345)", + "timestamp": "Timestamp({ t: 1680701109, i: 1 })", + "long": "Long(\"123456789123456789\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + }, + "right": { + "path": [], + "value": {} + }, + "delta": { + "_id": ["ObjectId(\"642d766b7300158b1f22e972\")", 0, 0], + "double": ["Double(1.2)", 0, 0], + "string": ["Hello, world!", 0, 0], + "object": [ + { + "key": "value" + }, + 0, + 0 + ], + "array": [[1, 2, 3], 0, 0], + "binData": ["Binary.createFromBase64(\"AQID\", 0)", 0, 0], + "objectId": ["ObjectId(\"642d766c7300158b1f22e975\")", 0, 0], + "boolean": [true, 0, 0], + "date": ["2023-04-05T13:25:08.445Z", 0, 0], + "null": [null, 0, 0], + "regex": ["BSONRegExp(\"pattern\", \"i\")", 0, 0], + "javascript": ["Code(\"function() {}\")", 0, 0], + "symbol": ["BSONSymbol(\"symbol\")", 0, 0], + "javascriptWithScope": [ + "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + 0, + 0 + ], + "int": ["Int32(12345)", 0, 0], + "timestamp": ["Timestamp({ t: 1680701109, i: 1 })", 0, 0], + "long": ["Long(\"123456789123456789\")", 0, 0], + "decimal": [ + "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + 0, + 0 + ], + "minKey": ["MinKey()", 0, 0], + "maxKey": ["MaxKey()", 0, 0], + "binaries": [ + { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + 0, + 0 + ], + "dbRef": [ + "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))", + 0, + 0 + ] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "_id", + "delta": null, + "changeType": "removed", + "left": { + "path": ["_id"], + "value": "ObjectId(\"642d766b7300158b1f22e972\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "double", + "delta": null, + "changeType": "removed", + "left": { + "path": ["double"], + "value": "Double(1.2)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "string", + "delta": null, + "changeType": "removed", + "left": { + "path": ["string"], + "value": "Hello, world!" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "object", + "delta": null, + "changeType": "removed", + "left": { + "path": ["object"], + "value": { + "key": "value" + } + }, + "properties": [ + { + "implicitChangeType": "removed", + "objectKey": "key", + "delta": null, + "changeType": "removed", + "left": { + "path": ["object", "key"], + "value": "value" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "array", + "delta": null, + "changeType": "removed", + "left": { + "path": ["array"], + "value": [1, 2, 3] + }, + "items": [ + { + "implicitChangeType": "removed", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["array", 0], + "value": 1 + } + }, + { + "implicitChangeType": "removed", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["array", 1], + "value": 2 + } + }, + { + "implicitChangeType": "removed", + "index": 2, + "delta": null, + "changeType": "removed", + "left": { + "path": ["array", 2], + "value": 3 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binData", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "objectId", + "delta": null, + "changeType": "removed", + "left": { + "path": ["objectId"], + "value": "ObjectId(\"642d766c7300158b1f22e975\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "boolean", + "delta": null, + "changeType": "removed", + "left": { + "path": ["boolean"], + "value": true + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "date", + "delta": null, + "changeType": "removed", + "left": { + "path": ["date"], + "value": "2023-04-05T13:25:08.445Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "null", + "delta": null, + "changeType": "removed", + "left": { + "path": ["null"], + "value": null + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "regex", + "delta": null, + "changeType": "removed", + "left": { + "path": ["regex"], + "value": "BSONRegExp(\"pattern\", \"i\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascript", + "delta": null, + "changeType": "removed", + "left": { + "path": ["javascript"], + "value": "Code(\"function() {}\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "symbol", + "delta": null, + "changeType": "removed", + "left": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbol\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascriptWithScope", + "delta": null, + "changeType": "removed", + "left": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "int", + "delta": null, + "changeType": "removed", + "left": { + "path": ["int"], + "value": "Int32(12345)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "timestamp", + "delta": null, + "changeType": "removed", + "left": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 1 })" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "long", + "delta": null, + "changeType": "removed", + "left": { + "path": ["long"], + "value": "Long(\"123456789123456789\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "decimal", + "delta": null, + "changeType": "removed", + "left": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minKey", + "delta": null, + "changeType": "removed", + "left": { + "path": ["minKey"], + "value": "MinKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maxKey", + "delta": null, + "changeType": "removed", + "left": { + "path": ["maxKey"], + "value": "MaxKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binaries", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + }, + "properties": [ + { + "implicitChangeType": "removed", + "objectKey": "generic", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "functionData", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 1)" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "binaryOld", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 2)" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "uuidOld", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "uuid", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "uuid"], + "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "md5", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "encrypted", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "compressedTimeSeries", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)" + } + }, + { + "implicitChangeType": "removed", + "objectKey": "custom", + "delta": null, + "changeType": "removed", + "left": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "dbRef", + "delta": null, + "changeType": "removed", + "left": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/all_types_small_change.json b/packages/compass-crud/test/fixture-results/all_types_small_change.json new file mode 100644 index 00000000000..1e0c2b993ee --- /dev/null +++ b/packages/compass-crud/test/fixture-results/all_types_small_change.json @@ -0,0 +1,607 @@ +{ + "left": { + "path": [], + "value": { + "_id": "ObjectId(\"642d766b7300158b1f22e972\")", + "double": "Double(1.2)", + "string": "Hello, world!", + "object": { + "key": "value" + }, + "array": [1, 2, 3], + "binData": "Binary.createFromBase64(\"AQID\", 0)", + "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "boolean": true, + "date": "2023-04-05T13:25:08.445Z", + "null": null, + "regex": "BSONRegExp(\"pattern\", \"i\")", + "javascript": "Code(\"function() {}\")", + "symbol": "BSONSymbol(\"symbol\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "Int32(12345)", + "timestamp": "Timestamp({ t: 1680701109, i: 1 })", + "long": "Long(\"123456789123456789\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + }, + "right": { + "path": [], + "value": { + "_id": "ObjectId(\"642d766b7300158b1f22e972\")", + "double": "Double(1.2)", + "string": "oh no!", + "object": { + "key": "value" + }, + "array": [1, 2, 3], + "binData": "Binary.createFromBase64(\"AQID\", 0)", + "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "boolean": true, + "date": "2023-04-05T13:25:08.445Z", + "null": null, + "regex": "BSONRegExp(\"pattern\", \"i\")", + "javascript": "Code(\"function() {}\")", + "symbol": "BSONSymbol(\"symbol\")", + "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "Int32(12345)", + "timestamp": "Timestamp({ t: 1680701109, i: 1 })", + "long": "Long(\"123456789123456789\")", + "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "MinKey()", + "maxKey": "MaxKey()", + "binaries": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + }, + "delta": { + "string": ["Hello, world!", "oh no!"] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "_id", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["_id"], + "value": "ObjectId(\"642d766b7300158b1f22e972\")" + }, + "right": { + "path": ["_id"], + "value": "ObjectId(\"642d766b7300158b1f22e972\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "double", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["double"], + "value": "Double(1.2)" + }, + "right": { + "path": ["double"], + "value": "Double(1.2)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "string", + "delta": null, + "changeType": "changed", + "left": { + "path": ["string"], + "value": "Hello, world!" + }, + "right": { + "path": ["string"], + "value": "oh no!" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "object", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["object"], + "value": { + "key": "value" + } + }, + "right": { + "path": ["object"], + "value": { + "key": "value" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "key", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["object", "key"], + "value": "value" + }, + "right": { + "path": ["object", "key"], + "value": "value" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "array", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array"], + "value": [1, 2, 3] + }, + "right": { + "path": ["array"], + "value": [1, 2, 3] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 0], + "value": 1 + }, + "right": { + "path": ["array", 0], + "value": 1 + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 1], + "value": 2 + }, + "right": { + "path": ["array", 1], + "value": 2 + } + }, + { + "implicitChangeType": "unchanged", + "index": 2, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["array", 2], + "value": 3 + }, + "right": { + "path": ["array", 2], + "value": 3 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binData", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + }, + "right": { + "path": ["binData"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "objectId", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["objectId"], + "value": "ObjectId(\"642d766c7300158b1f22e975\")" + }, + "right": { + "path": ["objectId"], + "value": "ObjectId(\"642d766c7300158b1f22e975\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "boolean", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["boolean"], + "value": true + }, + "right": { + "path": ["boolean"], + "value": true + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "date", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["date"], + "value": "2023-04-05T13:25:08.445Z" + }, + "right": { + "path": ["date"], + "value": "2023-04-05T13:25:08.445Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "null", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["null"], + "value": null + }, + "right": { + "path": ["null"], + "value": null + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "regex", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["regex"], + "value": "BSONRegExp(\"pattern\", \"i\")" + }, + "right": { + "path": ["regex"], + "value": "BSONRegExp(\"pattern\", \"i\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascript", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["javascript"], + "value": "Code(\"function() {}\")" + }, + "right": { + "path": ["javascript"], + "value": "Code(\"function() {}\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "symbol", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbol\")" + }, + "right": { + "path": ["symbol"], + "value": "BSONSymbol(\"symbol\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "javascriptWithScope", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + }, + "right": { + "path": ["javascriptWithScope"], + "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "int", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["int"], + "value": "Int32(12345)" + }, + "right": { + "path": ["int"], + "value": "Int32(12345)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "timestamp", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 1 })" + }, + "right": { + "path": ["timestamp"], + "value": "Timestamp({ t: 1680701109, i: 1 })" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "long", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["long"], + "value": "Long(\"123456789123456789\")" + }, + "right": { + "path": ["long"], + "value": "Long(\"123456789123456789\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "decimal", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + }, + "right": { + "path": ["decimal"], + "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minKey", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["minKey"], + "value": "MinKey()" + }, + "right": { + "path": ["minKey"], + "value": "MinKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maxKey", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["maxKey"], + "value": "MaxKey()" + }, + "right": { + "path": ["maxKey"], + "value": "MaxKey()" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binaries", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + }, + "right": { + "path": ["binaries"], + "value": { + "generic": "Binary.createFromBase64(\"AQID\", 0)", + "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", + "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", + "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", + "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", + "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", + "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", + "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "generic", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + }, + "right": { + "path": ["binaries", "generic"], + "value": "Binary.createFromBase64(\"AQID\", 0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "functionData", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 1)" + }, + "right": { + "path": ["binaries", "functionData"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "binaryOld", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 2)" + }, + "right": { + "path": ["binaries", "binaryOld"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 2)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "uuidOld", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)" + }, + "right": { + "path": ["binaries", "uuidOld"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "uuid", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "uuid"], + "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + }, + "right": { + "path": ["binaries", "uuid"], + "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "md5", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)" + }, + "right": { + "path": ["binaries", "md5"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "encrypted", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)" + }, + "right": { + "path": ["binaries", "encrypted"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "compressedTimeSeries", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)" + }, + "right": { + "path": ["binaries", "compressedTimeSeries"], + "value": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "custom", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + }, + "right": { + "path": ["binaries", "custom"], + "value": "Binary.createFromBase64(\"Ly84PQ==\", 128)" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "dbRef", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + }, + "right": { + "path": ["dbRef"], + "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/array_changes_add_array_to_array.json b/packages/compass-crud/test/fixture-results/array_changes_add_array_to_array.json new file mode 100644 index 00000000000..b9b78d307e7 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/array_changes_add_array_to_array.json @@ -0,0 +1,95 @@ +{ + "left": { + "path": [], + "value": { + "foo": [[1]] + } + }, + "right": { + "path": [], + "value": { + "foo": [[1], [2]] + } + }, + "delta": { + "foo": { + "1": [[2]], + "_t": "a" + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "1": [[2]], + "_t": "a" + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [[1]] + }, + "right": { + "path": ["foo"], + "value": [[1], [2]] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": [1] + }, + "right": { + "path": ["foo", 0], + "value": [1] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0, 0], + "value": 1 + }, + "right": { + "path": ["foo", 0, 0], + "value": 1 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "1", + "right": { + "path": ["foo", "1"], + "value": [2] + }, + "delta": null, + "items": [ + { + "implicitChangeType": "added", + "index": 0, + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", "1", 0], + "value": 2 + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/array_changes_add_object_to_array.json b/packages/compass-crud/test/fixture-results/array_changes_add_object_to_array.json new file mode 100644 index 00000000000..b766a02d6f6 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/array_changes_add_object_to_array.json @@ -0,0 +1,131 @@ +{ + "left": { + "path": [], + "value": { + "foo": [ + { + "a": 1 + } + ] + } + }, + "right": { + "path": [], + "value": { + "foo": [ + { + "a": 1 + }, + { + "bar": "baz" + } + ] + } + }, + "delta": { + "foo": { + "1": [ + { + "bar": "baz" + } + ], + "_t": "a" + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "1": [ + { + "bar": "baz" + } + ], + "_t": "a" + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [ + { + "a": 1 + } + ] + }, + "right": { + "path": ["foo"], + "value": [ + { + "a": 1 + }, + { + "bar": "baz" + } + ] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": { + "a": 1 + } + }, + "right": { + "path": ["foo", 0], + "value": { + "a": 1 + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "a", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0, "a"], + "value": 1 + }, + "right": { + "path": ["foo", 0, "a"], + "value": 1 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "1", + "right": { + "path": ["foo", "1"], + "value": { + "bar": "baz" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "added", + "objectKey": "bar", + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", "1", "bar"], + "value": "baz" + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/array_changes_add_simple_value_to_array.json b/packages/compass-crud/test/fixture-results/array_changes_add_simple_value_to_array.json new file mode 100644 index 00000000000..e740fb6603e --- /dev/null +++ b/packages/compass-crud/test/fixture-results/array_changes_add_simple_value_to_array.json @@ -0,0 +1,95 @@ +{ + "left": { + "path": [], + "value": { + "foo": [1, 2, 3] + } + }, + "right": { + "path": [], + "value": { + "foo": [1, 2, 3, 4] + } + }, + "delta": { + "foo": { + "3": [4], + "_t": "a" + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "3": [4], + "_t": "a" + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [1, 2, 3] + }, + "right": { + "path": ["foo"], + "value": [1, 2, 3, 4] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": 1 + }, + "right": { + "path": ["foo", 0], + "value": 1 + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 1], + "value": 2 + }, + "right": { + "path": ["foo", 1], + "value": 2 + } + }, + { + "implicitChangeType": "unchanged", + "index": 2, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 2], + "value": 3 + }, + "right": { + "path": ["foo", 2], + "value": 3 + } + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "3", + "right": { + "path": ["foo", "3"], + "value": 4 + }, + "delta": null + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/array_changes_remove_array_from_array.json b/packages/compass-crud/test/fixture-results/array_changes_remove_array_from_array.json new file mode 100644 index 00000000000..80ad16d7a01 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/array_changes_remove_array_from_array.json @@ -0,0 +1,95 @@ +{ + "left": { + "path": [], + "value": { + "foo": [[1], [2]] + } + }, + "right": { + "path": [], + "value": { + "foo": [[1]] + } + }, + "delta": { + "foo": { + "_t": "a", + "_1": [[2], 0, 0] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "_t": "a", + "_1": [[2], 0, 0] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [[1], [2]] + }, + "right": { + "path": ["foo"], + "value": [[1]] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": [1] + }, + "right": { + "path": ["foo", 0], + "value": [1] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0, 0], + "value": 1 + }, + "right": { + "path": ["foo", 0, 0], + "value": 1 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1], + "value": [2] + }, + "items": [ + { + "implicitChangeType": "removed", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1, 0], + "value": 2 + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/array_changes_remove_object_from_array.json b/packages/compass-crud/test/fixture-results/array_changes_remove_object_from_array.json new file mode 100644 index 00000000000..095b646f1fe --- /dev/null +++ b/packages/compass-crud/test/fixture-results/array_changes_remove_object_from_array.json @@ -0,0 +1,135 @@ +{ + "left": { + "path": [], + "value": { + "foo": [ + { + "a": 1 + }, + { + "bar": "baz" + } + ] + } + }, + "right": { + "path": [], + "value": { + "foo": [ + { + "a": 1 + } + ] + } + }, + "delta": { + "foo": { + "_t": "a", + "_1": [ + { + "bar": "baz" + }, + 0, + 0 + ] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "_t": "a", + "_1": [ + { + "bar": "baz" + }, + 0, + 0 + ] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [ + { + "a": 1 + }, + { + "bar": "baz" + } + ] + }, + "right": { + "path": ["foo"], + "value": [ + { + "a": 1 + } + ] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": { + "a": 1 + } + }, + "right": { + "path": ["foo", 0], + "value": { + "a": 1 + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "a", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0, "a"], + "value": 1 + }, + "right": { + "path": ["foo", 0, "a"], + "value": 1 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1], + "value": { + "bar": "baz" + } + }, + "properties": [ + { + "implicitChangeType": "removed", + "objectKey": "bar", + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1, "bar"], + "value": "baz" + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/array_changes_remove_simple_value_from_array.json b/packages/compass-crud/test/fixture-results/array_changes_remove_simple_value_from_array.json new file mode 100644 index 00000000000..41504f74047 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/array_changes_remove_simple_value_from_array.json @@ -0,0 +1,81 @@ +{ + "left": { + "path": [], + "value": { + "foo": [1, 2, 3] + } + }, + "right": { + "path": [], + "value": { + "foo": [1, 3] + } + }, + "delta": { + "foo": { + "_t": "a", + "_1": [2, 0, 0] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "_t": "a", + "_1": [2, 0, 0] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [1, 2, 3] + }, + "right": { + "path": ["foo"], + "value": [1, 3] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": 1 + }, + "right": { + "path": ["foo", 0], + "value": 1 + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1], + "value": 2 + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 2], + "value": 3 + }, + "right": { + "path": ["foo", 2], + "value": 3 + } + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/array_changes_simple_array.json b/packages/compass-crud/test/fixture-results/array_changes_simple_array.json new file mode 100644 index 00000000000..39fc7e02154 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/array_changes_simple_array.json @@ -0,0 +1,113 @@ +{ + "left": { + "path": [], + "value": { + "foo": [1, 2, 3] + } + }, + "right": { + "path": [], + "value": { + "foo": ["a", "b", "c"] + } + }, + "delta": { + "foo": { + "0": ["a"], + "1": ["b"], + "2": ["c"], + "_t": "a", + "_0": [1, 0, 0], + "_1": [2, 0, 0], + "_2": [3, 0, 0] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "0": ["a"], + "1": ["b"], + "2": ["c"], + "_t": "a", + "_0": [1, 0, 0], + "_1": [2, 0, 0], + "_2": [3, 0, 0] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [1, 2, 3] + }, + "right": { + "path": ["foo"], + "value": ["a", "b", "c"] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "0", + "right": { + "path": ["foo", "0"], + "value": "a" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "1", + "right": { + "path": ["foo", "1"], + "value": "b" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "2", + "right": { + "path": ["foo", "2"], + "value": "c" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 0], + "value": 1 + } + }, + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1], + "value": 2 + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 2], + "value": 3 + } + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/bson_type_change.json b/packages/compass-crud/test/fixture-results/bson_type_change.json new file mode 100644 index 00000000000..cb5b9cbb9c8 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/bson_type_change.json @@ -0,0 +1,35 @@ +{ + "left": { + "path": [], + "value": { + "foo": "Double(1.2)" + } + }, + "right": { + "path": [], + "value": { + "foo": "Int32(1)" + } + }, + "delta": { + "foo": ["Double(1.2)", "Int32(1)"] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": null, + "changeType": "changed", + "left": { + "path": ["foo"], + "value": "Double(1.2)" + }, + "right": { + "path": ["foo"], + "value": "Int32(1)" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_array_simple.json b/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_array_simple.json new file mode 100644 index 00000000000..13bfabcab35 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_array_simple.json @@ -0,0 +1,121 @@ +{ + "left": { + "path": [], + "value": { + "foo": { + "bar": [[1]] + } + } + }, + "right": { + "path": [], + "value": { + "foo": { + "bar": [["a"]] + } + } + }, + "delta": { + "foo": { + "bar": { + "0": [["a"]], + "_t": "a", + "_0": [[1], 0, 0] + } + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "bar": { + "0": [["a"]], + "_t": "a", + "_0": [[1], 0, 0] + } + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": { + "bar": [[1]] + } + }, + "right": { + "path": ["foo"], + "value": { + "bar": [["a"]] + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "bar", + "delta": { + "0": [["a"]], + "_t": "a", + "_0": [[1], 0, 0] + }, + "changeType": "unchanged", + "left": { + "path": ["foo", "bar"], + "value": [[1]] + }, + "right": { + "path": ["foo", "bar"], + "value": [["a"]] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "0", + "right": { + "path": ["foo", "bar", "0"], + "value": ["a"] + }, + "delta": null, + "items": [ + { + "implicitChangeType": "added", + "index": 0, + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", "bar", "0", 0], + "value": "a" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", "bar", 0], + "value": [1] + }, + "items": [ + { + "implicitChangeType": "removed", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", "bar", 0, 0], + "value": 1 + } + } + ] + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_simple.json b/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_simple.json new file mode 100644 index 00000000000..d9b7c23173f --- /dev/null +++ b/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_array_simple.json @@ -0,0 +1,97 @@ +{ + "left": { + "path": [], + "value": { + "foo": { + "bar": [1] + } + } + }, + "right": { + "path": [], + "value": { + "foo": { + "bar": ["a"] + } + } + }, + "delta": { + "foo": { + "bar": { + "0": ["a"], + "_t": "a", + "_0": [1, 0, 0] + } + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "bar": { + "0": ["a"], + "_t": "a", + "_0": [1, 0, 0] + } + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": { + "bar": [1] + } + }, + "right": { + "path": ["foo"], + "value": { + "bar": ["a"] + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "bar", + "delta": { + "0": ["a"], + "_t": "a", + "_0": [1, 0, 0] + }, + "changeType": "unchanged", + "left": { + "path": ["foo", "bar"], + "value": [1] + }, + "right": { + "path": ["foo", "bar"], + "value": ["a"] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "0", + "right": { + "path": ["foo", "bar", "0"], + "value": "a" + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", "bar", 0], + "value": 1 + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_simple.json b/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_simple.json new file mode 100644 index 00000000000..b2e6a292444 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/nested_object_changes_nested_object_simple.json @@ -0,0 +1,63 @@ +{ + "left": { + "path": [], + "value": { + "foo": { + "bar": 1 + } + } + }, + "right": { + "path": [], + "value": { + "foo": { + "bar": "a" + } + } + }, + "delta": { + "foo": { + "bar": [1, "a"] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "bar": [1, "a"] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": { + "bar": 1 + } + }, + "right": { + "path": ["foo"], + "value": { + "bar": "a" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "bar", + "delta": null, + "changeType": "changed", + "left": { + "path": ["foo", "bar"], + "value": 1 + }, + "right": { + "path": ["foo", "bar"], + "value": "a" + } + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/objects_in_arrays_add_number_next_to_object_in_array.json b/packages/compass-crud/test/fixture-results/objects_in_arrays_add_number_next_to_object_in_array.json new file mode 100644 index 00000000000..7802ebfc674 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/objects_in_arrays_add_number_next_to_object_in_array.json @@ -0,0 +1,105 @@ +{ + "left": { + "path": [], + "value": { + "foo": [ + { + "bar": "baz" + } + ] + } + }, + "right": { + "path": [], + "value": { + "foo": [ + 0, + { + "bar": "baz" + } + ] + } + }, + "delta": { + "foo": { + "0": [0], + "_t": "a" + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "0": [0], + "_t": "a" + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [ + { + "bar": "baz" + } + ] + }, + "right": { + "path": ["foo"], + "value": [ + 0, + { + "bar": "baz" + } + ] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "0", + "right": { + "path": ["foo", "0"], + "value": 0 + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": { + "bar": "baz" + } + }, + "right": { + "path": ["foo", 0], + "value": { + "bar": "baz" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "bar", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0, "bar"], + "value": "baz" + }, + "right": { + "path": ["foo", 0, "bar"], + "value": "baz" + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/objects_in_arrays_object_inside_array_changed.json b/packages/compass-crud/test/fixture-results/objects_in_arrays_object_inside_array_changed.json new file mode 100644 index 00000000000..589d0666073 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/objects_in_arrays_object_inside_array_changed.json @@ -0,0 +1,147 @@ +{ + "left": { + "path": [], + "value": { + "foo": [ + 0, + { + "bar": "baz" + } + ] + } + }, + "right": { + "path": [], + "value": { + "foo": [ + 0, + { + "bar": "bazz" + } + ] + } + }, + "delta": { + "foo": { + "1": [ + { + "bar": "bazz" + } + ], + "_t": "a", + "_1": [ + { + "bar": "baz" + }, + 0, + 0 + ] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "1": [ + { + "bar": "bazz" + } + ], + "_t": "a", + "_1": [ + { + "bar": "baz" + }, + 0, + 0 + ] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [ + 0, + { + "bar": "baz" + } + ] + }, + "right": { + "path": ["foo"], + "value": [ + 0, + { + "bar": "bazz" + } + ] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 0], + "value": 0 + }, + "right": { + "path": ["foo", 0], + "value": 0 + } + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "1", + "right": { + "path": ["foo", "1"], + "value": { + "bar": "bazz" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "added", + "objectKey": "bar", + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", "1", "bar"], + "value": "bazz" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1], + "value": { + "bar": "baz" + } + }, + "properties": [ + { + "implicitChangeType": "removed", + "objectKey": "bar", + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1, "bar"], + "value": "baz" + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/objects_in_arrays_object_value_nested_in_an_array.json b/packages/compass-crud/test/fixture-results/objects_in_arrays_object_value_nested_in_an_array.json new file mode 100644 index 00000000000..3c0a501cd30 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/objects_in_arrays_object_value_nested_in_an_array.json @@ -0,0 +1,129 @@ +{ + "left": { + "path": [], + "value": { + "foo": [ + { + "bar": 1 + } + ] + } + }, + "right": { + "path": [], + "value": { + "foo": [ + { + "bar": 2 + } + ] + } + }, + "delta": { + "foo": { + "0": [ + { + "bar": 2 + } + ], + "_t": "a", + "_0": [ + { + "bar": 1 + }, + 0, + 0 + ] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "0": [ + { + "bar": 2 + } + ], + "_t": "a", + "_0": [ + { + "bar": 1 + }, + 0, + 0 + ] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [ + { + "bar": 1 + } + ] + }, + "right": { + "path": ["foo"], + "value": [ + { + "bar": 2 + } + ] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "changeType": "added", + "index": "0", + "right": { + "path": ["foo", "0"], + "value": { + "bar": 2 + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "added", + "objectKey": "bar", + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", "0", "bar"], + "value": 2 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 0], + "value": { + "bar": 1 + } + }, + "properties": [ + { + "implicitChangeType": "removed", + "objectKey": "bar", + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 0, "bar"], + "value": 1 + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/objects_in_arrays_remove_number_next_to_object_in_array.json b/packages/compass-crud/test/fixture-results/objects_in_arrays_remove_number_next_to_object_in_array.json new file mode 100644 index 00000000000..ce2a5dce4d5 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/objects_in_arrays_remove_number_next_to_object_in_array.json @@ -0,0 +1,105 @@ +{ + "left": { + "path": [], + "value": { + "foo": [ + 0, + { + "bar": "baz" + } + ] + } + }, + "right": { + "path": [], + "value": { + "foo": [ + { + "bar": "baz" + } + ] + } + }, + "delta": { + "foo": { + "_t": "a", + "_0": [0, 0, 0] + } + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": { + "_t": "a", + "_0": [0, 0, 0] + }, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": [ + 0, + { + "bar": "baz" + } + ] + }, + "right": { + "path": ["foo"], + "value": [ + { + "bar": "baz" + } + ] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 0], + "value": 0 + } + }, + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 1], + "value": { + "bar": "baz" + } + }, + "right": { + "path": ["foo", 1], + "value": { + "bar": "baz" + } + }, + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "bar", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo", 1, "bar"], + "value": "baz" + }, + "right": { + "path": ["foo", 1, "bar"], + "value": "baz" + } + } + ] + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/shape_changes_array_to_object.json b/packages/compass-crud/test/fixture-results/shape_changes_array_to_object.json new file mode 100644 index 00000000000..18b4918fa93 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/shape_changes_array_to_object.json @@ -0,0 +1,84 @@ +{ + "left": { + "path": [], + "value": { + "foo": [1, 2] + } + }, + "right": { + "path": [], + "value": { + "foo": { + "bar": "baz" + } + } + }, + "delta": { + "foo": [ + [1, 2], + { + "bar": "baz" + } + ] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "removed", + "objectKey": "foo", + "left": { + "path": ["foo"], + "value": [1, 2] + }, + "delta": null, + "items": [ + { + "implicitChangeType": "removed", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 0], + "value": 1 + } + }, + { + "implicitChangeType": "removed", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1], + "value": 2 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["foo"], + "value": { + "bar": "baz" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "added", + "objectKey": "bar", + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", "bar"], + "value": "baz" + } + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/shape_changes_array_to_simple.json b/packages/compass-crud/test/fixture-results/shape_changes_array_to_simple.json new file mode 100644 index 00000000000..efed5f71a51 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/shape_changes_array_to_simple.json @@ -0,0 +1,63 @@ +{ + "left": { + "path": [], + "value": { + "foo": [1, 2] + } + }, + "right": { + "path": [], + "value": { + "foo": 1 + } + }, + "delta": { + "foo": [[1, 2], 1] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "removed", + "objectKey": "foo", + "left": { + "path": ["foo"], + "value": [1, 2] + }, + "delta": null, + "items": [ + { + "implicitChangeType": "removed", + "index": 0, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 0], + "value": 1 + } + }, + { + "implicitChangeType": "removed", + "index": 1, + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", 1], + "value": 2 + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["foo"], + "value": 1 + }, + "delta": null + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/shape_changes_object_to_array.json b/packages/compass-crud/test/fixture-results/shape_changes_object_to_array.json new file mode 100644 index 00000000000..c6f6a2e526a --- /dev/null +++ b/packages/compass-crud/test/fixture-results/shape_changes_object_to_array.json @@ -0,0 +1,84 @@ +{ + "left": { + "path": [], + "value": { + "foo": { + "bar": "baz" + } + } + }, + "right": { + "path": [], + "value": { + "foo": [1, 2] + } + }, + "delta": { + "foo": [ + { + "bar": "baz" + }, + [1, 2] + ] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "removed", + "objectKey": "foo", + "left": { + "path": ["foo"], + "value": { + "bar": "baz" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "removed", + "objectKey": "bar", + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", "bar"], + "value": "baz" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["foo"], + "value": [1, 2] + }, + "delta": null, + "items": [ + { + "implicitChangeType": "added", + "index": 0, + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", 0], + "value": 1 + } + }, + { + "implicitChangeType": "added", + "index": 1, + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", 1], + "value": 2 + } + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/shape_changes_object_to_simple.json b/packages/compass-crud/test/fixture-results/shape_changes_object_to_simple.json new file mode 100644 index 00000000000..1af74812247 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/shape_changes_object_to_simple.json @@ -0,0 +1,62 @@ +{ + "left": { + "path": [], + "value": { + "foo": { + "bar": "baz" + } + } + }, + "right": { + "path": [], + "value": { + "foo": 1 + } + }, + "delta": { + "foo": [ + { + "bar": "baz" + }, + 1 + ] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "removed", + "objectKey": "foo", + "left": { + "path": ["foo"], + "value": { + "bar": "baz" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "removed", + "objectKey": "bar", + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo", "bar"], + "value": "baz" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["foo"], + "value": 1 + }, + "delta": null + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/shape_changes_simple_to_array.json b/packages/compass-crud/test/fixture-results/shape_changes_simple_to_array.json new file mode 100644 index 00000000000..988ae0e22f9 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/shape_changes_simple_to_array.json @@ -0,0 +1,63 @@ +{ + "left": { + "path": [], + "value": { + "foo": 1 + } + }, + "right": { + "path": [], + "value": { + "foo": [1, 2] + } + }, + "delta": { + "foo": [1, [1, 2]] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "removed", + "objectKey": "foo", + "left": { + "path": ["foo"], + "value": 1 + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["foo"], + "value": [1, 2] + }, + "delta": null, + "items": [ + { + "implicitChangeType": "added", + "index": 0, + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", 0], + "value": 1 + } + }, + { + "implicitChangeType": "added", + "index": 1, + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", 1], + "value": 2 + } + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/shape_changes_simple_to_object.json b/packages/compass-crud/test/fixture-results/shape_changes_simple_to_object.json new file mode 100644 index 00000000000..2fedf339f3c --- /dev/null +++ b/packages/compass-crud/test/fixture-results/shape_changes_simple_to_object.json @@ -0,0 +1,62 @@ +{ + "left": { + "path": [], + "value": { + "foo": 1 + } + }, + "right": { + "path": [], + "value": { + "foo": { + "bar": "baz" + } + } + }, + "delta": { + "foo": [ + 1, + { + "bar": "baz" + } + ] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "removed", + "objectKey": "foo", + "left": { + "path": ["foo"], + "value": 1 + }, + "delta": null + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["foo"], + "value": { + "bar": "baz" + } + }, + "delta": null, + "properties": [ + { + "implicitChangeType": "added", + "objectKey": "bar", + "delta": null, + "changeType": "added", + "right": { + "path": ["foo", "bar"], + "value": "baz" + } + } + ] + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/simple_add_field.json b/packages/compass-crud/test/fixture-results/simple_add_field.json new file mode 100644 index 00000000000..c67ea2f552e --- /dev/null +++ b/packages/compass-crud/test/fixture-results/simple_add_field.json @@ -0,0 +1,46 @@ +{ + "left": { + "path": [], + "value": { + "foo": "a" + } + }, + "right": { + "path": [], + "value": { + "foo": "a", + "bar": "b" + } + }, + "delta": { + "bar": ["b"] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": "a" + }, + "right": { + "path": ["foo"], + "value": "a" + } + }, + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "bar", + "right": { + "path": ["bar"], + "value": "b" + }, + "delta": null + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/simple_different_simple_types.json b/packages/compass-crud/test/fixture-results/simple_different_simple_types.json new file mode 100644 index 00000000000..ead8d8f7df5 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/simple_different_simple_types.json @@ -0,0 +1,35 @@ +{ + "left": { + "path": [], + "value": { + "foo": 1 + } + }, + "right": { + "path": [], + "value": { + "foo": "a" + } + }, + "delta": { + "foo": [1, "a"] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": null, + "changeType": "changed", + "left": { + "path": ["foo"], + "value": 1 + }, + "right": { + "path": ["foo"], + "value": "a" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/simple_remove_field.json b/packages/compass-crud/test/fixture-results/simple_remove_field.json new file mode 100644 index 00000000000..143ebfafd3a --- /dev/null +++ b/packages/compass-crud/test/fixture-results/simple_remove_field.json @@ -0,0 +1,46 @@ +{ + "left": { + "path": [], + "value": { + "foo": "a", + "bar": "b" + } + }, + "right": { + "path": [], + "value": { + "foo": "a" + } + }, + "delta": { + "bar": ["b", 0, 0] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["foo"], + "value": "a" + }, + "right": { + "path": ["foo"], + "value": "a" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "bar", + "delta": null, + "changeType": "removed", + "left": { + "path": ["bar"], + "value": "b" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/simple_same_simple_type.json b/packages/compass-crud/test/fixture-results/simple_same_simple_type.json new file mode 100644 index 00000000000..9e2cf461399 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/simple_same_simple_type.json @@ -0,0 +1,35 @@ +{ + "left": { + "path": [], + "value": { + "foo": 1 + } + }, + "right": { + "path": [], + "value": { + "foo": 2 + } + }, + "delta": { + "foo": [1, 2] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": null, + "changeType": "changed", + "left": { + "path": ["foo"], + "value": 1 + }, + "right": { + "path": ["foo"], + "value": 2 + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/simple_simple_add.json b/packages/compass-crud/test/fixture-results/simple_simple_add.json new file mode 100644 index 00000000000..104331d0ffd --- /dev/null +++ b/packages/compass-crud/test/fixture-results/simple_simple_add.json @@ -0,0 +1,29 @@ +{ + "left": { + "path": [], + "value": {} + }, + "right": { + "path": [], + "value": { + "foo": "bar" + } + }, + "delta": { + "foo": ["bar"] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "changeType": "added", + "objectKey": "foo", + "right": { + "path": ["foo"], + "value": "bar" + }, + "delta": null + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/simple_simple_remove.json b/packages/compass-crud/test/fixture-results/simple_simple_remove.json new file mode 100644 index 00000000000..be23b843529 --- /dev/null +++ b/packages/compass-crud/test/fixture-results/simple_simple_remove.json @@ -0,0 +1,29 @@ +{ + "left": { + "path": [], + "value": { + "foo": "bar" + } + }, + "right": { + "path": [], + "value": {} + }, + "delta": { + "foo": ["bar", 0, 0] + }, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "foo", + "delta": null, + "changeType": "removed", + "left": { + "path": ["foo"], + "value": "bar" + } + } + ] +} diff --git a/packages/compass-crud/test/fixture-results/stress_tests_airbnb.json b/packages/compass-crud/test/fixture-results/stress_tests_airbnb.json new file mode 100644 index 00000000000..cb0e055561a --- /dev/null +++ b/packages/compass-crud/test/fixture-results/stress_tests_airbnb.json @@ -0,0 +1,1913 @@ +{ + "left": { + "path": [], + "value": { + "_id": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")", + "id": "Int32(13913)", + "listing_url": "https://www.airbnb.com/rooms/13913", + "scrape_id": "Long(\"20220910194334\")", + "last_scraped": "2022-09-11T00:00:00.000Z", + "source": "city scrape", + "name": "Holiday London DB Room Let-on going", + "description": "My bright double bedroom with a large window has a relaxed feeling! It comfortably fits one or two and is centrally located just two blocks from Finsbury Park. Enjoy great restaurants in the area and easy access to easy transport tubes, trains and buses. Babies and children of all ages are welcome.

The space
Hello Everyone,

I'm offering my lovely double bedroom in Finsbury Park area (zone 2) for let in a shared apartment.
You will share the apartment with me and it is fully furnished with a self catering kitchen. Two people can easily sleep well as the room has a queen size bed. I also have a travel cot for a baby for guest with small children.

I will require a deposit up front as a security gesture on both our parts and will be given back to you when you return the keys.

I trust anyone who will be responding to this add would treat my home with care and respect .

Best Wishes

Alina

Gue", + "neighborhood_overview": "Finsbury Park is a friendly melting pot community composed of Turkish, French, Spanish, Middle Eastern, Irish and English families.
We have a wonderful variety of international restaurants directly under us on Stroud Green Road. And there are many shops and large Tescos supermarket right next door.

But you can also venture up to Crouch End and along Greens Lanes where there will endless choice of Turkish and Middle Eastern cuisines.s", + "picture_url": "https://a0.muscache.com/pictures/miso/Hosting-13913/original/d755aa6d-cebb-4464-80be-2722c921e8d5.jpeg", + "host_id": "Int32(54730)", + "host_url": "https://www.airbnb.com/users/show/54730", + "host_name": "Alina", + "host_since": "2009-11-16T00:00:00.000Z", + "host_location": "London, United Kingdom", + "host_about": "I am a Multi-Media Visual Artist and Creative Practitioner in Education. I live in London England with a Greek/Canadian origins and work internationally. \r\n\r\nI love everything there is to be enjoyed in life and travel is on top of my list!", + "host_response_time": "within a day", + "host_response_rate": "80%", + "host_acceptance_rate": "70%", + "host_is_superhost": false, + "host_thumbnail_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_small", + "host_picture_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_x_medium", + "host_neighbourhood": "LB of Islington", + "host_listings_count": "Int32(3)", + "host_total_listings_count": "Int32(4)", + "host_verifications": "['email', 'phone']", + "host_has_profile_pic": true, + "host_identity_verified": true, + "neighbourhood": "Islington, Greater London, United Kingdom", + "neighbourhood_cleansed": "Islington", + "latitude": "Double(51.56861)", + "longitude": "Double(-0.1127)", + "property_type": "Private room in rental unit", + "room_type": "Private room", + "accommodates": "Int32(1)", + "bathrooms_text": "1 shared bath", + "bedrooms": "Int32(1)", + "beds": "Int32(1)", + "amenities": [ + "Extra pillows and blankets", + "Oven", + "Fire extinguisher", + "Hair dryer", + "Hangers", + "Crib", + "Dishes and silverware", + "Luggage dropoff allowed", + "Essentials", + "Outlet covers", + "Patio or balcony", + "Shampoo", + "Free parking on premises", + "TV with standard cable", + "Free street parking", + "Cooking basics", + "Bed linens", + "Babysitter recommendations", + "Carbon monoxide alarm", + "Bathtub", + "Heating", + "Wifi", + "Building staff", + "Children’s books and toys", + "Coffee maker", + "Long term stays allowed", + "Pack ’n play/Travel crib", + "Refrigerator", + "Room-darkening shades", + "Iron", + "Kitchen", + "Stove", + "Lock on bedroom door", + "Hot water", + "Washer", + "Paid parking off premises", + "Children’s dinnerware", + "Smoke alarm", + "Ethernet connection", + "Dryer", + "Cable TV" + ], + "price": "$50.00", + "minimum_nights": "Int32(1)", + "maximum_nights": "Int32(29)", + "minimum_minimum_nights": "Int32(1)", + "maximum_minimum_nights": "Int32(1)", + "minimum_maximum_nights": "Int32(29)", + "maximum_maximum_nights": "Int32(29)", + "minimum_nights_avg_ntm": "Int32(1)", + "maximum_nights_avg_ntm": "Int32(29)", + "has_availability": true, + "availability_30": "Int32(17)", + "availability_60": "Int32(38)", + "availability_90": "Int32(68)", + "availability_365": "Int32(343)", + "calendar_last_scraped": "2022-09-11T00:00:00.000Z", + "number_of_reviews": "Int32(30)", + "number_of_reviews_ltm": "Int32(9)", + "number_of_reviews_l30d": "Int32(0)", + "first_review": "2010-08-18T00:00:00.000Z", + "last_review": "2022-07-15T00:00:00.000Z", + "review_scores_rating": "Double(4.9)", + "review_scores_accuracy": "Double(4.82)", + "review_scores_cleanliness": "Double(4.89)", + "review_scores_checkin": "Double(4.86)", + "review_scores_communication": "Double(4.93)", + "review_scores_location": "Double(4.75)", + "review_scores_value": "Double(4.82)", + "instant_bookable": false, + "calculated_host_listings_count": "Int32(2)", + "calculated_host_listings_count_entire_homes": "Int32(1)", + "calculated_host_listings_count_private_rooms": "Int32(1)", + "calculated_host_listings_count_shared_rooms": "Int32(0)", + "reviews_per_month": "Double(0.2)" + } + }, + "right": { + "path": [], + "value": { + "_id": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")", + "id": "Int32(13913)", + "listing_url": "https://www.airbnb.com/rooms/13913", + "scrape_id": "Long(\"20220910194334\")", + "last_scraped": "2022-09-11T00:00:00.000Z", + "source": "city scrape", + "name": "Holiday London DB Room Let-on going", + "description": "My bright double bedroom with a large window has a relaxed feeling! It comfortably fits one or two and is centrally located just two blocks from Finsbury Park. Enjoy great restaurants in the area and easy access to easy transport tubes, trains and buses. Babies and children of all ages are welcome.

The space
Hello Everyone,

I'm offering my lovely double bedroom in Finsbury Park area (zone 2) for let in a shared apartment.
You will share the apartment with me and it is fully furnished with a self catering kitchen. Two people can easily sleep well as the room has a queen size bed. I also have a travel cot for a baby for guest with small children.

I will require a deposit up front as a security gesture on both our parts and will be given back to you when you return the keys.

I trust anyone who will be responding to this add would treat my home with care and respect .

Best Wishes

Alina

Gue", + "neighborhood_overview": "Finsbury Park is a friendly melting pot community composed of Turkish, French, Spanish, Middle Eastern, Irish and English families.
We have a wonderful variety of international restaurants directly under us on Stroud Green Road. And there are many shops and large Tescos supermarket right next door.

But you can also venture up to Crouch End and along Greens Lanes where there will endless choice of Turkish and Middle Eastern cuisines.s", + "picture_url": "https://a0.muscache.com/pictures/miso/Hosting-13913/original/d755aa6d-cebb-4464-80be-2722c921e8d5.jpeg", + "host_id": "Int32(54730)", + "host_url": "https://www.airbnb.com/users/show/54730", + "host_name": "Alina", + "host_since": "2009-11-16T00:00:00.000Z", + "host_location": "London, United Kingdom", + "host_about": "I am a Multi-Media Visual Artist and Creative Practitioner in Education. I live in London England with a Greek/Canadian origins and work internationally. \r\n\r\nI love everything there is to be enjoyed in life and travel is on top of my list!", + "host_response_time": "within a day", + "host_response_rate": "80%", + "host_acceptance_rate": "70%", + "host_is_superhost": false, + "host_thumbnail_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_small", + "host_picture_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_x_medium", + "host_neighbourhood": "LB of Islington", + "host_listings_count": "Int32(3)", + "host_total_listings_count": "Int32(4)", + "host_verifications": "['email', 'phone']", + "host_has_profile_pic": true, + "host_identity_verified": true, + "neighbourhood": "Islington, Greater London, United Kingdom", + "neighbourhood_cleansed": "Islington", + "latitude": "Double(51.56861)", + "longitude": "Double(-0.1127)", + "property_type": "Private room in rental unit", + "room_type": "Private room", + "accommodates": "Int32(1)", + "bathrooms_text": "1 shared bath", + "bedrooms": "Int32(1)", + "beds": "Int32(1)", + "amenities": [ + "Extra pillows and blankets", + "Oven", + "Fire extinguisher", + "Hair dryer", + "Hangers", + "Crib", + "Dishes and silverware", + "Luggage dropoff allowed", + "Essentials", + "Outlet covers", + "Patio or balcony", + "Shampoo", + "Free parking on premises", + "TV with standard cable", + "Free street parking", + "Cooking basics", + "Bed linens", + "Babysitter recommendations", + "Carbon monoxide alarm", + "Bathtub", + "Heating", + "Wifi", + "Building staff", + "Children’s books and toys", + "Coffee maker", + "Long term stays allowed", + "Pack ’n play/Travel crib", + "Refrigerator", + "Room-darkening shades", + "Iron", + "Kitchen", + "Stove", + "Lock on bedroom door", + "Hot water", + "Washer", + "Paid parking off premises", + "Children’s dinnerware", + "Smoke alarm", + "Ethernet connection", + "Dryer", + "Cable TV" + ], + "price": "$50.00", + "minimum_nights": "Int32(1)", + "maximum_nights": "Int32(29)", + "minimum_minimum_nights": "Int32(1)", + "maximum_minimum_nights": "Int32(1)", + "minimum_maximum_nights": "Int32(29)", + "maximum_maximum_nights": "Int32(29)", + "minimum_nights_avg_ntm": "Int32(1)", + "maximum_nights_avg_ntm": "Int32(29)", + "has_availability": true, + "availability_30": "Int32(17)", + "availability_60": "Int32(38)", + "availability_90": "Int32(68)", + "availability_365": "Int32(343)", + "calendar_last_scraped": "2022-09-11T00:00:00.000Z", + "number_of_reviews": "Int32(30)", + "number_of_reviews_ltm": "Int32(9)", + "number_of_reviews_l30d": "Int32(0)", + "first_review": "2010-08-18T00:00:00.000Z", + "last_review": "2022-07-15T00:00:00.000Z", + "review_scores_rating": "Double(4.9)", + "review_scores_accuracy": "Double(4.82)", + "review_scores_cleanliness": "Double(4.89)", + "review_scores_checkin": "Double(4.86)", + "review_scores_communication": "Double(4.93)", + "review_scores_location": "Double(4.75)", + "review_scores_value": "Double(4.82)", + "instant_bookable": false, + "calculated_host_listings_count": "Int32(2)", + "calculated_host_listings_count_entire_homes": "Int32(1)", + "calculated_host_listings_count_private_rooms": "Int32(1)", + "calculated_host_listings_count_shared_rooms": "Int32(0)", + "reviews_per_month": "Double(0.2)" + } + }, + "delta": null, + "implicitChangeType": "unchanged", + "changeType": "unchanged", + "properties": [ + { + "implicitChangeType": "unchanged", + "objectKey": "_id", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["_id"], + "value": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")" + }, + "right": { + "path": ["_id"], + "value": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "id", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["id"], + "value": "Int32(13913)" + }, + "right": { + "path": ["id"], + "value": "Int32(13913)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "listing_url", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["listing_url"], + "value": "https://www.airbnb.com/rooms/13913" + }, + "right": { + "path": ["listing_url"], + "value": "https://www.airbnb.com/rooms/13913" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "scrape_id", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["scrape_id"], + "value": "Long(\"20220910194334\")" + }, + "right": { + "path": ["scrape_id"], + "value": "Long(\"20220910194334\")" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "last_scraped", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["last_scraped"], + "value": "2022-09-11T00:00:00.000Z" + }, + "right": { + "path": ["last_scraped"], + "value": "2022-09-11T00:00:00.000Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "source", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["source"], + "value": "city scrape" + }, + "right": { + "path": ["source"], + "value": "city scrape" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "name", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["name"], + "value": "Holiday London DB Room Let-on going" + }, + "right": { + "path": ["name"], + "value": "Holiday London DB Room Let-on going" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "description", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["description"], + "value": "My bright double bedroom with a large window has a relaxed feeling! It comfortably fits one or two and is centrally located just two blocks from Finsbury Park. Enjoy great restaurants in the area and easy access to easy transport tubes, trains and buses. Babies and children of all ages are welcome.

The space
Hello Everyone,

I'm offering my lovely double bedroom in Finsbury Park area (zone 2) for let in a shared apartment.
You will share the apartment with me and it is fully furnished with a self catering kitchen. Two people can easily sleep well as the room has a queen size bed. I also have a travel cot for a baby for guest with small children.

I will require a deposit up front as a security gesture on both our parts and will be given back to you when you return the keys.

I trust anyone who will be responding to this add would treat my home with care and respect .

Best Wishes

Alina

Gue" + }, + "right": { + "path": ["description"], + "value": "My bright double bedroom with a large window has a relaxed feeling! It comfortably fits one or two and is centrally located just two blocks from Finsbury Park. Enjoy great restaurants in the area and easy access to easy transport tubes, trains and buses. Babies and children of all ages are welcome.

The space
Hello Everyone,

I'm offering my lovely double bedroom in Finsbury Park area (zone 2) for let in a shared apartment.
You will share the apartment with me and it is fully furnished with a self catering kitchen. Two people can easily sleep well as the room has a queen size bed. I also have a travel cot for a baby for guest with small children.

I will require a deposit up front as a security gesture on both our parts and will be given back to you when you return the keys.

I trust anyone who will be responding to this add would treat my home with care and respect .

Best Wishes

Alina

Gue" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "neighborhood_overview", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["neighborhood_overview"], + "value": "Finsbury Park is a friendly melting pot community composed of Turkish, French, Spanish, Middle Eastern, Irish and English families.
We have a wonderful variety of international restaurants directly under us on Stroud Green Road. And there are many shops and large Tescos supermarket right next door.

But you can also venture up to Crouch End and along Greens Lanes where there will endless choice of Turkish and Middle Eastern cuisines.s" + }, + "right": { + "path": ["neighborhood_overview"], + "value": "Finsbury Park is a friendly melting pot community composed of Turkish, French, Spanish, Middle Eastern, Irish and English families.
We have a wonderful variety of international restaurants directly under us on Stroud Green Road. And there are many shops and large Tescos supermarket right next door.

But you can also venture up to Crouch End and along Greens Lanes where there will endless choice of Turkish and Middle Eastern cuisines.s" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "picture_url", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["picture_url"], + "value": "https://a0.muscache.com/pictures/miso/Hosting-13913/original/d755aa6d-cebb-4464-80be-2722c921e8d5.jpeg" + }, + "right": { + "path": ["picture_url"], + "value": "https://a0.muscache.com/pictures/miso/Hosting-13913/original/d755aa6d-cebb-4464-80be-2722c921e8d5.jpeg" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_id", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_id"], + "value": "Int32(54730)" + }, + "right": { + "path": ["host_id"], + "value": "Int32(54730)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_url", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_url"], + "value": "https://www.airbnb.com/users/show/54730" + }, + "right": { + "path": ["host_url"], + "value": "https://www.airbnb.com/users/show/54730" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_name", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_name"], + "value": "Alina" + }, + "right": { + "path": ["host_name"], + "value": "Alina" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_since", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_since"], + "value": "2009-11-16T00:00:00.000Z" + }, + "right": { + "path": ["host_since"], + "value": "2009-11-16T00:00:00.000Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_location", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_location"], + "value": "London, United Kingdom" + }, + "right": { + "path": ["host_location"], + "value": "London, United Kingdom" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_about", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_about"], + "value": "I am a Multi-Media Visual Artist and Creative Practitioner in Education. I live in London England with a Greek/Canadian origins and work internationally. \r\n\r\nI love everything there is to be enjoyed in life and travel is on top of my list!" + }, + "right": { + "path": ["host_about"], + "value": "I am a Multi-Media Visual Artist and Creative Practitioner in Education. I live in London England with a Greek/Canadian origins and work internationally. \r\n\r\nI love everything there is to be enjoyed in life and travel is on top of my list!" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_response_time", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_response_time"], + "value": "within a day" + }, + "right": { + "path": ["host_response_time"], + "value": "within a day" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_response_rate", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_response_rate"], + "value": "80%" + }, + "right": { + "path": ["host_response_rate"], + "value": "80%" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_acceptance_rate", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_acceptance_rate"], + "value": "70%" + }, + "right": { + "path": ["host_acceptance_rate"], + "value": "70%" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_is_superhost", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_is_superhost"], + "value": false + }, + "right": { + "path": ["host_is_superhost"], + "value": false + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_thumbnail_url", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_thumbnail_url"], + "value": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_small" + }, + "right": { + "path": ["host_thumbnail_url"], + "value": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_small" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_picture_url", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_picture_url"], + "value": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_x_medium" + }, + "right": { + "path": ["host_picture_url"], + "value": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_x_medium" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_neighbourhood", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_neighbourhood"], + "value": "LB of Islington" + }, + "right": { + "path": ["host_neighbourhood"], + "value": "LB of Islington" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_listings_count", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_listings_count"], + "value": "Int32(3)" + }, + "right": { + "path": ["host_listings_count"], + "value": "Int32(3)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_total_listings_count", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_total_listings_count"], + "value": "Int32(4)" + }, + "right": { + "path": ["host_total_listings_count"], + "value": "Int32(4)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_verifications", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_verifications"], + "value": "['email', 'phone']" + }, + "right": { + "path": ["host_verifications"], + "value": "['email', 'phone']" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_has_profile_pic", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_has_profile_pic"], + "value": true + }, + "right": { + "path": ["host_has_profile_pic"], + "value": true + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "host_identity_verified", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["host_identity_verified"], + "value": true + }, + "right": { + "path": ["host_identity_verified"], + "value": true + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "neighbourhood", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["neighbourhood"], + "value": "Islington, Greater London, United Kingdom" + }, + "right": { + "path": ["neighbourhood"], + "value": "Islington, Greater London, United Kingdom" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "neighbourhood_cleansed", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["neighbourhood_cleansed"], + "value": "Islington" + }, + "right": { + "path": ["neighbourhood_cleansed"], + "value": "Islington" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "latitude", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["latitude"], + "value": "Double(51.56861)" + }, + "right": { + "path": ["latitude"], + "value": "Double(51.56861)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "longitude", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["longitude"], + "value": "Double(-0.1127)" + }, + "right": { + "path": ["longitude"], + "value": "Double(-0.1127)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "property_type", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["property_type"], + "value": "Private room in rental unit" + }, + "right": { + "path": ["property_type"], + "value": "Private room in rental unit" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "room_type", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["room_type"], + "value": "Private room" + }, + "right": { + "path": ["room_type"], + "value": "Private room" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "accommodates", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["accommodates"], + "value": "Int32(1)" + }, + "right": { + "path": ["accommodates"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "bathrooms_text", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["bathrooms_text"], + "value": "1 shared bath" + }, + "right": { + "path": ["bathrooms_text"], + "value": "1 shared bath" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "bedrooms", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["bedrooms"], + "value": "Int32(1)" + }, + "right": { + "path": ["bedrooms"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "beds", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["beds"], + "value": "Int32(1)" + }, + "right": { + "path": ["beds"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "amenities", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities"], + "value": [ + "Extra pillows and blankets", + "Oven", + "Fire extinguisher", + "Hair dryer", + "Hangers", + "Crib", + "Dishes and silverware", + "Luggage dropoff allowed", + "Essentials", + "Outlet covers", + "Patio or balcony", + "Shampoo", + "Free parking on premises", + "TV with standard cable", + "Free street parking", + "Cooking basics", + "Bed linens", + "Babysitter recommendations", + "Carbon monoxide alarm", + "Bathtub", + "Heating", + "Wifi", + "Building staff", + "Children’s books and toys", + "Coffee maker", + "Long term stays allowed", + "Pack ’n play/Travel crib", + "Refrigerator", + "Room-darkening shades", + "Iron", + "Kitchen", + "Stove", + "Lock on bedroom door", + "Hot water", + "Washer", + "Paid parking off premises", + "Children’s dinnerware", + "Smoke alarm", + "Ethernet connection", + "Dryer", + "Cable TV" + ] + }, + "right": { + "path": ["amenities"], + "value": [ + "Extra pillows and blankets", + "Oven", + "Fire extinguisher", + "Hair dryer", + "Hangers", + "Crib", + "Dishes and silverware", + "Luggage dropoff allowed", + "Essentials", + "Outlet covers", + "Patio or balcony", + "Shampoo", + "Free parking on premises", + "TV with standard cable", + "Free street parking", + "Cooking basics", + "Bed linens", + "Babysitter recommendations", + "Carbon monoxide alarm", + "Bathtub", + "Heating", + "Wifi", + "Building staff", + "Children’s books and toys", + "Coffee maker", + "Long term stays allowed", + "Pack ’n play/Travel crib", + "Refrigerator", + "Room-darkening shades", + "Iron", + "Kitchen", + "Stove", + "Lock on bedroom door", + "Hot water", + "Washer", + "Paid parking off premises", + "Children’s dinnerware", + "Smoke alarm", + "Ethernet connection", + "Dryer", + "Cable TV" + ] + }, + "items": [ + { + "implicitChangeType": "unchanged", + "index": 0, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 0], + "value": "Extra pillows and blankets" + }, + "right": { + "path": ["amenities", 0], + "value": "Extra pillows and blankets" + } + }, + { + "implicitChangeType": "unchanged", + "index": 1, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 1], + "value": "Oven" + }, + "right": { + "path": ["amenities", 1], + "value": "Oven" + } + }, + { + "implicitChangeType": "unchanged", + "index": 2, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 2], + "value": "Fire extinguisher" + }, + "right": { + "path": ["amenities", 2], + "value": "Fire extinguisher" + } + }, + { + "implicitChangeType": "unchanged", + "index": 3, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 3], + "value": "Hair dryer" + }, + "right": { + "path": ["amenities", 3], + "value": "Hair dryer" + } + }, + { + "implicitChangeType": "unchanged", + "index": 4, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 4], + "value": "Hangers" + }, + "right": { + "path": ["amenities", 4], + "value": "Hangers" + } + }, + { + "implicitChangeType": "unchanged", + "index": 5, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 5], + "value": "Crib" + }, + "right": { + "path": ["amenities", 5], + "value": "Crib" + } + }, + { + "implicitChangeType": "unchanged", + "index": 6, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 6], + "value": "Dishes and silverware" + }, + "right": { + "path": ["amenities", 6], + "value": "Dishes and silverware" + } + }, + { + "implicitChangeType": "unchanged", + "index": 7, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 7], + "value": "Luggage dropoff allowed" + }, + "right": { + "path": ["amenities", 7], + "value": "Luggage dropoff allowed" + } + }, + { + "implicitChangeType": "unchanged", + "index": 8, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 8], + "value": "Essentials" + }, + "right": { + "path": ["amenities", 8], + "value": "Essentials" + } + }, + { + "implicitChangeType": "unchanged", + "index": 9, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 9], + "value": "Outlet covers" + }, + "right": { + "path": ["amenities", 9], + "value": "Outlet covers" + } + }, + { + "implicitChangeType": "unchanged", + "index": 10, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 10], + "value": "Patio or balcony" + }, + "right": { + "path": ["amenities", 10], + "value": "Patio or balcony" + } + }, + { + "implicitChangeType": "unchanged", + "index": 11, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 11], + "value": "Shampoo" + }, + "right": { + "path": ["amenities", 11], + "value": "Shampoo" + } + }, + { + "implicitChangeType": "unchanged", + "index": 12, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 12], + "value": "Free parking on premises" + }, + "right": { + "path": ["amenities", 12], + "value": "Free parking on premises" + } + }, + { + "implicitChangeType": "unchanged", + "index": 13, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 13], + "value": "TV with standard cable" + }, + "right": { + "path": ["amenities", 13], + "value": "TV with standard cable" + } + }, + { + "implicitChangeType": "unchanged", + "index": 14, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 14], + "value": "Free street parking" + }, + "right": { + "path": ["amenities", 14], + "value": "Free street parking" + } + }, + { + "implicitChangeType": "unchanged", + "index": 15, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 15], + "value": "Cooking basics" + }, + "right": { + "path": ["amenities", 15], + "value": "Cooking basics" + } + }, + { + "implicitChangeType": "unchanged", + "index": 16, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 16], + "value": "Bed linens" + }, + "right": { + "path": ["amenities", 16], + "value": "Bed linens" + } + }, + { + "implicitChangeType": "unchanged", + "index": 17, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 17], + "value": "Babysitter recommendations" + }, + "right": { + "path": ["amenities", 17], + "value": "Babysitter recommendations" + } + }, + { + "implicitChangeType": "unchanged", + "index": 18, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 18], + "value": "Carbon monoxide alarm" + }, + "right": { + "path": ["amenities", 18], + "value": "Carbon monoxide alarm" + } + }, + { + "implicitChangeType": "unchanged", + "index": 19, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 19], + "value": "Bathtub" + }, + "right": { + "path": ["amenities", 19], + "value": "Bathtub" + } + }, + { + "implicitChangeType": "unchanged", + "index": 20, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 20], + "value": "Heating" + }, + "right": { + "path": ["amenities", 20], + "value": "Heating" + } + }, + { + "implicitChangeType": "unchanged", + "index": 21, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 21], + "value": "Wifi" + }, + "right": { + "path": ["amenities", 21], + "value": "Wifi" + } + }, + { + "implicitChangeType": "unchanged", + "index": 22, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 22], + "value": "Building staff" + }, + "right": { + "path": ["amenities", 22], + "value": "Building staff" + } + }, + { + "implicitChangeType": "unchanged", + "index": 23, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 23], + "value": "Children’s books and toys" + }, + "right": { + "path": ["amenities", 23], + "value": "Children’s books and toys" + } + }, + { + "implicitChangeType": "unchanged", + "index": 24, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 24], + "value": "Coffee maker" + }, + "right": { + "path": ["amenities", 24], + "value": "Coffee maker" + } + }, + { + "implicitChangeType": "unchanged", + "index": 25, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 25], + "value": "Long term stays allowed" + }, + "right": { + "path": ["amenities", 25], + "value": "Long term stays allowed" + } + }, + { + "implicitChangeType": "unchanged", + "index": 26, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 26], + "value": "Pack ’n play/Travel crib" + }, + "right": { + "path": ["amenities", 26], + "value": "Pack ’n play/Travel crib" + } + }, + { + "implicitChangeType": "unchanged", + "index": 27, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 27], + "value": "Refrigerator" + }, + "right": { + "path": ["amenities", 27], + "value": "Refrigerator" + } + }, + { + "implicitChangeType": "unchanged", + "index": 28, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 28], + "value": "Room-darkening shades" + }, + "right": { + "path": ["amenities", 28], + "value": "Room-darkening shades" + } + }, + { + "implicitChangeType": "unchanged", + "index": 29, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 29], + "value": "Iron" + }, + "right": { + "path": ["amenities", 29], + "value": "Iron" + } + }, + { + "implicitChangeType": "unchanged", + "index": 30, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 30], + "value": "Kitchen" + }, + "right": { + "path": ["amenities", 30], + "value": "Kitchen" + } + }, + { + "implicitChangeType": "unchanged", + "index": 31, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 31], + "value": "Stove" + }, + "right": { + "path": ["amenities", 31], + "value": "Stove" + } + }, + { + "implicitChangeType": "unchanged", + "index": 32, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 32], + "value": "Lock on bedroom door" + }, + "right": { + "path": ["amenities", 32], + "value": "Lock on bedroom door" + } + }, + { + "implicitChangeType": "unchanged", + "index": 33, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 33], + "value": "Hot water" + }, + "right": { + "path": ["amenities", 33], + "value": "Hot water" + } + }, + { + "implicitChangeType": "unchanged", + "index": 34, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 34], + "value": "Washer" + }, + "right": { + "path": ["amenities", 34], + "value": "Washer" + } + }, + { + "implicitChangeType": "unchanged", + "index": 35, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 35], + "value": "Paid parking off premises" + }, + "right": { + "path": ["amenities", 35], + "value": "Paid parking off premises" + } + }, + { + "implicitChangeType": "unchanged", + "index": 36, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 36], + "value": "Children’s dinnerware" + }, + "right": { + "path": ["amenities", 36], + "value": "Children’s dinnerware" + } + }, + { + "implicitChangeType": "unchanged", + "index": 37, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 37], + "value": "Smoke alarm" + }, + "right": { + "path": ["amenities", 37], + "value": "Smoke alarm" + } + }, + { + "implicitChangeType": "unchanged", + "index": 38, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 38], + "value": "Ethernet connection" + }, + "right": { + "path": ["amenities", 38], + "value": "Ethernet connection" + } + }, + { + "implicitChangeType": "unchanged", + "index": 39, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 39], + "value": "Dryer" + }, + "right": { + "path": ["amenities", 39], + "value": "Dryer" + } + }, + { + "implicitChangeType": "unchanged", + "index": 40, + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["amenities", 40], + "value": "Cable TV" + }, + "right": { + "path": ["amenities", 40], + "value": "Cable TV" + } + } + ] + }, + { + "implicitChangeType": "unchanged", + "objectKey": "price", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["price"], + "value": "$50.00" + }, + "right": { + "path": ["price"], + "value": "$50.00" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minimum_nights", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["minimum_nights"], + "value": "Int32(1)" + }, + "right": { + "path": ["minimum_nights"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maximum_nights", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["maximum_nights"], + "value": "Int32(29)" + }, + "right": { + "path": ["maximum_nights"], + "value": "Int32(29)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minimum_minimum_nights", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["minimum_minimum_nights"], + "value": "Int32(1)" + }, + "right": { + "path": ["minimum_minimum_nights"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maximum_minimum_nights", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["maximum_minimum_nights"], + "value": "Int32(1)" + }, + "right": { + "path": ["maximum_minimum_nights"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minimum_maximum_nights", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["minimum_maximum_nights"], + "value": "Int32(29)" + }, + "right": { + "path": ["minimum_maximum_nights"], + "value": "Int32(29)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maximum_maximum_nights", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["maximum_maximum_nights"], + "value": "Int32(29)" + }, + "right": { + "path": ["maximum_maximum_nights"], + "value": "Int32(29)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "minimum_nights_avg_ntm", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["minimum_nights_avg_ntm"], + "value": "Int32(1)" + }, + "right": { + "path": ["minimum_nights_avg_ntm"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "maximum_nights_avg_ntm", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["maximum_nights_avg_ntm"], + "value": "Int32(29)" + }, + "right": { + "path": ["maximum_nights_avg_ntm"], + "value": "Int32(29)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "has_availability", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["has_availability"], + "value": true + }, + "right": { + "path": ["has_availability"], + "value": true + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "availability_30", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["availability_30"], + "value": "Int32(17)" + }, + "right": { + "path": ["availability_30"], + "value": "Int32(17)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "availability_60", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["availability_60"], + "value": "Int32(38)" + }, + "right": { + "path": ["availability_60"], + "value": "Int32(38)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "availability_90", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["availability_90"], + "value": "Int32(68)" + }, + "right": { + "path": ["availability_90"], + "value": "Int32(68)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "availability_365", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["availability_365"], + "value": "Int32(343)" + }, + "right": { + "path": ["availability_365"], + "value": "Int32(343)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "calendar_last_scraped", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["calendar_last_scraped"], + "value": "2022-09-11T00:00:00.000Z" + }, + "right": { + "path": ["calendar_last_scraped"], + "value": "2022-09-11T00:00:00.000Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "number_of_reviews", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["number_of_reviews"], + "value": "Int32(30)" + }, + "right": { + "path": ["number_of_reviews"], + "value": "Int32(30)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "number_of_reviews_ltm", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["number_of_reviews_ltm"], + "value": "Int32(9)" + }, + "right": { + "path": ["number_of_reviews_ltm"], + "value": "Int32(9)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "number_of_reviews_l30d", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["number_of_reviews_l30d"], + "value": "Int32(0)" + }, + "right": { + "path": ["number_of_reviews_l30d"], + "value": "Int32(0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "first_review", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["first_review"], + "value": "2010-08-18T00:00:00.000Z" + }, + "right": { + "path": ["first_review"], + "value": "2010-08-18T00:00:00.000Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "last_review", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["last_review"], + "value": "2022-07-15T00:00:00.000Z" + }, + "right": { + "path": ["last_review"], + "value": "2022-07-15T00:00:00.000Z" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "review_scores_rating", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["review_scores_rating"], + "value": "Double(4.9)" + }, + "right": { + "path": ["review_scores_rating"], + "value": "Double(4.9)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "review_scores_accuracy", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["review_scores_accuracy"], + "value": "Double(4.82)" + }, + "right": { + "path": ["review_scores_accuracy"], + "value": "Double(4.82)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "review_scores_cleanliness", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["review_scores_cleanliness"], + "value": "Double(4.89)" + }, + "right": { + "path": ["review_scores_cleanliness"], + "value": "Double(4.89)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "review_scores_checkin", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["review_scores_checkin"], + "value": "Double(4.86)" + }, + "right": { + "path": ["review_scores_checkin"], + "value": "Double(4.86)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "review_scores_communication", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["review_scores_communication"], + "value": "Double(4.93)" + }, + "right": { + "path": ["review_scores_communication"], + "value": "Double(4.93)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "review_scores_location", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["review_scores_location"], + "value": "Double(4.75)" + }, + "right": { + "path": ["review_scores_location"], + "value": "Double(4.75)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "review_scores_value", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["review_scores_value"], + "value": "Double(4.82)" + }, + "right": { + "path": ["review_scores_value"], + "value": "Double(4.82)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "instant_bookable", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["instant_bookable"], + "value": false + }, + "right": { + "path": ["instant_bookable"], + "value": false + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "calculated_host_listings_count", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["calculated_host_listings_count"], + "value": "Int32(2)" + }, + "right": { + "path": ["calculated_host_listings_count"], + "value": "Int32(2)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "calculated_host_listings_count_entire_homes", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["calculated_host_listings_count_entire_homes"], + "value": "Int32(1)" + }, + "right": { + "path": ["calculated_host_listings_count_entire_homes"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "calculated_host_listings_count_private_rooms", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["calculated_host_listings_count_private_rooms"], + "value": "Int32(1)" + }, + "right": { + "path": ["calculated_host_listings_count_private_rooms"], + "value": "Int32(1)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "calculated_host_listings_count_shared_rooms", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["calculated_host_listings_count_shared_rooms"], + "value": "Int32(0)" + }, + "right": { + "path": ["calculated_host_listings_count_shared_rooms"], + "value": "Int32(0)" + } + }, + { + "implicitChangeType": "unchanged", + "objectKey": "reviews_per_month", + "delta": null, + "changeType": "unchanged", + "left": { + "path": ["reviews_per_month"], + "value": "Double(0.2)" + }, + "right": { + "path": ["reviews_per_month"], + "value": "Double(0.2)" + } + } + ] +} From 3e43385fdc39ef8a4d89cd6ccf6ba017eecb3695 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 13:07:45 +0000 Subject: [PATCH 03/23] leave space for expand/collapse buttons --- packages/compass-crud/src/components/bulk-update-dialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-crud/src/components/bulk-update-dialog.tsx b/packages/compass-crud/src/components/bulk-update-dialog.tsx index c1a398bcec3..eb768cb88d2 100644 --- a/packages/compass-crud/src/components/bulk-update-dialog.tsx +++ b/packages/compass-crud/src/components/bulk-update-dialog.tsx @@ -478,7 +478,7 @@ export default function BulkUpdateDialog({ } const previewCardStyles = css({ - padding: `${spacing[3]}px 0`, + padding: spacing[3], }); function UpdatePreviewDocument({ From b5392afe413579a8496ed81d9fd674589dcf85fe Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 13:25:22 +0000 Subject: [PATCH 04/23] css tweaks --- .../src/components/change-view/change-view.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx index 0f5fd016b5c..1547ca22309 100644 --- a/packages/compass-crud/src/components/change-view/change-view.tsx +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -87,13 +87,15 @@ const changeArrayItemStyles = css({ const changeKeyIndexStyles = css({ fontWeight: 'bold', - padding: `0 ${spacing[1]}px`, alignSelf: 'flex-start', }); const changeSummaryStyles = css({ display: 'inline-flex', alignItems: 'flex-start', + flexWrap: 'wrap', + columnGap: spacing[1], + rowGap: '1px', }); function getChangeSummaryClass(obj: UnifiedBranch, darkMode?: boolean) { @@ -188,7 +190,7 @@ function ChangeArrayItemObject({ item }: { item: ObjectItemBranch }) { } const changeLeafStyles = css({ - paddingLeft: spacing[1] + spacing[2] /* line up with expand/collapse */, + paddingLeft: spacing[3], }); function ChangeArrayItemLeaf({ item }: { item: ItemBranch }) { @@ -244,8 +246,7 @@ const changeArrayInlineWrapStyles = css({ const changeArrayInlineStyles = css({ marginLeft: spacing[4] + spacing[1], - display: - 'inline-flex' /* so the green/red background colour doesn't stretch all the way to the end */, + display: 'inline-flex', // so the green/red background colour doesn't stretch all the way to the end flexWrap: 'wrap', }); From 5e6caa312790a94e6dbb502518031c30e0b6bfe0 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 13:26:09 +0000 Subject: [PATCH 05/23] toBSON fixes --- .../src/components/change-view/bson-utils.ts | 3 ++ .../change-view/unified-document.spec.ts | 28 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/bson-utils.ts b/packages/compass-crud/src/components/change-view/bson-utils.ts index ea4d5bd0596..a6f3a74844a 100644 --- a/packages/compass-crud/src/components/change-view/bson-utils.ts +++ b/packages/compass-crud/src/components/change-view/bson-utils.ts @@ -31,6 +31,9 @@ export function unBSON(value: any | any[]): any | any[] { return mapped; } else if (value?._bsontype) { return stringifyBSON(value); + } else if (Object.prototype.toString.call(value) === '[object RegExp]') { + // make sure these match when diffing + return value.toString(); } else { return value; } diff --git a/packages/compass-crud/src/components/change-view/unified-document.spec.ts b/packages/compass-crud/src/components/change-view/unified-document.spec.ts index 1e589ad6e89..7366936eb2c 100644 --- a/packages/compass-crud/src/components/change-view/unified-document.spec.ts +++ b/packages/compass-crud/src/components/change-view/unified-document.spec.ts @@ -89,15 +89,27 @@ function checkAllPaths(obj: UnifiedBranch, before: Document, after: Document) { describe('unifyDocuments', function () { it('merges before and after documents into one structure', function () { - const before = { a: new ObjectId('642d766b7300158b1f22e972') }; - const after = { b: new ObjectId('642d766c7300158b1f22e975') }; + const before = { + a: new ObjectId('642d766b7300158b1f22e972'), + foo: /regex/i, + }; + const after = { + b: new ObjectId('642d766c7300158b1f22e975'), + foo: /regex/i, + }; const result = unifyDocuments(before, after); // this assertion checks the basic structure of the result expect(result).to.deep.equal({ - left: { path: [], value: { a: 'ObjectId("642d766b7300158b1f22e972")' } }, - right: { path: [], value: { b: 'ObjectId("642d766c7300158b1f22e975")' } }, + left: { + path: [], + value: { a: 'ObjectId("642d766b7300158b1f22e972")', foo: '/regex/i' }, + }, + right: { + path: [], + value: { b: 'ObjectId("642d766c7300158b1f22e975")', foo: '/regex/i' }, + }, delta: { a: ['ObjectId("642d766b7300158b1f22e972")', 0, 0], b: ['ObjectId("642d766c7300158b1f22e975")'], @@ -112,6 +124,14 @@ describe('unifyDocuments', function () { changeType: 'removed', left: { path: ['a'], value: 'ObjectId("642d766b7300158b1f22e972")' }, }, + { + implicitChangeType: 'unchanged', + objectKey: 'foo', + delta: null, + changeType: 'unchanged', + left: { path: ['foo'], value: '/regex/i' }, + right: { path: ['foo'], value: '/regex/i' }, + }, { implicitChangeType: 'unchanged', changeType: 'added', From 233776b7f9e1b0eaa854a8cc945dfd2d71001106 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 16:20:55 +0000 Subject: [PATCH 06/23] address TODOs --- .../components/change-view/change-view.tsx | 39 ++++++++----------- .../change-view/unified-document.ts | 2 - 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx index 1547ca22309..44e74062b27 100644 --- a/packages/compass-crud/src/components/change-view/change-view.tsx +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -34,7 +34,7 @@ type LeftRightContextType = { right: Document; }; -const expandButton = css({ +const expandButtonStyles = css({ margin: 0, padding: 0, border: 'none', @@ -45,6 +45,7 @@ const expandButton = css({ display: 'flex', alignSelf: 'center', color: 'inherit', + paddingRight: spacing[1], }); const addedStylesDark = css({ @@ -88,13 +89,13 @@ const changeArrayItemStyles = css({ const changeKeyIndexStyles = css({ fontWeight: 'bold', alignSelf: 'flex-start', + paddingRight: spacing[1], }); const changeSummaryStyles = css({ display: 'inline-flex', alignItems: 'flex-start', flexWrap: 'wrap', - columnGap: spacing[1], rowGap: '1px', }); @@ -132,7 +133,7 @@ function ChangeArrayItemArray({ item }: { item: ItemBranch }) { type="button" aria-pressed={isOpen} aria-label={isOpen ? 'Collapse field items' : 'Expand field items'} - className={expandButton} + className={expandButtonStyles} onClick={toggleIsOpen} > - getValueShape( - item.changeType === 'added' ? item.right.value : item.left.value - ) === 'leaf' - ) + obj.items.every((item) => { + const value = + item.changeType === 'added' ? item.right.value : item.left.value; + return ( + getValueShape(value) === 'leaf' && value?._bsontype === undefined + ); + }) ) { - // if it is an array containing just leaf values then we can special-case it and output it all on one line + // if it is an array containing just simple (ie. not bson) leaf values + // then we can special-case it and output it all on one line const classes = [changeArrayInlineStyles]; if (implicitChangeType === 'added') { @@ -336,7 +333,7 @@ function ChangeObjectPropertyObject({ type="button" aria-pressed={isOpen} aria-label={isOpen ? 'Collapse field items' : 'Expand field items'} - className={expandButton} + className={expandButtonStyles} onClick={toggleIsOpen} > Date: Fri, 8 Dec 2023 16:24:32 +0000 Subject: [PATCH 07/23] factor out expand button --- .../components/change-view/change-view.tsx | 72 +++++++------------ 1 file changed, 24 insertions(+), 48 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx index 44e74062b27..aeac6d85bda 100644 --- a/packages/compass-crud/src/components/change-view/change-view.tsx +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -112,6 +112,26 @@ function getChangeSummaryClass(obj: UnifiedBranch, darkMode?: boolean) { } } +function ExpandButton({ + isOpen, + toggleIsOpen, +}: { + isOpen: boolean; + toggleIsOpen: () => void; +}) { + return ( + + ); +} + function ChangeArrayItemArray({ item }: { item: ItemBranch }) { const [isOpen, setIsOpen] = useState( !!item.delta || item.changeType !== 'unchanged' @@ -129,18 +149,7 @@ function ChangeArrayItemArray({ item }: { item: ItemBranch }) { return (
- +
{item.index}:
@@ -168,18 +177,7 @@ function ChangeArrayItemObject({ item }: { item: ObjectItemBranch }) { return (
- +
{item.index}:
@@ -329,18 +327,7 @@ function ChangeObjectPropertyObject({ return (
- +
{property.objectKey}:
@@ -374,18 +361,7 @@ function ChangeObjectPropertyArray({ property }: { property: PropertyBranch }) { return (
- +
{property.objectKey}:
From b49de1bd30797d69981a8767cfbd58c871532fd0 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 16:32:03 +0000 Subject: [PATCH 08/23] fix bulk update e2e test --- packages/compass-e2e-tests/tests/collection-bulk-update.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts index 26566d1a4aa..8ede363ed6a 100644 --- a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts +++ b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts @@ -81,7 +81,7 @@ describe('Bulk Update', () => { .$(Selectors.BulkUpdatePreviewDocument + ':first-child') .getText(); console.log(text); - return /foo\s+:\s+"bar"/.test(text); + return /foo\s*:\s+"bar"/.test(text); }); // Press update From b10f7dfb860477a124d1b806c5202b9cab4f005f Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 16:34:16 +0000 Subject: [PATCH 09/23] depcheck --- packages/compass-crud/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/compass-crud/package.json b/packages/compass-crud/package.json index a28d5c1061d..55801bee906 100644 --- a/packages/compass-crud/package.json +++ b/packages/compass-crud/package.json @@ -92,6 +92,7 @@ "enzyme": "^3.11.0", "eslint": "^7.25.0", "hadron-app": "^5.16.2", + "jsondiffpatch": "^0.5.0", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-instance-model": "^12.16.3", @@ -118,7 +119,6 @@ "hadron-app-registry": "^9.1.1", "hadron-document": "^8.4.4", "hadron-type-checker": "^7.1.1", - "mongodb-data-service": "^22.16.2", - "jsondiffpatch": "^0.5.0" + "mongodb-data-service": "^22.16.2" } } From a90f1f9249cd42f029da80f79c68b483cce03503 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Fri, 8 Dec 2023 16:46:22 +0000 Subject: [PATCH 10/23] unit tests for ChangeView component --- .../change-view/change-view.spec.tsx | 45 +++++++++++++++++++ .../components/change-view/change-view.tsx | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 packages/compass-crud/src/components/change-view/change-view.spec.tsx diff --git a/packages/compass-crud/src/components/change-view/change-view.spec.tsx b/packages/compass-crud/src/components/change-view/change-view.spec.tsx new file mode 100644 index 00000000000..bfb5dc8e0f0 --- /dev/null +++ b/packages/compass-crud/src/components/change-view/change-view.spec.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { expect } from 'chai'; +import { render, screen, cleanup } from '@testing-library/react'; +import { ChangeView } from './change-view'; +import { fixtureGroups } from '../../../test/before-after-fixtures'; + +function renderChangeView( + props?: Partial> +) { + return render(); +} + +describe('ChangeView Component', function () { + afterEach(function () { + cleanup(); + }); + + it('renders', function () { + renderChangeView({ + before: { a: 1 }, + after: { b: 2 }, + }); + + expect(screen.getByTestId('change-view-test')).to.exist; + }); + + for (const group of fixtureGroups) { + context(group.name, function () { + for (const { name, before, after } of group.fixtures) { + it(name, function () { + renderChangeView({ + name, + before, + after, + }); + + // A bit primitive. Just trying to see if there are any errors as a + // sort of regression test. Not sure how to write an assertion that + // would workfor each one. + expect(screen.getByTestId(`change-view-${name}`)).to.exist; + }); + } + }); + } +}); diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx index aeac6d85bda..a35a5b2885b 100644 --- a/packages/compass-crud/src/components/change-view/change-view.tsx +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -578,7 +578,7 @@ export function ChangeView({ changeViewStyles, darkMode ? changeViewStylesDark : changeViewStylesLight )} - data-testid={`change-view-{${name}}`} + data-testid={`change-view-${name}`} >
From 675737ca572b036d5e3be6caa03fc7deb1d4930c Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 11 Dec 2023 10:48:20 +0000 Subject: [PATCH 11/23] address TODO --- .../src/components/change-view/bson-utils.ts | 10 +- .../change-view/unified-document.spec.ts | 26 +- .../all_types_all_types_add.json | 94 +++--- .../all_types_all_types_changed.json | 177 +++++----- .../all_types_all_types_identical.json | 124 +++---- .../all_types_all_types_remove.json | 92 +++--- .../all_types_small_change.json | 124 +++---- .../fixture-results/bson_type_change.json | 10 +- .../fixture-results/stress_tests_airbnb.json | 304 +++++++++--------- 9 files changed, 484 insertions(+), 477 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/bson-utils.ts b/packages/compass-crud/src/components/change-view/bson-utils.ts index a6f3a74844a..b461f363fac 100644 --- a/packages/compass-crud/src/components/change-view/bson-utils.ts +++ b/packages/compass-crud/src/components/change-view/bson-utils.ts @@ -4,15 +4,7 @@ import { isSimpleObject } from './shape-utils'; export function stringifyBSON(value: any) { if (value?.inspect) { - // TODO: This is a temporary hack - we'd use our existing formatters to - // output colourful/rich previews of values, not just plain text and we - // don't need this behaviour in unBSON() anyway - it doesn't matter that - // jsondiffpatch sees `new ` when diffing. - const s = value.inspect(); - if (s.startsWith('new ')) { - return s.slice(4); - } - return s; + return value.inspect(); } if (value?.toISOString) { return value.toISOString(); diff --git a/packages/compass-crud/src/components/change-view/unified-document.spec.ts b/packages/compass-crud/src/components/change-view/unified-document.spec.ts index 7366936eb2c..535e57e5a74 100644 --- a/packages/compass-crud/src/components/change-view/unified-document.spec.ts +++ b/packages/compass-crud/src/components/change-view/unified-document.spec.ts @@ -104,15 +104,21 @@ describe('unifyDocuments', function () { expect(result).to.deep.equal({ left: { path: [], - value: { a: 'ObjectId("642d766b7300158b1f22e972")', foo: '/regex/i' }, + value: { + a: 'new ObjectId("642d766b7300158b1f22e972")', + foo: '/regex/i', + }, }, right: { path: [], - value: { b: 'ObjectId("642d766c7300158b1f22e975")', foo: '/regex/i' }, + value: { + b: 'new ObjectId("642d766c7300158b1f22e975")', + foo: '/regex/i', + }, }, delta: { - a: ['ObjectId("642d766b7300158b1f22e972")', 0, 0], - b: ['ObjectId("642d766c7300158b1f22e975")'], + a: ['new ObjectId("642d766b7300158b1f22e972")', 0, 0], + b: ['new ObjectId("642d766c7300158b1f22e975")'], }, implicitChangeType: 'unchanged', changeType: 'unchanged', @@ -122,7 +128,10 @@ describe('unifyDocuments', function () { objectKey: 'a', delta: null, changeType: 'removed', - left: { path: ['a'], value: 'ObjectId("642d766b7300158b1f22e972")' }, + left: { + path: ['a'], + value: 'new ObjectId("642d766b7300158b1f22e972")', + }, }, { implicitChangeType: 'unchanged', @@ -136,7 +145,10 @@ describe('unifyDocuments', function () { implicitChangeType: 'unchanged', changeType: 'added', objectKey: 'b', - right: { path: ['b'], value: 'ObjectId("642d766c7300158b1f22e975")' }, + right: { + path: ['b'], + value: 'new ObjectId("642d766c7300158b1f22e975")', + }, delta: null, }, ], @@ -166,8 +178,6 @@ describe('unifyDocuments', function () { filename ); - await fs.writeFile(expectedPath, json, 'utf8'); - let expectedText: string; try { expectedText = await fs.readFile(expectedPath, 'utf8'); diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_add.json b/packages/compass-crud/test/fixture-results/all_types_all_types_add.json index 46974653880..e2232f8cff3 100644 --- a/packages/compass-crud/test/fixture-results/all_types_all_types_add.json +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_add.json @@ -6,45 +6,45 @@ "right": { "path": [], "value": { - "_id": "ObjectId(\"642d766b7300158b1f22e972\")", - "double": "Double(1.2)", + "_id": "new ObjectId(\"642d766b7300158b1f22e972\")", + "double": "new Double(1.2)", "string": "Hello, world!", "object": { "key": "value" }, "array": [1, 2, 3], "binData": "Binary.createFromBase64(\"AQID\", 0)", - "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "objectId": "new ObjectId(\"642d766c7300158b1f22e975\")", "boolean": true, "date": "2023-04-05T13:25:08.445Z", "null": null, - "regex": "BSONRegExp(\"pattern\", \"i\")", - "javascript": "Code(\"function() {}\")", - "symbol": "BSONSymbol(\"symbol\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "int": "Int32(12345)", - "timestamp": "Timestamp({ t: 1680701109, i: 1 })", - "long": "Long(\"123456789123456789\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"pattern\", \"i\")", + "javascript": "new Code(\"function() {}\")", + "symbol": "new BSONSymbol(\"symbol\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "new Int32(12345)", + "timestamp": "new Timestamp({ t: 1680701109, i: 1 })", + "long": "new Long(\"123456789123456789\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } }, "delta": { - "_id": ["ObjectId(\"642d766b7300158b1f22e972\")"], - "double": ["Double(1.2)"], + "_id": ["new ObjectId(\"642d766b7300158b1f22e972\")"], + "double": ["new Double(1.2)"], "string": ["Hello, world!"], "object": [ { @@ -53,29 +53,31 @@ ], "array": [[1, 2, 3]], "binData": ["Binary.createFromBase64(\"AQID\", 0)"], - "objectId": ["ObjectId(\"642d766c7300158b1f22e975\")"], + "objectId": ["new ObjectId(\"642d766c7300158b1f22e975\")"], "boolean": [true], "date": ["2023-04-05T13:25:08.445Z"], "null": [null], - "regex": ["BSONRegExp(\"pattern\", \"i\")"], - "javascript": ["Code(\"function() {}\")"], - "symbol": ["BSONSymbol(\"symbol\")"], + "regex": ["new BSONRegExp(\"pattern\", \"i\")"], + "javascript": ["new Code(\"function() {}\")"], + "symbol": ["new BSONSymbol(\"symbol\")"], "javascriptWithScope": [ - "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" ], - "int": ["Int32(12345)"], - "timestamp": ["Timestamp({ t: 1680701109, i: 1 })"], - "long": ["Long(\"123456789123456789\")"], - "decimal": ["Decimal128(\"5.477284286264328586719275128128001E-4088\")"], - "minKey": ["MinKey()"], - "maxKey": ["MaxKey()"], + "int": ["new Int32(12345)"], + "timestamp": ["new Timestamp({ t: 1680701109, i: 1 })"], + "long": ["new Long(\"123456789123456789\")"], + "decimal": [ + "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" + ], + "minKey": ["new MinKey()"], + "maxKey": ["new MaxKey()"], "binaries": [ { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -83,7 +85,7 @@ } ], "dbRef": [ - "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" ] }, "implicitChangeType": "unchanged", @@ -95,7 +97,7 @@ "objectKey": "_id", "right": { "path": ["_id"], - "value": "ObjectId(\"642d766b7300158b1f22e972\")" + "value": "new ObjectId(\"642d766b7300158b1f22e972\")" }, "delta": null }, @@ -105,7 +107,7 @@ "objectKey": "double", "right": { "path": ["double"], - "value": "Double(1.2)" + "value": "new Double(1.2)" }, "delta": null }, @@ -201,7 +203,7 @@ "objectKey": "objectId", "right": { "path": ["objectId"], - "value": "ObjectId(\"642d766c7300158b1f22e975\")" + "value": "new ObjectId(\"642d766c7300158b1f22e975\")" }, "delta": null }, @@ -241,7 +243,7 @@ "objectKey": "regex", "right": { "path": ["regex"], - "value": "BSONRegExp(\"pattern\", \"i\")" + "value": "new BSONRegExp(\"pattern\", \"i\")" }, "delta": null }, @@ -251,7 +253,7 @@ "objectKey": "javascript", "right": { "path": ["javascript"], - "value": "Code(\"function() {}\")" + "value": "new Code(\"function() {}\")" }, "delta": null }, @@ -261,7 +263,7 @@ "objectKey": "symbol", "right": { "path": ["symbol"], - "value": "BSONSymbol(\"symbol\")" + "value": "new BSONSymbol(\"symbol\")" }, "delta": null }, @@ -271,7 +273,7 @@ "objectKey": "javascriptWithScope", "right": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "value": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" }, "delta": null }, @@ -281,7 +283,7 @@ "objectKey": "int", "right": { "path": ["int"], - "value": "Int32(12345)" + "value": "new Int32(12345)" }, "delta": null }, @@ -291,7 +293,7 @@ "objectKey": "timestamp", "right": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 1 })" + "value": "new Timestamp({ t: 1680701109, i: 1 })" }, "delta": null }, @@ -301,7 +303,7 @@ "objectKey": "long", "right": { "path": ["long"], - "value": "Long(\"123456789123456789\")" + "value": "new Long(\"123456789123456789\")" }, "delta": null }, @@ -311,7 +313,7 @@ "objectKey": "decimal", "right": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" }, "delta": null }, @@ -321,7 +323,7 @@ "objectKey": "minKey", "right": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" }, "delta": null }, @@ -331,7 +333,7 @@ "objectKey": "maxKey", "right": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" }, "delta": null }, @@ -346,7 +348,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -402,7 +404,7 @@ "changeType": "added", "right": { "path": ["binaries", "uuid"], - "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + "value": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" } }, { @@ -453,7 +455,7 @@ "objectKey": "dbRef", "right": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" }, "delta": null } diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_changed.json b/packages/compass-crud/test/fixture-results/all_types_all_types_changed.json index bd786587865..bfa6fe0aec2 100644 --- a/packages/compass-crud/test/fixture-results/all_types_all_types_changed.json +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_changed.json @@ -2,87 +2,87 @@ "left": { "path": [], "value": { - "_id": "ObjectId(\"642d766b7300158b1f22e972\")", - "double": "Double(1.2)", + "_id": "new ObjectId(\"642d766b7300158b1f22e972\")", + "double": "new Double(1.2)", "string": "Hello, world!", "object": { "key": "value" }, "array": [1, 2, 3], "binData": "Binary.createFromBase64(\"AQID\", 0)", - "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "objectId": "new ObjectId(\"642d766c7300158b1f22e975\")", "boolean": true, "date": "2023-04-05T13:25:08.445Z", "null": null, - "regex": "BSONRegExp(\"pattern\", \"i\")", - "javascript": "Code(\"function() {}\")", - "symbol": "BSONSymbol(\"symbol\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "int": "Int32(12345)", - "timestamp": "Timestamp({ t: 1680701109, i: 1 })", - "long": "Long(\"123456789123456789\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"pattern\", \"i\")", + "javascript": "new Code(\"function() {}\")", + "symbol": "new BSONSymbol(\"symbol\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "new Int32(12345)", + "timestamp": "new Timestamp({ t: 1680701109, i: 1 })", + "long": "new Long(\"123456789123456789\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } }, "right": { "path": [], "value": { - "_id": "ObjectId(\"6564759d220c47fd4c97379c\")", - "double": "Double(1.3)", + "_id": "new ObjectId(\"6564759d220c47fd4c97379c\")", + "double": "new Double(1.3)", "string": "oh no!", "object": { "foo": "bar" }, "array": [1, 2, 3, 4], "binData": "Binary.createFromBase64(\"AQIDBA==\", 0)", - "objectId": "ObjectId(\"656475ac220c47fd4c97379d\")", + "objectId": "new ObjectId(\"656475ac220c47fd4c97379d\")", "boolean": false, "date": "2023-04-05T13:25:08.446Z", "null": null, - "regex": "BSONRegExp(\"patterns\", \"i\")", - "javascript": "Code(\"function() { /* woop */ }\")", - "symbol": "BSONSymbol(\"symbols are deprecated\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})", - "int": "Int32(123456)", - "timestamp": "Timestamp({ t: 1680701109, i: 2 })", - "long": "Long(\"1234567891234567890\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-3960\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"patterns\", \"i\")", + "javascript": "new Code(\"function() { /* woop */ }\")", + "symbol": "new BSONSymbol(\"symbols are deprecated\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})", + "int": "new Int32(123456)", + "timestamp": "new Timestamp({ t: 1680701109, i: 2 })", + "long": "new Long(\"1234567891234567890\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-3960\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQIDBA==\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PSA=\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PSA=\", 2)", "uuidOld": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)", - "uuid": "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")", + "uuid": "new UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")", "md5": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 5)", "encrypted": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 7)", "custom": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" } }, "delta": { "_id": [ - "ObjectId(\"642d766b7300158b1f22e972\")", - "ObjectId(\"6564759d220c47fd4c97379c\")" + "new ObjectId(\"642d766b7300158b1f22e972\")", + "new ObjectId(\"6564759d220c47fd4c97379c\")" ], - "double": ["Double(1.2)", "Double(1.3)"], + "double": ["new Double(1.2)", "new Double(1.3)"], "string": ["Hello, world!", "oh no!"], "object": { "key": ["value", 0, 0], @@ -97,36 +97,39 @@ "Binary.createFromBase64(\"AQIDBA==\", 0)" ], "objectId": [ - "ObjectId(\"642d766c7300158b1f22e975\")", - "ObjectId(\"656475ac220c47fd4c97379d\")" + "new ObjectId(\"642d766c7300158b1f22e975\")", + "new ObjectId(\"656475ac220c47fd4c97379d\")" ], "boolean": [true, false], "date": ["2023-04-05T13:25:08.445Z", "2023-04-05T13:25:08.446Z"], "regex": [ - "BSONRegExp(\"pattern\", \"i\")", - "BSONRegExp(\"patterns\", \"i\")" + "new BSONRegExp(\"pattern\", \"i\")", + "new BSONRegExp(\"patterns\", \"i\")" ], "javascript": [ - "Code(\"function() {}\")", - "Code(\"function() { /* woop */ }\")" + "new Code(\"function() {}\")", + "new Code(\"function() { /* woop */ }\")" ], "symbol": [ - "BSONSymbol(\"symbol\")", - "BSONSymbol(\"symbols are deprecated\")" + "new BSONSymbol(\"symbol\")", + "new BSONSymbol(\"symbols are deprecated\")" ], "javascriptWithScope": [ - "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})" + "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "new Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})" ], - "int": ["Int32(12345)", "Int32(123456)"], + "int": ["new Int32(12345)", "new Int32(123456)"], "timestamp": [ - "Timestamp({ t: 1680701109, i: 1 })", - "Timestamp({ t: 1680701109, i: 2 })" + "new Timestamp({ t: 1680701109, i: 1 })", + "new Timestamp({ t: 1680701109, i: 2 })" + ], + "long": [ + "new Long(\"123456789123456789\")", + "new Long(\"1234567891234567890\")" ], - "long": ["Long(\"123456789123456789\")", "Long(\"1234567891234567890\")"], "decimal": [ - "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "Decimal128(\"5.477284286264328586719275128128001E-3960\")" + "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "new Decimal128(\"5.477284286264328586719275128128001E-3960\")" ], "binaries": { "generic": [ @@ -146,8 +149,8 @@ "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)" ], "uuid": [ - "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", - "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" + "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "new UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" ], "md5": [ "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", @@ -167,8 +170,8 @@ ] }, "dbRef": [ - "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))", - "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" + "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))", + "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" ] }, "implicitChangeType": "unchanged", @@ -181,11 +184,11 @@ "changeType": "changed", "left": { "path": ["_id"], - "value": "ObjectId(\"642d766b7300158b1f22e972\")" + "value": "new ObjectId(\"642d766b7300158b1f22e972\")" }, "right": { "path": ["_id"], - "value": "ObjectId(\"6564759d220c47fd4c97379c\")" + "value": "new ObjectId(\"6564759d220c47fd4c97379c\")" } }, { @@ -195,11 +198,11 @@ "changeType": "changed", "left": { "path": ["double"], - "value": "Double(1.2)" + "value": "new Double(1.2)" }, "right": { "path": ["double"], - "value": "Double(1.3)" + "value": "new Double(1.3)" } }, { @@ -351,11 +354,11 @@ "changeType": "changed", "left": { "path": ["objectId"], - "value": "ObjectId(\"642d766c7300158b1f22e975\")" + "value": "new ObjectId(\"642d766c7300158b1f22e975\")" }, "right": { "path": ["objectId"], - "value": "ObjectId(\"656475ac220c47fd4c97379d\")" + "value": "new ObjectId(\"656475ac220c47fd4c97379d\")" } }, { @@ -407,11 +410,11 @@ "changeType": "changed", "left": { "path": ["regex"], - "value": "BSONRegExp(\"pattern\", \"i\")" + "value": "new BSONRegExp(\"pattern\", \"i\")" }, "right": { "path": ["regex"], - "value": "BSONRegExp(\"patterns\", \"i\")" + "value": "new BSONRegExp(\"patterns\", \"i\")" } }, { @@ -421,11 +424,11 @@ "changeType": "changed", "left": { "path": ["javascript"], - "value": "Code(\"function() {}\")" + "value": "new Code(\"function() {}\")" }, "right": { "path": ["javascript"], - "value": "Code(\"function() { /* woop */ }\")" + "value": "new Code(\"function() { /* woop */ }\")" } }, { @@ -435,11 +438,11 @@ "changeType": "changed", "left": { "path": ["symbol"], - "value": "BSONSymbol(\"symbol\")" + "value": "new BSONSymbol(\"symbol\")" }, "right": { "path": ["symbol"], - "value": "BSONSymbol(\"symbols are deprecated\")" + "value": "new BSONSymbol(\"symbols are deprecated\")" } }, { @@ -449,11 +452,11 @@ "changeType": "changed", "left": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "value": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" }, "right": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})" + "value": "new Code(\"function() {}\", {\"foo\":\"a\",\"bar\":\"1\"})" } }, { @@ -463,11 +466,11 @@ "changeType": "changed", "left": { "path": ["int"], - "value": "Int32(12345)" + "value": "new Int32(12345)" }, "right": { "path": ["int"], - "value": "Int32(123456)" + "value": "new Int32(123456)" } }, { @@ -477,11 +480,11 @@ "changeType": "changed", "left": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 1 })" + "value": "new Timestamp({ t: 1680701109, i: 1 })" }, "right": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 2 })" + "value": "new Timestamp({ t: 1680701109, i: 2 })" } }, { @@ -491,11 +494,11 @@ "changeType": "changed", "left": { "path": ["long"], - "value": "Long(\"123456789123456789\")" + "value": "new Long(\"123456789123456789\")" }, "right": { "path": ["long"], - "value": "Long(\"1234567891234567890\")" + "value": "new Long(\"1234567891234567890\")" } }, { @@ -505,11 +508,11 @@ "changeType": "changed", "left": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" }, "right": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-3960\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-3960\")" } }, { @@ -519,11 +522,11 @@ "changeType": "unchanged", "left": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" }, "right": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" } }, { @@ -533,11 +536,11 @@ "changeType": "unchanged", "left": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" }, "right": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" } }, { @@ -561,8 +564,8 @@ "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)" ], "uuid": [ - "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", - "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" + "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "new UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" ], "md5": [ "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", @@ -589,7 +592,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -603,7 +606,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PSA=\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PSA=\", 2)", "uuidOld": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 3)", - "uuid": "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")", + "uuid": "new UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")", "md5": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 5)", "encrypted": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=\", 7)", @@ -674,11 +677,11 @@ "changeType": "changed", "left": { "path": ["binaries", "uuid"], - "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + "value": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" }, "right": { "path": ["binaries", "uuid"], - "value": "UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" + "value": "new UUID(\"0e1f691e-d3ed-45d8-a151-cb9c995c50ff\")" } }, { @@ -746,11 +749,11 @@ "changeType": "changed", "left": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" }, "right": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a79\"))" } } ] diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_identical.json b/packages/compass-crud/test/fixture-results/all_types_all_types_identical.json index 0b112775963..f885280869a 100644 --- a/packages/compass-crud/test/fixture-results/all_types_all_types_identical.json +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_identical.json @@ -2,79 +2,79 @@ "left": { "path": [], "value": { - "_id": "ObjectId(\"642d766b7300158b1f22e972\")", - "double": "Double(1.2)", + "_id": "new ObjectId(\"642d766b7300158b1f22e972\")", + "double": "new Double(1.2)", "string": "Hello, world!", "object": { "key": "value" }, "array": [1, 2, 3], "binData": "Binary.createFromBase64(\"AQID\", 0)", - "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "objectId": "new ObjectId(\"642d766c7300158b1f22e975\")", "boolean": true, "date": "2023-04-05T13:25:08.445Z", "null": null, - "regex": "BSONRegExp(\"pattern\", \"i\")", - "javascript": "Code(\"function() {}\")", - "symbol": "BSONSymbol(\"symbol\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "int": "Int32(12345)", - "timestamp": "Timestamp({ t: 1680701109, i: 1 })", - "long": "Long(\"123456789123456789\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"pattern\", \"i\")", + "javascript": "new Code(\"function() {}\")", + "symbol": "new BSONSymbol(\"symbol\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "new Int32(12345)", + "timestamp": "new Timestamp({ t: 1680701109, i: 1 })", + "long": "new Long(\"123456789123456789\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } }, "right": { "path": [], "value": { - "_id": "ObjectId(\"642d766b7300158b1f22e972\")", - "double": "Double(1.2)", + "_id": "new ObjectId(\"642d766b7300158b1f22e972\")", + "double": "new Double(1.2)", "string": "Hello, world!", "object": { "key": "value" }, "array": [1, 2, 3], "binData": "Binary.createFromBase64(\"AQID\", 0)", - "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "objectId": "new ObjectId(\"642d766c7300158b1f22e975\")", "boolean": true, "date": "2023-04-05T13:25:08.445Z", "null": null, - "regex": "BSONRegExp(\"pattern\", \"i\")", - "javascript": "Code(\"function() {}\")", - "symbol": "BSONSymbol(\"symbol\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "int": "Int32(12345)", - "timestamp": "Timestamp({ t: 1680701109, i: 1 })", - "long": "Long(\"123456789123456789\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"pattern\", \"i\")", + "javascript": "new Code(\"function() {}\")", + "symbol": "new BSONSymbol(\"symbol\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "new Int32(12345)", + "timestamp": "new Timestamp({ t: 1680701109, i: 1 })", + "long": "new Long(\"123456789123456789\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } }, "delta": null, @@ -88,11 +88,11 @@ "changeType": "unchanged", "left": { "path": ["_id"], - "value": "ObjectId(\"642d766b7300158b1f22e972\")" + "value": "new ObjectId(\"642d766b7300158b1f22e972\")" }, "right": { "path": ["_id"], - "value": "ObjectId(\"642d766b7300158b1f22e972\")" + "value": "new ObjectId(\"642d766b7300158b1f22e972\")" } }, { @@ -102,11 +102,11 @@ "changeType": "unchanged", "left": { "path": ["double"], - "value": "Double(1.2)" + "value": "new Double(1.2)" }, "right": { "path": ["double"], - "value": "Double(1.2)" + "value": "new Double(1.2)" } }, { @@ -236,11 +236,11 @@ "changeType": "unchanged", "left": { "path": ["objectId"], - "value": "ObjectId(\"642d766c7300158b1f22e975\")" + "value": "new ObjectId(\"642d766c7300158b1f22e975\")" }, "right": { "path": ["objectId"], - "value": "ObjectId(\"642d766c7300158b1f22e975\")" + "value": "new ObjectId(\"642d766c7300158b1f22e975\")" } }, { @@ -292,11 +292,11 @@ "changeType": "unchanged", "left": { "path": ["regex"], - "value": "BSONRegExp(\"pattern\", \"i\")" + "value": "new BSONRegExp(\"pattern\", \"i\")" }, "right": { "path": ["regex"], - "value": "BSONRegExp(\"pattern\", \"i\")" + "value": "new BSONRegExp(\"pattern\", \"i\")" } }, { @@ -306,11 +306,11 @@ "changeType": "unchanged", "left": { "path": ["javascript"], - "value": "Code(\"function() {}\")" + "value": "new Code(\"function() {}\")" }, "right": { "path": ["javascript"], - "value": "Code(\"function() {}\")" + "value": "new Code(\"function() {}\")" } }, { @@ -320,11 +320,11 @@ "changeType": "unchanged", "left": { "path": ["symbol"], - "value": "BSONSymbol(\"symbol\")" + "value": "new BSONSymbol(\"symbol\")" }, "right": { "path": ["symbol"], - "value": "BSONSymbol(\"symbol\")" + "value": "new BSONSymbol(\"symbol\")" } }, { @@ -334,11 +334,11 @@ "changeType": "unchanged", "left": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "value": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" }, "right": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "value": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" } }, { @@ -348,11 +348,11 @@ "changeType": "unchanged", "left": { "path": ["int"], - "value": "Int32(12345)" + "value": "new Int32(12345)" }, "right": { "path": ["int"], - "value": "Int32(12345)" + "value": "new Int32(12345)" } }, { @@ -362,11 +362,11 @@ "changeType": "unchanged", "left": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 1 })" + "value": "new Timestamp({ t: 1680701109, i: 1 })" }, "right": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 1 })" + "value": "new Timestamp({ t: 1680701109, i: 1 })" } }, { @@ -376,11 +376,11 @@ "changeType": "unchanged", "left": { "path": ["long"], - "value": "Long(\"123456789123456789\")" + "value": "new Long(\"123456789123456789\")" }, "right": { "path": ["long"], - "value": "Long(\"123456789123456789\")" + "value": "new Long(\"123456789123456789\")" } }, { @@ -390,11 +390,11 @@ "changeType": "unchanged", "left": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" }, "right": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" } }, { @@ -404,11 +404,11 @@ "changeType": "unchanged", "left": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" }, "right": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" } }, { @@ -418,11 +418,11 @@ "changeType": "unchanged", "left": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" }, "right": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" } }, { @@ -437,7 +437,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -451,7 +451,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -522,11 +522,11 @@ "changeType": "unchanged", "left": { "path": ["binaries", "uuid"], - "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + "value": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" }, "right": { "path": ["binaries", "uuid"], - "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + "value": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" } }, { @@ -594,11 +594,11 @@ "changeType": "unchanged", "left": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" }, "right": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } } ] diff --git a/packages/compass-crud/test/fixture-results/all_types_all_types_remove.json b/packages/compass-crud/test/fixture-results/all_types_all_types_remove.json index da3113d79a7..06cd28ff568 100644 --- a/packages/compass-crud/test/fixture-results/all_types_all_types_remove.json +++ b/packages/compass-crud/test/fixture-results/all_types_all_types_remove.json @@ -2,40 +2,40 @@ "left": { "path": [], "value": { - "_id": "ObjectId(\"642d766b7300158b1f22e972\")", - "double": "Double(1.2)", + "_id": "new ObjectId(\"642d766b7300158b1f22e972\")", + "double": "new Double(1.2)", "string": "Hello, world!", "object": { "key": "value" }, "array": [1, 2, 3], "binData": "Binary.createFromBase64(\"AQID\", 0)", - "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "objectId": "new ObjectId(\"642d766c7300158b1f22e975\")", "boolean": true, "date": "2023-04-05T13:25:08.445Z", "null": null, - "regex": "BSONRegExp(\"pattern\", \"i\")", - "javascript": "Code(\"function() {}\")", - "symbol": "BSONSymbol(\"symbol\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "int": "Int32(12345)", - "timestamp": "Timestamp({ t: 1680701109, i: 1 })", - "long": "Long(\"123456789123456789\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"pattern\", \"i\")", + "javascript": "new Code(\"function() {}\")", + "symbol": "new BSONSymbol(\"symbol\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "new Int32(12345)", + "timestamp": "new Timestamp({ t: 1680701109, i: 1 })", + "long": "new Long(\"123456789123456789\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } }, "right": { @@ -43,8 +43,8 @@ "value": {} }, "delta": { - "_id": ["ObjectId(\"642d766b7300158b1f22e972\")", 0, 0], - "double": ["Double(1.2)", 0, 0], + "_id": ["new ObjectId(\"642d766b7300158b1f22e972\")", 0, 0], + "double": ["new Double(1.2)", 0, 0], "string": ["Hello, world!", 0, 0], "object": [ { @@ -55,35 +55,35 @@ ], "array": [[1, 2, 3], 0, 0], "binData": ["Binary.createFromBase64(\"AQID\", 0)", 0, 0], - "objectId": ["ObjectId(\"642d766c7300158b1f22e975\")", 0, 0], + "objectId": ["new ObjectId(\"642d766c7300158b1f22e975\")", 0, 0], "boolean": [true, 0, 0], "date": ["2023-04-05T13:25:08.445Z", 0, 0], "null": [null, 0, 0], - "regex": ["BSONRegExp(\"pattern\", \"i\")", 0, 0], - "javascript": ["Code(\"function() {}\")", 0, 0], - "symbol": ["BSONSymbol(\"symbol\")", 0, 0], + "regex": ["new BSONRegExp(\"pattern\", \"i\")", 0, 0], + "javascript": ["new Code(\"function() {}\")", 0, 0], + "symbol": ["new BSONSymbol(\"symbol\")", 0, 0], "javascriptWithScope": [ - "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", 0, 0 ], - "int": ["Int32(12345)", 0, 0], - "timestamp": ["Timestamp({ t: 1680701109, i: 1 })", 0, 0], - "long": ["Long(\"123456789123456789\")", 0, 0], + "int": ["new Int32(12345)", 0, 0], + "timestamp": ["new Timestamp({ t: 1680701109, i: 1 })", 0, 0], + "long": ["new Long(\"123456789123456789\")", 0, 0], "decimal": [ - "Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", 0, 0 ], - "minKey": ["MinKey()", 0, 0], - "maxKey": ["MaxKey()", 0, 0], + "minKey": ["new MinKey()", 0, 0], + "maxKey": ["new MaxKey()", 0, 0], "binaries": [ { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -93,7 +93,7 @@ 0 ], "dbRef": [ - "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))", + "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))", 0, 0 ] @@ -108,7 +108,7 @@ "changeType": "removed", "left": { "path": ["_id"], - "value": "ObjectId(\"642d766b7300158b1f22e972\")" + "value": "new ObjectId(\"642d766b7300158b1f22e972\")" } }, { @@ -118,7 +118,7 @@ "changeType": "removed", "left": { "path": ["double"], - "value": "Double(1.2)" + "value": "new Double(1.2)" } }, { @@ -214,7 +214,7 @@ "changeType": "removed", "left": { "path": ["objectId"], - "value": "ObjectId(\"642d766c7300158b1f22e975\")" + "value": "new ObjectId(\"642d766c7300158b1f22e975\")" } }, { @@ -254,7 +254,7 @@ "changeType": "removed", "left": { "path": ["regex"], - "value": "BSONRegExp(\"pattern\", \"i\")" + "value": "new BSONRegExp(\"pattern\", \"i\")" } }, { @@ -264,7 +264,7 @@ "changeType": "removed", "left": { "path": ["javascript"], - "value": "Code(\"function() {}\")" + "value": "new Code(\"function() {}\")" } }, { @@ -274,7 +274,7 @@ "changeType": "removed", "left": { "path": ["symbol"], - "value": "BSONSymbol(\"symbol\")" + "value": "new BSONSymbol(\"symbol\")" } }, { @@ -284,7 +284,7 @@ "changeType": "removed", "left": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "value": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" } }, { @@ -294,7 +294,7 @@ "changeType": "removed", "left": { "path": ["int"], - "value": "Int32(12345)" + "value": "new Int32(12345)" } }, { @@ -304,7 +304,7 @@ "changeType": "removed", "left": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 1 })" + "value": "new Timestamp({ t: 1680701109, i: 1 })" } }, { @@ -314,7 +314,7 @@ "changeType": "removed", "left": { "path": ["long"], - "value": "Long(\"123456789123456789\")" + "value": "new Long(\"123456789123456789\")" } }, { @@ -324,7 +324,7 @@ "changeType": "removed", "left": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" } }, { @@ -334,7 +334,7 @@ "changeType": "removed", "left": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" } }, { @@ -344,7 +344,7 @@ "changeType": "removed", "left": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" } }, { @@ -359,7 +359,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -414,7 +414,7 @@ "changeType": "removed", "left": { "path": ["binaries", "uuid"], - "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + "value": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" } }, { @@ -466,7 +466,7 @@ "changeType": "removed", "left": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } } ] diff --git a/packages/compass-crud/test/fixture-results/all_types_small_change.json b/packages/compass-crud/test/fixture-results/all_types_small_change.json index 1e0c2b993ee..5684fe2e002 100644 --- a/packages/compass-crud/test/fixture-results/all_types_small_change.json +++ b/packages/compass-crud/test/fixture-results/all_types_small_change.json @@ -2,79 +2,79 @@ "left": { "path": [], "value": { - "_id": "ObjectId(\"642d766b7300158b1f22e972\")", - "double": "Double(1.2)", + "_id": "new ObjectId(\"642d766b7300158b1f22e972\")", + "double": "new Double(1.2)", "string": "Hello, world!", "object": { "key": "value" }, "array": [1, 2, 3], "binData": "Binary.createFromBase64(\"AQID\", 0)", - "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "objectId": "new ObjectId(\"642d766c7300158b1f22e975\")", "boolean": true, "date": "2023-04-05T13:25:08.445Z", "null": null, - "regex": "BSONRegExp(\"pattern\", \"i\")", - "javascript": "Code(\"function() {}\")", - "symbol": "BSONSymbol(\"symbol\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "int": "Int32(12345)", - "timestamp": "Timestamp({ t: 1680701109, i: 1 })", - "long": "Long(\"123456789123456789\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"pattern\", \"i\")", + "javascript": "new Code(\"function() {}\")", + "symbol": "new BSONSymbol(\"symbol\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "new Int32(12345)", + "timestamp": "new Timestamp({ t: 1680701109, i: 1 })", + "long": "new Long(\"123456789123456789\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } }, "right": { "path": [], "value": { - "_id": "ObjectId(\"642d766b7300158b1f22e972\")", - "double": "Double(1.2)", + "_id": "new ObjectId(\"642d766b7300158b1f22e972\")", + "double": "new Double(1.2)", "string": "oh no!", "object": { "key": "value" }, "array": [1, 2, 3], "binData": "Binary.createFromBase64(\"AQID\", 0)", - "objectId": "ObjectId(\"642d766c7300158b1f22e975\")", + "objectId": "new ObjectId(\"642d766c7300158b1f22e975\")", "boolean": true, "date": "2023-04-05T13:25:08.445Z", "null": null, - "regex": "BSONRegExp(\"pattern\", \"i\")", - "javascript": "Code(\"function() {}\")", - "symbol": "BSONSymbol(\"symbol\")", - "javascriptWithScope": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", - "int": "Int32(12345)", - "timestamp": "Timestamp({ t: 1680701109, i: 1 })", - "long": "Long(\"123456789123456789\")", - "decimal": "Decimal128(\"5.477284286264328586719275128128001E-4088\")", - "minKey": "MinKey()", - "maxKey": "MaxKey()", + "regex": "new BSONRegExp(\"pattern\", \"i\")", + "javascript": "new Code(\"function() {}\")", + "symbol": "new BSONSymbol(\"symbol\")", + "javascriptWithScope": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})", + "int": "new Int32(12345)", + "timestamp": "new Timestamp({ t: 1680701109, i: 1 })", + "long": "new Long(\"123456789123456789\")", + "decimal": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")", + "minKey": "new MinKey()", + "maxKey": "new MaxKey()", "binaries": { "generic": "Binary.createFromBase64(\"AQID\", 0)", "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", "custom": "Binary.createFromBase64(\"Ly84PQ==\", 128)" }, - "dbRef": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "dbRef": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } }, "delta": { @@ -90,11 +90,11 @@ "changeType": "unchanged", "left": { "path": ["_id"], - "value": "ObjectId(\"642d766b7300158b1f22e972\")" + "value": "new ObjectId(\"642d766b7300158b1f22e972\")" }, "right": { "path": ["_id"], - "value": "ObjectId(\"642d766b7300158b1f22e972\")" + "value": "new ObjectId(\"642d766b7300158b1f22e972\")" } }, { @@ -104,11 +104,11 @@ "changeType": "unchanged", "left": { "path": ["double"], - "value": "Double(1.2)" + "value": "new Double(1.2)" }, "right": { "path": ["double"], - "value": "Double(1.2)" + "value": "new Double(1.2)" } }, { @@ -238,11 +238,11 @@ "changeType": "unchanged", "left": { "path": ["objectId"], - "value": "ObjectId(\"642d766c7300158b1f22e975\")" + "value": "new ObjectId(\"642d766c7300158b1f22e975\")" }, "right": { "path": ["objectId"], - "value": "ObjectId(\"642d766c7300158b1f22e975\")" + "value": "new ObjectId(\"642d766c7300158b1f22e975\")" } }, { @@ -294,11 +294,11 @@ "changeType": "unchanged", "left": { "path": ["regex"], - "value": "BSONRegExp(\"pattern\", \"i\")" + "value": "new BSONRegExp(\"pattern\", \"i\")" }, "right": { "path": ["regex"], - "value": "BSONRegExp(\"pattern\", \"i\")" + "value": "new BSONRegExp(\"pattern\", \"i\")" } }, { @@ -308,11 +308,11 @@ "changeType": "unchanged", "left": { "path": ["javascript"], - "value": "Code(\"function() {}\")" + "value": "new Code(\"function() {}\")" }, "right": { "path": ["javascript"], - "value": "Code(\"function() {}\")" + "value": "new Code(\"function() {}\")" } }, { @@ -322,11 +322,11 @@ "changeType": "unchanged", "left": { "path": ["symbol"], - "value": "BSONSymbol(\"symbol\")" + "value": "new BSONSymbol(\"symbol\")" }, "right": { "path": ["symbol"], - "value": "BSONSymbol(\"symbol\")" + "value": "new BSONSymbol(\"symbol\")" } }, { @@ -336,11 +336,11 @@ "changeType": "unchanged", "left": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "value": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" }, "right": { "path": ["javascriptWithScope"], - "value": "Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" + "value": "new Code(\"function() {}\", {\"foo\":1,\"bar\":\"a\"})" } }, { @@ -350,11 +350,11 @@ "changeType": "unchanged", "left": { "path": ["int"], - "value": "Int32(12345)" + "value": "new Int32(12345)" }, "right": { "path": ["int"], - "value": "Int32(12345)" + "value": "new Int32(12345)" } }, { @@ -364,11 +364,11 @@ "changeType": "unchanged", "left": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 1 })" + "value": "new Timestamp({ t: 1680701109, i: 1 })" }, "right": { "path": ["timestamp"], - "value": "Timestamp({ t: 1680701109, i: 1 })" + "value": "new Timestamp({ t: 1680701109, i: 1 })" } }, { @@ -378,11 +378,11 @@ "changeType": "unchanged", "left": { "path": ["long"], - "value": "Long(\"123456789123456789\")" + "value": "new Long(\"123456789123456789\")" }, "right": { "path": ["long"], - "value": "Long(\"123456789123456789\")" + "value": "new Long(\"123456789123456789\")" } }, { @@ -392,11 +392,11 @@ "changeType": "unchanged", "left": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" }, "right": { "path": ["decimal"], - "value": "Decimal128(\"5.477284286264328586719275128128001E-4088\")" + "value": "new Decimal128(\"5.477284286264328586719275128128001E-4088\")" } }, { @@ -406,11 +406,11 @@ "changeType": "unchanged", "left": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" }, "right": { "path": ["minKey"], - "value": "MinKey()" + "value": "new MinKey()" } }, { @@ -420,11 +420,11 @@ "changeType": "unchanged", "left": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" }, "right": { "path": ["maxKey"], - "value": "MaxKey()" + "value": "new MaxKey()" } }, { @@ -439,7 +439,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -453,7 +453,7 @@ "functionData": "Binary.createFromBase64(\"Ly84PQ==\", 1)", "binaryOld": "Binary.createFromBase64(\"Ly84PQ==\", 2)", "uuidOld": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 3)", - "uuid": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", + "uuid": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")", "md5": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 5)", "encrypted": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 6)", "compressedTimeSeries": "Binary.createFromBase64(\"Yy8vU1pFU3pUR21RNk9mUjM4QTExQT09\", 7)", @@ -524,11 +524,11 @@ "changeType": "unchanged", "left": { "path": ["binaries", "uuid"], - "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + "value": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" }, "right": { "path": ["binaries", "uuid"], - "value": "UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" + "value": "new UUID(\"aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa\")" } }, { @@ -596,11 +596,11 @@ "changeType": "unchanged", "left": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" }, "right": { "path": ["dbRef"], - "value": "DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" + "value": "new DBRef(\"namespace\", new ObjectId(\"642d76b4b7ebfab15d3c4a78\"))" } } ] diff --git a/packages/compass-crud/test/fixture-results/bson_type_change.json b/packages/compass-crud/test/fixture-results/bson_type_change.json index cb5b9cbb9c8..2f06475856b 100644 --- a/packages/compass-crud/test/fixture-results/bson_type_change.json +++ b/packages/compass-crud/test/fixture-results/bson_type_change.json @@ -2,17 +2,17 @@ "left": { "path": [], "value": { - "foo": "Double(1.2)" + "foo": "new Double(1.2)" } }, "right": { "path": [], "value": { - "foo": "Int32(1)" + "foo": "new Int32(1)" } }, "delta": { - "foo": ["Double(1.2)", "Int32(1)"] + "foo": ["new Double(1.2)", "new Int32(1)"] }, "implicitChangeType": "unchanged", "changeType": "unchanged", @@ -24,11 +24,11 @@ "changeType": "changed", "left": { "path": ["foo"], - "value": "Double(1.2)" + "value": "new Double(1.2)" }, "right": { "path": ["foo"], - "value": "Int32(1)" + "value": "new Int32(1)" } } ] diff --git a/packages/compass-crud/test/fixture-results/stress_tests_airbnb.json b/packages/compass-crud/test/fixture-results/stress_tests_airbnb.json index cb0e055561a..31510618087 100644 --- a/packages/compass-crud/test/fixture-results/stress_tests_airbnb.json +++ b/packages/compass-crud/test/fixture-results/stress_tests_airbnb.json @@ -2,17 +2,17 @@ "left": { "path": [], "value": { - "_id": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")", - "id": "Int32(13913)", + "_id": "new ObjectId(\"65648c68cf3ba12a2fcb9c1e\")", + "id": "new Int32(13913)", "listing_url": "https://www.airbnb.com/rooms/13913", - "scrape_id": "Long(\"20220910194334\")", + "scrape_id": "new Long(\"20220910194334\")", "last_scraped": "2022-09-11T00:00:00.000Z", "source": "city scrape", "name": "Holiday London DB Room Let-on going", "description": "My bright double bedroom with a large window has a relaxed feeling! It comfortably fits one or two and is centrally located just two blocks from Finsbury Park. Enjoy great restaurants in the area and easy access to easy transport tubes, trains and buses. Babies and children of all ages are welcome.

The space
Hello Everyone,

I'm offering my lovely double bedroom in Finsbury Park area (zone 2) for let in a shared apartment.
You will share the apartment with me and it is fully furnished with a self catering kitchen. Two people can easily sleep well as the room has a queen size bed. I also have a travel cot for a baby for guest with small children.

I will require a deposit up front as a security gesture on both our parts and will be given back to you when you return the keys.

I trust anyone who will be responding to this add would treat my home with care and respect .

Best Wishes

Alina

Gue", "neighborhood_overview": "Finsbury Park is a friendly melting pot community composed of Turkish, French, Spanish, Middle Eastern, Irish and English families.
We have a wonderful variety of international restaurants directly under us on Stroud Green Road. And there are many shops and large Tescos supermarket right next door.

But you can also venture up to Crouch End and along Greens Lanes where there will endless choice of Turkish and Middle Eastern cuisines.s", "picture_url": "https://a0.muscache.com/pictures/miso/Hosting-13913/original/d755aa6d-cebb-4464-80be-2722c921e8d5.jpeg", - "host_id": "Int32(54730)", + "host_id": "new Int32(54730)", "host_url": "https://www.airbnb.com/users/show/54730", "host_name": "Alina", "host_since": "2009-11-16T00:00:00.000Z", @@ -25,21 +25,21 @@ "host_thumbnail_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_small", "host_picture_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_x_medium", "host_neighbourhood": "LB of Islington", - "host_listings_count": "Int32(3)", - "host_total_listings_count": "Int32(4)", + "host_listings_count": "new Int32(3)", + "host_total_listings_count": "new Int32(4)", "host_verifications": "['email', 'phone']", "host_has_profile_pic": true, "host_identity_verified": true, "neighbourhood": "Islington, Greater London, United Kingdom", "neighbourhood_cleansed": "Islington", - "latitude": "Double(51.56861)", - "longitude": "Double(-0.1127)", + "latitude": "new Double(51.56861)", + "longitude": "new Double(-0.1127)", "property_type": "Private room in rental unit", "room_type": "Private room", - "accommodates": "Int32(1)", + "accommodates": "new Int32(1)", "bathrooms_text": "1 shared bath", - "bedrooms": "Int32(1)", - "beds": "Int32(1)", + "bedrooms": "new Int32(1)", + "beds": "new Int32(1)", "amenities": [ "Extra pillows and blankets", "Oven", @@ -84,54 +84,54 @@ "Cable TV" ], "price": "$50.00", - "minimum_nights": "Int32(1)", - "maximum_nights": "Int32(29)", - "minimum_minimum_nights": "Int32(1)", - "maximum_minimum_nights": "Int32(1)", - "minimum_maximum_nights": "Int32(29)", - "maximum_maximum_nights": "Int32(29)", - "minimum_nights_avg_ntm": "Int32(1)", - "maximum_nights_avg_ntm": "Int32(29)", + "minimum_nights": "new Int32(1)", + "maximum_nights": "new Int32(29)", + "minimum_minimum_nights": "new Int32(1)", + "maximum_minimum_nights": "new Int32(1)", + "minimum_maximum_nights": "new Int32(29)", + "maximum_maximum_nights": "new Int32(29)", + "minimum_nights_avg_ntm": "new Int32(1)", + "maximum_nights_avg_ntm": "new Int32(29)", "has_availability": true, - "availability_30": "Int32(17)", - "availability_60": "Int32(38)", - "availability_90": "Int32(68)", - "availability_365": "Int32(343)", + "availability_30": "new Int32(17)", + "availability_60": "new Int32(38)", + "availability_90": "new Int32(68)", + "availability_365": "new Int32(343)", "calendar_last_scraped": "2022-09-11T00:00:00.000Z", - "number_of_reviews": "Int32(30)", - "number_of_reviews_ltm": "Int32(9)", - "number_of_reviews_l30d": "Int32(0)", + "number_of_reviews": "new Int32(30)", + "number_of_reviews_ltm": "new Int32(9)", + "number_of_reviews_l30d": "new Int32(0)", "first_review": "2010-08-18T00:00:00.000Z", "last_review": "2022-07-15T00:00:00.000Z", - "review_scores_rating": "Double(4.9)", - "review_scores_accuracy": "Double(4.82)", - "review_scores_cleanliness": "Double(4.89)", - "review_scores_checkin": "Double(4.86)", - "review_scores_communication": "Double(4.93)", - "review_scores_location": "Double(4.75)", - "review_scores_value": "Double(4.82)", + "review_scores_rating": "new Double(4.9)", + "review_scores_accuracy": "new Double(4.82)", + "review_scores_cleanliness": "new Double(4.89)", + "review_scores_checkin": "new Double(4.86)", + "review_scores_communication": "new Double(4.93)", + "review_scores_location": "new Double(4.75)", + "review_scores_value": "new Double(4.82)", "instant_bookable": false, - "calculated_host_listings_count": "Int32(2)", - "calculated_host_listings_count_entire_homes": "Int32(1)", - "calculated_host_listings_count_private_rooms": "Int32(1)", - "calculated_host_listings_count_shared_rooms": "Int32(0)", - "reviews_per_month": "Double(0.2)" + "calculated_host_listings_count": "new Int32(2)", + "calculated_host_listings_count_entire_homes": "new Int32(1)", + "calculated_host_listings_count_private_rooms": "new Int32(1)", + "calculated_host_listings_count_shared_rooms": "new Int32(0)", + "reviews_per_month": "new Double(0.2)" } }, "right": { "path": [], "value": { - "_id": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")", - "id": "Int32(13913)", + "_id": "new ObjectId(\"65648c68cf3ba12a2fcb9c1e\")", + "id": "new Int32(13913)", "listing_url": "https://www.airbnb.com/rooms/13913", - "scrape_id": "Long(\"20220910194334\")", + "scrape_id": "new Long(\"20220910194334\")", "last_scraped": "2022-09-11T00:00:00.000Z", "source": "city scrape", "name": "Holiday London DB Room Let-on going", "description": "My bright double bedroom with a large window has a relaxed feeling! It comfortably fits one or two and is centrally located just two blocks from Finsbury Park. Enjoy great restaurants in the area and easy access to easy transport tubes, trains and buses. Babies and children of all ages are welcome.

The space
Hello Everyone,

I'm offering my lovely double bedroom in Finsbury Park area (zone 2) for let in a shared apartment.
You will share the apartment with me and it is fully furnished with a self catering kitchen. Two people can easily sleep well as the room has a queen size bed. I also have a travel cot for a baby for guest with small children.

I will require a deposit up front as a security gesture on both our parts and will be given back to you when you return the keys.

I trust anyone who will be responding to this add would treat my home with care and respect .

Best Wishes

Alina

Gue", "neighborhood_overview": "Finsbury Park is a friendly melting pot community composed of Turkish, French, Spanish, Middle Eastern, Irish and English families.
We have a wonderful variety of international restaurants directly under us on Stroud Green Road. And there are many shops and large Tescos supermarket right next door.

But you can also venture up to Crouch End and along Greens Lanes where there will endless choice of Turkish and Middle Eastern cuisines.s", "picture_url": "https://a0.muscache.com/pictures/miso/Hosting-13913/original/d755aa6d-cebb-4464-80be-2722c921e8d5.jpeg", - "host_id": "Int32(54730)", + "host_id": "new Int32(54730)", "host_url": "https://www.airbnb.com/users/show/54730", "host_name": "Alina", "host_since": "2009-11-16T00:00:00.000Z", @@ -144,21 +144,21 @@ "host_thumbnail_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_small", "host_picture_url": "https://a0.muscache.com/im/users/54730/profile_pic/1327774386/original.jpg?aki_policy=profile_x_medium", "host_neighbourhood": "LB of Islington", - "host_listings_count": "Int32(3)", - "host_total_listings_count": "Int32(4)", + "host_listings_count": "new Int32(3)", + "host_total_listings_count": "new Int32(4)", "host_verifications": "['email', 'phone']", "host_has_profile_pic": true, "host_identity_verified": true, "neighbourhood": "Islington, Greater London, United Kingdom", "neighbourhood_cleansed": "Islington", - "latitude": "Double(51.56861)", - "longitude": "Double(-0.1127)", + "latitude": "new Double(51.56861)", + "longitude": "new Double(-0.1127)", "property_type": "Private room in rental unit", "room_type": "Private room", - "accommodates": "Int32(1)", + "accommodates": "new Int32(1)", "bathrooms_text": "1 shared bath", - "bedrooms": "Int32(1)", - "beds": "Int32(1)", + "bedrooms": "new Int32(1)", + "beds": "new Int32(1)", "amenities": [ "Extra pillows and blankets", "Oven", @@ -203,38 +203,38 @@ "Cable TV" ], "price": "$50.00", - "minimum_nights": "Int32(1)", - "maximum_nights": "Int32(29)", - "minimum_minimum_nights": "Int32(1)", - "maximum_minimum_nights": "Int32(1)", - "minimum_maximum_nights": "Int32(29)", - "maximum_maximum_nights": "Int32(29)", - "minimum_nights_avg_ntm": "Int32(1)", - "maximum_nights_avg_ntm": "Int32(29)", + "minimum_nights": "new Int32(1)", + "maximum_nights": "new Int32(29)", + "minimum_minimum_nights": "new Int32(1)", + "maximum_minimum_nights": "new Int32(1)", + "minimum_maximum_nights": "new Int32(29)", + "maximum_maximum_nights": "new Int32(29)", + "minimum_nights_avg_ntm": "new Int32(1)", + "maximum_nights_avg_ntm": "new Int32(29)", "has_availability": true, - "availability_30": "Int32(17)", - "availability_60": "Int32(38)", - "availability_90": "Int32(68)", - "availability_365": "Int32(343)", + "availability_30": "new Int32(17)", + "availability_60": "new Int32(38)", + "availability_90": "new Int32(68)", + "availability_365": "new Int32(343)", "calendar_last_scraped": "2022-09-11T00:00:00.000Z", - "number_of_reviews": "Int32(30)", - "number_of_reviews_ltm": "Int32(9)", - "number_of_reviews_l30d": "Int32(0)", + "number_of_reviews": "new Int32(30)", + "number_of_reviews_ltm": "new Int32(9)", + "number_of_reviews_l30d": "new Int32(0)", "first_review": "2010-08-18T00:00:00.000Z", "last_review": "2022-07-15T00:00:00.000Z", - "review_scores_rating": "Double(4.9)", - "review_scores_accuracy": "Double(4.82)", - "review_scores_cleanliness": "Double(4.89)", - "review_scores_checkin": "Double(4.86)", - "review_scores_communication": "Double(4.93)", - "review_scores_location": "Double(4.75)", - "review_scores_value": "Double(4.82)", + "review_scores_rating": "new Double(4.9)", + "review_scores_accuracy": "new Double(4.82)", + "review_scores_cleanliness": "new Double(4.89)", + "review_scores_checkin": "new Double(4.86)", + "review_scores_communication": "new Double(4.93)", + "review_scores_location": "new Double(4.75)", + "review_scores_value": "new Double(4.82)", "instant_bookable": false, - "calculated_host_listings_count": "Int32(2)", - "calculated_host_listings_count_entire_homes": "Int32(1)", - "calculated_host_listings_count_private_rooms": "Int32(1)", - "calculated_host_listings_count_shared_rooms": "Int32(0)", - "reviews_per_month": "Double(0.2)" + "calculated_host_listings_count": "new Int32(2)", + "calculated_host_listings_count_entire_homes": "new Int32(1)", + "calculated_host_listings_count_private_rooms": "new Int32(1)", + "calculated_host_listings_count_shared_rooms": "new Int32(0)", + "reviews_per_month": "new Double(0.2)" } }, "delta": null, @@ -248,11 +248,11 @@ "changeType": "unchanged", "left": { "path": ["_id"], - "value": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")" + "value": "new ObjectId(\"65648c68cf3ba12a2fcb9c1e\")" }, "right": { "path": ["_id"], - "value": "ObjectId(\"65648c68cf3ba12a2fcb9c1e\")" + "value": "new ObjectId(\"65648c68cf3ba12a2fcb9c1e\")" } }, { @@ -262,11 +262,11 @@ "changeType": "unchanged", "left": { "path": ["id"], - "value": "Int32(13913)" + "value": "new Int32(13913)" }, "right": { "path": ["id"], - "value": "Int32(13913)" + "value": "new Int32(13913)" } }, { @@ -290,11 +290,11 @@ "changeType": "unchanged", "left": { "path": ["scrape_id"], - "value": "Long(\"20220910194334\")" + "value": "new Long(\"20220910194334\")" }, "right": { "path": ["scrape_id"], - "value": "Long(\"20220910194334\")" + "value": "new Long(\"20220910194334\")" } }, { @@ -388,11 +388,11 @@ "changeType": "unchanged", "left": { "path": ["host_id"], - "value": "Int32(54730)" + "value": "new Int32(54730)" }, "right": { "path": ["host_id"], - "value": "Int32(54730)" + "value": "new Int32(54730)" } }, { @@ -570,11 +570,11 @@ "changeType": "unchanged", "left": { "path": ["host_listings_count"], - "value": "Int32(3)" + "value": "new Int32(3)" }, "right": { "path": ["host_listings_count"], - "value": "Int32(3)" + "value": "new Int32(3)" } }, { @@ -584,11 +584,11 @@ "changeType": "unchanged", "left": { "path": ["host_total_listings_count"], - "value": "Int32(4)" + "value": "new Int32(4)" }, "right": { "path": ["host_total_listings_count"], - "value": "Int32(4)" + "value": "new Int32(4)" } }, { @@ -668,11 +668,11 @@ "changeType": "unchanged", "left": { "path": ["latitude"], - "value": "Double(51.56861)" + "value": "new Double(51.56861)" }, "right": { "path": ["latitude"], - "value": "Double(51.56861)" + "value": "new Double(51.56861)" } }, { @@ -682,11 +682,11 @@ "changeType": "unchanged", "left": { "path": ["longitude"], - "value": "Double(-0.1127)" + "value": "new Double(-0.1127)" }, "right": { "path": ["longitude"], - "value": "Double(-0.1127)" + "value": "new Double(-0.1127)" } }, { @@ -724,11 +724,11 @@ "changeType": "unchanged", "left": { "path": ["accommodates"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["accommodates"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -752,11 +752,11 @@ "changeType": "unchanged", "left": { "path": ["bedrooms"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["bedrooms"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -766,11 +766,11 @@ "changeType": "unchanged", "left": { "path": ["beds"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["beds"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -1468,11 +1468,11 @@ "changeType": "unchanged", "left": { "path": ["minimum_nights"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["minimum_nights"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -1482,11 +1482,11 @@ "changeType": "unchanged", "left": { "path": ["maximum_nights"], - "value": "Int32(29)" + "value": "new Int32(29)" }, "right": { "path": ["maximum_nights"], - "value": "Int32(29)" + "value": "new Int32(29)" } }, { @@ -1496,11 +1496,11 @@ "changeType": "unchanged", "left": { "path": ["minimum_minimum_nights"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["minimum_minimum_nights"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -1510,11 +1510,11 @@ "changeType": "unchanged", "left": { "path": ["maximum_minimum_nights"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["maximum_minimum_nights"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -1524,11 +1524,11 @@ "changeType": "unchanged", "left": { "path": ["minimum_maximum_nights"], - "value": "Int32(29)" + "value": "new Int32(29)" }, "right": { "path": ["minimum_maximum_nights"], - "value": "Int32(29)" + "value": "new Int32(29)" } }, { @@ -1538,11 +1538,11 @@ "changeType": "unchanged", "left": { "path": ["maximum_maximum_nights"], - "value": "Int32(29)" + "value": "new Int32(29)" }, "right": { "path": ["maximum_maximum_nights"], - "value": "Int32(29)" + "value": "new Int32(29)" } }, { @@ -1552,11 +1552,11 @@ "changeType": "unchanged", "left": { "path": ["minimum_nights_avg_ntm"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["minimum_nights_avg_ntm"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -1566,11 +1566,11 @@ "changeType": "unchanged", "left": { "path": ["maximum_nights_avg_ntm"], - "value": "Int32(29)" + "value": "new Int32(29)" }, "right": { "path": ["maximum_nights_avg_ntm"], - "value": "Int32(29)" + "value": "new Int32(29)" } }, { @@ -1594,11 +1594,11 @@ "changeType": "unchanged", "left": { "path": ["availability_30"], - "value": "Int32(17)" + "value": "new Int32(17)" }, "right": { "path": ["availability_30"], - "value": "Int32(17)" + "value": "new Int32(17)" } }, { @@ -1608,11 +1608,11 @@ "changeType": "unchanged", "left": { "path": ["availability_60"], - "value": "Int32(38)" + "value": "new Int32(38)" }, "right": { "path": ["availability_60"], - "value": "Int32(38)" + "value": "new Int32(38)" } }, { @@ -1622,11 +1622,11 @@ "changeType": "unchanged", "left": { "path": ["availability_90"], - "value": "Int32(68)" + "value": "new Int32(68)" }, "right": { "path": ["availability_90"], - "value": "Int32(68)" + "value": "new Int32(68)" } }, { @@ -1636,11 +1636,11 @@ "changeType": "unchanged", "left": { "path": ["availability_365"], - "value": "Int32(343)" + "value": "new Int32(343)" }, "right": { "path": ["availability_365"], - "value": "Int32(343)" + "value": "new Int32(343)" } }, { @@ -1664,11 +1664,11 @@ "changeType": "unchanged", "left": { "path": ["number_of_reviews"], - "value": "Int32(30)" + "value": "new Int32(30)" }, "right": { "path": ["number_of_reviews"], - "value": "Int32(30)" + "value": "new Int32(30)" } }, { @@ -1678,11 +1678,11 @@ "changeType": "unchanged", "left": { "path": ["number_of_reviews_ltm"], - "value": "Int32(9)" + "value": "new Int32(9)" }, "right": { "path": ["number_of_reviews_ltm"], - "value": "Int32(9)" + "value": "new Int32(9)" } }, { @@ -1692,11 +1692,11 @@ "changeType": "unchanged", "left": { "path": ["number_of_reviews_l30d"], - "value": "Int32(0)" + "value": "new Int32(0)" }, "right": { "path": ["number_of_reviews_l30d"], - "value": "Int32(0)" + "value": "new Int32(0)" } }, { @@ -1734,11 +1734,11 @@ "changeType": "unchanged", "left": { "path": ["review_scores_rating"], - "value": "Double(4.9)" + "value": "new Double(4.9)" }, "right": { "path": ["review_scores_rating"], - "value": "Double(4.9)" + "value": "new Double(4.9)" } }, { @@ -1748,11 +1748,11 @@ "changeType": "unchanged", "left": { "path": ["review_scores_accuracy"], - "value": "Double(4.82)" + "value": "new Double(4.82)" }, "right": { "path": ["review_scores_accuracy"], - "value": "Double(4.82)" + "value": "new Double(4.82)" } }, { @@ -1762,11 +1762,11 @@ "changeType": "unchanged", "left": { "path": ["review_scores_cleanliness"], - "value": "Double(4.89)" + "value": "new Double(4.89)" }, "right": { "path": ["review_scores_cleanliness"], - "value": "Double(4.89)" + "value": "new Double(4.89)" } }, { @@ -1776,11 +1776,11 @@ "changeType": "unchanged", "left": { "path": ["review_scores_checkin"], - "value": "Double(4.86)" + "value": "new Double(4.86)" }, "right": { "path": ["review_scores_checkin"], - "value": "Double(4.86)" + "value": "new Double(4.86)" } }, { @@ -1790,11 +1790,11 @@ "changeType": "unchanged", "left": { "path": ["review_scores_communication"], - "value": "Double(4.93)" + "value": "new Double(4.93)" }, "right": { "path": ["review_scores_communication"], - "value": "Double(4.93)" + "value": "new Double(4.93)" } }, { @@ -1804,11 +1804,11 @@ "changeType": "unchanged", "left": { "path": ["review_scores_location"], - "value": "Double(4.75)" + "value": "new Double(4.75)" }, "right": { "path": ["review_scores_location"], - "value": "Double(4.75)" + "value": "new Double(4.75)" } }, { @@ -1818,11 +1818,11 @@ "changeType": "unchanged", "left": { "path": ["review_scores_value"], - "value": "Double(4.82)" + "value": "new Double(4.82)" }, "right": { "path": ["review_scores_value"], - "value": "Double(4.82)" + "value": "new Double(4.82)" } }, { @@ -1846,11 +1846,11 @@ "changeType": "unchanged", "left": { "path": ["calculated_host_listings_count"], - "value": "Int32(2)" + "value": "new Int32(2)" }, "right": { "path": ["calculated_host_listings_count"], - "value": "Int32(2)" + "value": "new Int32(2)" } }, { @@ -1860,11 +1860,11 @@ "changeType": "unchanged", "left": { "path": ["calculated_host_listings_count_entire_homes"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["calculated_host_listings_count_entire_homes"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -1874,11 +1874,11 @@ "changeType": "unchanged", "left": { "path": ["calculated_host_listings_count_private_rooms"], - "value": "Int32(1)" + "value": "new Int32(1)" }, "right": { "path": ["calculated_host_listings_count_private_rooms"], - "value": "Int32(1)" + "value": "new Int32(1)" } }, { @@ -1888,11 +1888,11 @@ "changeType": "unchanged", "left": { "path": ["calculated_host_listings_count_shared_rooms"], - "value": "Int32(0)" + "value": "new Int32(0)" }, "right": { "path": ["calculated_host_listings_count_shared_rooms"], - "value": "Int32(0)" + "value": "new Int32(0)" } }, { @@ -1902,11 +1902,11 @@ "changeType": "unchanged", "left": { "path": ["reviews_per_month"], - "value": "Double(0.2)" + "value": "new Double(0.2)" }, "right": { "path": ["reviews_per_month"], - "value": "Double(0.2)" + "value": "new Double(0.2)" } } ] From 49dcde1a5a3daa814fd1b2b83218f2f2c53c5bc2 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 11 Dec 2023 12:53:07 +0000 Subject: [PATCH 12/23] don't promote values when loading before&after preview docs --- packages/data-service/src/data-service.spec.ts | 6 ++++-- packages/data-service/src/data-service.ts | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/data-service/src/data-service.spec.ts b/packages/data-service/src/data-service.spec.ts index 2a6a5cb2d89..cb68e1da58e 100644 --- a/packages/data-service/src/data-service.spec.ts +++ b/packages/data-service/src/data-service.spec.ts @@ -5,6 +5,7 @@ import chaiAsPromised from 'chai-as-promised'; import type { Sort } from 'mongodb'; import { Collection, MongoServerError } from 'mongodb'; import { MongoClient } from 'mongodb'; +import { Int32 } from 'bson'; import sinon from 'sinon'; import { v4 as uuid } from 'uuid'; import type { DataService } from './data-service'; @@ -1234,7 +1235,7 @@ describe('DataService', function () { }); }); - describe('#previewUpdate', function () { + describe.only('#previewUpdate', function () { const namespace = 'test.previewUpdate'; const sampleDocument = { _id: new ObjectId(), foo: 'bar' }; const replsetCluster = mochaTestServer({ @@ -1318,9 +1319,10 @@ describe('DataService', function () { expect(changeset.changes).to.have.length(1); expect(changeset.changes[0].before).to.deep.equal(sampleDocument); + expect(changeset.changes[0].after.counter._bsontype).to.equal('Int32'); expect(changeset.changes[0].after).to.deep.equal({ _id: sampleDocument._id, - counter: 1, + counter: new Int32(1), }); }); diff --git a/packages/data-service/src/data-service.ts b/packages/data-service/src/data-service.ts index f211218737e..f135c04865e 100644 --- a/packages/data-service/src/data-service.ts +++ b/packages/data-service/src/data-service.ts @@ -2390,7 +2390,13 @@ class DataServiceImpl extends WithLogContext implements DataService { async () => { const coll = this._collection(ns, 'CRUD'); const docsToPreview = await coll - .find(filter, { session, maxTimeMS: remainingTimeoutMS() }) + .find(filter, { + session, + maxTimeMS: remainingTimeoutMS(), + // by using promoteValues: false we can spot BSON type changes + // when diffing. ie. new Double(1) -> new Int32(1) + promoteValues: false, + }) .sort({ _id: 1 }) .limit(sample) .toArray(); @@ -2403,7 +2409,11 @@ class DataServiceImpl extends WithLogContext implements DataService { const changedDocs = await coll .find( { _id: { $in: idsToPreview } }, - { session, maxTimeMS: remainingTimeoutMS() } + { + session, + maxTimeMS: remainingTimeoutMS(), + promoteValues: false, + } ) .sort({ _id: 1 }) .toArray(); From 26165c48b4feccdd2eb40e4fdbce557c217cf6f6 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 11 Dec 2023 12:54:02 +0000 Subject: [PATCH 13/23] remove TODO --- packages/compass-crud/src/components/change-view/change-view.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx index a35a5b2885b..585af8cf2b0 100644 --- a/packages/compass-crud/src/components/change-view/change-view.tsx +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -519,7 +519,6 @@ function ChangeLeaf({ obj }: { obj: UnifiedBranch }) { ? lookupValue((obj.right as Branch).path, right) : undefined; - // TODO: BSONValue does not always show the bson type, so you can't spot bson type changes return (
{includeLeft && ( From f9ba3e3a69d188827db4fa1e0c8071b55ccfe4c9 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 11 Dec 2023 15:19:52 +0000 Subject: [PATCH 14/23] ignore the generated expected results --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index 3ed9bd72351..42c834204b5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ * text=auto eol=lf /packages/bson-transpilers/lib/**/* linguist-generated=true +/packages/compass-crud/test/fixture-results/* linguist-generated=true From f4c6f10e5af0f63155adfd7b4392bd9372efe5e6 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 11 Dec 2023 15:20:58 +0000 Subject: [PATCH 15/23] maybe without the leading slash --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 42c834204b5..1695fe91431 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,3 @@ * text=auto eol=lf /packages/bson-transpilers/lib/**/* linguist-generated=true -/packages/compass-crud/test/fixture-results/* linguist-generated=true +packages/compass-crud/test/fixture-results/* linguist-generated=true From b49d3a0b5b8291abb62e426ddfda96332153d1c8 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 11 Dec 2023 16:40:20 +0000 Subject: [PATCH 16/23] consistently use getValueShape() --- .../src/components/change-view/bson-utils.ts | 7 ++++--- .../src/components/change-view/change-view.tsx | 12 +++++++----- .../src/components/change-view/shape-utils.ts | 2 +- .../components/change-view/unified-document.spec.ts | 2 +- .../src/components/change-view/unified-document.ts | 10 ++++++---- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/bson-utils.ts b/packages/compass-crud/src/components/change-view/bson-utils.ts index b461f363fac..8c93ea33021 100644 --- a/packages/compass-crud/src/components/change-view/bson-utils.ts +++ b/packages/compass-crud/src/components/change-view/bson-utils.ts @@ -1,6 +1,6 @@ import { EJSON } from 'bson'; -import { isSimpleObject } from './shape-utils'; +import { getValueShape } from './shape-utils'; export function stringifyBSON(value: any) { if (value?.inspect) { @@ -13,9 +13,10 @@ export function stringifyBSON(value: any) { } export function unBSON(value: any | any[]): any | any[] { - if (Array.isArray(value)) { + const shape = getValueShape(value); + if (shape === 'array') { return value.map(unBSON); - } else if (isSimpleObject(value)) { + } else if (shape === 'object') { const mapped: Record = {}; for (const [k, v] of Object.entries(value)) { mapped[k] = unBSON(v); diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx index 585af8cf2b0..49236568190 100644 --- a/packages/compass-crud/src/components/change-view/change-view.tsx +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -27,7 +27,7 @@ import type { ArrayItemBranch, Branch, } from './unified-document'; -import { isSimpleObject, getValueShape } from './shape-utils'; +import { getValueShape } from './shape-utils'; type LeftRightContextType = { left: Document; @@ -213,10 +213,11 @@ function ChangeArrayItemLeaf({ item }: { item: ItemBranch }) { function ChangeArrayItem({ item }: { item: ItemBranch }) { const value = item.changeType === 'added' ? item.right.value : item.left.value; - if (Array.isArray(value)) { + const shape = getValueShape(value); + if (shape === 'array') { // array summary followed by array items if expanded return ; - } else if (isSimpleObject(value)) { + } else if (shape === 'object') { // object summary followed by object properties if expanded return ; } @@ -395,12 +396,13 @@ function ChangeObjectProperty({ property }: { property: PropertyBranch }) { property.changeType === 'added' ? property.right.value : property.left.value; - if (Array.isArray(value)) { + const shape = getValueShape(value); + if (shape === 'array') { // array summary followed by array items if expanded return ( ); - } else if (isSimpleObject(value)) { + } else if (shape === 'object') { // object summary followed by object properties if expanded return ( diff --git a/packages/compass-crud/src/components/change-view/shape-utils.ts b/packages/compass-crud/src/components/change-view/shape-utils.ts index c57db771c0e..08f172d413f 100644 --- a/packages/compass-crud/src/components/change-view/shape-utils.ts +++ b/packages/compass-crud/src/components/change-view/shape-utils.ts @@ -5,7 +5,7 @@ export function isSimpleObject(value: any) { ); } -export function getValueShape(value: any) { +export function getValueShape(value: any): 'array' | 'object' | 'leaf' { if (Array.isArray(value)) { return 'array'; } diff --git a/packages/compass-crud/src/components/change-view/unified-document.spec.ts b/packages/compass-crud/src/components/change-view/unified-document.spec.ts index 535e57e5a74..ab9e8f56f58 100644 --- a/packages/compass-crud/src/components/change-view/unified-document.spec.ts +++ b/packages/compass-crud/src/components/change-view/unified-document.spec.ts @@ -165,7 +165,7 @@ describe('unifyDocuments', function () { for (const { name, before, after } of group.fixtures) { it(name, async function () { const result = unifyDocuments(before, after); - const json = JSON.stringify(result, null, 4); + const json = JSON.stringify(result, null, 2); const filename = `${group.name} ${name}.json`.replace(/ /g, '_'); const expectedPath = path.join( diff --git a/packages/compass-crud/src/components/change-view/unified-document.ts b/packages/compass-crud/src/components/change-view/unified-document.ts index 3602b384483..3f333139b28 100644 --- a/packages/compass-crud/src/components/change-view/unified-document.ts +++ b/packages/compass-crud/src/components/change-view/unified-document.ts @@ -290,14 +290,15 @@ function propertiesWithChanges({ property.changeType === 'added' ? property.right.value : property.left.value; - if (Array.isArray(value)) { + const shape = getValueShape(value); + if (shape === 'array') { (property as ArrayPropertyBranch).items = itemsWithChanges({ left: property.left ?? undefined, right: property.right ?? undefined, delta: property.delta, implicitChangeType: getImplicitChangeType(property), } as BranchesWithChanges); - } else if (isSimpleObject(value)) { + } else if (shape === 'object') { (property as ObjectPropertyBranch).properties = propertiesWithChanges({ left: property.left ?? undefined, right: property.right ?? undefined, @@ -452,14 +453,15 @@ function itemsWithChanges({ for (const item of items) { const value = item.changeType === 'added' ? item.right.value : item.left.value; - if (Array.isArray(value)) { + const shape = getValueShape(value); + if (shape === 'array') { (item as ArrayItemBranch).items = itemsWithChanges({ left: item.left ?? undefined, right: item.right ?? undefined, delta: item.delta, implicitChangeType: getImplicitChangeType(item), } as BranchesWithChanges); - } else if (isSimpleObject(value)) { + } else if (shape === 'object') { (item as ObjectItemBranch).properties = propertiesWithChanges({ left: item.left ?? undefined, right: item.right ?? undefined, From 4ea96e51a3e1c45fe024b6bb201a238dcd7d148a Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 11 Dec 2023 17:12:36 +0000 Subject: [PATCH 17/23] live with horizontal scrolling rather than weird wrapping --- .../src/components/change-view/change-view.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/change-view.tsx b/packages/compass-crud/src/components/change-view/change-view.tsx index 49236568190..6e22cb0ff09 100644 --- a/packages/compass-crud/src/components/change-view/change-view.tsx +++ b/packages/compass-crud/src/components/change-view/change-view.tsx @@ -95,8 +95,12 @@ const changeKeyIndexStyles = css({ const changeSummaryStyles = css({ display: 'inline-flex', alignItems: 'flex-start', - flexWrap: 'wrap', - rowGap: '1px', + + // Not sure if it is better with/without this. There's very little horizontal + // space so even ellipsized strings tend to cause wrapping without this, but + // then with it the wrapping ends up being a bit aggressive. + //flexWrap: 'wrap', + //rowGap: '1px', }); function getChangeSummaryClass(obj: UnifiedBranch, darkMode?: boolean) { From 35789aa0f732475eec0a092a19c1c71a0a9f8517 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 12 Dec 2023 11:31:04 +0000 Subject: [PATCH 18/23] wider preview, remove extra spacing, format the default update text --- .../src/components/bulk-update-dialog.tsx | 4 ++-- packages/compass-crud/src/stores/crud-store.spec.ts | 8 ++++---- packages/compass-crud/src/stores/crud-store.ts | 12 +++++++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/compass-crud/src/components/bulk-update-dialog.tsx b/packages/compass-crud/src/components/bulk-update-dialog.tsx index eb768cb88d2..6c1f51c8f5f 100644 --- a/packages/compass-crud/src/components/bulk-update-dialog.tsx +++ b/packages/compass-crud/src/components/bulk-update-dialog.tsx @@ -38,7 +38,7 @@ const columnsStyles = css({ display: 'grid', width: '100%', gap: spacing[4], - gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', + gridTemplateColumns: '2fr 3fr', }); const queryStyles = css({ @@ -59,7 +59,7 @@ const descriptionStyles = css({ const previewStyles = css({ contain: 'size', - overflow: 'scroll', + overflow: 'auto', }); const previewDescriptionStyles = css({ diff --git a/packages/compass-crud/src/stores/crud-store.spec.ts b/packages/compass-crud/src/stores/crud-store.spec.ts index d27368f9284..c99614b0255 100644 --- a/packages/compass-crud/src/stores/crud-store.spec.ts +++ b/packages/compass-crud/src/stores/crud-store.spec.ts @@ -89,7 +89,7 @@ function waitForState(store, cb, timeout?: number) { return waitForStates(store, [cb], timeout); } -describe('store', function () { +describe.only('store', function () { this.timeout(5000); const cluster = mochaTestServer({ @@ -222,7 +222,7 @@ describe('store', function () { }, serverError: undefined, syntaxError: undefined, - updateText: '{\n $set: {}\n}', + updateText: '{\n $set: {\n\n },\n}', }, instanceDescription: 'Topology type: Unknown is not writable', isDataLake: false, @@ -941,7 +941,7 @@ describe('store', function () { previewAbortController: undefined, serverError: undefined, syntaxError: undefined, - updateText: '{ $set: { } }', + updateText: '{\n $set: {\n\n },\n}', }); }); @@ -977,7 +977,7 @@ describe('store', function () { previewAbortController: undefined, serverError: undefined, syntaxError: undefined, - updateText: '{ $set: { } }', + updateText: '{\n $set: {\n\n },\n}', }); }); }); diff --git a/packages/compass-crud/src/stores/crud-store.ts b/packages/compass-crud/src/stores/crud-store.ts index 29c7179061b..bf16287291f 100644 --- a/packages/compass-crud/src/stores/crud-store.ts +++ b/packages/compass-crud/src/stores/crud-store.ts @@ -85,6 +85,12 @@ export type DocumentView = 'List' | 'JSON' | 'Table'; const { debug, log, mongoLogId, track } = createLoggerAndTelemetry('COMPASS-CRUD-UI'); +const INITIAL_BULK_UPDATE_TEXT = `{ + $set: { + + }, +}`; + function pickQueryProps({ filter, sort, @@ -525,7 +531,7 @@ class CrudStoreImpl getInitialBulkUpdateState(): BulkUpdateState { return { isOpen: false, - updateText: '{\n $set: {}\n}', + updateText: INITIAL_BULK_UPDATE_TEXT, preview: { changes: [], }, @@ -1106,7 +1112,7 @@ class CrudStoreImpl isUpdatePreviewSupported: this.state.isUpdatePreviewSupported, }); - await this.updateBulkUpdatePreview('{ $set: { } }'); + await this.updateBulkUpdatePreview(INITIAL_BULK_UPDATE_TEXT); this.setState({ bulkUpdate: { ...this.state.bulkUpdate, @@ -2023,7 +2029,7 @@ export function activateDocumentsPlugin( void store.refreshDocuments(); void store.openBulkUpdateDialog(); void store.updateBulkUpdatePreview( - toJSString(query.update) || '{ $set: { } }' + toJSString(query.update) || INITIAL_BULK_UPDATE_TEXT ); } ); From 2de19fbf091405635dd1c9f7c638a488bdacfde8 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 12 Dec 2023 11:46:51 +0000 Subject: [PATCH 19/23] sans only --- packages/compass-crud/src/stores/crud-store.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-crud/src/stores/crud-store.spec.ts b/packages/compass-crud/src/stores/crud-store.spec.ts index c99614b0255..45e1f31b9bd 100644 --- a/packages/compass-crud/src/stores/crud-store.spec.ts +++ b/packages/compass-crud/src/stores/crud-store.spec.ts @@ -89,7 +89,7 @@ function waitForState(store, cb, timeout?: number) { return waitForStates(store, [cb], timeout); } -describe.only('store', function () { +describe('store', function () { this.timeout(5000); const cluster = mochaTestServer({ From e0f95d630b3c5ae82cac6a1d11a9e7955c189b36 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 12 Dec 2023 11:47:51 +0000 Subject: [PATCH 20/23] sans only --- packages/data-service/src/data-service.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/data-service/src/data-service.spec.ts b/packages/data-service/src/data-service.spec.ts index cb68e1da58e..b56b54bd5cf 100644 --- a/packages/data-service/src/data-service.spec.ts +++ b/packages/data-service/src/data-service.spec.ts @@ -1235,7 +1235,7 @@ describe('DataService', function () { }); }); - describe.only('#previewUpdate', function () { + describe('#previewUpdate', function () { const namespace = 'test.previewUpdate'; const sampleDocument = { _id: new ObjectId(), foo: 'bar' }; const replsetCluster = mochaTestServer({ From 8d4a9231f3bce1351ca96c67cd075f1a609d5d33 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 12 Dec 2023 12:06:30 +0000 Subject: [PATCH 21/23] json formatting seems to not be entirely deterministic.. --- .../src/components/change-view/bson-utils.ts | 3 +++ .../src/components/change-view/unified-document.spec.ts | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/compass-crud/src/components/change-view/bson-utils.ts b/packages/compass-crud/src/components/change-view/bson-utils.ts index 8c93ea33021..09bc368f5c1 100644 --- a/packages/compass-crud/src/components/change-view/bson-utils.ts +++ b/packages/compass-crud/src/components/change-view/bson-utils.ts @@ -27,6 +27,9 @@ export function unBSON(value: any | any[]): any | any[] { } else if (Object.prototype.toString.call(value) === '[object RegExp]') { // make sure these match when diffing return value.toString(); + } else if (Object.prototype.toString.call(value) === '[object Date]') { + // make sure dates are consistently strings when diffing + return value.toISOString(); } else { return value; } diff --git a/packages/compass-crud/src/components/change-view/unified-document.spec.ts b/packages/compass-crud/src/components/change-view/unified-document.spec.ts index ab9e8f56f58..1b72a5eb379 100644 --- a/packages/compass-crud/src/components/change-view/unified-document.spec.ts +++ b/packages/compass-crud/src/components/change-view/unified-document.spec.ts @@ -165,7 +165,6 @@ describe('unifyDocuments', function () { for (const { name, before, after } of group.fixtures) { it(name, async function () { const result = unifyDocuments(before, after); - const json = JSON.stringify(result, null, 2); const filename = `${group.name} ${name}.json`.replace(/ /g, '_'); const expectedPath = path.join( @@ -188,19 +187,21 @@ describe('unifyDocuments', function () { // just remove the result files and temporarily write them from in // here. console.log(expectedPath); - console.log(json); + console.log(JSON.stringify(result, null, 2)); throw err; } + const expectedResult = JSON.parse(expectedText); + try { - expect(json).to.deep.equal(expectedText); + expect(result).to.deep.equal(expectedResult); } catch (err) { // NOTE: If this fails it is probably because we changed the // structure. Check that the expected result makes sense and just // replace the file. Tip: Focusing these tests and using --bail // should really help. console.log(expectedPath); - console.log(json); + console.log(JSON.stringify(result, null, 2)); throw err; } From d43d75d31e4a2c11f6110e04177c452ef79b520f Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 12 Dec 2023 13:35:38 +0000 Subject: [PATCH 22/23] update e2e expected result --- packages/compass-e2e-tests/tests/collection-bulk-update.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts index 8ede363ed6a..bb635f3b403 100644 --- a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts +++ b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts @@ -67,7 +67,7 @@ describe('Bulk Update', () => { // Check that the modal starts with the default update text expect( await browser.getCodemirrorEditorText(Selectors.BulkUpdateUpdate) - ).to.equal('{ $set: { } }'); + ).to.equal('{\n $set: {\n\n },\n}'); // Change the update text await browser.setCodemirrorEditorValue( From 8830d8bc9f56e744039cdfa7a49ac539cd124534 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Tue, 12 Dec 2023 13:53:41 +0000 Subject: [PATCH 23/23] larger modal for bulk update --- .../compass-crud/src/components/bulk-update-dialog.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/compass-crud/src/components/bulk-update-dialog.tsx b/packages/compass-crud/src/components/bulk-update-dialog.tsx index 6c1f51c8f5f..e4dd22b285d 100644 --- a/packages/compass-crud/src/components/bulk-update-dialog.tsx +++ b/packages/compass-crud/src/components/bulk-update-dialog.tsx @@ -33,6 +33,11 @@ import type { BSONObject } from '../stores/crud-store'; import { ChangeView } from './change-view'; import { ReadonlyFilter } from './readonly-filter'; +const modalContentStyles = css({ + width: '100%', + maxWidth: '1280px', +}); + const columnsStyles = css({ marginTop: spacing[4], display: 'grid', @@ -78,7 +83,7 @@ const codeLightContainerStyles = css({ }); const multilineContainerStyles = css({ - maxHeight: spacing[4] * 20, + maxHeight: spacing[5] * 7, // fit at our default window size }); const bannerContainerStyles = css({ @@ -384,8 +389,8 @@ export default function BulkUpdateDialog({