Shopware 6 JEST unit test: setup failed with configuration error 'Could not locate module' - jestjs

I try to run a simple test with jest in Shopware 6 custom plugin application.
The test failed with configuration error "Could not locate module"
FAIL component/src/test/sum.spec.js
● Test suite failed to run
Configuration error:
Could not locate module #shopware-ag/admin-extension-sdk/es/data/Criteria mapped as:
#shopware-ag/admin-extension-sdk/umd$1.
Please check your configuration for these entries:
{
"moduleNameMapper": {
"/^#shopware-ag\/admin-extension-sdk\/es(.*)$/": "#shopware-ag/admin-extension-sdk/umd$1"
},
"resolver": undefined
}
> 1 | import Criteria from '#shopware-ag/admin-extension-sdk/es/data/Criteria';
| ^
2 |
3 | // eslint-disable-next-line sw-deprecation-rules/private-feature-declarations
4 | export default Criteria;
at createNoMappedModuleFoundError (../node_modules/jest-resolve/build/resolver.js:759:17)
at Object.<anonymous> (../../../../../../../../../src/Administration/Resources/app/administration/src/core/data/criteria.data.ts:1:1)
at Object.<anonymous> (../../../../../../../../../src/Administration/Resources/app/administration/src/core/data/index.js:2:1)
at Object.<anonymous> (../../../../../../../../../src/Administration/Resources/app/administration/src/core/shopware.ts:34:1)
at Object.<anonymous> (../node_modules/#shopware-ag/jest-preset-sw6-admin/#tool/setup-env-for-shopware.js:8:18)
...
The file #shopware-ag/admin-extension-sdk/es/data/Criteria (Criteria.d.ts) is present.
// package.json
...
...
"dependencies": {
"#babel/preset-typescript": "^7.18.6",
"#babel/runtime": "^7.20.13",
"#shopware-ag/admin-extension-sdk": "^3.0.3"
},
"devDependencies": {
"#babel/core": "^7.20.12",
"#babel/plugin-proposal-decorators": "^7.20.13",
"#babel/plugin-proposal-export-namespace-from": "^7.18.9",
"#babel/plugin-proposal-function-sent": "^7.18.6",
"#babel/plugin-proposal-json-strings": "^7.18.6",
"#babel/plugin-proposal-numeric-separator": "^7.18.6",
"#babel/plugin-proposal-throw-expressions": "^7.18.6",
"#babel/plugin-syntax-dynamic-import": "^7.8.3",
"#babel/plugin-syntax-import-meta": "^7.10.4",
"#babel/plugin-transform-runtime": "^7.19.6",
"#babel/preset-env": "^7.20.2",
"#babel/register": "^7.18.9",
"#shopware-ag/jest-preset-sw6-admin": "^4.0.1",
"#vue/test-utils": "^2.2.10",
"babel-jest": "^29.4.2",
"jest": "^29.4.2",
"jest-environment-jsdom": "^29.4.2"
}
...
My jest config file:
const { join, resolve } = require('path');
process.env.ADMIN_PATH = resolve("../../../../../../../../src/Administration/Resources/app/administration/");
module.exports = {
preset: '#shopware-ag/jest-preset-sw6-admin',
globals: {
// adminPath: process.env.ADMIN_PATH,
adminPath: process.env.ADMIN_PATH,
// projectRoot: process.env.PROJECT_ROOT,
},
rootDir: "./component/",
moduleNameMapper: {
'^test(.*)$': '<rootDir>/test$1',
vue$: 'vue/dist/vue.common.dev.js',
"uuid": require.resolve('uuid'),
},
};
Questions
Why does the mapping fail?
Is there a dependency missing in my package.json?
I miss documentation about this.
Not yet a solution here, what I have done:
re-setup using the Shopware instruction
rewrite the jest.config.js:
const ADMIN_PATH = process.env.ADMIN_PATH = resolve(
"../../../../../../../../src/Administration/Resources/app/administration/"
)
module.exports = {
preset: "#shopware-ag/jest-preset-sw6-admin",
globals: {
adminPath: ADMIN_PATH,
},
moduleNameMapper: {
"uuid": require.resolve('uuid'),
},
};
running test: same mapping error:
Could not locate module
#shopware-ag/admin-extension-sdk/es/data/Criteria mapped as:
#shopware-ag/admin-extension-sdk/umd$1.
debug the request: the mapping error comes from this script
custom/plugins/MyPlugin/src/Resources/app/administration/test/node_modules/#shopware-ag/jest-preset-sw6-admin/jest-preset.js
What i find out, the required imported script is a typescript which import another typescript:
../../../../../../../../../src/Administration/Resources/app/administration/src/core/data/index.js:2:1):
import ChangesetGenerator from './changeset-generator.data';
import Criteria from './criteria.data';
...
export default {
ChangesetGenerator,
Criteria,
...
};
../../../../../../../../src/Administration/Resources/app/administration/src/core/data/criteria.data.ts:
import Criteria from '#shopware-ag/admin-extension-sdk/es/data/Criteria'; // <---this import fails
// eslint-disable-next-line sw-deprecation-rules/private-feature-declarations
export default Criteria;
No glue if the typescript context is relevant, but the further required import of js file is imported without error

