Add more unit tests to utils
This commit is contained in:
parent
3a2566b4e7
commit
1e1a049990
@ -21,11 +21,6 @@ export const COMMON_BASES = {
|
|||||||
[ChainId.KOVAN]: [WETH[ChainId.KOVAN]]
|
[ChainId.KOVAN]: [WETH[ChainId.KOVAN]]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SUPPORTED_THEMES = {
|
|
||||||
DARK: 'DARK',
|
|
||||||
LIGHT: 'LIGHT'
|
|
||||||
}
|
|
||||||
|
|
||||||
const MAINNET_WALLETS = {
|
const MAINNET_WALLETS = {
|
||||||
INJECTED: {
|
INJECTED: {
|
||||||
connector: injected,
|
connector: injected,
|
||||||
|
@ -8,8 +8,7 @@ import styled, {
|
|||||||
} from 'styled-components'
|
} from 'styled-components'
|
||||||
import { AppDispatch, AppState } from '../state'
|
import { AppDispatch, AppState } from '../state'
|
||||||
import { updateUserDarkMode } from '../state/user/actions'
|
import { updateUserDarkMode } from '../state/user/actions'
|
||||||
import { getQueryParam, checkSupportedTheme } from '../utils'
|
import { getQueryParam } from '../utils'
|
||||||
import { SUPPORTED_THEMES } from '../constants'
|
|
||||||
import { useIsDarkMode } from '../state/user/hooks'
|
import { useIsDarkMode } from '../state/user/hooks'
|
||||||
import { Text, TextProps } from 'rebass'
|
import { Text, TextProps } from 'rebass'
|
||||||
import { Colors } from './styled'
|
import { Colors } from './styled'
|
||||||
@ -122,11 +121,11 @@ export default function ThemeProvider({ children }: { children: React.ReactNode
|
|||||||
const userDarkMode = useSelector<AppState, boolean | null>(state => state.user.userDarkMode)
|
const userDarkMode = useSelector<AppState, boolean | null>(state => state.user.userDarkMode)
|
||||||
const darkMode = useIsDarkMode()
|
const darkMode = useIsDarkMode()
|
||||||
|
|
||||||
const themeURL = checkSupportedTheme(getQueryParam(window.location, 'theme'))
|
const themeURL = getQueryParam(window.location, 'theme')
|
||||||
const urlContainsDarkMode: boolean | null = themeURL
|
const urlContainsDarkMode: boolean | null = themeURL
|
||||||
? themeURL.toUpperCase() === SUPPORTED_THEMES.DARK
|
? themeURL.toUpperCase() === 'DARK'
|
||||||
? true
|
? true
|
||||||
: themeURL.toUpperCase() === SUPPORTED_THEMES.LIGHT
|
: themeURL.toUpperCase() === 'LIGHT'
|
||||||
? false
|
? false
|
||||||
: null
|
: null
|
||||||
: null
|
: null
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
|
import { BigNumber } from '@ethersproject/bignumber'
|
||||||
import { AddressZero } from '@ethersproject/constants'
|
import { AddressZero } from '@ethersproject/constants'
|
||||||
import { TokenAmount, Token, ChainId } from '@uniswap/sdk'
|
import { TokenAmount, Token, ChainId, Percent, JSBI } from '@uniswap/sdk'
|
||||||
|
|
||||||
import { getEtherscanLink, calculateSlippageAmount } from '.'
|
import {
|
||||||
|
getEtherscanLink,
|
||||||
|
calculateSlippageAmount,
|
||||||
|
isAddress,
|
||||||
|
shortenAddress,
|
||||||
|
calculateGasMargin,
|
||||||
|
basisPointsToPercent
|
||||||
|
} from '.'
|
||||||
|
|
||||||
describe('utils', () => {
|
describe('utils', () => {
|
||||||
describe('#getEtherscanLink', () => {
|
describe('#getEtherscanLink', () => {
|
||||||
@ -11,6 +19,15 @@ describe('utils', () => {
|
|||||||
it('correct for address', () => {
|
it('correct for address', () => {
|
||||||
expect(getEtherscanLink(1, 'abc', 'address')).toEqual('https://etherscan.io/address/abc')
|
expect(getEtherscanLink(1, 'abc', 'address')).toEqual('https://etherscan.io/address/abc')
|
||||||
})
|
})
|
||||||
|
it('unrecognized chain id defaults to mainnet', () => {
|
||||||
|
expect(getEtherscanLink(2, 'abc', 'address')).toEqual('https://etherscan.io/address/abc')
|
||||||
|
})
|
||||||
|
it('ropsten', () => {
|
||||||
|
expect(getEtherscanLink(3, 'abc', 'address')).toEqual('https://ropsten.etherscan.io/address/abc')
|
||||||
|
})
|
||||||
|
it('enum', () => {
|
||||||
|
expect(getEtherscanLink(ChainId.RINKEBY, 'abc', 'address')).toEqual('https://rinkeby.etherscan.io/address/abc')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#calculateSlippageAmount', () => {
|
describe('#calculateSlippageAmount', () => {
|
||||||
@ -24,4 +41,59 @@ describe('utils', () => {
|
|||||||
expect(() => calculateSlippageAmount(tokenAmount, 10001)).toThrow()
|
expect(() => calculateSlippageAmount(tokenAmount, 10001)).toThrow()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('#isAddress', () => {
|
||||||
|
it('returns false if not', () => {
|
||||||
|
expect(isAddress('')).toBe(false)
|
||||||
|
expect(isAddress('0x0000')).toBe(false)
|
||||||
|
expect(isAddress(1)).toBe(false)
|
||||||
|
expect(isAddress({})).toBe(false)
|
||||||
|
expect(isAddress(undefined)).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns the checksummed address', () => {
|
||||||
|
expect(isAddress('0xf164fc0ec4e93095b804a4795bbe1e041497b92a')).toBe('0xf164fC0Ec4E93095b804a4795bBe1e041497b92a')
|
||||||
|
expect(isAddress('0xf164fC0Ec4E93095b804a4795bBe1e041497b92a')).toBe('0xf164fC0Ec4E93095b804a4795bBe1e041497b92a')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('succeeds even without prefix', () => {
|
||||||
|
expect(isAddress('f164fc0ec4e93095b804a4795bbe1e041497b92a')).toBe('0xf164fC0Ec4E93095b804a4795bBe1e041497b92a')
|
||||||
|
})
|
||||||
|
it('fails if too long', () => {
|
||||||
|
expect(isAddress('f164fc0ec4e93095b804a4795bbe1e041497b92a0')).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#shortenAddress', () => {
|
||||||
|
it('throws on invalid address', () => {
|
||||||
|
expect(() => shortenAddress('abc')).toThrow("Invalid 'address'")
|
||||||
|
})
|
||||||
|
|
||||||
|
it('truncates middle characters', () => {
|
||||||
|
expect(shortenAddress('0xf164fc0ec4e93095b804a4795bbe1e041497b92a')).toBe('0xf164...b92a')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('truncates middle characters even without prefix', () => {
|
||||||
|
expect(shortenAddress('f164fc0ec4e93095b804a4795bbe1e041497b92a')).toBe('0xf164...b92a')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders checksummed address', () => {
|
||||||
|
expect(shortenAddress('0x2E1b342132A67Ea578e4E3B814bae2107dc254CC'.toLowerCase())).toBe('0x2E1b...54CC')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#calculateGasMargin', () => {
|
||||||
|
it('adds 10%', () => {
|
||||||
|
expect(calculateGasMargin(BigNumber.from(1000)).toString()).toEqual('1100')
|
||||||
|
expect(calculateGasMargin(BigNumber.from(50)).toString()).toEqual('55')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#basisPointsToPercent', () => {
|
||||||
|
it('converts basis points numbers to percents', () => {
|
||||||
|
expect(basisPointsToPercent(100).equalTo(new Percent(JSBI.BigInt(1), JSBI.BigInt(100)))).toBeTruthy()
|
||||||
|
expect(basisPointsToPercent(500).equalTo(new Percent(JSBI.BigInt(5), JSBI.BigInt(100)))).toBeTruthy()
|
||||||
|
expect(basisPointsToPercent(50).equalTo(new Percent(JSBI.BigInt(5), JSBI.BigInt(1000)))).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -7,15 +7,16 @@ import { BigNumber } from '@ethersproject/bignumber'
|
|||||||
|
|
||||||
import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json'
|
import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json'
|
||||||
import { abi as IUniswapV2Router01ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router01.json'
|
import { abi as IUniswapV2Router01ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router01.json'
|
||||||
import { ROUTER_ADDRESS, SUPPORTED_THEMES } from '../constants'
|
import { ROUTER_ADDRESS } from '../constants'
|
||||||
|
|
||||||
import ERC20_ABI from '../constants/abis/erc20.json'
|
import ERC20_ABI from '../constants/abis/erc20.json'
|
||||||
import ERC20_BYTES32_ABI from '../constants/abis/erc20_bytes32.json'
|
import ERC20_BYTES32_ABI from '../constants/abis/erc20_bytes32.json'
|
||||||
import { JSBI, Percent, TokenAmount } from '@uniswap/sdk'
|
import { ChainId, JSBI, Percent, TokenAmount } from '@uniswap/sdk'
|
||||||
|
|
||||||
|
// returns the checksummed address if the address is valid, otherwise returns false
|
||||||
export function isAddress(value: any): string | false {
|
export function isAddress(value: any): string | false {
|
||||||
try {
|
try {
|
||||||
return getAddress(value.toLowerCase())
|
return getAddress(value)
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -26,7 +27,7 @@ export enum ERROR_CODES {
|
|||||||
TOKEN_DECIMALS = 2
|
TOKEN_DECIMALS = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
const ETHERSCAN_PREFIXES = {
|
const ETHERSCAN_PREFIXES: { [chainId in ChainId]: string } = {
|
||||||
1: '',
|
1: '',
|
||||||
3: 'ropsten.',
|
3: 'ropsten.',
|
||||||
4: 'rinkeby.',
|
4: 'rinkeby.',
|
||||||
@ -34,12 +35,8 @@ const ETHERSCAN_PREFIXES = {
|
|||||||
42: 'kovan.'
|
42: 'kovan.'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEtherscanLink(
|
export function getEtherscanLink(chainId: ChainId, data: string, type: 'transaction' | 'address'): string {
|
||||||
networkId: 1 | 3 | 4 | 5 | 42 | string | number,
|
const prefix = `https://${ETHERSCAN_PREFIXES[chainId] || ETHERSCAN_PREFIXES[1]}etherscan.io`
|
||||||
data: string,
|
|
||||||
type: 'transaction' | 'address'
|
|
||||||
) {
|
|
||||||
const prefix = `https://${ETHERSCAN_PREFIXES[networkId] || ETHERSCAN_PREFIXES[1]}etherscan.io`
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'transaction': {
|
case 'transaction': {
|
||||||
@ -89,22 +86,18 @@ export function getAllQueryParams(): QueryParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkSupportedTheme(themeName: string) {
|
// shorten the checksummed version of the input address to have 0x + 4 characters at start and end
|
||||||
if (themeName && themeName.toUpperCase() in SUPPORTED_THEMES) {
|
|
||||||
return themeName.toUpperCase()
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
export function shortenAddress(address: string, chars = 4): string {
|
export function shortenAddress(address: string, chars = 4): string {
|
||||||
if (!isAddress(address)) {
|
const parsed = isAddress(address)
|
||||||
|
if (!parsed) {
|
||||||
throw Error(`Invalid 'address' parameter '${address}'.`)
|
throw Error(`Invalid 'address' parameter '${address}'.`)
|
||||||
}
|
}
|
||||||
return `${address.substring(0, chars + 2)}...${address.substring(42 - chars)}`
|
return `${parsed.substring(0, chars + 2)}...${parsed.substring(42 - chars)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add 10%
|
||||||
export function calculateGasMargin(value: BigNumber): BigNumber {
|
export function calculateGasMargin(value: BigNumber): BigNumber {
|
||||||
return value.mul(BigNumber.from(10000).add(BigNumber.from(1000))).div(BigNumber.from(10000)) // add 10%
|
return value.mul(BigNumber.from(10000).add(BigNumber.from(1000))).div(BigNumber.from(10000))
|
||||||
}
|
}
|
||||||
|
|
||||||
// converts a basis points value to a sdk percent
|
// converts a basis points value to a sdk percent
|
||||||
|
@ -7205,7 +7205,7 @@ escape-html@~1.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||||
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
|
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
|
||||||
|
|
||||||
escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0:
|
escape-string-regexp@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
|
||||||
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
||||||
|
Loading…
Reference in New Issue
Block a user