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?

Add Comment
1 Answer(s)

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.)

Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.