Comparing version 6.2.1 to 6.3.0
@@ -25,2 +25,8 @@ /// <reference types="node" /> | ||
/** | ||
* Represent and compare react elements as JSX strings. | ||
* | ||
* Only supported in the 'pretty' formatting style. | ||
*/ | ||
reactString?: boolean; | ||
/** | ||
* set when formatting keys and values of collections | ||
@@ -108,2 +114,4 @@ * | ||
isArray(): boolean; | ||
isReactElement(element?: any): boolean; | ||
isReactElementChildren(children: any): boolean; | ||
isIterable(): boolean; | ||
@@ -120,2 +128,3 @@ isKeyless(): boolean; | ||
printValue(): void; | ||
printReactElement(): void; | ||
printDate(): void; | ||
@@ -122,0 +131,0 @@ printRegExp(): void; |
@@ -39,2 +39,3 @@ "use strict"; | ||
this.options = options; | ||
options.reactString = options.reactString !== false; | ||
this.parent = options.parent || null; | ||
@@ -128,2 +129,20 @@ this.memo = null; | ||
} | ||
isReactElement(element = this.object) { | ||
return (!!this.options.reactString && | ||
!!this.style.reactElement && | ||
!!element && | ||
typeof element === 'object' && | ||
typeof element.$$typeof === 'symbol' && | ||
!!Symbol.keyFor(element.$$typeof)?.startsWith('react.') && | ||
this.isReactElementChildren(element.props?.children)); | ||
} | ||
isReactElementChildren(children) { | ||
return !children || typeof children === 'string' | ||
? true | ||
: typeof children === 'object' | ||
? children instanceof Set || Array.isArray(children) | ||
? ![...children].some(c => !this.isReactElementChildren(c)) | ||
: Format.prototype.isReactElement.call(this, children) | ||
: false; | ||
} | ||
// technically this means "is an iterable we don't have another fit for" | ||
@@ -262,2 +281,15 @@ // sets, arrays, maps, and streams all handled specially. | ||
} | ||
printReactElement() { | ||
// already verified in isReactElement before getting here. | ||
/* c8 ignore start */ | ||
if (!this.style.reactElement) | ||
return this.printPojo(); | ||
/* c8 ignore stop */ | ||
const indent = this.indentLevel(); | ||
this.memo += this.style | ||
.reactElement(this.object) | ||
.trim() | ||
.split('\n') | ||
.join('\n' + indent); | ||
} | ||
printDate() { | ||
@@ -344,4 +376,6 @@ this.memo += this.object.toISOString(); | ||
? this.printArray() | ||
: // TODO streams, JSX | ||
this.printPojo(); | ||
: this.isReactElement() | ||
? this.printReactElement() | ||
: // TODO streams, JSX | ||
this.printPojo(); | ||
} | ||
@@ -348,0 +382,0 @@ nodeId() { |
@@ -62,2 +62,4 @@ import { Format, FormatOptions } from './format.js'; | ||
printEnd(): void; | ||
isReactElement(): boolean; | ||
printReactElement(): void; | ||
printPojo(): void; | ||
@@ -64,0 +66,0 @@ pojoIsEmpty(): boolean; |
@@ -282,3 +282,36 @@ "use strict"; | ||
} | ||
isReactElement() { | ||
return (super.isReactElement(this.object) && | ||
super.isReactElement(this.expect)); | ||
} | ||
printReactElement() { | ||
const obj = this.simplePrint(this.object); | ||
const exp = this.simplePrintExpect(); | ||
this.memo += obj; | ||
this.memoExpect += exp; | ||
if (obj === exp) { | ||
return; | ||
} | ||
// they don't match as JSX strings, but if we would consider the objects | ||
// to be equivalent, then still treat it as a match. | ||
const subDiff = new this.constructor(this.object, { | ||
...this.options, | ||
expect: this.expect, | ||
parent: this.parent || undefined, | ||
reactString: false, | ||
}); | ||
subDiff.print(); | ||
if (!subDiff.match) { | ||
this.unmatch(); | ||
} | ||
else { | ||
this.memo += obj; | ||
this.memoExpect += obj; | ||
} | ||
} | ||
printPojo() { | ||
if (!this.memo) | ||
this.memo = ''; | ||
if (!this.memoExpect) | ||
this.memoExpect = ''; | ||
// even though it's not a simple mismatch, it's possible that | ||
@@ -285,0 +318,0 @@ // a child entry will cause a mismatch, so we have to print |
/// <reference types="node" /> | ||
import { ReactNode } from 'react'; | ||
import type { Format } from './format.js'; | ||
@@ -89,2 +90,4 @@ export type StyleType = 'pretty' | 'js' | 'tight'; | ||
bufferKeySep: () => string; | ||
/** a react element */ | ||
reactElement?: (node: ReactNode) => string; | ||
/** an empty string */ | ||
@@ -91,0 +94,0 @@ stringEmpty: () => string; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.styles = void 0; | ||
const react_element_to_jsx_string_js_1 = __importDefault(require("./react-element-to-jsx-string.js")); | ||
// can't use buf.toString('ascii') because that unmasks high bytes | ||
@@ -86,2 +90,9 @@ const bufToAscii = (buf) => buf | ||
bufferKeySep: () => ': ', | ||
reactElement: (el) => (0, react_element_to_jsx_string_js_1.default)(el, { | ||
showDefaultProps: true, | ||
showFunctions: true, | ||
useBooleanShorthandSyntax: true, | ||
sortProps: true, | ||
useFragmentShortSyntax: true, | ||
}), | ||
stringEmpty: () => '""', | ||
@@ -88,0 +99,0 @@ stringOneLine: str => JSON.stringify(str), |
@@ -25,2 +25,8 @@ /// <reference types="node" resolution-mode="require"/> | ||
/** | ||
* Represent and compare react elements as JSX strings. | ||
* | ||
* Only supported in the 'pretty' formatting style. | ||
*/ | ||
reactString?: boolean; | ||
/** | ||
* set when formatting keys and values of collections | ||
@@ -108,2 +114,4 @@ * | ||
isArray(): boolean; | ||
isReactElement(element?: any): boolean; | ||
isReactElementChildren(children: any): boolean; | ||
isIterable(): boolean; | ||
@@ -120,2 +128,3 @@ isKeyless(): boolean; | ||
printValue(): void; | ||
printReactElement(): void; | ||
printDate(): void; | ||
@@ -122,0 +131,0 @@ printRegExp(): void; |
@@ -36,2 +36,3 @@ import { styles } from './styles.js'; | ||
this.options = options; | ||
options.reactString = options.reactString !== false; | ||
this.parent = options.parent || null; | ||
@@ -125,2 +126,20 @@ this.memo = null; | ||
} | ||
isReactElement(element = this.object) { | ||
return (!!this.options.reactString && | ||
!!this.style.reactElement && | ||
!!element && | ||
typeof element === 'object' && | ||
typeof element.$$typeof === 'symbol' && | ||
!!Symbol.keyFor(element.$$typeof)?.startsWith('react.') && | ||
this.isReactElementChildren(element.props?.children)); | ||
} | ||
isReactElementChildren(children) { | ||
return !children || typeof children === 'string' | ||
? true | ||
: typeof children === 'object' | ||
? children instanceof Set || Array.isArray(children) | ||
? ![...children].some(c => !this.isReactElementChildren(c)) | ||
: Format.prototype.isReactElement.call(this, children) | ||
: false; | ||
} | ||
// technically this means "is an iterable we don't have another fit for" | ||
@@ -259,2 +278,15 @@ // sets, arrays, maps, and streams all handled specially. | ||
} | ||
printReactElement() { | ||
// already verified in isReactElement before getting here. | ||
/* c8 ignore start */ | ||
if (!this.style.reactElement) | ||
return this.printPojo(); | ||
/* c8 ignore stop */ | ||
const indent = this.indentLevel(); | ||
this.memo += this.style | ||
.reactElement(this.object) | ||
.trim() | ||
.split('\n') | ||
.join('\n' + indent); | ||
} | ||
printDate() { | ||
@@ -341,4 +373,6 @@ this.memo += this.object.toISOString(); | ||
? this.printArray() | ||
: // TODO streams, JSX | ||
this.printPojo(); | ||
: this.isReactElement() | ||
? this.printReactElement() | ||
: // TODO streams, JSX | ||
this.printPojo(); | ||
} | ||
@@ -345,0 +379,0 @@ nodeId() { |
@@ -62,2 +62,4 @@ import { Format, FormatOptions } from './format.js'; | ||
printEnd(): void; | ||
isReactElement(): boolean; | ||
printReactElement(): void; | ||
printPojo(): void; | ||
@@ -64,0 +66,0 @@ pojoIsEmpty(): boolean; |
@@ -279,3 +279,36 @@ import { createTwoFilesPatch } from 'diff'; | ||
} | ||
isReactElement() { | ||
return (super.isReactElement(this.object) && | ||
super.isReactElement(this.expect)); | ||
} | ||
printReactElement() { | ||
const obj = this.simplePrint(this.object); | ||
const exp = this.simplePrintExpect(); | ||
this.memo += obj; | ||
this.memoExpect += exp; | ||
if (obj === exp) { | ||
return; | ||
} | ||
// they don't match as JSX strings, but if we would consider the objects | ||
// to be equivalent, then still treat it as a match. | ||
const subDiff = new this.constructor(this.object, { | ||
...this.options, | ||
expect: this.expect, | ||
parent: this.parent || undefined, | ||
reactString: false, | ||
}); | ||
subDiff.print(); | ||
if (!subDiff.match) { | ||
this.unmatch(); | ||
} | ||
else { | ||
this.memo += obj; | ||
this.memoExpect += obj; | ||
} | ||
} | ||
printPojo() { | ||
if (!this.memo) | ||
this.memo = ''; | ||
if (!this.memoExpect) | ||
this.memoExpect = ''; | ||
// even though it's not a simple mismatch, it's possible that | ||
@@ -282,0 +315,0 @@ // a child entry will cause a mismatch, so we have to print |
/// <reference types="node" resolution-mode="require"/> | ||
import { ReactNode } from 'react'; | ||
import type { Format } from './format.js'; | ||
@@ -89,2 +90,4 @@ export type StyleType = 'pretty' | 'js' | 'tight'; | ||
bufferKeySep: () => string; | ||
/** a react element */ | ||
reactElement?: (node: ReactNode) => string; | ||
/** an empty string */ | ||
@@ -91,0 +94,0 @@ stringEmpty: () => string; |
@@ -0,1 +1,2 @@ | ||
import reactElementToJsxString from './react-element-to-jsx-string.js'; | ||
// can't use buf.toString('ascii') because that unmasks high bytes | ||
@@ -83,2 +84,9 @@ const bufToAscii = (buf) => buf | ||
bufferKeySep: () => ': ', | ||
reactElement: (el) => reactElementToJsxString(el, { | ||
showDefaultProps: true, | ||
showFunctions: true, | ||
useBooleanShorthandSyntax: true, | ||
sortProps: true, | ||
useFragmentShortSyntax: true, | ||
}), | ||
stringEmpty: () => '""', | ||
@@ -85,0 +93,0 @@ stringOneLine: str => JSON.stringify(str), |
{ | ||
"name": "tcompare", | ||
"version": "6.2.1", | ||
"version": "6.3.0", | ||
"description": "A comprehensive comparison library, for use in test frameworks", | ||
@@ -43,3 +43,4 @@ "tshy": { | ||
"dependencies": { | ||
"diff": "^5.1.0" | ||
"diff": "^5.1.0", | ||
"react-element-to-jsx-string": "^15.0.0" | ||
}, | ||
@@ -46,0 +47,0 @@ "tap": { |
@@ -184,2 +184,19 @@ # tcompare | ||
- `reactString` - Represent and compare React elements as JSX | ||
strings. Only supported in the `pretty` formatting style. | ||
Enabled by default, set `{ reactString: false }` in the options | ||
to disable it. | ||
When enabled, react elements are _first_ compared as react JSX | ||
strings, and if the strings match, treated as equivalent, even | ||
if they would not otherwise be treated as a match as plain | ||
objects (for example, if `children` is set to `'hello'` vs | ||
`['hello']`, these are considered identical, because they result in the same JSX). | ||
If they do not match, then they are still considered a | ||
match if their plain object represenatations would be | ||
considered a match. So for example, `<x a="b" />` would match | ||
`<x a={/b|c/} />` for functions where strings can match against | ||
regular expressions. | ||
- `bufferChunkSize` - The number of bytes to show per line when | ||
@@ -186,0 +203,0 @@ printing long `Buffer` objects. Defaults to 32. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
471330
103
4976
312
2
1
+ Added@base2/pretty-print-object@1.0.1(transitive)
+ Addedis-plain-object@5.0.0(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedreact@18.3.1(transitive)
+ Addedreact-dom@18.3.1(transitive)
+ Addedreact-element-to-jsx-string@15.0.0(transitive)
+ Addedreact-is@18.1.0(transitive)
+ Addedscheduler@0.23.2(transitive)