0xdw
0xdw

Reputation: 3842

Chai's satisfy function is not returning the expected value

So I have an object like below and I wanna check both "" and String. I mean the test case should pass whether it is a string literal or a string object.

The js file

// * Changing this object to solve the issue is not allowed
const obj = {
  a: {
    format: "url"
  },
  b: {
    format: String
  }
};

As you can see a's format is a string literal while b's format is an object.

The wired case is I'm curious that what kind of value is coming under s parameter (in the test case satisfy). Because it keeps returning false for b's format but true for a's format.

The mocha test file

it('`format` should be a string', () => {
  // this returns true
  chai.expect(obj.a.format).to.satisfy(function (s) {
    return (typeof (s) === 'string') || (s instanceof String);
  });
  // sadly this returns false
  chai.expect(obj.b.format).to.satisfy(function (s) {
    return (typeof (s) === 'string') || (s instanceof String);
  });
});

The test output

`format` should be a string:

AssertionError: expected [Function: String] to satisfy [Function]
+ expected - actual

-false
+true

What is the issue here? I was hoping that obj.a.format should addressed by typeof(s) === 'string' while obj.b.format addressed by s instanceof String? And how do I make the test case to accept both scenarios, whether it is a "string" or String?

Upvotes: 0

Views: 447

Answers (1)

Remember: the type of "string" is string, because it's a string. Nothing weird there. But the type of String is object, because it's the String prototype object, and a prototype is by definition not an instance of itself, so neither typeof (s) === 'string' or s instanceof String will be true. So if you want to check if b is a string instance or the actual String prototype, use s === String, not s instanceof String.

Upvotes: 1

Related Questions