type(coverage): improve flow coverage

This commit is contained in:
George Lima 2019-01-28 21:34:07 -03:00
parent 408b65ada9
commit 2982dda4d3
17 changed files with 82 additions and 103 deletions

View File

@ -24,7 +24,7 @@ const DefaultButton = styled.button`
transition: background-color 0.1s ${props => props.theme.colors.transitionEase}; transition: background-color 0.1s ${props => props.theme.colors.transitionEase};
`; `;
const Primary = styled(DefaultButton)` const Primary = styled<{ theme: Object }>(DefaultButton)`
background-color: ${props => props.theme.colors.primary}; background-color: ${props => props.theme.colors.primary};
color: ${props => props.theme.colors.secondary}; color: ${props => props.theme.colors.secondary};
border: none; border: none;
@ -40,7 +40,7 @@ const Primary = styled(DefaultButton)`
} }
`; `;
const Secondary = styled(DefaultButton)` const Secondary = styled<{ theme: Object }>(DefaultButton)`
background-color: transparent; background-color: transparent;
color: ${props => props.theme.colors.secondary}; color: ${props => props.theme.colors.secondary};
border: 2px solid ${props => props.theme.colors.buttonBorderColor}; border: 2px solid ${props => props.theme.colors.buttonBorderColor};

View File

@ -1,9 +1,9 @@
// @flow // @flow
import styled from 'styled-components'; import styled from 'styled-components';
import { TextComponent } from './text'; import { TextComponent, type Props } from './text';
export const InputLabelComponent = styled(TextComponent)` export const InputLabelComponent = styled<{ ...Props, marginTop: string }>(TextComponent)`
margin: ${props => props.marginTop || '20px'} 0 8.5px 0; margin: ${props => props.marginTop || '20px'} 0 8.5px 0;
font-weight: ${props => props.theme.fontWeight.bold}; font-weight: ${props => props.theme.fontWeight.bold};
`; `;

View File

