@pie-lib/charting 7.1.0-beta.8 → 8.0.0-next.20261002094057

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 (232) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +20 -0
  2. package/dist/actions-button.d.ts +26 -0
  3. package/dist/actions-button.js +84 -0
  4. package/dist/autosize-input.d.ts +10 -0
  5. package/dist/autosize-input.js +66 -0
  6. package/dist/axes.d.ts +84 -0
  7. package/dist/axes.js +376 -0
  8. package/dist/bars/bar.d.ts +47 -0
  9. package/dist/bars/bar.js +27 -0
  10. package/dist/bars/common/bars.d.ts +98 -0
  11. package/dist/bars/common/bars.js +174 -0
  12. package/dist/bars/common/correct-check-icon.d.ts +18 -0
  13. package/dist/bars/common/correct-check-icon.js +50 -0
  14. package/dist/bars/histogram.d.ts +47 -0
  15. package/dist/bars/histogram.js +28 -0
  16. package/dist/chart-setup.d.ts +29 -0
  17. package/dist/chart-setup.js +231 -0
  18. package/dist/chart-type.d.ts +32 -0
  19. package/dist/chart-type.js +68 -0
  20. package/dist/chart-types.d.ts +41 -0
  21. package/dist/chart-types.js +17 -0
  22. package/dist/chart.d.ts +88 -0
  23. package/dist/chart.js +250 -0
  24. package/dist/common/correctness-indicators.d.ts +70 -0
  25. package/dist/common/correctness-indicators.js +106 -0
  26. package/dist/common/drag-handle.d.ts +129 -0
  27. package/dist/common/drag-handle.js +120 -0
  28. package/dist/common/drag-icon.d.ts +23 -0
  29. package/dist/common/drag-icon.js +45 -0
  30. package/dist/common/styles.d.ts +23 -0
  31. package/dist/common/styles.js +17 -0
  32. package/dist/grid.d.ts +45 -0
  33. package/dist/grid.js +56 -0
  34. package/dist/index.d.ts +14 -0
  35. package/dist/index.js +6 -0
  36. package/dist/key-legend.d.ts +19 -0
  37. package/dist/key-legend.js +46 -0
  38. package/dist/line/common/drag-handle.d.ts +120 -0
  39. package/dist/line/common/drag-handle.js +92 -0
  40. package/dist/line/common/line.d.ts +96 -0
  41. package/dist/line/common/line.js +114 -0
  42. package/dist/line/line-cross.d.ts +47 -0
  43. package/dist/line/line-cross.js +133 -0
  44. package/dist/line/line-dot.d.ts +47 -0
  45. package/dist/line/line-dot.js +101 -0
  46. package/dist/mark-label.d.ts +55 -0
  47. package/dist/mark-label.js +143 -0
  48. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/Axis.js +67 -0
  49. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/AxisBottom.js +29 -0
  50. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/AxisLeft.js +30 -0
  51. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/AxisRenderer.js +66 -0
  52. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/axis/Ticks.js +39 -0
  53. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/constants/orientation.js +9 -0
  54. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/createPoint.js +14 -0
  55. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getAxisRangePaddingConfig.js +13 -0
  56. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getLabelTransform.js +16 -0
  57. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getTickFormatter.js +8 -0
  58. package/dist/node_modules/.bun/@visx_axis@4.0.0_d84c32d47042070f/node_modules/@visx/axis/esm/utils/getTickPosition.js +14 -0
  59. package/dist/node_modules/.bun/@visx_grid@4.0.0_d84c32d47042070f/node_modules/@visx/grid/esm/grids/GridColumns.js +46 -0
  60. package/dist/node_modules/.bun/@visx_grid@4.0.0_d84c32d47042070f/node_modules/@visx/grid/esm/grids/GridRows.js +46 -0
  61. package/dist/node_modules/.bun/@visx_grid@4.0.0_d84c32d47042070f/node_modules/@visx/grid/esm/utils/getScaleBandwidth.js +6 -0
  62. package/dist/node_modules/.bun/@visx_group@4.0.0_d84c32d47042070f/node_modules/@visx/group/esm/Group.js +17 -0
  63. package/dist/node_modules/.bun/@visx_point@4.0.0/node_modules/@visx/point/esm/Point.js +20 -0
  64. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/align.js +6 -0
  65. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/base.js +6 -0
  66. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/clamp.js +6 -0
  67. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/constant.js +6 -0
  68. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/domain.js +6 -0
  69. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/exponent.js +6 -0
  70. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/interpolate.js +10 -0
  71. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/nice.js +37 -0
  72. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/padding.js +6 -0
  73. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/range.js +6 -0
  74. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/reverse.js +9 -0
  75. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/round.js +7 -0
  76. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/scaleOperator.js +56 -0
  77. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/unknown.js +6 -0
  78. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/operators/zero.js +9 -0
  79. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/scales/band.js +9 -0
  80. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/scales/point.js +9 -0
  81. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/coerceNumber.js +10 -0
  82. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/createColorInterpolator.js +29 -0
  83. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/getTicks.js +7 -0
  84. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/isUtcScale.js +7 -0
  85. package/dist/node_modules/.bun/@visx_scale@4.0.0/node_modules/@visx/scale/esm/utils/toString.js +6 -0
  86. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/Bar.js +15 -0
  87. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/Circle.js +15 -0
  88. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/Line.js +27 -0
  89. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/shapes/LinePath.js +24 -0
  90. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/util/D3ShapeFactories.js +9 -0
  91. package/dist/node_modules/.bun/@visx_shape@4.0.0_d84c32d47042070f/node_modules/@visx/shape/esm/util/setNumberOrNumberAccessor.js +6 -0
  92. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/Text.js +27 -0
  93. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/hooks/useText.js +68 -0
  94. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/util/getStringWidth.js +19 -0
  95. package/dist/node_modules/.bun/@visx_text@4.0.0_d84c32d47042070f/node_modules/@visx/text/esm/util/memoize.js +13 -0
  96. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-interpolate.js +8 -0
  97. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-scale.js +8 -0
  98. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-shape.js +8 -0
  99. package/dist/node_modules/.bun/@visx_vendor@4.0.0/node_modules/@visx/vendor/esm/d3-time.js +8 -0
  100. package/dist/node_modules/.bun/balanced-match@0.4.2/node_modules/balanced-match/index.js +32 -0
  101. package/dist/node_modules/.bun/balanced-match@1.0.2/node_modules/balanced-match/index.js +33 -0
  102. package/dist/node_modules/.bun/classnames@2.5.1/node_modules/classnames/index.js +32 -0
  103. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +16 -0
  104. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/formula_evaluator.js +37 -0
  105. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/lexer.js +509 -0
  106. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/math_function.js +108 -0
  107. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix.js +31 -0
  108. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix_evaluator.js +45 -0
  109. package/dist/node_modules/.bun/reduce-css-calc@1.3.0/node_modules/reduce-css-calc/index.js +49 -0
  110. package/dist/node_modules/.bun/reduce-function-call@1.0.3/node_modules/reduce-function-call/index.js +34 -0
  111. package/dist/plot/common/plot.d.ts +103 -0
  112. package/dist/plot/common/plot.js +227 -0
  113. package/dist/plot/dot.d.ts +47 -0
  114. package/dist/plot/dot.js +62 -0
  115. package/dist/plot/line.d.ts +47 -0
  116. package/dist/plot/line.js +84 -0
  117. package/dist/utils.d.ts +39 -0
  118. package/dist/utils.js +101 -0
  119. package/package.json +45 -36
  120. package/CHANGELOG.json +0 -17
  121. package/CHANGELOG.md +0 -1116
  122. package/lib/actions-button.js +0 -145
  123. package/lib/actions-button.js.map +0 -1
  124. package/lib/axes.js +0 -643
  125. package/lib/axes.js.map +0 -1
  126. package/lib/bars/bar.js +0 -58
  127. package/lib/bars/bar.js.map +0 -1
  128. package/lib/bars/common/bars.js +0 -277
  129. package/lib/bars/common/bars.js.map +0 -1
  130. package/lib/bars/common/correct-check-icon.js +0 -54
  131. package/lib/bars/common/correct-check-icon.js.map +0 -1
  132. package/lib/bars/histogram.js +0 -59
  133. package/lib/bars/histogram.js.map +0 -1
  134. package/lib/chart-setup.js +0 -382
  135. package/lib/chart-setup.js.map +0 -1
  136. package/lib/chart-type.js +0 -80
  137. package/lib/chart-type.js.map +0 -1
  138. package/lib/chart-types.js +0 -22
  139. package/lib/chart-types.js.map +0 -1
  140. package/lib/chart.js +0 -384
  141. package/lib/chart.js.map +0 -1
  142. package/lib/common/correctness-indicators.js +0 -156
  143. package/lib/common/correctness-indicators.js.map +0 -1
  144. package/lib/common/drag-handle.js +0 -160
  145. package/lib/common/drag-handle.js.map +0 -1
  146. package/lib/common/drag-icon.js +0 -52
  147. package/lib/common/drag-icon.js.map +0 -1
  148. package/lib/common/styles.js +0 -22
  149. package/lib/common/styles.js.map +0 -1
  150. package/lib/grid.js +0 -112
  151. package/lib/grid.js.map +0 -1
  152. package/lib/index.js +0 -42
  153. package/lib/index.js.map +0 -1
  154. package/lib/key-legend.js +0 -87
  155. package/lib/key-legend.js.map +0 -1
  156. package/lib/line/common/drag-handle.js +0 -146
  157. package/lib/line/common/drag-handle.js.map +0 -1
  158. package/lib/line/common/line.js +0 -214
  159. package/lib/line/common/line.js.map +0 -1
  160. package/lib/line/line-cross.js +0 -214
  161. package/lib/line/line-cross.js.map +0 -1
  162. package/lib/line/line-dot.js +0 -158
  163. package/lib/line/line-dot.js.map +0 -1
  164. package/lib/mark-label.js +0 -237
  165. package/lib/mark-label.js.map +0 -1
  166. package/lib/plot/common/plot.js +0 -349
  167. package/lib/plot/common/plot.js.map +0 -1
  168. package/lib/plot/dot.js +0 -110
  169. package/lib/plot/dot.js.map +0 -1
  170. package/lib/plot/line.js +0 -140
  171. package/lib/plot/line.js.map +0 -1
  172. package/lib/tool-menu.js +0 -106
  173. package/lib/tool-menu.js.map +0 -1
  174. package/lib/utils.js +0 -189
  175. package/lib/utils.js.map +0 -1
  176. package/src/__tests__/actions-button.test.jsx +0 -280
  177. package/src/__tests__/axes.test.jsx +0 -667
  178. package/src/__tests__/chart-setup.test.jsx +0 -532
  179. package/src/__tests__/chart-type.test.jsx +0 -23
  180. package/src/__tests__/chart.test.jsx +0 -86
  181. package/src/__tests__/grid.test.jsx +0 -37
  182. package/src/__tests__/key-legend.test.jsx +0 -223
  183. package/src/__tests__/mark-label.test.jsx +0 -33
  184. package/src/__tests__/tool-menu.test.jsx +0 -522
  185. package/src/__tests__/utils.js +0 -36
  186. package/src/__tests__/utils.test.js +0 -100
  187. package/src/actions-button.jsx +0 -115
  188. package/src/axes.jsx +0 -594
  189. package/src/bars/__tests__/bar.test.jsx +0 -45
  190. package/src/bars/__tests__/histogram.test.jsx +0 -45
  191. package/src/bars/__tests__/utils.js +0 -30
  192. package/src/bars/bar.js +0 -28
  193. package/src/bars/common/__tests__/bars.test.jsx +0 -68
  194. package/src/bars/common/__tests__/utils.js +0 -30
  195. package/src/bars/common/bars.jsx +0 -249
  196. package/src/bars/common/correct-check-icon.jsx +0 -25
  197. package/src/bars/histogram.js +0 -28
  198. package/src/chart-setup.jsx +0 -356
  199. package/src/chart-type.js +0 -59
  200. package/src/chart-types.js +0 -8
  201. package/src/chart.jsx +0 -357
  202. package/src/common/__tests__/correctness-indicators.test.jsx +0 -720
  203. package/src/common/__tests__/drag-handle.test.jsx +0 -58
  204. package/src/common/__tests__/utils.js +0 -30
  205. package/src/common/correctness-indicators.jsx +0 -128
  206. package/src/common/drag-handle.jsx +0 -125
  207. package/src/common/drag-icon.jsx +0 -36
  208. package/src/common/styles.js +0 -19
  209. package/src/grid.jsx +0 -80
  210. package/src/index.js +0 -7
  211. package/src/key-legend.jsx +0 -77
  212. package/src/line/__tests__/line-cross.test.jsx +0 -463
  213. package/src/line/__tests__/line-dot.test.jsx +0 -41
  214. package/src/line/__tests__/utils.js +0 -36
  215. package/src/line/common/__tests__/drag-handle.test.jsx +0 -62
  216. package/src/line/common/__tests__/line.test.jsx +0 -79
  217. package/src/line/common/__tests__/utils.js +0 -30
  218. package/src/line/common/drag-handle.jsx +0 -114
  219. package/src/line/common/line.jsx +0 -171
  220. package/src/line/line-cross.js +0 -144
  221. package/src/line/line-dot.js +0 -111
  222. package/src/mark-label.jsx +0 -238
  223. package/src/plot/__tests__/dot.test.jsx +0 -344
  224. package/src/plot/__tests__/line.test.jsx +0 -375
  225. package/src/plot/__tests__/utils.js +0 -30
  226. package/src/plot/common/__tests__/plot.test.jsx +0 -69
  227. package/src/plot/common/__tests__/utils.js +0 -30
  228. package/src/plot/common/plot.jsx +0 -358
  229. package/src/plot/dot.js +0 -74
  230. package/src/plot/line.js +0 -98
  231. package/src/tool-menu.jsx +0 -85
  232. package/src/utils.js +0 -201
