Jest: SyntaxError: Unexpected token export
When I run my jasmine test with Jest I get an error:
G:\git\diamant\SpaUI\node_modules\linqts\dist\src\index.js:10
export { default as List } from './list';
^^^^^^
SyntaxError: Unexpected token export
> 1 | import { List } from 'linqts';
| ^
2 | import { ReportMessageData } from './../models/report.model';
3 | import { TranslateService } from '@ngx-translate/core';
4 | import { Injectable } from '@angular/core';
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
at Object.<anonymous> (src/app/feature-modules/report/services/report-message-flatten.service.ts:1:1)
I understand that I have to tell Jest to transform the code to plain Javascript, but I don't know how to do it.
My jest.config.js
looks as follows:
var preset = require("jest-preset-angular/jest-preset");
module.exports = {
...preset,
preset: "jest-preset-angular",
transformIgnorePatterns: ["<rootDir>/node_modules/(?!linqts)"],
testMatch: ["**/*.test.ts"],
globals: {
...preset.globals,
"ts-jest": {
...preset.globals["ts-jest"],
tsConfig: "src/tsconfig.test.json",
isolatedModules: true
}
},
moduleNameMapper: {
'^@diamant/feature-modules(.*)$': '<rootDir>/src/app/feature-modules/$1',
}
};
1 answer
-
answered 2020-11-25 07:19
Sohail Ashraf
Jest doesn't support
ES6
module and hence throwing this error when you directly run the test with Jest. if you want to run like that then you have to add babel.In newer version of jest babel-jest is now automatically loaded by Jest and fully integrated
Hope this answer your question.
Adding babel in jest.
Installation
babel-jest
is now automatically loaded by Jest and fully integrated. This step is only required if you are using babel-jest to transform TypeScript files.npm install --save-dev babel-jest
Usage
In your package.json file make the following changes:
{ "scripts": { "test": "jest" }, "jest": { "transform": { "^.+\\.[t|j]sx?$": "babel-jest" } } }
Create .babelrc configuration file Create a
babel.config.json
config in your project root and enable somepresets
. To start, you can use the env preset, which enables transforms for ES2015+npm install @babel/preset-env --save-dev
In order to enable the preset you have to define it in your
babel.config.json
file, like this:{ "presets": ["@babel/preset-env"] }
Check for more details on Babel official site
See also questions close to this topic
-
Creating a linked list object using js
I want to make a linked list using
custom Object
that pushes a value, pop a value, display all its content, remove an item from a specific place, and insert at a specific place as long as the value is missing from the sequence otherwise through an exception. All of the properties should be defined using data descriptor, prevent them from being deleted, iterated, or being modified.I can do no more than this ... I'm new to js.
var linkedList = {}; /* linkedList.name = 'Ahmed'; [].push.call(linkedList, 'sad', "sd"); */ Object.defineProperty(linkedList, "name", { value: "mohamed", writable: false, configurable: false, enumerable: false }) linkedList.next = {'sd':'as'};
Any help? thanks in advance
-
Trying to trigger a CSS animation with a button press through Javascript
I'm trying to trigger a CSS animation with a button press by using Javascript. I've used other question and answers here, but to no avail. My code seems like it should work -- what am I missing? When I click the button, the background color of the div which I specify should change color over 2 seconds to light blue. I've tried changing the color of both my Body and my Test div, but nothing changes. My alert() triggers, which is confusing as it is in the same function as my colorChange.
<!DOCTYPE html> <html lang="en"> <head> <title><model-viewer> example</title> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <script> function colorChange() { alert("The button works"); document.getElementByID('test').style.animation="changeColor"; } </script> <style> body { background-color: darkblue; -webkit-transition: all 2s ease; -moz-transition: all 2s ease; -o-transition: all 2s ease; -ms-transition: all 2s ease; transition: all 2s ease; } .test { width: 500px; height: 500px; background-color: pink; } @keyframes changeColor { to { background-color: lightblue; } } </style> </head> <body id="body"> <div class="test"></div> <button id="button" onclick="colorChange()">test animation</button> </body> </html>
-
No output from (GET) Ajax Result From Php Array with json_encode
I have a GET form that gets a Php Array and json encodes it. The Issue I am having is the success data is not displaying. I want the success to display data in a Alert or console but for some reason it's not working. I have tried many options. Thanks for your help.
PS: I know the GET and all files work because when I got the script the Ajax response result would populate/append a table successfully. I am modifying it.
Here is the php index file with the AJAX:
<!doctype html> <html> <head> <title>Return JSON response from AJAX using jQuery and PHP</title> <link href="style.css" type="text/css" rel="stylesheet"> <script src="jquery-3.1.1.min.js" type="text/javascript"></script> </head> <body> <script> $(document).ready(function() { $.ajax({ url: 'ajaxfile.php', type: 'get', dataType: 'JSON', success: function(data) { var obj = jQuery.parseJSON(data); alert(obj.username); } }); }); </script> </body> </html>
Here is the php file that queries the database and encodes/array json:
<?php $return_arr = array(); $sql = "SELECT * FROM users ORDER BY NAME"; $result = $conn->query($sql); // Check database connection first if ($conn->query($sql) === FALSE) { echo 'database connection failed'; die(); } else { while($row = $result->fetch_array()) { $id = $row['id']; $username = $row['username']; $name = $row['name']; $email = $row['email']; $return_arr[] = array("id" => $id, "username" => $username, "name" => $name, "email" => $email); } // Encoding array in JSON format echo json_encode($return_arr); } ?>
echo json_encode array output from the php file looks like below (test content):
[{"id":"1","username":"jiten","name":"Jiten singh\t","email":"jiten9"},{"id":"2","username":"kuldeep","name":"Kuldeep","email":"kuldee"},{"id":"3","username":"mayank","name":"Mayank","email":"mayank"},{"id":"9","username":"mohit","name":"Mohit","email":"mohit"},{"id":"13","username":"mukesh","name":"Mukesh","email":"mukesh"},{"id":"6","username":"nitin","name":"Nitin","email":"niti"},{"id":"12","username":"palash","name":"Palash","email":"palash"},{"id":"7","username":"rahul","name":"Rahul singh","email":"rahul"},{"id":"10","username":"rohit","name":"Rohit singh","email":"rohit"},{"id":"8","username":"shreya","name":"Shreya","email":"shreyam"},{"id":"11","username":"sonarika","name":"Sonarika","email":"sonarika"},{"id":"5","username":"vijay","name":"Vijay","email":"vijayec"},{"id":"14","username":"vishal","name":"Vishal Sahu\t","email":"visha"},{"id":"4","username":"yssyogesh","name":"Yogesh singh","email":"yoges"}]
when I make the success result (data) and alert(data), this is what I get,empty objects
-
Creating two value range slider from Angular material native component
I need a two value range slider for my app, however none of the packages that I've looked at on NPM etc are 100% suitable for what I need. The Angular Material slider is the most suitable, however it doesn't allow for two values to be used on a single slider.
To get around this, I've had an idea of placing one slider on top of the other, to give the impression of one slider with two values. This works well, and has a smooth behaviour which is one of the requirements that I wanted my slider to have.
However, I would also like to add a bar in between the two slider thumbs, so that the selected range is highlighted and visible. The native slider does have this, but since it only allows one value the highlight starts from 0 and extends to the value of the slider.
Instead I want to have the highlight between the upper and lower values of the thumbs on the slider. But I have no idea how to add this to it. So I was wondering if someone could help me out. I'm not entirely sure if I'd need to add a new element on top of the bar that adjusts to the size between the two thumbs or if I'd have to do something different.
Alternatively if anyone knows how to make NGX-slider allow a smooth step like the angular material slider that would be the best solution and I'd love to hear it. https://www.npmjs.com/package/@angular-slider/ngx-slider
https://angular-9-material-starter-5ueh7p.stackblitz.io
Code so far
<mat-slider class="slider-left"></mat-slider> <mat-slider class="slider-right"></mat-slider> .slider-right { position: relative; left: -128px; } ::ng-deep .mat-slider-track-fill { background-color: rgba(0, 0, 0, 0.26) !important; } ::ng-deep .mat-slider-track-background { background-color: rgba(0, 0, 0, 0.26); }
-
Angular 10 form action not getting variable
I am creating a form in angular, used from a 3rd party, which needs to redirect away from my site for a payment and back.
I have added their sample code (the form which does a post) into my angular app and added a formGroup, and an action to the form (the action is the url I want to redirect to).
<form [formGroup]="tdsvt" (ngSubmit)="onSubmit2021" method="post" id="redirectForm" action="{{redirectUrl}}"> <input type="hidden" name="id" formControlName="reqID" /> </form>
I have changed the action to the variable that is needed, but it does not redirect and it stays blank. I have tried doing a normal post request and subscribe like so:
return this.http.post<any>(redirectUrl, data);
But I am hit with a CORS issue as it is a total different URL.
How can I get the action to work as a variable and redirect? Or if I shouldn't use an action, what's the best method around this?
Thank you
-
Child route with fragment
I have a page with a side menu, each side menu item has a routerLink that sends a different fragment. I want to know if it is possible that this new route with the fragment has a child route.
Example:
Side menu:
<button type="button" routerLink="['/pageA']" fragment="frag">btn side menu</button>
On click this button, the route would look like this: http://localhost:4200/#/pageA#frag
Content Page
<button type="button" routerLink="['child-a']">A</button> <button type="button" routerLink="['child-b']">B</button> <router-outlet></router-outlet> // Here son A or son B will be loaded
And when click on button A, the route would look like this: http://localhost:4200/#/pageA#frag/child-a
page-routing.module.ts
const routes: Routes = [ { path: '', component: PageAComponent, children: [ { path: 'child-a', component: ChildAComponent, }, { path: 'child-b', component: ChildBComponent, }, ], }, ];
-
setting a type only for the value of an object
I have this object:
const theme = {}
This object is being filled by a function, this function adds a property to this object whenever it's called, the key it sets is a random number as a string, so "1", "31" and so on, and the value it sets is a string.
I was looking for something like this in TypeScript:
interface Theme { string: string } const theme: Theme = {} const theFunction(){ const key = `${Math.floor(Math.random() * 1000)}`; const value = "value"; theme[key] = value; }
The theFunction might get called at any unknown time,
-
How to format "2021-01-19T12:50:00Z" to: 2021-01-19 12:50:00
I am using angular and rxjs.
So I have this:
x: console.log(res.map(date => date.dt))
And it returns this:
0: "2021-01-19T12:50:00Z" 1: "2021-01-19T12:51:00Z" 2: "2021-01-19T12:52:00Z" 3: "2021-01-19T12:53:00Z" 4: "2021-01-19T12:54:00Z" 5: "2021-01-19T12:55:00Z" 6: "2021-01-19T12:56:00Z" 7: "2021-01-19T12:57:00Z" 8: "2021-01-19T12:59:00Z"
But of course that is not readable.
SO I want to convert it to for example this: '2021-01-19 12:50:00',
So: yyyy-MM-dd HH-MM-SS
But so what I have to change?
Thank you
-
jest mocking a response to handle response.blob()
I'm trying to test the below code which makes an api call to download a file blob from the reponse by calling
response.blob()
. However I'm not sure how I can mock this and the response so that I can test a successful response and validate that thedownloadFile()
function is called. The key part I'm not sure about is how to mock a function's returned value to be an object that you later call a method on (.blob())code to test:
...... const response = await apiCall<Response>(dispatch, request, false); try { const file = await response.blob(); const fileUrl = window.URL.createObjectURL(file); downloadFile(fileUrl, 'filename.csv'); } catch { throw response; }
test
describe('downloadsAFile', () => { it('downloads successfully', async () => { global.URL.createObjectURL = jest.fn(); expect(downloadFile).toBeCalled(); });
-
Test worker thread with mocks
My Node application uses AWS SDK, and in order to mock it locally I am using Jest's manual mocks. Basically I am placing in
__mocks__
folder barebone mock of AWS SDK that simulates methods I use - and during Jest tests this "AWS-SDK" is being called by the main code.This works fine for the regular code flow. But when I invoke a worker thread (I am using sync-thread library but this is true for regular worker usage) - code inside of the worker tries to call real AWS-SDK when running Jest tests.
Is there a way to make it use mocked one as well? Also environmental variables set in the worker don't persist for the caller thread - is this by design or could they be set this way?
-
NestJS: Unit Test Joi Validation
I'am new using Node and Nest framework, and I have a problem when testing modules that import a Custom Config Module that uses Joi to validate env vars:
yarn test Test suite failed to run Config validation error: "APP_PORT" is required
app-config.module.ts
@Module({ imports: [ ConfigModule.forRoot({ expandVariables: true, load: [configuration], validationSchema: Joi.object({ APP_PORT: Joi.number().required() }), }), ], providers: [AppConfigService], exports: [AppConfigService], }) export class AppConfigModule { }
app.config.ts
import { registerAs } from '@nestjs/config'; export default registerAs('app', () => ({ env: process.env.NODE_ENV, port: process.env.APP_PORT || 3000 ... }));
invoice.service.spec.ts
describe('InvoiceService', () => { let service: InvoiceService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [ ConfigModule.forRoot({ load: [configuration], ignoreEnvFile: true, }), AppConfigModule ], providers: [ InvoiceService, .... ], }).compile(); service = module.get<InvoiceService>(InvoiceService); }); it('should be defined', () => { expect(service).toBeDefined(); }); });
I use env file to deploy locally, and I only set up
ignoreEnvFile: true
in test class because env file is ignore from github repo, and project integrate github actions that run unit test.How is the best way to solved this problem? I would not like add env file to repo. Exist any way to disable/fake/mock Joi validation method. I saw some examples using setupFiles but I'm not sure if it's a good practice.
-
How do I test code inside ".subscribe()" Angular/Jasmine
I have this Code in my
StatisticComponent
this.subscription = this.locationService.getStatisticOne(this.formService.getFormValue()) .subscribe(data => { this.array = data; this.wrongValueOne = this.array.shift(); for (let array of this.array) { this.addData(this.myChartOne, array.date, array.leistung); } });
Now I want to write a Test to see if anything inside this
.subscribe()
function is being called or executed. This code snippet is being executed inside agenerateStatisticOne()
function which is called in agetData()
function which is called inngOnInit()
or at a button press. The problem is that im new to writing tests and don't even know if what I've found here makes even sense, but I have this code for the test for nowdescribe('StatisticComponent', () => { let component: StatisticComponent; let fixture: ComponentFixture<StatisticComponent>; const locationServiceSpy = jasmine.createSpyObj('LocationService', { getStatisticOne: of([{ id: 1 }, { id: 2 }, { id: 3 }]) }); beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [StatisticComponent], imports: [ HttpClientTestingModule ], providers: [{ provide: LocationService, useValue: locationServiceSpy }, LocationService, HttpClientTestingModule ], }) .compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(StatisticComponent); component = fixture.componentInstance; locationService = TestBed.get(LocationService); fixture.detectChanges(); }); it('should call array.shift ', fakeAsync(() => { const service = TestBed.get(LocationService); // get your service spyOn(service, 'getStatisticOne').and.callThrough(); // create spy spyOn(Array.prototype, 'shift'); fixture.detectChanges(); tick(); expect(Array.prototype.shift).toHaveBeenCalled(); }));
The error I get when running the code is "expected spy shift to have been called"
-
How to test subscription to an Observable - when do I need done() and when must I provide the second parameter to subscribe?
I'm looking at the Testing Services section of the Angular Guide, and I'm confused by some apparent inconsistencies on that page.
At the top, in the very first example it has a sample test like this:
it('#getObservableValue should return value from observable', (done: DoneFn) => { service.getObservableValue().subscribe(value => { expect(value).toBe('observable value'); done(); }); });
Notice that it calls
done()
at the end of thesubscribe
block.Later on the same page there are some tests that use a different approach. For example, the very last example on the page has a test like this:
it('should return expected heroes (HttpClient called once)', () => { const expectedHeroes: Hero[] = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]; httpClientSpy.get.and.returnValue(asyncData(expectedHeroes)); heroService.getHeroes().subscribe( heroes => expect(heroes).toEqual(expectedHeroes, 'expected heroes'), fail ); expect(httpClientSpy.get.calls.count()).toBe(1, 'one call'); });
The first thing that stands out is that this test does not call
done()
.Secondly, it provides a second parameter (the
fail
function) to thesubscribe
call. (I do understand what that parameter is for). It actually calls out in the accompanying text that providing the second parameter is important:The subscribe() method takes a success (next) and fail (error) callback. Make sure you provide both callbacks so that you capture errors. Neglecting to do so produces an asynchronous uncaught observable error that the test runner will likely attribute to a completely different test.
...which begs the question(s):
- Why does the second test not call
done()
, and - Why does the first test not provide the second parameter to
subscribe
?
I imagine that there is a "good reason" for both of these things, but it's not at all obvious to me what that is - and so it's difficult to know when to use which pattern.
- Why does the second test not call
-
best practice, test main.ts and polyfills.ts in angular?
I'm somewhat new to angular, I'm writing jasmine tests and can't seem to find this answer. Is it best practice to test main.ts and polyfills.ts or do you simply exclude them from coverage?