chaijs / chai

BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
https://chaijs.github.io
MIT License
8.15k stars 698 forks source link

Syntax error in ESM import examples in docs #1628

Open niquedegraaff opened 4 months ago

niquedegraaff commented 4 months ago

Importing chai mocha in current state is just a hell. No matter how i try to import it, it will certainly throw breaking errors.

In the docs, it is stated that when using ESM modules, that we need to use this kind of import statements:

import chai, { expect } from 'chai';
import { request }, chaiHttp from 'chai-http';

chai.use(chaiHttp);

describe('GET /user', () => {
  it('should return the user', done => {
    request('http://example.com')
      .get('/user')
      .end((err, res) => {
        expect(res).to.have.status(200);
        expect(res.body).to.be.an('object');
        done();
      });
  })

How is that correct syntax? I cannot import chai like that. (Yes i have ESM enabled) image

Now if i import it like this,

import { use, expect } from "chai";
import chaiHttp from "chai-http";
import app from "../app/app.js"; // Our app

const chai = use(chaiHttp);

describe("User", () => {
  before(() => {});
  after(() => {});

  it("should create a user", async () => {
    const res = chai.request(app).get("/users/create");
    expect(res).to.have.status(200);
    expect(res).to.be.json;
  });
});

Then it throws the TypeError: chai.request is not a function error and also a deprecation warning: (node:7452) [DEP0151] DeprecationWarning: Package \xxcensoredxx\node_modules\chai-http\ has a "main" field set to "./index", excluding the full filename and extension to the resolved file at "index.js", imported from \xxcensoredxx\test\user.test.js. Automatic extension resolution of the "main" field is deprecated for ES modules. (Usenode --trace-deprecation ...to show where the warning was created)

43081j commented 4 months ago

I think the docs are just slightly ahead of where the code is. Our mistake (i.e the docs got updated but the code didn't yet)

The latter is correct for now - importing and using the use function, then chai.request

In future, request should be imported directly

Also the deprecation notice is correct, we should update our main field to include a file extension. Contributions welcome 🙏

hubcraftjv commented 3 months ago

Now if i import it like this,

import { use, expect } from "chai";
import chaiHttp from "chai-http";
import app from "../app/app.js"; // Our app

const chai = use(chaiHttp);

describe("User", () => {
  before(() => {});
  after(() => {});

  it("should create a user", async () => {
    const res = chai.request(app).get("/users/create");
    expect(res).to.have.status(200);
    expect(res).to.be.json;
  });
});

Any update ? i got the exact same issue here

Update - not exactly a solution but downgrading it to 4.5.0 works for me

43081j commented 3 months ago

https://github.com/chaijs/chai-http?tab=readme-ov-file#application--server

as per the updated readme, it should be chai.request.execute(app) rather than chai.request(app)

this seems clear from the readme, so maybe we just need a notice somewhere to tell you and others it has changed. do you have any suggestions for how this would've been easier to find?

melroyvandenberg commented 2 months ago

Yup same issue as I commented here as well: https://github.com/chaijs/chai/issues/1578#issuecomment-2363573105

melroyvandenberg commented 2 months ago

as per the updated readme, it should be chai.request.execute(app) rather than chai.request(app)

if that is true.. Why is my editor saying this:

image

And then I was looking at the index.d.ts and there we go... oopsy:

image

43081j commented 2 months ago

yes it certainly is chai.request.execute(app), or even better, request.execute(app)

the current readme for chai-http is correct (as it says to use chai.request.execute).

we should probably update it to recommend request.execute instead but that isn't a blocker, as both ways are supported

somewhere down the line, the types are wrong it seems. I'll take a look

in your screenshot of index.d.ts, and in the current index.d.ts in chai-http, it is correct. request is a ChaiHttpRequest which is an object with an execute method