Ava test runner in my project has its own env variables defined like this in package.json:
"ava": {
"require": [
"esm"
],
"files": [
"test/unit/**/**/ava-*"
],
"environmentVariables": {
"SERVER_DEFAULT_TIMEZONE": "Australia/Sydney",
"PAY_MAX": "false",
"NODE_ENV": "development"
},
"timeout": "20s"
},
Now when doing a unit test for a certain file it happens that I need to cover this line in the function that I'm testing:
const isPayMax = process.env.PAY_MAX === "true";
So I'm trying to make that condition true so I can cover in my test. However, no matter I tried setting it to "true" or any other value, it still keep the value defined in package.json.
I've also tried using rewire module but it doesn't seem to work as well.
Also tried setting manually the environment variable in my test file like this process.env.PAY_MAX = "true" but no luck as well.
Any thoughts on how to deal with this? Thanks.
Related
I'm struggeling now for a couple of days to get my testsetup running. Rough outline: Vite, Svelte (with ts), Jest.
I'm using import.meta.env.SOMENAME for my environment vars although this works fine for development as soon as a component uses import.meta.env the test will fail with:
SyntaxError: Cannot use 'import.meta' outside a module
I've tried different transformers, babel-plugins and configs but never succeeded...
My jest config:
"jest": {
"globals": {
"ts-jest": {
"isolatedModules": true
}
},
"verbose": true,
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.ts$": "ts-jest",
"^.+\\.js$": "babel-jest"
},
"setupFilesAfterEnv": ["<rootDir>/setupTests.ts"],
"moduleFileExtensions": ["js", "ts", "svelte"]
}
babel.config.js
module.exports = {
presets: [
[
"#babel/preset-env",
{
targets: {
node: "current"
}
}
]
]
};
svelte.config.cjs
const sveltePreprocess = require('svelte-preprocess')
module.exports = {
emitCss: true,
preprocess: sveltePreprocess()
};
Among other things I tried to use #babel/plugin-syntax-import-meta but ended up with the same error. Also vite-jest looked very promising but again I couldn't make it work.
I appreciate every hint I can get. If I can provide any additional info please let me know. Also my knowledge of vite and babel is very limited so REALLY appreciate any help IU can get on this topic.
Update (Solution)
So If you use babel you could use babel-preset-vite. The approach with esbuild-jest from Apu is also good solution that many people use. Unfortunately those things didn't work for me so I decided to use a workaround with vite's define.
This workaround consists of two steps.
replace import.meta.env with process.env (if this is a deal breaker for you then I hope you have luck with the solutions above) You only have to replace the instances in files you want to test with jest.
Update Vite config with define. This step is necessary or your build will break (dev will still work)
vite.config.js
const dotEnvConfig = dotenv.config();
export default defineConfig({
define: {
"process.env.NODE_ENV": `"${process.env.NODE_ENV}"`,
"process.env.VITE_APP_SOMENAME": `"${process.env.VITE_APP_SOMENAME}"`
},
...
)};
I know this is just a workaround but maybe this helps someone. Thanks & Good Luck.
A more recent alternative to Jest that understands import.meta.env is Vitest.
It should require almost no additional configuration to get started and it's highly compatible with Jest so it requires few changes to the actual tests.
The advantages of Vitest over Jest for this use case are:
It's designed specifically for Vite and will process tests on demand
It will reuse your existing Vite configuration:
Any define variables will be replaced as expected
Extensions that Vite adds to import.meta will be available as usual
I was having issues with svelte component testing as well using jest. babel is not good at resolving import.meta. I used esbuild-jest to transform both ts and js files. It solves the issue with the import.meta. Here is my jest.config.cjs.
npm i esbuild esbuild-jest -D
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig');
const config = {
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.(ts|tsx|js|jsx)$": ["esbuild-jest"]
},
"moduleFileExtensions": [
"js",
"ts",
"tsx",
"svelte"
],
"setupFilesAfterEnv": [
"#testing-library/jest-dom/extend-expect"
],
"collectCoverageFrom": [
"**/*.(t|j)s",
"**/*.svelte"
],
coverageProvider: 'v8',
"coverageDirectory": "./coverage",
"coveragePathIgnorePatterns": [
"/node_modules/",
"/.svelte-kit/"
],
"moduleNameMapper": pathsToModuleNameMapper(compilerOptions.paths, {prefix: '<rootDir>/'})
};
module.exports = config;
I'm trying to turn off lint warning for my eslint at VS code.
My code is contains.
console.log('blabla..');
eslint said as below.
error Unexpected console statement no-console
Even though already add no-restricted-syntax at my .eslintrc.json, no fixed.
Here is my .eslintrc.json
{
"env": {
"es6": true,
"node": true,
"amd": true,
"mocha": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module"
},
"rules": {
"linebreak-style": [
"error",
"windows"
],
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.name='console'][callee.property.name=/^(log|warn|error|info|trace)$/]",
"message": "Unexpected property on console object was called"
}
]
}
}
What did I mistake?
Allowing the console.log to stay in code is requiring a separate rule.
You need to add 'no-console' statement to your eslint config rules.
Like so:
rules: {
"no-console": 0
}
A better practice is to warn you about all the console.log in your code, like so:
rules: {
"no-console": 1
}
I followed the advice of Elad and went into the package.json to add the rule of "no-console": 0 and at first it didn't seem like it worked but this is because I needed to restart the development server. If it seems like it's not working, make sure you restart the development server because if you change anything in the package-json, you have to restart your server.
You can add // eslint-disable-line if you need to ignore a specific (or multiple) line
I'm using the following jest.unittest.json file (used via jest --config option):
{
"bail": false,
"verbose": true,
"transform": {
"^.+\\.(ts|tsx)$": "typescript-babel-jest"
},
"testPathIgnorePatterns": [
"<rootDir>/lib",
"<rootDir>/lib_es6",
"/node_modules/",
"fixtures.ts",
"/fixtures/"
],
"moduleFileExtensions": [
"js", "jsx", "ts", "tsx", "node"
],
"roots": [
"<rootDir>/src/__unittests__/Logger",
"<rootDir>/src/__unittests__/Renderer/renderer.test.ts"
],
"testRegex": "<rootDir>/src/__unittests__/.*\\.test.(ts|tsx|js|jsx)$"
}
Note the test files are src/unittests/Renderer/renderer.test.ts, and so on.
It used to work until jest v19, but after upgrading to v20, this config no longer works.
When I do jest --config jest.unittest.json --verbose, I get:
Pattern: "" - 0 matches
Is there anything wrong with my config?
Try to change testRegex to something like that:
"(/src/__unittests__/.*|\\.(test|spec))\\.(ts|tsx|js)$"
I'd say it's interesting, that you configure 2 roots and use only one path in your testRegex. Also in the documentation they catch the path and the file name without extension, which is not the way you do it. Catch the path and filename with the parenthesis. See the documentation there (I'd skip <rootDir> too as you probably want to use both roots): https://jestjs.io/docs/configuration#testregex-string--arraystring
I have a GitHub project that has passed Travis CI. Upon creating a pull request for a new feature, Travis CI fails both pr and push due to two eslint errors:
/home/travis/build/enove/Thriver/packages/thriver-accounts/lib/accounts.js
121:5 error Strings must use singlequote quotes
122:5 error Strings must use singlequote quotes
Lines 119 through 122 of accounts.js are as follows:
119: return `Hello ${user.profile.firstname}!\n\n` +
120: `To verify your account email, simply click the link below.\n\n${url}\n\n` +
121: `If you weren't expecting this email, simply delete it.\n\n` +
122: `Thanks!\n\nAll of us at WCASA`;
The commit did not even change accounts.js, and a local eslint passes without error. I checked and verified that the versions of node, npm, and meteor are the same locally as they are in Travis CI.
The Travis CI configuration is as follows:
{
"sudo": "required",
"language": "node_js",
"node_js": "4.1.1",
"before_install": [
"curl -L https://git.io/ejPSng | /bin/sh"
],
"env": "CXX=g++-4.8",
"addons": {
"apt": {
"sources": [
"ubuntu-toolchain-r-test"
],
"packages": [
"g++-4.8"
]
}
},
"services": "mongodb",
"script": [
"meteor npm run lint"
],
"group": "stable",
"dist": "precise",
"os": "linux"
}
The .eslintrc is as follows:
{
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 6,
"ecmaFeatures": {
"impliedStrict": true
}
},
"env": {
"browser": true,
"node": true,
"mongo": true,
"meteor": true
},
"extends": [
"airbnb"
//"plugin:meteor/recommended"
],
"globals": {
"Thriver": true,
"SimpleSchema": true,
"Marked": true,
"SHA256": true,
"google": true,
"geoXML3": true,
"AutoForm": true,
"details_shim": true
},
"rules": {
"no-underscore-dangle": 0,
"new-cap": 0
}
}
This has happened before in a different file and I "resolved" the issue by having eslint ignore the line. But I can't do that for every mystery issue. Any advice?
http://eslint.org/docs/rules/quotes
This is most likely the fix to your problem.
JavaScript allows you to define strings in one of three ways: double quotes, single quotes, and backticks (as of ECMAScript 6). For example:
/*eslint-env es6*/
var double = "double";
var single = 'single';
var backtick = `backtick`; // ES6 only
The choice of how to define strings in a codebase is a stylistic one outside of template literals (which allow embedded of expressions to be interpreted). Many codebases require strings to be defined in a consistent manner.
I would try setting one of these rules and running the tests again.
Let me know if this does not fix your problem!
I still have no idea how eslint was passing locally. Perhaps I was behind in eslint or airbnb version. However, I realized that the lines really did need to be corrected. The bottom two lines of code should not use back ticks because there aren't any variables in those strings.
119: return `Hello ${user.profile.firstname}!\n\n` +
120: `To verify your account email, simply click the link below.\n\n${url}\n\n` +
121: 'If you weren\'t expecting this email, simply delete it.\n\n' +
122: 'Thanks!\n\nAll of us at WCASA';
Eslint is a lot happier with a concatenated string of different styles than a consistent one where not every segment contains a variable.
I have some qunit tests setup to test my code that extensively uses requirejs. I use Chutzpah to perform the test running within VS. Everything works fine if I run the tests in the browser but not from within VS only. It seems to be ignoring my require.config call. If I change my references in my files to not point to shims but directly to files, it will work, but that breaks other things within my code.
Does anyone have this working? If so, how? I have looked at their example code but it doesn't use require.config and shims.
Start from this tutorial.
To run a config, with shims, just add a reference to your config file in chutzpah.json. Example below, slightly simplified for readability.
The chutzpah.json file
{
"Framework": "qunit",
"TestHarnessReferenceMode": "AMD",
"TestHarnessLocationMode": "SettingsFileAdjacent",
"References": [
{ "Path": "../Scripts/Components/RequireJS/require.js" },
{ "Path": "config.js" }
]
}
The config.js file
require.config({
"paths": {
"jquery": "../Scripts/jquery-2.1.4",
"jquery-linq": "../Scripts/jquery.linq",
"signalr": "../Scripts/jquery.signalR-2.2.0",
"signalrhubs": "../Scripts/mock-signalr-hubs",
"knockout": "../Scripts/knockout-3.3.0",
"constants": "../Scripts/constants",
"HomeVm": "Source/HomeVm"
},
"shim": {
"jquery.linq": {
"deps": ["jquery"]
},
"bootstrap": {
"deps": ["jquery"]
},
"signalr": {
"deps": ["jquery"]
}
}
});