Gulp 4 keep watching even on error - error-handling

How can I make this
// ...
gulp.watch(source.app, gulp.series(
lint(source.app),
transpile(source.app),
ATDD,
));
To keep watching even if error occurred from linter or transpiler?
My task function looks like this:
// ...
function lintWorker(source) {
return gulp.src(source)
.pipe(tslint({
configuration: "tslint.json",
options : {
formatter: "prose"
}
}))
.pipe(tslint.report(stylish, {
emitError: false,
sort: true,
bell: true
}));
};
export function lint(source) {
let fn = () => {
return lintWorker(source);
};
fn.displayName = ["linting", ...source].join(" ");
return fn;
};

I found the simple way how to do it.
gulp.watch(source.app, (done) => {
gulp.series(
lint(source.app),
transpile(source.app),
ATDD,
)((err) => {
if (err) {
console.error("error", err);
}
done();
});
});

Related

Why is Jest running the typescript test files and then the compiled JS test files?

When I run Jest, I get 9 failing, 11 passing out of a total of 20, but there are only 10 tests between two different test files, here it is:
const fs = require('fs');
const assert = require('assert');
import * as jwt from 'jsonwebtoken';
import * as auth from '../services/authentication-service';
const JWT_ERROR_INVALID_SIG = 'invalid signature';
describe('MMD Integration', () => {
const SERVICE = "knox";
const SERVICE_ID = "aluna1";
const badPublicKeyFile = "badkey.pub";
describe('Service Config is accessible', () => {
it('should contain data', async (done) => {
let config: {} | null = null;
config = await auth.getServiceConfig().catch(err => {
console.log("caught getServiceConfig error:", err);
return null;
});
if (config != null) {
assert.include(Object.keys(config), SERVICE);
} else {
console.log("Test failed!");
}
});
});
describe('Public Key', () => {
describe('is valid', () => {
it('should decode successfully', async (done) => {
let config: {} | null = null;
config = await auth.getServiceConfig().catch(err => {
console.log("caught getServiceConfig error:", err);
return null;
});
let publicKey: string | null = null;
if (config) {
publicKey = await auth.getServicePublicKey(SERVICE, config).catch(err => {
console.log("caught getServicePublicKey error:", err);
return null;
});
const token = await auth.genJwt(SERVICE);
if (token == null) {
console.log("genJwt returned null: stopping test");
done();
} else if (!publicKey) {
console.log("No public key: stopping test");
done();
} else {
jwt.verify(token, publicKey, (err, decoded) => {
if (err) {
console.log("WARNING: valid public key failed!", err.message);
} else if (decoded && Object.keys(decoded).includes('vendor')) {
assert.include(Object.values(decoded), SERVICE);
} else {
console.log("Test failed!");
}
});
}
}
});
});
describe('is bad', () => {
const badPublicKey = fs.readFileSync(badPublicKeyFile);
it('should fail verify', async (done) => {
const token = await auth.genJwt(SERVICE);
if (token == null) {
console.log("genJwt returned null: stopping test");
done();
} else {
jwt.verify(token, badPublicKey, (err: any, decoded: any) => {
if (err) {
assert.equal(err.message, JWT_ERROR_INVALID_SIG);
} else {
console.log("WARNING: bad public key worked!", decoded);
}
});
}
});
});
});
describe('Verify Service', () => {
describe('with valid public key', () => {
it('should succeed', async (done) => {
try {
const token = await auth.genJwt(SERVICE);
if (token == null) {
console.log("genJwt returned null: stopping test");
done();
} else {
const result = await auth.verifyService(SERVICE, token).catch(err => {
console.log("caught verifyService error: stopping test", err);
throw new Error(err);
});
assert.equal(result, "OK");
}
} catch (err) {
assert.equal(err, "OK");
}
});
});
describe('with mismatch token', () => {
it('should fail', async (done) => {
try {
const result = await auth.verifyService(SERVICE, "xyz").catch(err => {
console.log("caught verifyService error: stopping test", err);
done();
});
} catch (err) {
assert.notEqual(err, "OK");
}
});
});
});
describe('Service as real MMD', () => {
it('should fail', async (done) => {
try {
const token = await auth.genJwt("mmd");
if (token == null) {
console.log("genJwt returned null: stopping test");
throw new Error('null token');
} else {
const result = await auth.verifyService("mmd", token).catch(err => {
console.log("caught verifyService error:", err);
throw new Error(err);
});
}
} catch (err) {
assert.notEqual(err, "OK");
console.log(err);
}
});
});
});
describe('Get Token from Request Header', () => {
const someToken = "fake-jwt";
const headers = {
'Content-Type': 'application/json'
, 'Authorization': 'Bearer ' + someToken
, 'Aluna-Service': 'foobar'
};
const badHeaders2 = {
'Content-Type': 'application/json'
, 'Authorization': someToken
, 'Aluna-Service': 'foobar'
};
describe('Request header has authorization', () => {
it('should return token', () => {
const result = auth.getTokenFromAuth(headers.Authorization);
assert.equal(result, someToken);
});
});
describe('Request header is missing authorization', () => {
it('should return null', () => {
const result = auth.getTokenFromAuth('');
assert.equal(result, null);
});
});
describe('Authorization is missing Bearer', () => {
it('should return null', () => {
const result = auth.getTokenFromAuth(badHeaders2.Authorization);
assert.equal(result, null);
});
});
});
import request from 'supertest';
import { app } from '../app';
it('renders a greeting to screen', () => {
return request(app).get('/').send({ greeting: 'howdy' }).expect(200);
})
This is what I see in the terminal:
Test Suites: 3 failed, 1 passed, 4 totaload:flatten Completed in 1ms
Tests: 9 failed, 11 passed, 20 total
Snapshots: 0 total
Time: 31.358 s
Ran all test suites.
Watch Usage
› Press f to run only failed tests.
› Press o to only run tests related to changed files.
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press q to quit watch mode.
› Press Enter to trigger a test run.
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.
at Object.getCodec (node_modules/iconv-lite/lib/index.js:65:27)
at Object.getDecoder (node_modules/iconv-lite/lib/index.js:127:23)
at getDecoder (node_modules/raw-body/index.js:45:18)
at readStream (node_modules/raw-body/index.js:180:15)
at getRawBody (node_modules/raw-body/index.js:108:12)
[2022-03-07T18:40:25.852Z] 1.0.1-dev error: uncaughtException: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Error: Caught error after test environment was torn down
This API was meant to work with Jest or that was the original testing suite installed, but someone else came behind and started using Mocha that they are using globally on their machine. Would anyone mind also sharing why tests would pass on their global install of Mocha but not on Jest?
Just wanted to post a solution which is not buried in comments.
By default jest will find any test files in your entire project. If you are building or copying files to a build/release directory, you need to do one of the following:
(Recommended) Exclude the test files from your build pipeline. I usually create a separate tsconfig for building which excludes the test files. Your build command should point to this tsconfig: tsc --project tsconfig.build.json. Note: you can extend tsconfigs so that you don't have to manage duplicates. Here's an example of what your tsconfig.build.json might look like:
{
"extends": "./tsconfig.json",
"exclude": ["src/**/*.test.ts"]
}
-- OR --
Exclude your build directories from jest, adding testPathIgnorePatterns: ['dist/'] to your jest.config.js (assuming your compiled JavaScript files are in the dist folder)

Error: Unknown named module: "./constants"

I am having an issue where I am trying to import an API, specifically the what3words API, in to my react native app. The problem is that every time I try to import the module, I receive the error 'Unknown named module'
I have managed to pinpoint the issue. When i go in to the node_modules folder, and go to the what3words/api folder and comment out all the 'requires', the error goes away, but then I am unable to use the api.
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "./constants", "./requests/autosuggest", "./requests/autosuggest-selection", "./requests/available-languages", "./requests/convert-to-3wa", "./requests/convert-to-coordinates", "./requests/grid-section", "./utils"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.valid3wa = exports.getWords = exports.getOptions = exports.setOptions = exports.gridSectionGeoJson = exports.gridSection = exports.convertToCoordinatesGeoJson = exports.convertToCoordinates = exports.convertTo3waGeoJson = exports.convertTo3wa = exports.availableLanguages = exports.autosuggestSelection = exports.autosuggest = exports.W3W_REGEX = void 0;
var constants_1 = require("./constants");
Object.defineProperty(exports, "W3W_REGEX", { enumerable: true, get: function () { return constants_1.W3W_REGEX; } });
// var autosuggest_1 = require("./requests/autosuggest");
Object.defineProperty(exports, "autosuggest", { enumerable: true, get: function () { return autosuggest_1.autosuggest; } });
// var autosuggest_selection_1 = require("./requests/autosuggest-selection");
Object.defineProperty(exports, "autosuggestSelection", { enumerable: true, get: function () { return autosuggest_selection_1.autosuggestSelection; } });
// var available_languages_1 = require("./requests/available-languages");
Object.defineProperty(exports, "availableLanguages", { enumerable: true, get: function () { return available_languages_1.availableLanguages; } });
// var convert_to_3wa_1 = require("./requests/convert-to-3wa");
Object.defineProperty(exports, "convertTo3wa", { enumerable: true, get: function () { return convert_to_3wa_1.convertTo3wa; } });
Object.defineProperty(exports, "convertTo3waGeoJson", { enumerable: true, get: function () { return convert_to_3wa_1.convertTo3waGeoJson; } });
// var convert_to_coordinates_1 = require("./requests/convert-to-coordinates");
Object.defineProperty(exports, "convertToCoordinates", { enumerable: true, get: function () { return convert_to_coordinates_1.convertToCoordinates; } });
Object.defineProperty(exports, "convertToCoordinatesGeoJson", { enumerable: true, get: function () { return convert_to_coordinates_1.convertToCoordinatesGeoJson; } });
// var grid_section_1 = require("./requests/grid-section");
Object.defineProperty(exports, "gridSection", { enumerable: true, get: function () { return grid_section_1.gridSection; } });
Object.defineProperty(exports, "gridSectionGeoJson", { enumerable: true, get: function () { return grid_section_1.gridSectionGeoJson; } });
// var utils_1 = require("../es2015/utils.js");
Object.defineProperty(exports, "setOptions", { enumerable: true, get: function () { return utils_1.setOptions; } });
Object.defineProperty(exports, "getOptions", { enumerable: true, get: function () { return utils_1.getOptions; } });
Object.defineProperty(exports, "getWords", { enumerable: true, get: function () { return utils_1.getWords; } });
Object.defineProperty(exports, "valid3wa", { enumerable: true, get: function () { return utils_1.valid3wa; } });
});
After searching online, it appears that this issue is to do with metro and the require function. Please help, Thanks
Managed to fix it!! With some help from one of the contributors of the what3words api. It seems that this is an issue with metro not being able to bundle umd modules. Luckily, the what3words api has es2015 module which we can use instead, so i just used
const api = require('#what3words/api/es2015');
Instead of the previous
const api = require('#what3words/api');
Check https://github.com/what3words/w3w-node-wrapper/issues/28 for the full debugging

