Implement String.regex "invalidate" configuration#1035
Conversation
|
(Realized I missed the API doc update. Pushing now) |
lib/string.js
Outdated
|
|
||
| const patternMatch = pattern.test(value); | ||
|
|
||
| if ((patternMatch && !patternIsInvalidated) || (!patternMatch && patternIsInvalidated)) { |
There was a problem hiding this comment.
Clearer with patternMatch ^ patternIsInvalidated.
lib/string.js
Outdated
| const testName = patternIsInvalidated ? 'invalidatedRegex' : 'regex'; | ||
|
|
||
| if (pattern.test(value)) { | ||
| return this._test(testName, pattern, function (value, state, options) { |
There was a problem hiding this comment.
pattern should now become an object with every details in it (name, pattern, invalidated), I wouldn't change the name of the test depending on the options.
There was a problem hiding this comment.
I changed the test name to distinguish between a normal regex test and an inverted regex test in the describe'd value. Using the revision you requested, should the name/pattern/inverted flag just become part of the arg property on the describe?
{
type: 'string',
invalids: [''],
rules: [
{
name: 'regex',
arg: {
pattern: /[a-z]/,
inverted: true
}
}
]
}There was a problem hiding this comment.
It will automatically if you do.
There was a problem hiding this comment.
pattern.pattern gets a bit weird. Especially at this.createError (end up with a pattern: pattern.pattern). How about patternObject with a pattern property?
(Running low on time on my lunch break. Going to move forward with patternObject, but willing to change if you disagree)
lib/string.js
Outdated
| } | ||
|
|
||
| regex(pattern, name) { | ||
| regex(pattern, config) { |
There was a problem hiding this comment.
I prefer the term options, in readme too.
There was a problem hiding this comment.
I was going to use "options", but then I have a variable name clash with the test callback defined on line 103.
There was a problem hiding this comment.
Oh, didn't see that one. patternOptions then ?
API.md
Outdated
| - `name` - optional name for patterns (useful with multiple patterns). Defaults to 'required'. | ||
| - `config` - an optional configuration object with the following supported properties: | ||
| - `name` - optional pattern name. Defaults to `required`. | ||
| - `invalidate` - optional boolean flag. Defaults to `false` behavior. If specified as `true`, the provided pattern will be disallowed instead of required. |
There was a problem hiding this comment.
Not a big fan of invalidate, it makes me think of caching. What about invert ?
API.md
Outdated
| - `pattern` - a regular expression object the string value must match against. | ||
| - `name` - optional name for patterns (useful with multiple patterns). Defaults to 'required'. | ||
| - `config` - an optional configuration object with the following supported properties: | ||
| - `name` - optional pattern name. Defaults to `required`. |
There was a problem hiding this comment.
Same as the original, I have absolutely no idea where that Defaults to required came from, it isn't :)
lib/string.js
Outdated
| pattern = new RegExp(pattern.source, pattern.ignoreCase ? 'i' : undefined); // Future version should break this and forbid unsupported regex flags | ||
|
|
||
| return this._test('regex', pattern, function (value, state, options) { | ||
| const patternIsInvalidated = (typeof config === 'object' && Hoek.reach(config, 'invalidate')); |
There was a problem hiding this comment.
Why use hoek to access it since it's a direct property and you just checked it's an object ?
There was a problem hiding this comment.
Habit. Updating along with other changes. :)
lib/string.js
Outdated
| pattern: new RegExp(pattern.source, pattern.ignoreCase ? 'i' : undefined) // Future version should break this and forbid unsupported regex flags | ||
| }; | ||
|
|
||
| const patternIsInverted = (typeof patternOptions === 'object' && patternOptions.invert); |
There was a problem hiding this comment.
if (typeof patternOptions === 'string') {
patternOjbect.name = patternOptions;
}
else if (typeof patternOptions === 'object') {
patternOjbect.name = patternOptions.name;
patternObject.invert = !!patternOptions.invert;
}There was a problem hiding this comment.
For patternObject.name = patternOptions.name; it looks like I need to have either a conditional check or a fallback value for describe when name isn't provided:
"name": "[undefined]"
Preference here?
There was a problem hiding this comment.
Where are you getting this ? It's not supposed to be stringified.
There was a problem hiding this comment.
I was actually just taking a second look at that. The stringified piece is just because I copied the Lab test output. But I am seeing this:
const schema = Joi.string().regex(/[a-z]/, {
invert: true
});
const description = schema.describe();
console.log(description.rules[0]);
/*
{ name: 'regex',
arg: { pattern: /[a-z]/, name: undefined, invert: true } }
*/If having name: undefined is okay, then no problem. I just wouldn't expect any property at all in this case.
There was a problem hiding this comment.
Just a if then, no ternary.
lib/string.js
Outdated
| } | ||
|
|
||
| return this.createError((name ? 'string.regex.name' : 'string.regex.base'), { name, pattern, value }, state, options); | ||
| const name = typeof patternOptions === 'string' ? |
There was a problem hiding this comment.
This becomes useless with upper snippet.
lib/string.js
Outdated
| const name = typeof patternOptions === 'string' ? | ||
| patternOptions : | ||
| Hoek.reach(patternOptions, 'name'); | ||
| const baseRegex = patternIsInverted ? 'string.regex.inverted' : 'string.regex.base'; |
There was a problem hiding this comment.
The error code can be precalculated outside of the test, we should do that.
|
|
||
| ```js | ||
| const schema = Joi.string().regex(/^[abc]+$/); | ||
|
|
There was a problem hiding this comment.
Missing the simpler inlined string.
API.md
Outdated
| ``` | ||
|
|
||
| #### `string.regex(pattern, [name])` | ||
| #### `string.regex(pattern, [name | config])` |
|
Enough work for you, I have other ideas but I'll try them out locally, thanks a lot ! |
|
Awesome, thanks for the feedback and guidance! |
|
Just pushed a small fix, just so you know what I was aiming for. |
|
Ah, I see. Cool 👍 |
|
This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions. |
Per discussions in #1033 and #1020, refactored
string().regex(pattern, [name])to supportstring().regex(pattern, [name | config])as follows:nameis a string it behaves as currently implemented. No change.configis an object, it supports the following properties:name: {string}, behaves as currently implemented.invalidate: {boolean}, defaults tofalsebehavior; iftrue, disallows the provided regex pattern.Usage: