Jest --coverage ignores Nest.js controller and service files - jestjs

I have written tests for a Nest.js project for all controller and service files (which are adhering to the usual myApp.service.ts | myApp.controller.ts naming convention).
I can successfully run all tests for the files, however, when I attempt to generate a coverage report with jest --coverage, controller and service files are omitted (regardless of them being tested or not), while all other files are included, including files following similar naming convention, i.e. myApp.module.ts.
My Jest configuration:
{
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
Things I've tried:
Removing *.spec.ts files.
Adding exclusion rules to collectCoverageFrom to make sure that the config is being loaded (it is).
Adding new, more specific rules to collectCoverageFrom, such as **/*.service.ts, **/*.controller.ts as well as absolute paths to specific files.
Adding the same rules to forceCoverageMatch
Nothing has worked thus far.

Same problem here. I solved by clearing jest cache (--clearcache).

I solved the problem by deleting node_modlues, dist and package-lock.json and reinstalled dependencies with yarn. Doing the same with npm didn't work.
Still not quite sure what the cause was.

Related

How can I disable the code coverage folder that PhpStorm creates when tests are run?

With the latest version (currently 2021.1) of PhpStorm when running tests it adds a coverage folder to my src directory.
It appears to be a code coverage report for all files. Is there a way to stop it doing that?
I have never used it and often forget to add it to my .gitignore file and it often gets committed.
For us it is unnecessary.
EDIT 2021-06-03
As per LazyOne's comment below, it does seem to be jest.
I was unaware that it was a jest only issue as I don't use PHP at the moment (though still have the editor).
It only started happening on recent updates hence my confusion.
Setting the coverageDirectory to something different indeed moves the coverage folder.
Removing all coverage settings, and running a test with coverage still does create the folder.
Here is a screenshot of the folder that is being created looks like.
Jest config is currently
{
"globalSetup": "../jest.setup.ts",
"setupFilesAfterEnv": ["../jest.setupFiles.ts"],
"rootDir": "src",
"moduleFileExtensions": ["js", "json", "ts"],
"collectCoverage": true,
"collectCoverageFrom": [
"./**/*.{ts,js}",
"!./**/tests/**/*",
"!./**/mocks/**/*",
"!./**/routes.*",
"!./**/config/**/*",
"!./**/__tests__/**/*",
"!./**/__mocks__/**/*",
"!./**/test/**/*",
"!./**/exports.*",
"!./src/coverage"
],
"coverageReporters": ["text", "text-summary"],
"coverageDirectory": "../coverage",
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)x?$",
"testPathIgnorePatterns": [],
"transform": {
"^.+\\.(ts)?$": "ts-jest"
}
}

Nestjs e2e testing of an application within a monorepo fails to resolve #app import from library with jest despite config in package.json