How to test Axios reject condition using Jest

I wrote a unit test for some Axios calls in my component. I verified the success path, where the call resolves successfully, but I am not able to verify the failure path, where the call rejects. How do I use mocks to verify this?
Here's a snippet of my FetchImage.vue component:
methods: {
preparedFetch() {
axios.get(this.imageurl).then(result => {
this.imageInformation.title = result.data.title;
this.imageInformation.copyright = result.data.copyright;
this.imageInformation.detailExplanation = result.data.explanation;
this.imageInformation.date = result.data.date;
this.imageInformation.urlinfo = result.data.url;
this.resultArrived = true;
this.$emit('imagefetched',this.imageInformation);
})
.catch( error => {
this.errorMessage = "Information not found";
this.resultArrived = true;
});
}
}
And my test for when the call rejects (for an invalid URL):
describe('Invalid response',async () => {
beforeEach(() => {
axios.get.mockClear();
axios.get.mockReturnValue(Promise.reject({}));
});
it('Invalid URL verfication', async () => {
// Given
const result = {
errorMessage : "Information not found",
resultArrived : true,
fetchStatus : true
};
// Fetch the error result
axios.get.mockReturnValue(Promise.resolve(result));
const fetchwrapper = mount(FetchImage);
fetchwrapper.vm.imageurl = "https://invalid.request.gov";
fetchwrapper.vm.preparedFetch();
await fetchwrapper.vm.$nextTick();
// Validate the result
expect(axios.get).not.toHaveBeenCalledWith('https://api.nasa.gov/planetary/apod?api_key=vME6LAMD7IhEiy7rDmjfIaG6MhiKbu1MNIqxtqd1');
expect(axios.get).toHaveBeenCalledWith("https://invalid.request.gov");
expect(axios.get).toHaveBeenCalledTimes(1);
expect(fetchwrapper.vm.errorMessage.length).not.toEqual(0);
expect(fetchwrapper.vm.errorMessage).toBe("Information not found");
});
});
Your catch block isn't running because the mock return value is using Promise.resolve() when it actually should be Promise.reject():
describe('Invalid response',async () => {
it('Invalid URL verfication', async () => {
// axios.get.mockReturnValue(Promise.resolve(result)); // DON'T DO THIS
axios.get.mockReturnValue(Promise.reject(result));
});
});
You have to reject the value by using the built-in jest method.
describe('Invalid response', async () => {
it('Invalid URL verfication', async () => {
axios.get.mockRejectedValue(result);
});
});

Cannot read property of "then" of undefined APOLLO GRAPHQL

