Skip to content

Commit 9f2d544

Browse files
TrevorBurnhamaduh95
authored andcommitted
test: move sqlite length validation out of the reentry test
The "non-integer callback length" suite in test-sqlite-options-getter-reentry.js checks that function() and aggregate() reject a callback whose length property is not an integer. That is plain argument validation: no property getter runs, and nothing changes mid-call, so the tests do not belong in a file about option getters re-entering the database. Move them into the "input validation" suites that already cover the other argument type checks for each method. Drop "a normal function length is still accepted", which duplicates "uses function.length when false" in test-sqlite-custom-functions.js. The two tests that put the getter on length itself stay where they are, since closing the database from that getter is what they exercise. Refs: #65595 Signed-off-by: Trevor Burnham <trevorburnham@gmail.com> PR-URL: #65769 Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent cfee7fa commit 9f2d544

3 files changed

Lines changed: 66 additions & 59 deletions

File tree

test/parallel/test-sqlite-aggregate-function.mjs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ describe('DatabaseSync.prototype.aggregate()', () => {
77
describe('input validation', () => {
88
const db = new DatabaseSync(':memory:');
99

10+
// The length property is configurable, so any type can reach the
11+
// conversion that derives the aggregate's arity from it.
12+
const lengths = ['abc', {}, [], null, undefined, NaN, 1.5,
13+
Symbol.iterator, 10n, true, 2 ** 40];
14+
15+
function withLength(fn, length) {
16+
Object.defineProperty(fn, 'length', {
17+
configurable: true,
18+
value: length,
19+
});
20+
return fn;
21+
}
22+
1023
test('throws if options.start is not provided', (t) => {
1124
t.assert.throws(() => {
1225
db.aggregate('sum', {
@@ -81,6 +94,37 @@ describe('DatabaseSync.prototype.aggregate()', () => {
8194
message: /The "options\.inverse" argument must be a function/,
8295
});
8396
});
97+
98+
test('throws if options.step.length is not an integer', (t) => {
99+
for (const length of lengths) {
100+
t.assert.throws(() => {
101+
db.aggregate('sum', {
102+
start: 0,
103+
step: withLength((acc, value) => acc + value, length),
104+
result: (total) => total
105+
});
106+
}, {
107+
code: 'ERR_INVALID_ARG_TYPE',
108+
message: /The "options\.step\.length" property must be an integer/,
109+
}, `length=${String(length)}`);
110+
}
111+
});
112+
113+
test('throws if options.inverse.length is not an integer', (t) => {
114+
for (const length of lengths) {
115+
t.assert.throws(() => {
116+
db.aggregate('sum', {
117+
start: 0,
118+
step: (acc, value) => acc + value,
119+
inverse: withLength((acc, value) => acc - value, length),
120+
result: (total) => total
121+
});
122+
}, {
123+
code: 'ERR_INVALID_ARG_TYPE',
124+
message: /The "options\.inverse\.length" property must be an integer/,
125+
}, `length=${String(length)}`);
126+
}
127+
});
84128
});
85129
});
86130

test/parallel/test-sqlite-custom-functions.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,28 @@ suite('DatabaseSync.prototype.function()', () => {
7171
message: /The "options\.directOnly" argument must be a boolean/,
7272
});
7373
});
74+
75+
test('throws if function.length is not an integer', () => {
76+
// The length property is configurable, so any type can reach the
77+
// conversion that derives the function's arity from it.
78+
const lengths = ['abc', {}, [], null, undefined, NaN, 1.5,
79+
Symbol.iterator, 10n, true, 2 ** 40];
80+
81+
for (const length of lengths) {
82+
const fn = () => 1;
83+
Object.defineProperty(fn, 'length', {
84+
configurable: true,
85+
value: length,
86+
});
87+
88+
assert.throws(() => {
89+
db.function('foo', fn);
90+
}, {
91+
code: 'ERR_INVALID_ARG_TYPE',
92+
message: /The "function\.length" property must be an integer/,
93+
}, `length=${String(length)}`);
94+
}
95+
});
7496
});
7597

7698
suite('useBigIntArguments', () => {

test/parallel/test-sqlite-options-getter-reentry.js

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -242,62 +242,3 @@ suite('resizing a deserialize() buffer from an options getter', () => {
242242
});
243243
});
244244
});
245-
246-
// fn.length is configurable, so it must be validated rather than cast blindly.
247-
suite('non-integer callback length', () => {
248-
const badLengths = ['abc', {}, [], null, undefined, NaN, 1.5, Symbol.iterator,
249-
10n, true, 2 ** 40];
250-
251-
test('function() rejects a non-integer length', (t) => {
252-
const db = new DatabaseSync(':memory:');
253-
for (const value of badLengths) {
254-
const fn = () => 1;
255-
Object.defineProperty(fn, 'length', { configurable: true, value });
256-
t.assert.throws(() => {
257-
db.function('fn', fn);
258-
}, {
259-
code: 'ERR_INVALID_ARG_TYPE',
260-
message: /The "function\.length" property must be an integer/,
261-
}, `length=${String(value)}`);
262-
}
263-
});
264-
265-
test('aggregate() rejects a non-integer step length', (t) => {
266-
const db = new DatabaseSync(':memory:');
267-
for (const value of badLengths) {
268-
const step = (acc, next) => acc;
269-
Object.defineProperty(step, 'length', { configurable: true, value });
270-
t.assert.throws(() => {
271-
db.aggregate('agg', { start: 0, step, result: (acc) => acc });
272-
}, {
273-
code: 'ERR_INVALID_ARG_TYPE',
274-
message: /The "options\.step\.length" property must be an integer/,
275-
}, `length=${String(value)}`);
276-
}
277-
});
278-
279-
test('aggregate() rejects a non-integer inverse length', (t) => {
280-
const db = new DatabaseSync(':memory:');
281-
for (const value of badLengths) {
282-
const inverse = (acc, next) => acc;
283-
Object.defineProperty(inverse, 'length', { configurable: true, value });
284-
t.assert.throws(() => {
285-
db.aggregate('agg', {
286-
start: 0,
287-
step: (acc, next) => acc,
288-
inverse,
289-
result: (acc) => acc,
290-
});
291-
}, {
292-
code: 'ERR_INVALID_ARG_TYPE',
293-
message: /The "options\.inverse\.length" property must be an integer/,
294-
}, `length=${String(value)}`);
295-
}
296-
});
297-
298-
test('a normal function length is still accepted', (t) => {
299-
const db = new DatabaseSync(':memory:');
300-
db.function('plus', (a, b) => a + b);
301-
t.assert.strictEqual(db.prepare('SELECT plus(1, 2) AS v').get().v, 3);
302-
});
303-
});

0 commit comments

Comments
 (0)