I'm trying to run e2e tests for a monorepo application that also utilises several libraries from within the monorepo, all imports throughout the application are resolved using "#app" imports, for example import { ConfigService } from "#app/config"
However, when trying to run e2e tests via the command:
"test:public": "jest --config ./apps/public-microservice/test/jest-e2e.json",
Jest throws:
Cannot find module '#app/config' from '../src/public-microservice.module.ts'
I've looked at this demo-repo from #jmcdo29 and can't find anything that is different with my configuration.
I've noticed there was an issue about wrong configurations being generated via jest here in 2019, but it has long been resolved, and my configuration for jest in package.json does indeed mention:
"moduleNameMapper": {
"#app/config/(.*)": "<rootDir>/libs/config/src/$1",
"#app/config": "<rootDir>/libs/config/src",
whilst the local targeted file by the package.json script command only contains:
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
Is there something that's missing from my command or my configuration?
Is there anything I need to specify to tell jest to extend the configuration for jest available in package.json?
Any help investingating this is appreciated, thanks.
I added the "moduleNameMapper" key to my jest e2e suite config and updated the "../" relative paths to match where my libs are, in my specific scenario, it looks like this:
"moduleNameMapper": {
"#app/config/(.*)": "<rootDir>../../../libs/config/src/$1",
"#app/config": "<rootDir>../../../libs/config/src",
},

how to get Jest --watch to run on changes to JSON/YAML files?

I'm running some jest tests with --watch that depend on data fixtures. I want the watch run to trigger when I edit my data files, not just the code.
I've added the following to my package.json specifically adding yaml for moduleFileExtensions but still not having any luck. Based on:
https://jestjs.io/docs/en/configuration#modulefileextensions-arraystring
Is there a setting I could make to the package.json to see if it's even getting picked up at all? I guess next step is to try with a .js config, throw some errors in and see if I'm barking up the wrong tree!
The yaml files are not part of an "import" or otherwise, they are just loaded by my code. So I'm hoping for a way that "touching" the files would re-trigger the watch to run.
Perhaps the watch command needs to also specify what data files to watch?
"jest": {
"verbose": true,
"modulePaths": [
"cdn",
"src"
],
"moduleFileExtensions": [
"js",
"json",
"jsx",
"ts",
"tsx",
"yaml"
]
According to this issue moduleFileExtensions is the right place for configuring additional file extensions to watch. However instead of modulePaths you should use roots to configure directories that you want watched.
Jest definition of modulePaths:
An alternative API to setting the NODE_PATH env variable, modulePaths is an array of absolute paths to additional locations to search when resolving modules.
Modules are resolved before the tests are executed and are not expected to change much. If you're wanting to add directories for Jest to watch then you might consider using the roots config.
Jest definition of roots:
A list of paths to directories that Jest should use to search for files in.
package.json
{
...
"jest": {
"roots": [
"<rootDir>/cdn",
"<rootDir>/src"
],
"moduleFileExtensions": [
"js",
"json",
"jsx",
"ts",
"tsx",
"node",
"yaml",
"yml"
]
}
}
Note that I also added "yml" to moduleFileExtensions just in case you're using yml/yaml.

Typescript project setup with shared package

I have a few premises before starting:
I want a shared package which will be included in three other packages,
typescript,
just one node modules,
multiplatform usage (Windows / Linux),
use dependencies from the shared package,
(live reload will be nice),
not to lose the ability to later publish shared package (the other three packages are web servers, but now is under heavy development),
common scripts build:web build:api build:admin from global package.
My dreamed folder structure is:
/
/node_modules/***
/packages/shared/package.json // Shared dependencies like typeorm, lodash etc..
/packages/shared/src/index.ts
/packages/shared/src/models/User.ts
/packages/web/package.json
/packages/web/tsconfig.json
/packages/web/src/index.ts // first express server (using shared code)
/packages/api/package.json
/packages/api/tsconfig.json
/packages/api/src/index.ts
...
/package.json
/tsconfig.common.json
There are a lot of solutions across the internet - Lerna, typescript project reference, npm / yarn link... but I am not able to find a suitable solution...
For example, this https://github.com/Quramy/lerna-yarn-workspaces-example is cool, but I was not able to setup to run something like this:
// package.json
{
"scripts": {
"debug:web": "concurrently \"(cd packages/shared && tsc -w)\" \"(cd packages/web && tsc -w)\" \"(cd packages/web && nodemon --inspect dist/index.js --watch .. /)\""
...
I want to continuously build the shared package (generate dist/index.js and .ts files) and in nodemon restart server after something changed in ../ (packages folder).
After a few hours I gave up to chance to have code reloading and try that via "easiest-way" I could find - no package in shared but include code directly via:
// shared/index.ts
export const createConnection = () => ....
// web/index.ts
import { createConnection } from 'shared'
it looks like it does not work either:
// tsconfig.json
{
"extends": "../../tsconfig.settings.json",
"compilerOptions": {
"rootDir": "../",
"outDir": "dist",
"baseUrl": "./",
"paths": {
"shared": [ "../shared/src/" ]
}
}
}
the problem is now:
File /shared/src/index.ts is not listed within the file list of the project in tsconfig.json. Projects must list all files or use an 'include' pattern.
Next step is (obviously):
{
"extends": "../../tsconfig.settings.json",
"include": [
"./src/**/*.ts",
"../shared/src/**/*.ts"
],
"compilerOptions": {
"rootDir": "../",
"outDir": "dist",
"baseUrl": "./",
"paths": {
"shared": [ "../shared/src/" ]
}
}
}
This works! No errors, but no files in "dist" also... LOL
I am pretty sure, there is some nice solution, example or it won't work either, but I was not able to find it or build it.
Correct me if I'm wrong, but you need an example where the project is separated to packages in a monorepository, written in Typescript and some of the packages depend on each-other.
If that's the case, I created project like this. I used one of Typescript new features: project references. You can specify other tsconfigs in your config file and you can define a dependency for them. For example: package B depends on package A. Typescript is going to compile B and use its declarations before start compile A.
Here is a small example for the tsconfig
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib"
},
"include": ["src"],
"exclude": ["lib"],
"references": [{ "path": "../util" }, { "path": "../crud-request" }]
}
You can get more informations here: https://www.typescriptlang.org/docs/handbook/projectreferences.html
I used this project as an example to build my own, maybe it'll be useful for you too:
https://github.com/nestjsx/crud

