diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index b326b00..fb2518e 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -76,3 +76,5 @@ jobs:
name: ${{ steps.prebuild.outputs.version }} Release
body: ${{ steps.prebuild.outputs.version }}
target: ${{ github.ref }}
+ draft: true
+ prerelease: false
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 47b00dd..5b27cfc 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -66,6 +66,8 @@ jobs:
name: ${{ steps.prebuild.outputs.version }} Release
body: ${{ steps.prebuild.outputs.version }}
target: ${{ github.ref }}
+ draft: true
+ prerelease: false
- name: upload
id: upload
uses: ./.github/actions/upload-asset
diff --git a/package.json b/package.json
index b471a4a..a67127c 100644
--- a/package.json
+++ b/package.json
@@ -1,21 +1,21 @@
{
"name": "typescript-react-electron-starter",
- "version": "0.0.2",
+ "version": "0.0.3",
"description": "TypeScript React Electron Starter",
"main": "app/main.js",
"scripts": {
- "clear": "gulp --cwd . clear && rimraf ./node_modules ./app ./dist ./coverage ./it/screenshots ./package-lock.json ./gulpfile.js ./gulpfile.js.map ./.github/actions/gulpfile.js ./.github/actions/gulpfile.js.map",
+ "clear": "gulp --cwd . clear && rimraf ./node_modules ./app ./dist ./coverage ./coverage-it ./it/screenshots ./package-lock.json ./gulpfile.js ./gulpfile.js.map ./.github/actions/gulpfile.js ./.github/actions/gulpfile.js.map",
"postinstall": "tsc -p ./",
"actions": "gulp --gulpfile ./.github/actions/gulpfile.js --cwd .",
- "prebuild": "rimraf ./app ./dist ./coverage ./it/screenshots",
+ "prebuild": "rimraf ./app ./dist ./coverage ./coverage-it ./it/screenshots",
"build": "gulp --cwd .",
"predist": "rimraf ./app ./dist",
"dist": "gulp --cwd . dist",
"start": "electron ./",
"pretest": "rimraf ./coverage",
"test": "jest --testEnvironment enzyme --coverage --coverageDirectory ../coverage --rootDir ./src",
- "preit": "rimraf ./it/screenshots",
- "it": "jest --rootDir ./it"
+ "preit": "rimraf ./coverage-it ./it/screenshots",
+ "it": "jest --runInBand --coverage --coverageDirectory ../coverage-it --rootDir ./it"
},
"repository": {
"type": "git",
@@ -30,8 +30,10 @@
"typescript"
],
"jest": {
+ "collectCoverage": true,
"collectCoverageFrom": [
"**/*.{ts,tsx}",
+ "**/*.{js,jsx}",
"!**/node_modules/**"
],
"moduleFileExtensions": [
diff --git a/src/__snapshots__/application.spec.tsx.snap b/src/__snapshots__/application.spec.tsx.snap
index b37fa81..514f176 100644
--- a/src/__snapshots__/application.spec.tsx.snap
+++ b/src/__snapshots__/application.spec.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Application Application snapshot 1`] = `
+exports[`Application snapshot 1`] = `
diff --git a/src/application.spec.tsx b/src/application.spec.tsx
index db0b8c9..cffb864 100644
--- a/src/application.spec.tsx
+++ b/src/application.spec.tsx
@@ -1,3 +1,4 @@
+import { mount, ReactWrapper } from "enzyme";
import * as React from "react";
import * as renderer from "react-test-renderer";
@@ -7,16 +8,43 @@ import { RendererService } from "./rendererService";
describe("Application", (): void => {
- const service: RendererService = new RendererService(undefined as any, undefined as any);
+ const pingMock: jest.Mock
= jest.fn();
+ const RendererServiceMock: jest.Mock
+ = jest.fn().mockImplementation((props: TestSubject.IApplicationProperties, context?: any) => {
+ return {
+ ping: pingMock,
+ };
+ });
+
+ const service: RendererService = new RendererServiceMock();
- it("Application export exists", (): void => {
+ beforeEach((): void => {
+ RendererServiceMock.mockClear();
+ });
+ it("export exists", (): void => {
expect(TestSubject.Application).toBeDefined();
});
- it("Application snapshot", (): void => {
+ it("snapshot", (): void => {
const snapshot: renderer.ReactTestRenderer = renderer.create();
snapshot.toJSON();
expect(snapshot).toMatchSnapshot();
});
+ it("header", (): void => {
+ const testSubject: ReactWrapper
+ = mount();
+
+ expect(testSubject.find("h1").text()).toBe("Application loaded");
+ });
+
+ it("button clicked", (): void => {
+ const testSubject: ReactWrapper
+ = mount();
+
+ expect(pingMock).toBeCalledTimes(0);
+ testSubject.find("Button").find("button").simulate("click");
+ expect(pingMock).toBeCalledTimes(1);
+ });
+
});
diff --git a/src/application.tsx b/src/application.tsx
index 532c9dc..b2c5f90 100644
--- a/src/application.tsx
+++ b/src/application.tsx
@@ -4,7 +4,7 @@ import { RendererService } from "./rendererService";
import { Button } from "./button";
-interface IApplicationProperties {
+export interface IApplicationProperties {
service: RendererService;
}
diff --git a/src/mainService.spec.tsx b/src/mainService.spec.tsx
index fb1148a..0c7b597 100644
--- a/src/mainService.spec.tsx
+++ b/src/mainService.spec.tsx
@@ -2,31 +2,109 @@ import { mount, ReactWrapper } from "enzyme";
import * as React from "react";
import * as renderer from "react-test-renderer";
+import { IIPCMessage, IPCChannel, IPCMessageType } from "./ipc";
+
import * as TestSubject from "./mainService";
describe("MainService", (): void => {
- it("MainService export exists", (): void => {
+ const sendMock: jest.Mock = jest.fn();
+ const onMock: jest.Mock = jest.fn();
+ let eventCallback: (event: Electron.IpcMainEvent | Electron.IpcRendererEvent, ...args: any[]) => void;
+
+ const handler: (channel: IPCChannel,
+ callback: (event: Electron.IpcMainEvent | Electron.IpcRendererEvent, ...args: any[]) => void)
+ => void = (channel: IPCChannel, callback: (event: Electron.IpcMainEvent | Electron.IpcRendererEvent,
+ ...args: any[]) => void): void => {
+ eventCallback = callback;
+ onMock(channel);
+ };
+
+ const ipcMock: any = {
+ on: handler,
+ send: sendMock,
+ };
+
+ beforeEach((): void => {
+ onMock.mockClear();
+ });
+
+ it("export exists", (): void => {
expect(TestSubject.MainService).toBeDefined();
});
it("register", (): void => {
- const ipc: any = {
- on: jest.fn(),
+ const testSubject: TestSubject.MainService = new TestSubject.MainService(ipcMock, "main-channel");
+ testSubject.register();
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ });
+
+ it("invalid event", (): void => {
+ const testSubject: TestSubject.MainService = new TestSubject.MainService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
};
+ testSubject.register();
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, 1, 2, 3);
+ expect(event.sender.send).toHaveBeenCalledTimes(0);
+ });
- const testSubject: TestSubject.MainService = new TestSubject.MainService(ipc, "main-channel");
+ it("ping event", (): void => {
+ const testSubject: TestSubject.MainService = new TestSubject.MainService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
+ };
testSubject.register();
- expect(ipc.on).toHaveBeenCalledTimes(1);
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, {
+ data: "test",
+ timestamp: new Date(),
+ type: "ping",
+ } as IIPCMessage);
+ expect(event.sender.send).toHaveBeenCalledTimes(2);
});
- it("callback", (): void => {
- const ipc: any = {
- on: jest.fn(),
+
+ it("pong event", (): void => {
+ const testSubject: TestSubject.MainService = new TestSubject.MainService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
};
+ testSubject.register();
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, {
+ data: "test",
+ timestamp: new Date(),
+ type: "pong",
+ } as IIPCMessage);
+ expect(event.sender.send).toHaveBeenCalledTimes(0);
+ });
- const testSubject: TestSubject.MainService = new TestSubject.MainService(ipc, "main-channel");
+ it("unknown event", (): void => {
+ const testSubject: TestSubject.MainService = new TestSubject.MainService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
+ };
testSubject.register();
- expect(ipc.on).toHaveBeenCalledTimes(1);
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, {
+ data: "test",
+ timestamp: new Date(),
+ type: "test",
+ } as any);
+ expect(event.sender.send).toHaveBeenCalledTimes(0);
});
});
diff --git a/src/rendererService.spec.tsx b/src/rendererService.spec.tsx
index 7ce07e5..c804a93 100644
--- a/src/rendererService.spec.tsx
+++ b/src/rendererService.spec.tsx
@@ -2,41 +2,112 @@ import { mount, ReactWrapper } from "enzyme";
import * as React from "react";
import * as renderer from "react-test-renderer";
+import { IIPCMessage, IPCChannel, IPCMessageType } from "./ipc";
+
import * as TestSubject from "./rendererService";
+
describe("RendererService", (): void => {
- it("RendererService export exists", (): void => {
+ const sendMock: jest.Mock = jest.fn();
+ const onMock: jest.Mock = jest.fn();
+ let eventCallback: (event: Electron.IpcMainEvent | Electron.IpcRendererEvent, ...args: any[]) => void;
+
+ const handler: (channel: IPCChannel,
+ callback: (event: Electron.IpcMainEvent | Electron.IpcRendererEvent, ...args: any[]) => void)
+ => void = (channel: IPCChannel, callback: (event: Electron.IpcMainEvent | Electron.IpcRendererEvent,
+ ...args: any[]) => void): void => {
+ eventCallback = callback;
+ onMock(channel);
+ };
+
+ const ipcMock: any = {
+ on: handler,
+ send: sendMock,
+ };
+
+ beforeEach((): void => {
+ onMock.mockClear();
+ });
+
+ it("export exists", (): void => {
expect(TestSubject.RendererService).toBeDefined();
});
it("ping", (): void => {
- const ipc: any = {
- send: jest.fn(),
- };
-
- const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipc, "main-channel");
+ const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipcMock, "main-channel");
testSubject.ping();
- expect(ipc.send).toHaveBeenCalledTimes(1);
+ expect(ipcMock.send).toHaveBeenCalledTimes(1);
});
it("register", (): void => {
- const ipc: any = {
- on: jest.fn(),
+ const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipcMock, "main-channel");
+ testSubject.register();
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ });
+
+
+ it("event", (): void => {
+ const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
};
+ testSubject.register();
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, "test");
+ });
- const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipc, "main-channel");
+ it("invalid event", (): void => {
+ const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
+ };
testSubject.register();
- expect(ipc.on).toHaveBeenCalledTimes(1);
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, "test", 1);
+ eventCallback(event);
});
- it("callback", (): void => {
- const ipc: any = {
- on: jest.fn(),
+ it("ping event", (): void => {
+ const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
};
+ testSubject.register();
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, {
+ data: "test",
+ timestamp: new Date(),
+ type: "ping",
+ } as IIPCMessage);
+ expect(event.sender.send).toHaveBeenCalledTimes(1);
+ });
- const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipc, "main-channel");
+
+ it("pong event", (): void => {
+ const testSubject: TestSubject.RendererService = new TestSubject.RendererService(ipcMock, "main-channel");
+ const eventSenderSendMock: jest.Mock = jest.fn();
+ const event: any = {
+ sender: {
+ send: eventSenderSendMock,
+ },
+ };
testSubject.register();
- expect(ipc.on).toHaveBeenCalledTimes(1);
+ expect(onMock).toHaveBeenNthCalledWith(1, "main-channel");
+ eventCallback(event, {
+ data: "test",
+ timestamp: new Date(),
+ type: "pong",
+ } as IIPCMessage);
+ expect(event.sender.send).toHaveBeenCalledTimes(0);
});
});
diff --git a/src/rendererService.ts b/src/rendererService.ts
index 3fd8b8a..3d789d8 100644
--- a/src/rendererService.ts
+++ b/src/rendererService.ts
@@ -13,7 +13,6 @@ export class RendererService extends IpcService {
protected handleMessage(event: Electron.IpcRendererEvent, message: IIPCMessage): void {
switch (message.type) {
case "ping":
- console.log(message);
this.send(event.sender, this.channel, "pong", message.data);
break;
case "pong":