@pie-lib/graphing 4.0.5-next.31 → 4.0.5-next.36

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 (453) hide show
  1. package/CHANGELOG.json +1 -0
  2. package/CHANGELOG.md +1469 -0
  3. package/LICENSE.md +5 -0
  4. package/lib/axis/arrow.js +79 -0
  5. package/lib/axis/arrow.js.map +1 -0
  6. package/lib/axis/axes.js +329 -0
  7. package/lib/axis/axes.js.map +1 -0
  8. package/lib/axis/index.js +21 -0
  9. package/lib/axis/index.js.map +1 -0
  10. package/lib/bg.js +114 -0
  11. package/lib/bg.js.map +1 -0
  12. package/lib/container/actions.js +18 -0
  13. package/lib/container/actions.js.map +1 -0
  14. package/lib/container/index.js +127 -0
  15. package/lib/container/index.js.map +1 -0
  16. package/lib/container/marks.js +22 -0
  17. package/lib/container/marks.js.map +1 -0
  18. package/lib/container/middleware.js +19 -0
  19. package/lib/container/middleware.js.map +1 -0
  20. package/lib/container/reducer.js +18 -0
  21. package/lib/container/reducer.js.map +1 -0
  22. package/lib/coordinates-label.js +79 -0
  23. package/lib/coordinates-label.js.map +1 -0
  24. package/lib/graph-with-controls.js +294 -0
  25. package/lib/graph-with-controls.js.map +1 -0
  26. package/lib/graph.js +327 -0
  27. package/lib/graph.js.map +1 -0
  28. package/lib/grid-setup.js +414 -0
  29. package/lib/grid-setup.js.map +1 -0
  30. package/lib/grid.js +131 -0
  31. package/lib/grid.js.map +1 -0
  32. package/lib/index.js +47 -0
  33. package/lib/index.js.map +1 -0
  34. package/lib/key-legend.js +201 -0
  35. package/lib/key-legend.js.map +1 -0
  36. package/lib/label-svg-icon.js +50 -0
  37. package/lib/label-svg-icon.js.map +1 -0
  38. package/lib/labels.js +243 -0
  39. package/lib/labels.js.map +1 -0
  40. package/lib/mark-label.js +285 -0
  41. package/lib/mark-label.js.map +1 -0
  42. package/lib/toggle-bar.js +252 -0
  43. package/lib/toggle-bar.js.map +1 -0
  44. package/lib/tool-menu.js +78 -0
  45. package/lib/tool-menu.js.map +1 -0
  46. package/lib/tools/absolute/component.js +29 -0
  47. package/lib/tools/absolute/component.js.map +1 -0
  48. package/lib/tools/absolute/index.js +50 -0
  49. package/lib/tools/absolute/index.js.map +1 -0
  50. package/lib/tools/circle/bg-circle.js +123 -0
  51. package/lib/tools/circle/bg-circle.js.map +1 -0
  52. package/lib/tools/circle/component.js +321 -0
  53. package/lib/tools/circle/component.js.map +1 -0
  54. package/lib/tools/circle/index.js +41 -0
  55. package/lib/tools/circle/index.js.map +1 -0
  56. package/lib/tools/exponential/component.js +28 -0
  57. package/lib/tools/exponential/component.js.map +1 -0
  58. package/lib/tools/exponential/index.js +56 -0
  59. package/lib/tools/exponential/index.js.map +1 -0
  60. package/lib/tools/index.js +86 -0
  61. package/lib/tools/index.js.map +1 -0
  62. package/lib/tools/line/component.js +97 -0
  63. package/lib/tools/line/component.js.map +1 -0
  64. package/lib/tools/line/index.js +11 -0
  65. package/lib/tools/line/index.js.map +1 -0
  66. package/lib/tools/parabola/component.js +28 -0
  67. package/lib/tools/parabola/component.js.map +1 -0
  68. package/lib/tools/parabola/index.js +50 -0
  69. package/lib/tools/parabola/index.js.map +1 -0
  70. package/lib/tools/point/component.js +148 -0
  71. package/lib/tools/point/component.js.map +1 -0
  72. package/lib/tools/point/index.js +24 -0
  73. package/lib/tools/point/index.js.map +1 -0
  74. package/lib/tools/polygon/component.js +437 -0
  75. package/lib/tools/polygon/component.js.map +1 -0
  76. package/lib/tools/polygon/index.js +89 -0
  77. package/lib/tools/polygon/index.js.map +1 -0
  78. package/lib/tools/polygon/line.js +112 -0
  79. package/lib/tools/polygon/line.js.map +1 -0
  80. package/lib/tools/polygon/polygon.js +130 -0
  81. package/lib/tools/polygon/polygon.js.map +1 -0
  82. package/lib/tools/ray/component.js +95 -0
  83. package/lib/tools/ray/component.js.map +1 -0
  84. package/lib/tools/ray/index.js +11 -0
  85. package/lib/tools/ray/index.js.map +1 -0
  86. package/lib/tools/segment/component.js +71 -0
  87. package/lib/tools/segment/component.js.map +1 -0
  88. package/lib/tools/segment/index.js +11 -0
  89. package/lib/tools/segment/index.js.map +1 -0
  90. package/lib/tools/shared/arrow-head.js +111 -0
  91. package/lib/tools/shared/arrow-head.js.map +1 -0
  92. package/lib/tools/shared/icons/CorrectSVG.js +40 -0
  93. package/lib/tools/shared/icons/CorrectSVG.js.map +1 -0
  94. package/lib/tools/shared/icons/IncorrectSVG.js +40 -0
  95. package/lib/tools/shared/icons/IncorrectSVG.js.map +1 -0
  96. package/lib/tools/shared/icons/MissingSVG.js +39 -0
  97. package/lib/tools/shared/icons/MissingSVG.js.map +1 -0
  98. package/lib/tools/shared/line/index.js +550 -0
  99. package/lib/tools/shared/line/index.js.map +1 -0
  100. package/lib/tools/shared/line/line-path.js +118 -0
  101. package/lib/tools/shared/line/line-path.js.map +1 -0
  102. package/lib/tools/shared/line/with-root-edge.js +121 -0
  103. package/lib/tools/shared/line/with-root-edge.js.map +1 -0
  104. package/lib/tools/shared/point/arrow-point.js +72 -0
  105. package/lib/tools/shared/point/arrow-point.js.map +1 -0
  106. package/lib/tools/shared/point/arrow.js +67 -0
  107. package/lib/tools/shared/point/arrow.js.map +1 -0
  108. package/lib/tools/shared/point/base-point.js +157 -0
  109. package/lib/tools/shared/point/base-point.js.map +1 -0
  110. package/lib/tools/shared/point/index.js +68 -0
  111. package/lib/tools/shared/point/index.js.map +1 -0
  112. package/lib/tools/shared/styles.js +33 -0
  113. package/lib/tools/shared/styles.js.map +1 -0
  114. package/lib/tools/shared/types.js +16 -0
  115. package/lib/tools/shared/types.js.map +1 -0
  116. package/lib/tools/sine/component.js +40 -0
  117. package/lib/tools/sine/component.js.map +1 -0
  118. package/lib/tools/sine/index.js +50 -0
  119. package/lib/tools/sine/index.js.map +1 -0
  120. package/lib/tools/vector/component.js +68 -0
  121. package/lib/tools/vector/component.js.map +1 -0
  122. package/lib/tools/vector/index.js +11 -0
  123. package/lib/tools/vector/index.js.map +1 -0
  124. package/lib/undo-redo.js +86 -0
  125. package/lib/undo-redo.js.map +1 -0
  126. package/lib/use-debounce.js +25 -0
  127. package/lib/use-debounce.js.map +1 -0
  128. package/lib/utils.js +229 -0
  129. package/lib/utils.js.map +1 -0
  130. package/package.json +33 -45
  131. package/src/__tests__/bg.test.jsx +250 -0
  132. package/src/__tests__/coordinates-label.test.jsx +243 -0
  133. package/src/__tests__/graph-with-controls.test.jsx +198 -0
  134. package/src/__tests__/graph.test.jsx +721 -0
  135. package/src/__tests__/grid-setup.test.jsx +645 -0
  136. package/src/__tests__/grid.test.jsx +22 -0
  137. package/src/__tests__/key-legend.test.jsx +260 -0
  138. package/src/__tests__/label-svg-icon.test.jsx +278 -0
  139. package/src/__tests__/labels.test.jsx +55 -0
  140. package/src/__tests__/mark-label.test.jsx +63 -0
  141. package/src/__tests__/toggle-bar.test.jsx +146 -0
  142. package/src/__tests__/tool-menu.test.jsx +115 -0
  143. package/src/__tests__/undo-redo.test.jsx +24 -0
  144. package/src/__tests__/use-debounce.test.js +21 -0
  145. package/src/__tests__/utils.js +41 -0
  146. package/src/__tests__/utils.test.js +105 -0
  147. package/src/axis/__tests__/arrow.test.jsx +38 -0
  148. package/src/axis/__tests__/axes.test.jsx +216 -0
  149. package/src/axis/arrow.jsx +57 -0
  150. package/src/axis/axes.jsx +285 -0
  151. package/src/axis/index.js +3 -0
  152. package/src/bg.jsx +96 -0
  153. package/src/container/__tests__/actions.test.js +105 -0
  154. package/src/container/__tests__/index.test.jsx +319 -0
  155. package/src/container/__tests__/marks.test.js +172 -0
  156. package/src/container/__tests__/middleware.test.js +235 -0
  157. package/src/container/__tests__/reducer.test.js +324 -0
  158. package/src/container/actions.js +8 -0
  159. package/src/container/index.jsx +91 -0
  160. package/src/container/marks.js +14 -0
  161. package/src/container/middleware.js +7 -0
  162. package/src/container/reducer.js +5 -0
  163. package/src/coordinates-label.jsx +63 -0
  164. package/src/graph-with-controls.jsx +239 -0
  165. package/src/graph.jsx +303 -0
  166. package/src/grid-setup.jsx +432 -0
  167. package/src/grid.jsx +133 -0
  168. package/src/index.js +7 -0
  169. package/src/key-legend.jsx +142 -0
  170. package/src/label-svg-icon.jsx +39 -0
  171. package/src/labels.jsx +207 -0
  172. package/src/mark-label.jsx +244 -0
  173. package/src/toggle-bar.jsx +224 -0
  174. package/src/tool-menu.jsx +49 -0
  175. package/src/tools/absolute/__tests__/component.test.jsx +53 -0
  176. package/src/tools/absolute/component.jsx +23 -0
  177. package/src/tools/absolute/index.js +31 -0
  178. package/src/tools/circle/__tests__/bg-circle.test.jsx +26 -0
  179. package/src/tools/circle/__tests__/component.test.jsx +494 -0
  180. package/src/tools/circle/__tests__/index.test.js +480 -0
  181. package/src/tools/circle/bg-circle.jsx +81 -0
  182. package/src/tools/circle/component.jsx +264 -0
  183. package/src/tools/circle/index.js +25 -0
  184. package/src/tools/exponential/__tests__/component.test.jsx +53 -0
  185. package/src/tools/exponential/__tests__/index.test.js +729 -0
  186. package/src/tools/exponential/component.jsx +23 -0
  187. package/src/tools/exponential/index.js +39 -0
  188. package/src/tools/index.js +48 -0
  189. package/src/tools/line/__tests__/component.test.jsx +37 -0
  190. package/src/tools/line/component.jsx +93 -0
  191. package/src/tools/line/index.js +4 -0
  192. package/src/tools/parabola/__tests__/component.test.jsx +48 -0
  193. package/src/tools/parabola/__tests__/index.test.js +470 -0
  194. package/src/tools/parabola/component.jsx +23 -0
  195. package/src/tools/parabola/index.js +31 -0
  196. package/src/tools/point/__tests__/component.test.jsx +349 -0
  197. package/src/tools/point/__tests__/index.test.js +241 -0
  198. package/src/tools/point/component.jsx +126 -0
  199. package/src/tools/point/index.js +11 -0
  200. package/src/tools/polygon/__tests__/component.test.jsx +471 -0
  201. package/src/tools/polygon/__tests__/index.test.js +294 -0
  202. package/src/tools/polygon/__tests__/line.test.jsx +35 -0
  203. package/src/tools/polygon/__tests__/polygon.test.jsx +61 -0
  204. package/src/tools/polygon/component.jsx +409 -0
  205. package/src/tools/polygon/index.js +52 -0
  206. package/src/tools/polygon/line.jsx +74 -0
  207. package/src/tools/polygon/polygon.jsx +110 -0
  208. package/src/tools/ray/__tests__/component.test.jsx +29 -0
  209. package/src/tools/ray/component.jsx +92 -0
  210. package/src/tools/ray/index.js +4 -0
  211. package/src/tools/segment/__tests__/component.test.jsx +28 -0
  212. package/src/tools/segment/component.jsx +65 -0
  213. package/src/tools/segment/index.js +4 -0
  214. package/src/tools/shared/__tests__/arrow-head.test.jsx +31 -0
  215. package/src/tools/shared/arrow-head.jsx +102 -0
  216. package/src/tools/shared/icons/CorrectSVG.jsx +32 -0
  217. package/src/tools/shared/icons/IncorrectSVG.jsx +30 -0
  218. package/src/tools/shared/icons/MissingSVG.jsx +31 -0
  219. package/src/tools/shared/line/__tests__/index.test.jsx +109 -0
  220. package/src/tools/shared/line/__tests__/line-path.test.jsx +53 -0
  221. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +73 -0
  222. package/src/tools/shared/line/index.jsx +487 -0
  223. package/src/tools/shared/line/line-path.jsx +80 -0
  224. package/src/tools/shared/line/with-root-edge.jsx +97 -0
  225. package/src/tools/shared/point/__tests__/arrow-point.test.jsx +91 -0
  226. package/src/tools/shared/point/__tests__/base-point.test.jsx +87 -0
  227. package/src/tools/shared/point/arrow-point.jsx +46 -0
  228. package/src/tools/shared/point/arrow.jsx +37 -0
  229. package/src/tools/shared/point/base-point.jsx +121 -0
  230. package/src/tools/shared/point/index.jsx +54 -0
  231. package/src/tools/shared/styles.js +27 -0
  232. package/src/tools/shared/types.js +10 -0
  233. package/src/tools/sine/__tests__/component.test.jsx +51 -0
  234. package/src/tools/sine/component.jsx +32 -0
  235. package/src/tools/sine/index.js +33 -0
  236. package/src/tools/vector/__tests__/component.test.jsx +25 -0
  237. package/src/tools/vector/component.jsx +56 -0
  238. package/src/tools/vector/index.js +4 -0
  239. package/src/undo-redo.jsx +45 -0
  240. package/src/use-debounce.js +13 -0
  241. package/src/utils.js +224 -0
  242. package/dist/_virtual/_rolldown/runtime.js +0 -23
  243. package/dist/autosize-input.d.ts +0 -10
  244. package/dist/autosize-input.js +0 -66
  245. package/dist/axis/arrow.d.ts +0 -13
  246. package/dist/axis/arrow.js +0 -34
  247. package/dist/axis/axes.d.ts +0 -132
  248. package/dist/axis/axes.js +0 -214
  249. package/dist/axis/index.d.ts +0 -10
  250. package/dist/bg.d.ts +0 -51
  251. package/dist/bg.js +0 -44
  252. package/dist/container/actions.d.ts +0 -15
  253. package/dist/container/actions.js +0 -7
  254. package/dist/container/index.d.ts +0 -58
  255. package/dist/container/index.js +0 -48
  256. package/dist/container/marks.d.ts +0 -10
  257. package/dist/container/marks.js +0 -11
  258. package/dist/container/middleware.d.ts +0 -10
  259. package/dist/container/middleware.js +0 -4
  260. package/dist/container/reducer.d.ts +0 -14
  261. package/dist/container/reducer.js +0 -7
  262. package/dist/coordinates-label.d.ts +0 -50
  263. package/dist/coordinates-label.js +0 -46
  264. package/dist/graph-with-controls.d.ts +0 -88
  265. package/dist/graph-with-controls.js +0 -154
  266. package/dist/graph.d.ts +0 -126
  267. package/dist/graph.js +0 -209
  268. package/dist/grid-setup.d.ts +0 -27
  269. package/dist/grid-setup.js +0 -307
  270. package/dist/grid.d.ts +0 -43
  271. package/dist/grid.js +0 -59
  272. package/dist/index.d.ts +0 -15
  273. package/dist/index.js +0 -7
  274. package/dist/key-legend.d.ts +0 -21
  275. package/dist/key-legend.js +0 -231
  276. package/dist/label-svg-icon.d.ts +0 -18
  277. package/dist/label-svg-icon.js +0 -42
  278. package/dist/labels.d.ts +0 -37
  279. package/dist/labels.js +0 -152
  280. package/dist/mark-label.d.ts +0 -58
  281. package/dist/mark-label.js +0 -171
  282. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/Axis.js +0 -101
  283. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/AxisRenderer.js +0 -63
  284. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/axis/Ticks.js +0 -44
  285. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/constants/orientation.js +0 -9
  286. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/createPoint.js +0 -14
  287. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getAxisRangePaddingConfig.js +0 -21
  288. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getLabelTransform.js +0 -16
  289. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getTickFormatter.js +0 -8
  290. package/dist/node_modules/.bun/@visx_axis@3.12.0_f4eacebf2041cd4f/node_modules/@visx/axis/esm/utils/getTickPosition.js +0 -15
  291. package/dist/node_modules/.bun/@visx_curve@3.12.0/node_modules/@visx/curve/esm/index.js +0 -2
  292. package/dist/node_modules/.bun/@visx_grid@3.12.0_f4eacebf2041cd4f/node_modules/@visx/grid/esm/grids/Grid.js +0 -79
  293. package/dist/node_modules/.bun/@visx_grid@3.12.0_f4eacebf2041cd4f/node_modules/@visx/grid/esm/grids/GridColumns.js +0 -79
  294. package/dist/node_modules/.bun/@visx_grid@3.12.0_f4eacebf2041cd4f/node_modules/@visx/grid/esm/grids/GridRows.js +0 -79
  295. package/dist/node_modules/.bun/@visx_grid@3.12.0_f4eacebf2041cd4f/node_modules/@visx/grid/esm/utils/getScaleBandwidth.js +0 -6
  296. package/dist/node_modules/.bun/@visx_group@3.12.0_f4eacebf2041cd4f/node_modules/@visx/group/esm/Group.js +0 -50
  297. package/dist/node_modules/.bun/@visx_point@3.12.0/node_modules/@visx/point/esm/Point.js +0 -18
  298. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/coerceNumber.js +0 -10
  299. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/getTicks.js +0 -9
  300. package/dist/node_modules/.bun/@visx_scale@3.12.0/node_modules/@visx/scale/esm/utils/toString.js +0 -6
  301. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/shapes/Line.js +0 -47
  302. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/shapes/LinePath.js +0 -50
  303. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/util/D3ShapeFactories.js +0 -9
  304. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/esm/util/setNumberOrNumberAccessor.js +0 -6
  305. package/dist/node_modules/.bun/@visx_shape@3.12.0_f4eacebf2041cd4f/node_modules/@visx/shape/lib/shapes/Line.js +0 -53
  306. package/dist/node_modules/.bun/@visx_text@3.12.0_f4eacebf2041cd4f/node_modules/@visx/text/esm/Text.js +0 -57
  307. package/dist/node_modules/.bun/@visx_text@3.12.0_f4eacebf2041cd4f/node_modules/@visx/text/esm/hooks/useText.js +0 -91
  308. package/dist/node_modules/.bun/@visx_text@3.12.0_f4eacebf2041cd4f/node_modules/@visx/text/esm/util/getStringWidth.js +0 -21
  309. package/dist/node_modules/.bun/balanced-match@0.4.2/node_modules/balanced-match/index.js +0 -32
  310. package/dist/node_modules/.bun/balanced-match@1.0.2/node_modules/balanced-match/index.js +0 -33
  311. package/dist/node_modules/.bun/classnames@2.5.1/node_modules/classnames/index.js +0 -32
  312. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +0 -16
  313. package/dist/node_modules/.bun/invariant@2.2.4/node_modules/invariant/browser.js +0 -28
  314. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_Hash.js +0 -21
  315. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_ListCache.js +0 -21
  316. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_Map.js +0 -10
  317. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_MapCache.js +0 -21
  318. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_Symbol.js +0 -9
  319. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_assocIndexOf.js +0 -14
  320. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_baseGetTag.js +0 -15
  321. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_baseIsNative.js +0 -16
  322. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_coreJsData.js +0 -9
  323. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_freeGlobal.js +0 -8
  324. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_getMapData.js +0 -14
  325. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_getNative.js +0 -15
  326. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_getRawTag.js +0 -19
  327. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_getValue.js +0 -11
  328. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_hashClear.js +0 -13
  329. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_hashDelete.js +0 -12
  330. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_hashGet.js +0 -18
  331. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_hashHas.js +0 -14
  332. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_hashSet.js +0 -14
  333. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_isKeyable.js +0 -12
  334. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_isMasked.js +0 -16
  335. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_listCacheClear.js +0 -11
  336. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_listCacheDelete.js +0 -14
  337. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_listCacheGet.js +0 -14
  338. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_listCacheHas.js +0 -13
  339. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_listCacheSet.js +0 -14
  340. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_mapCacheClear.js +0 -19
  341. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_mapCacheDelete.js +0 -14
  342. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_mapCacheGet.js +0 -13
  343. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_mapCacheHas.js +0 -13
  344. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_mapCacheSet.js +0 -14
  345. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_nativeCreate.js +0 -9
  346. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_objectToString.js +0 -12
  347. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_root.js +0 -10
  348. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/_toSource.js +0 -20
  349. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/eq.js +0 -11
  350. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/isFunction.js +0 -16
  351. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/isObject.js +0 -12
  352. package/dist/node_modules/.bun/lodash@4.17.21/node_modules/lodash/memoize.js +0 -20
  353. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/formula_evaluator.js +0 -37
  354. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/lexer.js +0 -509
  355. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/math_function.js +0 -108
  356. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix.js +0 -31
  357. package/dist/node_modules/.bun/math-expression-evaluator@1.4.0/node_modules/math-expression-evaluator/src/postfix_evaluator.js +0 -45
  358. package/dist/node_modules/.bun/react-redux@9.3.0_9e2203c65d1d5fa1/node_modules/react-redux/dist/react-redux.js +0 -471
  359. package/dist/node_modules/.bun/reduce-css-calc@1.3.0/node_modules/reduce-css-calc/index.js +0 -49
  360. package/dist/node_modules/.bun/reduce-function-call@1.0.3/node_modules/reduce-function-call/index.js +0 -34
  361. package/dist/node_modules/.bun/redux-undo@1.1.0/node_modules/redux-undo/dist/redux-undo.js +0 -185
  362. package/dist/node_modules/.bun/redux@5.0.1/node_modules/redux/dist/redux.js +0 -198
  363. package/dist/node_modules/.bun/use-sync-external-store@1.6.0_f4eacebf2041cd4f/node_modules/use-sync-external-store/cjs/use-sync-external-store-with-selector.development.js +0 -53
  364. package/dist/node_modules/.bun/use-sync-external-store@1.6.0_f4eacebf2041cd4f/node_modules/use-sync-external-store/cjs/use-sync-external-store-with-selector.production.js +0 -51
  365. package/dist/node_modules/.bun/use-sync-external-store@1.6.0_f4eacebf2041cd4f/node_modules/use-sync-external-store/with-selector.js +0 -10
  366. package/dist/toggle-bar.d.ts +0 -40
  367. package/dist/toggle-bar.js +0 -155
  368. package/dist/tool-menu.d.ts +0 -29
  369. package/dist/tool-menu.js +0 -41
  370. package/dist/tools/absolute/component.d.ts +0 -16
  371. package/dist/tools/absolute/component.js +0 -15
  372. package/dist/tools/absolute/index.d.ts +0 -20
  373. package/dist/tools/absolute/index.js +0 -32
  374. package/dist/tools/circle/bg-circle.d.ts +0 -116
  375. package/dist/tools/circle/bg-circle.js +0 -72
  376. package/dist/tools/circle/component.d.ts +0 -83
  377. package/dist/tools/circle/component.js +0 -195
  378. package/dist/tools/circle/index.d.ts +0 -20
  379. package/dist/tools/circle/index.js +0 -22
  380. package/dist/tools/exponential/component.d.ts +0 -16
  381. package/dist/tools/exponential/component.js +0 -14
  382. package/dist/tools/exponential/index.d.ts +0 -20
  383. package/dist/tools/exponential/index.js +0 -32
  384. package/dist/tools/index.d.ts +0 -27
  385. package/dist/tools/index.js +0 -55
  386. package/dist/tools/line/component.d.ts +0 -124
  387. package/dist/tools/line/component.js +0 -72
  388. package/dist/tools/line/index.d.ts +0 -13
  389. package/dist/tools/line/index.js +0 -6
  390. package/dist/tools/parabola/component.d.ts +0 -16
  391. package/dist/tools/parabola/component.js +0 -14
  392. package/dist/tools/parabola/index.d.ts +0 -20
  393. package/dist/tools/parabola/index.js +0 -32
  394. package/dist/tools/point/component.d.ts +0 -50
  395. package/dist/tools/point/component.js +0 -85
  396. package/dist/tools/point/index.d.ts +0 -15
  397. package/dist/tools/point/index.js +0 -13
  398. package/dist/tools/polygon/component.d.ts +0 -120
  399. package/dist/tools/polygon/component.js +0 -262
  400. package/dist/tools/polygon/index.d.ts +0 -19
  401. package/dist/tools/polygon/index.js +0 -55
  402. package/dist/tools/polygon/line.d.ts +0 -125
  403. package/dist/tools/polygon/line.js +0 -63
  404. package/dist/tools/polygon/polygon.d.ts +0 -122
  405. package/dist/tools/polygon/polygon.js +0 -74
  406. package/dist/tools/ray/component.d.ts +0 -101
  407. package/dist/tools/ray/component.js +0 -71
  408. package/dist/tools/ray/index.d.ts +0 -13
  409. package/dist/tools/ray/index.js +0 -6
  410. package/dist/tools/segment/component.d.ts +0 -100
  411. package/dist/tools/segment/component.js +0 -52
  412. package/dist/tools/segment/index.d.ts +0 -13
  413. package/dist/tools/segment/index.js +0 -6
  414. package/dist/tools/shared/arrow-head.d.ts +0 -51
  415. package/dist/tools/shared/arrow-head.js +0 -63
  416. package/dist/tools/shared/icons/CorrectSVG.d.ts +0 -26
  417. package/dist/tools/shared/icons/CorrectSVG.js +0 -29
  418. package/dist/tools/shared/icons/IncorrectSVG.d.ts +0 -26
  419. package/dist/tools/shared/icons/IncorrectSVG.js +0 -27
  420. package/dist/tools/shared/icons/MissingSVG.d.ts +0 -26
  421. package/dist/tools/shared/icons/MissingSVG.js +0 -28
  422. package/dist/tools/shared/line/index.d.ts +0 -245
  423. package/dist/tools/shared/line/index.js +0 -319
  424. package/dist/tools/shared/line/line-path.d.ts +0 -57
  425. package/dist/tools/shared/line/line-path.js +0 -71
  426. package/dist/tools/shared/line/with-root-edge.d.ts +0 -142
  427. package/dist/tools/shared/line/with-root-edge.js +0 -73
  428. package/dist/tools/shared/point/arrow-point.d.ts +0 -56
  429. package/dist/tools/shared/point/arrow-point.js +0 -41
  430. package/dist/tools/shared/point/arrow.d.ts +0 -45
  431. package/dist/tools/shared/point/arrow.js +0 -35
  432. package/dist/tools/shared/point/base-point.d.ts +0 -52
  433. package/dist/tools/shared/point/base-point.js +0 -103
  434. package/dist/tools/shared/point/index.d.ts +0 -216
  435. package/dist/tools/shared/point/index.js +0 -45
  436. package/dist/tools/shared/styles.d.ts +0 -29
  437. package/dist/tools/shared/styles.js +0 -20
  438. package/dist/tools/shared/types.d.ts +0 -21
  439. package/dist/tools/shared/types.js +0 -11
  440. package/dist/tools/sine/component.d.ts +0 -16
  441. package/dist/tools/sine/component.js +0 -22
  442. package/dist/tools/sine/index.d.ts +0 -20
  443. package/dist/tools/sine/index.js +0 -32
  444. package/dist/tools/vector/component.d.ts +0 -100
  445. package/dist/tools/vector/component.js +0 -44
  446. package/dist/tools/vector/index.d.ts +0 -13
  447. package/dist/tools/vector/index.js +0 -6
  448. package/dist/undo-redo.d.ts +0 -22
  449. package/dist/undo-redo.js +0 -47
  450. package/dist/use-debounce.d.ts +0 -9
  451. package/dist/use-debounce.js +0 -13
  452. package/dist/utils.d.ts +0 -61
  453. package/dist/utils.js +0 -75