Use non-relative imports using TypeScript's baseurl property without WebPack

I am writing a node web application using TypeScript and Express.
I managed to get everything working, however the issue I have run into is that my imports don't seem to respect the baseUrl option of my tsconfig.json.
Here is how my tsconfig.json looks like:
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"pretty": true,
"sourceMap": true,
"target": "es6",
"outDir": "./dist",
"baseUrl": "./src"
},
"exclude": [
"node_modules"
]
}
As an example, let's say I have the following files:
- dist/
- a/
- car.js
- b/
- hat.js
In car.js I can easily require hat.js by doing:
import hat from '../../b/hat'; // relative version
This works as expected.
However, I also want to be able to do the following:
import hat from 'b/hat'; // absolute version
This does not generate any issues during compilation or shows any IDE errors, as the tsconfig.json specifies the baseUrl as ./src. Thus the above is perfectly valid TypeScript code.
However, my expectation was that the code will compile down to the relative version:
const hat = require('../../b/hat');
Unfortunatly it compiled down to:
const hat = require('b/hat');
and thus predictably does not work.
Other users have solved this issue by using 3rd party tools such as: https://github.com/s-panferov/awesome-typescript-loader
https://decembersoft.com/posts/say-goodbye-to-relative-paths-in-typescript-imports/
But majority of these tools is designed to work with WebPack, which isn't really suitable for an node back-end application. This is because we are running a long-running server, and thus won't benefit from being bundled into a single file versus several different files (unlike front-end web development).
My question is, how can I compile my TypeScript files, without WebPack, so that absolute imports works correctly.
So the way to do it is to transform back the non-relative imports to relative imports after build so that commonjs will recognize them. And the way to easily do it is the following:
Step 1: Install the transform modules:
npm i -D typescript-transform-paths
npm i -D ttypescript
Step 2: Modify tsconfig.json
"compilerOptions: {
...
"plugins": [
{ "transform": "typescript-transform-paths" },
{ "transform": "typescript-transform-paths", "afterDeclarations": true }
]
}
Step 3: Modify package.json
We will use ttypescript to build the project instead of tsc inorder to use transformers.
"build": "ttsc"
Step 4: Build and Start the project
npm run build
npm start
OP I haven't gotten this to work yet, but this article may provide some guidance: https://levelup.gitconnected.com/get-rid-of-relative-import-path-hell-in-your-typescript-project-9952adec2e84
TL;DR
yarn add link-module-alias
package.json
...
"_moduleAliases": {
"~": "dist"
}
...
My question is, how can I compile my TypeScript files, without WebPack, so that absolute imports works correctly.
My opinion
Don't. In fact don't do it even do it with webpack.
Reason
The node resolution algorithm is complicated enough : https://nodejs.org/api/modules.html#modules_all_together and doesn't need to be complicated further with "and oh, now we have baseurl".
If you still want to do it, here are your options.

Resources