@agions/taroviz 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +318 -53
  2. package/dist/index.esm.js +67955 -3318
  3. package/package.json +102 -20
  4. package/src/__tests__/integration.test.tsx +168 -0
  5. package/src/adapters/__tests__/index.test.ts +91 -0
  6. package/src/adapters/h5/__tests__/index.test.ts +156 -0
  7. package/src/adapters/h5/index.ts +301 -0
  8. package/src/adapters/harmony/index.ts +274 -0
  9. package/src/adapters/index.ts +234 -0
  10. package/src/adapters/swan/index.ts +274 -0
  11. package/src/adapters/tt/index.ts +274 -0
  12. package/src/adapters/types.ts +162 -0
  13. package/src/adapters/weapp/index.ts +237 -0
  14. package/src/charts/bar/__tests__/index.test.tsx +113 -0
  15. package/src/charts/bar/index.tsx +27 -0
  16. package/src/charts/common/BaseChartWrapper.tsx +136 -0
  17. package/src/charts/funnel/index.tsx +33 -0
  18. package/src/charts/gauge/index.tsx +33 -0
  19. package/src/charts/heatmap/index.tsx +33 -0
  20. package/src/charts/index.ts +21 -0
  21. package/src/charts/line/__tests__/index.test.tsx +107 -0
  22. package/src/charts/line/index.tsx +27 -0
  23. package/src/charts/pie/__tests__/index.test.tsx +112 -0
  24. package/src/charts/pie/index.tsx +22 -0
  25. package/src/charts/radar/index.tsx +33 -0
  26. package/src/charts/scatter/index.tsx +33 -0
  27. package/src/charts/types.ts +146 -0
  28. package/src/charts/utils.ts +56 -0
  29. package/src/core/__tests__/platform.test.ts +48 -0
  30. package/src/core/animation/AnimationManager.ts +391 -0
  31. package/src/core/animation/index.ts +20 -0
  32. package/src/core/animation/types.ts +248 -0
  33. package/src/core/components/BaseChart.tsx +1319 -0
  34. package/src/core/index.ts +19 -0
  35. package/src/core/types/chart.ts +66 -0
  36. package/src/core/types/common.ts +224 -0
  37. package/src/core/types/index.ts +281 -0
  38. package/src/core/types/platform.ts +325 -0
  39. package/src/core/utils/__tests__/common.test.ts +52 -0
  40. package/src/core/utils/__tests__/environment.test.ts +94 -0
  41. package/src/core/utils/__tests__/i18n.test.ts +247 -0
  42. package/src/core/utils/__tests__/index.test.ts +219 -0
  43. package/src/core/utils/__tests__/uuid.test.ts +78 -0
  44. package/src/core/utils/chartInstances.ts +69 -0
  45. package/src/core/utils/codeGenerator/CodeGenerator.ts +655 -0
  46. package/src/core/utils/codeGenerator/index.ts +13 -0
  47. package/src/core/utils/codeGenerator/types.ts +200 -0
  48. package/src/core/utils/common.ts +58 -0
  49. package/src/core/utils/configGenerator/ConfigGenerator.ts +583 -0
  50. package/src/core/utils/configGenerator/index.ts +13 -0
  51. package/src/core/utils/configGenerator/types.ts +445 -0
  52. package/src/core/utils/debug/DebugPanel.tsx +637 -0
  53. package/src/core/utils/debug/debugger.ts +322 -0
  54. package/src/core/utils/debug/index.ts +21 -0
  55. package/src/core/utils/debug/types.ts +142 -0
  56. package/src/core/utils/i18n.ts +452 -0
  57. package/src/core/utils/index.ts +162 -0
  58. package/src/core/utils/performance/PerformanceAnalyzer.ts +586 -0
  59. package/src/core/utils/performance/index.ts +13 -0
  60. package/src/core/utils/performance/types.ts +180 -0
  61. package/src/core/utils/uuid.ts +30 -0
  62. package/src/editor/ThemeEditor.tsx +449 -0
  63. package/src/editor/index.ts +10 -0
  64. package/src/hooks/__tests__/index.test.tsx +333 -0
  65. package/src/hooks/index.ts +214 -0
  66. package/src/index.ts +75 -0
  67. package/src/main.tsx +247 -0
  68. package/src/react-dom.d.ts +7 -0
  69. package/src/themes/__tests__/index.test.ts +91 -0
  70. package/src/themes/index.ts +465 -0
  71. package/dist/index.esm.js.map +0 -1
  72. package/dist/index.js +0 -4012
  73. package/dist/index.js.map +0 -1