Related

[eslint][node.js] eslint-disable not working

I'm trying to disable eslint for a line of code but to no effect.
I tried to tackle the problem as in eslint docs. One approach, used in C:...somepath...\index.js:
/* eslint-disable */
const fetch = (url, init) =>
import('node-fetch').then(({ default: fetch }) => fetch(url, init));
/* eslint-enable */
And another approach, used in C:\Users...somepath...\shared\index.js:
// eslint-disable-next-line
const fetch = (url, init) => import('node-fetch').then(({ default: fetch }) => fetch(url, init));
None of them seem to work as while running npx eslint "**/*.js" I keep on getting:
C:\...somepath...\index.js
6:32 error Parsing error: Unexpected token import
C:\Users\...somepath...\shared\index.js
11:7 error Parsing error: Unexpected token import
I'm using commonjs, and yes, I know that import is not designed to be used out of es modules but according to node-fetch documentation I can do so and the solution is working fine. Yet, eslint is still throwing errors. After failing to add some rules ignoring importing, I decided to just disable the problematic pieces of code.
I'm extending airbnb and my .eslintrc is as simple as that:
{
"extends": "airbnb"
}
Relevant dependencies/devDependencies in package.json:
"dependencies": {
"node": "^16.17.0",
"node-fetch": "^3.2.10",
"npm": "^8.19.1"
},
"devDependencies": {
"#typescript-eslint/eslint-plugin": "^5.36.2",
"#typescript-eslint/parser": "^5.36.2",
"eslint": "^8.2.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"prettier": "2.7.1"
}
I've tried applying /* eslint-disable */ to a whole file to check whether it works at all - no it doesn't. This led me to think whether airbnb doesn't have sth like "noInlineConfig": true set but I checked and it seems like not the case.
Can you please help me with the issue?
In order to use dynamic imports in your code, you need to set the language version to 2020 or higher. The preferred way to do so is to set a predefined environment in your .eslintrc file:
{
"extends": "airbnb",
"env": {
"es2020": true
}
}
to set the language version for a particular file only, use an override:
{
"extends": "airbnb",
"overrides": [{
"files": "./path/to/file.js",
"env": {
"es2020": true
}
}]
}

Why does my NestJS library work only if I installed it from NPM?

