WIP: use ts-mock-imports

This commit is contained in:
Florent 2021-02-28 17:49:31 +01:00 committed by Florent F
parent eacf90b161
commit d2f8a2fb75
4 changed files with 160 additions and 165 deletions

6
package-lock.json generated
View File

@ -2541,6 +2541,12 @@
"is-number": "^7.0.0"
}
},
"ts-mock-imports": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/ts-mock-imports/-/ts-mock-imports-1.3.3.tgz",
"integrity": "sha512-zCAcb89Y+f3Bhw5VaHrHMh5tiuwAQEl5D3e0r5ELCdLl9EnZpb8Oeei/S60Qf4LORIfmJEXb3TpR5kxtL6j2cg==",
"dev": true
},
"ts-node": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",

View File

@ -38,8 +38,9 @@
"prettier": "2.2.1",
"proxyquire": "2.1.3",
"sinon-chai": "3.5.0",
"ts-sinon": "2.0.1",
"ts-mock-imports": "1.3.3",
"ts-node": "9.1.1",
"ts-sinon": "2.0.1",
"tsc-watch": "^4.2.9",
"typescript": "^4.1.3"
},

View File

@ -1,4 +1,4 @@
import Parser from "rss-parser/index";
import Parser from "rss-parser";
import { ListenerRSSInfos as ListenerInfo } from "./Models/ListenerRSSInfos";
import EventEmitter from "events";
@ -15,7 +15,7 @@ export class ListenerRss extends EventEmitter {
customfields?: { [key: string]: string[] | string };
// private fields
parser: Parser | undefined = undefined;
parser: Parser;
loopRunning: boolean = false;
/**
@ -26,28 +26,23 @@ export class ListenerRss extends EventEmitter {
super();
this.setData(config);
this.setParser();
}
/**
* @brief Private function. Is useed to initilize the parser object with the customfields var
*/
setParser() {
// set parser
this.parser = new Parser(
this.customfields !== undefined
? {
customFields: {
feed: [],
item: Object.entries(this.customfields).map(([, value]) => {
return Array.isArray(value) ? value[0] : value;
}),
},
}
: {}
); // if customfield is set -> let's set the parser with, else let the option empty
this.parser = this.generateParser();
}
generateParser(): Parser {
const parserConfig = this.customfields && {
customFields: {
feed: [],
item: Object.entries(this.customfields).map(([, value]) => {
return Array.isArray(value) ? value[0] : value;
}),
},
};
return new Parser(parserConfig); // if customfield is set -> let's set the parser with, else let the option empty
}
//
/**
* @brief Private function. Initialized the listener with an ListenerRSSInfos interface
* @param infos ListenerRSSInfos interface who's contain the ListenerInfos
@ -66,11 +61,9 @@ export class ListenerRss extends EventEmitter {
* @return return a promise with the received data
*/
fetchRSS(): Promise<Parser.Output<any>> {
if (this.parser !== undefined && this.address !== undefined) {
return this.parser.parseURL(this.address).catch((err) => {
throw new Error("bad address or no access : " + err);
});
} else throw new Error("listener must be first initialized");
return this.parser.parseURL(this.address).catch((err) => {
throw new Error("bad address or no access : " + err);
});
}
/**

View File

@ -1,5 +1,5 @@
// external lib
import Parser from "rss-parser";
import * as parserModule from "rss-parser";
// tested class
import {
@ -10,6 +10,7 @@ import {
// Unit test
import * as chai from "chai";
import * as sinon from "ts-sinon";
import { ImportMock } from "ts-mock-imports";
const sinonChai = require("sinon-chai");
@ -18,8 +19,6 @@ chai.use(sinonChai);
const expect = chai.expect;
describe("test class RSS: jsonfile", function () {
// let myListener: Listeners | undefined = undefined;
const infosListener: ListenerRRSInfo = {
name: "my-test-service",
address: "fake.rss.service",
@ -77,28 +76,28 @@ describe("test class RSS: jsonfile", function () {
/**
* The function create my Stubs for my Listener and my Parser
*/
function fun_initStub(
myListener: Listeners
): sinon.StubbedInstance<Listeners> {
stubListener = sinon.stubObject<Listeners>(myListener, ["setParser"]);
stubListener.setParser.callsFake(() => {
if (stubListener.parser !== undefined) {
stubParser = sinon.stubObject<Parser>(stubListener.parser, [
"parseURL",
]);
stubParser.parseURL
.withArgs(infosListener.address)
.resolves(mockedRSSOutput);
stubParser.parseURL
.withArgs("bad.rss.service")
.rejects(new Error("connect ECONNREFUSED 127.0.0.1:80"));
}
stubListener.parser = stubParser;
});
stubListener.setParser();
// stubListener.fetchRSS.returns(stubParser.parseURL(stubListener.address));
return stubListener;
}
// function fun_initStub(
// myListener: Listeners
// ): sinon.StubbedInstance<Listeners> {
// stubListener = sinon.stubObject<Listeners>(myListener, ["setParser"]);
// stubListener.setParser.callsFake(() => {
// if (stubListener.parser !== undefined) {
// stubParser = sinon.stubObject<Parser>(stubListener.parser, [
// "parseURL",
// ]);
// stubParser.parseURL
// .withArgs(infosListener.address)
// .resolves(mockedRSSOutput);
// stubParser.parseURL
// .withArgs("bad.rss.service")
// .rejects(new Error("connect ECONNREFUSED 127.0.0.1:80"));
// }
// stubListener.parser = stubParser;
// });
// stubListener.setParser();
// // stubListener.fetchRSS.returns(stubParser.parseURL(stubListener.address));
// return stubListener;
// }
// afterEach(function () {
// // restore stubs
@ -225,142 +224,138 @@ describe("test class RSS: jsonfile", function () {
});
describe("fetch some data", function () {
it("fetch without issues", function () {
let myListener = new Listeners(infosListener);
fun_initStub();
it.only("fetch without issues", function () {
const mockManager = ImportMock.mockClass<
parserModule.default,
typeof parserModule
>(parserModule.default);
mockManager.mock("parseURL").resolves(mockedRSSOutput);
const myListener = new Listeners(infosListener);
expect(myListener).to.not.be.undefined;
if (myListener !== undefined) {
// fetch
let res = stubListener.fetchRSS();
//assertion
// calls
expect(stubParser.parseURL).to.have.been.calledOnce;
expect(stubParser.parseURL).to.have.been.calledWith(
infosListener.address
);
res
.then((obj: any) => {
expect(obj).to.be.eql(mockedRSSOutput);
})
.catch((err) => {
expect(err).to.be.undefined;
});
} else throw new Error("Error into the before instruction");
});
it("fetch with bad address", function () {
let myListener = new Listeners({
name: "my-test-service",
address: "bad.rss.service",
customfields: {
description: ["media:group", "media:description"],
icon: ["media:group", "media:thumbnail"],
},
});
let stubListener = fun_initStub(myListener);
// fetch
let res = stubListener.fetchRSS();
let res = myListener.fetchRSS();
//assertion
// calls
expect(stubParser.parseURL).to.have.been.calledOnce;
expect(stubParser.parseURL).to.have.been.calledWith("bad.rss.service");
// Promise
res
return res
.then((obj: any) => {
expect(obj).to.be.undefined;
expect(obj).to.be.eql(mockedRSSOutput);
})
.catch((err) => {
expect(err).to.be.eql(new Error("connect ECONNREFUSED 127.0.0.1:80"));
expect(err).to.be.undefined;
});
});
// it("fetch with bad address", function () {
// let myListener = new Listeners({
// name: "my-test-service",
// address: "bad.rss.service",
// customfields: {
// description: ["media:group", "media:description"],
// icon: ["media:group", "media:thumbnail"],
// },
// });
// let stubListener = fun_initStub(myListener);
// // fetch
// let res = stubListener.fetchRSS();
// //assertion
// // calls
// expect(stubParser.parseURL).to.have.been.calledOnce;
// expect(stubParser.parseURL).to.have.been.calledWith("bad.rss.service");
// // Promise
// res
// .then((obj: any) => {
// expect(obj).to.be.undefined;
// })
// .catch((err) => {
// expect(err).to.be.eql(new Error("connect ECONNREFUSED 127.0.0.1:80"));
// });
// });
});
describe.skip("start", function () {
it("Let's start the timer", async function () {
let clock: sinon.default.SinonFakeTimers = sinon.default.useFakeTimers();
// describe.skip("start", function () {
// it("Let's start the timer", async function () {
// let clock: sinon.default.SinonFakeTimers = sinon.default.useFakeTimers();
// classic build
let myListener = new Listeners({
name: "my-test-service",
address: "fake.rss.service",
timeloop: 60,
customfields: {
description: ["media:group", "media:description"],
icon: ["media:group", "media:thumbnail"],
},
});
let stubListener = fun_initStub(myListener);
stubListener.fetchRSS.reset();
stubListener.fetchRSS.resolves(mockedRSSOutput);
// // classic build
// let myListener = new Listeners({
// name: "my-test-service",
// address: "fake.rss.service",
// timeloop: 60,
// customfields: {
// description: ["media:group", "media:description"],
// icon: ["media:group", "media:thumbnail"],
// },
// });
// let stubListener = fun_initStub(myListener);
// stubListener.fetchRSS.reset();
// stubListener.fetchRSS.resolves(mockedRSSOutput);
//spy
let fun_spy: sinon.default.SinonSpy = sinon.default.spy((obj, err) => {
expect(obj).to.be.eql(mockedRSSOutput);
expect(err).to.be.eql(undefined);
});
// //spy
// let fun_spy: sinon.default.SinonSpy = sinon.default.spy((obj, err) => {
// expect(obj).to.be.eql(mockedRSSOutput);
// expect(err).to.be.eql(undefined);
// });
// start timer
stubListener.on("update", (obj) => fun_spy(obj));
// stubListener.start(fun_spy);
// // start timer
// stubListener.on("update", (obj) => fun_spy(obj));
// // stubListener.start(fun_spy);
// wait and assertion
// After 1ms
await clock.tickAsync(1);
expect(stubListener.fetchRSS).to.have.been.calledOnce;
expect(fun_spy).to.have.been.calledOnce;
// // wait and assertion
// // After 1ms
// await clock.tickAsync(1);
// expect(stubListener.fetchRSS).to.have.been.calledOnce;
// expect(fun_spy).to.have.been.calledOnce;
// After 60s
await clock.tickAsync(59999);
expect(stubListener.fetchRSS).to.have.been.calledTwice;
expect(fun_spy).to.have.been.calledTwice;
// // After 60s
// await clock.tickAsync(59999);
// expect(stubListener.fetchRSS).to.have.been.calledTwice;
// expect(fun_spy).to.have.been.calledTwice;
stubListener.stop();
});
// stubListener.stop();
// });
it("Let's start the timer (with a bad address)", async function () {
let clock: sinon.default.SinonFakeTimers = sinon.default.useFakeTimers();
// it("Let's start the timer (with a bad address)", async function () {
// let clock: sinon.default.SinonFakeTimers = sinon.default.useFakeTimers();
// classic build
let myListener = new Listeners({
name: "my-test-service",
address: "fake.rss.service",
timeloop: 60,
customfields: {
description: ["media:group", "media:description"],
icon: ["media:group", "media:thumbnail"],
},
});
let stubListener = fun_initStub(myListener);
stubListener.fetchRSS.reset();
stubListener.fetchRSS.rejects(
new Error("connect ECONNREFUSED 127.0.0.1:80")
);
// // classic build
// let myListener = new Listeners({
// name: "my-test-service",
// address: "fake.rss.service",
// timeloop: 60,
// customfields: {
// description: ["media:group", "media:description"],
// icon: ["media:group", "media:thumbnail"],
// },
// });
// let stubListener = fun_initStub(myListener);
// stubListener.fetchRSS.reset();
// stubListener.fetchRSS.rejects(
// new Error("connect ECONNREFUSED 127.0.0.1:80")
// );
//spy
let fun_spy: sinon.default.SinonSpy = sinon.default.spy((obj, err) => {
expect(obj).to.be.eql(undefined);
expect(err).to.not.be.eql(undefined);
});
// //spy
// let fun_spy: sinon.default.SinonSpy = sinon.default.spy((obj, err) => {
// expect(obj).to.be.eql(undefined);
// expect(err).to.not.be.eql(undefined);
// });
// start timer
// stubListener.start(fun_spy);
// // start timer
// // stubListener.start(fun_spy);
// wait and assertion
// After 1ms
await clock.tickAsync(1);
expect(stubListener.fetchRSS).to.have.been.calledOnce;
expect(fun_spy).to.have.been.calledOnce;
// // wait and assertion
// // After 1ms
// await clock.tickAsync(1);
// expect(stubListener.fetchRSS).to.have.been.calledOnce;
// expect(fun_spy).to.have.been.calledOnce;
// After 60s
await clock.tickAsync(59999);
expect(stubListener.fetchRSS).to.have.been.calledTwice;
expect(fun_spy).to.have.been.calledTwice;
// // After 60s
// await clock.tickAsync(59999);
// expect(stubListener.fetchRSS).to.have.been.calledTwice;
// expect(fun_spy).to.have.been.calledTwice;
stubListener.stop();
});
});
// stubListener.stop();
// });
// });
});