@agent-canvas/cli 0.8.0 → 0.9.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 (199) hide show
  1. package/dist/commands/__tests__/add-arrow.test.d.ts +1 -0
  2. package/dist/commands/__tests__/add-arrow.test.js +186 -0
  3. package/dist/commands/__tests__/add-image.test.d.ts +1 -0
  4. package/dist/commands/__tests__/add-image.test.js +170 -0
  5. package/dist/commands/__tests__/add-line.test.d.ts +1 -0
  6. package/dist/commands/__tests__/add-line.test.js +138 -0
  7. package/dist/commands/__tests__/add-polygon.test.d.ts +1 -0
  8. package/dist/commands/__tests__/add-polygon.test.js +147 -0
  9. package/dist/commands/__tests__/add-shape.test.d.ts +1 -0
  10. package/dist/commands/__tests__/add-shape.test.js +193 -0
  11. package/dist/commands/__tests__/add-text.test.d.ts +1 -0
  12. package/dist/commands/__tests__/add-text.test.js +144 -0
  13. package/dist/commands/__tests__/clear.test.d.ts +1 -0
  14. package/dist/commands/__tests__/clear.test.js +65 -0
  15. package/dist/commands/__tests__/delete-elements.test.d.ts +1 -0
  16. package/dist/commands/__tests__/delete-elements.test.js +103 -0
  17. package/dist/commands/__tests__/export.test.d.ts +1 -0
  18. package/dist/commands/__tests__/export.test.js +187 -0
  19. package/dist/commands/__tests__/group-elements.test.d.ts +1 -0
  20. package/dist/commands/__tests__/group-elements.test.js +93 -0
  21. package/dist/commands/__tests__/list.test.d.ts +1 -0
  22. package/dist/commands/__tests__/list.test.js +134 -0
  23. package/dist/commands/__tests__/load.test.d.ts +1 -0
  24. package/dist/commands/__tests__/load.test.js +158 -0
  25. package/dist/commands/__tests__/move-elements.test.d.ts +1 -0
  26. package/dist/commands/__tests__/move-elements.test.js +117 -0
  27. package/dist/commands/__tests__/new-canvas.test.d.ts +1 -0
  28. package/dist/commands/__tests__/new-canvas.test.js +113 -0
  29. package/dist/commands/__tests__/read.test.d.ts +1 -0
  30. package/dist/commands/__tests__/read.test.js +247 -0
  31. package/dist/commands/__tests__/rename-canvas.test.d.ts +1 -0
  32. package/dist/commands/__tests__/rename-canvas.test.js +86 -0
  33. package/dist/commands/__tests__/resize-elements.test.d.ts +1 -0
  34. package/dist/commands/__tests__/resize-elements.test.js +150 -0
  35. package/dist/commands/__tests__/rotate-elements.test.d.ts +1 -0
  36. package/dist/commands/__tests__/rotate-elements.test.js +114 -0
  37. package/dist/commands/__tests__/save.test.d.ts +1 -0
  38. package/dist/commands/__tests__/save.test.js +105 -0
  39. package/dist/commands/__tests__/ungroup-element.test.d.ts +1 -0
  40. package/dist/commands/__tests__/ungroup-element.test.js +93 -0
  41. package/dist/commands/__tests__/use-canvas.test.d.ts +1 -0
  42. package/dist/commands/__tests__/use-canvas.test.js +86 -0
  43. package/dist/commands/add-arrow.d.ts +40 -0
  44. package/dist/commands/add-arrow.js +52 -0
  45. package/dist/commands/add-image.d.ts +26 -0
  46. package/dist/commands/add-image.js +66 -0
  47. package/dist/commands/add-line.d.ts +27 -0
  48. package/dist/commands/add-line.js +35 -0
  49. package/dist/commands/add-polygon.d.ts +26 -0
  50. package/dist/commands/add-polygon.js +44 -0
  51. package/dist/commands/add-shape.d.ts +32 -0
  52. package/dist/commands/add-shape.js +41 -0
  53. package/dist/commands/add-text.d.ts +28 -0
  54. package/dist/commands/add-text.js +35 -0
  55. package/dist/commands/clear.d.ts +17 -0
  56. package/dist/commands/clear.js +23 -0
  57. package/dist/commands/delete-elements.d.ts +20 -0
  58. package/dist/commands/delete-elements.js +26 -0
  59. package/dist/commands/export.d.ts +26 -0
  60. package/dist/commands/export.js +45 -0
  61. package/dist/commands/group-elements.d.ts +20 -0
  62. package/dist/commands/group-elements.js +28 -0
  63. package/dist/commands/list.d.ts +23 -0
  64. package/dist/commands/list.js +50 -0
  65. package/dist/commands/load.d.ts +20 -0
  66. package/dist/commands/load.js +67 -0
  67. package/dist/commands/move-elements.d.ts +22 -0
  68. package/dist/commands/move-elements.js +26 -0
  69. package/dist/commands/new-canvas.d.ts +21 -0
  70. package/dist/commands/new-canvas.js +29 -0
  71. package/dist/commands/read.d.ts +23 -0
  72. package/dist/commands/read.js +49 -0
  73. package/dist/commands/rename-canvas.d.ts +20 -0
  74. package/dist/commands/rename-canvas.js +27 -0
  75. package/dist/commands/resize-elements.d.ts +24 -0
  76. package/dist/commands/resize-elements.js +41 -0
  77. package/dist/commands/rotate-elements.d.ts +21 -0
  78. package/dist/commands/rotate-elements.js +26 -0
  79. package/dist/commands/save.d.ts +18 -0
  80. package/dist/commands/save.js +27 -0
  81. package/dist/commands/start.d.ts +0 -1
  82. package/dist/commands/start.js +0 -41
  83. package/dist/commands/ungroup-element.d.ts +20 -0
  84. package/dist/commands/ungroup-element.js +28 -0
  85. package/dist/commands/use-canvas.d.ts +20 -0
  86. package/dist/commands/use-canvas.js +27 -0
  87. package/dist/index.js +124 -518
  88. package/dist/lib/__tests__/image-utils.test.d.ts +1 -0
  89. package/dist/lib/__tests__/image-utils.test.js +123 -0
  90. package/dist/lib/__tests__/toon-converter.test.d.ts +1 -0
  91. package/dist/lib/__tests__/toon-converter.test.js +586 -0
  92. package/dist/lib/__tests__/ws-client.test.d.ts +1 -0
  93. package/dist/lib/__tests__/ws-client.test.js +22 -0
  94. package/dist/lib/image-utils.d.ts +3 -0
  95. package/dist/lib/image-utils.js +21 -0
  96. package/dist/lib/protocol.d.ts +24 -0
  97. package/dist/lib/toon-converter.d.ts +104 -0
  98. package/dist/lib/toon-converter.js +221 -0
  99. package/dist/static/assets/{ar-SA-G6X2FPQ2-DrFZc17I.js → ar-SA-G6X2FPQ2-DBOnFzSe.js} +1 -1
  100. package/dist/static/assets/{arc-BE4RRWho.js → arc-bbUtBUEI.js} +1 -1
  101. package/dist/static/assets/{az-AZ-76LH7QW2-DgHo0c8x.js → az-AZ-76LH7QW2-Cc10aZ9u.js} +1 -1
  102. package/dist/static/assets/{bg-BG-XCXSNQG7-D6Qfq7sN.js → bg-BG-XCXSNQG7-Ccf7m1dz.js} +1 -1
  103. package/dist/static/assets/{blockDiagram-38ab4fdb-j4QCKNBJ.js → blockDiagram-38ab4fdb-fpHXuuqC.js} +1 -1
  104. package/dist/static/assets/{bn-BD-2XOGV67Q-DtD_GeTA.js → bn-BD-2XOGV67Q-DUsn1OkS.js} +1 -1
  105. package/dist/static/assets/{c4Diagram-3d4e48cf-BmQ9mE4L.js → c4Diagram-3d4e48cf-R8YUsP4D.js} +1 -1
  106. package/dist/static/assets/{ca-ES-6MX7JW3Y-pqblEVH2.js → ca-ES-6MX7JW3Y-hu4EsJg6.js} +1 -1
  107. package/dist/static/assets/channel-DOejQ6Zr.js +1 -0
  108. package/dist/static/assets/{classDiagram-70f12bd4-CUF5vm_X.js → classDiagram-70f12bd4-Bd-nCoOe.js} +1 -1
  109. package/dist/static/assets/{classDiagram-v2-f2320105-Cpj_A_lB.js → classDiagram-v2-f2320105-BSqlF2Ya.js} +1 -1
  110. package/dist/static/assets/clone-BACvnIVb.js +1 -0
  111. package/dist/static/assets/{createText-2e5e7dd3-pnM7Sebc.js → createText-2e5e7dd3-DDxcRLmM.js} +1 -1
  112. package/dist/static/assets/{cs-CZ-2BRQDIVT-CybzkHZt.js → cs-CZ-2BRQDIVT-CvZtKTE7.js} +1 -1
  113. package/dist/static/assets/{da-DK-5WZEPLOC-pqELhXiQ.js → da-DK-5WZEPLOC-Bo6-ltfA.js} +1 -1
  114. package/dist/static/assets/{de-DE-XR44H4JA-ZL76WiIL.js → de-DE-XR44H4JA-Rki2qM_x.js} +1 -1
  115. package/dist/static/assets/{edges-e0da2a9e-B9extNmC.js → edges-e0da2a9e-DWJxCouB.js} +1 -1
  116. package/dist/static/assets/{el-GR-BZB4AONW-rKEdKItN.js → el-GR-BZB4AONW-BRy2rrt9.js} +1 -1
  117. package/dist/static/assets/{erDiagram-9861fffd-Bf-1lr9-.js → erDiagram-9861fffd-DXldiM4J.js} +1 -1
  118. package/dist/static/assets/{es-ES-U4NZUMDT-BB6riLIk.js → es-ES-U4NZUMDT-hCKbxwHs.js} +1 -1
  119. package/dist/static/assets/{eu-ES-A7QVB2H4-ChqJNrpA.js → eu-ES-A7QVB2H4-CmZGwoa5.js} +1 -1
  120. package/dist/static/assets/{fa-IR-HGAKTJCU--KEd62Xu.js → fa-IR-HGAKTJCU-C6DRPcaF.js} +1 -1
  121. package/dist/static/assets/{fi-FI-Z5N7JZ37-CdB0adCJ.js → fi-FI-Z5N7JZ37-DBaspnIB.js} +1 -1
  122. package/dist/static/assets/{flowDb-956e92f1-Dbca38tY.js → flowDb-956e92f1-C48Cmgvd.js} +1 -1
  123. package/dist/static/assets/{flowDiagram-66a62f08-DpQc0ZQB.js → flowDiagram-66a62f08-DV7f8TtG.js} +1 -1
  124. package/dist/static/assets/flowDiagram-v2-96b9c2cf-MnAxlKb6.js +1 -0
  125. package/dist/static/assets/{flowchart-elk-definition-4a651766-CAxl2EAj.js → flowchart-elk-definition-4a651766-C2muEpzy.js} +1 -1
  126. package/dist/static/assets/{fr-FR-RHASNOE6-LEJbMD3b.js → fr-FR-RHASNOE6-D1dEEEfS.js} +1 -1
  127. package/dist/static/assets/{ganttDiagram-c361ad54-BsKueDb1.js → ganttDiagram-c361ad54-CrooqCzc.js} +1 -1
  128. package/dist/static/assets/{gitGraphDiagram-72cf32ee-BySoTKcT.js → gitGraphDiagram-72cf32ee-x7BVIo_3.js} +1 -1
  129. package/dist/static/assets/{gl-ES-HMX3MZ6V-Bi3P3M7W.js → gl-ES-HMX3MZ6V-Czkw2ahx.js} +1 -1
  130. package/dist/static/assets/{graph-B_0qOa-k.js → graph-Bv0C_szp.js} +1 -1
  131. package/dist/static/assets/{he-IL-6SHJWFNN-DE7_aRwg.js → he-IL-6SHJWFNN-BLwbN3CV.js} +1 -1
  132. package/dist/static/assets/{hi-IN-IWLTKZ5I-CjARmJ8i.js → hi-IN-IWLTKZ5I-BJh3HrXc.js} +1 -1
  133. package/dist/static/assets/{hu-HU-A5ZG7DT2-d79urL5L.js → hu-HU-A5ZG7DT2-D00s-8EN.js} +1 -1
  134. package/dist/static/assets/{id-ID-SAP4L64H-bxo8Q0Jv.js → id-ID-SAP4L64H-BmyuzwXV.js} +1 -1
  135. package/dist/static/assets/{index-3862675e-BLm8h60G.js → index-3862675e-mZlepZqF.js} +1 -1
  136. package/dist/static/assets/{index-BkW4NM9R.js → index-Bnmyv9TE.js} +4 -4
  137. package/dist/static/assets/index-jjzEa4oB.js +316 -0
  138. package/dist/static/assets/{infoDiagram-f8f76790-CZ4J5sjk.js → infoDiagram-f8f76790-w7FUTsVV.js} +1 -1
  139. package/dist/static/assets/{it-IT-JPQ66NNP-D41R3uEK.js → it-IT-JPQ66NNP-CeVq0l8v.js} +1 -1
  140. package/dist/static/assets/{ja-JP-DBVTYXUO-zK8NUJnS.js → ja-JP-DBVTYXUO-BUNKxxGA.js} +1 -1
  141. package/dist/static/assets/{journeyDiagram-49397b02-DtFcZaIk.js → journeyDiagram-49397b02-DYjDqkQG.js} +1 -1
  142. package/dist/static/assets/{kaa-6HZHGXH3-CbGIc6V6.js → kaa-6HZHGXH3-BIKwULqb.js} +1 -1
  143. package/dist/static/assets/{kab-KAB-ZGHBKWFO-BweHPuX1.js → kab-KAB-ZGHBKWFO-BDpRo7IX.js} +1 -1
  144. package/dist/static/assets/{kk-KZ-P5N5QNE5-DSokMm7h.js → kk-KZ-P5N5QNE5-bI2LN3W0.js} +1 -1
  145. package/dist/static/assets/{km-KH-HSX4SM5Z-LYiEs3ge.js → km-KH-HSX4SM5Z-gtwrLJn5.js} +1 -1
  146. package/dist/static/assets/{ko-KR-MTYHY66A-BzgMEtcU.js → ko-KR-MTYHY66A-BVcwVELq.js} +1 -1
  147. package/dist/static/assets/{ku-TR-6OUDTVRD-D1FtjbSs.js → ku-TR-6OUDTVRD-COvDJH7d.js} +1 -1
  148. package/dist/static/assets/{layout-CQWIZrii.js → layout-HBWJ9_zM.js} +1 -1
  149. package/dist/static/assets/{line-BryEd-Ku.js → line-DxrK6d-_.js} +1 -1
  150. package/dist/static/assets/{linear-SXhM57Mz.js → linear-TwnxNDQ0.js} +1 -1
  151. package/dist/static/assets/{lt-LT-XHIRWOB4-BPrhIUrC.js → lt-LT-XHIRWOB4-BxYB7tM6.js} +1 -1
  152. package/dist/static/assets/{lv-LV-5QDEKY6T-CXJse_rs.js → lv-LV-5QDEKY6T-CGURbwyW.js} +1 -1
  153. package/dist/static/assets/{mindmap-definition-fc14e90a-C8giDsiX.js → mindmap-definition-fc14e90a-CWJfWF5a.js} +1 -1
  154. package/dist/static/assets/{mr-IN-CRQNXWMA-Clab-bAO.js → mr-IN-CRQNXWMA-65brZPyQ.js} +1 -1
  155. package/dist/static/assets/{my-MM-5M5IBNSE-Dp08JzEw.js → my-MM-5M5IBNSE-DaCAmQNv.js} +1 -1
  156. package/dist/static/assets/{nb-NO-T6EIAALU-CiaXJA-W.js → nb-NO-T6EIAALU-BiSJhu0W.js} +1 -1
  157. package/dist/static/assets/{nl-NL-IS3SIHDZ-D-9KUTnx.js → nl-NL-IS3SIHDZ-D3rj4Vme.js} +1 -1
  158. package/dist/static/assets/{nn-NO-6E72VCQL-Bg5gsQ4h.js → nn-NO-6E72VCQL-rxxP7Cwf.js} +1 -1
  159. package/dist/static/assets/{oc-FR-POXYY2M6-G4iqllhL.js → oc-FR-POXYY2M6-6emd2NQX.js} +1 -1
  160. package/dist/static/assets/{pa-IN-N4M65BXN-l6Lk41uX.js → pa-IN-N4M65BXN-CXwT_z_m.js} +1 -1
  161. package/dist/static/assets/{pica-CtkejCRD.js → pica-CtyIOuSv.js} +1 -1
  162. package/dist/static/assets/{pieDiagram-8a3498a8-CG6gQ14H.js → pieDiagram-8a3498a8-Ccff4vHz.js} +1 -1
  163. package/dist/static/assets/{pl-PL-T2D74RX3-BZPbB8S3.js → pl-PL-T2D74RX3-DMx_ZmIC.js} +1 -1
  164. package/dist/static/assets/{pt-BR-5N22H2LF-CIC4vRyd.js → pt-BR-5N22H2LF-D9nz7afr.js} +1 -1
  165. package/dist/static/assets/{pt-PT-UZXXM6DQ-rkGTBEI0.js → pt-PT-UZXXM6DQ-DeFH3geX.js} +1 -1
  166. package/dist/static/assets/{quadrantDiagram-120e2f19-BL9eFu4M.js → quadrantDiagram-120e2f19-RF2ZGF1U.js} +1 -1
  167. package/dist/static/assets/{requirementDiagram-deff3bca-crxdUpVK.js → requirementDiagram-deff3bca-CvnD9QLg.js} +1 -1
  168. package/dist/static/assets/{ro-RO-JPDTUUEW-GDhpTKBO.js → ro-RO-JPDTUUEW-Cy22QAjW.js} +1 -1
  169. package/dist/static/assets/{ru-RU-B4JR7IUQ-BzHvMwjC.js → ru-RU-B4JR7IUQ-Cw2rH2nW.js} +1 -1
  170. package/dist/static/assets/{sankeyDiagram-04a897e0-bM05WQw3.js → sankeyDiagram-04a897e0-CWfRjMv0.js} +1 -1
  171. package/dist/static/assets/{sequenceDiagram-704730f1-DjknV0Qp.js → sequenceDiagram-704730f1-pAE8N_Ym.js} +1 -1
  172. package/dist/static/assets/{si-LK-N5RQ5JYF-D3P3TNDH.js → si-LK-N5RQ5JYF-DmXIZ3i0.js} +1 -1
  173. package/dist/static/assets/{sk-SK-C5VTKIMK-CM8yTXlZ.js → sk-SK-C5VTKIMK-CboHDpHd.js} +1 -1
  174. package/dist/static/assets/{sl-SI-NN7IZMDC-CxoGm3aM.js → sl-SI-NN7IZMDC-8XnCHmN4.js} +1 -1
  175. package/dist/static/assets/{stateDiagram-587899a1-CmWqIdF5.js → stateDiagram-587899a1-B4nuLay6.js} +1 -1
  176. package/dist/static/assets/{stateDiagram-v2-d93cdb3a-CgzNTiHW.js → stateDiagram-v2-d93cdb3a-9cMNxr_8.js} +1 -1
  177. package/dist/static/assets/{styles-6aaf32cf-CI4s6NIA.js → styles-6aaf32cf-CynMMkPq.js} +1 -1
  178. package/dist/static/assets/{styles-9a916d00-ZcdN6rtW.js → styles-9a916d00-BTmAnC2j.js} +1 -1
  179. package/dist/static/assets/{styles-c10674c1-ZFkD6ta7.js → styles-c10674c1-DQ_pTuGr.js} +1 -1
  180. package/dist/static/assets/{subset-shared.chunk-B4F4dEPr.js → subset-shared.chunk-DPGuz0R6.js} +1 -1
  181. package/dist/static/assets/{subset-worker.chunk-CmgaOgn3.js → subset-worker.chunk-CMiOYLER.js} +1 -1
  182. package/dist/static/assets/{sv-SE-XGPEYMSR-CnVZlafq.js → sv-SE-XGPEYMSR-ATPKfqXs.js} +1 -1
  183. package/dist/static/assets/{svgDrawCommon-08f97a94-DbN3OiBf.js → svgDrawCommon-08f97a94-qY4BnSWc.js} +1 -1
  184. package/dist/static/assets/{ta-IN-2NMHFXQM-Bl-eCjzL.js → ta-IN-2NMHFXQM-Ct5-Fher.js} +1 -1
  185. package/dist/static/assets/{th-TH-HPSO5L25-CNIGPjSR.js → th-TH-HPSO5L25-5a6bUzcv.js} +1 -1
  186. package/dist/static/assets/{timeline-definition-85554ec2-Cmr82Iq1.js → timeline-definition-85554ec2-Bgexbl3C.js} +1 -1
  187. package/dist/static/assets/{tr-TR-DEFEU3FU-Cx7HbGIA.js → tr-TR-DEFEU3FU-WsK7dnwA.js} +1 -1
  188. package/dist/static/assets/{uk-UA-QMV73CPH-BxcA50Ze.js → uk-UA-QMV73CPH-B_P61mnc.js} +1 -1
  189. package/dist/static/assets/{vi-VN-M7AON7JQ-BvGuRh0c.js → vi-VN-M7AON7JQ-qdiQcney.js} +1 -1
  190. package/dist/static/assets/{xychartDiagram-e933f94c-BcWLDEHu.js → xychartDiagram-e933f94c-vkQjFADD.js} +1 -1
  191. package/dist/static/assets/{zh-CN-LNUGB5OW-SQH8i3l5.js → zh-CN-LNUGB5OW-DQ3BQjPe.js} +1 -1
  192. package/dist/static/assets/{zh-HK-E62DVLB3-COWoLNur.js → zh-HK-E62DVLB3-Ynj07W9J.js} +1 -1
  193. package/dist/static/assets/{zh-TW-RAJ6MFWO-Cm5B69ig.js → zh-TW-RAJ6MFWO-DNkcasuo.js} +1 -1
  194. package/dist/static/index.html +1 -1
  195. package/package.json +5 -2
  196. package/dist/static/assets/channel-DjiT9qJ0.js +0 -1
  197. package/dist/static/assets/clone-nkJpLn4s.js +0 -1
  198. package/dist/static/assets/flowDiagram-v2-96b9c2cf-Dlfh8z7R.js +0 -1
  199. package/dist/static/assets/index-B6CTdFKu.js +0 -311