@ -1,5 +1,5 @@
// @flow // @flow
/* eslint-disable max-len */
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { Link, type Location } from 'react-router-dom'; import { Link, type Location } from 'react-router-dom';
@ -17,15 +17,11 @@ const Wrapper = styled.div`
`; `;
const StyledLink = styled(Link)` const StyledLink = styled(Link)`
color: ${props => (props.isActive color: ${props => (props.isActive ? props.theme.colors.sidebarItemActive : props.theme.colors.sidebarItem)};
? props.theme.colors.sidebarItemActive
: props.theme.colors.sidebarItem)};
font-size: ${props => `${props.theme.fontSize.regular}em`}; font-size: ${props => `${props.theme.fontSize.regular}em`};
text-decoration: none; text-decoration: none;
font-weight: ${props => props.theme.fontWeight.bold}; font-weight: ${props => props.theme.fontWeight.bold};
background-color: ${props => (props.isActive background-color: ${props => (props.isActive ? `${props.theme.colors.sidebarHoveredItem}` : 'transparent')};
? `${props.theme.colors.sidebarHoveredItem}`
: 'transparent')};
letter-spacing: 0.25px; letter-spacing: 0.25px;
padding: 25px 20px; padding: 25px 20px;
height: 35px; height: 35px;
@ -33,9 +29,7 @@ const StyledLink = styled(Link)`
display: flex; display: flex;
align-items: center; align-items: center;
outline: none; outline: none;
border-right: ${props => (props.isActive border-right: ${props => (props.isActive ? `3px solid ${props.theme.colors.sidebarItemActive}` : 'none')};
? `3px solid ${props.theme.colors.sidebarItemActive}`
: 'none')};
cursor: pointer; cursor: pointer;
transition: all 0.03s ${props => props.theme.colors.transitionEase}; transition: all 0.03s ${props => props.theme.colors.transitionEase};
@ -76,11 +70,7 @@ export const SidebarComponent = ({ options, location }: Props) => (
return ( return (
<StyledLink isActive={isActive} key={item.route} to={item.route}> <StyledLink isActive={isActive} key={item.route} to={item.route}>
<Icon <Icon isActive={isActive} src={item.icon(isActive)} alt={`${item.route}`} />
isActive={isActive}
src={item.icon(isActive)}
alt={`${item.route}`}
/>
{item.label} {item.label}
</StyledLink> </StyledLink>
); );

View File

@ -16,7 +16,7 @@ const Text = styled.p`
text-align: ${props => props.align}; text-align: ${props => props.align};
`; `;
type Props = { export type Props = {
...ElementProps<'p'>, ...ElementProps<'p'>,
value: string, value: string,
isBold?: boolean, isBold?: boolean,

View File

@ -37,25 +37,30 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
if (err) return dispatch(loadWalletSummaryError({ error: err.message })); if (err) return dispatch(loadWalletSummaryError({ error: err.message }));
const [zAddressesErr, zAddresses] = await eres(rpc.z_listaddresses()); const [zAddressesErr, zAddresses = []] = await eres(rpc.z_listaddresses());
const [tAddressesErr, transparentAddresses] = await eres( if (zAddressesErr) {
rpc.getaddressesbyaccount(''), return dispatch(
); loadWalletSummaryError({
error: zAddressesErr.message,
}),
);
}
// eslint-disable-next-line const [tAddressesErr, tAddresses = []] = await eres(rpc.getaddressesbyaccount(''));
if (zAddressesErr || tAddressesErr) return dispatch(
loadWalletSummaryError({ if (tAddressesErr) {
error: zAddressesErr?.message || tAddressesErr?.message, return dispatch(
}), loadWalletSummaryError({
); error: tAddressesErr.message,
}),
);
}
const [transactionsErr, transactions] = await eres(rpc.listtransactions()); const [transactionsErr, transactions] = await eres(rpc.listtransactions());
if (transactionsErr) { if (transactionsErr) {
return dispatch( return dispatch(loadWalletSummaryError({ error: transactionsErr.message }));
loadWalletSummaryError({ error: transactionsErr.message }),
);
} }
const formattedTransactions = flow([ const formattedTransactions = flow([
@ -75,20 +80,18 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
])(transactions); ])(transactions);
if (!zAddresses.length) { if (!zAddresses.length) {
const [getNewZAddressErr, newZAddress] = await eres( const [getNewZAddressErr, newZAddress] = await eres(rpc.z_getnewaddress());
rpc.z_getnewaddress(),
);
if (!getNewZAddressErr && newZAddress) { if (!getNewZAddressErr && newZAddress) {
zAddresses.push(newZAddress); zAddresses.push(newZAddress);
} }
} }
if (!transparentAddresses.length) { if (!tAddresses.length) {
const [getNewAddressErr, newAddress] = await eres(rpc.getnewaddress('')); const [getNewAddressErr, newAddress] = await eres(rpc.getnewaddress(''));
if (!getNewAddressErr && newAddress) { if (!getNewAddressErr && newAddress) {
transparentAddresses.push(newAddress); tAddresses.push(newAddress);
} }
} }
@ -97,9 +100,9 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
transparent: walletSummary.transparent, transparent: walletSummary.transparent,
total: walletSummary.total, total: walletSummary.total,
shielded: walletSummary.private, shielded: walletSummary.private,
addresses: [...zAddresses, ...transparentAddresses], addresses: [...zAddresses, ...tAddresses],
transactions: formattedTransactions, transactions: formattedTransactions,
zecPrice: store.get('ZEC_DOLLAR_PRICE'), zecPrice: Number(store.get('ZEC_DOLLAR_PRICE')),
}), }),
); );
}, },

View File

@ -48,6 +48,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
}: SendTransactionInput) => { }: SendTransactionInput) => {
dispatch(sendTransaction()); dispatch(sendTransaction());
// $FlowFixMe
const [sendErr, operationId] = await eres( const [sendErr, operationId] = await eres(
rpc.z_sendmany( rpc.z_sendmany(
from, from,
@ -136,7 +137,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
}, },
loadZECPrice: () => dispatch( loadZECPrice: () => dispatch(
loadZECPrice({ loadZECPrice({
value: store.get('ZEC_DOLLAR_PRICE'), value: Number(store.get('ZEC_DOLLAR_PRICE')),
}), }),
), ),
}); });

View File

@ -31,14 +31,10 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
getTransactions: async () => { getTransactions: async () => {
dispatch(loadTransactions()); dispatch(loadTransactions());
const [transactionsErr, transactions = []] = await eres( const [transactionsErr, transactions = []] = await eres(rpc.listtransactions());
rpc.listtransactions(),
);
if (transactionsErr) { if (transactionsErr) {
return dispatch( return dispatch(loadTransactionsError({ error: transactionsErr.message }));
loadTransactionsError({ error: transactionsErr.message }),
);
} }
const formattedTransactions = flow([ const formattedTransactions = flow([
@ -60,7 +56,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
dispatch( dispatch(
loadTransactionsSuccess({ loadTransactionsSuccess({
list: formattedTransactions, list: formattedTransactions,
zecPrice: store.get('ZEC_DOLLAR_PRICE'), zecPrice: Number(store.get('ZEC_DOLLAR_PRICE')),
}), }),
); );
}, },

View File

@ -1,7 +1,10 @@
// @flow
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import App from './app'; import App from './app';
const el = document.getElementById('root'); const el = document.getElementById('root');
ReactDOM.render(<App />, el);
if (el) ReactDOM.render(<App />, el);

View File

@ -8,7 +8,7 @@ export const LOAD_WALLET_SUMMARY_SUCCESS = 'LOAD_WALLET_SUMMARY_SUCCESS';
export const LOAD_WALLET_SUMMARY_ERROR = 'LOAD_WALLET_SUMMARY_ERROR'; export const LOAD_WALLET_SUMMARY_ERROR = 'LOAD_WALLET_SUMMARY_ERROR';
// Actions Creators // Actions Creators
export const loadWalletSummary = () => ({ export const loadWalletSummary: () => Action = () => ({
type: LOAD_WALLET_SUMMARY, type: LOAD_WALLET_SUMMARY,
payload: {}, payload: {},
}); });

View File

@ -4,4 +4,4 @@ type State = {||};
export type Action = { type: $Subtype<string>, payload: Object }; export type Action = { type: $Subtype<string>, payload: Object };
export type GetState = () => State; export type GetState = () => State;
export type Dispatch = (action: Action) => any; export type Dispatch = (action: Action) => void;

View File

@ -170,6 +170,7 @@ export class SettingsView extends PureComponent<Props, State> {
)}.dat`; )}.dat`;
electron.remote.dialog.showSaveDialog( electron.remote.dialog.showSaveDialog(
undefined,
{ defaultPath: backupFileName }, { defaultPath: backupFileName },
async (pathToSave) => { async (pathToSave) => {
if (!pathToSave) return; if (!pathToSave) return;
@ -182,19 +183,13 @@ export class SettingsView extends PureComponent<Props, State> {
/* eslint-disable no-alert */ /* eslint-disable no-alert */
if (cannotAccess) { if (cannotAccess) {
alert( alert("Couldn't backup the wallet.dat file. You need to back it up manually.");
"Couldn't backup the wallet.dat file. You need to back it up manually.",
);
} }
const [error] = await eres( const [error] = await eres(promisify(fs.copyFile)(walletDatPath, pathToSave));
promisify(fs.copyFile)(walletDatPath, pathToSave),
);
if (error) { if (error) {
alert( alert("Couldn't backup the wallet.dat file. You need to back it up manually.");
"Couldn't backup the wallet.dat file. You need to back it up manually.",
);
} }
}, },
); );
@ -307,16 +302,12 @@ export class SettingsView extends PureComponent<Props, State> {
<InputLabelComponent value='Please paste your private keys here, one per line. The keys will be imported into your zcashd node' /> <InputLabelComponent value='Please paste your private keys here, one per line. The keys will be imported into your zcashd node' />
<InputComponent <InputComponent
value={importedPrivateKeys} value={importedPrivateKeys}
onChange={value => this.setState({ importedPrivateKeys: value }) onChange={value => this.setState({ importedPrivateKeys: value })}
}
inputType='textarea' inputType='textarea'
rows={10} rows={10}
/> />
{successImportPrivateKeys && ( {successImportPrivateKeys && (
<TextComponent <TextComponent value='Private keys imported in your node' align='center' />
value='Private keys imported in your node'
align='center'
/>
)} )}
{error && <TextComponent value={error} align='center' />} {error && <TextComponent value={error} align='center' />}
</ModalContent> </ModalContent>

View File

@ -71,9 +71,7 @@ const downloadFile = ({ file, pathToSave }): Promise<*> => new Promise((resolve,
log(`SHA256 validation for file ${file.name} succeeded!`); log(`SHA256 validation for file ${file.name} succeeded!`);
resolve(file.name); resolve(file.name);
} else { } else {
reject( reject(new Error(`SHA256 validation failed for file: ${file.name}`));
new Error(`SHA256 validation failed for file: ${file.name}`),
);
} }
}); });
}) })
@ -84,9 +82,7 @@ const downloadFile = ({ file, pathToSave }): Promise<*> => new Promise((resolve,
let missingDownloadParam = false; let missingDownloadParam = false;
export default (): Promise<*> => new Promise((resolve, reject) => { export default (): Promise<*> => new Promise((resolve, reject) => {
const firstRunProcess = cp.spawn( const firstRunProcess = cp.spawn(path.join(getBinariesPath(), 'win', 'first-run.bat'));
path.join(getBinariesPath(), 'win', 'first-run.bat'),
);
firstRunProcess.stdout.on('data', data => log(data.toString())); firstRunProcess.stdout.on('data', data => log(data.toString()));
firstRunProcess.stderr.on('data', data => reject(data.toString())); firstRunProcess.stderr.on('data', data => reject(data.toString()));
@ -95,12 +91,7 @@ export default (): Promise<*> => new Promise((resolve, reject) => {
await Promise.all( await Promise.all(
FILES.map(async (file) => { FILES.map(async (file) => {
const pathToSave = path.join( const pathToSave = path.join(app.getPath('userData'), '..', 'ZcashParams', file.name);
app.getPath('userData'),
'..',
'ZcashParams',
file.name,
);
const [cannotAccess] = await eres( const [cannotAccess] = await eres(
util.promisify(fs.access)(pathToSave, fs.constants.F_OK), util.promisify(fs.access)(pathToSave, fs.constants.F_OK),
@ -115,11 +106,7 @@ export default (): Promise<*> => new Promise((resolve, reject) => {
if (isValid) { if (isValid) {
log(`${file.name} already is in ${pathToSave}...`); log(`${file.name} already is in ${pathToSave}...`);
} else { } else {
log( log(`File: ${file.name} failed in the SHASUM validation, downloading again...`);
`File: ${
file.name
} failed in the SHASUM validation, downloading again...`,
);
queue.add(() => { queue.add(() => {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
downloadFile({ file, pathToSave }).then(() => log(`Download ${file.name} finished!`)); downloadFile({ file, pathToSave }).then(() => log(`Download ${file.name} finished!`));

View File

@ -5,11 +5,9 @@ import dotenv from 'dotenv';
import path from 'path'; import path from 'path';
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import { app, BrowserWindow } from 'electron'; import { app, BrowserWindow, typeof BrowserWindow as BrowserWindowType } from 'electron';
import { autoUpdater } from 'electron-updater'; import { autoUpdater } from 'electron-updater';
import isDev from 'electron-is-dev'; import isDev from 'electron-is-dev';
/* eslint-enable import/no-extraneous-dependencies */
import type { BrowserWindow as BrowserWindowType } from 'electron';
import eres from 'eres'; import eres from 'eres';
import { registerDebugShortcut } from '../utils/debug-shortcut'; import { registerDebugShortcut } from '../utils/debug-shortcut';
import runDaemon from './daemon/zcashd-child-process'; import runDaemon from './daemon/zcashd-child-process';
@ -26,10 +24,12 @@ let zcashDaemon;
const showStatus = (text) => { const showStatus = (text) => {
if (text === 'Update downloaded') updateAvailable = true; if (text === 'Update downloaded') updateAvailable = true;
mainWindow.webContents.send('update', { if (mainWindow) {
updateAvailable, mainWindow.webContents.send('update', {
updateInfo: text, updateAvailable,
}); updateInfo: text,
});
}
}; };
const createWindow = () => { const createWindow = () => {
@ -42,9 +42,9 @@ const createWindow = () => {
autoUpdater.on('download-progress', progress => showStatus( autoUpdater.on('download-progress', progress => showStatus(
/* eslint-disable-next-line max-len */ /* eslint-disable-next-line max-len */
`Download speed: ${progress.bytesPerSecond} - Downloaded ${ `Download speed: ${progress.bytesPerSecond} - Downloaded ${progress.percent}% (${
progress.percent progress.transferred
}% (${progress.transferred}/${progress.total})`, }/${progress.total})`,
)); ));
autoUpdater.on('update-downloaded', () => { autoUpdater.on('update-downloaded', () => {
updateAvailable = true; updateAvailable = true;
@ -64,16 +64,14 @@ const createWindow = () => {
}); });
getZecPrice().then((obj) => { getZecPrice().then((obj) => {
store.set('ZEC_DOLLAR_PRICE', obj.USD); store.set('ZEC_DOLLAR_PRICE', String(obj.USD));
}); });
mainWindow.setVisibleOnAllWorkspaces(true); mainWindow.setVisibleOnAllWorkspaces(true);
registerDebugShortcut(app, mainWindow); registerDebugShortcut(app, mainWindow);
mainWindow.loadURL( mainWindow.loadURL(
isDev isDev ? 'http://0.0.0.0:8080/' : `file://${path.join(__dirname, '../build/index.html')}`,
? 'http://0.0.0.0:8080/'
: `file://${path.join(__dirname, '../build/index.html')}`,
); );
exports.app = app; exports.app = app;

