how to run jest test from multiple locations in VSCode - javascript

I managed to mock typeorm to an extent but then now I'm facing a strange issue that I'll illustrate here.
import { myEntity } from './entity';
import typeorm = require('typeorm');
describe('test suire'), () => {
let myRepository: typeorm.Repository<myEntity>;
test('my test case', () => {
typeorm.Repository = jest.fn().mockReturnValue({
createQueryBuilder: jest.fn().mockReturnValue({
where: jest.fn().mockReturnThis(),
getMany: jest.fn().mockReturnValue([]);
})
});
myRepository = new typeorm.Repository();
expect(myRepository.createQueryBuilder).toHaveBeenCalledTimes(0);
})
})
I have a package structure like this:
root/
package.json
project1/
package.json
src/
the_above_test.spec.ts
When I run node_modules/.bin/jest path_to_above_test.spec.ts from project1 it works. But when I run the same command from root I get:
Matcher error: received value must be a mock or spy function
Received has value: undefined at line:
expect(myRepository.createQueryBuilder).toHaveBeenCalledTimes(0);
The intention here is to debug the test from within VS Code. But since VS code is open at the root level, it executes the test from there. If there's no bug in my code, how can I tell VS Code to run the test from the project1 directory?

You can specify different jest configurations in your /.vscode/launch.json
Each configuration will have it's own working directory, specified using "cwd".
here's a working example:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"name": "functions",
"request": "launch",
"program": "${workspaceFolder}/packages/functions/node_modules/jest/bin/jest",
"args": [
"./test/eventHooks.test.ts",
"--runInBand"
],
"cwd": "${workspaceFolder}/packages/functions",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
},
{
"type": "node",
"name": "functions",
"request": "launch",
"program": "${workspaceFolder}/packages/types/node_modules/jest/bin/jest",
"args": [
"./test/eventHooks.test.ts",
"--runInBand"
],
"cwd": "${workspaceFolder}/packages/types",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}

Related

How to conditional exports from package.json

I have section exports in my package.json:
"exports": {
"import": "./dist/a.es.js",
"require": "./dist/b.umd.js"
},
But for development, I would like to have different path:
"exports": {
"DEV": {
"import": "./src/a.es.js", // <---------- SRC
"require": "./src/b.umd.js" , // <---------- SRC
},
"PROD": {
"import": "./dist/a.es.js",
"require": "./dist/b.umd.js"
}
},
Is there any way how to use some env variable?
I was able to solve this using this setup
In the package that my program imports:
{
"name": "my-special-node-package",
"version": "1.0.0",
"license": "MIT",
"exports": {
".": {
"production": {
"require": "./prod/index.cjs.js",
"import": "./prod/index.esm.js"
},
"default": {
"require": "./index.cjs.js",
"import": "./index.esm.js"
}
},
}
}
And then in my program:
// index.js
const myPkg = require('my-special-node-package')
On production I use node --conditions=production index.js to execute the node program. Otherwise I use node index.js in dev mode.
Also, since I'm using TypeScript and since TypeScript is only really used during development time, I was able to change the default require/import values to point to a index.ts file.
{
// ....
"exports": {
".": {
"production": {
"require": "./dist/index.cjs.js",
"import": "./dist/index.esm.js"
},
"default": "./index.ts"
},
}
}
This setup allows for my local development to always TS files directly and not rely on each package to be built whenever it changes.

How to run mocha in the same file with the JS script

Is it possible to have the JS code and the mocha tests in the same file? The purpose will be to have both the implementation and the tests in the same file when you just want to play with something, learn JS, prepare for an interview, etc.
The file will be executed in VSCode using Debug (F5).
function increment(n) {
return n + 1;
}
mocha.setup("bdd");
const { assert } = chai;
describe('Array', function () {
describe('#indexOf()', function () {
it('should increment', function () {
assert.equal(increment(1), 2);
});
});
});
mocha.run();
Trying to run this example which is how you run mocha tests in browser, I get an error "mocha is not defined"
I ran "npm install --save-dev mocha" and "npm install --save-dev chai".
The file is test1.js.
In app.js I have "require("./test1")".
The launch configuration is:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "pwa-node"
}
]
}
After more googling I found the solution, your Debug launch.json file have to have the below configuration. Basically the program you need to launch is "${workspaceFolder}/node_modules/mocha/bin/_mocha".
You do not need any mocha commands in your JS file: mocha.setup("bdd"); mocha.run();
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Mocha Tests",
"type": "pwa-node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"-u",
"bdd",
"--timeout",
"999999",
"--colors",
"${workspaceFolder}/thon-ly-40-questions"
],
"skipFiles": [
"<node_internals>/**"
],
},
]
}

How do I run babel-plugin-tester with jest?

