chai-things icon indicating copy to clipboard operation
chai-things copied to clipboard

`Expect` syntax support?

Open ivitivan opened this issue 9 years ago • 14 comments

Hi!

Does it work with expect syntax?

ivitivan avatar Aug 28 '15 10:08 ivitivan

Yes.

RubenVerborgh avatar Aug 28 '15 10:08 RubenVerborgh

I've been trying to wrap some chai-things in expect syntax as a custom assertion for the purposes of use with Serenity-JS but I get an error when I try to do it. Should works fine.

export const AllContainsOrgCode = expected => actual => actual.should.eventually.all.have.property('orgCode', expected);
export const AllContainsOrgCodeExpect = expected => actual => expect(actual).to.eventually.all.have.property('orgCode', expected);

The first line works fine but the latter line throws an error: TS2339:Property 'have' does not exist on type 'PromisedKeyFilter'.

weijie-tang avatar Apr 27 '17 13:04 weijie-tang

@weijie-tang I'm assuming by .eventually that you're using chai-as-promised as well. Which order are you loading chai-as-promised and chai-things? chai-things needs to be loaded first. The first example below works for me, but not the second:

// Works
chai.use(chaiThings);
chai.use(chaiAsPromised);

it("blah", function () {
  var orgs = Promise.resolve([
    {"orgCode": 42},
    {"orgCode": 42},
  ]);

  return expect(orgs).to.eventually.all.have.property("orgCode", 42);
});
// Doesn't work because of `.use` order
chai.use(chaiAsPromised);
chai.use(chaiThings);

it("blah", function () {
  var orgs = Promise.resolve([
    {"orgCode": 42},
    {"orgCode": 42},
  ]);

  return expect(orgs).to.eventually.all.have.property("orgCode", 42);
});

If that's not the issue, then my second guess is related to a conflict between .all in Chai core and chai-things; it has a different behavior between core and the plugin. This conflict isn't destructive enough to cause my above examples to stop working, but when you combine it with the chai-as-promised TypeScript type definitions (which seem to treat .all based on Chai core instead of chai-things), maybe it's causing a destructive conflict. I don't know enough about TypeScript to troubleshoot further.

meeber avatar Apr 27 '17 22:04 meeber

@meeber I have them imported in the same order as you do and I still get the error.

import chai = require('chai');
chai.use(require('chai-things'));
chai.use(require('chai-as-promised'));
const expect = chai.expect;

weijie-tang avatar Apr 28 '17 11:04 weijie-tang

@weijie-tang Then my best guess is a conflict between chai-as-promised TypeScript type definitions and chai-things. I base that on the error message you're receiving and the fact that my simple example above works with chai-as-promised and chai-things but no TypeScript.

meeber avatar Apr 28 '17 11:04 meeber

Any progress on this? TS2339:Property 'have' does not exist on type 'PromisedKeyFilter' when using TypeScript

ADjenkov avatar Sep 19 '17 06:09 ADjenkov

I think this now is a general problem as chai now also has to.all

dhilgarth avatar Oct 09 '17 09:10 dhilgarth

Hey,

When attempting to use expect alongside chai-things it breaks, stating that:

expected { Object (sql, values) } to have a property 'length'

Order of use is the following:

var chai = require('chai');
chai.should();

chai.use(require('chai-things'));
var expect = chai.expect;

Any hints ?

jorgemachado89 avatar Jan 08 '18 15:01 jorgemachado89

@jorgemachado89 Please also add the code for your assertion. It seems logical that an object { sql, values } does not have a property length.

RubenVerborgh avatar Jan 08 '18 16:01 RubenVerborgh

Thanks for the quick feedback. Here follows an example below:

var chai = require('chai');
chai.should();

chai.use(require('chai-things'));
var expect = chai.expect;

describe('something', function() {
 it('the test description', function() {
    expect({
      sql: 'sasasasa',
      values: [['sasa','sasa'],['sasa','sasasa']]
    })
    .to.be.an('object')
    .to.have.deep.all.keys('sql', 'values');
 }};
});

Returns the following:

AssertionError: expected { Object (sql, values) } to have a property 'length'

Including chai-things, breaks the behaviour of expect from chai

jorgemachado89 avatar Jan 09 '18 15:01 jorgemachado89

@RubenVerborgh any progress on this? We've just encountered this as well:

Including chai-things, breaks the behaviour of expect from chai)

Knaledge avatar Mar 22 '19 21:03 Knaledge

@RubenVerborgh I have not been involved anymore with chai for several years, so I unfortunately cannot advise you on this one.

RubenVerborgh avatar Mar 22 '19 22:03 RubenVerborgh

Could this be solved by replacing the .add with .each?

phil294 avatar Nov 30 '19 13:11 phil294

Tried several ways, but chai-things do not work in typescript:

import { expect, use } from 'chai';
use(require('chai-things'));

expect(actual).all.have.property("Id", fixture.Id);
---
test.ts:162:24 - error TS2339: Property 'have' does not exist on type 'KeyFilter'.

162     expect(actual).all.have.property("Id", fixture.Id);
                           ~~~~

Same result

import * as chai from 'chai';
chai.use(require('chai-things'));
const expect = chai.expect;
...

Crusader4Christ avatar Sep 15 '20 18:09 Crusader4Christ