Jest test failing when using Array.prototype.includes with Typescript?
I started using Array.prototype.includes in this project:
https://github.com/fireflysemantics/validator
It is packaged using the Angular Package Format and the source is in this directory:
https://github.com/fireflysemantics/validator/tree/master/projects/validator
The project builds fine, however when the Jest tests are run this error occurs:
FAIL projects/validator/src/lib/decorators/IsDefined.spec.ts ● should create an error when using validate TypeError: Cannot read property 'includes' of undefined 35 | const mc: MetaClass = ValidationContainer.metaClasses.get(cn); 36 | if (mc) { > 37 | const properties: string[] = mc.properties.filter(p => !exlude.includes(p))
So it seems as if Jest is not picking up the property typescript configuration, which does include:
"lib": [ "dom", "es2018" ]
Thoughts?
You are misinterpreting the error. It’s not that includes
is not allowed.
It’s that it cannot access the property includes
on a value that is undefined
, i.e. apparently you try to do undefined.includes
, so that would mean that exlude
must be undefined
.
In your IsDefined.spec.ts
you are calling validate
like this:
it(`should create an error when using validate`, ()=>{ let IDI = new IsDefinedInvalid(); let e = validate(IDI); expect(e.valid).toBeFalsy(); });
So, you are passing only 1 argument (IDI
) to validate
. However, in validate.ts
you define the function like this:
export function validate(target: any, exlude?: string[]): ObjectErrors { let oes: ObjectErrors = new ObjectErrors(); const cn: string = target.constructor.name; const mc: MetaClass = ValidationContainer.metaClasses.get(cn); if (mc) { const properties: string[] = mc.properties.filter(p => !exlude.includes(p)) properties.forEach(p => { if (!validateProperty(target, p, oes)) { oes.valid = false; } }); } return oes; }
As you can see, validate
takes two arguments – target
and exlude
. (By the way, that is misspelled and should be exclude
with a c
.) Yes, exlude
as marked as optional with ?
, so it’s contractually OK that you omit it, however inside the validate
function you then use exlude
(in the line that crashed) without first checking whether it is undefined
, so you end up calling undefined.includes(p)
!
To be honest, I’m not sure why the TypeScript compiler isn’t complaining at this point. (Maybe a commenter has an idea why…)
Anyway, the solution is to set a default value of []
in the function definition in validate.ts
:
export function validate(target: any, exlude: string[] = []): ObjectErrors {
(Of course it would also work to pass the second argument as empty array when calling the function (validate(IDI, [])
), but then the bug in validate
will still exist.)