I'm making a NestJS library and got a very strange problem. To test my library, I created a simple NestJS project and linked my library via yarn link into it. And when I start my project it always throws me an error, and even if I delete lines of code that produce that error (even though they should not), it throws me another error and this never ends. But if I publish it and install, there are not any errors end everything's working great.
The package.json of my library:
{
"name": "kindagoose",
"version": "1.0.10",
"description": "Integrate Typegoose with NestJS!",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"keywords": [
"nest",
"nestjs",
"mongoose",
"typegoose",
"mongo",
"mongodb"
],
"repository": {
"url": "https://github.com/GrapeoffJS/kindagoose",
"type": "git"
},
"author": "Dmitriy Grape <grapeoff.official#gmail.com>",
"engines": {
"node": ">=16.16.0"
},
"bugs": {
"url": "https://github.com/GrapeoffJS/kindagoose/issues",
"email": "grapeoff.official#gmail.com"
},
"scripts": {
"build": "rimraf dist && tsc -p tsconfig.json",
"build:dev": "rimraf dist && tsc --watch -p tsconfig.json",
"prepare": "yarn build"
},
"license": "GPL-3.0-only",
"private": false,
"devDependencies": {
"#nestjs/common": "^9.0.7",
"#nestjs/core": "^9.0.7",
"#typegoose/typegoose": "^9.11.0",
"mongoose": "^6.5.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.5.6",
"#types/mongoose": "^5.11.97",
"#typescript-eslint/eslint-plugin": "^5.31.0",
"#typescript-eslint/parser": "^5.31.0",
"eslint": "^8.20.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-security": "^1.5.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-sonarjs": "^0.14.0",
"eslint-plugin-unicorn": "^43.0.2",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"typescript": "^4.7.4"
},
"peerDependencies": {
"#nestjs/common": "^9.0.0",
"#nestjs/core": "^9.0.0",
"#typegoose/typegoose": "^9.11.0",
"mongoose": "^6.5.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.5.6"
}
}
One of errors:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the KindagooseCoreModule (KindagooseConnectionName, ?). Please make sure that the argument ModuleRef at index [1] is available in the KindagooseCoreModule context.
Potential solutions:
- If ModuleRef is a provider, is it part of the current KindagooseCoreModule?
- If ModuleRef is exported from a separate #Module, is that module imported within KindagooseCoreModule?
#Module({
imports: [ /* the Module containing ModuleRef */ ]
})
Error: Nest can't resolve dependencies of the KindagooseCoreModule (KindagooseConnectionName, ?). Please make sure that the argument ModuleRef at index [1] is available in the
KindagooseCoreModule context.
Potential solutions:
- If ModuleRef is a provider, is it part of the current KindagooseCoreModule?
- If ModuleRef is exported from a separate #Module, is that module imported within KindagooseCoreModule?
#Module({
imports: [ /* the Module containing ModuleRef */ ]
})
at Injector.lookupComponentInParentModules (D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\injector.js:241:19)
at Injector.resolveComponentInstance (D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\injector.js:194:33)
at resolveParam (D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\injector.js:116:38)
at async Promise.all (index 1)
at Injector.resolveConstructorParams (D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\injector.js:131:27)
at Injector.loadInstance (D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\injector.js:57:13)
at Injector.loadProvider (D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\injector.js:84:9)
at async Promise.all (index 0)
at InstanceLoader.createInstancesOfProviders (D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\instance-loader.js:44:9)
at D:\WebStorm\kindagoose-test\node_modules\#nestjs\core\injector\instance-loader.js:29:13
Source code: https://github.com/GrapeoffJS/kindagoose
that's due to how nodejs module resolution works. You might have multiple #nestjs/core module loaded in your app. Search for moduleRef here: https://docs.nestjs.com/faq/common-errors

jest-mongodb error: TypeError: Class extends value undefined is not a constructor or null

