Skip to content

Commit

Permalink
assert: --assert-full-diff
Browse files Browse the repository at this point in the history
  • Loading branch information
RedYetiDev committed May 10, 2024
1 parent 2863c54 commit 2a0ae9b
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 9 deletions.
11 changes: 11 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,15 @@ under this flag.
To allow polyfills to be added,
[`--require`][] and [`--import`][] both run before freezing intrinsics.

### `--full-assert-diff`

<!-- YAML
added: REPLACEME
-->

When an [`AssertionError`][] occurs, display the entire `diff`, rather than
a truncated version.

### `--heap-prof`

<!-- YAML
Expand Down Expand Up @@ -2612,6 +2621,7 @@ one is included in the list below.
* `--force-fips`
* `--force-node-api-uncaught-exceptions-policy`
* `--frozen-intrinsics`
* `--full-assert-diff`
* `--heapsnapshot-near-heap-limit`
* `--heapsnapshot-signal`
* `--http-parser`
Expand Down Expand Up @@ -3132,6 +3142,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
[`--print`]: #-p---print-script
[`--redirect-warnings`]: #--redirect-warningsfile
[`--require`]: #-r---require-module
[`AssertionError`]: assert.md#class-assertassertionerror
[`Buffer`]: buffer.md#class-buffer
[`CRYPTO_secure_malloc_init`]: https://www.openssl.org/docs/man3.0/man3/CRYPTO_secure_malloc_init.html
[`NODE_OPTIONS`]: #node_optionsoptions
Expand Down
3 changes: 3 additions & 0 deletions doc/node.1
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ Same requirements as
.It Fl -frozen-intrinsics
Enable experimental frozen intrinsics support.
.
.It Fl -full-assert-diff
Show the full diff when an AssertionError occurs.
.
.It Fl -heapsnapshot-near-heap-limit Ns = Ns Ar max_count
Generate heap snapshot when the V8 heap usage is approaching the heap limit.
No more than the specified number of snapshots will be generated.
Expand Down
36 changes: 27 additions & 9 deletions lib/internal/assert/assertion_error.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const {
validateObject,
} = require('internal/validators');
const { isErrorStackTraceLimitWritable } = require('internal/errors');
const { getOptionValue } = require('internal/options');


