Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 39 additions & 23 deletions src/core/friendly_errors/param_validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function validateParams(p5, fn, lifecycles) {
'Boolean': z.boolean(),
'Function': z.function(),
'Integer': z.number().int(),
'Number': z.number(),
'Number': z.union([z.number(), z.literal(Infinity), z.literal(-Infinity)]),
'Object': z.object({}),
'String': z.string()
};
Expand Down Expand Up @@ -414,31 +414,47 @@ function validateParams(p5, fn, lifecycles) {
const processUnionError = error => {
const expectedTypes = new Set();
let actualType;
let isActualTypeSet = false;

error.errors.forEach(err => {
const issue = err[0];
if (issue) {
if (!actualType) {
actualType = issue.message;
}
const setActualType = (val) => {
if (!isActualTypeSet) {
actualType = val;
isActualTypeSet = true;
}
};

if (issue.code === 'invalid_type') {
actualType = issue.message.split(', received ')[1];
expectedTypes.add(issue.expected);
const processIssues = (issues, path) => {
if (!issues) return;
issues.forEach(err => {
const issue = err[0];
if (issue) {
if (issue.code === 'invalid_union') {
processIssues(issue.errors, issue.path);
} else {
if (issue.code === 'invalid_type') {
setActualType(issue.message.split(', received ')[1]);
expectedTypes.add(issue.expected);
} else if (issue.code === 'invalid_value') {
expectedTypes.add('constant (please refer to documentation for allowed values)');
setActualType(args[path[0]]);
} else if (issue.code === 'custom') {
const match = issue.message.match(/Input not instance of (\w+)/);
if (match) expectedTypes.add(match[1]);
setActualType(undefined);
}
}
}
// The case for constants. Since we don't want to print out the actual
// constant values in the error message, the error message will
// direct users to the documentation.
else if (issue.code === 'invalid_value') {
expectedTypes.add('constant (please refer to documentation for allowed values)');
actualType = args[error.path[0]];
} else if (issue.code === 'custom') {
const match = issue.message.match(/Input not instance of (\w+)/);
if (match) expectedTypes.add(match[1]);
actualType = undefined;
}
}
});
});
};

processIssues(error.errors, error.path);

if (
expectedTypes.has('number') &&
expectedTypes.has('constant (please refer to documentation for allowed values)')
) {
expectedTypes.delete('constant (please refer to documentation for allowed values)');
}

if (expectedTypes.size > 0) {
if (error.path?.length > 0 && args[error.path[0]] instanceof Promise) {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/core/param_errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@

invalidInputs.forEach(({ input }) => {
const result = mockP5Prototype._validate('p5.saturation', input);
assert.isTrue(result.error.startsWith('🌸 p5.js says: Expected Color or array or string at the first parameter, but received'));

Check failure on line 67 in test/unit/core/param_errors.js

View workflow job for this annotation

GitHub Actions / test

test/unit/core/param_errors.js > Validate Params > validateParams: multiple types allowed for single parameter > saturation(): invalid inputs

AssertionError: expected false to be true - Expected + Received - true + false ❯ test/unit/core/param_errors.js:67:16 ❯ test/unit/core/param_errors.js:65:21

Check failure on line 67 in test/unit/core/param_errors.js

View workflow job for this annotation

GitHub Actions / test

test/unit/core/param_errors.js > Validate Params > validateParams: multiple types allowed for single parameter > saturation(): invalid inputs

AssertionError: expected false to be true - Expected + Received - true + false ❯ test/unit/core/param_errors.js:67:16 ❯ test/unit/core/param_errors.js:65:21
});
});
});
Expand Down Expand Up @@ -279,4 +279,4 @@
assert.isFalse(result.success);
});
});
});
});
Loading