I'm trying to run tests with jest on a basic mongodb set-up with express. following the instructions in the jestjs.io documentation. When I run may package.json script: "test": "jest" I get the following error:
TypeError: Class extends value undefined is not a constructor or null
at Object.<anonymous> (node_modules/#shelf/jest-mongodb/environment.js:20:49)
The line in environment.js referenced above is:
module.exports = class MongoEnvironment extends TestEnvironment {
So the TestEnvironmentclass is undefined. Judging from other stack discussions it looks like there's some circular reference issue. Possibly to be solved by changing the order of how the modules are run, but I don't know how to do this?
I've tried changing my version of node, and I've also tried deleting my node_modules and reinstalling. When I run yarn check it tells me all my packages are in sync.
package.json:
...
"dependencies": {
"dotenv": "^16.0.1",
"express": "^4.18.1",
"mongodb": "^4.6.0"
},
"devDependencies": {
"#babel/core": "^7.18.2",
"#babel/preset-env": "^7.18.2",
"#babel/preset-typescript": "^7.17.12",
"#shelf/jest-mongodb": "^3.0.0",
"#types/express": "^4.17.13",
"#types/jest": "^27.5.1",
"#types/mongodb": "^4.0.7",
"#types/node": "^17.0.36",
"jest": "^28.1.0",
"jest-environment-node": "^27.0.0",
"ts-jest": "^28.0.3",
"ts-node-dev": "^2.0.0",
"typescript": "^4.7.2"
},
...
I was able to solve it from:
const NodeEnvironment = require('jest-environment-node')
to:
const NodeEnvironment = require('jest-environment-node').default
I got rid of this error by updating:
"jest-environment-node": "^27.0.0",
to
"jest-environment-node": "^28.1.0",

Import HTML as string and test with Jest

I'm using sveltekit and I can't use the files api to import html templates. So I decided to import by writing a module that imports the content of the document as a string (described here).
// src/global.d.ts
/// <reference types="#sveltejs/kit" />
declare module '*.html' {
const content: string
export default content
}
So far so good, but now I need to test the code and jest can't interpret the code.
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/home/developer/workspace/src/assets/html/confirm_email.html:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){<!DOCTYPE html>
^
SyntaxError: Unexpected token '<'
I don't understand how jest understands the .d.ts files... How do I get to test the code?
Do you install #babel/plugin-transform-runtime"?
I share my config for jest/svelte-jester..
I have:
jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"$lib": ["src/lib"],
"$lib/*": ["src/lib/*"]
}
},
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"],
}
svelte.config.js
import vercel from '#sveltejs/adapter-vercel'
/** #type {import('#sveltejs/kit').Config} */
const config = {
kit: {
adapter: vercel(),
vite: {
define: {
'process.env': process.env,
},
},
},
transform: {
"^.+\\.svelte$": ["svelte-jester", { "preprocess": true }]
}
};
export default config;
babel.config.json
{
"presets": [
["#babel/preset-env", { "modules": "auto" }]
],
"plugins": ["babel-plugin-transform-vite-meta-env","#babel/plugin-transform-runtime"]
}
jest.config.js
export default {
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.svelte$": "svelte-jester",
},
"moduleFileExtensions": ["svelte", "js"],
"testEnvironment": "jsdom",
"setupFilesAfterEnv": ["#testing-library/jest-dom/extend-expect"]
}
and whole package.json
{
"name": "sveltekit",
"version": "0.0.1",
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
"package": "svelte-kit package",
"preview": "svelte-kit preview",
"test": "jest src",
"test:watch": "npm run test -- --watch"
},
"devDependencies": {
"#babel/core": "^7.16.12",
"#babel/plugin-transform-modules-commonjs": "^7.16.8",
"#babel/plugin-transform-runtime": "^7.17.0",
"#babel/preset-env": "^7.16.11",
"#supabase/supabase-js": "^1.29.1",
"#sveltejs/adapter-auto": "^1.0.0-next.7",
"#sveltejs/kit": "^1.0.0-next.215",
"#sveltejs/svelte-virtual-list": "^3.0.1",
"#testing-library/svelte": "^3.0.3",
"autoprefixer": "^10.4.1",
"babel-jest": "^27.4.6",
"babel-plugin-transform-vite-meta-env": "^1.0.3",
"jest": "^27.4.7",
"postcss-load-config": "^3.1.1",
"prettier": "^2.5.1",
"prettier-plugin-svelte": "^2.5.1",
"svelte": "^3.44.0",
"svelte-jester": "^2.1.5",
"svelte-lazy": "^1.0.12",
"tailwindcss": "^3.0.8",
"ts-jest": "^27.1.3"
},
"type": "module",
"dependencies": {
"#fontsource/fira-mono": "^4.5.0",
"#lukeed/uuid": "^2.0.0",
"#testing-library/jest-dom": "^5.16.1",
"cookie": "^0.4.1",
"svelte-lazy-image": "^0.2.0",
"swiper": "^8.0.3"
},
"testEnvironment": "jsdom"
}
I hope it will help you.I had a lot of troubles too with setting up jest..
1.Import html as string
I solved the problem using another approach...
I'm using a resource of vite to import the html file as an asset, as can be seen here in the documentation
import confirm_email_template from '../../../assets/html/confirm_email.html?raw'
2.Test using Jest
For production it works perfectly, but for unit testing the code breaks because Jest can't import the asset as a module.
So the second part of the problem was fixed (I don't know if this is the best practice) using asset mocks.
// jest.config.cjs
{
⋮
moduleNameMapper: {
⋮
'([a-zA-Z_ ]+\\.html)\\?raw$': '<rootDir>/__mocks/$1.cjs'
}
⋮
}
To make it work, I created the following folder structure:
__mocks
|
confirm_email.html.cjs
another_asset_mocked.html.cjs
The confirm_email.html.cjs looks like this:
// __mocks/confirm_email.html.cjs
module.exports = '<html>content<html>'

NodeJS [DEP0097] DeprecationWarning:

Can you help me with this error?
(node:6692) [DEP0097] DeprecationWarning: Using a domain property in
MakeCallback is deprecated. Use the async_context v ariant of
MakeCallback or the AsyncResource class instead. Unhandled rejection
Error in plugin "webpack-stream"
the codeis
import gulp from 'gulp';
import yargs from 'yargs';
import sass from 'gulp-sass';
import cleanCSS from 'gulp-clean-css';
import gulpif from 'gulp-if';
import sourcemaps from 'gulp-sourcemaps';
import imagemin from 'gulp-imagemin';
import del from 'del';
import webpack from 'webpack-stream';
export const scripts = () => {
return gulp.src(paths.scripts.src)
.pipe(webpack({
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}]
},
output : {
filename: 'bundle.js'
}
}))
.pipe(gulp.dest(paths.scripts.dest));
}
and from package.json:
"devDependencies": {
"#babel/core": "^7.4.5",
"#babel/preset-env": "^7.4.5",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"babel-register": "^6.26.0",
"del": "^4.1.1",
"gulp": "^4.0.2",
"gulp-clean-css": "^4.2.0",
"gulp-if": "^2.0.2",
"gulp-imagemin": "^6.0.0",
"gulp-sass": "^4.0.2",
"gulp-sourcemaps": "^2.6.5",
"node-sass": "^4.12.0",
"webpack": "^4.32.2",
"webpack-stream": "^5.2.1",
"yargs": "^13.2.4"
}
what should I upgrade/add?
My friend asks me to solve this problem but I can't regenerate this problem with my system.
Until I found this Doc
DEP0097: MakeCallback with domain property#
node v10.0.0
Runtime deprecation.
Type: Runtime
Users of MakeCallback that add the domain property to carry context, should start
using the async_context variant of MakeCallback or CallbackScope, or the
high-level AsyncResource class.
Then After change node version by the upgrade and downgrade it working fine no error got.
It is a specific node v10 problem at runtime.
I don't have any idea from where deprecation show but most of the time it is on async/await and promise code.
This solution works. Use run option with below:
run{ skipUncaughtErrors: true }

Resources