karma-typescript: import JS file with Async keyword - async-await

I'm using karma-typescript, with this karma config file :
karmaTypescriptConfig: {
compilerOptions: {
target: "es5",
lib: ["dom", "es2015", "es2017"]
},
bundlerOptions: {
transforms: [require("karma-typescript-es6-transform")()]
}
},
In my spec files, I have this code :
import {} from './local/lib.js'
In my lib.js, I have this code :
async function() {}
When executing my tests with npm test, I have this error :
ERROR [source-reader.karma-typescript] Error parsing code: Unexpected token (X:Y) in /local/lib.js
If I remove the async keyword, everything is alright.
How can I edit my karma config file to fix the error ?

According to an issue in the Github of the karma-typescript package (https://github.com/monounity/karma-typescript/issues/344), there is an undocumented flag which may help you test code which contains ES2017 code:
karmaTypescriptConfig: {
compilerOptions: {
target: "es5",
lib: ["dom", "es2015", "es2017"]
},
bundlerOptions: {
acornOptions: {
ecmaVersion: 8,
},
transforms: [require("karma-typescript-es6-transform")()]
}
},
This flag made appear our issues with the async keyword. However, there is still an issue with the spread syntax (...array) in our code, even using this flag. If anyone knows an answer how to also fix that, I will happily extend my answer.

Related

Unable to load .mjs file and run tests with Mocha

I am unable to load an .mjs file and run tests with mocha.
I have tried mocha v.7.2.0 with flag --experimental-modules and v.10.0.0 without flag.
I am using node v.14.15.4.
The import statement that I have in my code to test is:
import * as XLSX from 'xlsx/xlsx.mjs';
NB: this import statement works 100% fine while building my app with Webpack.
The error I get when I try to run unit tests on this code with Mocha is:
(node:5452) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use node --trace-warnings ... to show where the warning was created)
C:\Users......webapp\node_modules\xlsx\xlsx.mjs:81
export { set_cptable };
^^^^^^
SyntaxError: Unexpected token 'export' at wrapSafe (internal/modules/cjs/loader.js:979:16)
My mocha invocation is a vanilla mocha \"src/**/*.spec.js\", which I call through an npm task; as I mentioned before, flag --experimental-modules does not help.
My .babelrc, which (I suspect) is used to transpile my code, is the following:
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-transform-runtime",
"react-hot-loader/babel",
["module-resolver", {
"alias": {
"#src": "./src"
}
}]
],
"env": {
"coverage": {
"plugins": [
"istanbul"
]
}
}
}
What can I do to solve this problem?

TS-Node with Mocha doesn't use TS_NODE_PROJECT

I'm having trouble with using the env variable TS_NODE_PROJECT when ts-node is used for testing using Mocha.
The project structure looks like this:
src/
main_test.ts
tsconfig.json
package.json
In my test, I want to use an async function, which requires "lib": ["es2018"] as a compilation option.
// src/main_test.ts
describe('', () => {
it('test', () => {
(async function() {})()
});
});
// src/tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"lib": ["es2018"]
},
"exclude": [
"../node_modules"
]
}
To run the test, I use this command, but it results in an error:
TS_NODE_PROJECT='src' && mocha --require ts-node/register src/*_test.ts
# TSError: тип Unable to compile TypeScript:
# error TS2468: Cannot find global value 'Promise'.
# src/main_test.ts(3,10): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
This means that src/tsconfig.json is not used. According to Overriding `tsconfig.json` for ts-node in mocha
and the ts-node documentation, the command should pass the correct tsconfig.json path to ts-node.
Moving src/tsconfig.json to project directory and running the same command causes the test to succeed. How can I pass the tsconfig.json path to ts-node so that the test compiles correctly?
Oh. How embarrassing...
TS_NODE_PROJECT='src/tsconfig.json' mocha --require ts-node/register src/*_test.ts
I find very useful to move mocha setup in different files so package.json remains clean, you can use a mocharc file like this:
module.exports = {
ignore: [
'./test/helpers/**/*',
'./test/mocha.env.js'
],
require: [
'test/mocha.env', // init env here
'ts-node/register'
],
extension: [
'ts'
]
}
and then create the file test/mocha.env.js (or call it as you wish) with this content:
process.env.NODE_ENV = 'test'
process.env.TS_NODE_PROJECT = 'src/tsconfig.json'

Using karma-typescript with graphql-tag loader

I am trying to run tests written in TypeScript using tape and the karma-typescript loader.
In my project I use webpack with graphql-tag/loader and import the queries directly into my TypeScript files like:
import myQuery from "../query/hello.graphql";
These imports are causing issues when I try and run the tests.
module.exports = function (config) {
config.set({
frameworks: ["tap", "karma-typescript"],
files: [
"src/**/*.ts",
"src/**/*.tsx",
"query/**/*.graphql"
],
preprocessors: {
"src/**/*.ts": ["karma-typescript"],
"src/**/*.tsx": ["karma-typescript"]
},
karmaTypescriptConfig: {
compilerOptions: {
"skipLibCheck": true,
"allowSyntheticDefaultImports": true
},
bundlerOptions: {
transforms: [
require("karma-typescript-es6-transform")()
]
}
},
reporters: ["progress", "karma-typescript"],
browsers: ["Firefox"]
});
};
I guess that I would ideally like to perform a second transform on the .graphql files. Based on the approach used in jest-transform-graphql, I tried adding another transform:
function (context, callback) {
if (/\.graphql$/.test(context.module)) {
context.source = loader.call({ cacheable() { } }, context.source);
return callback(undefined, true);
}
return callback(undefined, false);
}
But I still get errors like:
{
"message": "SyntaxError: unexpected token: identifier\nat query/hello.graphql:1:6\n\n",
"str": "SyntaxError: unexpected token: identifier\nat query/hello.graphql:1:6\n\n"
}
How can I apply the transformation to the graphql files, so that I don't get syntax errors from them in the browser?

