Skip to content

Commit

Permalink
Merge branch 'main' into feature/bn2
Browse files Browse the repository at this point in the history
  • Loading branch information
napalmpapalam committed Jul 11, 2023
2 parents af0ff6e + 464abf3 commit 592ad51
Show file tree
Hide file tree
Showing 20 changed files with 897 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package-lock.json
*.log

deprecated
coverage
packages/*/coverage

.eslintcache

Expand Down
6 changes: 2 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [Unreleased]

## [0.3.0-rc.0] - 2023-07-11
## Unreleased
### Added
- `@distributedlab/w3p` Test coverage
- `@distributedlab/tools`
- `BN`
- `percent, addPercent, subPercent, negated` methods
Expand Down
2 changes: 1 addition & 1 deletion packages/w3p/examples/vue-use-provider-composable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
type Chain,
type ChainId,
createProvider,
type CreateProviderOpts,
type CreateProviderOpts, IProvider,
Provider,
type ProviderProxyConstructor,
PROVIDERS,
Expand Down
7 changes: 7 additions & 0 deletions packages/w3p/src/helpers/amount.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { hexToDecimal } from '@/helpers'

test('performs amount unit test', () => {
expect(hexToDecimal(667)).toBe(667)
expect(hexToDecimal('667')).toBe(1639)
expect(hexToDecimal('667ae')).toBe(419758)
})
41 changes: 41 additions & 0 deletions packages/w3p/src/helpers/eth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { DECIMALS } from '@distributedlab/tools'

import { CHAIN_TYPES } from '@/enums'
import { getEthExplorerAddressUrl, getEthExplorerTxUrl } from '@/helpers'

const exampleChain = {
id: 1,
name: 'Example',
rpcUrl: 'https://mainnet.example.io/v3/',
explorerUrl: 'https://example.io',
token: { name: 'Example', symbol: 'ex', decimals: DECIMALS.WEI },
type: CHAIN_TYPES.EVM,
icon: 'https://example.com/image.svg',
}

describe('performs eth helper unit test', () => {
describe('performs get tx url', () => {
test('getEthExplorerTxUrl should return correct value', () => {
expect(
getEthExplorerTxUrl(
exampleChain,
'0x2446f1fd773fbb9f080e674b60c6a033c7ed7427b8b9413cf28a2a4a6da9b56c',
),
).toBe(
'https://example.io/tx/0x2446f1fd773fbb9f080e674b60c6a033c7ed7427b8b9413cf28a2a4a6da9b56c',
)
})
})
describe('performs get address url', () => {
test('getEthExplorerAddressUrl should return correct value', () => {
expect(
getEthExplorerAddressUrl(
exampleChain,
'0xFeebabE6b0418eC13b30aAdF129F5DcDd4f70CeA',
),
).toBe(
'https://example.io/address/0xFeebabE6b0418eC13b30aAdF129F5DcDd4f70CeA',
)
})
})
})
40 changes: 40 additions & 0 deletions packages/w3p/src/helpers/near.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
getNearExplorerAddressUrl,
getNearExplorerTxUrl,
nearToYocto,
yoctoToNear,
} from '@/helpers'

const exampleExplorerUrl = 'https://example.io'

describe('performs near helper unit test', () => {
describe('performs get url', () => {
test('getNearExplorerTxUrl should return correct value', () => {
expect(
getNearExplorerTxUrl(
exampleExplorerUrl,
'EL9cEcoiF1ThH1HXrdE5LBuJKzSe6dRr7tia61fohPrP',
),
).toBe(
'https://example.io/transactions/EL9cEcoiF1ThH1HXrdE5LBuJKzSe6dRr7tia61fohPrP',
)
})
test('getNearExplorerAddressUrl should return correct value', () => {
expect(
getNearExplorerAddressUrl(exampleExplorerUrl, 'example.address'),
).toBe('https://example.io/accounts/example.address')
})
})
describe('performs convert near and yocto', () => {
test('nearToYocto should return correct value', () => {
expect(nearToYocto('1')).toBe('1000000000000000000000000')
expect(nearToYocto('0.123')).toBe('123000000000000000000000')
expect(nearToYocto('999')).toBe('999000000000000000000000000')
})
test('yoctoToNear should return correct value', () => {
expect(yoctoToNear('1')).toBe('0.000000000000000000000001')
expect(yoctoToNear('999000000000000000000000000')).toBe('999')
expect(yoctoToNear('1000000000000000000000000')).toBe('1')
})
})
})
62 changes: 62 additions & 0 deletions packages/w3p/src/helpers/solana.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { CHAIN_TYPES } from '@/enums'
import { getSolExplorerAddressUrl, getSolExplorerTxUrl } from '@/helpers'

const exampleChainDevnet = {
id: 'devnet',
name: 'Example',
rpcUrl: 'https://devnet.example.io/v3/',
explorerUrl: 'https://example.io',
token: { name: 'Example', symbol: 'ex', decimals: 18 },
type: CHAIN_TYPES.Solana,
icon: 'https://example.com/image.svg',
}
const exampleChainMainnet = {
id: 'mainnet',
name: 'Example',
rpcUrl: 'https://mainnet.example.io/v3/',
explorerUrl: 'https://example.io',
token: { name: 'Example', symbol: 'ex', decimals: 18 },
type: CHAIN_TYPES.Solana,
icon: 'https://example.com/image.svg',
}

describe('performs solana helper unit test', () => {
describe('performs get url', () => {
test('getSolExplorerTxUrl should return correct value', () => {
expect(
getSolExplorerTxUrl(
exampleChainDevnet,
'3StNaySNpdoEgJM8ZM8bxgvcZxGsbYb9QAwmczsGePGxW23etvsSCNJPLjYWH68Cdzv9o3a6W5CmQD3Pk8wqCtmj',
),
).toBe(
'https://example.io/tx/3StNaySNpdoEgJM8ZM8bxgvcZxGsbYb9QAwmczsGePGxW23etvsSCNJPLjYWH68Cdzv9o3a6W5CmQD3Pk8wqCtmj?cluster=devnet',
)
})
expect(
getSolExplorerTxUrl(
exampleChainMainnet,
'3StNaySNpdoEgJM8ZM8bxgvcZxGsbYb9QAwmczsGePGxW23etvsSCNJPLjYWH68Cdzv9o3a6W5CmQD3Pk8wqCtmj',
),
).toBe(
'https://example.io/tx/3StNaySNpdoEgJM8ZM8bxgvcZxGsbYb9QAwmczsGePGxW23etvsSCNJPLjYWH68Cdzv9o3a6W5CmQD3Pk8wqCtmj',
)
})
test('getSolExplorerAddressUrl should return correct value', () => {
expect(
getSolExplorerAddressUrl(
exampleChainDevnet,
'E5y776YkgGtKz45KHVD9HohYb3qXNASQUQStQrsLqhkm',
),
).toBe(
'https://example.io/address/E5y776YkgGtKz45KHVD9HohYb3qXNASQUQStQrsLqhkm?cluster=devnet',
)
expect(
getSolExplorerAddressUrl(
exampleChainMainnet,
'E5y776YkgGtKz45KHVD9HohYb3qXNASQUQStQrsLqhkm',
),
).toBe(
'https://example.io/address/E5y776YkgGtKz45KHVD9HohYb3qXNASQUQStQrsLqhkm',
)
})
})
53 changes: 53 additions & 0 deletions packages/w3p/src/provider-detector.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { PROVIDERS } from '@/enums'
import { ProviderDetector } from '@/provider-detector'
import { MetamaskProvider } from '@/providers'
import { clearWindowMock, mockWindow } from '@/tests'

describe('performs provider detector unit test', () => {
describe('performs init', () => {
let providerDetector: ProviderDetector<keyof Record<string, string>>

beforeEach(() => {
providerDetector = new ProviderDetector()
mockWindow({ ethereum: {} })
})

afterEach(clearWindowMock)

test('should initialize the provider detector', async () => {
await providerDetector.init()

expect(providerDetector.isInitiated).toBeTruthy()
expect(providerDetector.isEnabled).toBeTruthy()
})
})
describe('performs get and add providers', () => {
let providerDetector: ProviderDetector<keyof Record<string, string>>

beforeEach(() => {
providerDetector = new ProviderDetector()
})

afterEach(clearWindowMock)

test('should list empty providers', async () => {
expect(providerDetector.providers).toEqual({})
})
test('should add and return list providers', async () => {
mockWindow({ ethereum: { providers: [MetamaskProvider] } })
providerDetector.addProvider({ name: PROVIDERS.Metamask })
providerDetector.addProvider({ name: PROVIDERS.Coinbase })
expect(providerDetector.providers).toEqual({
metamask: { name: PROVIDERS.Metamask },
coinbase: { name: PROVIDERS.Coinbase },
})
})
test('should add and return metamask provider', async () => {
mockWindow({ ethereum: { providers: [MetamaskProvider] } })
providerDetector.addProvider({ name: PROVIDERS.Metamask })
expect(providerDetector.getProvider(PROVIDERS.Metamask)).toEqual({
name: PROVIDERS.Metamask,
})
})
})
})
104 changes: 104 additions & 0 deletions packages/w3p/src/provider.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { PROVIDERS } from '@/enums'
import { MetamaskProvider } from '@/providers'
import { mockWindow } from '@/tests'
import type { ProviderInstance } from '@/types'

import { Provider } from './provider'

describe('performs provider unit test', () => {
mockWindow({
ethereum: {
once: jest.fn(),
on: jest.fn(),
off: jest.fn(),
addListener: jest.fn(),
removeListener: jest.fn(),
removeAllListeners: jest.fn(),
providers: [MetamaskProvider],
selectedAddress: 'testAddress',
request: jest.fn(),
},
})
const providerInstance: ProviderInstance = {
name: PROVIDERS.Metamask,
instance: window.ethereum,
}
afterEach(() => {
jest.restoreAllMocks()
})

describe('performs provider init', () => {
test('should throw an error if no provider instance is injected', async () => {
const provider = new Provider(MetamaskProvider)
await expect(
provider.init({ name: PROVIDERS.Metamask }),
).rejects.toThrowError()
})

test('should initialize the proxy and set the selected provider', async () => {
const mockInit = jest.fn()
jest
.spyOn(MetamaskProvider.prototype, 'init')
.mockImplementation(mockInit)
const provider = new Provider(MetamaskProvider)
await provider.init(providerInstance)
expect(provider.providerType).toBe(PROVIDERS.Metamask)
expect(provider.isConnected).toBe(false)
})
})
describe('performs connect', () => {
test('should throw an error if the proxy is not initialized', async () => {
const provider = new Provider(MetamaskProvider)
await expect(provider.connect()).rejects.toThrow()
})

test('should connect the proxy', async () => {
const mockConnectFn = jest.fn()
const mockInit = jest.fn()
jest
.spyOn(MetamaskProvider.prototype, 'init')
.mockImplementation(mockInit)
const provider = new Provider(MetamaskProvider)
await provider.init(providerInstance)
jest.spyOn(provider, 'connect').mockImplementation(mockConnectFn)
await provider.connect()
expect(mockConnectFn).toHaveBeenCalled()
})
})

describe('performs switchChain', () => {
test('should switch the chain', async () => {
const switchChainFn = jest.fn()
const mockInit = jest.fn()
jest
.spyOn(MetamaskProvider.prototype, 'init')
.mockImplementation(mockInit)
const provider = new Provider(MetamaskProvider)
await provider.init(providerInstance)
jest.spyOn(provider, 'switchChain').mockImplementation(switchChainFn)
await provider.switchChain('1')
expect(switchChainFn).toHaveBeenCalledWith('1')
})
})
describe('performs sign and sent tx', () => {
test('should throw an error if the proxy is not initialized', async () => {
const provider = new Provider(MetamaskProvider)
await expect(provider.signAndSendTx('0x1test')).rejects.toThrow()
})

test('should sign and sent tx', async () => {
const mockSignAndSentTxFn = jest.fn()
const mockInit = jest.fn()
jest
.spyOn(MetamaskProvider.prototype, 'init')
.mockImplementation(mockInit)
const provider = new Provider(MetamaskProvider)
await provider.init(providerInstance)
jest
.spyOn(provider, 'signAndSendTx')
.mockImplementation(mockSignAndSentTxFn)
await provider.signAndSendTx('0x1test')
expect(mockSignAndSentTxFn).toHaveBeenCalled()
})
})
})
Loading

0 comments on commit 592ad51

Please sign in to comment.