@@ -0,0 +1,193 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { addShape } from '../add-shape';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ log: vi.fn(),
14
+ error: vi.fn(),
15
+ exit: vi.fn(),
16
+ ...overrides,
17
+ };
18
+ }
19
+ describe('addShape', () => {
20
+ // ==================== Parameter Assembly Tests ====================
21
+ describe('parameter assembly', () => {
22
+ it('should send correct params with required options only', async () => {
23
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
24
+ const mockClient = createMockClient(mockSend);
25
+ const deps = createMockDeps({
26
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
27
+ });
28
+ await addShape({ type: 'rectangle', x: 100, y: 200 }, deps);
29
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({
30
+ type: 'addShape',
31
+ id: 'test-id',
32
+ params: expect.objectContaining({
33
+ type: 'rectangle',
34
+ x: 100,
35
+ y: 200,
36
+ }),
37
+ }));
38
+ // customData should be undefined when no note
39
+ const callParams = mockSend.mock.calls[0][0].params;
40
+ expect(callParams.customData).toBeUndefined();
41
+ // label should be undefined when no label
42
+ expect(callParams.label).toBeUndefined();
43
+ });
44
+ it('should send correct style params', async () => {
45
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
46
+ const mockClient = createMockClient(mockSend);
47
+ const deps = createMockDeps({
48
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
49
+ });
50
+ await addShape({
51
+ type: 'ellipse',
52
+ x: 50,
53
+ y: 60,
54
+ width: 200,
55
+ height: 100,
56
+ strokeColor: '#ff0000',
57
+ backgroundColor: '#00ff00',
58
+ strokeWidth: 2,
59
+ strokeStyle: 'dashed',
60
+ fillStyle: 'solid',
61
+ }, deps);
62
+ const callParams = mockSend.mock.calls[0][0].params;
63
+ expect(callParams.type).toBe('ellipse');
64
+ expect(callParams.x).toBe(50);
65
+ expect(callParams.y).toBe(60);
66
+ expect(callParams.width).toBe(200);
67
+ expect(callParams.height).toBe(100);
68
+ expect(callParams.strokeColor).toBe('#ff0000');
69
+ expect(callParams.backgroundColor).toBe('#00ff00');
70
+ expect(callParams.strokeWidth).toBe(2);
71
+ expect(callParams.strokeStyle).toBe('dashed');
72
+ expect(callParams.fillStyle).toBe('solid');
73
+ });
74
+ it('should set label with text and fontSize when label is provided', async () => {
75
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
76
+ const mockClient = createMockClient(mockSend);
77
+ const deps = createMockDeps({
78
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
79
+ });
80
+ await addShape({
81
+ type: 'rectangle',
82
+ x: 100,
83
+ y: 100,
84
+ label: 'Hello World',
85
+ labelFontSize: 24,
86
+ }, deps);
87
+ const callParams = mockSend.mock.calls[0][0].params;
88
+ expect(callParams.label).toEqual({ text: 'Hello World', fontSize: 24 });
89
+ });
90
+ it('should set label without fontSize when labelFontSize is not provided', async () => {
91
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
92
+ const mockClient = createMockClient(mockSend);
93
+ const deps = createMockDeps({
94
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
95
+ });
96
+ await addShape({
97
+ type: 'diamond',
98
+ x: 100,
99
+ y: 100,
100
+ label: 'No font size',
101
+ }, deps);
102
+ const callParams = mockSend.mock.calls[0][0].params;
103
+ expect(callParams.label).toEqual({ text: 'No font size', fontSize: undefined });
104
+ });
105
+ it('should not include label field when label is not provided', async () => {
106
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
107
+ const mockClient = createMockClient(mockSend);
108
+ const deps = createMockDeps({
109
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
110
+ });
111
+ await addShape({ type: 'rectangle', x: 0, y: 0 }, deps);
112
+ const callParams = mockSend.mock.calls[0][0].params;
113
+ expect(callParams.label).toBeUndefined();
114
+ });
115
+ it('should set customData with note when note is provided', async () => {
116
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
117
+ const mockClient = createMockClient(mockSend);
118
+ const deps = createMockDeps({
119
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
120
+ });
121
+ await addShape({
122
+ type: 'rectangle',
123
+ x: 100,
124
+ y: 100,
125
+ note: 'my note',
126
+ }, deps);
127
+ const callParams = mockSend.mock.calls[0][0].params;
128
+ expect(callParams.customData).toEqual({ note: 'my note' });
129
+ });
130
+ it('should not include customData when note is not provided', async () => {
131
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
132
+ const mockClient = createMockClient(mockSend);
133
+ const deps = createMockDeps({
134
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
135
+ });
136
+ await addShape({ type: 'rectangle', x: 0, y: 0 }, deps);
137
+ const callParams = mockSend.mock.calls[0][0].params;
138
+ expect(callParams.customData).toBeUndefined();
139
+ });
140
+ });
141
+ // ==================== Response Handling Tests ====================
142
+ describe('response handling', () => {
143
+ it('should log success message with dimensions when provided', async () => {
144
+ const mockSend = vi.fn(() => Promise.resolve({
145
+ success: true,
146
+ elementId: 'el-123',
147
+ x: 100,
148
+ y: 200,
149
+ width: 300,
150
+ height: 400,
151
+ }));
152
+ const mockClient = createMockClient(mockSend);
153
+ const deps = createMockDeps({
154
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
155
+ });
156
+ await addShape({ type: 'rectangle', x: 100, y: 200 }, deps);
157
+ expect(deps.log).toHaveBeenCalledWith('Shape created (id: el-123 x=100 y=200 w=300 h=400)');
158
+ });
159
+ it('should error and exit on failure response', async () => {
160
+ const mockSend = vi.fn(() => Promise.resolve({
161
+ success: false,
162
+ error: 'Something went wrong',
163
+ }));
164
+ const mockClient = createMockClient(mockSend);
165
+ const deps = createMockDeps({
166
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
167
+ });
168
+ await addShape({ type: 'rectangle', x: 0, y: 0 }, deps);
169
+ expect(deps.error).toHaveBeenCalledWith('Failed: Something went wrong');
170
+ expect(deps.exit).toHaveBeenCalledWith(1);
171
+ });
172
+ it('should close client after success', async () => {
173
+ const mockClose = vi.fn();
174
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
175
+ const mockClient = { send: mockSend, close: mockClose };
176
+ const deps = createMockDeps({
177
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
178
+ });
179
+ await addShape({ type: 'rectangle', x: 0, y: 0 }, deps);
180
+ expect(mockClose).toHaveBeenCalled();
181
+ });
182
+ it('should close client after failure', async () => {
183
+ const mockClose = vi.fn();
184
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
185
+ const mockClient = { send: mockSend, close: mockClose };
186
+ const deps = createMockDeps({
187
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
188
+ });
189
+ await addShape({ type: 'rectangle', x: 0, y: 0 }, deps);
190
+ expect(mockClose).toHaveBeenCalled();
191
+ });
192
+ });
193
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,144 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { addText } from '../add-text';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ log: vi.fn(),
14
+ error: vi.fn(),
15
+ exit: vi.fn(),
16
+ ...overrides,
17
+ };
18
+ }
19
+ describe('addText', () => {
20
+ // ==================== Parameter Assembly Tests ====================
21
+ describe('parameter assembly', () => {
22
+ it('should send correct params with required options only', async () => {
23
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
24
+ const mockClient = createMockClient(mockSend);
25
+ const deps = createMockDeps({
26
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
27
+ });
28
+ await addText({ text: 'Hello World', x: 100, y: 200 }, deps);
29
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({
30
+ type: 'addText',
31
+ id: 'test-id',
32
+ params: expect.objectContaining({
33
+ text: 'Hello World',
34
+ x: 100,
35
+ y: 200,
36
+ }),
37
+ }));
38
+ // customData should be undefined when no note
39
+ const callParams = mockSend.mock.calls[0][0].params;
40
+ expect(callParams.customData).toBeUndefined();
41
+ });
42
+ it('should send correct optional params', async () => {
43
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
44
+ const mockClient = createMockClient(mockSend);
45
+ const deps = createMockDeps({
46
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
47
+ });
48
+ await addText({
49
+ text: 'Styled Text',
50
+ x: 50,
51
+ y: 60,
52
+ fontSize: 24,
53
+ textAlign: 'center',
54
+ anchor: 'topLeft',
55
+ strokeColor: '#ff0000',
56
+ }, deps);
57
+ const callParams = mockSend.mock.calls[0][0].params;
58
+ expect(callParams.text).toBe('Styled Text');
59
+ expect(callParams.x).toBe(50);
60
+ expect(callParams.y).toBe(60);
61
+ expect(callParams.fontSize).toBe(24);
62
+ expect(callParams.textAlign).toBe('center');
63
+ expect(callParams.anchor).toBe('topLeft');
64
+ expect(callParams.strokeColor).toBe('#ff0000');
65
+ });
66
+ it('should set customData with note when note is provided', async () => {
67
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
68
+ const mockClient = createMockClient(mockSend);
69
+ const deps = createMockDeps({
70
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
71
+ });
72
+ await addText({
73
+ text: 'Text with note',
74
+ x: 100,
75
+ y: 100,
76
+ note: 'my note',
77
+ }, deps);
78
+ const callParams = mockSend.mock.calls[0][0].params;
79
+ expect(callParams.customData).toEqual({ note: 'my note' });
80
+ });
81
+ it('should not include customData when note is not provided', async () => {
82
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
83
+ const mockClient = createMockClient(mockSend);
84
+ const deps = createMockDeps({
85
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
86
+ });
87
+ await addText({ text: 'No note', x: 0, y: 0 }, deps);
88
+ const callParams = mockSend.mock.calls[0][0].params;
89
+ expect(callParams.customData).toBeUndefined();
90
+ });
91
+ });
92
+ // ==================== Response Handling Tests ====================
93
+ describe('response handling', () => {
94
+ it('should log success message with position and dimensions', async () => {
95
+ const mockSend = vi.fn(() => Promise.resolve({
96
+ success: true,
97
+ elementId: 'el-123',
98
+ x: 100,
99
+ y: 200,
100
+ width: 150,
101
+ height: 30,
102
+ }));
103
+ const mockClient = createMockClient(mockSend);
104
+ const deps = createMockDeps({
105
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
106
+ });
107
+ await addText({ text: 'Test', x: 100, y: 200 }, deps);
108
+ expect(deps.log).toHaveBeenCalledWith('Text created (id: el-123, x: 100, y: 200, 150x30)');
109
+ });
110
+ it('should error and exit on failure response', async () => {
111
+ const mockSend = vi.fn(() => Promise.resolve({
112
+ success: false,
113
+ error: 'Something went wrong',
114
+ }));
115
+ const mockClient = createMockClient(mockSend);
116
+ const deps = createMockDeps({
117
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
118
+ });
119
+ await addText({ text: 'Test', x: 0, y: 0 }, deps);
120
+ expect(deps.error).toHaveBeenCalledWith('Failed: Something went wrong');
121
+ expect(deps.exit).toHaveBeenCalledWith(1);
122
+ });
123
+ it('should close client after success', async () => {
124
+ const mockClose = vi.fn();
125
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, elementId: 'el-1' }));
126
+ const mockClient = { send: mockSend, close: mockClose };
127
+ const deps = createMockDeps({
128
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
129
+ });
130
+ await addText({ text: 'Test', x: 0, y: 0 }, deps);
131
+ expect(mockClose).toHaveBeenCalled();
132
+ });
133
+ it('should close client after failure', async () => {
134
+ const mockClose = vi.fn();
135
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
136
+ const mockClient = { send: mockSend, close: mockClose };
137
+ const deps = createMockDeps({
138
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
139
+ });
140
+ await addText({ text: 'Test', x: 0, y: 0 }, deps);
141
+ expect(mockClose).toHaveBeenCalled();
142
+ });
143
+ });
144
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,65 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { clear } from '../clear';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ log: vi.fn(),
14
+ error: vi.fn(),
15
+ exit: vi.fn(),
16
+ ...overrides,
17
+ };
18
+ }
19
+ describe('clear', () => {
20
+ // ==================== Response Handling Tests ====================
21
+ describe('response handling', () => {
22
+ it('should log success message on success', async () => {
23
+ const mockSend = vi.fn(() => Promise.resolve({ success: true }));
24
+ const mockClient = createMockClient(mockSend);
25
+ const deps = createMockDeps({
26
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
27
+ });
28
+ await clear(deps);
29
+ expect(deps.log).toHaveBeenCalledWith('Canvas cleared');
30
+ });
31
+ it('should error and exit on failure response', async () => {
32
+ const mockSend = vi.fn(() => Promise.resolve({
33
+ success: false,
34
+ error: 'Clear failed',
35
+ }));
36
+ const mockClient = createMockClient(mockSend);
37
+ const deps = createMockDeps({
38
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
39
+ });
40
+ await clear(deps);
41
+ expect(deps.error).toHaveBeenCalledWith('Failed: Clear failed');
42
+ expect(deps.exit).toHaveBeenCalledWith(1);
43
+ });
44
+ it('should close client after success', async () => {
45
+ const mockClose = vi.fn();
46
+ const mockSend = vi.fn(() => Promise.resolve({ success: true }));
47
+ const mockClient = { send: mockSend, close: mockClose };
48
+ const deps = createMockDeps({
49
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
50
+ });
51
+ await clear(deps);
52
+ expect(mockClose).toHaveBeenCalled();
53
+ });
54
+ it('should close client after failure', async () => {
55
+ const mockClose = vi.fn();
56
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
57
+ const mockClient = { send: mockSend, close: mockClose };
58
+ const deps = createMockDeps({
59
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
60
+ });
61
+ await clear(deps);
62
+ expect(mockClose).toHaveBeenCalled();
63
+ });
64
+ });
65
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,103 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { deleteElements } from '../delete-elements';
3
+ function createMockClient(sendFn) {
4
+ return {
5
+ send: sendFn ?? vi.fn(() => Promise.resolve({ success: true, deletedCount: 2 })),
6
+ close: vi.fn(),
7
+ };
8
+ }
9
+ function createMockDeps(overrides) {
10
+ return {
11
+ connectToCanvas: vi.fn(() => Promise.resolve(createMockClient())),
12
+ generateId: vi.fn(() => 'test-id'),
13
+ log: vi.fn(),
14
+ error: vi.fn(),
15
+ exit: vi.fn(),
16
+ ...overrides,
17
+ };
18
+ }
19
+ describe('deleteElements', () => {
20
+ // ==================== Parameter Assembly Tests ====================
21
+ describe('parameter assembly', () => {
22
+ it('should parse comma-separated element IDs correctly', async () => {
23
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, deletedCount: 3 }));
24
+ const mockClient = createMockClient(mockSend);
25
+ const deps = createMockDeps({
26
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
27
+ });
28
+ await deleteElements({ elementIds: 'id1, id2, id3' }, deps);
29
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({
30
+ type: 'deleteElements',
31
+ id: 'test-id',
32
+ params: {
33
+ elementIds: ['id1', 'id2', 'id3'],
34
+ },
35
+ }));
36
+ });
37
+ it('should handle single element ID', async () => {
38
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, deletedCount: 1 }));
39
+ const mockClient = createMockClient(mockSend);
40
+ const deps = createMockDeps({
41
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
42
+ });
43
+ await deleteElements({ elementIds: 'single-id' }, deps);
44
+ const callParams = mockSend.mock.calls[0][0].params;
45
+ expect(callParams.elementIds).toEqual(['single-id']);
46
+ });
47
+ it('should trim whitespace from element IDs', async () => {
48
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, deletedCount: 2 }));
49
+ const mockClient = createMockClient(mockSend);
50
+ const deps = createMockDeps({
51
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
52
+ });
53
+ await deleteElements({ elementIds: ' id1 , id2 ' }, deps);
54
+ const callParams = mockSend.mock.calls[0][0].params;
55
+ expect(callParams.elementIds).toEqual(['id1', 'id2']);
56
+ });
57
+ });
58
+ // ==================== Response Handling Tests ====================
59
+ describe('response handling', () => {
60
+ it('should log success message with deleted count', async () => {
61
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, deletedCount: 5 }));
62
+ const mockClient = createMockClient(mockSend);
63
+ const deps = createMockDeps({
64
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
65
+ });
66
+ await deleteElements({ elementIds: 'id1,id2,id3,id4,id5' }, deps);
67
+ expect(deps.log).toHaveBeenCalledWith('Deleted 5 element(s)');
68
+ });
69
+ it('should error and exit on failure response', async () => {
70
+ const mockSend = vi.fn(() => Promise.resolve({
71
+ success: false,
72
+ error: 'Element not found',
73
+ }));
74
+ const mockClient = createMockClient(mockSend);
75
+ const deps = createMockDeps({
76
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
77
+ });
78
+ await deleteElements({ elementIds: 'invalid-id' }, deps);
79
+ expect(deps.error).toHaveBeenCalledWith('Failed: Element not found');
80
+ expect(deps.exit).toHaveBeenCalledWith(1);
81
+ });
82
+ it('should close client after success', async () => {
83
+ const mockClose = vi.fn();
84
+ const mockSend = vi.fn(() => Promise.resolve({ success: true, deletedCount: 1 }));
85
+ const mockClient = { send: mockSend, close: mockClose };
86
+ const deps = createMockDeps({
87
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
88
+ });
89
+ await deleteElements({ elementIds: 'id1' }, deps);
90
+ expect(mockClose).toHaveBeenCalled();
91
+ });
92
+ it('should close client after failure', async () => {
93
+ const mockClose = vi.fn();
94
+ const mockSend = vi.fn(() => Promise.resolve({ success: false, error: 'error' }));
95
+ const mockClient = { send: mockSend, close: mockClose };
96
+ const deps = createMockDeps({
97
+ connectToCanvas: vi.fn(() => Promise.resolve(mockClient)),
98
+ });
99
+ await deleteElements({ elementIds: 'id1' }, deps);
100
+ expect(mockClose).toHaveBeenCalled();
101
+ });
102
+ });
103
+ });
@@ -0,0 +1 @@
1
+ export {};