Uncaught Error: Module name "lib/chai" has not been loaded yet for context: use require([])

i m using karma-mocha ..my karma.conf file is working with karma-jasmine...but not working with karma-mocha....my karma.conf file:--
module.exports = function(config){
config.set({
basePath : '../app',
preprocessors: {
'**/*.html':'ng-html2js'
},
ngHtml2JsPreprocessor: {
prependPrefix: '/'
},
files : [
'node_modules/jquery/**/*.js',
'lib/angular/angular.js',
'lib/angular/angular-*.js',
'../test/lib/angular-mocks.js',
'../test/lib/sinon-1.15.0.js',
'../test/chai/chai.js',
'js/**/*.js',
'../test/unit/**/*.js',
'**/*.html'
],
autoWatch : true,
frameworks: ['mocha','requirejs','chai'],
browsers : ['Chrome'],
plugins : [
'karma-chrome-launcher',
'karma-mocha',
'karma-ng-html2js-preprocessor',
'karma-requirejs',
'karma-chai'
],
junitReporter : {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
});
};
you are missing chai lib path files array in which is dependency to mocha.include it.
files : [
'node_modules/jquery/**/*.js',
'lib/angular/angular.js',
'lib/angular/angular-*.js',
'../test/lib/angular-mocks.js',
'../test/lib/sinon-1.15.0.js',
'../test/chai/chai.js',
'js/**/*.js',
'../test/unit/**/*.js',
'**/*.html'
],
I came across a similar situation just with Jasmine.
I'd like to introduce my solution.
Try it what is written in the error message. There is a link to a website: http://requirejs.org/docs/errors.html#notloaded
//If this code is not in a define call,
//DO NOT use require('foo'), but use the async
//callback version:
require(['foo'], function (foo) {
//foo is now loaded.
});
My case written for Jasmine in Coffee script looks like this:
sinon = require(['sinon', 'jasmine-sinon']) (foo)->
Now I can use sinon as an object in my unit test and can also follow the documentation of sinon, as well as jasmin-sinon.

How to set up Browserify with Elixir and Browserify Shim on Laravel 5?

I am trying to set up Browserify with Elixir and Browserify Shim on Laravel 5.2 to use Gulp with my JavaScript files, but I didn't have much luck so far. This should be pretty straightforward to do, but it isn't.
Here is my package.json
{
"private": true,
"devDependencies": {
"gulp": "^3.8.8"
},
"dependencies": {
"bootstrap-sass": "^3.0.0",
"browserify-shim": "^3.8.12",
"jquery": "^2.2.0",
"jquery-ui": "^1.10.5",
"laravel-elixir": "^4.0.0"
},
"browser": {
"app": "./resources/assets/js/app.js",
"utils": "./resources/assets/js/utils.js",
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"app": {
"depends": [
"jquery:$",
"utils:Utils"
]
},
"utils": {
"depends": [
"jquery:$"
]
},
}
}
gulpfile.js
var elixir = require('laravel-elixir');
elixir(function (mix) {
mix.browserify('main.js', './public/js/bundle.js');
});
Entry script main.js looks like this:
var $ = require('jquery');
var Utils = require('utils');
var App = require('app');
app.js
var App = {
init: function(){
console.log(Utils);
Utils.doSomething();
}
//other methods
};
In short: Utils depends on $, and App depends on both $ and Utils.
When I hit gulp from terminal, bundle.js is correctly created. All scripts are wrapped up in Browserify code (as expected). Each script has all included dependencies, like I configured in package.json so this part looks good as well.
The problem is that all my included dependencies are empty objects. For example, Utils in app.js is empty, and I get an error when I try to call its method "doSomething". Console log prints out an empty object "{}" instead of real object. The only correctly included script is jQuery and it's not an empty object.
What could be wrong here? Do I need to make some changes in my JS files or in configuration to make this work? It looks like I'm pretty close to the solution, but it still does not work and I can't use it at all.
It is the easiest solution to directly use 'exports' from browserify-shim property:
"browserify-shim": {
"app": {
"exports": "App",
"depends": [
"jquery:$",
"utils:Utils"
]
},
"utils": {
"exports": "Utils",
"depends": [
"jquery:$"
]
},
}
Take a look at this repo which I believe shows the fixed version of your app. The issue is that your app.js and utils.js modules aren't exporting anything to their respective require calls. One option is to add a line like:
module.exports = App;
to the bottom of your app.js file, and the equivalent to the bottom of your utils.js file. You'll see if you test the repo that badapp doesn't have this line and produces the exact behavior you're describing.
See this answer for an explanation of the issue.

Resources