Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Commit

Permalink
♻️ Update stdin functions and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsujutsu committed Oct 8, 2018
1 parent d288f63 commit a3f12ed
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 166 deletions.
14 changes: 9 additions & 5 deletions src/commands/signature/broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,25 @@
*/
import BaseCommand from '../../base';
import { ValidationError } from '../../utils/error';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import getAPIClient from '../../utils/api';

const getSignatureInput = async () => {
const rawStdIn = await getRawStdIn();
if (rawStdIn.length <= 0) {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No signature was provided.');
}
return data;
} catch (e) {
throw new ValidationError('No signature was provided.');
}
return rawStdIn[0];
};

export default class BroadcastCommand extends BaseCommand {
async run() {
const { args: { signature } } = this.parse(BroadcastCommand);
const signatureInput = signature || (await getSignatureInput(signature));
const signatureInput = signature || (await getSignatureInput());
let signatureObject;
try {
signatureObject = JSON.parse(signatureInput);
Expand Down
25 changes: 12 additions & 13 deletions src/commands/signature/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@
import elements from 'lisk-elements';
import { flags as flagParser } from '@oclif/command';
import BaseCommand from '../../base';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import { ValidationError } from '../../utils/error';
import parseTransactionString from '../../utils/transactions';
import getInputsFromSources from '../../utils/input';
import commonFlags from '../../utils/flags';

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

export default class CreateCommand extends BaseCommand {
async run() {
Expand All @@ -41,8 +41,7 @@ export default class CreateCommand extends BaseCommand {
flags: { passphrase: passphraseSource },
} = this.parse(CreateCommand);

const transactionInput =
transaction || (await getTransactionInput(transaction));
const transactionInput = transaction || (await getTransactionInput());

const transactionObject = parseTransactionString(transactionInput);

Expand Down
25 changes: 12 additions & 13 deletions src/commands/transaction/broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,25 @@
import BaseCommand from '../../base';
import parseTransactionString from '../../utils/transactions';
import { ValidationError } from '../../utils/error';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import getAPIClient from '../../utils/api';

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

export default class BroadcastCommand extends BaseCommand {
async run() {
const { args: { transaction } } = this.parse(BroadcastCommand);
const transactionInput =
transaction || (await getTransactionInput(transaction));
const transactionInput = transaction || (await getTransactionInput());
const transactionObject = parseTransactionString(transactionInput);
const client = getAPIClient(this.userConfig.api);
const response = await client.transactions.broadcast(transactionObject);
Expand Down
26 changes: 12 additions & 14 deletions src/commands/transaction/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@
import elements from 'lisk-elements';
import { flags as flagParser } from '@oclif/command';
import BaseCommand from '../../base';
import { getRawStdIn } from '../../utils/input/utils';
import { getStdIn } from '../../utils/input/utils';
import { ValidationError } from '../../utils/error';
import parseTransactionString from '../../utils/transactions';
import getInputsFromSources from '../../utils/input';
import commonFlags from '../../utils/flags';

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

export default class SignCommand extends BaseCommand {
async run() {
Expand All @@ -44,9 +44,7 @@ export default class SignCommand extends BaseCommand {
},
} = this.parse(SignCommand);

const transactionInput =
transaction || (await getTransactionInput(transaction));

const transactionInput = transaction || (await getTransactionInput());
const transactionObject = parseTransactionString(transactionInput);

const { passphrase, secondPassphrase } = await getInputsFromSources({
Expand Down
22 changes: 11 additions & 11 deletions src/commands/transaction/verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import elements from 'lisk-elements';
import { flags as flagParser } from '@oclif/command';
import BaseCommand from '../../base';
import parseTransactionString from '../../utils/transactions';
import { getRawStdIn, getData } from '../../utils/input/utils';
import { getStdIn, getData } from '../../utils/input/utils';
import { ValidationError } from '../../utils/error';

const secondPublicKeyDescription = `Specifies a source for providing a second public key to the command. The second public key must be provided via this option. Sources must be one of \`file\` or \`stdin\`. In the case of \`file\`, a corresponding identifier must also be provided.
Expand All @@ -29,17 +29,17 @@ const secondPublicKeyDescription = `Specifies a source for providing a second pu
- --second-public-key 790049f919979d5ea42cca7b7aa0812cbae8f0db3ee39c1fe3cef18e25b67951
`;

const getTransactionInput = async () =>
getRawStdIn()
.then(rawStdIn => {
if (rawStdIn.length <= 0) {
throw new ValidationError('No transaction was provided.');
}
return rawStdIn[0];
})
.catch(() => {
const getTransactionInput = async () => {
try {
const { data } = await getStdIn({ dataIsRequired: true });
if (!data) {
throw new ValidationError('No transaction was provided.');
});
}
return data;
} catch (e) {
throw new ValidationError('No transaction was provided.');
}
};

const processSecondPublicKey = async secondPublicKey =>
secondPublicKey.includes(':') ? getData(secondPublicKey) : secondPublicKey;
Expand Down
34 changes: 8 additions & 26 deletions src/utils/input/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,36 +44,13 @@ export const splitSource = source => {
};
};

const timeoutPromise = async readFromStd => {
try {
await (() =>
new Promise(([reject]) => setTimeout(reject, DEFAULT_TIMEOUT)))();
} catch (e) {
if (stdinIsTTY()) {
throw new Error(`Timed out after ${DEFAULT_TIMEOUT} ms`);
}
}
return readFromStd;
};

export const getRawStdIn = () => {
const readFromStd = new Promise(resolve => {
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
return rl
.on('line', line => lines.push(line))
.on('close', () => resolve(lines));
});
return Promise.race([readFromStd, timeoutPromise(readFromStd)]);
};

export const getStdIn = ({
passphraseIsRequired,
secondPassphraseIsRequired,
passwordIsRequired,
dataIsRequired,
} = {}) => {
const readFromStd = new Promise(resolve => {
const readFromStd = new Promise((resolve, reject) => {
if (
!(
passphraseIsRequired ||
Expand All @@ -84,10 +61,15 @@ export const getStdIn = ({
) {
return resolve({});
}

const lines = [];
const rl = readline.createInterface({ input: process.stdin });

// Prevent readline hanging when command called with no input or piped
const id = setTimeout(() => {
clearTimeout(id);
reject(new Error(`Timed out after ${DEFAULT_TIMEOUT} ms`));
}, DEFAULT_TIMEOUT);

const handleClose = () => {
const passphraseIndex = 0;
const passphrase = passphraseIsRequired ? lines[passphraseIndex] : null;
Expand All @@ -113,7 +95,7 @@ export const getStdIn = ({

return rl.on('line', line => lines.push(line)).on('close', handleClose);
});
return Promise.race([readFromStd, timeoutPromise(DEFAULT_TIMEOUT)]);
return readFromStd;
};

export const getPassphraseFromPrompt = async ({
Expand Down
14 changes: 7 additions & 7 deletions test/commands/signature/broadcast.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ describe('signature:broadcast', () => {
.stub(api, 'default', sandbox.stub().returns(apiClientStub))
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves(defaultSignatureString),
'getStdIn',
sandbox.stub().resolves({ data: defaultSignatureString }),
)
.stdout();

describe('signature:broadcast', () => {
setupTest()
.stub(inputUtils, 'getRawStdIn', sandbox.stub().resolves([]))
.stub(inputUtils, 'getStdIn', sandbox.stub().resolves({}))
.command(['signature:broadcast'])
.catch(error => {
return expect(error.message).to.contain('No signature was provided.');
Expand Down Expand Up @@ -84,8 +84,8 @@ describe('signature:broadcast', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves(['{invalid: json, format: bad}']),
'getStdIn',
sandbox.stub().resolves({ data: '{invalid: json, format: bad}' }),
)
.command(['signature:broadcast'])
.catch(error => {
Expand All @@ -98,8 +98,8 @@ describe('signature:broadcast', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([defaultSignatureString]),
'getStdIn',
sandbox.stub().resolves({ data: defaultSignatureString }),
)
.command(['signature:broadcast'])
.it('should broadcast the signature', () => {
Expand Down
16 changes: 8 additions & 8 deletions test/commands/signature/create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
'getStdIn',
sandbox.stub().rejects(new Error('Timeout error')),
)
.command(['signature:create'])
Expand Down Expand Up @@ -138,7 +138,7 @@ describe('signature:create', () => {

describe('transaction | signature:create', () => {
setupTest()
.stub(inputUtils, 'getRawStdIn', sandbox.stub().resolves([]))
.stub(inputUtils, 'getStdIn', sandbox.stub().resolves({}))
.command(['signature:create'])
.catch(error => {
return expect(error.message).to.contain('No transaction was provided.');
Expand All @@ -148,8 +148,8 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([invalidTransaction]),
'getStdIn',
sandbox.stub().resolves({ data: invalidTransaction }),
)
.command(['signature:create'])
.catch(error => {
Expand All @@ -162,8 +162,8 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([JSON.stringify(defaultTransaction)]),
'getStdIn',
sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }),
)
.command(['signature:create'])
.it(
Expand Down Expand Up @@ -192,8 +192,8 @@ describe('signature:create', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([JSON.stringify(defaultTransaction)]),
'getStdIn',
sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }),
)
.command(['signature:create', '--passphrase=pass:123'])
.it(
Expand Down
12 changes: 6 additions & 6 deletions test/commands/transaction/broadcast.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('transaction:broadcast', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
'getStdIn',
sandbox.stub().rejects(new Error('Timeout error')),
)
.command(['transaction:broadcast'])
Expand Down Expand Up @@ -99,7 +99,7 @@ describe('transaction:broadcast', () => {

describe('transaction | transaction:broadcast', () => {
setupTest()
.stub(inputUtils, 'getRawStdIn', sandbox.stub().resolves([]))
.stub(inputUtils, 'getStdIn', sandbox.stub().resolves({}))
.command(['transaction:broadcast'])
.catch(error => {
return expect(error.message).to.contain('No transaction was provided.');
Expand All @@ -109,8 +109,8 @@ describe('transaction:broadcast', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves(wrongTransaction),
'getStdIn',
sandbox.stub().resolves({ data: wrongTransaction }),
)
.command(['transaction:broadcast'])
.catch(error => {
Expand All @@ -123,8 +123,8 @@ describe('transaction:broadcast', () => {
setupTest()
.stub(
inputUtils,
'getRawStdIn',
sandbox.stub().resolves([JSON.stringify(defaultTransaction)]),
'getStdIn',
sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }),
)
.command(['transaction:broadcast'])
.it('should broadcast the transaction', () => {
Expand Down
Loading

0 comments on commit a3f12ed

Please sign in to comment.