Unexpected token export for JEST & AGM module

Viewed 636

I'm writing tests using Jasmine for angular. When testing my component that uses AGM I get the following error:

C:\Path\node_modules\@agm\core\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename, global,jest){export * from './directives';
         ^^^^^^
SyntaxError: Unexpected token export

knowing that my testing component.spec.ts is empty and doesn't test anything yet.

1 Answers

This solution should work :

You need to install 3 new packages in your dev dependencies (if you don't have them) :

npm install --save-dev @babel/core @babel/cli @babel/preset-env

Then you need to create a file named .babelrc to the root project and add this line :

{ "presets": ["@babel/preset-env"] }

The next step is to add a npm script that will run babel to compile the js files in ES2015. Open your package.json add this to the scripts section :

"compile_@agm_core": "babel node_modules/@agm/core -d node_modules/@agm/core --presets @babel/preset-env"

This script has to be run after the npm install, so add this line in the scripts section of your package.json too :

"postinstall": "npm run compile_@agm_core",

Once you did that, run a npm install and you will see something like :

babel node_modules/@agm/core -d node_modules/@agm/core --presets @babel/preset-env Successfully compiled 35 files with Babel.

The second part is to test your component that is using the AGM imports. I don't know actually how you use it, but this is the logic :

my-agm-component.ts :

import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core';
import { MapsAPILoader } from '@agm/core';

@Component({
    selector: 'app-my-agm-component',
    templateUrl: './my-agm.component.html'
})
export class MyAgmComponent implements OnInit {
    public latitude: number = 39.8282;
    public longitude: number = -98.5795;
    public zoom: number = 4;
    @ViewChild('search')
    public searchElementRef: ElementRef;

    constructor(private mapsAPILoader: MapsAPILoader, private ngZone: NgZone) {
    }

    ngOnInit(): void {
        this.loadGMAP();
    }

    private async loadGMAP(): Promise<void> {
        await this.mapsAPILoader.load();
        this.listenGMAPSearch();
    }

    private listenGMAPSearch(): void {
        const autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement, {
            types: ['address']
        });

        autocomplete.addListener('place_changed', () => {
            this.ngZone.run(() => {
                this.onPlaceChanged(autocomplete.getPlace());
            });
        });
    }

    private onPlaceChanged(place: google.maps.places.PlaceResult): void {
        if (!place.geometry) {
            return;
        }

        // handle addr from place.geometry here
    }
}

my-agm-component.spec.ts :

I'm using mocha not jest, but this is how I test my component initialization. You should be able to run your spec file without the unexpected token export error.

import { NgZone } from '@angular/core';
import { stubClass, expect, stub } from '../../../../../../test';
import { MyAgmComponent } from './my-agm.component';

describe('MyAgmComponent', () => {
    let component: MyAgmComponent, mapsAPILoader: any, ngZone: NgZone;

    beforeEach(() => {
        // mocking mapsAPILoader
        mapsAPILoader = <any>{load: () => Promise.resolve({})};

        // spying load method call
        stub(mapsAPILoader, 'load').returns(null);

        // initializing component
        component = new MyAgmComponent(
            mapsAPILoader,
            ngZone = stubClass(NgZone)
        );
    });

    it('should init the component', () => {
        return expect(component).to.not.be.undefined;
    });
});

I know this is a long post but I hope it was helpful. This solution is based on this github thread.

Related