@@ -0,0 +1,319 @@
1
+ import React from 'react';
2
+ import { render, waitFor } from '@pie-lib/test-utils';
3
+ import Root, { GraphContainer } from '../index';
4
+ import { changeMarks } from '../actions';
5
+
6
+ jest.mock('../../graph-with-controls', () => {
7
+ return function GraphWithControls({ marks, onChangeMarks, onUndo, onRedo, onReset, disabled }) {
8
+ return (
9
+ <div data-testid="graph-with-controls">
10
+ <div data-testid="marks-count">{marks?.length || 0}</div>
11
+ {disabled && <div data-testid="disabled-indicator">Disabled</div>}
12
+ <button data-testid="change-marks" onClick={() => onChangeMarks && onChangeMarks([{ id: 1 }])}>
13
+ Change
14
+ </button>
15
+ <button data-testid="undo" onClick={onUndo}>
16
+ Undo
17
+ </button>
18
+ <button data-testid="redo" onClick={onRedo}>
19
+ Redo
20
+ </button>
21
+ <button data-testid="reset" onClick={onReset}>
22
+ Reset
23
+ </button>
24
+ </div>
25
+ );
26
+ };
27
+ });
28
+
29
+ jest.mock('@pie-lib/drag', () => ({
30
+ DragProvider: ({ children }) => <div data-testid="drag-provider">{children}</div>,
31
+ }));
32
+
33
+ describe('Container Root Component', () => {
34
+ const defaultProps = {
35
+ marks: [],
36
+ onChangeMarks: jest.fn(),
37
+ };
38
+
39
+ const renderComponent = (props = {}) => {
40
+ return render(<Root {...defaultProps} {...props} />);
41
+ };
42
+
43
+ describe('rendering', () => {
44
+ it('renders without crashing', () => {
45
+ const { container } = renderComponent();
46
+ expect(container).toBeInTheDocument();
47
+ });
48
+
49
+ it('renders GraphWithControls', () => {
50
+ const { getByTestId } = renderComponent();
51
+ expect(getByTestId('graph-with-controls')).toBeInTheDocument();
52
+ });
53
+
54
+ it('renders with Provider when no correctness set', () => {
55
+ const { container } = renderComponent({ marks: [{ id: 1, type: 'point' }] });
56
+ expect(container.querySelector('[data-testid="graph-with-controls"]')).toBeInTheDocument();
57
+ });
58
+
59
+ it('renders directly when correctness is set', () => {
60
+ const marks = [{ id: 1, type: 'point', correctness: { value: 'correct' } }];
61
+ const { getByTestId } = renderComponent({ marks });
62
+
63
+ expect(getByTestId('graph-with-controls')).toBeInTheDocument();
64
+ expect(getByTestId('disabled-indicator')).toBeInTheDocument();
65
+ });
66
+
67
+ it('passes marks to GraphWithControls', () => {
68
+ const marks = [{ id: 1 }, { id: 2 }];
69
+ const { getByTestId } = renderComponent({ marks });
70
+ expect(getByTestId('marks-count')).toHaveTextContent('2');
71
+ });
72
+ });
73
+
74
+ describe('Redux store', () => {
75
+ it('creates Redux store on mount', () => {
76
+ const component = new Root({ marks: [], onChangeMarks: jest.fn() });
77
+ expect(component.store).toBeDefined();
78
+ expect(typeof component.store.getState).toBe('function');
79
+ expect(typeof component.store.dispatch).toBe('function');
80
+ });
81
+
82
+ it('initializes store with marks from props', () => {
83
+ const marks = [{ id: 1, type: 'point' }];
84
+ const component = new Root({ marks, onChangeMarks: jest.fn() });
85
+
86
+ const state = component.store.getState();
87
+ expect(state.marks.present).toEqual(marks);
88
+ });
89
+
90
+ it('initializes store with empty marks', () => {
91
+ const component = new Root({ marks: [], onChangeMarks: jest.fn() });
92
+
93
+ const state = component.store.getState();
94
+ expect(state.marks.present).toEqual([]);
95
+ });
96
+
97
+ it('subscribes to store changes', async () => {
98
+ const onChangeMarks = jest.fn();
99
+ const component = new Root({ marks: [], onChangeMarks });
100
+
101
+ const newMarks = [{ id: 1 }];
102
+ component.store.dispatch(changeMarks(newMarks));
103
+
104
+ await waitFor(() => {
105
+ expect(onChangeMarks).toHaveBeenCalledWith(newMarks);
106
+ });
107
+ });
108
+ });
109
+
110
+ describe('componentDidUpdate', () => {
111
+ it('updates store when marks prop changes', () => {
112
+ const onChangeMarks = jest.fn();
113
+ const { rerender } = render(<Root marks={[]} onChangeMarks={onChangeMarks} />);
114
+
115
+ const newMarks = [{ id: 1, type: 'point' }];
116
+ rerender(<Root marks={newMarks} onChangeMarks={onChangeMarks} />);
117
+
118
+ expect(onChangeMarks).not.toHaveBeenCalled();
119
+ });
120
+
121
+ it('does not update when marks are equal', () => {
122
+ const marks = [{ id: 1, type: 'point' }];
123
+ const onChangeMarks = jest.fn();
124
+ const { rerender } = render(<Root marks={marks} onChangeMarks={onChangeMarks} />);
125
+
126
+ onChangeMarks.mockClear();
127
+
128
+ rerender(<Root marks={marks} onChangeMarks={onChangeMarks} />);
129
+
130
+ expect(onChangeMarks).not.toHaveBeenCalled();
131
+ });
132
+
133
+ it('handles marks changing from empty to non-empty', () => {
134
+ const onChangeMarks = jest.fn();
135
+ const { rerender } = render(<Root marks={[]} onChangeMarks={onChangeMarks} />);
136
+
137
+ const newMarks = [{ id: 1 }];
138
+
139
+ expect(() => {
140
+ rerender(<Root marks={newMarks} onChangeMarks={onChangeMarks} />);
141
+ }).not.toThrow();
142
+ });
143
+
144
+ it('handles marks changing from non-empty to empty', () => {
145
+ const onChangeMarks = jest.fn();
146
+ const { rerender } = render(<Root marks={[{ id: 1 }]} onChangeMarks={onChangeMarks} />);
147
+
148
+ expect(() => {
149
+ rerender(<Root marks={[]} onChangeMarks={onChangeMarks} />);
150
+ }).not.toThrow();
151
+ });
152
+ });
153
+
154
+ describe('onStoreChange', () => {
155
+ it('calls onChangeMarks when store state changes', async () => {
156
+ const onChangeMarks = jest.fn();
157
+ const component = new Root({ marks: [], onChangeMarks });
158
+
159
+ const newMarks = [{ id: 1, type: 'point' }];
160
+ component.store.dispatch(changeMarks(newMarks));
161
+
162
+ await waitFor(() => {
163
+ expect(onChangeMarks).toHaveBeenCalledWith(newMarks);
164
+ });
165
+ });
166
+
167
+ it('does not call onChangeMarks when marks are equal', () => {
168
+ const marks = [{ id: 1, type: 'point' }];
169
+ const onChangeMarks = jest.fn();
170
+ const component = new Root({ marks, onChangeMarks });
171
+
172
+ onChangeMarks.mockClear();
173
+
174
+ component.store.dispatch(changeMarks(marks));
175
+
176
+ expect(onChangeMarks).not.toHaveBeenCalled();
177
+ });
178
+
179
+ it('handles multiple store changes', async () => {
180
+ const onChangeMarks = jest.fn();
181
+ const component = new Root({ marks: [], onChangeMarks });
182
+
183
+ component.store.dispatch(changeMarks([{ id: 1 }]));
184
+ component.store.dispatch(changeMarks([{ id: 2 }]));
185
+ component.store.dispatch(changeMarks([{ id: 3 }]));
186
+
187
+ await waitFor(() => {
188
+ expect(onChangeMarks).toHaveBeenCalledTimes(3);
189
+ });
190
+ });
191
+ });
192
+
193
+ describe('correctness handling', () => {
194
+ it('disables when any mark has correctness', () => {
195
+ const marks = [
196
+ { id: 1, type: 'point' },
197
+ { id: 2, type: 'point', correctness: { value: 'correct' } },
198
+ ];
199
+ const { getByTestId } = renderComponent({ marks });
200
+
201
+ expect(getByTestId('disabled-indicator')).toBeInTheDocument();
202
+ });
203
+
204
+ it('renders without Provider when correctness is set', () => {
205
+ const marks = [{ id: 1, correctness: { value: 'correct' } }];
206
+ const { container } = renderComponent({ marks });
207
+
208
+ expect(container.querySelector('[data-testid="graph-with-controls"]')).toBeInTheDocument();
209
+ });
210
+
211
+ it('does not disable when no correctness is set', () => {
212
+ const marks = [
213
+ { id: 1, type: 'point' },
214
+ { id: 2, type: 'line' },
215
+ ];
216
+ const { queryByTestId } = renderComponent({ marks });
217
+
218
+ expect(queryByTestId('disabled-indicator')).not.toBeInTheDocument();
219
+ });
220
+
221
+ it('handles correctness with different values', () => {
222
+ const marks = [{ id: 1, correctness: { value: 'incorrect' } }];
223
+ const { getByTestId } = renderComponent({ marks });
224
+
225
+ expect(getByTestId('disabled-indicator')).toBeInTheDocument();
226
+ });
227
+
228
+ it('handles empty correctness object', () => {
229
+ const marks = [{ id: 1, correctness: {} }];
230
+ const { getByTestId } = renderComponent({ marks });
231
+
232
+ expect(getByTestId('disabled-indicator')).toBeInTheDocument();
233
+ });
234
+ });
235
+
236
+ describe('props forwarding', () => {
237
+ it('forwards additional props to GraphWithControls', () => {
238
+ const { container } = renderComponent({
239
+ className: 'custom-class',
240
+ size: { width: 500, height: 500 },
241
+ });
242
+
243
+ expect(container.querySelector('[data-testid="graph-with-controls"]')).toBeInTheDocument();
244
+ });
245
+
246
+ it('does not forward onChangeMarks and marks to GraphWithControls', () => {
247
+ const { getByTestId } = renderComponent({
248
+ marks: [{ id: 1 }],
249
+ onChangeMarks: jest.fn(),
250
+ otherProp: 'test',
251
+ });
252
+
253
+ expect(getByTestId('graph-with-controls')).toBeInTheDocument();
254
+ });
255
+ });
256
+
257
+ describe('edge cases', () => {
258
+ it('handles empty marks array', () => {
259
+ const { container } = renderComponent({ marks: [] });
260
+ expect(container).toBeInTheDocument();
261
+ });
262
+
263
+ it('handles marks with complex structure', () => {
264
+ const marks = [
265
+ {
266
+ id: 1,
267
+ type: 'line',
268
+ from: { x: 0, y: 0 },
269
+ to: { x: 10, y: 10 },
270
+ label: 'Line A',
271
+ correctness: { value: 'correct', label: 'Correct!' },
272
+ },
273
+ ];
274
+ const { getByTestId } = renderComponent({ marks });
275
+ expect(getByTestId('graph-with-controls')).toBeInTheDocument();
276
+ });
277
+
278
+ it('handles switching between correctness states', () => {
279
+ const { rerender } = render(<Root marks={[{ id: 1 }]} onChangeMarks={jest.fn()} />);
280
+
281
+ rerender(<Root marks={[{ id: 1, correctness: { value: 'correct' } }]} onChangeMarks={jest.fn()} />);
282
+
283
+ rerender(<Root marks={[{ id: 1 }]} onChangeMarks={jest.fn()} />);
284
+
285
+ expect(document.querySelector('[data-testid="graph-with-controls"]')).toBeInTheDocument();
286
+ });
287
+ });
288
+
289
+ describe('store synchronization', () => {
290
+ it('keeps store and props in sync', async () => {
291
+ const onChangeMarks = jest.fn();
292
+ const component = new Root({ marks: [], onChangeMarks });
293
+
294
+ const newMarks = [{ id: 1 }];
295
+ component.store.dispatch(changeMarks(newMarks));
296
+
297
+ await waitFor(() => {
298
+ const state = component.store.getState();
299
+ expect(state.marks.present).toEqual(newMarks);
300
+ expect(onChangeMarks).toHaveBeenCalledWith(newMarks);
301
+ });
302
+ });
303
+ });
304
+ });
305
+
306
+ describe('GraphContainer (connected component)', () => {
307
+ it('is a connected component', () => {
308
+ expect(GraphContainer).toBeDefined();
309
+ expect(GraphContainer.displayName).toContain('Connect');
310
+ });
311
+
312
+ it('maps state to props', () => {
313
+ expect(GraphContainer).toBeDefined();
314
+ });
315
+
316
+ it('maps dispatch to props', () => {
317
+ expect(GraphContainer).toBeDefined();
318
+ });
319
+ });
@@ -0,0 +1,172 @@
1
+ import marks from '../marks';
2
+
3
+ describe('marks reducer', () => {
4
+ describe('initial state', () => {
5
+ it('returns empty array as initial state', () => {
6
+ const state = marks(undefined, { type: 'INIT' });
7
+ expect(state).toEqual([]);
8
+ });
9
+
10
+ it('handles no state parameter', () => {
11
+ const state = marks(undefined, { type: 'UNKNOWN_ACTION' });
12
+ expect(Array.isArray(state)).toBe(true);
13
+ });
14
+ });
15
+
16
+ describe('CHANGE_MARKS action', () => {
17
+ it('updates state with new marks', () => {
18
+ const initialState = [];
19
+ const newMarks = [{ id: 1, type: 'point' }];
20
+ const action = { type: 'CHANGE_MARKS', marks: newMarks };
21
+
22
+ const state = marks(initialState, action);
23
+ expect(state).toEqual(newMarks);
24
+ });
25
+
26
+ it('replaces existing marks', () => {
27
+ const initialState = [{ id: 1, type: 'point' }];
28
+ const newMarks = [{ id: 2, type: 'line' }];
29
+ const action = { type: 'CHANGE_MARKS', marks: newMarks };
30
+
31
+ const state = marks(initialState, action);
32
+ expect(state).toEqual(newMarks);
33
+ expect(state.length).toBe(1);
34
+ expect(state[0].id).toBe(2);
35
+ });
36
+
37
+ it('handles empty marks array', () => {
38
+ const initialState = [{ id: 1, type: 'point' }];
39
+ const action = { type: 'CHANGE_MARKS', marks: [] };
40
+
41
+ const state = marks(initialState, action);
42
+ expect(state).toEqual([]);
43
+ });
44
+
45
+ it('handles multiple marks', () => {
46
+ const initialState = [];
47
+ const newMarks = [
48
+ { id: 1, type: 'point', x: 1, y: 2 },
49
+ { id: 2, type: 'line', from: { x: 0, y: 0 }, to: { x: 5, y: 5 } },
50
+ { id: 3, type: 'circle', center: { x: 3, y: 3 }, radius: 2 },
51
+ ];
52
+ const action = { type: 'CHANGE_MARKS', marks: newMarks };
53
+
54
+ const state = marks(initialState, action);
55
+ expect(state).toEqual(newMarks);
56
+ expect(state.length).toBe(3);
57
+ });
58
+
59
+ it('throws error when marks is not an array', () => {
60
+ const initialState = [];
61
+ const action = { type: 'CHANGE_MARKS', marks: 'not an array' };
62
+
63
+ expect(() => marks(initialState, action)).toThrow('marks must be an array');
64
+ });
65
+
66
+ it('throws error when marks is null', () => {
67
+ const initialState = [];
68
+ const action = { type: 'CHANGE_MARKS', marks: null };
69
+
70
+ expect(() => marks(initialState, action)).toThrow('marks must be an array');
71
+ });
72
+
73
+ it('throws error when marks is undefined', () => {
74
+ const initialState = [];
75
+ const action = { type: 'CHANGE_MARKS', marks: undefined };
76
+
77
+ expect(() => marks(initialState, action)).toThrow('marks must be an array');
78
+ });
79
+
80
+ it('throws error when marks is an object', () => {
81
+ const initialState = [];
82
+ const action = { type: 'CHANGE_MARKS', marks: { id: 1 } };
83
+
84
+ expect(() => marks(initialState, action)).toThrow('marks must be an array');
85
+ });
86
+
87
+ it('throws error when marks is a number', () => {
88
+ const initialState = [];
89
+ const action = { type: 'CHANGE_MARKS', marks: 123 };
90
+
91
+ expect(() => marks(initialState, action)).toThrow('marks must be an array');
92
+ });
93
+
94
+ it('preserves mark properties', () => {
95
+ const initialState = [];
96
+ const newMarks = [
97
+ {
98
+ id: 1,
99
+ type: 'point',
100
+ x: 10,
101
+ y: 20,
102
+ label: 'A',
103
+ correctness: { value: 'correct' },
104
+ editable: true,
105
+ interactive: true,
106
+ },
107
+ ];
108
+ const action = { type: 'CHANGE_MARKS', marks: newMarks };
109
+
110
+ const state = marks(initialState, action);
111
+ expect(state[0]).toEqual(newMarks[0]);
112
+ expect(state[0].correctness).toBeDefined();
113
+ expect(state[0].editable).toBe(true);
114
+ });
115
+ });
116
+
117
+ describe('unknown actions', () => {
118
+ it('returns current state for unknown action', () => {
119
+ const initialState = [{ id: 1, type: 'point' }];
120
+ const action = { type: 'UNKNOWN_ACTION' };
121
+
122
+ const state = marks(initialState, action);
123
+ expect(state).toBe(initialState);
124
+ });
125
+
126
+ it('returns current state for ADD_MARK action', () => {
127
+ const initialState = [{ id: 1, type: 'point' }];
128
+ const action = { type: 'ADD_MARK' };
129
+
130
+ const state = marks(initialState, action);
131
+ expect(state).toBe(initialState);
132
+ });
133
+
134
+ it('does not modify state for unknown actions', () => {
135
+ const initialState = [{ id: 1, type: 'point' }];
136
+ const action = { type: 'SOME_OTHER_ACTION', data: 'test' };
137
+
138
+ const state = marks(initialState, action);
139
+ expect(state).toEqual(initialState);
140
+ });
141
+ });
142
+
143
+ describe('immutability', () => {
144
+ it('does not mutate original state', () => {
145
+ const initialState = [{ id: 1, type: 'point' }];
146
+ const originalState = [...initialState];
147
+ const newMarks = [{ id: 2, type: 'line' }];
148
+ const action = { type: 'CHANGE_MARKS', marks: newMarks };
149
+
150
+ marks(initialState, action);
151
+ expect(initialState).toEqual(originalState);
152
+ });
153
+
154
+ it('returns new array reference for CHANGE_MARKS', () => {
155
+ const initialState = [{ id: 1, type: 'point' }];
156
+ const newMarks = [{ id: 1, type: 'point' }];
157
+ const action = { type: 'CHANGE_MARKS', marks: newMarks };
158
+
159
+ const state = marks(initialState, action);
160
+ expect(state).not.toBe(initialState);
161
+ expect(state).toBe(newMarks);
162
+ });
163
+
164
+ it('returns same reference for unknown actions', () => {
165
+ const initialState = [{ id: 1, type: 'point' }];
166
+ const action = { type: 'UNKNOWN_ACTION' };
167
+
168
+ const state = marks(initialState, action);
169
+ expect(state).toBe(initialState);
170
+ });
171
+ });
172
+ });