@@ -1,720 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
- import { createTheme, ThemeProvider } from '@mui/material/styles';
4
- import { CorrectnessIndicator, SmallCorrectPointIndicator, TickCorrectnessIndicator } from '../correctness-indicators';
5
-
6
- jest.mock('@pie-lib/render-ui', () => ({
7
- color: {
8
- correct: () => '#00ff00',
9
- incorrectWithIcon: () => '#ff0000',
10
- defaults: {
11
- WHITE: '#ffffff',
12
- },
13
- },
14
- }));
15
-
16
- jest.mock('@mui/icons-material/Check', () => {
17
- return function Check(props) {
18
- return <svg data-testid="check-icon" title={props.title} className={props.className} />;
19
- };
20
- });
21
-
22
- jest.mock('@mui/icons-material/Close', () => {
23
- return function Close(props) {
24
- return <svg data-testid="close-icon" title={props.title} className={props.className} />;
25
- };
26
- });
27
-
28
- let theme;
29
-
30
- beforeAll(() => {
31
- theme = createTheme();
32
- });
33
-
34
- describe('CorrectnessIndicator', () => {
35
- const mockScale = {
36
- x: jest.fn((val) => val * 10),
37
- y: jest.fn((val) => val * 10),
38
- };
39
-
40
- beforeEach(() => {
41
- jest.clearAllMocks();
42
- });
43
-
44
- const renderComponent = (extras = {}) => {
45
- const defaults = {
46
- scale: mockScale,
47
- x: 5,
48
- y: 10,
49
- correctness: { value: 'correct', label: 'Correct Answer' },
50
- interactive: true,
51
- };
52
- const props = { ...defaults, ...extras };
53
- return render(
54
- <ThemeProvider theme={theme}>
55
- <svg>
56
- <CorrectnessIndicator {...props} />
57
- </svg>
58
- </ThemeProvider>,
59
- );
60
- };
61
-
62
- describe('rendering', () => {
63
- it('should render without crashing', () => {
64
- const { container } = renderComponent();
65
- expect(container).toBeInTheDocument();
66
- });
67
-
68
- it('should render foreignObject element', () => {
69
- const { container } = renderComponent();
70
- const foreignObject = container.querySelector('foreignObject');
71
- expect(foreignObject).toBeInTheDocument();
72
- });
73
-
74
- it('should render check icon for correct answer', () => {
75
- const { getByTestId } = renderComponent({
76
- correctness: { value: 'correct', label: 'Correct' },
77
- });
78
- expect(getByTestId('check-icon')).toBeInTheDocument();
79
- });
80
-
81
- it('should render close icon for incorrect answer', () => {
82
- const { getByTestId } = renderComponent({
83
- correctness: { value: 'incorrect', label: 'Incorrect' },
84
- });
85
- expect(getByTestId('close-icon')).toBeInTheDocument();
86
- });
87
-
88
- it('should not render when correctness is null', () => {
89
- const { container } = renderComponent({ correctness: null });
90
- const foreignObject = container.querySelector('foreignObject');
91
- expect(foreignObject).not.toBeInTheDocument();
92
- });
93
-
94
- it('should not render when correctness is undefined', () => {
95
- const { container } = renderComponent({ correctness: undefined });
96
- const foreignObject = container.querySelector('foreignObject');
97
- expect(foreignObject).not.toBeInTheDocument();
98
- });
99
-
100
- it('should not render when interactive is false', () => {
101
- const { container } = renderComponent({ interactive: false });
102
- const foreignObject = container.querySelector('foreignObject');
103
- expect(foreignObject).not.toBeInTheDocument();
104
- });
105
-
106
- it('should render with correct title for correct answer', () => {
107
- const { getByTestId } = renderComponent({
108
- correctness: { value: 'correct', label: 'Well done!' },
109
- });
110
- const icon = getByTestId('check-icon');
111
- expect(icon).toHaveAttribute('title', 'Well done!');
112
- });
113
-
114
- it('should render with correct title for incorrect answer', () => {
115
- const { getByTestId } = renderComponent({
116
- correctness: { value: 'incorrect', label: 'Try again' },
117
- });
118
- const icon = getByTestId('close-icon');
119
- expect(icon).toHaveAttribute('title', 'Try again');
120
- });
121
- });
122
-
123
- describe('positioning with scale', () => {
124
- it('should use scale to calculate position', () => {
125
- const { container } = renderComponent({
126
- scale: mockScale,
127
- x: 5,
128
- y: 10,
129
- });
130
- const foreignObject = container.querySelector('foreignObject');
131
- expect(mockScale.x).toHaveBeenCalledWith(5);
132
- expect(mockScale.y).toHaveBeenCalledWith(10);
133
- // position is scaled value - 11 (half of 22px icon size)
134
- expect(foreignObject).toHaveAttribute('x', '39'); // 50 - 11
135
- expect(foreignObject).toHaveAttribute('y', '89'); // 100 - 11
136
- });
137
-
138
- it('should have correct size attributes', () => {
139
- const { container } = renderComponent();
140
- const foreignObject = container.querySelector('foreignObject');
141
- expect(foreignObject).toHaveAttribute('width', '22');
142
- expect(foreignObject).toHaveAttribute('height', '22');
143
- });
144
-
145
- it('should handle different x and y values', () => {
146
- const { container } = renderComponent({
147
- x: 20,
148
- y: 30,
149
- });
150
- expect(mockScale.x).toHaveBeenCalledWith(20);
151
- expect(mockScale.y).toHaveBeenCalledWith(30);
152
- });
153
-
154
- it('should use raw values when scale is not provided', () => {
155
- const { container } = renderComponent({
156
- scale: null,
157
- x: 50,
158
- y: 100,
159
- });
160
- const foreignObject = container.querySelector('foreignObject');
161
- expect(foreignObject).toHaveAttribute('x', '39'); // 50 - 11
162
- expect(foreignObject).toHaveAttribute('y', '89'); // 100 - 11
163
- });
164
- });
165
-
166
- describe('edge cases', () => {
167
- it('should handle zero coordinates', () => {
168
- const { container } = renderComponent({
169
- x: 0,
170
- y: 0,
171
- });
172
- const foreignObject = container.querySelector('foreignObject');
173
- expect(foreignObject).toHaveAttribute('x', '-11');
174
- expect(foreignObject).toHaveAttribute('y', '-11');
175
- });
176
-
177
- it('should handle negative coordinates', () => {
178
- const { container } = renderComponent({
179
- x: -5,
180
- y: -10,
181
- });
182
- expect(mockScale.x).toHaveBeenCalledWith(-5);
183
- expect(mockScale.y).toHaveBeenCalledWith(-10);
184
- });
185
-
186
- it('should handle large coordinates', () => {
187
- const { container } = renderComponent({
188
- x: 1000,
189
- y: 2000,
190
- });
191
- expect(mockScale.x).toHaveBeenCalledWith(1000);
192
- expect(mockScale.y).toHaveBeenCalledWith(2000);
193
- });
194
-
195
- it('should handle correctness with empty label', () => {
196
- const { getByTestId } = renderComponent({
197
- correctness: { value: 'correct', label: '' },
198
- });
199
- const icon = getByTestId('check-icon');
200
- expect(icon).toHaveAttribute('title', '');
201
- });
202
-
203
- it('should handle correctness with undefined label', () => {
204
- const { getByTestId } = renderComponent({
205
- correctness: { value: 'correct', label: undefined },
206
- });
207
- expect(getByTestId('check-icon')).toBeInTheDocument();
208
- });
209
-
210
- it('should render when both correctness and interactive are true', () => {
211
- const { container } = renderComponent({
212
- correctness: { value: 'correct', label: 'Test' },
213
- interactive: true,
214
- });
215
- expect(container.querySelector('foreignObject')).toBeInTheDocument();
216
- });
217
-
218
- it('should not render when interactive is false even with correctness', () => {
219
- const { container } = renderComponent({
220
- correctness: { value: 'correct', label: 'Test' },
221
- interactive: false,
222
- });
223
- expect(container.querySelector('foreignObject')).not.toBeInTheDocument();
224
- });
225
- });
226
- });
227
-
228
- describe('SmallCorrectPointIndicator', () => {
229
- const mockScale = {
230
- x: jest.fn((val) => val * 10),
231
- y: jest.fn((val) => val * 10),
232
- };
233
-
234
- const correctData = [
235
- { label: 'A', value: 10 },
236
- { label: 'B', value: 20 },
237
- { label: 'C', value: '30' },
238
- ];
239
-
240
- beforeEach(() => {
241
- jest.clearAllMocks();
242
- });
243
-
244
- const renderComponent = (extras = {}) => {
245
- const defaults = {
246
- scale: mockScale,
247
- x: 5,
248
- correctness: { value: 'incorrect', label: 'Incorrect' },
249
- correctData,
250
- label: 'A',
251
- };
252
- const props = { ...defaults, ...extras };
253
- return render(
254
- <ThemeProvider theme={theme}>
255
- <svg>
256
- <SmallCorrectPointIndicator {...props} />
257
- </svg>
258
- </ThemeProvider>,
259
- );
260
- };
261
-
262
- describe('rendering', () => {
263
- it('should render without crashing', () => {
264
- const { container } = renderComponent();
265
- expect(container).toBeInTheDocument();
266
- });
267
-
268
- it('should render foreignObject when incorrect', () => {
269
- const { container } = renderComponent({
270
- correctness: { value: 'incorrect', label: 'Wrong' },
271
- label: 'A',
272
- });
273
- const foreignObject = container.querySelector('foreignObject');
274
- expect(foreignObject).toBeInTheDocument();
275
- });
276
-
277
- it('should render small check icon when incorrect', () => {
278
- const { getByTestId } = renderComponent({
279
- correctness: { value: 'incorrect', label: 'Wrong' },
280
- label: 'A',
281
- });
282
- const icon = getByTestId('check-icon');
283
- expect(icon).toBeInTheDocument();
284
- expect(icon).toHaveClass('small');
285
- });
286
-
287
- it('should not render when correctness is correct', () => {
288
- const { container } = renderComponent({
289
- correctness: { value: 'correct', label: 'Correct' },
290
- });
291
- const foreignObject = container.querySelector('foreignObject');
292
- expect(foreignObject).not.toBeInTheDocument();
293
- });
294
-
295
- it('should not render when correctness is null', () => {
296
- const { container } = renderComponent({ correctness: null });
297
- const foreignObject = container.querySelector('foreignObject');
298
- expect(foreignObject).not.toBeInTheDocument();
299
- });
300
-
301
- it('should not render when correctness is undefined', () => {
302
- const { container } = renderComponent({ correctness: undefined });
303
- const foreignObject = container.querySelector('foreignObject');
304
- expect(foreignObject).not.toBeInTheDocument();
305
- });
306
- });
307
-
308
- describe('positioning', () => {
309
- it('should calculate correct position for label A', () => {
310
- const { container } = renderComponent({
311
- x: 5,
312
- label: 'A',
313
- });
314
- const foreignObject = container.querySelector('foreignObject');
315
- expect(mockScale.x).toHaveBeenCalledWith(5);
316
- expect(mockScale.y).toHaveBeenCalledWith(10); // value from correctData for label A
317
- // Position is scaled value - 7.5 (half of 15px small icon size)
318
- expect(foreignObject).toHaveAttribute('x', '42.5'); // 50 - 7.5
319
- expect(foreignObject).toHaveAttribute('y', '92.5'); // 100 - 7.5
320
- });
321
-
322
- it('should calculate correct position for label B', () => {
323
- const { container } = renderComponent({
324
- x: 5,
325
- label: 'B',
326
- });
327
- expect(mockScale.y).toHaveBeenCalledWith(20);
328
- });
329
-
330
- it('should calculate correct position for label C with string value', () => {
331
- const { container } = renderComponent({
332
- x: 5,
333
- label: 'C',
334
- });
335
- expect(mockScale.y).toHaveBeenCalledWith(30);
336
- });
337
-
338
- it('should have correct size attributes for small icon', () => {
339
- const { container } = renderComponent({
340
- label: 'A',
341
- });
342
- const foreignObject = container.querySelector('foreignObject');
343
- expect(foreignObject).toHaveAttribute('width', '15');
344
- expect(foreignObject).toHaveAttribute('height', '15');
345
- });
346
- });
347
-
348
- describe('correctData handling', () => {
349
- it('should find correct value from correctData by label', () => {
350
- const { container } = renderComponent({
351
- label: 'B',
352
- });
353
- const foreignObject = container.querySelector('foreignObject');
354
- expect(foreignObject).toBeInTheDocument();
355
- expect(mockScale.y).toHaveBeenCalledWith(20);
356
- });
357
-
358
- it('should not render when label is not in correctData', () => {
359
- const { container } = renderComponent({
360
- label: 'Z',
361
- });
362
- const foreignObject = container.querySelector('foreignObject');
363
- expect(foreignObject).not.toBeInTheDocument();
364
- });
365
-
366
- it('should not render when correctData value is NaN', () => {
367
- const { container } = renderComponent({
368
- correctData: [{ label: 'A', value: 'invalid' }],
369
- label: 'A',
370
- });
371
- const foreignObject = container.querySelector('foreignObject');
372
- expect(foreignObject).not.toBeInTheDocument();
373
- });
374
-
375
- it('should handle empty correctData array', () => {
376
- const { container } = renderComponent({
377
- correctData: [],
378
- label: 'A',
379
- });
380
- const foreignObject = container.querySelector('foreignObject');
381
- expect(foreignObject).not.toBeInTheDocument();
382
- });
383
-
384
- it('should not render when correctData is undefined (correctness not incorrect)', () => {
385
- const { container } = renderComponent({
386
- correctness: { value: 'correct', label: 'Correct' },
387
- correctData: undefined,
388
- label: 'A',
389
- });
390
- const foreignObject = container.querySelector('foreignObject');
391
- expect(foreignObject).not.toBeInTheDocument();
392
- });
393
-
394
- it('should parse string values correctly', () => {
395
- const { container } = renderComponent({
396
- correctData: [{ label: 'D', value: '45.5' }],
397
- label: 'D',
398
- });
399
- const foreignObject = container.querySelector('foreignObject');
400
- expect(foreignObject).toBeInTheDocument();
401
- expect(mockScale.y).toHaveBeenCalledWith(45.5);
402
- });
403
-
404
- it('should handle zero values', () => {
405
- const { container } = renderComponent({
406
- correctData: [{ label: 'E', value: 0 }],
407
- label: 'E',
408
- });
409
- const foreignObject = container.querySelector('foreignObject');
410
- expect(foreignObject).toBeInTheDocument();
411
- expect(mockScale.y).toHaveBeenCalledWith(0);
412
- });
413
-
414
- it('should handle negative values', () => {
415
- const { container } = renderComponent({
416
- correctData: [{ label: 'F', value: -10 }],
417
- label: 'F',
418
- });
419
- const foreignObject = container.querySelector('foreignObject');
420
- expect(foreignObject).toBeInTheDocument();
421
- expect(mockScale.y).toHaveBeenCalledWith(-10);
422
- });
423
- });
424
-
425
- describe('icon properties', () => {
426
- it('should render icon with correct title', () => {
427
- const { getByTestId } = renderComponent({
428
- correctness: { value: 'incorrect', label: 'Not quite right' },
429
- label: 'A',
430
- });
431
- const icon = getByTestId('check-icon');
432
- expect(icon).toHaveAttribute('title', 'Not quite right');
433
- });
434
-
435
- it('should render icon with small className', () => {
436
- const { getByTestId } = renderComponent({
437
- label: 'A',
438
- });
439
- const icon = getByTestId('check-icon');
440
- expect(icon).toHaveClass('small');
441
- });
442
- });
443
-
444
- describe('edge cases', () => {
445
- it('should handle missing label prop', () => {
446
- const { container } = renderComponent({
447
- label: undefined,
448
- });
449
- const foreignObject = container.querySelector('foreignObject');
450
- expect(foreignObject).not.toBeInTheDocument();
451
- });
452
-
453
- it('should handle empty string label', () => {
454
- const { container } = renderComponent({
455
- label: '',
456
- });
457
- const foreignObject = container.querySelector('foreignObject');
458
- expect(foreignObject).not.toBeInTheDocument();
459
- });
460
-
461
- it('should handle very large values in correctData', () => {
462
- const { container } = renderComponent({
463
- correctData: [{ label: 'G', value: 999999 }],
464
- label: 'G',
465
- });
466
- const foreignObject = container.querySelector('foreignObject');
467
- expect(foreignObject).toBeInTheDocument();
468
- expect(mockScale.y).toHaveBeenCalledWith(999999);
469
- });
470
-
471
- it('should only render for incorrect answers', () => {
472
- const { container: incorrectContainer } = renderComponent({
473
- correctness: { value: 'incorrect', label: 'Wrong' },
474
- label: 'A',
475
- });
476
- expect(incorrectContainer.querySelector('foreignObject')).toBeInTheDocument();
477
-
478
- const { container: correctContainer } = renderComponent({
479
- correctness: { value: 'correct', label: 'Right' },
480
- label: 'A',
481
- });
482
- expect(correctContainer.querySelector('foreignObject')).not.toBeInTheDocument();
483
- });
484
- });
485
- });
486
-
487
- describe('TickCorrectnessIndicator', () => {
488
- beforeEach(() => {
489
- jest.clearAllMocks();
490
- });
491
-
492
- const renderComponent = (extras = {}) => {
493
- const defaults = {
494
- correctness: { value: 'correct', label: 'Correct Answer' },
495
- interactive: true,
496
- };
497
- const props = { ...defaults, ...extras };
498
- return render(
499
- <ThemeProvider theme={theme}>
500
- <TickCorrectnessIndicator {...props} />
501
- </ThemeProvider>,
502
- );
503
- };
504
-
505
- describe('rendering', () => {
506
- it('should render without crashing', () => {
507
- const { container } = renderComponent();
508
- expect(container).toBeInTheDocument();
509
- });
510
-
511
- it('should render check icon for correct answer', () => {
512
- const { getByTestId } = renderComponent({
513
- correctness: { value: 'correct', label: 'Correct' },
514
- });
515
- expect(getByTestId('check-icon')).toBeInTheDocument();
516
- });
517
-
518
- it('should render close icon for incorrect answer', () => {
519
- const { getByTestId } = renderComponent({
520
- correctness: { value: 'incorrect', label: 'Incorrect' },
521
- });
522
- expect(getByTestId('close-icon')).toBeInTheDocument();
523
- });
524
-
525
- it('should not render when correctness is null', () => {
526
- const { queryByTestId } = renderComponent({ correctness: null });
527
- expect(queryByTestId('check-icon')).not.toBeInTheDocument();
528
- expect(queryByTestId('close-icon')).not.toBeInTheDocument();
529
- });
530
-
531
- it('should not render when correctness is undefined', () => {
532
- const { queryByTestId } = renderComponent({ correctness: undefined });
533
- expect(queryByTestId('check-icon')).not.toBeInTheDocument();
534
- expect(queryByTestId('close-icon')).not.toBeInTheDocument();
535
- });
536
-
537
- it('should not render when interactive is false', () => {
538
- const { queryByTestId } = renderComponent({ interactive: false });
539
- expect(queryByTestId('check-icon')).not.toBeInTheDocument();
540
- expect(queryByTestId('close-icon')).not.toBeInTheDocument();
541
- });
542
-
543
- it('should render with correct title for correct answer', () => {
544
- const { getByTestId } = renderComponent({
545
- correctness: { value: 'correct', label: 'Great job!' },
546
- });
547
- const icon = getByTestId('check-icon');
548
- expect(icon).toHaveAttribute('title', 'Great job!');
549
- });
550
-
551
- it('should render with correct title for incorrect answer', () => {
552
- const { getByTestId } = renderComponent({
553
- correctness: { value: 'incorrect', label: 'Not correct' },
554
- });
555
- const icon = getByTestId('close-icon');
556
- expect(icon).toHaveAttribute('title', 'Not correct');
557
- });
558
- });
559
-
560
- describe('interactive flag', () => {
561
- it('should render when interactive is true', () => {
562
- const { getByTestId } = renderComponent({
563
- interactive: true,
564
- correctness: { value: 'correct', label: 'Test' },
565
- });
566
- expect(getByTestId('check-icon')).toBeInTheDocument();
567
- });
568
-
569
- it('should not render when interactive is false', () => {
570
- const { queryByTestId } = renderComponent({
571
- interactive: false,
572
- correctness: { value: 'correct', label: 'Test' },
573
- });
574
- expect(queryByTestId('check-icon')).not.toBeInTheDocument();
575
- });
576
-
577
- it('should not render when interactive is undefined', () => {
578
- const { queryByTestId } = renderComponent({
579
- interactive: undefined,
580
- correctness: { value: 'correct', label: 'Test' },
581
- });
582
- expect(queryByTestId('check-icon')).not.toBeInTheDocument();
583
- });
584
-
585
- it('should not render when interactive is null', () => {
586
- const { queryByTestId } = renderComponent({
587
- interactive: null,
588
- correctness: { value: 'correct', label: 'Test' },
589
- });
590
- expect(queryByTestId('check-icon')).not.toBeInTheDocument();
591
- });
592
- });
593
-
594
- describe('correctness values', () => {
595
- it('should render check icon when value is "correct"', () => {
596
- const { getByTestId, queryByTestId } = renderComponent({
597
- correctness: { value: 'correct', label: 'Test' },
598
- });
599
- expect(getByTestId('check-icon')).toBeInTheDocument();
600
- expect(queryByTestId('close-icon')).not.toBeInTheDocument();
601
- });
602
-
603
- it('should render close icon when value is "incorrect"', () => {
604
- const { getByTestId, queryByTestId } = renderComponent({
605
- correctness: { value: 'incorrect', label: 'Test' },
606
- });
607
- expect(getByTestId('close-icon')).toBeInTheDocument();
608
- expect(queryByTestId('check-icon')).not.toBeInTheDocument();
609
- });
610
-
611
- it('should render close icon for any value other than "correct"', () => {
612
- const { getByTestId } = renderComponent({
613
- correctness: { value: 'partial', label: 'Test' },
614
- });
615
- expect(getByTestId('close-icon')).toBeInTheDocument();
616
- });
617
-
618
- it('should handle empty value string', () => {
619
- const { getByTestId } = renderComponent({
620
- correctness: { value: '', label: 'Test' },
621
- });
622
- expect(getByTestId('close-icon')).toBeInTheDocument();
623
- });
624
- });
625
-
626
- describe('edge cases', () => {
627
- it('should handle correctness with empty label', () => {
628
- const { getByTestId } = renderComponent({
629
- correctness: { value: 'correct', label: '' },
630
- });
631
- const icon = getByTestId('check-icon');
632
- expect(icon).toHaveAttribute('title', '');
633
- });
634
-
635
- it('should handle correctness with undefined label', () => {
636
- const { getByTestId } = renderComponent({
637
- correctness: { value: 'correct', label: undefined },
638
- });
639
- expect(getByTestId('check-icon')).toBeInTheDocument();
640
- });
641
-
642
- it('should handle correctness with null value', () => {
643
- const { queryByTestId } = renderComponent({
644
- correctness: { value: null, label: 'Test' },
645
- });
646
- expect(queryByTestId('close-icon')).toBeInTheDocument();
647
- });
648
-
649
- it('should require both correctness and interactive to render', () => {
650
- const { queryByTestId: query1 } = renderComponent({
651
- correctness: { value: 'correct', label: 'Test' },
652
- interactive: false,
653
- });
654
- expect(query1('check-icon')).not.toBeInTheDocument();
655
-
656
- const { queryByTestId: query2 } = renderComponent({
657
- correctness: null,
658
- interactive: true,
659
- });
660
- expect(query2('check-icon')).not.toBeInTheDocument();
661
- });
662
-
663
- it('should handle special characters in label', () => {
664
- const { getByTestId } = renderComponent({
665
- correctness: { value: 'correct', label: 'Test <>&"' },
666
- });
667
- const icon = getByTestId('check-icon');
668
- expect(icon).toHaveAttribute('title', 'Test <>&"');
669
- });
670
-
671
- it('should handle unicode characters in label', () => {
672
- const { getByTestId } = renderComponent({
673
- correctness: { value: 'correct', label: 'Test 你好 🎉' },
674
- });
675
- const icon = getByTestId('check-icon');
676
- expect(icon).toHaveAttribute('title', 'Test 你好 🎉');
677
- });
678
-
679
- it('should handle very long labels', () => {
680
- const longLabel = 'This is a very long label that might cause layout issues in the UI';
681
- const { getByTestId } = renderComponent({
682
- correctness: { value: 'correct', label: longLabel },
683
- });
684
- const icon = getByTestId('check-icon');
685
- expect(icon).toHaveAttribute('title', longLabel);
686
- });
687
- });
688
-
689
- describe('component consistency', () => {
690
- it('should render same icon type consistently for same correctness value', () => {
691
- const { getByTestId, unmount } = renderComponent({
692
- correctness: { value: 'correct', label: 'Test 1' },
693
- });
694
-
695
- expect(getByTestId('check-icon')).toBeInTheDocument();
696
- unmount();
697
-
698
- const { getByTestId: get2 } = renderComponent({
699
- correctness: { value: 'correct', label: 'Test 2' },
700
- });
701
-
702
- expect(get2('check-icon')).toBeInTheDocument();
703
- });
704
-
705
- it('should render different icons for different correctness values', () => {
706
- const { getByTestId, unmount } = renderComponent({
707
- correctness: { value: 'correct', label: 'Correct' },
708
- });
709
-
710
- expect(getByTestId('check-icon')).toBeInTheDocument();
711
- unmount();
712
-
713
- const { getByTestId: get2 } = renderComponent({
714
- correctness: { value: 'incorrect', label: 'Incorrect' },
715
- });
716
-
717
- expect(get2('close-icon')).toBeInTheDocument();
718
- });
719
- });
720
- });