It should be very simple this one, but I can't run it. I have installed the plugin according the their docs and written a simple example also according to their docs:
test.js:
import pluginTester from 'babel-plugin-tester'
pluginTester({
plugin: identifierReversePlugin,
snapshot: true,
tests: [
{code: '"hello";', snapshot: false},
{
code: 'var hello = "hi";',
output: 'var olleh = "hi";',
},
`
function sayHi(person) {
return 'Hello ' + person + '!'
}
console.log(sayHi('Jenny'))
`,
],
})
// normally you would import this from your plugin module
function identifierReversePlugin() {
return {
name: 'identifier reverse',
visitor: {
Identifier(idPath) {
idPath.node.name = idPath.node.name.split('').reverse().join('')
},
},
}
}
I have installed jest according to jest docs:
npm install jest --save-dev
My package.json file:
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest"
},
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"#babel/cli": "^7.10.1",
"#babel/core": "^7.10.2",
"#babel/preset-env": "^7.10.2",
"babel-jest": "^26.0.1",
"babel-plugin-tester": "^9.2.0",
"jest": "^26.0.1"
}
}
I also have babel config as:
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
I try to run npx jest test.js but it just spits out
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
I can run jest on a simple example without babel-plugin-tester, so everything seems to work, but I probably don't understand how it is intended to be used with jest. I feel so stupid.
This is stupid! I had to rename my testfile to fit *.test.js. Why don't jest trust me that the file I intend to run indeed contains tests?! This is obviously a stupid implementation of jest!!
Hours of wasted time.. thanks to stupid jest

babel-plugin-module-resolver adding extra ../ to path

While I am aware that Babel is capable of transpiling TypeScript itself, I've had enough weird issues I'd like to first transpile TypeScript->JS and then run Babel on that.
I've got my tsconfig.json files working as expected. When I compile my TypeScript (from ./src folder relative to babel.config.json's path), it outputs to a ./build folder. I have Babel set to take what's in the ./build folder and output to the ./dist folder.
The output of TSC shows import {bar} from 'foo' and import {thing} from 'foo/util', as expected. But Babel's output looks like ../../../libfoo/libfoo.js when it should be ../../libfoo/libfoo.js
No matter what I try with root/cwd, I can't seem to get that extra ../ to disappear. I've managed to make it go away a couple times, but then I rebuild without changing the babel config, and it comes back.
My babel.config.json currently looks like this:
{
"presets": [
["#babel/preset-env", {"targets": {
"node": true,
"electron": "80"
}}],
["#babel/preset-typescript", { "onlyRemoveTypeImports": true }]
],
"plugins": [
["babel-plugin-module-resolver", {
"alias": {
"^foo/(.+)": "./libfoo/\\1.js",
"^foo$": "./libfoo/libfoo.js"
}
}],
["#babel/plugin-transform-modules-umd"],
["#babel/plugin-transform-typescript", {
"allowNamespaces": true,
"allowDeclareFields": true,
"onlyRemoveTypeImports": true
}],
["#babel/plugin-proposal-pipeline-operator", { "proposal": "fsharp" }],
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/plugin-proposal-optional-chaining",
"#babel/plugin-proposal-do-expressions",
"#babel/plugin-proposal-logical-assignment-operators",
"#babel/plugin-proposal-partial-application",
["#babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }],
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-throw-expressions",
"#babel/plugin-proposal-export-default-from",
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-function-bind"
],
"sourceMaps": true
}
Well, I found a solution that doesn't really fix the problem but makes it works.
My files structure is something like this:
|-dist
|-src
|-db
|-connect
|-index.ts
|-index.ts
|-.babelrc
When babel compiles the code, the import of db/connect in src/index.ts, go from this:
import ... from "db/connect"
to this:
var _connect = require("../db/connect");
To resolve this, I simply add /dist to the paths in .babelrc
before:
[
"module-resolver",
{
"root": ["./"], # or ["src"] or "src" or ["./src"] or "./src" or any way you can imagine
"alias": {
"db": "./db",
}
}
}
]
after:
[
"module-resolver",
{
"alias": {
"db": "./dist/db",
}
}
}
]
And the import is now:
var _connect = require("../dist/db/connect");
As you said, the root doesn't affect the require path, so I just removed it.
This doesn't fix the problem, but makes it work.
Hope it helps, good luck! :)

How to use JSPM overrides in SystemJS config file?

My JSPM version: 0.17.0-beta.5.
My project is using ES6 style import statement using TypeScript.
So...
I installed angular-ui-router like so:
jspm install angular-ui-router
This saves the following lines to my package.json:
"jspm" {
"overrides": {
"github:angular-ui/ui-router#0.2.17": {
"directories": {
"lib": "release"
},
"format": "cjs",
"main": "angular-ui-router",
"registry": "jspm",
"dependencies": {
"angular": "^1.3.2"
},
"meta": {
"angular-ui-router.js": {
"deps": [
"angular"
]
}
}
},
// ... other stuff
Great! So it says the file that should be loaded is located in the release folder.
But in my browser, I load my jspm.conf.js file, which says:
SystemJS.config({
"packages": {
"github:angular-ui/ui-router#0.2.17": {
"map": {
"angular": "github:angular/bower-angular#1.4.9"
}
},
}
// ... little further
"map": {
"angular-ui-router": "github:angular-ui/ui-router#0.2.17"
}
So there is no notion there that SystemJS should look in the release folder as I mentioned above. Therefor, I can't import like
import 'angular-ui-router'
but only like
import angular-ui-router/release/angular-ui-router
How do I use the overrides from package.json in my SystemJS config file jspm.config.js which is loaded in the browser?

Categories

Resources