Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rzhao271 committed Nov 4, 2021
1 parent d8e207d commit 25c21bc
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 26 deletions.
100 changes: 75 additions & 25 deletions spec-main/api-app-spec.ts
Expand Up @@ -208,6 +208,7 @@ describe('app module', () => {
interface SingleInstanceLockTestArgs {
args: string[];
expectedAdditionalData: unknown;
expectedAck: unknown;
}

it('prevents the second launch of app', async function () {
Expand Down Expand Up @@ -237,6 +238,8 @@ describe('app module', () => {

const secondInstanceArgs = [process.execPath, appPath, ...testArgs.args, '--some-switch', 'some-arg'];
const second = cp.spawn(secondInstanceArgs[0], secondInstanceArgs.slice(1));
const secondStdoutLines = second.stdout.pipe(split());
const dataAckPromise = emittedOnce(secondStdoutLines, 'data');
const secondExited = emittedOnce(second, 'exit');

const [code2] = await secondExited;
Expand All @@ -247,6 +250,8 @@ describe('app module', () => {
const [args, additionalData] = dataFromSecondInstance[0].toString('ascii').split('||');
const secondInstanceArgsReceived: string[] = JSON.parse(args.toString('ascii'));
const secondInstanceDataReceived = JSON.parse(additionalData.toString('ascii'));
const ackData = await dataAckPromise;
const dataAckReceived = JSON.parse(ackData[0].toString('ascii'));

// Ensure secondInstanceArgs is a subset of secondInstanceArgsReceived
for (const arg of secondInstanceArgs) {
Expand All @@ -255,77 +260,122 @@ describe('app module', () => {
}
expect(secondInstanceDataReceived).to.be.deep.equal(testArgs.expectedAdditionalData,
`received data ${JSON.stringify(secondInstanceDataReceived)} is not equal to expected data ${JSON.stringify(testArgs.expectedAdditionalData)}.`);
expect(dataAckReceived).to.be.deep.equal(testArgs.expectedAck,
`received data ${JSON.stringify(dataAckReceived)} is not equal to expected data ${JSON.stringify(testArgs.expectedAck)}.`);
}

it('passes arguments to the second-instance event no additional data', async () => {
const expectedAdditionalData = {
level: 1,
testkey: 'testvalue1',
inner: {
level: 2,
testkey: 'testvalue2'
}
};

const expectedAck = {
level: 1,
testkey: 'acktestvalue1',
inner: {
level: 2,
testkey: 'acktestvalue2'
}
};

it('passes arguments to the second-instance event with no additional data', async () => {
await testArgumentPassing({
args: [],
expectedAdditionalData: null
expectedAdditionalData: null,
expectedAck: null
});
});

it('sends and receives JSON object data', async () => {
const expectedAdditionalData = {
level: 1,
testkey: 'testvalue1',
inner: {
level: 2,
testkey: 'testvalue2'
}
};
it('passes arguments to the second-instance event', async () => {
await testArgumentPassing({
args: ['--send-data'],
expectedAdditionalData
expectedAdditionalData,
expectedAck: null
});
});

it('gets back an ack after preventing default', async () => {
await testArgumentPassing({
args: ['--send-ack', '--prevent-default'],
expectedAdditionalData: null,
expectedAck
});
});

it('is able to send back empty ack after preventing default', async () => {
await testArgumentPassing({
args: ['--prevent-default'],
expectedAdditionalData: null,
expectedAck: null
});
});

it('sends and receives data', async () => {
await testArgumentPassing({
args: ['--send-ack', '--prevent-default', '--send-data'],
expectedAdditionalData,
expectedAck
});
});

it('sends and receives numerical data', async () => {
await testArgumentPassing({
args: ['--send-data', '--data-content=2'],
expectedAdditionalData: 2
args: ['--send-ack', '--ack-content=1', '--prevent-default', '--send-data', '--data-content=2'],
expectedAdditionalData: 2,
expectedAck: 1
});
});

it('sends and receives string data', async () => {
await testArgumentPassing({
args: ['--send-data', '--data-content="data"'],
expectedAdditionalData: 'data'
args: ['--send-ack', '--ack-content="ack"', '--prevent-default', '--send-data', '--data-content="data"'],
expectedAdditionalData: 'data',
expectedAck: 'ack'
});
});

it('sends and receives boolean data', async () => {
await testArgumentPassing({
args: ['--send-data', '--data-content=false'],
expectedAdditionalData: false
args: ['--send-ack', '--ack-content=true', '--prevent-default', '--send-data', '--data-content=false'],
expectedAdditionalData: false,
expectedAck: true
});
});

it('sends and receives array data', async () => {
await testArgumentPassing({
args: ['--send-data', '--data-content=[2, 3, 4]'],
expectedAdditionalData: [2, 3, 4]
args: ['--send-ack', '--ack-content=[1, 2, 3]', '--prevent-default', '--send-data', '--data-content=[2, 3, 4]'],
expectedAdditionalData: [2, 3, 4],
expectedAck: [1, 2, 3]
});
});

it('sends and receives mixed array data', async () => {
await testArgumentPassing({
args: ['--send-data', '--data-content=["2", true, 4]'],
expectedAdditionalData: ['2', true, 4]
args: ['--send-ack', '--ack-content=["1", true, 3]', '--prevent-default', '--send-data', '--data-content=["2", false, 4]'],
expectedAdditionalData: ['2', false, 4],
expectedAck: ['1', true, 3]
});
});

it('sends and receives null data', async () => {
await testArgumentPassing({
args: ['--send-data', '--data-content=null'],
expectedAdditionalData: null
args: ['--send-ack', '--ack-content=null', '--prevent-default', '--send-data', '--data-content=null'],
expectedAdditionalData: null,
expectedAck: null
});
});

it('cannot send or receive undefined data', async () => {
try {
await testArgumentPassing({
args: ['--send-ack', '--ack-content="undefined"', '--prevent-default', '--send-data', '--data-content="undefined"'],
expectedAdditionalData: undefined
expectedAdditionalData: undefined,
expectedAck: undefined
});
assert(false);
} catch (e) {
Expand Down
34 changes: 33 additions & 1 deletion spec/fixtures/api/singleton-data/main.js
Expand Up @@ -7,6 +7,15 @@ app.whenReady().then(() => {
console.log('started'); // ping parent
});

// Send data from the second instance to the first instance.
const sendAdditionalData = app.commandLine.hasSwitch('send-data');

// Prevent the default behaviour of second-instance, which sends back an empty ack.
const preventDefault = app.commandLine.hasSwitch('prevent-default');

// Send an object back for the ack rather than undefined.
const sendAck = app.commandLine.hasSwitch('send-ack');

let obj = {
level: 1,
testkey: 'testvalue1',
Expand All @@ -15,19 +24,42 @@ let obj = {
testkey: 'testvalue2'
}
};
let ackObj = {
level: 1,
testkey: 'acktestvalue1',
inner: {
level: 2,
testkey: 'acktestvalue2'
}
};

if (app.commandLine.hasSwitch('data-content')) {
obj = JSON.parse(app.commandLine.getSwitchValue('data-content'));
if (obj === 'undefined') {
obj = undefined;
}
}
if (app.commandLine.hasSwitch('ack-content')) {
ackObj = JSON.parse(app.commandLine.getSwitchValue('ack-content'));
if (ackObj === 'undefined') {
ackObj = undefined;
}
}

app.on('first-instance-ack', (event, additionalData) => {
console.log(JSON.stringify(additionalData));
});

const gotTheLock = sendAdditionalData
? app.requestSingleInstanceLock(obj) : app.requestSingleInstanceLock();

app.on('second-instance', (event, args, workingDirectory, data) => {
app.on('second-instance', (event, args, workingDirectory, data, ackCallback) => {
if (preventDefault) {
event.preventDefault();
}
setImmediate(() => {
console.log([JSON.stringify(args), JSON.stringify(data)].join('||'));
sendAck ? ackCallback(ackObj) : ackCallback();
app.exit(0);
});
});
Expand Down

0 comments on commit 25c21bc

Please sign in to comment.