serpapi / serpapi-javascript

Scrape and parse search engine results using SerpApi.
https://serpapi.com
MIT License
45 stars 4 forks source link

Error when running with Jest #10

Closed lalalune closed 1 year ago

lalalune commented 1 year ago

Project is building and working, here's the code: https://github.com/hwchase17/langchainjs/blob/main/langchain/agents/tools/serpapi.ts

Testing with jest: TypeError: Cannot convert undefined or null to object

Other tests work, just something with SerpApi... has this been encountered before?

sebastianquek commented 1 year ago

Interesting. The issue stems from ts-jest/babel-jest trying to transform serpapi's exports to CommonJS although they are already in CommonJS syntax. More specifically the domexception library:

import { test } from "@jest/globals";
import DOMException from "domexception";

test("test", async () => {
  const e1 = new DOMException("Something went wrong", "BadThingsError");
  expect(e1.name).toEqual("BadThingsError");
});
> jest

 FAIL  ./example.test.ts
  ● Test suite failed to run

    TypeError: Cannot convert undefined or null to object
        at Function.getPrototypeOf (<anonymous>)

      1 | import { test } from "@jest/globals";
    > 2 | import DOMException from "domexception";
        | ^
      3 |
      4 | test("test", async () => {
      5 |   const e1 = new DOMException("Something went wrong", "BadThingsError");

      at Object.<anonymous> (node_modules/domexception/lib/utils.js:34:39)
      at Object.<anonymous> (node_modules/domexception/lib/DOMException.js:4:15)
      at Object.<anonymous> (node_modules/domexception/webidl2js-wrapper.js:2:22)
      at Object.<anonymous> (node_modules/domexception/index.js:2:22)
      at Object.<anonymous> (example.test.ts:2:1)

One way to resolve this is to remove transformIgnorePatterns so that the default pattern is used. This excludes node_modules from getting transformed. Unless there was some reason to transform them? [EDIT: see below for a better approach]

--- a/langchain/jest.config.js
+++ b/langchain/jest.config.js
@@ -7,7 +7,5 @@ module.exports = {
     "^.+\\.(ts|tsx)$": "ts-jest",
     "^.+\\.(js)$": "babel-jest",
   },
-  transformIgnorePatterns: [
-  ],
   setupFiles: ["dotenv/config"],
 };

PS: The preset specified in jest.config.js actually isn't doing anything as the transform property is overriding it entirely.


EDIT: Upon diving deeper, the error is thrown here, where the prototype of the async generator function is undefined. Somehow babel is not transforming this correctly even when preset-env includes a plugin to handle this.

A better fix would be to set the babel targets to be node since you probably want langchain to run on node anyway: https://babeljs.io/docs/en/options#targetsnode

--- a/langchain/babel.config.js
+++ b/langchain/babel.config.js
@@ -1,2 +1,6 @@
 // babel.config.js
-module.exports = {presets: ['@babel/preset-env']};
+module.exports = {
+  presets: [
+    ["@babel/preset-env", { targets: { node: true } }],
+  ],
+};
sebastianquek commented 1 year ago

@lalalune I've updated serpapi to 1.1.1 which removes the production dependency on domexception. Let me know if you're still facing issues after the update. Will close this for now.

lalalune commented 1 year ago

@sebastianquek thanks, you rock!!