mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
Flatten dictionary members at construction while preserving inheritance order. Skip member scans for nullish inputs without defaults or required members, and define own descriptor properties to avoid inherited setters. Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: https://github.com/nodejs/node/pull/65857 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
68 lines
2.1 KiB
JavaScript
68 lines
2.1 KiB
JavaScript
'use strict';
|
|
|
|
// Flags: --expose-internals
|
|
|
|
const common = require('../common');
|
|
const assert = require('node:assert/strict');
|
|
const { createDictionaryConverter } = require('internal/webidl');
|
|
|
|
const groups = [
|
|
[{ key: 'z', converter: String }, { key: 'b', converter: String }],
|
|
[{ key: 'c', converter: String }, { key: 'a', converter: String }],
|
|
];
|
|
let convert;
|
|
Object.defineProperty(Array.prototype, 2, {
|
|
configurable: true,
|
|
get: common.mustNotCall(),
|
|
set: common.mustNotCall(),
|
|
});
|
|
try {
|
|
convert = createDictionaryConverter('Derived', groups);
|
|
} finally {
|
|
delete Array.prototype[2];
|
|
}
|
|
|
|
const first = convert(null);
|
|
const second = convert(undefined, new Proxy({}, { get: common.mustNotCall() }));
|
|
assert.deepStrictEqual(first, { __proto__: null });
|
|
assert.deepStrictEqual(second, first);
|
|
assert.notStrictEqual(first, second);
|
|
|
|
const trace = [];
|
|
const input = {
|
|
__proto__: { c: 'inherited' },
|
|
b: {
|
|
toString: common.mustCall(() => {
|
|
trace.push('convert b');
|
|
input.z = 'changed';
|
|
return 'b';
|
|
}),
|
|
},
|
|
z: 'original',
|
|
a: 'a',
|
|
};
|
|
const result = convert(new Proxy(input, {
|
|
get(target, key) { trace.push(key); return target[key]; },
|
|
}));
|
|
assert.deepStrictEqual(trace, ['b', 'convert b', 'z', 'a', 'c']);
|
|
assert.deepStrictEqual(result, { __proto__: null, b: 'b', z: 'changed', a: 'a', c: 'inherited' });
|
|
|
|
trace.length = 0;
|
|
convert(new Proxy({}, { get(target, key) { trace.push(key); } }));
|
|
assert.deepStrictEqual(trace, ['b', 'z', 'a', 'c']);
|
|
|
|
const defaults = createDictionaryConverter('Defaults', [[{
|
|
key: 'z', converter: common.mustNotCall(), defaultValue: common.mustCall(() => [], 2),
|
|
}]]);
|
|
assert.notStrictEqual(defaults(null).z, defaults(undefined).z);
|
|
|
|
const required = createDictionaryConverter('Required', [[{
|
|
key: 'z', converter: common.mustNotCall(), defaultValue: common.mustCall(() => 'default', 2),
|
|
}], [
|
|
{ key: 'a', converter: common.mustNotCall(), required: true },
|
|
{ key: 'b', converter: common.mustNotCall(), defaultValue: common.mustNotCall() },
|
|
]]);
|
|
for (const value of [null, undefined]) {
|
|
assert.throws(() => required(value), { code: 'ERR_MISSING_OPTION' });
|
|
}
|