1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-21 17:37:01 +01:00

Update ESLint config to v8 (#12886)

The ESLint config has been updated to v8. The breaking changes are:

* The Prettier rule `quoteProps` has been changed from `consistent` to
`as-needed`, meaning that if one key requires quoting, only that key is
quoted rather than all keys.
* The ESLint rule `no-shadow` has been made more strict. It now
prevents globals from being shadowed as well.

Most of these changes were applied with `yarn lint:fix`. Only the
shadowing changes required manual fixing (shadowing variable names were
either replaced with destructuring or renamed).

The dependency `globalThis` was added to the list of dynamic
dependencies in the build system, where it should have been already.
This was causing `depcheck` to fail because the new lint rules required
removing the one place where `globalThis` had been erroneously imported
previously.

A rule requiring a newline between multiline blocks and expressions has
been disabled temporarily to make this PR smaller and to avoid
introducing conflicts with other PRs.
This commit is contained in:
Mark Stacey 2021-12-09 15:36:24 -03:30 committed by GitHub
parent d4ebf98cc4
commit ba54a3d83b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 295 additions and 266 deletions

View File

@ -87,6 +87,27 @@ module.exports = {
'node/no-process-env': 'off',
// TODO: remove this override
'padding-line-between-statements': [
'error',
{
blankLine: 'always',
prev: 'directive',
next: '*',
},
{
blankLine: 'any',
prev: 'directive',
next: 'directive',
},
// Disabled temporarily to reduce conflicts while PR queue is large
// {
// blankLine: 'always',
// prev: ['multiline-block-like', 'multiline-expression'],
// next: ['multiline-block-like', 'multiline-expression'],
// },
],
// TODO: re-enable these rules
'node/no-sync': 'off',
'node/no-unpublished-import': 'off',

View File

@ -119,9 +119,9 @@ describe('Transaction state history helper', function () {
},
};
const before = new Date().getTime();
const timeBefore = new Date().getTime();
const result = generateHistoryEntry(prevState, nextState, note);
const after = new Date().getTime();
const timeAfter = new Date().getTime();
assert.ok(Array.isArray(result));
assert.equal(result.length, 3);
@ -134,7 +134,9 @@ describe('Transaction state history helper', function () {
assert.equal(result[0].path, expectedEntry1.path);
assert.equal(result[0].value, expectedEntry1.value);
assert.equal(result[0].note, note);
assert.ok(result[0].timestamp >= before && result[0].timestamp <= after);
assert.ok(
result[0].timestamp >= timeBefore && result[0].timestamp <= timeAfter,
);
const expectedEntry2 = {
op: 'replace',

View File

@ -845,9 +845,9 @@ describe('TransactionStateManager', function () {
);
// modify value and updateTransaction
updatedTx.txParams.gasPrice = desiredGasPrice;
const before = new Date().getTime();
const timeBefore = new Date().getTime();
txStateManager.updateTransaction(updatedTx);
const after = new Date().getTime();
const timeAfter = new Date().getTime();
// check updated value
const result = txStateManager.getTransaction('1');
assert.equal(
@ -888,8 +888,8 @@ describe('TransactionStateManager', function () {
'two history items (initial + diff) value',
);
assert.ok(
result.history[1][0].timestamp >= before &&
result.history[1][0].timestamp <= after,
result.history[1][0].timestamp >= timeBefore &&
result.history[1][0].timestamp <= timeAfter,
);
});

View File

@ -27,7 +27,7 @@ const createWyrePurchaseUrl = async (address) => {
const response = await fetchWithTimeout(fiatOnRampUrlApi, {
method: 'GET',
headers: {
'Accept': 'application/json',
Accept: 'application/json',
'Content-Type': 'application/json',
},
});

View File

@ -351,13 +351,13 @@ describe('migration #48', () => {
data: {
AddressBookController: {
addressBook: {
'1': {
1: {
address1: {
chainId: '1',
foo: 'bar',
},
},
'100': {
100: {
address1: {
chainId: '100',
foo: 'bar',
@ -416,7 +416,7 @@ describe('migration #48', () => {
data: {
AddressBookController: {
addressBook: {
'2': {
2: {
address1: {
chainId: '2',
key2: 'kaplar',
@ -489,7 +489,7 @@ describe('migration #48', () => {
AddressBookController: {
addressBook: {
'0x1': { foo: { bar: 'baz' } },
'kaplar': { foo: { bar: 'baz' } },
kaplar: { foo: { bar: 'baz' } },
},
bar: {
baz: 'buzz',
@ -505,7 +505,7 @@ describe('migration #48', () => {
AddressBookController: {
addressBook: {
'0x1': { foo: { bar: 'baz' } },
'kaplar': { foo: { bar: 'baz' } },
kaplar: { foo: { bar: 'baz' } },
},
bar: {
baz: 'buzz',

View File

@ -210,7 +210,7 @@ function getOldState() {
permissions: [
{
'@context': ['https://github.com/MetaMask/rpc-cap'],
'caveats': [
caveats: [
{
name: 'primaryAccountOnly',
type: 'limitResponseLength',
@ -222,10 +222,10 @@ function getOldState() {
value: ['0xc42edfcc21ed14dda456aa0756c153f7985d8813'],
},
],
'date': 1597334833084,
'id': 'e01bada4-ddc7-47b6-be67-d4603733e0e9',
'invoker': 'https://faucet.metamask.io',
'parentCapability': 'eth_accounts',
date: 1597334833084,
id: 'e01bada4-ddc7-47b6-be67-d4603733e0e9',
invoker: 'https://faucet.metamask.io',
parentCapability: 'eth_accounts',
},
],
},
@ -233,7 +233,7 @@ function getOldState() {
permissions: [
{
'@context': ['https://github.com/MetaMask/rpc-cap'],
'caveats': [
caveats: [
{
name: 'primaryAccountOnly',
type: 'limitResponseLength',
@ -245,10 +245,10 @@ function getOldState() {
value: ['0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'],
},
],
'date': 1616006369498,
'id': '3d0bdc27-e8e4-4fb0-a24b-340d61f6a3fa',
'invoker': 'https://metamask.github.io',
'parentCapability': 'eth_accounts',
date: 1616006369498,
id: '3d0bdc27-e8e4-4fb0-a24b-340d61f6a3fa',
invoker: 'https://metamask.github.io',
parentCapability: 'eth_accounts',
},
],
},
@ -256,7 +256,7 @@ function getOldState() {
permissions: [
{
'@context': ['https://github.com/MetaMask/rpc-cap'],
'caveats': [
caveats: [
{
name: 'primaryAccountOnly',
type: 'limitResponseLength',
@ -268,10 +268,10 @@ function getOldState() {
value: ['0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'],
},
],
'date': 1605908022382,
'id': '88c5de24-11a9-4f1e-9651-b072f4c11928',
'invoker': 'https://xdai.io',
'parentCapability': 'eth_accounts',
date: 1605908022382,
id: '88c5de24-11a9-4f1e-9651-b072f4c11928',
invoker: 'https://xdai.io',
parentCapability: 'eth_accounts',
},
],
},
@ -388,7 +388,7 @@ function getOldState() {
result: [
{
'@context': ['https://github.com/MetaMask/rpc-cap'],
'caveats': [
caveats: [
{
name: 'primaryAccountOnly',
type: 'limitResponseLength',
@ -400,10 +400,10 @@ function getOldState() {
value: ['0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'],
},
],
'date': 1616006369498,
'id': '3d0bdc27-e8e4-4fb0-a24b-340d61f6a3fa',
'invoker': 'https://metamask.github.io',
'parentCapability': 'eth_accounts',
date: 1616006369498,
id: '3d0bdc27-e8e4-4fb0-a24b-340d61f6a3fa',
invoker: 'https://metamask.github.io',
parentCapability: 'eth_accounts',
},
],
},

View File

@ -23,6 +23,7 @@ const { BuildType, getBrowserVersionMap } = require('./utils');
// Packages required dynamically via browserify configuration in dependencies
// Required for LavaMoat policy generation
require('loose-envify');
require('globalthis');
require('@babel/plugin-proposal-object-rest-spread');
require('@babel/plugin-transform-runtime');
require('@babel/plugin-proposal-class-properties');

View File

@ -3,7 +3,7 @@ const { PassThrough, Transform } = require('stream');
const { BuildType } = require('../utils');
const { lintTransformedFile } = require('./utils');
const hasOwnProperty = (obj, key) => Reflect.hasOwnProperty.call(obj, key);
const hasKey = (obj, key) => Reflect.hasOwnProperty.call(obj, key);
module.exports = {
createRemoveFencedCodeTransform,
@ -90,7 +90,7 @@ function createRemoveFencedCodeTransform(
buildType,
shouldLintTransformedFiles = true,
) {
if (!hasOwnProperty(BuildType, buildType)) {
if (!hasKey(BuildType, buildType)) {
throw new Error(
`Code fencing transform received unrecognized build type "${buildType}".`,
);
@ -140,7 +140,7 @@ const CommandValidators = {
}
params.forEach((param) => {
if (!hasOwnProperty(BuildType, param)) {
if (!hasKey(BuildType, param)) {
throw new Error(
getInvalidParamsMessage(
filePath,
@ -250,7 +250,7 @@ function removeFencedCode(filePath, typeOfCurrentBuild, fileContent) {
// The first element of a RegEx match array is the input
const [, terminus, command, parameters] = directiveMatches;
if (!hasOwnProperty(DirectiveTerminuses, terminus)) {
if (!hasKey(DirectiveTerminuses, terminus)) {
throw new Error(
getInvalidFenceLineMessage(
filePath,
@ -259,7 +259,8 @@ function removeFencedCode(filePath, typeOfCurrentBuild, fileContent) {
),
);
}
if (!hasOwnProperty(DirectiveCommands, command)) {
if (!hasKey(DirectiveCommands, command)) {
throw new Error(
getInvalidFenceLineMessage(
filePath,

View File

@ -240,7 +240,7 @@ async function start() {
body: JSON_PAYLOAD,
headers: {
'User-Agent': 'metamaskbot',
'Authorization': `token ${GITHUB_COMMENT_TOKEN}`,
Authorization: `token ${GITHUB_COMMENT_TOKEN}`,
},
});
if (!response.ok) {

View File

@ -8,7 +8,7 @@ module.exports = {
coveragePathIgnorePatterns: ['.stories.js', '.snap'],
coverageReporters: ['html', 'text-summary'],
coverageThreshold: {
'global': {
global: {
branches: 35,
functions: 37,
lines: 43,

View File

@ -2547,6 +2547,11 @@
"which": true
}
},
"globalthis": {
"packages": {
"define-properties": true
}
},
"globby": {
"builtin": {
"fs.Stats": true,

View File

@ -232,10 +232,10 @@
"@lavamoat/allow-scripts": "^1.0.6",
"@lavamoat/lavapack": "^2.0.4",
"@metamask/auto-changelog": "^2.1.0",
"@metamask/eslint-config": "^6.0.0",
"@metamask/eslint-config-jest": "^6.0.0",
"@metamask/eslint-config-mocha": "^6.0.0",
"@metamask/eslint-config-nodejs": "^6.0.0",
"@metamask/eslint-config": "^8.0.0",
"@metamask/eslint-config-jest": "^8.0.0",
"@metamask/eslint-config-mocha": "^8.0.0",
"@metamask/eslint-config-nodejs": "^8.0.0",
"@metamask/forwarder": "^1.1.0",
"@metamask/test-dapp": "^4.0.1",
"@sentry/cli": "^1.58.0",

View File

@ -73,7 +73,7 @@ module.exports = {
'function-parentheses-newline-inside': 'always-multi-line',
'function-parentheses-space-inside': 'never-single-line',
'function-whitespace-after': 'always',
'indentation': 2,
indentation: 2,
'length-zero-no-unit': true,
// 'max-empty-lines': 1,
'media-feature-colon-space-after': 'always',

View File

@ -138,28 +138,28 @@ const AssetListItem = ({
};
AssetListItem.propTypes = {
'className': PropTypes.string,
className: PropTypes.string,
'data-testid': PropTypes.string,
'iconClassName': PropTypes.string,
'onClick': PropTypes.func.isRequired,
'tokenAddress': PropTypes.string,
'tokenSymbol': PropTypes.string,
'tokenDecimals': PropTypes.number,
'tokenImage': PropTypes.string,
'warning': PropTypes.node,
'primary': PropTypes.string,
'secondary': PropTypes.string,
'identiconBorder': PropTypes.bool,
'isERC721': PropTypes.bool,
iconClassName: PropTypes.string,
onClick: PropTypes.func.isRequired,
tokenAddress: PropTypes.string,
tokenSymbol: PropTypes.string,
tokenDecimals: PropTypes.number,
tokenImage: PropTypes.string,
warning: PropTypes.node,
primary: PropTypes.string,
secondary: PropTypes.string,
identiconBorder: PropTypes.bool,
isERC721: PropTypes.bool,
};
AssetListItem.defaultProps = {
'className': undefined,
className: undefined,
'data-testid': undefined,
'iconClassName': undefined,
'tokenAddress': undefined,
'tokenImage': undefined,
'warning': undefined,
iconClassName: undefined,
tokenAddress: undefined,
tokenImage: undefined,
warning: undefined,
};
export default AssetListItem;

View File

@ -9,7 +9,7 @@ export default function UserPreferencedCurrencyDisplay({
ethLogoHeight = 12,
ethNumberOfDecimals,
fiatNumberOfDecimals,
'numberOfDecimals': propsNumberOfDecimals,
numberOfDecimals: propsNumberOfDecimals,
showEthLogo,
type,
...restProps
@ -40,22 +40,22 @@ export default function UserPreferencedCurrencyDisplay({
}
UserPreferencedCurrencyDisplay.propTypes = {
'className': PropTypes.string,
className: PropTypes.string,
'data-testid': PropTypes.string,
'prefix': PropTypes.string,
'value': PropTypes.string,
'numberOfDecimals': PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
'hideLabel': PropTypes.bool,
'hideTitle': PropTypes.bool,
'style': PropTypes.object,
'showEthLogo': PropTypes.bool,
'ethLogoHeight': PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
'type': PropTypes.oneOf([PRIMARY, SECONDARY]),
'ethNumberOfDecimals': PropTypes.oneOfType([
prefix: PropTypes.string,
value: PropTypes.string,
numberOfDecimals: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
hideLabel: PropTypes.bool,
hideTitle: PropTypes.bool,
style: PropTypes.object,
showEthLogo: PropTypes.bool,
ethLogoHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
type: PropTypes.oneOf([PRIMARY, SECONDARY]),
ethNumberOfDecimals: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
'fiatNumberOfDecimals': PropTypes.oneOfType([
fiatNumberOfDecimals: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),

View File

@ -8,19 +8,19 @@ export default {
component: ActionableMessage,
parameters: { docs: { page: README } },
argTypes: {
'message': { control: 'text' },
message: { control: 'text' },
'primaryAction.label': { control: 'text' },
'primaryAction.onClick': { action: 'primaryAction.onClick' },
'primaryActionV2.label': { control: 'text' },
'primaryActionV2.onClick': { action: 'primaryActionV2.onClick' },
'secondaryAction.label': { control: 'text' },
'secondaryAction.onClick': { action: 'secondaryAction.onClick' },
'className': { control: 'text' },
'type': { control: 'text' },
'withRightButton': { control: 'boolean' },
'infoTooltipText': { control: 'text' },
'useIcon': { control: 'boolean' },
'iconFillColor': { control: 'color' },
className: { control: 'text' },
type: { control: 'text' },
withRightButton: { control: 'boolean' },
infoTooltipText: { control: 'text' },
useIcon: { control: 'boolean' },
iconFillColor: { control: 'color' },
},
};

View File

@ -12,16 +12,16 @@ const CLASSNAME_ROUNDED = 'btn--rounded';
const CLASSNAME_FIRST_TIME = 'btn--first-time';
const typeHash = {
'default': CLASSNAME_DEFAULT,
'primary': CLASSNAME_PRIMARY,
'secondary': CLASSNAME_SECONDARY,
'warning': 'btn-warning',
'danger': 'btn-danger',
default: CLASSNAME_DEFAULT,
primary: CLASSNAME_PRIMARY,
secondary: CLASSNAME_SECONDARY,
warning: 'btn-warning',
danger: 'btn-danger',
'danger-primary': 'btn-danger-primary',
'link': 'btn-link',
link: 'btn-link',
// TODO: Legacy button type to be deprecated
'confirm': CLASSNAME_CONFIRM,
'raised': CLASSNAME_RAISED,
confirm: CLASSNAME_CONFIRM,
raised: CLASSNAME_RAISED,
'first-time': CLASSNAME_FIRST_TIME,
};

View File

@ -50,17 +50,17 @@ export default function CurrencyDisplay({
}
CurrencyDisplay.propTypes = {
'className': PropTypes.string,
'currency': PropTypes.string,
className: PropTypes.string,
currency: PropTypes.string,
'data-testid': PropTypes.string,
'denomination': PropTypes.oneOf([GWEI, ETH]),
'displayValue': PropTypes.string,
'hideLabel': PropTypes.bool,
'hideTitle': PropTypes.bool,
'numberOfDecimals': PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
'prefix': PropTypes.string,
'prefixComponent': PropTypes.node,
'style': PropTypes.object,
'suffix': PropTypes.string,
'value': PropTypes.string,
denomination: PropTypes.oneOf([GWEI, ETH]),
displayValue: PropTypes.string,
hideLabel: PropTypes.bool,
hideTitle: PropTypes.bool,
numberOfDecimals: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
prefix: PropTypes.string,
prefixComponent: PropTypes.node,
style: PropTypes.object,
suffix: PropTypes.string,
value: PropTypes.string,
};

View File

@ -25,13 +25,13 @@ const basic = {
const advanced = {
'Network Name': 'Ethereum Mainnet',
'Chain ID': '1',
'Ticker': 'ETH',
Ticker: 'ETH',
};
const tooltips = {
'Network Name': 'The name that is associated with this network',
'Chain ID': 'The numeric value representing the ID of this network',
'Ticker': 'The currency symbol of the primary currency for this network',
Ticker: 'The currency symbol of the primary currency for this network',
};
export const DefaultStory = () => (

View File

@ -36,11 +36,11 @@ export default function IconButton({
}
IconButton.propTypes = {
'onClick': PropTypes.func.isRequired,
'Icon': PropTypes.func.isRequired,
'disabled': PropTypes.bool,
'label': PropTypes.string.isRequired,
'tooltipRender': PropTypes.func,
'className': PropTypes.string,
onClick: PropTypes.func.isRequired,
Icon: PropTypes.func.isRequired,
disabled: PropTypes.bool,
label: PropTypes.string.isRequired,
tooltipRender: PropTypes.func,
className: PropTypes.string,
'data-testid': PropTypes.string,
};

View File

@ -59,14 +59,14 @@ export default function ListItem({
}
ListItem.propTypes = {
'title': PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
'titleIcon': PropTypes.node,
'subtitle': PropTypes.node,
'children': PropTypes.node,
'icon': PropTypes.node,
'rightContent': PropTypes.node,
'midContent': PropTypes.node,
'className': PropTypes.string,
'onClick': PropTypes.func,
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
titleIcon: PropTypes.node,
subtitle: PropTypes.node,
children: PropTypes.node,
icon: PropTypes.node,
rightContent: PropTypes.node,
midContent: PropTypes.node,
className: PropTypes.string,
onClick: PropTypes.func,
'data-testid': PropTypes.string,
};

View File

@ -24,20 +24,20 @@ const MenuItem = ({
);
MenuItem.propTypes = {
'children': PropTypes.node.isRequired,
'className': PropTypes.string,
children: PropTypes.node.isRequired,
className: PropTypes.string,
'data-testid': PropTypes.string,
'iconClassName': PropTypes.string,
'onClick': PropTypes.func,
'subtitle': PropTypes.node,
iconClassName: PropTypes.string,
onClick: PropTypes.func,
subtitle: PropTypes.node,
};
MenuItem.defaultProps = {
'className': undefined,
className: undefined,
'data-testid': undefined,
'iconClassName': undefined,
'onClick': undefined,
'subtitle': undefined,
iconClassName: undefined,
onClick: undefined,
subtitle: undefined,
};
export default MenuItem;

View File

@ -28,14 +28,14 @@ const styles = {
height: 6,
},
thumb: {
'height': 20,
'width': 20,
'marginTop': -7,
'marginLeft': -7,
'backgroundColor': '#037DD6',
'border': '1px solid #EAF6FF',
'boxSizing': 'border-box',
'boxShadow': '0px 0px 14px 0px rgba(0, 0, 0, 0.18)',
height: 20,
width: 20,
marginTop: -7,
marginLeft: -7,
backgroundColor: '#037DD6',
border: '1px solid #EAF6FF',
boxSizing: 'border-box',
boxShadow: '0px 0px 14px 0px rgba(0, 0, 0, 0.18)',
'&:focus, &$active': {
height: 20,
width: 20,

View File

@ -31,13 +31,13 @@ const Tab = (props) => {
};
Tab.propTypes = {
'activeClassName': PropTypes.string,
'className': PropTypes.string,
activeClassName: PropTypes.string,
className: PropTypes.string,
'data-testid': PropTypes.string,
'isActive': PropTypes.bool, // required, but added using React.cloneElement
'name': PropTypes.string.isRequired,
'onClick': PropTypes.func,
'tabIndex': PropTypes.number, // required, but added using React.cloneElement
isActive: PropTypes.bool, // required, but added using React.cloneElement
name: PropTypes.string.isRequired,
onClick: PropTypes.func,
tabIndex: PropTypes.number, // required, but added using React.cloneElement
};
Tab.defaultProps = {

View File

@ -18,8 +18,8 @@ const styles = {
'&$materialError': {
color: '#aeaeae',
},
'fontWeight': '400',
'color': '#aeaeae',
fontWeight: '400',
color: '#aeaeae',
},
materialFocused: {},
materialUnderline: {
@ -32,7 +32,7 @@ const styles = {
color: '#aeaeae',
},
materialWhitePaddedInput: {
'padding': '8px',
padding: '8px',
'&::placeholder': {
color: '#aeaeae',
@ -61,12 +61,12 @@ const styles = {
'label + &': {
marginTop: '9px',
},
'border': '1px solid #BBC0C5',
'height': '48px',
'borderRadius': '6px',
'padding': '0 16px',
'display': 'flex',
'alignItems': 'center',
border: '1px solid #BBC0C5',
height: '48px',
borderRadius: '6px',
padding: '0 16px',
display: 'flex',
alignItems: 'center',
'&$inputFocused': {
border: '1px solid #2f9ae0',
},
@ -188,8 +188,8 @@ const getBorderedThemeInputProps = ({
});
const themeToInputProps = {
'material': getMaterialThemeInputProps,
'bordered': getBorderedThemeInputProps,
material: getMaterialThemeInputProps,
bordered: getBorderedThemeInputProps,
'material-white-padded': getMaterialWhitePaddedThemeInputProps,
};

View File

@ -39,8 +39,8 @@ Password.args = {
label: 'Password',
type: 'password',
};
export const Error = (args) => <TextField {...args} />;
Error.args = {
export const TextError = (args) => <TextField {...args} />;
TextError.args = {
type: 'text',
label: 'Name',
error: 'Invalid Value',

View File

@ -21,13 +21,13 @@ const basic = {
const advanced = {
'Network Name': 'Ethereum Mainnet',
'Chain ID': '1',
'Ticker': 'ETH',
Ticker: 'ETH',
};
const tooltips = {
'Network Name': 'The name that is associated with this network',
'Chain ID': 'The numeric value representing the ID of this network',
'Ticker': 'The currency symbol of the primary currency for this network',
Ticker: 'The currency symbol of the primary currency for this network',
};
export const DefaultStory = () => (

View File

@ -5,21 +5,21 @@ describe('Common utils', () => {
it('should return a capitalized string from a camel-cased string', () => {
const tests = [
{
test: undefined,
input: undefined,
expected: '',
},
{
test: '',
input: '',
expected: '',
},
{
test: 'thisIsATest',
input: 'thisIsATest',
expected: 'This Is A Test',
},
];
tests.forEach(({ test, expected }) => {
expect(utils.camelCaseToCapitalize(test)).toStrictEqual(expected);
tests.forEach(({ input, expected }) => {
expect(utils.camelCaseToCapitalize(input)).toStrictEqual(expected);
});
});
});

View File

@ -45,22 +45,22 @@ const tests = [
];
describe('useTokenData', () => {
tests.forEach((test) => {
tests.forEach(({ data, tokenData }) => {
const testTitle =
// eslint-disable-next-line no-negated-condition
test.tokenData !== null
? `should return properly decoded data with _value ${test.tokenData.args[1]}`
tokenData !== null
? `should return properly decoded data with _value ${tokenData.args[1]}`
: `should return null when no data provided`;
it(`${testTitle}`, () => {
const { result } = renderHook(() => useTokenData(test.data));
if (test.tokenData) {
expect(result.current.name).toStrictEqual(test.tokenData.name);
const { result } = renderHook(() => useTokenData(data));
if (tokenData) {
expect(result.current.name).toStrictEqual(tokenData.name);
expect(result.current.args[0].toLowerCase()).toStrictEqual(
test.tokenData.args[0],
tokenData.args[0],
);
expect(test.tokenData.args[1]).toStrictEqual(result.current.args[1]);
expect(tokenData.args[1]).toStrictEqual(result.current.args[1]);
} else {
expect(result.current).toStrictEqual(test.tokenData);
expect(result.current).toStrictEqual(tokenData);
}
});
});

View File

@ -118,20 +118,20 @@ const tests = [
];
describe('useTokenDisplayValue', () => {
tests.forEach((test, idx) => {
describe(`when input is decimals: ${test.token.decimals} and value: ${test.tokenValue}`, () => {
it(`should return ${test.displayValue} as displayValue`, () => {
tests.forEach(({ displayValue, token, tokenData, tokenValue }, idx) => {
describe(`when input is decimals: ${token.decimals} and value: ${tokenValue}`, () => {
it(`should return ${displayValue} as displayValue`, () => {
const getTokenValueStub = sinon.stub(tokenUtil, 'getTokenValueParam');
const getTokenDataStub = sinon.stub(txUtil, 'getTokenData');
getTokenDataStub.callsFake(() => test.tokenData);
getTokenValueStub.callsFake(() => test.tokenValue);
getTokenDataStub.callsFake(() => tokenData);
getTokenValueStub.callsFake(() => tokenValue);
const { result } = renderHook(() =>
useTokenDisplayValue(`${idx}-fakestring`, test.token),
useTokenDisplayValue(`${idx}-fakestring`, token),
);
sinon.restore();
expect(result.current).toStrictEqual(test.displayValue);
expect(result.current).toStrictEqual(displayValue);
});
});
});

View File

@ -15,50 +15,50 @@ function shallowRender(props = {}, context = {}) {
describe('ImportWithSeedPhrase Component', () => {
it('should render without error', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const textareaCount = root.find('.first-time-flow__textarea').length;
const textareaCount = component.find('.first-time-flow__textarea').length;
expect(textareaCount).toStrictEqual(1);
});
describe('parseSeedPhrase', () => {
it('should handle a regular Secret Recovery Phrase', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const { parseSeedPhrase } = root.instance();
const { parseSeedPhrase } = component.instance();
expect(parseSeedPhrase('foo bar baz')).toStrictEqual('foo bar baz');
});
it('should handle a mixed-case Secret Recovery Phrase', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const { parseSeedPhrase } = root.instance();
const { parseSeedPhrase } = component.instance();
expect(parseSeedPhrase('FOO bAr baZ')).toStrictEqual('foo bar baz');
});
it('should handle an upper-case Secret Recovery Phrase', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const { parseSeedPhrase } = root.instance();
const { parseSeedPhrase } = component.instance();
expect(parseSeedPhrase('FOO BAR BAZ')).toStrictEqual('foo bar baz');
});
it('should trim extraneous whitespace from the given Secret Recovery Phrase', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const { parseSeedPhrase } = root.instance();
const { parseSeedPhrase } = component.instance();
expect(parseSeedPhrase(' foo bar baz ')).toStrictEqual(
'foo bar baz',
@ -66,31 +66,31 @@ describe('ImportWithSeedPhrase Component', () => {
});
it('should return an empty string when given a whitespace-only string', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const { parseSeedPhrase } = root.instance();
const { parseSeedPhrase } = component.instance();
expect(parseSeedPhrase(' ')).toStrictEqual('');
});
it('should return an empty string when given a string with only symbols', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const { parseSeedPhrase } = root.instance();
const { parseSeedPhrase } = component.instance();
expect(parseSeedPhrase('$')).toStrictEqual('');
});
it('should return an empty string for both null and undefined', () => {
const root = shallowRender({
const component = shallowRender({
onSubmit: sinon.spy(),
});
const { parseSeedPhrase } = root.instance();
const { parseSeedPhrase } = component.instance();
expect(parseSeedPhrase(undefined)).toStrictEqual('');
expect(parseSeedPhrase(null)).toStrictEqual('');

View File

@ -14,19 +14,19 @@ function shallowRender(props = {}, context = {}) {
describe('ConfirmSeedPhrase Component', () => {
it('should render correctly', () => {
const root = shallowRender({
const component = shallowRender({
seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬',
});
expect(root.find('.confirm-seed-phrase__seed-word--sorted')).toHaveLength(
12,
);
expect(
component.find('.confirm-seed-phrase__seed-word--sorted'),
).toHaveLength(12);
});
it('should add/remove selected on click', () => {
const metricsEventSpy = sinon.spy();
const replaceSpy = sinon.spy();
const root = shallowRender(
const component = shallowRender(
{
seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬',
history: { replace: replaceSpy },
@ -36,30 +36,30 @@ describe('ConfirmSeedPhrase Component', () => {
},
);
const seeds = root.find('.confirm-seed-phrase__seed-word--sorted');
const seeds = component.find('.confirm-seed-phrase__seed-word--sorted');
// Click on 3 seeds to add to selected
seeds.at(0).simulate('click');
seeds.at(1).simulate('click');
seeds.at(2).simulate('click');
expect(root.state().selectedSeedIndices).toStrictEqual([0, 1, 2]);
expect(component.state().selectedSeedIndices).toStrictEqual([0, 1, 2]);
// Click on a selected seed to remove
root.state();
root.update();
root.state();
root
component.state();
component.update();
component.state();
component
.find('.confirm-seed-phrase__seed-word--sorted')
.at(1)
.simulate('click');
expect(root.state().selectedSeedIndices).toStrictEqual([0, 2]);
expect(component.state().selectedSeedIndices).toStrictEqual([0, 2]);
});
it('should render correctly on hover', () => {
const metricsEventSpy = sinon.spy();
const replaceSpy = sinon.spy();
const root = shallowRender(
const component = shallowRender(
{
seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬',
history: { replace: replaceSpy },
@ -69,7 +69,7 @@ describe('ConfirmSeedPhrase Component', () => {
},
);
const seeds = root.find('.confirm-seed-phrase__seed-word--sorted');
const seeds = component.find('.confirm-seed-phrase__seed-word--sorted');
// Click on 3 seeds to add to selected
seeds.at(0).simulate('click');
@ -77,12 +77,12 @@ describe('ConfirmSeedPhrase Component', () => {
seeds.at(2).simulate('click');
// Dragging Seed # 2 to 0 placeth
root.instance().setDraggingSeedIndex(2);
root.instance().setHoveringIndex(0);
component.instance().setDraggingSeedIndex(2);
component.instance().setHoveringIndex(0);
root.update();
component.update();
const pendingSeeds = root.find(
const pendingSeeds = component.find(
'.confirm-seed-phrase__selected-seed-words__pending-seed',
);
@ -94,7 +94,7 @@ describe('ConfirmSeedPhrase Component', () => {
it('should insert seed in place on drop', () => {
const metricsEventSpy = sinon.spy();
const replaceSpy = sinon.spy();
const root = shallowRender(
const component = shallowRender(
{
seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬',
history: { replace: replaceSpy },
@ -104,7 +104,7 @@ describe('ConfirmSeedPhrase Component', () => {
},
);
const seeds = root.find('.confirm-seed-phrase__seed-word--sorted');
const seeds = component.find('.confirm-seed-phrase__seed-word--sorted');
// Click on 3 seeds to add to selected
seeds.at(0).simulate('click');
@ -112,14 +112,14 @@ describe('ConfirmSeedPhrase Component', () => {
seeds.at(2).simulate('click');
// Drop Seed # 2 to 0 placeth
root.instance().setDraggingSeedIndex(2);
root.instance().setHoveringIndex(0);
root.instance().onDrop(0);
component.instance().setDraggingSeedIndex(2);
component.instance().setHoveringIndex(0);
component.instance().onDrop(0);
root.update();
component.update();
expect(root.state().selectedSeedIndices).toStrictEqual([2, 0, 1]);
expect(root.state().pendingSeedIndices).toStrictEqual([2, 0, 1]);
expect(component.state().selectedSeedIndices).toStrictEqual([2, 0, 1]);
expect(component.state().pendingSeedIndices).toStrictEqual([2, 0, 1]);
});
it('should submit correctly', async () => {
@ -140,7 +140,7 @@ describe('ConfirmSeedPhrase Component', () => {
const metricsEventSpy = sinon.spy();
const replaceSpy = sinon.spy();
const initialize3BoxSpy = sinon.spy();
const root = shallowRender(
const component = shallowRender(
{
seedPhrase: '鼠 牛 虎 兔 龍 蛇 馬 羊 猴 雞 狗 豬',
history: { replace: replaceSpy },
@ -152,17 +152,17 @@ describe('ConfirmSeedPhrase Component', () => {
},
);
const sorted = root.state().sortedSeedWords;
const seeds = root.find('.confirm-seed-phrase__seed-word--sorted');
const sorted = component.state().sortedSeedWords;
const seeds = component.find('.confirm-seed-phrase__seed-word--sorted');
originalSeed.forEach((seed) => {
const seedIndex = sorted.findIndex((s) => s === seed);
seeds.at(seedIndex).simulate('click');
});
root.update();
component.update();
root.find('.first-time-flow__button').simulate('click');
component.find('.first-time-flow__button').simulate('click');
await new Promise((resolve) => setTimeout(resolve, 100));

View File

@ -3,7 +3,6 @@ import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { useLocation } from 'react-router-dom';
import { describe } from 'globalthis/implementation';
import { initialState, SEND_STAGES } from '../../ducks/send';
import { ensInitialState } from '../../ducks/ens';
import { renderWithProvider } from '../../../test/jest';

View File

@ -7,12 +7,12 @@ import ToggleButton from '../../../components/ui/toggle-button';
import AdvancedTab from './advanced-tab.component';
describe('AdvancedTab Component', () => {
let root;
let component;
let setAutoLockTimeLimitSpy = sinon.spy();
const toggleTestnet = sinon.spy();
beforeAll(() => {
root = shallow(
component = shallow(
<AdvancedTab
ipfsGateway=""
setAutoLockTimeLimit={setAutoLockTimeLimitSpy}
@ -37,12 +37,12 @@ describe('AdvancedTab Component', () => {
});
it('should render correctly when threeBoxFeatureFlag', () => {
expect(root.find('.settings-page__content-row')).toHaveLength(13);
expect(component.find('.settings-page__content-row')).toHaveLength(13);
});
it('should update autoLockTimeLimit', () => {
setAutoLockTimeLimitSpy = sinon.spy();
root = shallow(
component = shallow(
<AdvancedTab
ipfsGateway=""
setAutoLockTimeLimit={setAutoLockTimeLimitSpy}
@ -64,18 +64,18 @@ describe('AdvancedTab Component', () => {
},
);
const autoTimeout = root.find('.settings-page__content-row').at(8);
const autoTimeout = component.find('.settings-page__content-row').at(8);
const textField = autoTimeout.find(TextField);
textField.props().onChange({ target: { value: 1440 } });
expect(root.state().autoLockTimeLimit).toStrictEqual(1440);
expect(component.state().autoLockTimeLimit).toStrictEqual(1440);
autoTimeout.find('.settings-tab__rpc-save-button').simulate('click');
expect(setAutoLockTimeLimitSpy.args[0][0]).toStrictEqual(1440);
});
it('should toggle show test networks', () => {
const testNetworks = root.find('.settings-page__content-row').at(6);
const testNetworks = component.find('.settings-page__content-row').at(6);
const toggleButton = testNetworks.find(ToggleButton);
toggleButton.first().simulate('toggle');
expect(toggleTestnet.calledOnce).toStrictEqual(true);

View File

@ -5,16 +5,16 @@ import DropdownSearchList from '../dropdown-search-list';
import TextField from '../../../components/ui/text-field';
const characterWidthMap = {
'1': 5.86,
'2': 10.05,
'3': 10.45,
'4': 11.1,
'5': 10,
'6': 10.06,
'7': 9.17,
'8': 10.28,
'9': 10.06,
'0': 11.22,
1: 5.86,
2: 10.05,
3: 10.45,
4: 11.1,
5: 10,
6: 10.06,
7: 9.17,
8: 10.28,
9: 10.06,
0: 11.22,
'.': 4.55,
};

View File

@ -486,14 +486,14 @@ describe('custom-gas selectors', () => {
},
];
it('should return renderable data about basic estimates', () => {
tests.forEach((test) => {
tests.forEach(({ expectedResult, mockState, useFastestButtons }) => {
expect(
getRenderableBasicEstimateData(
test.mockState,
mockState,
GAS_LIMITS.SIMPLE,
test.useFastestButtons,
useFastestButtons,
),
).toStrictEqual(test.expectedResult);
).toStrictEqual(expectedResult);
});
});
});
@ -747,10 +747,10 @@ describe('custom-gas selectors', () => {
},
];
it('should return renderable data about basic estimates appropriate for buttons with less info', () => {
tests.forEach((test) => {
tests.forEach(({ expectedResult, mockState }) => {
expect(
getRenderableEstimateDataForSmallButtonsFromGWEI(test.mockState),
).toStrictEqual(test.expectedResult);
getRenderableEstimateDataForSmallButtonsFromGWEI(mockState),
).toStrictEqual(expectedResult);
});
});
});

View File

@ -2681,25 +2681,25 @@
web3 "^0.20.7"
web3-provider-engine "^16.0.3"
"@metamask/eslint-config-jest@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config-jest/-/eslint-config-jest-6.0.0.tgz#9e10cfbca31236afd7be2058be70365084e540d6"
integrity sha512-C0sXmyp5Hnp5IHVYXaW2TJAo/E9UiS192CwyUcw2qU1Ck7lj4z/wHdgROaH5F6rInqBO3afkDaqnArqvoxvO5Q==
"@metamask/eslint-config-jest@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config-jest/-/eslint-config-jest-8.0.0.tgz#1433c2dffbd60239430ea789c71df11e94872a1c"
integrity sha512-m2/crRcaiRO8z6NC04+AudfjgIXvdrUy2oDjecjELa3nmgkJ+cVemCfioREpjaXoXW/soNImZXbgLrA98uQ6ig==
"@metamask/eslint-config-mocha@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config-mocha/-/eslint-config-mocha-6.0.0.tgz#407fc07d4bdfbc79b64989fa9a56a5a671aa4721"
integrity sha512-Hf1JYLWsW9JQWWwlLHltK1l0wqLOjCF0z5V2Dwt0oGUjFdAoVm8fOa2TisrgHNHYuAtyd+ZaIEm/xQce1L2ovg==
"@metamask/eslint-config-mocha@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config-mocha/-/eslint-config-mocha-8.0.0.tgz#522287c45bec87cb6ab051fa47cdfa7f3000c7cf"
integrity sha512-xc82QVnFLoIPAnGr8fs/yOip9B5lOmwJbPOyTj986K32rdKPV45Tj8PCgvAFWBGtLlS6/Bb5ZQTmTZGNmB7IbQ==
"@metamask/eslint-config-nodejs@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config-nodejs/-/eslint-config-nodejs-6.0.0.tgz#df77bb35b91556030f1b23ad4ff51c1caf033339"
integrity sha512-nx7VhJRpJKQrcdDvy2bLCSWqBmWftgqxyG+BUw06XcWQzbmZTn94EXdLlH6zTQxmR4C+m+AOy5ung0NSUwmY3g==
"@metamask/eslint-config-nodejs@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config-nodejs/-/eslint-config-nodejs-8.0.0.tgz#2181f2777a8e66825c2fd9882cb173b5a4d2b689"
integrity sha512-hN49rqgzhqo7WCJuCCD8P3e9ZhwNt6m9+XEKxnj3v1DKw8v6P6BW210LvOfzd6TfpZxN20qqnt5kxZOcN/ZPpA==
"@metamask/eslint-config@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-6.0.0.tgz#ec53e8ab278073e882411ed89705bc7d06b78c81"
integrity sha512-LyakGYGwM8UQOGhwWa+5erAI1hXuiTgf/y7USzOomX6H9KiuY09IAUYnPh7ToPG2sedD2F48UF1bUm8yvCoZOw==
"@metamask/eslint-config@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-8.0.0.tgz#f4e3bcd6b37ec135b5a72902b0526cba2a6b5a4d"
integrity sha512-ZO9B3ohNhjomrufNAkxnDXV46Kut7NKzri7itDxUzHJncNtI1of7ewWh6fKPl/hr6Al6Gd7WgjPdJZGFpzKPQw==
"@metamask/eth-ledger-bridge-keyring@^0.10.0":
version "0.10.0"