Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,5 @@ jobs:
name: ${{ steps.prebuild.outputs.version }} Release
body: ${{ steps.prebuild.outputs.version }}
target: ${{ github.ref }}
draft: true
prerelease: false
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -30,8 +30,10 @@
"typescript"
],
"jest": {
"collectCoverage": true,
"collectCoverageFrom": [
"**/*.{ts,tsx}",
"**/*.{js,jsx}",
"!**/node_modules/**"
],
"moduleFileExtensions": [
Expand Down
2 changes: 1 addition & 1 deletion src/__snapshots__/application.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Application Application snapshot 1`] = `
exports[`Application snapshot 1`] = `
<div
className="section container"
>
Expand Down
34 changes: 31 additions & 3 deletions src/application.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { mount, ReactWrapper } from "enzyme";
import * as React from "react";
import * as renderer from "react-test-renderer";

Expand All @@ -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<any, any[]> = jest.fn();
const RendererServiceMock: jest.Mock<RendererService, any[]>
= 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(<TestSubject.Application service={ service } />);
snapshot.toJSON();
expect(snapshot).toMatchSnapshot();
});

it("header", (): void => {
const testSubject: ReactWrapper<TestSubject.IApplicationProperties, {}, TestSubject.Application>
= mount(<TestSubject.Application service={ service } />);

expect(testSubject.find("h1").text()).toBe("Application loaded");
});

it("button clicked", (): void => {
const testSubject: ReactWrapper<TestSubject.IApplicationProperties, {}, TestSubject.Application>
= mount(<TestSubject.Application service={ service } />);

expect(pingMock).toBeCalledTimes(0);
testSubject.find("Button").find("button").simulate("click");
expect(pingMock).toBeCalledTimes(1);
});

});
2 changes: 1 addition & 1 deletion src/application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { RendererService } from "./rendererService";

import { Button } from "./button";

interface IApplicationProperties {
export interface IApplicationProperties {
service: RendererService;
}

Expand Down
98 changes: 88 additions & 10 deletions src/mainService.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<any, any[]> = jest.fn();
const onMock: jest.Mock<any, any[]> = 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<any, any[]> = 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<any, any[]> = 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<string>);
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<any, any[]> = 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<string>);
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<any, any[]> = 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);
});
});
103 changes: 87 additions & 16 deletions src/rendererService.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<any, any[]> = jest.fn();
const onMock: jest.Mock<any, any[]> = 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<any, any[]> = 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<any, any[]> = 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<any, any[]> = 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<string>);
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<any, any[]> = 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<string>);
expect(event.sender.send).toHaveBeenCalledTimes(0);
});
});
1 change: 0 additions & 1 deletion src/rendererService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export class RendererService extends IpcService<Electron.IpcRenderer> {
protected handleMessage<MT>(event: Electron.IpcRendererEvent, message: IIPCMessage<MT>): void {
switch (message.type) {
case "ping":
console.log(message);
this.send(event.sender, this.channel, "pong", message.data);
break;
case "pong":
Expand Down