I'm having a trouble and i'm stuck. I used to replicate this on my other codes but this method doesn't work on apollo. Here is my method using the apollo on my vue.js.
handleLikePost() {
const variables = {
postId: this.postId,
username: this.user.username
};
this.$apollo.mutate({
mutation: LIKE_POST,
variables,
update: (cache, { data: { likePost } }) => {
const data = cache.readQuery({
query: GET_POST,
variables: { postId: this.postId }
});
data.getPost.likes += 1;
cache
.writeQuery({
query: GET_POST,
variables: { postId: this.postId },
data
})
.then(({ data }) => {
// const updatedUser = {
// ...this.user,
// favorites: data.likePost.favorites
// };
//this.$store.commit("setUser", updatedUser);
console.log(this.user);
console.log(data.likePost);
})
.catch(err => console.error(err));
}
});
}
I think the problem is you are not returning something from;
cache.writeQuery()
That's why .then({data}) is not getting something from writeQuery()

expressjs doesn't wait till query is done

I am using expressjs to retrieve data from elasticsearch and send back to my angular app at the front end. Currently I am facing a problem since expressjs doesn't wait until the query execution is finished. I searched for a solution for that and the community says use "Promise or Sync". But I cant figure out where should I use it. I tried to use it but I am getting errors.
This is where I am receiving the request from the frontend and calling the elasticsearch query for send the response.
api.post('/clsDependencies', (req, res) => {
classDependencies(req.body.className);
res.json(messages);
});
This the function for querying the elasticsearch.
function classDependencies(csName) {
let body = {
size: 20,
from: 0,
query: {
match: {
ClassName: {
query: csName
}
}
}
};
search('testclass', body)
.then(results => {
results.hits.hits.forEach((hit, index) => hit._source.dependencies.forEach(
function(myClass){
messages.push({text: myClass.methodSignature , owner: `\t${++nmb} -
${myClass.dependedntClass}`});
}))})
.catch(console.error);
};
Expected data gets initialized to the variable(messages) which I am trying to send back to the front end. But the variable doesn't get initialized at the time when response is send back. What Should I do to wait till the query execution finish before send back the data to frontend.
EDIT
messages is defined outside of both functions.
function classDirectory(className) {
let body = {
size: 20,
from: 0,
query: {
match: {
ClassName: {
query: className
}
}
}
};
return search('testclass', body).then(results => {
results.hits.hits.forEach((hit, index) =>
getDirectories(hit._source.JarFileName));
return messages;
})
.catch(function(err) {
// log the error, but keep the promise rejected
console.error(err);
throw err;
});
};
function getDirectories(jarName) {
let body = {
size: 20,
from: 0,
query: {
match: {
jarFileName: {
query: jarName
}
}
}
};
return search('testjar', body).then(results => {
results.hits.hits.forEach((hit, index) =>
messages.push({text: hit._source.jarFileName , owner: `\t${++nmb} -
${hit._source.directory}`})
);
return messages;
})
.catch(function(err) {
// log the error, but keep the promise rejected
console.error(err);
throw err;
});
};
The Javascript interpreter does not "block" when you make asynchronous calls. This has absolutely nothing to do with Express.
Your call to search() is non-blocking so while it's in process, classDependencies() returns and the rest of your code continues to run. This is the way asynchronous calls in Javascript work.
If you want to call res.json() when classDependencies() is done, then return a promise from it and call res.json() when that promise resolves.
You could do something like this:
api.post('/clsDependencies', (req, res) => {
classDependencies(req.body.className).then(messages => {
res.json(messages);
}).catch(err => {
res.status(500).send(something here);
});
});
function classDependencies(csName) {
let body = {
size: 20,
from: 0,
query: {
match: {
ClassName: {
query: csName
}
}
}
};
return search('testclass', body).then(results => {
let messages = [];
results.hits.hits.forEach((hit, index) => hit._source.dependencies.forEach(function(myClass) {
messages.push({
text: myClass.methodSignature,
owner: `\t${++nmb} - ${myClass.dependedntClass}`
});
}));
// make messages be the resolved value of the returns promise
return messages;
}).catch(function(err) {
// log the error, but keep the promise rejected
console.error(err);
throw err;
});
};
api.post('/clsDirectory', (req, res) => {
classDependency(req.body.className, res);
});
function classDependency(csName, cb) {
let body = {
size: 20,
from: 0,
query: {
match: {
ClassName: {
query: csName
}
}
}
};
search('testclass', body)
.then(results => {
results.hits.hits.forEach((hit, index) =>
hit._source.dependencies.forEach(
function(myClass){
messages.push({text: myClass.methodSignature , owner: `\t${++nmb} -
${myClass.dependedntClass}`});
}));
cb.json(messages);
})
.catch(console.error);
};