JEST: moduleName.startsWith is not a function - node.js

Setup
OS: macOS
JEST version:
$ jest --version
29.4.2
Goal
npm install -g node-red
npm install -g node-red-node-test-helper
I'm testing Node-RED by wrapping its node-red-node-test-helper companion package, with which I write a wrapper class to use the helper internally:
class FlowTester {
constructor() {
this.helper = require(Path.resolve(`${globalNodeModuleDir}/node-red-node-test-helper`));
}
init() {
this.helper.init(require(Path.resolve(`${globalNodeModuleDir}/node-red`)));
}
defineDefaultFixtureForEach() {
beforeEach((done) => {
this.helper.startServer(done);
});
afterEach((done) => {
this.helper.unload().then(() => {
this.helper.stopServer(done);
});
});
}
...
Here to clarify, due to architecture decisions, we found that node-red-node-test-helper cannot be installed as a local dependency inside the wrapper's package, but have to be installed globally instead. So we use absolaute path to require it.
Then in my individual node (think of it as a NodeJS package) package.json
{
...
"scripts": {
"test": "jest"
},
...
}
Finally I run the test:
cd my_node
npm test
Problem
Although my JEST tests all pass, but a warning pops up:
console.log
16:03:44  TypeError: moduleName.startsWith is not a function
16:03:44  at Resolver.isCoreModule (/usr/local/lib/node_modules/jest/node_modules/jest-resolve/build/resolver.js:452:20)
16:03:44  at Resolver._getModuleType (/usr/local/lib/node_modules/jest/node_modules/jest-resolve/build/resolver.js:576:17)
16:03:44  at Resolver.getModuleID (/usr/local/lib/node_modules/jest/node_modules/jest-resolve/build/resolver.js:529:29)
16:03:44  at Runtime._shouldMockCjs (/usr/local/lib/node_modules/jest/node_modules/jest-runtime/build/index.js:1815:37)
16:03:44  at Runtime.requireModuleOrMock (/usr/local/lib/node_modules/jest/node_modules/jest-runtime/build/index.js:1145:16)
16:03:44  at NodeTestHelper._initRuntime (/usr/local/lib/node_modules/node-red-node-test-helper/index.js:89:37)
16:03:44  at NodeTestHelper.init (/usr/local/lib/node_modules/node-red-node-test-helper/index.js:148:18)
16:03:44  at FlowTester.init (/Users/me/_util/node/_flowtest.js:18:15)
16:03:44  at Object.init (/Users/me/my_service/node/test/default/flow.test.js:16:9)
16:03:44  at Runtime._execModule (/usr/local/lib/node_modules/jest/node_modules/jest-runtime/build/index.js:1539:24)
16:03:44  at Runtime._loadModule (/usr/local/lib/node_modules/jest/node_modules/jest-runtime/build/index.js:1122:12)
16:03:44  at Runtime.requireModule (/usr/local/lib/node_modules/jest/node_modules/jest-runtime/build/index.js:982:12)
16:03:44  at jestAdapter (/usr/local/lib/node_modules/jest/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:77:13)
16:03:44  at processTicksAndRejections (internal/process/task_queues.js:95:5)
16:03:44  at runTestInternal (/usr/local/lib/node_modules/jest/node_modules/jest-runner/build/runTest.js:367:16)
16:03:44  at runTest (/usr/local/lib/node_modules/jest/node_modules/jest-runner/build/runTest.js:444:34)
16:03:44 
16:03:44  at NodeTestHelper._initRuntime (../../../../../../../../usr/local/lib/n
Analysis
The error looks like a type error to me. But the "mock" keyword among the callstack is suspicious because I haven't called any mocking API.
Question
A casual SO search didn't get me anywhere close.
I have no clue how a simple wrapper can cause this.
Is it the way I require the global package that's wrong?

Finally solved this.
The problem is that I misused require when importing node-red module.
The warning is gone after I changed this line
this.helper.init(require(Path.resolve(`${globalNodeModuleDir}/node-red`)));
to
this.helper.init(require.resolve(Path.resolve(`${globalNodeModuleDir}/node-red`)));
Basically I must use require.resolve() when importing node-red here.

Related

Jest can not deal with insertAdjacentElement?

I want to test a quite simple JS function
export function displaySpinner() {
const loadingOverlayDOM = document.createElement('DIV');
const spinner = document.createElement('IMG');
loadingOverlayDOM.id = 'overlay-spinner';
loadingOverlayDOM.className = 'content-overlay';
spinner.className = 'is-spinning';
spinner.setAttribute('src', '/assets/img/svg/icons/spinner.svg');
l loadingOverlayDOM.insertAdjacentElement('beforeend', spinner);
document.body.insertAdjacentElement('beforeend', loadingOverlayDOM);
}
with this (for the purpose of this issue stripped down) Jest test code:
test('displaySpinner displays the spinner overlay in the current page', () => {
utils.displaySpinner();
});
But the test run yells at me:
FAIL app/helper/utils.test.js
● utils › displaySpinner displays the spinner overlay in the current page
TypeError: loadingOverlayDOM.insertAdjacentElement is not a function
at Object.displaySpinner (app/helper/utils.js:185:439)
at Object.<anonymous> (app/helper/utils.test.js:87:15)
at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
at process._tickCallback (internal/process/next_tick.js:109:7)
Is this an error in Jest or am I missing something here?
I finally found the answer myself:
Jest uses jsdom which does not yet support the DOM function insertAdjacentElement (see this issue on GitHub and it's references). So I'll have to wait until jsdom implements it or use another method in my JS.
You can replace the default version of jsdom with an up-to-date version (e.g. 14) by installing the corresponding module:
npm install --save-dev jest-environment-jsdom-fourteen
or using yarn:
yarn add jest-environment-jsdom-fourteen --dev
and then using the jest testEnvironment config parameter:
{
"testEnvironment": "jest-environment-jsdom-fourteen"
}
Note that if you launch jest with the --env=jsdom argument, this will override the config file, so you need to remove it.

Adding server side code to angular-cli project conflicts with node typings

When adding a basic express.js configuration (using TypeScript) to an Angular2 project that was initialized with angular-cli ng new [project-name], I need to add the following typing to compile the express server using gulp:
typings install --ambient --save node
This adds the following line to typings/browser.d.ts and typings/main.d.ts
/// <reference path="browser/ambient/node/index.d.ts" />
and
/// <reference path="main/ambient/node/index.d.ts" />
In the express server.ts file I can add a reference to main instead of browser to keep TypeScript happy
/// <reference path="../typings/main.d.ts" />
But when I leave the node typing reference in the browser.d.ts file, the ng build command will fail:
Build failed.
The Broccoli Plugin: [BroccoliTypeScriptCompiler] failed with:
Error: Typescript found the following errors:
C:/Users/user123/Downloads/my-catalog-master/my-catalog-master/tmp/broccoli_type_script_compiler-input_base_path-7VFCE2dg.tmp/0/src/typings.d.ts (3, 13): Subsequent variable declarations must have the same type. Variable 'module' must be of type 'NodeModule', but here has type '{ id: string; }'.
at BroccoliTypeScriptCompiler._doIncrementalBuild (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:115:19)
at BroccoliTypeScriptCompiler.build (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:43:10)
at C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\broccoli-caching-writer\index.js:152:21
at lib$rsvp$$internal$$tryCatch (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\broccoli-caching-writer\node_modules\rsvp\dist\rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\broccoli-caching-writer\node_modules\rsvp\dist\rsvp.js:1048:17)
at lib$rsvp$$internal$$publish (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\broccoli-caching-writer\node_modules\rsvp\dist\rsvp.js:1019:11)
at lib$rsvp$asap$$flush (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\broccoli-caching-writer\node_modules\rsvp\dist\rsvp.js:1198:9)
at nextTickCallbackWith0Args (node.js:420:9)
at process._tickCallback (node.js:349:13)
The broccoli plugin was instantiated at:
at BroccoliTypeScriptCompiler.Plugin (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\broccoli-caching-writer\node_modules\broccoli-plugin\index.js:10:31)
at BroccoliTypeScriptCompiler.CachingWriter [as constructor] (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\broccoli-caching-writer\index.js:21:10)
at BroccoliTypeScriptCompiler (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:27:10)
at Angular2App._getTsTree (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\lib\broccoli\angular2-app.js:280:18)
at Angular2App._buildTree (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\lib\broccoli\angular2-app.js:101:23)
at new Angular2App (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\lib\broccoli\angular2-app.js:42:23)
at module.exports (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\angular-cli-build.js:6:10)
at Class.module.exports.Task.extend.setupBroccoliBuilder (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\lib\models\builder.js:55:19)
at Class.module.exports.Task.extend.init (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\lib\models\builder.js:89:10)
at new Class (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\node_modules\core-object\core-object.js:18:12)
at Class.module.exports.Task.extend.run (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\lib\tasks\build.js:15:19)
at C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\lib\commands\build.js:32:24
at lib$rsvp$$internal$$tryCatch (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1048:17)
at lib$rsvp$$internal$$publish (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1019:11)
at lib$rsvp$asap$$flush (C:\Users\user123\Downloads\my-catalog-master\my-catalog-master\node_modules\angular-cli\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1198:9)
I could delete the line for now in browser.d.ts so it starts working again but that's not ideal when re-installing typings. I'm currently using angular-cli v1.0.0-beta.0
The actual error originates from the src/typings.d.ts file. Angular-cli creates this typings.d.ts file with the following content:
/// <reference path="../typings/browser.d.ts" />
declare var module: { id: string };
Removing this file solved the problem and the application is still working.
I was able to resolve this by changing src/typings.d.ts
From
declare var module: { id: string };
To
declare var module: NodeModule;
And making sure that I had typings for Node 4 via typings install node-4 --ambient --save.
The error about .spec.ts file. When i update
'#angular/testing';
code like
'#angular/core/testing';
my error resolved;
import {
describe,
ddescribe,
expect,
iit,
it
} from '#angular/testing';
import {Hero} from './hero';
describe('Hero', () => {
it('should create an instance', () => {
expect(new Hero()).toBeTruthy();
});
});

How do I get jest to ignore the fairly common `debug` node package?

I've got a node js module that looks like this
"use strict";
var debug = require('debug')('foo');
var Foo = function() {
this.x = 123;
debug("init");
};
module.exports = Foo;
And my test looks like this
jest.dontMock('../lib/foo');
jest.dontMock('debug');
describe('footest', function() {
it('checks the foo', function() {
var Foo = require('../lib/foo');
var foo = new Foo();
expect(foo.x).toBe(123);
});
});
But when I run jest with
node node_modules/jest-cli/bin/jest.js
I get
Found 1 matching tests...
FAIL __tests__/foo-test.js (0.02s)
? footest › it checks the foo
- TypeError: /Users/gregg/src/jest-test/lib/foo.js: /Users/gregg/src/jest-test/node_modules/debug/node.js: Cannot read property 'buffer' of undefined
at Socket.self [as bytesWritten] (net.js:688:8)
at _getMetadata (/Users/gregg/src/jest-test/node_modules/jest-cli/src/lib/moduleMocker.js:279:49)
at _getMetadata (/Users/gregg/src/jest-test/node_modules/jest-cli/src/lib/moduleMocker.js:286:23)
at _getMetadata (/Users/gregg/src/jest-test/node_modules/jest-cli/src/lib/moduleMocker.js:279:27)
at _getMetadata (/Users/gregg/src/jest-test/node_modules/jest-cli/src/lib/moduleMocker.js:279:27)
at Object.module.exports.getMetadata (/Users/gregg/src/jest-test/node_modules/jest-cli/src/lib/moduleMocker.js:388:20)
at Loader._generateMock (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:280:56)
at Loader.requireMock (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:782:43)
at Loader.requireModuleOrMock (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:897:17)
at /Users/gregg/src/jest-test/node_modules/debug/node.js:6:11
at Object.runContentWithLocalBindings (/Users/gregg/src/jest-test/node_modules/jest-cli/src/lib/utils.js:309:17)
at Loader._execModule (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:243:9)
at Loader.requireModule (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:879:10)
at Loader.requireModuleOrMock (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:899:17)
at /Users/gregg/src/jest-test/lib/foo.js:3:13
at Object.runContentWithLocalBindings (/Users/gregg/src/jest-test/node_modules/jest-cli/src/lib/utils.js:309:17)
at Loader._execModule (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:243:9)
at Loader.requireModule (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:879:10)
at Loader.requireModuleOrMock (/Users/gregg/src/jest-test/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:899:17)
at Spec.<anonymous> (/Users/gregg/src/jest-test/__tests__/foo-test.js:7:14)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
How do I get jest to ignore the debug package and why does it appear to be making a mock when I told it not to?
Right now there is a bug in jest 0.1.18 (being fixed here, documented here) where core node modules cannot be ignored from being mocked.
Once the pull request is accepted by facebook, this problem should go away.
Until then, you can point your package.json to the repo of the fix:
"jest-cli": "git://github.com/adaschevici/jest.git#cf4c6ff97d7009ff8627dd7d3a59cfeff1f3c8b8"
which should resolve that issue.
The reason this happens is because jest.dontMock('debug'); will only prevent mocking the root file of the debug module, while all other internals will still be mocked.
One possible solution could be to prevent mocking debug library using unmockedModulePathPatterns configuration option:
In package.json:
{
"name": "...",
"version": "0.0.0",
...
"jest": {
"unmockedModulePathPatterns": ["/node_modules/debug"]
},
}
At the top of your test file, try this:
jest.autoMockOff();
Then manually mock files with jest.mock(..)
Update: There's a fix that doesn't require you turn off auto mocking. tldr; add debug, tty, and net to jest.unmockedModulePathPatterns in package.json

zombiejs (2.0.0-alpha30) + mochajs (1.17.1) on node 0.10.26

I started working through a book's example code and had the bright idea to update the libraries (node included, from 0.8 -> 0.10). Now there is some breakage & I get this error:
1) Todos Todo creation form should allow to create a todo:
Uncaught Error: connect ECONNREFUSED
at errnoException (net.js:904:11)
at Object.afterConnect [as oncomplete] (net.js:895:19)
I've commented out the assertions to try and locate the issue. It seems like it's a zombiejs centric issue but I'm not sure how to verify that because there are many modules installed as dependencies. There are 10 other tests that pass with most using the login function so I eliminated that from the probabilities. I tried to just post the necessary code snippets. I can provide more if this isn't enough detail. I've found a few stackoverflow posts with this error but the solutions didn't apply. If it turns out to be a zombie issue I will post something on their bug site.
it('should allow to create a todo', login(function (browser, done) {
Browser.visit('http:localhost:3000/todos/new', function (err) {
if (err) throw err;
//browser
// .fill('textarea[name="what]', 'Test todo')
// .pressButton('input[type="submit"]', function (err) {
// if (err) throw err;
//browser.assert.pathname('/todos', 'should be redirected to /todos');
//finish assertions
//browser.assert.elements('#todo-list tr.todo', 1, 'To-Do list should contain 1 item');
//});
});
}));
The main entries in package.json:
"dependencies": {
"union": "0.4.0",
"flatiron": "0.3.x",
"plates": "0.4.x",
"node-static": "0.7.x",
"nano":"5.x.x",
"flatware-cookie-parser" : "0.1.x" ,
"flatware-session": "0.1.x"
},
"devDependencies": {
"mocha" : "latest",
"zombie": "latest"
},
Thanks!!!
Ah, it was a stupid user error. I forgot to tell mocha the test was "done();". I added done to the end of the test case...tests are working as expected. Thanks!

Node-Webkit with external module containing native code

I'm using node-webkit with an external module called edge.
According to the node-webkit docs modules that contain native code must be recompiled using nw-gyp as oppose to node-gyp. I was able to recompile without error and node-webkit seems to import the module OK.
Heres my code. The code I'm trying to use:
var edge = require('edge.node');
var hello = edge.func(function () {/*
async (input) =>
{
return ".NET welcomes " + input.ToString();
}
*/});
hello('Node.js', function (error, result) {
if (error) throw error;
console.log(result);
});
Which throws the following error when run within node-webkit.
Uncaught TypeError: Object [object Object] has no method 'func'
If write the object out to console.log I can see:
Object {initializeClrFunc: function}
initializeClrFunc: function () { [native code] }
__proto__: Object
So the module seems to have loaded. If I run the same code outside of node-webkit, everything works perfectly and I can access the func function. This is driving me crazy - and any help would be really appreciated.
func method is provided by edge.js, the wrapper around edge.node native module. So you should replace require('edge.node') by require('edge').

Resources