简体   繁体   中英

mocha testing Angular (typescript) app that uses OpenLayers 6 fails with 'turf mocha "syntaxError: Unexpected token {"'

I solved this during the writing of the question and have provided my answer below since it was a bit tricky to work out. I am happy to hear any better or alternative answers.

I have an Angular OpenLayers 6 geomapping app. Being Angular I use Typescript and it transpiles and runs fine. And also being Angular it uses ng test to do the testing. All tests run fine.

However I use mocha + chai for testing in the IDE (IntelliJ) since I don't require UI testing for the mathematical work I'm currently performing ( ng test runs the UI tests if and when I need that. But in the IDE I select the tests to run). Testing this way worked fine until I added a new test that creates a new instance of a class that imports GeoJSON :

import GeoJSON from 'ol/format/GeoJSON';

That test fails (in mocha) with:

/home/smx9b6/dev/ng-eow/node_modules/ol/format/GeoJSON.js:17
import { assert } from '../asserts.js';
   ^

SyntaxError: Unexpected token {

Looking at the GeoJSON.js file it seems to have UMD module format (i think this is UMD ):

/**
 * @module ol/format/GeoJSON
 */
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();

import { assert } from '../asserts.js';
import Feature from '../Feature.js';

var GeoJSON = /** @class */ (function (_super) {
    __extends(GeoJSON, _super);
    /**
     * @param {Options=} opt_options Options.
     */
    function GeoJSON(opt_options) {
        ...
    }

    GeoJSON.prototype.writeGeometryObject = function (geometry, opt_options) {
        return writeGeometry(geometry, this.adaptOptions(opt_options));
    };
return GeoJSON;
}(JSONFeature));

And others, such as turf.js use the ES6 module format. eg. line-to-polygon :

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var bbox_1 = require("@turf/bbox");
var invariant_1 = require("@turf/invariant");
var helpers_1 = require("@turf/helpers");
...
function lineToPolygon(lines, options) {
    if (options === void 0) { options = {}; }
    ...
}

...

exports.default = lineToPolygon;

Mocha can't deal with this but Angular can - I don't know why. I run mocha with (as reported by IntelliJ when running the test - full paths removed):

node node_modules/mocha/bin/_mocha --require ts-node/register --ui bdd --reporter mochaIntellijReporter.js 
src/app/geometry-ops.spec.ts --grep "^geometry-ops centroid "

I have commonjs set as the module type:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [],
    "resolveJsonModule": true,
    "module": "commonjs",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  },
  ...
}

The error in full is:

/home/smx9b6/dev/ng-eow/node_modules/ol/format/GeoJSON.js:17
import { assert } from '../asserts.js';
       ^

SyntaxError: Unexpected token {
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/home/smx9b6/dev/ng-eow/src/app/layers-geometries.ts:4:1)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Module.m._compile (/home/smx9b6/dev/ng-eow/node_modules/ts-node/src/index.ts:439:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/home/smx9b6/dev/ng-eow/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/home/smx9b6/dev/ng-eow/src/app/geometry-ops.spec.ts:13:1)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Module.m._compile (/home/smx9b6/dev/ng-eow/node_modules/ts-node/src/index.ts:439:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/home/smx9b6/dev/ng-eow/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at /home/smx9b6/dev/ng-eow/node_modules/mocha/lib/mocha.js:334:36
    at Array.forEach (<anonymous>)
    at Mocha.loadFiles (/home/smx9b6/dev/ng-eow/node_modules/mocha/lib/mocha.js:331:14)
    at Mocha.run (/home/smx9b6/dev/ng-eow/node_modules/mocha/lib/mocha.js:809:10)
    at Object.exports.singleRun (/home/smx9b6/dev/ng-eow/node_modules/mocha/lib/cli/run-helpers.js:108:16)
    at exports.runMocha (/home/smx9b6/dev/ng-eow/node_modules/mocha/lib/cli/run-helpers.js:142:13)
    at Object.exports.handler.argv [as handler] (/home/smx9b6/dev/ng-eow/node_modules/mocha/lib/cli/run.js:292:3)
    at Object.runCommand (/home/smx9b6/dev/ng-eow/node_modules/mocha/node_modules/yargs/lib/command.js:242:26)
    at Object.parseArgs [as _parseArgs] (/home/smx9b6/dev/ng-eow/node_modules/mocha/node_modules/yargs/yargs.js:1087:28)
    at Object.parse (/home/smx9b6/dev/ng-eow/node_modules/mocha/node_modules/yargs/yargs.js:566:25)
    at Object.exports.main (/home/smx9b6/dev/ng-eow/node_modules/mocha/lib/cli/cli.js:68:6)
    at Object.<anonymous> (/home/smx9b6/dev/ng-eow/node_modules/mocha/bin/_mocha:10:23)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)

I worked out and provide an answer below. However I would still like to hear any feedback on this. Such as should OpenLayers change their module format? (I'm still getting my head around all the different module formats).

The answer is to add --require esm --require jsdom-global/register to the node / mocha call.

The esm is to specify ES6 as the module format and jsdom-global is to define the DOM in non-browser environments (specifically to define document ).

The full command is:

node node_modules/mocha/bin/_mocha --ui bdd \
--require ts-node/register \
--require esm \
--require jsdom-global/register \
--reporter landing \
src/app/geometry-ops.spec.ts --grep "^geometry-ops centroid "

(I added spaces in the command since it irks me when I have to scroll right to see such things).

I am happy to hear any better or alternative answers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM