Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: move the init call into provider #194

Merged
merged 8 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .fatherrc.base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineConfig } from 'father';
import { defineConfig, type IFatherConfig } from 'father';

export default defineConfig({
const isProd = process.env.NODE_ENV === 'production';
const conf: IFatherConfig = defineConfig({
cjs: {
output: 'dist/lib',
transformer: 'babel',
Expand All @@ -9,4 +10,20 @@ export default defineConfig({
output: 'dist/esm',
transformer: 'babel',
},
extraBabelPlugins: [
...(isProd
? [
// must declare type here to avoid TS complaint due to father typing being flaky
[
'transform-remove-console',
{
// remove .log but kept the rest for debugging
exclude: ['error', 'warn', 'info'],
},
] as NonNullable<IFatherConfig['extraBabelPlugins']>[number],
]
: []),
],
});

export default conf;
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@
</a>
</p>

<!-- | Branch | GitHub Actions | Tests | Coverage |
| --- | --- | --- | --- |
| `release/refactor-3.0.0` | [![coverage](https://github.com/AElfProject/aelf-web-login/actions/workflows/coverage.yml/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions/workflows/coverage.yml) | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/release-refactor-3.0.0-utils-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-base/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) | -->

| package | Tests | Coverage |
| --- | --- | --- |
| @aelf-web-login/utils | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/release-refactor-3.0.0-utils-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-utils/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |
| @aelf-web-login/base | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/release-refactor-3.0.0-base-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-base/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |
| @aelf-web-login/utils | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/master-utils-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-utils/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |
| @aelf-web-login/base | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/master-base-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-base/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |
| @aelf-web-login/react | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/aelf-web-login/feature/badge-json/master-react-test-results.json) | [![Coverage](https://aelfproject.github.io/aelf-web-login/coverage-react/badge.svg)](https://github.com/AElfProject/aelf-web-login/actions) |

# Install

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"@vitest/coverage-v8": "^1.1.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
Expand All @@ -83,7 +84,8 @@
"node": ">=20"
},
"resolutions": {
"@testing-library/dom": "^10.0.0"
"@testing-library/dom": "^10.0.0",
"@babel/core": "^7.0.0"
},
"repository": "https://github.com/AElfProject/aelf-web-login"
}
7 changes: 2 additions & 5 deletions packages/react/coverage/coverage-summary.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
{"total": {"lines":{"total":69,"covered":58,"skipped":0,"pct":84.05},"statements":{"total":73,"covered":61,"skipped":0,"pct":83.56},"functions":{"total":17,"covered":12,"skipped":0,"pct":70.58},"branches":{"total":17,"covered":14,"skipped":0,"pct":82.35},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":"Unknown"}}
,"/Users/aelf/Documents/Projects/aelf/aelf-web-login/packages/react/src/context.tsx": {"lines":{"total":15,"covered":13,"skipped":0,"pct":86.66},"functions":{"total":3,"covered":2,"skipped":0,"pct":66.66},"statements":{"total":16,"covered":14,"skipped":0,"pct":87.5},"branches":{"total":4,"covered":3,"skipped":0,"pct":75}}
,"/Users/aelf/Documents/Projects/aelf/aelf-web-login/packages/react/src/init.ts": {"lines":{"total":20,"covered":18,"skipped":0,"pct":90},"functions":{"total":5,"covered":4,"skipped":0,"pct":80},"statements":{"total":21,"covered":19,"skipped":0,"pct":90.47},"branches":{"total":7,"covered":6,"skipped":0,"pct":85.71}}
,"/Users/aelf/Documents/Projects/aelf/aelf-web-login/packages/react/src/useConnectWallet.tsx": {"lines":{"total":23,"covered":16,"skipped":0,"pct":69.56},"functions":{"total":4,"covered":2,"skipped":0,"pct":50},"statements":{"total":23,"covered":16,"skipped":0,"pct":69.56},"branches":{"total":6,"covered":5,"skipped":0,"pct":83.33}}
,"/Users/aelf/Documents/Projects/aelf/aelf-web-login/packages/react/src/useExternalStore.tsx": {"lines":{"total":11,"covered":11,"skipped":0,"pct":100},"functions":{"total":5,"covered":4,"skipped":0,"pct":80},"statements":{"total":13,"covered":12,"skipped":0,"pct":92.3},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
{"total": {"lines":{"total":17,"covered":16,"skipped":0,"pct":94.11},"statements":{"total":18,"covered":17,"skipped":0,"pct":94.44},"functions":{"total":3,"covered":3,"skipped":0,"pct":100},"branches":{"total":6,"covered":5,"skipped":0,"pct":83.33},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":"Unknown"}}
,"/Users/aelf/Documents/Projects/aelf/aelf-web-login/packages/react/src/context.tsx": {"lines":{"total":17,"covered":16,"skipped":0,"pct":94.11},"functions":{"total":3,"covered":3,"skipped":0,"pct":100},"statements":{"total":18,"covered":17,"skipped":0,"pct":94.44},"branches":{"total":6,"covered":5,"skipped":0,"pct":83.33}}
}
1 change: 1 addition & 0 deletions packages/react/empty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = '';
30 changes: 16 additions & 14 deletions packages/react/jest-report.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="jest tests" tests="7" failures="0" errors="0" time="1.605">
<testsuite name="useConnectWallet" errors="0" failures="0" skipped="0" timestamp="2024-11-20T04:06:56" time="0.55" tests="1">
<testcase classname="useConnectWallet should render hook" name="useConnectWallet should render hook" time="0.006">
<testsuites name="jest tests" tests="8" failures="0" errors="0" time="2.001">
<testsuite name="init" errors="0" failures="0" skipped="0" timestamp="2024-11-21T05:47:44" time="0.861" tests="3">
<testcase classname="init should initialize VConsole if showVconsole is true" name="init should initialize VConsole if showVconsole is true" time="0.154">
</testcase>
</testsuite>
<testsuite name="WebLoginProvider" errors="0" failures="0" skipped="0" timestamp="2024-11-20T04:06:57" time="0.172" tests="2">
<testcase classname="WebLoginProvider should render children with provided bridgeAPI" name="WebLoginProvider should render children with provided bridgeAPI" time="0.012">
<testcase classname="init should not initialize VConsole if showVconsole is false" name="init should not initialize VConsole if showVconsole is false" time="0.001">
</testcase>
<testcase classname="WebLoginProvider should return null if no bridgeAPI is provided" name="WebLoginProvider should return null if no bridgeAPI is provided" time="0.001">
<testcase classname="init should call initBridge with the given options" name="init should call initBridge with the given options" time="0.001">
</testcase>
</testsuite>
<testsuite name="init" errors="0" failures="0" skipped="0" timestamp="2024-11-20T04:06:57" time="0.163" tests="3">
<testcase classname="init should initialize VConsole if showVconsole is true" name="init should initialize VConsole if showVconsole is true" time="0.054">
</testcase>
<testcase classname="init should not initialize VConsole if showVconsole is false" name="init should not initialize VConsole if showVconsole is false" time="0.001">
<testsuite name="useExternalStore" errors="0" failures="0" skipped="0" timestamp="2024-11-21T05:47:44" time="0.929" tests="1">
<testcase classname="useExternalStore should render hook" name="useExternalStore should render hook" time="0.008">
</testcase>
<testcase classname="init should call initBridge with the given options" name="init should call initBridge with the given options" time="0.001">
</testsuite>
<testsuite name="useConnectWallet" errors="0" failures="0" skipped="0" timestamp="2024-11-21T05:47:44" time="0.944" tests="1">
<testcase classname="useConnectWallet should render hook" name="useConnectWallet should render hook" time="0.008">
</testcase>
</testsuite>
<testsuite name="useExternalStore" errors="0" failures="0" skipped="0" timestamp="2024-11-20T04:06:57" time="0.15" tests="1">
<testcase classname="useExternalStore should render hook" name="useExternalStore should render hook" time="0.005">
<testsuite name="WebLoginProvider" errors="0" failures="0" skipped="0" timestamp="2024-11-21T05:47:44" time="1.275" tests="3">
<testcase classname="WebLoginProvider should render children with provided bridgeAPI" name="WebLoginProvider should render children with provided bridgeAPI" time="0.015">
</testcase>
<testcase classname="WebLoginProvider should render children with provided config" name="WebLoginProvider should render children with provided config" time="0.323">
</testcase>
<testcase classname="WebLoginProvider should return null if no bridgeAPI nor config" name="WebLoginProvider should return null if no bridgeAPI nor config" time="0">
</testcase>
</testsuite>
</testsuites>
7 changes: 6 additions & 1 deletion packages/react/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ const config: JestConfigWithTsJest = {
roots: ['<rootDir>'],
modulePaths: ['./', compilerOptions.baseUrl],
moduleDirectories: ['node_modules', 'src'],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>../../' }),
moduleNameMapper: {
...pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>../../' }),
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/empty.js',
'\\.(css|less|scss|sass)$': '<rootDir>/empty.js',
},
preset: 'ts-jest',
};

Expand Down
1 change: 1 addition & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"dev": "father dev",
"build": "father build",
"test": "NODE_OPTIONS='$NODE_OPTIONS --experimental-vm-modules' jest",
"test:dev": "pnpm test -- --watch",
"test:coverage": "pnpm test -- --coverage",
"test:debug": "pnpm test -- --detectOpenHandles"
},
Expand Down
35 changes: 32 additions & 3 deletions packages/react/src/__tests__/context.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import { render, screen } from '@testing-library/react';
import { WebLoginProvider } from '../context';
import config from '../data/config';
import { IBridgeAPI } from '@aelf-web-login/wallet-adapter-bridge';

const mockBridgeAPI = {
const mockBridgeAPI: IBridgeAPI = {
getSignIn: jest.fn((children) => children),
store: {
getState: () => null,
subscribe: () => null,
},
instance: {} as IBridgeAPI['instance'],
mountApp: () => null,
unMountApp: () => null,
};

jest.mock('@aelf-web-login/wallet-adapter-bridge', () => ({
initBridge: jest.fn().mockReturnValue({
getSignIn: jest.fn((children) => children),
}),
}));

jest.mock('@aelf-web-login/wallet-adapter-portkey-aa', () => ({
PortkeyAAWallet: jest.fn(),
}));

describe('WebLoginProvider', () => {
it('should render children with provided bridgeAPI', () => {
render(
Expand All @@ -16,9 +35,19 @@ describe('WebLoginProvider', () => {
expect(screen.getByText('Test Child')).toBeInTheDocument();
});

it('should return null if no bridgeAPI is provided', () => {
it('should render children with provided config', () => {
render(
<WebLoginProvider config={config}>
<div>Test Child</div>
</WebLoginProvider>,
);

expect(screen.getByText('Test Child')).toBeInTheDocument();
});

it('should return null if no bridgeAPI nor config', () => {
const { container } = render(
<WebLoginProvider bridgeAPI={null}>
<WebLoginProvider>
<div>Test Child</div>
</WebLoginProvider>,
);
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/__tests__/init.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// import { initBridge, IConfigProps, IBridgeAPI } from '@aelf-web-login/wallet-adapter-bridge';
import { init } from '../index';

import { initBridge } from '@aelf-web-login/wallet-adapter-bridge';
jest.mock('vconsole');
jest.mock('@aelf-web-login/wallet-adapter-bridge', () => ({
initBridge: jest.fn(),
Expand All @@ -22,7 +22,7 @@ describe('init', () => {

it('should call initBridge with the given options', async () => {
const options = { baseConfig: { showVconsole: false } };
const { initBridge } = await import('@aelf-web-login/wallet-adapter-bridge');
// const { initBridge } = await import('@aelf-web-login/wallet-adapter-bridge');
init(options as any);
expect(initBridge).toHaveBeenCalledWith(options);
});
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/__tests__/useConnectWallet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import useConnectWallet from '../useConnectWallet';
import { WebLoginProvider } from '../context';
import { IBridgeAPI } from '@aelf-web-login/wallet-adapter-bridge';

jest.mock('@aelf-web-login/wallet-adapter-bridge', () => ({
initBridge: jest.fn(),
}));

const mockBridgeAPI: IBridgeAPI = {
getSignIn: jest.fn((children) => children),
store: {
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/__tests__/useExternalStore.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import useExternalStore from '../useExternalStore';
import { WebLoginProvider } from '../context';
import { IBridgeAPI } from '@aelf-web-login/wallet-adapter-bridge';

jest.mock('@aelf-web-login/wallet-adapter-bridge', () => ({
initBridge: jest.fn(),
}));

const mockBridgeAPI: Partial<IBridgeAPI> = {
getSignIn: jest.fn((children) => children),
store: {
Expand Down
32 changes: 23 additions & 9 deletions packages/react/src/context.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IBridgeAPI } from '@aelf-web-login/wallet-adapter-bridge';
import React from 'react';
import { IBridgeAPI, IConfigProps } from '@aelf-web-login/wallet-adapter-bridge';
import React, { useMemo } from 'react';
import init from './init';

const HOOK_ERROR_MESSAGE =
'Must call the provided initialization method`init` method before using hooks.';
Expand All @@ -22,18 +23,31 @@ export function useWebLoginContext(): IBridgeAPI {

export interface IWebLoginProviderProps {
children: React.ReactNode;
bridgeAPI: IBridgeAPI;
/**
* @deprecated use config instead
*/
bridgeAPI?: IBridgeAPI;
config: IConfigProps;
}

export const WebLoginProvider: React.FC<IWebLoginProviderProps> = ({ children, bridgeAPI }) => {
const { getSignIn } = bridgeAPI ?? {
getSignIn: () => null,
};
export const WebLoginProvider: React.FC<IWebLoginProviderProps> = ({
children,
bridgeAPI,
config,
}) => {
const finalBridgeAPI: IBridgeAPI | undefined = useMemo(
() => bridgeAPI || (config ? init(config) : undefined),
[bridgeAPI, config],
);

if (!bridgeAPI) {
if (!finalBridgeAPI) {
return null;
}
const { getSignIn } = finalBridgeAPI;

return (
<WebLoginContext.Provider value={bridgeAPI}>{getSignIn(children)}</WebLoginContext.Provider>
<WebLoginContext.Provider value={finalBridgeAPI}>
{getSignIn(children)}
</WebLoginContext.Provider>
);
};
Loading
Loading