1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 17:33:23 +01:00

Jest config (#10855)

* Setup jest config

* Adjust test for jest.

* Adjust lint config

* Omit swaps ui folder for unit testing

* Omit swaps from test:unit:lax

* Add jest.config.js to script files

* Restore mocks rather than clearing them.

* Update jest config and adjust lint to include subdirs

* Convert view-quote-price-difference test to jest

* Add jest ci and ci coverage scripts. Add jest unit test to general test command

* Add test coverage to ci

* Use --ignore flag

* Fixup

* Add @metamask/eslint-config-jest

* Update .eslintrc.js

Co-authored-by: Mark Stacey <markjstacey@gmail.com>

* Adds jest-coverage/

Co-authored-by: Mark Stacey <markjstacey@gmail.com>
This commit is contained in:
Thomas Huang 2021-04-09 10:20:32 -07:00 committed by GitHub
parent f7f1f28752
commit 253efc6f8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 168 additions and 73 deletions

View File

@ -444,6 +444,9 @@ jobs:
- store_artifacts:
path: coverage
destination: coverage
- store_artifacts:
path: jest-coverage
destination: jest-coverage
- store_artifacts:
path: test-artifacts
destination: test-artifacts
@ -501,11 +504,15 @@ jobs:
- run:
name: test:coverage
command: yarn test:coverage
- run:
name: test:coverage:jest
command: yarn test:coverage:jest
- persist_to_workspace:
root: .
paths:
- .nyc_output
- coverage
- jest-coverage
test-unit-global:
executor: node-browsers
steps:

View File

@ -26,6 +26,7 @@ module.exports = {
'test-*/**',
'docs/**',
'coverage/',
'jest-coverage/',
'development/chromereload.js',
'app/vendor/**',
'test/e2e/send-eth-with-private-key-test/**',
@ -107,11 +108,16 @@ module.exports = {
},
{
files: ['**/*.test.js'],
excludedFiles: ['ui/app/pages/swaps/**/*.test.js'],
extends: ['@metamask/eslint-config-mocha'],
rules: {
'mocha/no-setup-in-describe': 'off',
},
},
{
files: ['ui/app/pages/swaps/**/*.test.js'],
extends: ['@metamask/eslint-config-jest'],
},
{
files: [
'development/**/*.js',
@ -135,6 +141,7 @@ module.exports = {
'test/lib/wait-until-called.js',
'test/env.js',
'test/setup.js',
'jest.config.js',
],
parserOptions: {
sourceType: 'script',

1
.gitignore vendored
View File

@ -29,6 +29,7 @@ app/.DS_Store
storybook-build/
coverage/
jest-coverage/
dist
builds/
builds.zip

6
jest.config.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
restoreMocks: true,
coverageDirectory: 'jest-coverage/',
setupFiles: ['./test/setup.js', './test/env.js'],
testMatch: ['**/ui/app/pages/swaps/**/?(*.)+(test).js'],
};

View File

@ -14,15 +14,17 @@
"benchmark:firefox": "SELENIUM_BROWSER=firefox node test/e2e/benchmark.js",
"build:test": "yarn build test",
"build:test:metrics": "SEGMENT_HOST='http://localhost:9090' SEGMENT_WRITE_KEY='FAKE' SEGMENT_LEGACY_WRITE_KEY='FAKE' yarn build test",
"test": "yarn test:unit && yarn lint",
"test": "yarn lint && yarn test:unit && yarn test:unit:jest",
"dapp": "node development/static-server.js node_modules/@metamask/test-dapp/dist --port 8080",
"dapp-chain": "GANACHE_ARGS='-b 2' concurrently -k -n ganache,dapp -p '[{time}][{name}]' 'yarn ganache:start' 'sleep 5 && yarn dapp'",
"forwarder": "node ./development/static-server.js ./node_modules/@metamask/forwarder/dist/ --port 9010",
"dapp-forwarder": "concurrently -k -n forwarder,dapp -p '[{time}][{name}]' 'yarn forwarder' 'yarn dapp'",
"sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080",
"test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive './{ui,app,shared}/**/*.test.js'",
"test:unit": "mocha --exit --require test/env.js --require test/setup.js --ignore './ui/app/pages/swaps/**/*.test.js' --recursive './{ui,app,shared}/**/*.test.js'",
"test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*.test.js",
"test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --ignore './app/scripts/controllers/permissions/*.test.js' --recursive './{ui,app,shared}/**/*.test.js'",
"test:unit:jest": "jest",
"test:unit:jest:ci": "jest --maxWorkers=2",
"test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --ignore './app/scripts/controllers/permissions/*.test.js' --ignore './ui/app/pages/swaps/**/*.test.js' --recursive './{ui,app,shared}/**/*.test.js'",
"test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive './app/scripts/controllers/permissions/*.test.js'",
"test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive",
"test:e2e:chrome": "SELENIUM_BROWSER=chrome test/e2e/run-all.sh",
@ -30,6 +32,7 @@
"test:e2e:firefox": "SELENIUM_BROWSER=firefox test/e2e/run-all.sh",
"test:e2e:firefox:metrics": "SELENIUM_BROWSER=firefox mocha test/e2e/metrics.spec.js",
"test:coverage": "nyc --silent --check-coverage yarn test:unit:strict && nyc --silent --no-clean yarn test:unit:lax && nyc report --reporter=text --reporter=html",
"test:coverage:jest": "jest --coverage --maxWorkers=2 --collectCoverageFrom=**/ui/app/pages/swaps/**",
"test:coverage:strict": "nyc --check-coverage yarn test:unit:strict",
"test:coverage:path": "nyc --check-coverage yarn test:unit:path",
"ganache:start": "./development/run-ganache.sh",
@ -201,6 +204,7 @@
"@babel/register": "^7.5.5",
"@lavamoat/allow-scripts": "^1.0.4",
"@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/forwarder": "^1.1.0",
@ -233,6 +237,7 @@
"eslint": "^7.23.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.3.4",
"eslint-plugin-mocha": "^8.1.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.3.1",

View File

@ -1,11 +1,6 @@
import { strict as assert } from 'assert';
import proxyquire from 'proxyquire';
import nock from 'nock';
import { MAINNET_CHAIN_ID } from '../../../../shared/constants/network';
import {
TRADES_BASE_PROD_URL,
TOKENS_BASE_PROD_URL,
AGGREGATOR_METADATA_BASE_PROD_URL,
TOP_ASSET_BASE_PROD_URL,
TOKENS,
EXPECTED_TOKENS_RESULT,
MOCK_TRADE_RESPONSE_2,
@ -13,42 +8,24 @@ import {
TOP_ASSETS,
} from './swaps-util-test-constants';
const swapsUtils = proxyquire('./swaps.util.js', {
'../../helpers/utils/fetch-with-cache': {
default: (url, fetchObject) => {
assert.strictEqual(fetchObject.method, 'GET');
if (url.match(TRADES_BASE_PROD_URL)) {
assert.strictEqual(
url,
'https://api.metaswap.codefi.network/trades?destinationToken=0xE41d2489571d322189246DaFA5ebDe1F4699F498&sourceToken=0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4&sourceAmount=2000000000000000000000000000000000000&slippage=3&timeout=10000&walletAddress=0xmockAddress',
);
return Promise.resolve(MOCK_TRADE_RESPONSE_2);
}
if (url.match(TOKENS_BASE_PROD_URL)) {
assert.strictEqual(url, TOKENS_BASE_PROD_URL);
return Promise.resolve(TOKENS);
}
if (url.match(AGGREGATOR_METADATA_BASE_PROD_URL)) {
assert.strictEqual(url, AGGREGATOR_METADATA_BASE_PROD_URL);
return Promise.resolve(AGGREGATOR_METADATA);
}
if (url.match(TOP_ASSET_BASE_PROD_URL)) {
assert.strictEqual(url, TOP_ASSET_BASE_PROD_URL);
return Promise.resolve(TOP_ASSETS);
}
return Promise.resolve();
},
},
});
const {
import {
fetchTradesInfo,
fetchTokens,
fetchAggregatorMetadata,
fetchTopAssets,
} = swapsUtils;
} from './swaps.util';
describe('Swaps Util', function () {
describe('fetchTradesInfo', function () {
jest.mock('../../../lib/storage-helpers.js', () => ({
getStorageItem: jest.fn(),
setStorageItem: jest.fn(),
}));
describe('Swaps Util', () => {
afterEach(() => {
nock.cleanAll();
});
describe('fetchTradesInfo', () => {
const expectedResult1 = {
zeroEx: {
trade: {
@ -90,7 +67,12 @@ describe('Swaps Util', function () {
sourceAmount: '20000000000000000',
},
};
it('should fetch trade info on prod', async function () {
it('should fetch trade info on prod', async () => {
nock('https://api.metaswap.codefi.network')
.get('/trades')
.query(true)
.reply(200, MOCK_TRADE_RESPONSE_2);
const result = await fetchTradesInfo(
{
TOKENS,
@ -106,35 +88,53 @@ describe('Swaps Util', function () {
},
{ chainId: MAINNET_CHAIN_ID },
);
assert.deepStrictEqual(result, expectedResult2);
expect(result).toStrictEqual(expectedResult2);
});
});
describe('fetchTokens', function () {
it('should fetch tokens', async function () {
describe('fetchTokens', () => {
beforeEach(() => {
nock('https://api.metaswap.codefi.network')
.get('/tokens')
.reply(200, TOKENS);
});
it('should fetch tokens', async () => {
const result = await fetchTokens(MAINNET_CHAIN_ID);
assert.deepStrictEqual(result, EXPECTED_TOKENS_RESULT);
expect(result).toStrictEqual(EXPECTED_TOKENS_RESULT);
});
it('should fetch tokens on prod', async function () {
it('should fetch tokens on prod', async () => {
const result = await fetchTokens(MAINNET_CHAIN_ID);
assert.deepStrictEqual(result, EXPECTED_TOKENS_RESULT);
expect(result).toStrictEqual(EXPECTED_TOKENS_RESULT);
});
});
describe('fetchAggregatorMetadata', function () {
it('should fetch aggregator metadata', async function () {
const result = await fetchAggregatorMetadata(MAINNET_CHAIN_ID);
assert.deepStrictEqual(result, AGGREGATOR_METADATA);
describe('fetchAggregatorMetadata', () => {
beforeEach(() => {
nock('https://api.metaswap.codefi.network')
.get('/aggregatorMetadata')
.reply(200, AGGREGATOR_METADATA);
});
it('should fetch aggregator metadata on prod', async function () {
it('should fetch aggregator metadata', async () => {
const result = await fetchAggregatorMetadata(MAINNET_CHAIN_ID);
assert.deepStrictEqual(result, AGGREGATOR_METADATA);
expect(result).toStrictEqual(AGGREGATOR_METADATA);
});
it('should fetch aggregator metadata on prod', async () => {
const result = await fetchAggregatorMetadata(MAINNET_CHAIN_ID);
expect(result).toStrictEqual(AGGREGATOR_METADATA);
});
});
describe('fetchTopAssets', function () {
describe('fetchTopAssets', () => {
beforeEach(() => {
nock('https://api.metaswap.codefi.network')
.get('/topAssets')
.reply(200, TOP_ASSETS);
});
const expectedResult = {
'0x514910771af9ca656af840dff83e8264ecf986ca': {
index: '0',
@ -152,14 +152,14 @@ describe('Swaps Util', function () {
index: '4',
},
};
it('should fetch top assets', async function () {
it('should fetch top assets', async () => {
const result = await fetchTopAssets(MAINNET_CHAIN_ID);
assert.deepStrictEqual(result, expectedResult);
expect(result).toStrictEqual(expectedResult);
});
it('should fetch top assets on prod', async function () {
it('should fetch top assets on prod', async () => {
const result = await fetchTopAssets(MAINNET_CHAIN_ID);
assert.deepStrictEqual(result, expectedResult);
expect(result).toStrictEqual(expectedResult);
});
});
});

View File

@ -1,4 +1,3 @@
import assert from 'assert';
import React from 'react';
import { shallow } from 'enzyme';
import { Provider } from 'react-redux';
@ -6,7 +5,7 @@ import configureMockStore from 'redux-mock-store';
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network';
import ViewQuotePriceDifference from './view-quote-price-difference';
describe('View Price Quote Difference', function () {
describe('View Price Quote Difference', () => {
const t = (key) => `translate ${key}`;
const state = {
@ -98,21 +97,21 @@ describe('View Price Quote Difference', function () {
);
}
afterEach(function () {
afterEach(() => {
component.unmount();
});
it('does not render when there is no quote', function () {
it('does not render when there is no quote', () => {
const props = { ...DEFAULT_PROPS, usedQuote: null };
renderComponent(props);
const wrappingDiv = component.find(
'.view-quote__price-difference-warning-wrapper',
);
assert.strictEqual(wrappingDiv.length, 0);
expect(wrappingDiv).toHaveLength(0);
});
it('does not render when the item is in the low bucket', function () {
it('does not render when the item is in the low bucket', () => {
const props = { ...DEFAULT_PROPS };
props.usedQuote.priceSlippage.bucket = 'low';
@ -120,31 +119,31 @@ describe('View Price Quote Difference', function () {
const wrappingDiv = component.find(
'.view-quote__price-difference-warning-wrapper',
);
assert.strictEqual(wrappingDiv.length, 0);
expect(wrappingDiv).toHaveLength(0);
});
it('displays an error when in medium bucket', function () {
it('displays an error when in medium bucket', () => {
const props = { ...DEFAULT_PROPS };
props.usedQuote.priceSlippage.bucket = 'medium';
renderComponent(props);
assert.strictEqual(component.html().includes('medium'), true);
expect(component.html()).toContain('medium');
});
it('displays an error when in high bucket', function () {
it('displays an error when in high bucket', () => {
const props = { ...DEFAULT_PROPS };
props.usedQuote.priceSlippage.bucket = 'high';
renderComponent(props);
assert.strictEqual(component.html().includes('high'), true);
expect(component.html()).toContain('high');
});
it('displays a fiat error when calculationError is present', function () {
it('displays a fiat error when calculationError is present', () => {
const props = { ...DEFAULT_PROPS, priceSlippageUnknownFiatValue: true };
props.usedQuote.priceSlippage.calculationError =
'Could not determine price.';
renderComponent(props);
assert.strictEqual(component.html().includes('fiat-error'), true);
expect(component.html()).toContain('fiat-error');
});
});

View File

@ -2689,6 +2689,11 @@
web3 "^0.20.7"
web3-provider-engine "^16.0.1"
"@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-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"
@ -3708,6 +3713,11 @@
dependencies:
"@types/istanbul-lib-report" "*"
"@types/json-schema@^7.0.3":
version "7.0.7"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
version "7.0.6"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
@ -3959,6 +3969,52 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/experimental-utils@^4.0.1":
version "4.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.21.0.tgz#0b0bb7c15d379140a660c003bdbafa71ae9134b6"
integrity sha512-cEbgosW/tUFvKmkg3cU7LBoZhvUs+ZPVM9alb25XvR0dal4qHL3SiUqHNrzoWSxaXA9gsifrYrS1xdDV6w/gIA==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/scope-manager" "4.21.0"
"@typescript-eslint/types" "4.21.0"
"@typescript-eslint/typescript-estree" "4.21.0"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
"@typescript-eslint/scope-manager@4.21.0":
version "4.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.21.0.tgz#c81b661c4b8af1ec0c010d847a8f9ab76ab95b4d"
integrity sha512-kfOjF0w1Ix7+a5T1knOw00f7uAP9Gx44+OEsNQi0PvvTPLYeXJlsCJ4tYnDj5PQEYfpcgOH5yBlw7K+UEI9Agw==
dependencies:
"@typescript-eslint/types" "4.21.0"
"@typescript-eslint/visitor-keys" "4.21.0"
"@typescript-eslint/types@4.21.0":
version "4.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.21.0.tgz#abdc3463bda5d31156984fa5bc316789c960edef"
integrity sha512-+OQaupjGVVc8iXbt6M1oZMwyKQNehAfLYJJ3SdvnofK2qcjfor9pEM62rVjBknhowTkh+2HF+/KdRAc/wGBN2w==
"@typescript-eslint/typescript-estree@4.21.0":
version "4.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.21.0.tgz#3817bd91857beeaeff90f69f1f112ea58d350b0a"
integrity sha512-ZD3M7yLaVGVYLw4nkkoGKumb7Rog7QID9YOWobFDMQKNl+vPxqVIW/uDk+MDeGc+OHcoG2nJ2HphwiPNajKw3w==
dependencies:
"@typescript-eslint/types" "4.21.0"
"@typescript-eslint/visitor-keys" "4.21.0"
debug "^4.1.1"
globby "^11.0.1"
is-glob "^4.0.1"
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/visitor-keys@4.21.0":
version "4.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.21.0.tgz#990a9acdc124331f5863c2cf21c88ba65233cd8d"
integrity sha512-dH22dROWGi5Z6p+Igc8bLVLmwy7vEe8r+8c+raPQU0LxgogPUrRAtRGtvBWmlr9waTu3n+QLt/qrS/hWzk1x5w==
dependencies:
"@typescript-eslint/types" "4.21.0"
eslint-visitor-keys "^2.0.0"
"@webassemblyjs/ast@1.9.0":
version "1.9.0"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
@ -9957,6 +10013,13 @@ eslint-plugin-import@^2.22.1:
resolve "^1.17.0"
tsconfig-paths "^3.9.0"
eslint-plugin-jest@^24.3.4:
version "24.3.4"
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.3.4.tgz#6d90c3554de0302e879603dd6405474c98849f19"
integrity sha512-3n5oY1+fictanuFkTWPwSlehugBTAgwLnYLFsCllzE3Pl1BwywHl5fL0HFxmMjoQY8xhUDk8uAWc3S4JOHGh3A==
dependencies:
"@typescript-eslint/experimental-utils" "^4.0.1"
eslint-plugin-mocha@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-8.1.0.tgz#b9aebbede46a808e46e622c8fd99d2a2f353e725"
@ -10027,7 +10090,7 @@ eslint-scope@^4.0.3:
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-scope@^5.1.0, eslint-scope@^5.1.1:
eslint-scope@^5.0.0, eslint-scope@^5.1.0, eslint-scope@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
@ -25434,7 +25497,7 @@ tsconfig-paths@^3.9.0:
minimist "^1.2.0"
strip-bom "^3.0.0"
tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3:
tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@ -25449,6 +25512,13 @@ tsscmp@1.0.6:
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==
tsutils@^3.17.1:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
dependencies:
tslib "^1.8.1"
ttest@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ttest/-/ttest-2.1.1.tgz#ee0c9118fff6580a5c8d6cfe69845219e075277f"