-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
util: change sparse arrays inspection format #11576
Conversation
Existing tests are updated, but I'll add a couple of new ones. UPD: already added. |
61b0999
to
3fe8d6a
Compare
lib/util.js
Outdated
index++; | ||
} | ||
if (emptyElements > 0) { | ||
output.push(ctx.stylize(`[${emptyElements} empty]`, 'special')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still stand by my opinion of using 'undefined'
as the color, though I'm not going to block this PR if that's what others prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, let's wait and see what others think about it. If there's no specific preference, I'll change it to 'undefined'
.
test/parallel/test-util-inspect.js
Outdated
@@ -832,12 +832,12 @@ checkAlignment(new Map(big_array.map(function(y) { return [y, null]; }))); | |||
// Do not backport to v5/v4 unless all of | |||
// https://github.com/nodejs/node/pull/6334 is backported. | |||
{ | |||
const x = Array(101); | |||
const x = ','.repeat(100).split(','); // array of 101 empty strings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new Array(101).fill()
might be more semantically correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, thanks.
b692e86
to
72ecc70
Compare
@TimothyGu I've updated the PR to use the |
72ecc70
to
8993097
Compare
I'm on the fence on this one...leaning slightly towards keep existing behavior. I'm not sure that this is in fact more readable... going ahead and marking as semver-major though |
@evanlucas yes, certainly semver-major. An alternative solution that is at least similar to existing behavior yet solves the issue is to add an extra comma if the last element of a sparse array is missing. |
8993097
to
e923dbb
Compare
I agree with @evanlucas. I think something a bit more clear would be desired e.g. |
I don't feel strongly about it one way or another but one fairly compact approach is to use one
|
@Fishrock123 changed it to be > new Array(3)
[ [3 uninitialized elements] ]
> [1, 2, , , , 3, 4, 5]
[ 1, 2, [3 uninitialized elements], 3, 4, 5 ]
> [1, 2, , , , 3, 4, 5, , 2]
[ 1,
2,
[3 uninitialized elements],
3,
4,
5,
[1 uninitialized element],
2 ] |
@TimothyGu looks like this is somewhat controversial 😄 As I already suggested above, a better solution might be to leave the current format with a small addition: if a sparse array doesn't have its last element, just append an extra dangling comma. This way the output of |
} | ||
const remaining = value.length - index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn’t this be value.length - visisbleLength
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it shouldn't. visibleLength
is the count of... well, printed elements, i.e., 3
in case of [ 1, [10000 uninitialized elements], 2 ]
(maybe the variable name isn't that great, though). remaining
, on the other hand, is the count of real array indices which values were not printed.
@jasnell well, this would be hard to format with respect to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
(edit: +1 to doing this and +1 to “uninitialized”)
No, though it's now "correct", it wouldn't be less confusing. The goal for the message is to be 1) clear/unambiguous, and 2) concise. Having an extra dangling comma at the end would indeed be unambiguous in the sense of ES compliance, but it would be confusing considering chances are people might have already gotten used to this quirk in Node.js. That applies also to the suggestion to use At the same time, |
+1, good point. So what about the placeholder message? Considering browser examples provided in #11570, I don't really like the way Chromium formats sparse arrays (it isn't less confusing when Hence the current variants:
It would be great if anyone has better suggestions. @TimothyGu, @addaleax? |
I like “uninitialized” because it tells the user how that hole in the array actually came to be – it was simply not initialized to any particular value (except for when somebody does I’d be fine with any of {“empty”, “uninitialized”, “missing”} × {“item(s)”, “element(s)”}, though. |
@nodejs/ctc This needs another review from a CTC member. Also, is anybody objecting to the current format ( |
The square bracket use makes it a bit harder to parse. At a quick glance, it looks like a nested array. |
I'm good with the |
That would read like an object literal. Maybe |
@cjihrig, just wanted to suggest it :) |
Also, what about s/element(s)/item(s) to be consistent with an existing "... N more items" message? |
I think it is a bit excessively long but I don't see good and descriptive options otherwise. Well, I suppose |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM other than the two nits. Thanks for working on this!
assert(!/1 more item/.test(util.inspect(x, {maxArrayLength: 101}))); | ||
} | ||
|
||
{ | ||
const x = new Array(101).fill(); | ||
assert(/^\[ ... 101 more items ]$/.test( | ||
util.inspect(x, {maxArrayLength: 0}))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I know the regex is there already, but it doesn't seem to be needed, since assert.strictEqual(util.inspect(x, {maxArrayLength: 0}), '[ ... 101 more items ]')
should accomplish the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to open a new PR and change it for the whole group of tests here so that they look consistent and this PR doesn't modify the tests which are not related to its changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other that these two and analogous Uint8Array
test (line 873), there are tests where a regex can be reduced to a simple .endsWith()
check.
util.inspect(x, {maxArrayLength: 0}))); | ||
} | ||
|
||
{ | ||
const x = Array(101); | ||
assert(/^\[ ... 101 more items ]$/.test( | ||
util.inspect(x, {maxArrayLength: 0}))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
@addaleax I guess CITGM failures aren't related to this patch |
Missing elements in sparse arrays used to be serialized to empty placeholders delimited with commas by util.inspect() and in some cases the result was a syntactically correct representation of a JavaScript array with shorter length than the original one. This commit implements @TimothyGu's suggestion to change the way util.inspect() formats sparse arrays to something similar to how Firefox shows them. Fixes: nodejs#11570
2cb034c
to
fb4fe0d
Compare
Squashed the commits into one. |
@addaleax ping |
@aqrln Thanks for the ping, I’m busy but I’ll land this later today if nobody beats me to it |
Landed in ec2f098, thanks for the PR! |
Missing elements in sparse arrays used to be serialized to empty placeholders delimited with commas by util.inspect() and in some cases the result was a syntactically correct representation of a JavaScript array with shorter length than the original one. This commit implements @TimothyGu's suggestion to change the way util.inspect() formats sparse arrays to something similar to how Firefox shows them. Fixes: #11570 PR-URL: #11576 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
* Enclose tests that used to introduce module-level variables into their own scopes. * Replace ES5 anonymous functions with arrow functions where it makes sense. * And make one arrow function a regular function thus fixing a bug in a getter inside an object created in "Array with dynamic properties" test. This getter has never been invoked though, so the test hasn't been failing. * Convert snake_case identifiers to camelCase. * Make some variable names more readable. * Replace regular expressions in maxArrayLength tests with simple assert.strictEquals() and assert(...endsWith()) checks, as suggested in <nodejs#11576 (comment)>.
* Enclose tests that used to introduce module-level variables into their own scopes. * Replace ES5 anonymous functions with arrow functions where it makes sense. * And make one arrow function a regular function thus fixing a bug in a getter inside an object created in "Array with dynamic properties" test. This getter has never been invoked though, so the test hasn't been failing. * Convert snake_case identifiers to camelCase. * Make some variable names more readable. * Replace regular expressions in maxArrayLength tests with simple assert.strictEquals() and assert(...endsWith()) checks, as suggested in <#11576 (comment)>. PR-URL: #11779 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Missing elements in sparse arrays used to be serialized to empty placeholders delimited with commas by util.inspect() and in some cases the result was a syntactically correct representation of a JavaScript array with shorter length than the original one. This commit implements @TimothyGu's suggestion to change the way util.inspect() formats sparse arrays to something similar to how Firefox shows them. Fixes: nodejs#11570 PR-URL: nodejs#11576 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
* Enclose tests that used to introduce module-level variables into their own scopes. * Replace ES5 anonymous functions with arrow functions where it makes sense. * And make one arrow function a regular function thus fixing a bug in a getter inside an object created in "Array with dynamic properties" test. This getter has never been invoked though, so the test hasn't been failing. * Convert snake_case identifiers to camelCase. * Make some variable names more readable. * Replace regular expressions in maxArrayLength tests with simple assert.strictEquals() and assert(...endsWith()) checks, as suggested in <nodejs#11576 (comment)>. PR-URL: nodejs#11779 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
* Enclose tests that used to introduce module-level variables into their own scopes. * Replace ES5 anonymous functions with arrow functions where it makes sense. * And make one arrow function a regular function thus fixing a bug in a getter inside an object created in "Array with dynamic properties" test. This getter has never been invoked though, so the test hasn't been failing. * Convert snake_case identifiers to camelCase. * Make some variable names more readable. * Replace regular expressions in maxArrayLength tests with simple assert.strictEquals() and assert(...endsWith()) checks, as suggested in <nodejs#11576 (comment)>. PR-URL: nodejs#11779 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
* Enclose tests that used to introduce module-level variables into their own scopes. * Replace ES5 anonymous functions with arrow functions where it makes sense. * And make one arrow function a regular function thus fixing a bug in a getter inside an object created in "Array with dynamic properties" test. This getter has never been invoked though, so the test hasn't been failing. * Convert snake_case identifiers to camelCase. * Make some variable names more readable. * Replace regular expressions in maxArrayLength tests with simple assert.strictEquals() and assert(...endsWith()) checks, as suggested in <#11576 (comment)>. PR-URL: #11779 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Missing elements in sparse arrays used to be serialized to empty placeholders delimited with commas by util.inspect() and in some cases the result was a syntactically correct representation of a JavaScript array with shorter length than the original one. This PR implements @TimothyGu's suggestion to change the way util.inspect() formats sparse arrays to something similar to how Firefox shows them.
Fixes: #11570
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
util