View File

@ -1,3 +1,5 @@
// @flow
const path = require('path'); const path = require('path');
const appRoot = path.join(__dirname, '..'); const appRoot = path.join(__dirname, '..');

View File

@ -679,6 +679,7 @@ export type APIMethods = {
amount: number, amount: number,
vout: number, vout: number,
fee: number, fee: number,
category: string,
confirmations: number, confirmations: number,
blockhash: string, blockhash: string,
blockindex: number, blockindex: number,

View File

@ -1,5 +1,6 @@
// @flow // @flow
// eslint-disable-next-line import/no-extraneous-dependencies /* eslint-disable import/no-extraneous-dependencies */
// $FlowFixMe
import { net } from 'electron'; import { net } from 'electron';
type Payload = { type Payload = {

View File

@ -1,9 +1,15 @@
// @flow // @flow
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import { globalShortcut } from 'electron'; import { globalShortcut, typeof BrowserWindow, typeof app as ElectronApp } from 'electron';
export const registerDebugShortcut = (app: Object, mainWindow: Object) => globalShortcut.register('CommandOrControl+Option+B', () => { export const registerDebugShortcut = (app: ElectronApp, mainWindow: BrowserWindow) => {
app.dock.show(); if (globalShortcut) {
mainWindow.webContents.openDevTools(); globalShortcut.register('CommandOrControl+Option+B', () => {
}); // $FlowFixMe
app.dock.show();
// $FlowFixMe
mainWindow.webContents.openDevTools();
});
}
};