const kReadableOperator = {
Expand All @@ -41,6 +42,8 @@ const kReadableOperator = {
notDeepEqualUnequal: 'Expected values not to be loosely deep-equal:',
};

const kShowFullErrorDiff = !!getOptionValue('--full-assert-diff');

// Comparing short primitives should just show === / !== instead of using the
// diff.
const kMaxShortLength = 12;
Expand Down Expand Up @@ -142,7 +145,7 @@ function createErrDiff(actual, expected, operator) {
let a = actualLines[actualLines.length - 1];
let b = expectedLines[expectedLines.length - 1];
while (a === b) {
if (i++ < 3) {
if (i++ < 3 || kShowFullErrorDiff) {
end = `\n ${a}${end}`;
} else {
other = a;
Expand All @@ -164,7 +167,7 @@ function createErrDiff(actual, expected, operator) {

// Only remove lines in case it makes sense to collapse those.
// TODO: Accept env to always show the full error.
if (actualLines.length > 50) {
if (actualLines.length > 50 && !kShowFullErrorDiff) {
actualLines[46] = `${colors.blue}...${colors.white}`;
while (actualLines.length > 47) {
ArrayPrototypePop(actualLines);
Expand All @@ -177,7 +180,7 @@ function createErrDiff(actual, expected, operator) {

// There were at least five identical lines at the end. Mark a couple of
// skipped.
if (i >= 5) {
if (i >= 5 && !kShowFullErrorDiff) {
end = `\n${colors.blue}...${colors.white}${end}`;
skipped = true;
}
Expand Down Expand Up @@ -205,7 +208,14 @@ function createErrDiff(actual, expected, operator) {
if (maxLength < i + 1) {
// If more than two former lines are identical, print them. Collapse them
// in case more than five lines were identical.
if (identical > 2) {
if (kShowFullErrorDiff) {
let identicalCopy = identical - 2;
while (identicalCopy > 0) {
res += `\n ${lines[i - identicalCopy]}`;
printedLines++;
identicalCopy--;
}
} else if (identical > 2) {
if (identical > 3) {
if (identical > 4) {
if (identical === 5) {
Expand Down Expand Up @@ -261,7 +271,14 @@ function createErrDiff(actual, expected, operator) {
if (divergingLines) {
// If more than two former lines are identical, print them. Collapse
// them in case more than five lines were identical.
if (identical > 2) {
if (kShowFullErrorDiff) {
let identicalCopy = identical - 2;
while (identicalCopy > 0) {
res += `\n ${actualLines[i - identicalCopy]}`;
printedLines++;
identicalCopy--;
}
} else if (identical > 2) {
if (identical > 3) {
if (identical > 4) {
if (identical === 5) {
Expand Down Expand Up @@ -301,7 +318,7 @@ function createErrDiff(actual, expected, operator) {
}
}
// Inspected object to big (Show ~50 rows max)
if (printedLines > 50 && i < maxLines - 2) {
if (printedLines > 50 && i < maxLines - 2 && !kShowFullErrorDiff) {
return `${msg}${skippedMsg}\n${res}\n${colors.blue}...${colors.white}${other}\n` +
`${colors.blue}...${colors.white}`;
}
Expand All @@ -311,6 +328,7 @@ function createErrDiff(actual, expected, operator) {
}

function addEllipsis(string) {
if (kShowFullErrorDiff) return string;
const lines = StringPrototypeSplit(string, '\n', 11);
if (lines.length > 10) {
lines.length = 10;
Expand Down Expand Up @@ -395,15 +413,15 @@ class AssertionError extends Error {
const knownOperator = kReadableOperator[operator];
if (operator === 'notDeepEqual' && res === other) {
res = `${knownOperator}\n\n${res}`;
if (res.length > 1024) {
if (res.length > 1024 && !kShowFullErrorDiff) {
res = `${StringPrototypeSlice(res, 0, 1021)}...`;
}
super(res);
} else {
if (res.length > 512) {
if (res.length > 512 && !kShowFullErrorDiff) {
res = `${StringPrototypeSlice(res, 0, 509)}...`;
}
if (other.length > 512) {
if (other.length > 512 && !kShowFullErrorDiff) {
other = `${StringPrototypeSlice(other, 0, 509)}...`;
}
if (operator === 'deepEqual') {
Expand Down
4 changes: 4 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"experimental frozen intrinsics support",
&EnvironmentOptions::frozen_intrinsics,
kAllowedInEnvvar);
AddOption("--full-assert-diff",
"show full diff in assert messages",
&EnvironmentOptions::full_assert_diff,
kAllowedInEnvvar);
AddOption("--heapsnapshot-signal",
"Generate heap snapshot on specified signal",
&EnvironmentOptions::heap_snapshot_signal,
Expand Down
1 change: 1 addition & 0 deletions src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class EnvironmentOptions : public Options {
bool experimental_https_modules = false;
bool experimental_wasm_modules = false;
bool experimental_import_meta_resolve = false;
bool full_assert_diff = false;
std::string input_type; // Value of --input-type
std::string type; // Value of --experimental-default-type
bool experimental_permission = false;
Expand Down
62 changes: 62 additions & 0 deletions test/parallel/test-assert-full-diff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Flags: --full-assert-diff

'use strict';

require('../common');

const assert = require('assert');

{
// Large Paragraph(s)
const expected = `
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Sit amet mattis vulputate enim nulla aliquet porttitor lacus luctus.
Turpis egestas integer eget aliquet nibh praesent tristique magna.
Malesuada bibendum arcu vitae elementum curabitur vitae.
Feugiat vivamus at augue eget.
Erat velit scelerisque in dictum non consectetur a erat.
Id nibh tortor id aliquet.
Blandit cursus risus at ultrices mi tempus.
Varius morbi enim nunc faucibus a pellentesque sit.
Quam quisque id diam vel quam.
Sit amet mattis vulputate enim.
Lectus urna duis convallis convallis tellus id interdum velit.
Lacinia quis vel eros donec ac odio tempor orci dapibus.
Purus non enim praesent elementum facilisis leo.
Condimentum id venenatis a condimentum vitae. Pretium viverra suspendisse potenti nullam ac.
`;
const actual = expected.replace('Id nibh tortor id aliquet.', 'That\'s a tortor that trucks');

try {
assert.strictEqual(actual, expected);
} catch (err) {
assert.ok(expected.split('\n').every((line) => err.message.includes(line)));
assert.ok(actual.split('\n').every((line) => err.message.includes(line)));
}
}

{
// Large Array
const expected = Array.from({ length: 1000 }, (_, i) => i);
const actual = Array.from({ length: 1000 }, (_, i) => i + (i === 500 ? 1 : 0));

try {
assert.deepStrictEqual(actual, expected);
} catch (err) {
assert.ok(expected.every((line) => err.message.includes(line)));
assert.ok(actual.every((line) => err.message.includes(line)));
}
}

{
// Large Single-Line String
const expected = 'A'.repeat(500) + 'B' + 'A'.repeat(500);
const actual = expected.replace('B', 'C');

try {
assert.strictEqual(actual, expected);
} catch (err) {
assert.ok(err.message.includes(expected));
assert.ok(err.message.includes(actual));
}
}

0 comments on commit 2a0ae9b

Please sign in to comment.