package/package.json CHANGED
@@ -1,36 +1,118 @@
1
1
  {
2
2
  "name": "@agions/taroviz",
3
- "version": "1.1.0",
4
- "description": "TaroViz 是一个基于 Taro 和 ECharts 的图表组件库,支持多端小程序和 H5",
3
+ "version": "1.2.0",
4
+ "description": "基于 Taro 和 ECharts 的多端图表组件库",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
7
7
  "types": "dist/index.d.ts",
8
- "sideEffects": false,
9
8
  "files": [
10
9
  "dist",
11
- "README.md"
10
+ "src",
11
+ "README.md",
12
+ "LICENSE"
12
13
  ],
13
14
  "scripts": {
14
- "dev": "webpack --mode=development --watch",
15
- "build": "npx webpack --mode=production",
16
- "clean": "rimraf dist"
15
+ "dev": "webpack serve --mode development",
16
+ "build": "webpack --mode production",
17
+ "clean": "rimraf dist",
18
+ "test": "jest",
19
+ "cypress:open": "cypress open",
20
+ "cypress:run": "cypress run",
21
+ "cypress:component": "cypress open --component",
22
+ "test:e2e": "cypress run --e2e",
23
+ "lint": "eslint src --ext .ts,.tsx",
24
+ "type-check": "tsc --noEmit",
25
+ "prepare": "husky install",
26
+ "docs:api": "node scripts/update-docs.js generate",
27
+ "docs:html": "node scripts/update-docs.js html",
28
+ "docs:build": "node scripts/update-docs.js all",
29
+ "docs:serve": "node scripts/update-docs.js serve",
30
+ "docs:update": "node scripts/update-docs.js",
31
+ "docs:fix": "node scripts/doc-fix.js",
32
+ "deps:update": "node scripts/update-deps.js"
17
33
  },
18
- "publishConfig": {
19
- "access": "public"
34
+ "devDependencies": {
35
+ "@babel/plugin-proposal-decorators": "^7.25.9",
36
+ "@babel/plugin-transform-runtime": "^7.28.5",
37
+ "@babel/preset-env": "^7.26.9",
38
+ "@babel/preset-react": "^7.26.3",
39
+ "@babel/preset-typescript": "^7.27.0",
40
+ "@testing-library/cypress": "^10.1.0",
41
+ "@testing-library/dom": "^10.4.1",
42
+ "@testing-library/jest-dom": "^6.9.1",
43
+ "@testing-library/react": "^16.3.0",
44
+ "@types/jest": "^29.5.12",
45
+ "@types/node": "^20.11.24",
46
+ "@types/react": "^18.2.61",
47
+ "@types/react-dom": "^18.3.7",
48
+ "@types/testing-library__jest-dom": "^5.14.9",
49
+ "@typescript-eslint/eslint-plugin": "^7.1.0",
50
+ "@typescript-eslint/parser": "^7.1.0",
51
+ "babel-loader": "^10.0.0",
52
+ "clean-webpack-plugin": "^4.0.0",
53
+ "core-js": "3.41.0",
54
+ "css-loader": "^7.1.2",
55
+ "cypress": "^15.7.0",
56
+ "eslint": "^8.57.0",
57
+ "eslint-config-prettier": "^9.1.0",
58
+ "eslint-import-resolver-typescript": "^4.3.2",
59
+ "eslint-plugin-import": "^2.31.0",
60
+ "eslint-plugin-prettier": "^5.1.3",
61
+ "eslint-plugin-react": "^7.33.2",
62
+ "eslint-plugin-react-hooks": "^4.6.0",
63
+ "fork-ts-checker-webpack-plugin": "^9.1.0",
64
+ "glob": "^10.3.10",
65
+ "husky": "^9.0.11",
66
+ "jest": "^29.7.0",
67
+ "jest-environment-jsdom": "^30.2.0",
68
+ "lint-staged": "^15.2.2",
69
+ "marked": "^12.0.2",
70
+ "mini-css-extract-plugin": "^2.9.2",
71
+ "prettier": "^3.2.5",
72
+ "react-dom": "^18.3.1",
73
+ "rimraf": "^5.0.5",
74
+ "sass": "^1.86.3",
75
+ "sass-loader": "^16.0.5",
76
+ "terser-webpack-plugin": "^5.3.14",
77
+ "ts-jest": "^29.1.2",
78
+ "ts-loader": "^9.5.2",
79
+ "typedoc": "^0.28.2",
80
+ "typedoc-plugin-markdown": "^3.17.1",
81
+ "typescript": "^5.3.3",
82
+ "webpack": "^5.90.3",
83
+ "webpack-bundle-analyzer": "^4.10.2",
84
+ "webpack-cli": "^5.1.4",
85
+ "webpack-dev-server": "^5.0.4",
86
+ "whatwg-fetch": "^3.6.20"
20
87
  },
21
88
  "dependencies": {
22
- "@agions/taroviz-adapters": "1.1.0",
23
- "@agions/taroviz-charts": "1.1.0",
24
- "@agions/taroviz-core": "1.1.0",
25
- "@agions/taroviz-data": "1.1.0",
26
- "@agions/taroviz-hooks": "1.1.0",
27
- "@agions/taroviz-themes": "1.1.0"
89
+ "@babel/runtime": "^7.28.4",
90
+ "echarts": "^5.4.3",
91
+ "react": "^18.2.0"
28
92
  },
29
93
  "peerDependencies": {
30
- "@tarojs/components": ">=3.4.0",
31
- "@tarojs/taro": ">=3.4.0",
32
- "echarts": ">=5.4.0",
33
- "react": ">=16.13.0"
94
+ "@tarojs/components": "^3.6.0",
95
+ "@tarojs/runtime": "^3.6.0",
96
+ "@tarojs/taro": "^3.6.0"
34
97
  },
35
- "gitHead": "448ea59888a6b5731ffb6eac4478d088de799fed"
98
+ "engines": {
99
+ "node": ">=16.0.0"
100
+ },
101
+ "keywords": [
102
+ "taro",
103
+ "echarts",
104
+ "chart",
105
+ "component",
106
+ "multi-platform"
107
+ ],
108
+ "author": "TaroViz Team",
109
+ "license": "MIT",
110
+ "repository": {
111
+ "type": "git",
112
+ "url": "https://github.com/agions/taroviz.git"
113
+ },
114
+ "homepage": "https://agions.github.io/taroviz/",
115
+ "bugs": {
116
+ "url": "https://github.com/agions/taroviz/issues"
117
+ }
36
118
  }
@@ -0,0 +1,168 @@
1
+ import { render } from '@testing-library/react';
2
+ import React from 'react';
3
+
4
+ import { LineChart } from '../charts';
5
+
6
+ // Mock ECharts and adapters
7
+ jest.mock('echarts/core', () => ({
8
+ use: jest.fn(),
9
+ init: jest.fn(() => ({
10
+ setOption: jest.fn(),
11
+ showLoading: jest.fn(),
12
+ hideLoading: jest.fn(),
13
+ on: jest.fn(),
14
+ off: jest.fn(),
15
+ dispose: jest.fn(),
16
+ resize: jest.fn(),
17
+ })),
18
+ getInstanceByDom: jest.fn(),
19
+ }));
20
+
21
+ // Mock specific ECharts chart imports
22
+ jest.mock('echarts/charts', () => ({
23
+ LineChart: jest.fn(),
24
+ BarChart: jest.fn(),
25
+ PieChart: jest.fn(),
26
+ }));
27
+
28
+ jest.mock('echarts/components', () => ({
29
+ GridComponent: jest.fn(),
30
+ TooltipComponent: jest.fn(),
31
+ TitleComponent: jest.fn(),
32
+ LegendComponent: jest.fn(),
33
+ }));
34
+
35
+ jest.mock('../adapters', () => ({
36
+ getAdapter: jest.fn(() => ({
37
+ init: jest.fn(),
38
+ setOption: jest.fn(),
39
+ resize: jest.fn(),
40
+ dispose: jest.fn(),
41
+ on: jest.fn(),
42
+ off: jest.fn(),
43
+ showLoading: jest.fn(),
44
+ hideLoading: jest.fn(),
45
+ })),
46
+ }));
47
+
48
+ jest.mock('../charts/common/BaseChartWrapper', () => ({
49
+ __esModule: true,
50
+ default: (props: any) => (
51
+ <div
52
+ data-testid="base-chart-wrapper"
53
+ className={`taroviz-${props.chartType}`}
54
+ style={{ width: props.width, height: props.height }}
55
+ >
56
+ <div data-testid="chart-option">{JSON.stringify(props.option)}</div>
57
+ <div data-testid="chart-loading">{props.loading ? 'loading' : 'not-loading'}</div>
58
+ </div>
59
+ ),
60
+ }));
61
+
62
+ describe('Integration Tests', () => {
63
+ describe('Chart Rendering Flow', () => {
64
+ it('should render a complete chart with all components', () => {
65
+ const mockOption = {
66
+ xAxis: { type: 'category' as const, data: ['Mon', 'Tue', 'Wed'] },
67
+ yAxis: { type: 'value' as const },
68
+ series: [{ data: [120, 200, 150], type: 'line' as const }],
69
+ };
70
+
71
+ const { getByTestId } = render(
72
+ <LineChart option={mockOption} width="500px" height="300px" loading={false} />
73
+ );
74
+
75
+ const chartWrapper = getByTestId('base-chart-wrapper');
76
+ const chartOption = getByTestId('chart-option');
77
+ const chartLoading = getByTestId('chart-loading');
78
+
79
+ expect(chartWrapper).toBeInTheDocument();
80
+ expect(chartWrapper).toHaveClass('taroviz-line-chart');
81
+ expect(chartOption).toHaveTextContent(JSON.stringify(mockOption));
82
+ expect(chartLoading).toHaveTextContent('not-loading');
83
+ });
84
+
85
+ it('should handle chart option updates', () => {
86
+ const initialOption = {
87
+ xAxis: { type: 'category' as const, data: ['Mon', 'Tue', 'Wed'] },
88
+ yAxis: { type: 'value' as const },
89
+ series: [{ data: [120, 200, 150], type: 'line' as const }],
90
+ };
91
+
92
+ const updatedOption = {
93
+ xAxis: { type: 'category' as const, data: ['Mon', 'Tue', 'Wed', 'Thu'] },
94
+ yAxis: { type: 'value' as const },
95
+ series: [{ data: [120, 200, 150, 250], type: 'line' as const }],
96
+ };
97
+
98
+ const { getByTestId, rerender } = render(
99
+ <LineChart option={initialOption} width="500px" height="300px" />
100
+ );
101
+
102
+ // Check initial rendering
103
+ let chartOption = getByTestId('chart-option');
104
+ expect(chartOption).toHaveTextContent(JSON.stringify(initialOption));
105
+
106
+ // Update option and check
107
+ rerender(<LineChart option={updatedOption} width="500px" height="300px" />);
108
+
109
+ chartOption = getByTestId('chart-option');
110
+ expect(chartOption).toHaveTextContent(JSON.stringify(updatedOption));
111
+ });
112
+
113
+ it('should handle loading state changes', () => {
114
+ const mockOption = {
115
+ xAxis: { type: 'category' as const, data: ['Mon', 'Tue', 'Wed'] },
116
+ yAxis: { type: 'value' as const },
117
+ series: [{ data: [120, 200, 150], type: 'line' as const }],
118
+ };
119
+
120
+ const { getByTestId, rerender } = render(<LineChart option={mockOption} loading={false} />);
121
+
122
+ // Check initial loading state
123
+ let chartLoading = getByTestId('chart-loading');
124
+ expect(chartLoading).toHaveTextContent('not-loading');
125
+
126
+ // Update loading state and check
127
+ rerender(<LineChart option={mockOption} loading={true} />);
128
+
129
+ chartLoading = getByTestId('chart-loading');
130
+ expect(chartLoading).toHaveTextContent('loading');
131
+ });
132
+
133
+ it('should render different chart types with consistent API', () => {
134
+ // Test LineChart
135
+ const lineOption = {
136
+ xAxis: { type: 'category' as const, data: ['Mon', 'Tue', 'Wed'] },
137
+ yAxis: { type: 'value' as const },
138
+ series: [{ data: [120, 200, 150], type: 'line' as const }],
139
+ };
140
+
141
+ const { getByTestId: getLineChart } = render(
142
+ <LineChart option={lineOption} width="400px" height="200px" />
143
+ );
144
+
145
+ const lineChartWrapper = getLineChart('base-chart-wrapper');
146
+ expect(lineChartWrapper).toBeInTheDocument();
147
+ expect(lineChartWrapper).toHaveClass('taroviz-line-chart');
148
+ });
149
+ });
150
+
151
+ describe('Chart Event Handling', () => {
152
+ it('should pass events to chart instance', () => {
153
+ const mockOption = {
154
+ xAxis: { type: 'category' as const, data: ['Mon', 'Tue', 'Wed'] },
155
+ yAxis: { type: 'value' as const },
156
+ series: [{ data: [120, 200, 150], type: 'line' as const }],
157
+ };
158
+
159
+ const mockOnClick = jest.fn();
160
+
161
+ render(<LineChart option={mockOption} onEvents={{ click: mockOnClick }} />);
162
+
163
+ // The event should be passed to the chart instance via BaseChartWrapper
164
+ // We can verify this by checking that the BaseChartWrapper received the onEvents prop
165
+ // In our mock, this is handled by the getAdapter mock
166
+ });
167
+ });
168
+ });
@@ -0,0 +1,91 @@
1
+ import { PlatformType } from '../../core';
2
+ import { detectPlatform, getEnv, getAdapter } from '../index';
3
+
4
+ // Mock dependencies
5
+ jest.mock('../h5', () => ({
6
+ default: {
7
+ create: jest.fn(() => ({
8
+ init: jest.fn(),
9
+ setOption: jest.fn(),
10
+ resize: jest.fn(),
11
+ dispose: jest.fn(),
12
+ })),
13
+ },
14
+ }));
15
+
16
+ jest.mock('../weapp', () => ({
17
+ default: {
18
+ create: jest.fn(() => ({
19
+ init: jest.fn(),
20
+ setOption: jest.fn(),
21
+ resize: jest.fn(),
22
+ dispose: jest.fn(),
23
+ })),
24
+ },
25
+ }));
26
+
27
+ describe('Adapter Functions', () => {
28
+ describe('getEnv', () => {
29
+ it('should return h5 for browser environment', () => {
30
+ const env = getEnv();
31
+ expect(env).toBe('h5');
32
+ });
33
+ });
34
+
35
+ describe('getAdapter', () => {
36
+ it('should return adapter instance for browser environment', () => {
37
+ const adapter = getAdapter({});
38
+ expect(adapter).toBeDefined();
39
+ expect(typeof adapter.init).toBe('function');
40
+ expect(typeof adapter.setOption).toBe('function');
41
+ });
42
+
43
+ it('should return adapter instance with custom options', () => {
44
+ const mockOptions = {
45
+ width: 500,
46
+ height: 300,
47
+ theme: 'dark',
48
+ renderer: 'canvas' as const,
49
+ };
50
+
51
+ const adapter = getAdapter(mockOptions);
52
+ expect(adapter).toBeDefined();
53
+ expect(typeof adapter.init).toBe('function');
54
+ });
55
+ });
56
+
57
+ describe('detectPlatform', () => {
58
+ it('should return H5 by default', () => {
59
+ const platform = detectPlatform();
60
+ expect(platform).toBe(PlatformType.H5);
61
+ });
62
+ });
63
+
64
+ describe('Cross-Platform Compatibility', () => {
65
+ it('should have consistent interface across all platforms', () => {
66
+ const adapter = getAdapter({});
67
+
68
+ // 确保所有平台的适配器都有相同的方法接口
69
+ const requiredMethods = ['init', 'setOption', 'resize', 'dispose'];
70
+
71
+ requiredMethods.forEach(method => {
72
+ expect(typeof adapter[method as keyof typeof adapter]).toBe('function');
73
+ });
74
+ });
75
+
76
+ it('should handle different option types across platforms', () => {
77
+ // 测试不同类型的选项
78
+ const testOptions = [
79
+ { width: 500, height: 300 },
80
+ { theme: 'dark' },
81
+ { renderer: 'canvas' as const },
82
+ { renderer: 'svg' as const },
83
+ ];
84
+
85
+ testOptions.forEach(options => {
86
+ const adapter = getAdapter(options);
87
+ expect(adapter).toBeDefined();
88
+ });
89
+ });
90
+ });
91
+ });
@@ -0,0 +1,156 @@
1
+ import * as echarts from 'echarts/core';
2
+
3
+ import H5Adapter from '../index';
4
+
5
+ // Mock ECharts renderers first
6
+ jest.mock('echarts/renderers', () => ({
7
+ CanvasRenderer: jest.fn(),
8
+ SVGRenderer: jest.fn(),
9
+ }));
10
+
11
+ // Mock ECharts components
12
+ jest.mock('echarts/components', () => ({
13
+ GridComponent: jest.fn(),
14
+ TooltipComponent: jest.fn(),
15
+ TitleComponent: jest.fn(),
16
+ LegendComponent: jest.fn(),
17
+ }));
18
+
19
+ // Mock ECharts charts
20
+ jest.mock('echarts/charts', () => ({
21
+ LineChart: jest.fn(),
22
+ BarChart: jest.fn(),
23
+ PieChart: jest.fn(),
24
+ }));
25
+
26
+ // Mock ECharts
27
+ jest.mock('echarts/core', () => ({
28
+ init: jest.fn(() => ({
29
+ setOption: jest.fn(),
30
+ resize: jest.fn(),
31
+ on: jest.fn(),
32
+ off: jest.fn(),
33
+ showLoading: jest.fn(),
34
+ hideLoading: jest.fn(),
35
+ dispose: jest.fn(),
36
+ getDataURL: jest.fn(() => 'data:image/png;base64,test'),
37
+ clear: jest.fn(),
38
+ })),
39
+ use: jest.fn(),
40
+ }));
41
+
42
+ describe('H5Adapter', () => {
43
+ let adapter: H5Adapter;
44
+ let mockContainer: HTMLElement;
45
+
46
+ beforeEach(() => {
47
+ // Create a mock container
48
+ mockContainer = document.createElement('div');
49
+ mockContainer.id = 'test-canvas';
50
+ document.body.appendChild(mockContainer);
51
+
52
+ // Create adapter instance
53
+ adapter = H5Adapter.create({
54
+ canvasId: 'test-canvas',
55
+ width: 500,
56
+ height: 300,
57
+ theme: 'dark',
58
+ renderer: 'canvas',
59
+ });
60
+ });
61
+
62
+ afterEach(() => {
63
+ // Clean up
64
+ document.body.removeChild(mockContainer);
65
+ });
66
+
67
+ describe('initialization', () => {
68
+ it('should create an instance with correct options', () => {
69
+ expect(adapter).toBeInstanceOf(H5Adapter);
70
+ });
71
+
72
+ it('should initialize the chart instance', () => {
73
+ const instance = adapter.init();
74
+ expect(instance).toBeDefined();
75
+ expect(echarts.init).toHaveBeenCalled();
76
+ });
77
+ });
78
+
79
+ describe('chart operations', () => {
80
+ it('should set chart options', () => {
81
+ const mockOption = {
82
+ xAxis: { type: 'category' as const, data: ['Mon', 'Tue'] },
83
+ yAxis: { type: 'value' as const },
84
+ series: [{ data: [120, 200], type: 'line' as const }],
85
+ };
86
+
87
+ adapter.setOption(mockOption);
88
+
89
+ // After initialization, setOption should be called on the instance
90
+ const _instance = adapter.init();
91
+ adapter.setOption(mockOption);
92
+ });
93
+
94
+ it('should handle theme setting', () => {
95
+ adapter.setTheme('light');
96
+ expect(adapter['options'].theme).toBe('light');
97
+ });
98
+
99
+ it('should resize the chart', () => {
100
+ const _instance = adapter.init();
101
+ adapter.resize();
102
+ });
103
+
104
+ it('should show and hide loading', () => {
105
+ const _instance = adapter.init();
106
+ adapter.showLoading();
107
+ adapter.hideLoading();
108
+ });
109
+
110
+ it('should convert chart to data URL', () => {
111
+ const _instance = adapter.init();
112
+ const dataUrl = adapter.convertToDataURL();
113
+ expect(dataUrl).toBeDefined();
114
+ });
115
+
116
+ it('should clear the chart', () => {
117
+ const _instance = adapter.init();
118
+ adapter.clear();
119
+ });
120
+
121
+ it('should dispose the chart', () => {
122
+ const _instance = adapter.init();
123
+ adapter.dispose();
124
+ });
125
+ });
126
+
127
+ describe('event handling', () => {
128
+ it('should bind and unbind events', () => {
129
+ const _instance = adapter.init();
130
+ const mockHandler = jest.fn();
131
+
132
+ adapter.on('click', mockHandler);
133
+ adapter.off('click', mockHandler);
134
+ });
135
+ });
136
+
137
+ describe('adapter information', () => {
138
+ it('should return adapter name', () => {
139
+ expect(adapter.getName()).toBe('H5Adapter');
140
+ });
141
+
142
+ it('should return adapter version', () => {
143
+ expect(adapter.getVersion()).toBe('1.1.1');
144
+ });
145
+
146
+ it('should return platform info', () => {
147
+ const platformInfo = adapter.getPlatformInfo();
148
+ expect(platformInfo).toEqual(
149
+ expect.objectContaining({
150
+ platform: 'h5',
151
+ renderer: 'canvas',
152
+ })
153
+ );
154
+ });
155
+ });
156
+ });