@marimo-team/islands 0.24.3-dev70 → 0.24.3-dev72

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 (26) hide show
  1. package/dist/{ErrorBoundary-DRnJ4tjG.js → ErrorBoundary-Wa8uIU73.js} +1 -1
  2. package/dist/{code-visibility-BcnKKK7F.js → code-visibility-D4b6xC1_.js} +1 -1
  3. package/dist/{common-DeZXXH6G.js → common-DOyLCadc.js} +1 -1
  4. package/dist/{data-grid-overlay-editor-DpRB7C-a.js → data-grid-overlay-editor-BILyU65g.js} +1 -1
  5. package/dist/{feedback-button-CC0QIjji.js → feedback-button-CTlzrpEN.js} +2 -2
  6. package/dist/{glide-data-editor-vv9GN4qa.js → glide-data-editor-pQiTAqma.js} +3 -3
  7. package/dist/{globals-Df9GEzVy.js → globals-dzjJ4Mbf.js} +1 -1
  8. package/dist/main.js +6 -6
  9. package/dist/{number-overlay-editor-DoPKikqK.js → number-overlay-editor-Bo2AW2sM.js} +1 -1
  10. package/dist/{reveal-component-ykpOHQgq.js → reveal-component-Dldi8B9A.js} +2 -2
  11. package/package.json +1 -1
  12. package/src/components/data-table/__tests__/filters.test.ts +21 -21
  13. package/src/components/data-table/charts/__tests__/spec.test.ts +5 -10
  14. package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +13 -11
  15. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +3 -7
  16. package/src/components/ui/__tests__/badge.test.ts +6 -4
  17. package/src/core/ai/context/providers/__tests__/error.test.ts +16 -22
  18. package/src/core/cells/__tests__/pending-delete-service.test.tsx +4 -3
  19. package/src/core/codemirror/find-replace/__tests__/navigate.test.ts +8 -16
  20. package/src/core/codemirror/language/embedded/__tests__/embedded-python.test.ts +4 -8
  21. package/src/core/export/__tests__/hooks.test.ts +1 -6
  22. package/src/core/network/__tests__/requests-network.test.ts +4 -3
  23. package/src/core/static/__tests__/files.test.ts +12 -30
  24. package/src/core/websocket/__tests__/useMarimoKernelConnection.test.ts +8 -6
  25. package/src/plugins/impl/vega/__tests__/make-selectable.test.ts +42 -48
  26. package/src/utils/__tests__/path.test.ts +6 -5
@@ -135,7 +135,7 @@ function F(e) {
135
135
  }
136
136
  //#endregion
137
137
  //#region src/components/editor/boundary/ErrorBoundary.tsx
138
- var I = (0, T.lazy)(() => import("./feedback-button-CC0QIjji.js").then((e) => ({ default: e.FeedbackModal }))), L = (e) => {
138
+ var I = (0, T.lazy)(() => import("./feedback-button-CTlzrpEN.js").then((e) => ({ default: e.FeedbackModal }))), L = (e) => {
139
139
  let t = (0, w.c)(2), n;
140
140
  return t[0] === e.children ? n = t[1] : (n = /* @__PURE__ */ (0, j.jsx)(O, {
141
141
  FallbackComponent: R,
@@ -18,7 +18,7 @@ function x() {
18
18
  return e.warn("Failed to get version from mount config"), null;
19
19
  }
20
20
  }
21
- var S = x() || "0.24.3-dev70", C = u(S), w = u(!0);
21
+ var S = x() || "0.24.3-dev72", C = u(S), w = u(!0);
22
22
  u(null);
23
23
  //#endregion
24
24
  //#region src/core/wasm/state.ts
@@ -12,7 +12,7 @@ import { t as dt } from "./check-B7cIK6gb.js";
12
12
  import { A as ft, C as pt, D as mt, M as ht, O as gt, S as _t, _ as vt, b as yt, c as bt, d as xt, g as St, h as Ct, i as wt, m as Tt, n as Et, p as Dt, s as Ot, t as kt, u as At, v as jt, y as Mt } from "./select-C6plhmZr.js";
13
13
  import { $ as Nt, $t as Pt, A as Ft, At as It, B as Lt, Bt as Rt, Ct as zt, D as Bt, Dt as Vt, E as Ht, Et as Ut, F as Wt, Ft as Gt, G as Kt, Gt as qt, H as Jt, Ht as Yt, I as Xt, It as Zt, Jt as Qt, K as $t, Kt as en, L as tn, Lt as nn, M as rn, Mt as an, N as on, Nt as sn, O as cn, Ot as ln, P as un, Pt as dn, Q as fn, Qt as pn, R as mn, Rt as hn, S as gn, St as _n, T as vn, Tt as yn, U as bn, Ut as xn, V as Sn, Vt as Cn, W as wn, Wt as Tn, X as En, Xt as Dn, Y as On, Yt as kn, Z as An, Zt as jn, _ as Mn, _t as Nn, a as Pn, an as Fn, b as In, bt as Ln, cn as Rn, ct as zn, d as Bn, dn as Vn, dt as Hn, en as Un, et as Wn, f as Gn, fn as Kn, ft as qn, gt as Jn, h as Yn, ht as Xn, i as Zn, it as Qn, j as $n, jt as er, k as tr, kt as nr, l as rr, ln as ir, lt as ar, mt as or, n as sr, nn as cr, nt as lr, o as ur, on as dr, ot as fr, pn as pr, pt as mr, qt as hr, rn as gr, rt as _r, s as vr, sn as yr, st as br, t as xr, tn as Sr, tt as Cr, u as wr, un as Tr, ut as Er, vt as Dr, w as Or, wt as kr, x as Ar, xt as jr, y as Mr, yt as Nr, z as Pr, zt as Fr } from "./dropdown-menu-CZgjYSAh.js";
14
14
  import { _ as Ir, a as Lr, c as Rr, d as zr, i as Br, n as Vr, o as Hr, p as Ur, r as Wr, s as Gr, t as Kr } from "./toDate-WXg1yLcI.js";
15
- import { n as qr, t as Jr } from "./ErrorBoundary-DRnJ4tjG.js";
15
+ import { n as qr, t as Jr } from "./ErrorBoundary-Wa8uIU73.js";
16
16
  import { t as Yr } from "./clsx-CoeGtWvn.js";
17
17
  import { t as Xr } from "./react-dom-BUgJ-ab_.js";
18
18
  import { t as Zr } from "./jsx-runtime-DgDPJV9S.js";
@@ -2,7 +2,7 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-ofJbxM4x.js";
3
3
  import { t as n } from "./react-dom-BUgJ-ab_.js";
4
4
  import { c as r, l as i, u as a } from "./data-grid-types-BucVmDDp.js";
5
- import { a as o, i as s, n as c, r as l } from "./glide-data-editor-vv9GN4qa.js";
5
+ import { a as o, i as s, n as c, r as l } from "./glide-data-editor-pQiTAqma.js";
6
6
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/internal/data-grid-overlay-editor/data-grid-overlay-editor-style.js
7
7
  var u = /* @__PURE__ */ e(t(), 1), d = /* @__PURE__ */ e(n(), 1), f = /*#__PURE__*/ o("div")({
8
8
  name: "DataGridOverlayEditorStyle",
@@ -5,12 +5,12 @@ import { t as i } from "./compiler-runtime-Cj8ZWiNS.js";
5
5
  import { t as a } from "./copy-icon-CLdENY__.js";
6
6
  import { Bt as o, H as s, Ht as c, L as l, Ot as u, V as d, d as f, hn as p } from "./cells-BLjghRgH.js";
7
7
  import { b as m } from "./select-C6plhmZr.js";
8
- import { n as h, t as ee } from "./globals-Df9GEzVy.js";
8
+ import { n as h, t as ee } from "./globals-dzjJ4Mbf.js";
9
9
  import { t as g } from "./jsx-runtime-DgDPJV9S.js";
10
10
  import { C as _, _ as te, i as v } from "./useTheme-DzXmYZ5V.js";
11
11
  import { a as ne, i as re, n as ie, r as ae } from "./dialog-CgNq6y9-.js";
12
12
  import { t as oe } from "./useAsyncData-BD6AStMt.js";
13
- import { t as se } from "./code-visibility-BcnKKK7F.js";
13
+ import { t as se } from "./code-visibility-D4b6xC1_.js";
14
14
  import { i as ce, n as le } from "./error-entries-CJR74llu.js";
15
15
  //#region src/components/ui/skeleton.tsx
16
16
  var y = /* @__PURE__ */ e(r(), 1), b = i(), x = g(), ue = (e) => {
@@ -6,7 +6,7 @@ import { i as s, n as c, r as l } from "./copy-icon-CLdENY__.js";
6
6
  import { C as u, c as d, i as f, n as p, s as m, t as h, x as g } from "./select-C6plhmZr.js";
7
7
  import { d as _, h as v, i as y, l as b, n as x, o as S, s as C, t as w, u as T } from "./dropdown-menu-CZgjYSAh.js";
8
8
  import { c as E, d as D, l as O, n as k, o as A, s as ee, t as j, u as te } from "./glide-utils-B3rUT5PI.js";
9
- import { n as ne, t as re } from "./ErrorBoundary-DRnJ4tjG.js";
9
+ import { n as ne, t as re } from "./ErrorBoundary-Wa8uIU73.js";
10
10
  import { t as M } from "./react-dom-BUgJ-ab_.js";
11
11
  import { t as N } from "./jsx-runtime-DgDPJV9S.js";
12
12
  import { t as ie } from "./label-BJ49YTvk.js";
@@ -7062,7 +7062,7 @@ function rs(e, t, n, r, i) {
7062
7062
  }
7063
7063
  //#endregion
7064
7064
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/data-editor/data-editor.js
7065
- var is = /* @__PURE__ */ e(_r(), 1), as = /* @__PURE__ */ e(xr(), 1), os = K.lazy(async () => await import("./data-grid-overlay-editor-DpRB7C-a.js")), ss = 0;
7065
+ var is = /* @__PURE__ */ e(_r(), 1), as = /* @__PURE__ */ e(xr(), 1), os = K.lazy(async () => await import("./data-grid-overlay-editor-BILyU65g.js")), ss = 0;
7066
7066
  function cs(e) {
7067
7067
  return (0, is.default)((0, as.default)((0, as.default)(e).filter((e) => e.span !== void 0).map((e) => (0, Za.default)((e.span?.[0] ?? 0) + 1, (e.span?.[1] ?? 0) + 1))));
7068
7068
  }
@@ -9293,7 +9293,7 @@ function Vs(e, t, n, r, i) {
9293
9293
  }
9294
9294
  //#endregion
9295
9295
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/cells/number-cell.js
9296
- var Hs = K.lazy(async () => await import("./number-overlay-editor-DoPKikqK.js")), Us = {
9296
+ var Hs = K.lazy(async () => await import("./number-overlay-editor-Bo2AW2sM.js")), Us = {
9297
9297
  getAccessibilityString: (e) => e.data?.toString() ?? "",
9298
9298
  kind: W.Number,
9299
9299
  needsHover: (e) => e.hoverEffect === !0,
@@ -1,6 +1,6 @@
1
1
  import { g as e } from "./tooltip-qB8NlSqV.js";
2
2
  import { _ as t } from "./useTheme-DzXmYZ5V.js";
3
- import { r as n } from "./code-visibility-BcnKKK7F.js";
3
+ import { r as n } from "./code-visibility-D4b6xC1_.js";
4
4
  var r = e("triangle-alert", [
5
5
  ["path", {
6
6
  d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
package/dist/main.js CHANGED
@@ -7,7 +7,7 @@ import { C as T, F as E, G as D, I as O, J as k, K as A, L as j, P as M, R as N,
7
7
  import { a as se, f as ce, g as V, i as le, n as ue, o as de, p as fe, r as pe, t as me } from "./tooltip-qB8NlSqV.js";
8
8
  import { $ as he, $t as ge, At as _e, B as ve, C as ye, D as be, Dt as xe, F as Se, G as Ce, Gt as we, I as Te, J as Ee, L as De, Mt as Oe, Nt as ke, O as Ae, Ot as je, P as Me, Q as Ne, Qt as Pe, S as Fe, T as Ie, Tt as Le, U as Re, Ut as ze, W as Be, Wt as Ve, X as He, Xt as Ue, Y as We, Yt as Ge, Zt as Ke, _n as qe, _t as Je, an as Ye, bn as Xe, c as Ze, cn as Qe, ct as $e, d as et, dn as tt, dt as nt, f as rt, fn as it, ft as at, g as ot, gn as st, gt as ct, h as lt, in as ut, it as dt, jt as ft, k as pt, kt as mt, l as ht, m as gt, mn as _t, n as vt, o as yt, on as bt, p as xt, pn as St, pt as Ct, q as wt, qt as Tt, r as Et, rn as Dt, rt as Ot, u as kt, v as At, w as jt, xt as Mt, yn as Nt, zt as Pt } from "./cells-BLjghRgH.js";
9
9
  import { D as Ft, E as It, O as Lt, S as Rt, T as zt, _ as Bt, a as Vt, c as Ht, d as Ut, f as Wt, g as Gt, h as Kt, i as qt, l as Jt, m as Yt, n as Xt, o as Zt, p as Qt, r as $t, s as en, t as tn, u as nn, v as rn, w as an, x as on, y as sn } from "./spec-CAYwFeV6.js";
10
- import { $t as cn, A as ln, At as un, B as dn, Bt as fn, C as pn, Ct as mn, D as hn, Dt as gn, E as _n, Et as vn, F as yn, Ft as bn, G as xn, Gt as Sn, H as Cn, Ht as wn, I as Tn, It as En, J as Dn, Jt as On, K as kn, Kt as An, L as jn, Lt as Mn, M as Nn, Mt as Pn, N as Fn, Nt as In, O as Ln, Ot as Rn, P as zn, Pt as Bn, Qt as Vn, R as Hn, Rt as Un, S as Wn, St as Gn, T as Kn, Tt as qn, U as Jn, Ut as Yn, V as Xn, Vt as Zn, W as Qn, Wt as $n, X as er, Xt as tr, Y as nr, Yt as rr, Zt as ir, _ as ar, _t as or, an as sr, at as cr, b as lr, c as ur, cn as dr, ct as fr, d as pr, dn as mr, dt as hr, en as gr, et as _r, f as vr, fn as yr, ft as br, g as xr, gt as Sr, h as Cr, hn as wr, ht as Tr, in as Er, it as Dr, j as Or, jt as kr, k as Ar, kt as jr, ln as Mr, lt as Nr, m as Pr, mn as Fr, mt as Ir, nn as Lr, nt as Rr, ot as zr, p as Br, pn as Vr, pt as Hr, q as Ur, qt as Wr, r as Gr, rn as Kr, rt as qr, sn as Jr, st as Yr, t as Xr, tn as Zr, tt as Qr, u as $r, un as ei, ut as ti, v as ni, vt as ri, w as ii, wt as ai, x as oi, y as si, yt as ci, z as li, zt as ui } from "./common-DeZXXH6G.js";
10
+ import { $t as cn, A as ln, At as un, B as dn, Bt as fn, C as pn, Ct as mn, D as hn, Dt as gn, E as _n, Et as vn, F as yn, Ft as bn, G as xn, Gt as Sn, H as Cn, Ht as wn, I as Tn, It as En, J as Dn, Jt as On, K as kn, Kt as An, L as jn, Lt as Mn, M as Nn, Mt as Pn, N as Fn, Nt as In, O as Ln, Ot as Rn, P as zn, Pt as Bn, Qt as Vn, R as Hn, Rt as Un, S as Wn, St as Gn, T as Kn, Tt as qn, U as Jn, Ut as Yn, V as Xn, Vt as Zn, W as Qn, Wt as $n, X as er, Xt as tr, Y as nr, Yt as rr, Zt as ir, _ as ar, _t as or, an as sr, at as cr, b as lr, c as ur, cn as dr, ct as fr, d as pr, dn as mr, dt as hr, en as gr, et as _r, f as vr, fn as yr, ft as br, g as xr, gt as Sr, h as Cr, hn as wr, ht as Tr, in as Er, it as Dr, j as Or, jt as kr, k as Ar, kt as jr, ln as Mr, lt as Nr, m as Pr, mn as Fr, mt as Ir, nn as Lr, nt as Rr, ot as zr, p as Br, pn as Vr, pt as Hr, q as Ur, qt as Wr, r as Gr, rn as Kr, rt as qr, sn as Jr, st as Yr, t as Xr, tn as Zr, tt as Qr, u as $r, un as ei, ut as ti, v as ni, vt as ri, w as ii, wt as ai, x as oi, y as si, yt as ci, z as li, zt as ui } from "./common-DOyLCadc.js";
11
11
  import { c as di, i as fi, n as pi, o as mi, t as hi } from "./useLifecycle-DPgiiwwU.js";
12
12
  import { t as gi } from "./check-B7cIK6gb.js";
13
13
  import { A as _i, C as vi, D as yi, E as bi, M as xi, O as Si, S as Ci, T as wi, a as Ti, b as Ei, c as Di, i as Oi, k as ki, l as Ai, n as ji, o as Mi, r as Ni, s as Pi, t as Fi, w as Ii, x as Li } from "./select-C6plhmZr.js";
@@ -15,8 +15,8 @@ import { B as Ri, C as zi, J as Bi, Mt as Vi, Nt as Hi, S as Ui, Vt as Wi, W as
15
15
  import { _ as ha, c as ga, d as _a, f as va, g as ya, h as ba, m as xa, u as Sa, v as Ca } from "./toDate-WXg1yLcI.js";
16
16
  import { a as wa, c as Ta, d as Ea, f as Da, i as Oa, l as ka, n as Aa, o as ja, r as Ma, s as Na, t as Pa } from "./process-output-BurYfV57.js";
17
17
  import { a as Fa, c as Ia, d as La, i as Ra, l as za, r as Ba, u as Va } from "./glide-utils-B3rUT5PI.js";
18
- import { n as Ha, t as Ua } from "./ErrorBoundary-DRnJ4tjG.js";
19
- import { n as Wa, t as Ga } from "./globals-Df9GEzVy.js";
18
+ import { n as Ha, t as Ua } from "./ErrorBoundary-Wa8uIU73.js";
19
+ import { n as Wa, t as Ga } from "./globals-dzjJ4Mbf.js";
20
20
  import { t as Ka } from "./react-dom-BUgJ-ab_.js";
21
21
  import { t as qa } from "./jsx-runtime-DgDPJV9S.js";
22
22
  import { B as Ja, C as H, Ct as Ya, D as Xa, E as Za, Et as Qa, F as U, G as $a, H as eo, I as to, L as no, M as W, N as ro, O as io, P as ao, Q as oo, R as so, S as G, St as co, Tt as lo, U as uo, W as fo, Y as po, Z as mo, _ as ho, a as go, b as _o, bt as vo, c as yo, d as bo, dt as xo, f as So, g as Co, gt as wo, h as To, i as Eo, j as K, k as Do, l as Oo, m as ko, n as Ao, o as jo, p as Mo, r as No, s as Po, u as Fo, v as Io, vt as Lo, w as Ro, wt as zo, x as Bo, xt as Vo, y as Ho, yt as Uo } from "./use-restore-focus-D5D9xEjZ.js";
@@ -40,7 +40,7 @@ import { t as Ns } from "./useAsyncData-BD6AStMt.js";
40
40
  import { i as Ps, n as Fs, r as Is } from "./formats-BR5iGb4s.js";
41
41
  import { M as Ls, N as Rs } from "./vega-loader.browser-D95WfUcj.js";
42
42
  import { a as zs, n as Bs } from "./loader-D2W4oM-3.js";
43
- import { c as Vs, d as Hs, i as Us, l as Ws, o as Gs, s as Ks, t as qs, u as Js } from "./code-visibility-BcnKKK7F.js";
43
+ import { c as Vs, d as Hs, i as Us, l as Ws, o as Gs, s as Ks, t as qs, u as Js } from "./code-visibility-D4b6xC1_.js";
44
44
  import { t as Ys } from "./useDeepCompareMemoize-D_HNdyvI.js";
45
45
  import { t as Xs } from "./esm-BElI3qKH.js";
46
46
  //#region ../node_modules/.pnpm/iconify-icon@2.3.0/node_modules/iconify-icon/dist/iconify-icon.mjs
@@ -10458,7 +10458,7 @@ function RC(e, t) {
10458
10458
  }
10459
10459
  //#endregion
10460
10460
  //#region src/plugins/impl/DataEditorPlugin.tsx
10461
- var zC = J.lazy(() => import("./glide-data-editor-vv9GN4qa.js").then((e) => e.t)), BC = xS("marimo-data-editor", { cssStyles: [WS] }).withData(W({
10461
+ var zC = J.lazy(() => import("./glide-data-editor-pQiTAqma.js").then((e) => e.t)), BC = xS("marimo-data-editor", { cssStyles: [WS] }).withData(W({
10462
10462
  initialValue: W({ edits: G(W({
10463
10463
  rowIdx: K(),
10464
10464
  columnId: U(),
@@ -29922,7 +29922,7 @@ function bR(e) {
29922
29922
  }
29923
29923
  //#endregion
29924
29924
  //#region src/components/editor/renderers/slides-layout/slides-layout.tsx
29925
- var xR = J.lazy(() => import("./reveal-component-ykpOHQgq.js")), SR = (e) => {
29925
+ var xR = J.lazy(() => import("./reveal-component-Dldi8B9A.js")), SR = (e) => {
29926
29926
  let t = (0, X.c)(33), { layout: n, setLayout: r, cells: i, mode: a } = e, o = rs(Ce), s = a === "read" || o, c = rs(xt) > 1, [l, u] = (0, J.useState)(null), d;
29927
29927
  t[0] !== i || t[1] !== n ? (d = vP(i, n), t[0] = i, t[1] = n, t[2] = d) : d = t[2];
29928
29928
  let { slideCells: f, skippedIds: p, noOutputIds: m, slideTypes: h, startCellIndex: g } = d, _;
@@ -1,6 +1,6 @@
1
1
  import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-ofJbxM4x.js";
3
- import { a as n } from "./glide-data-editor-vv9GN4qa.js";
3
+ import { a as n } from "./glide-data-editor-pQiTAqma.js";
4
4
  //#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.2.8_b9e6aec46d952f631ce71b0585d2a8e5/node_modules/@glideapps/glide-data-grid/dist/esm/internal/data-grid-overlay-editor/private/number-overlay-editor-style.js
5
5
  var r = /* @__PURE__ */ e(t()), i = /*#__PURE__*/ n("div")({
6
6
  name: "NumberOverlayEditorStyle",
@@ -4,13 +4,13 @@ import { t as o } from "./react-ofJbxM4x.js";
4
4
  import { t as s } from "./compiler-runtime-Cj8ZWiNS.js";
5
5
  import { g as c, t as l } from "./tooltip-qB8NlSqV.js";
6
6
  import { G as u, w as d } from "./cells-BLjghRgH.js";
7
- import { $ as f, Q as p, Z as m, an as h, i as g, l as _, ln as v, n as y, on as b, r as x, t as S, u as C } from "./common-DeZXXH6G.js";
7
+ import { $ as f, Q as p, Z as m, an as h, i as g, l as _, ln as v, n as y, on as b, r as x, t as S, u as C } from "./common-DOyLCadc.js";
8
8
  import { M as w } from "./select-C6plhmZr.js";
9
9
  import { J as T } from "./dropdown-menu-CZgjYSAh.js";
10
10
  import { t as E } from "./jsx-runtime-DgDPJV9S.js";
11
11
  import { q as ee } from "./use-restore-focus-D5D9xEjZ.js";
12
12
  import { A as D, C as O, b as k } from "./useTheme-DzXmYZ5V.js";
13
- import { a as A, n as te, t as ne } from "./code-visibility-BcnKKK7F.js";
13
+ import { a as A, n as te, t as ne } from "./code-visibility-D4b6xC1_.js";
14
14
  /* empty css */
15
15
  var j = c("sticky-note", [["path", {
16
16
  d: "M21 9a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 15 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2z",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.24.3-dev70",
3
+ "version": "0.24.3-dev72",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -368,11 +368,10 @@ describe("schema validation", () => {
368
368
  operator: ">=",
369
369
  value: 18,
370
370
  });
371
- expect(result.success).toBe(true);
372
- if (result.success) {
373
- expect(result.data.type).toBe("condition");
374
- expect(result.data.negate).toBe(false);
375
- }
371
+ expect(result).toMatchObject({
372
+ success: true,
373
+ data: { type: "condition", negate: false },
374
+ });
376
375
  });
377
376
 
378
377
  it("FilterConditionSchema defaults type and negate", () => {
@@ -381,11 +380,10 @@ describe("schema validation", () => {
381
380
  operator: "==",
382
381
  value: 5,
383
382
  });
384
- expect(result.success).toBe(true);
385
- if (result.success) {
386
- expect(result.data.type).toBe("condition");
387
- expect(result.data.negate).toBe(false);
388
- }
383
+ expect(result).toMatchObject({
384
+ success: true,
385
+ data: { type: "condition", negate: false },
386
+ });
389
387
  });
390
388
 
391
389
  it("FilterConditionSchema accepts negate=true", () => {
@@ -395,10 +393,10 @@ describe("schema validation", () => {
395
393
  value: 5,
396
394
  negate: true,
397
395
  });
398
- expect(result.success).toBe(true);
399
- if (result.success) {
400
- expect(result.data.negate).toBe(true);
401
- }
396
+ expect(result).toMatchObject({
397
+ success: true,
398
+ data: { negate: true },
399
+ });
402
400
  });
403
401
 
404
402
  it("FilterGroupSchema accepts valid group", () => {
@@ -440,12 +438,14 @@ describe("schema validation", () => {
440
438
 
441
439
  it("FilterGroupSchema defaults fields", () => {
442
440
  const result = FilterGroupSchema.safeParse({});
443
- expect(result.success).toBe(true);
444
- if (result.success) {
445
- expect(result.data.type).toBe("group");
446
- expect(result.data.operator).toBe("and");
447
- expect(result.data.children).toEqual([]);
448
- expect(result.data.negate).toBe(false);
449
- }
441
+ expect(result).toMatchObject({
442
+ success: true,
443
+ data: {
444
+ type: "group",
445
+ operator: "and",
446
+ children: [],
447
+ negate: false,
448
+ },
449
+ });
450
450
  });
451
451
  });
@@ -169,16 +169,11 @@ describe("getAxisEncoding", () => {
169
169
 
170
170
  const expectedAggregate = (result as { aggregate?: string }).aggregate;
171
171
 
172
- // For aggregations that are not valid for string data types, we should return undefined
173
- if (
174
- agg === NONE_VALUE ||
175
- agg === BIN_AGGREGATION ||
176
- !STRING_AGGREGATION_FNS.includes(agg)
177
- ) {
178
- expect(expectedAggregate).toBeUndefined();
179
- } else if (STRING_AGGREGATION_FNS.includes(agg)) {
180
- expect(expectedAggregate).toEqual(agg);
181
- }
172
+ const isStringAggregation =
173
+ agg !== NONE_VALUE &&
174
+ agg !== BIN_AGGREGATION &&
175
+ STRING_AGGREGATION_FNS.includes(agg);
176
+ expect(expectedAggregate).toBe(isStringAggregation ? agg : undefined);
182
177
  }
183
178
  });
184
179
 
@@ -278,18 +278,20 @@ describe("file browser navigation", () => {
278
278
  await new Promise(requestAnimationFrame);
279
279
  });
280
280
  dragEvent(folder, "drop");
281
- if (canMove) {
282
- await waitFor(() =>
283
- expect(client.sendRenameFileOrFolder).toHaveBeenCalledExactlyOnceWith(
284
- {
285
- path: "/workspace/notes.txt",
286
- newPath: "/workspace/data/notes.txt",
287
- },
288
- ),
281
+ await waitFor(() => {
282
+ expect(client.sendRenameFileOrFolder.mock.calls).toEqual(
283
+ canMove
284
+ ? [
285
+ [
286
+ {
287
+ path: "/workspace/notes.txt",
288
+ newPath: "/workspace/data/notes.txt",
289
+ },
290
+ ],
291
+ ]
292
+ : [],
289
293
  );
290
- } else {
291
- expect(client.sendRenameFileOrFolder).not.toHaveBeenCalled();
292
- }
294
+ });
293
295
  dragEvent(source, "dragend");
294
296
  },
295
297
  );
@@ -217,7 +217,7 @@ interface BackwardsCompatCase {
217
217
  * properties need to be listed — extra properties are ignored.
218
218
  */
219
219
  expected: {
220
- deck?: unknown;
220
+ deck: unknown;
221
221
  cellIds: string[];
222
222
  cellEntries?: Array<[string, unknown]>;
223
223
  };
@@ -355,9 +355,7 @@ describe("SlidesLayoutPlugin backwards compatibility", () => {
355
355
  // known field, the deserialized config won't carry it and the
356
356
  // assertion below fails.
357
357
  const layout = SlidesLayoutPlugin.deserializeLayout(parsed.data, cells);
358
- if (expected.deck !== undefined) {
359
- expect(layout.deck).toEqual(expected.deck);
360
- }
358
+ expect(layout.deck).toEqual(expected.deck);
361
359
  for (const [cellEntryId, expectedConfig] of expected.cellEntries ?? []) {
362
360
  expect(layout.cells.get(cellId(cellEntryId))).toMatchObject(
363
361
  expectedConfig as object,
@@ -379,9 +377,7 @@ describe("SlidesLayoutPlugin backwards compatibility", () => {
379
377
  expectedConfig as object,
380
378
  );
381
379
  }
382
- if (expected.deck !== undefined) {
383
- expect(redeserialized.deck).toEqual(expected.deck);
384
- }
380
+ expect(redeserialized.deck).toEqual(expected.deck);
385
381
  },
386
382
  );
387
383
 
@@ -54,10 +54,12 @@ describe("badgeVariants", () => {
54
54
  ].join(" "),
55
55
  ),
56
56
  );
57
- if (variant !== "outline") {
58
- expect(classes).toContain("forced-colors:hover:bg-[Highlight]");
59
- expect(classes).toContain("forced-colors:hover:text-[HighlightText]");
60
- }
57
+ expect(classes.includes("forced-colors:hover:bg-[Highlight]")).toBe(
58
+ variant !== "outline",
59
+ );
60
+ expect(classes.includes("forced-colors:hover:text-[HighlightText]")).toBe(
61
+ variant !== "outline",
62
+ );
61
63
  },
62
64
  );
63
65
  });
@@ -104,10 +104,10 @@ describe("ErrorContextProvider", () => {
104
104
  ]);
105
105
 
106
106
  const items = provider.getItems();
107
- expect(items[1].data.type).toBe("cell-error");
108
- if (items[1].data.type === "cell-error") {
109
- expect(items[1].data.error.cellName).toBe("cell-0");
110
- }
107
+ expect(items[1].data).toMatchObject({
108
+ type: "cell-error",
109
+ error: { cellName: "cell-0" },
110
+ });
111
111
  expect(items[1].name).toBe("Error: cell-0");
112
112
  expect(items[1].description).toBe("Invalid syntax");
113
113
  });
@@ -150,25 +150,19 @@ describe("ErrorContextProvider", () => {
150
150
  `);
151
151
 
152
152
  // Test the info function
153
- expect(completion.info).toBeDefined();
154
- if (typeof completion.info === "function") {
155
- const infoResult = completion.info(completion);
156
- if (
157
- infoResult &&
158
- typeof infoResult === "object" &&
159
- "dom" in infoResult
160
- ) {
161
- const infoElement = infoResult.dom as HTMLElement;
162
- expect(infoElement.tagName).toBe("DIV");
163
- expect(infoElement.textContent).toContain("Errors");
164
- expect(infoElement.textContent).toContain("2 errors");
165
- } else if (infoResult && "tagName" in (infoResult as any)) {
166
- const infoElement = infoResult as HTMLElement;
167
- expect(infoElement.tagName).toBe("DIV");
168
- expect(infoElement.textContent).toContain("Errors");
169
- expect(infoElement.textContent).toContain("2 errors");
170
- }
153
+ if (typeof completion.info !== "function") {
154
+ throw new Error("Expected completion info to be a function");
155
+ }
156
+ const infoResult = completion.info(completion);
157
+ if (!infoResult || typeof infoResult !== "object") {
158
+ throw new Error("Expected completion info to return an element");
171
159
  }
160
+ const infoElement = (
161
+ "dom" in infoResult ? infoResult.dom : infoResult
162
+ ) as HTMLElement;
163
+ expect(infoElement.tagName).toBe("DIV");
164
+ expect(infoElement.textContent).toContain("Errors");
165
+ expect(infoElement.textContent).toContain("2 errors");
172
166
  });
173
167
 
174
168
  it("should handle single error correctly", () => {
@@ -194,9 +194,10 @@ describe("pending-delete-service", () => {
194
194
  wrapper,
195
195
  });
196
196
  expect(result.current.isPending).toBe(true);
197
- if (result.current.isPending) {
198
- expect(result.current.shouldConfirmDelete).toBe(false);
199
- expect("confirm" in result.current).toBe(false);
197
+ if (!result.current.isPending) {
198
+ throw new Error("Expected cell deletion to be pending");
200
199
  }
200
+ expect(result.current.shouldConfirmDelete).toBe(false);
201
+ expect("confirm" in result.current).toBe(false);
201
202
  });
202
203
  });
@@ -500,17 +500,15 @@ describe("navigate", () => {
500
500
  const view1Positions = result.position.get(view1);
501
501
  const view2Positions = result.position.get(view2);
502
502
 
503
- if (view1Positions) {
504
- expect(view1Positions.size).toBeGreaterThan(0);
505
- // Check that position keys are in "from:to" format
506
- for (const key of view1Positions.keys()) {
507
- expect(key).toMatch(/^\d+:\d+$/);
508
- }
503
+ invariant(view1Positions, "Expected positions for the first view");
504
+ expect(view1Positions.size).toBeGreaterThan(0);
505
+ // Check that position keys are in "from:to" format
506
+ for (const key of view1Positions.keys()) {
507
+ expect(key).toMatch(/^\d+:\d+$/);
509
508
  }
510
509
 
511
- if (view2Positions) {
512
- expect(view2Positions.size).toBeGreaterThan(0);
513
- }
510
+ invariant(view2Positions, "Expected positions for the second view");
511
+ expect(view2Positions.size).toBeGreaterThan(0);
514
512
  });
515
513
 
516
514
  it("should handle regex patterns", () => {
@@ -654,13 +652,7 @@ describe("navigate", () => {
654
652
 
655
653
  const result = findNext();
656
654
  // Should still work by starting from index 0
657
- if (result) {
658
- expect(result).toBeTruthy();
659
- invariant(result, "findNext should return a result");
660
- } else {
661
- // It's ok if no match is found since "hello" might not be in the mock views
662
- expect(result).toBe(false);
663
- }
655
+ expect(result).toMatchObject({ from: 0, to: 5 });
664
656
  });
665
657
 
666
658
  it("should handle malformed regex in replace pattern", () => {
@@ -17,14 +17,10 @@ describe("parsePython", () => {
17
17
  const pythonParser = python().language.parser;
18
18
  const config = parsePython(pythonParser, IS_ACTIVE);
19
19
 
20
- expect(config.defineNodes).toBeDefined();
21
- if (config.defineNodes) {
22
- expect(config.defineNodes).toHaveLength(2);
23
- // @ts-expect-error - we know that the defineNodes are NodeSpec
24
- expect(config.defineNodes[0].name).toBe("Python");
25
- // @ts-expect-error - we know that the defineNodes are NodeSpec
26
- expect(config.defineNodes[1].name).toBe("PythonMark");
27
- }
20
+ expect(config.defineNodes).toMatchObject([
21
+ { name: "Python" },
22
+ { name: "PythonMark" },
23
+ ]);
28
24
  });
29
25
 
30
26
  it("should not parse double curly braces", () => {
@@ -552,12 +552,7 @@ describe("useEnrichCellOutputs", () => {
552
552
  // Verify the exact return type structure
553
553
  expect(output).toHaveProperty(cid);
554
554
  const cellOutput = output[cid];
555
- expect(cellOutput).toBeDefined();
556
- expect(Array.isArray(cellOutput)).toBe(true);
557
- if (cellOutput) {
558
- expect(cellOutput[0]).toBe("image/png");
559
- expect(cellOutput[1]).toBe(mockDataUrl);
560
- }
555
+ expect(cellOutput).toEqual(["image/png", mockDataUrl]);
561
556
  });
562
557
  });
563
558
 
@@ -69,9 +69,10 @@ describe("createNetworkRequests", () => {
69
69
  const methodNames = Object.keys(requests);
70
70
 
71
71
  for (const methodName of methodNames) {
72
- if (!ACTIONS[methodName as keyof typeof ACTIONS]) {
73
- expect.fail(`Method ${methodName} has no action defined`);
74
- }
72
+ expect(
73
+ ACTIONS[methodName as keyof typeof ACTIONS],
74
+ `Method ${methodName} has no action defined`,
75
+ ).toBeDefined();
75
76
  }
76
77
  });
77
78
 
@@ -291,14 +291,10 @@ describe("patchVegaLoader - loader.load", () => {
291
291
  const loader = createLoader();
292
292
  const unpatch = patchVegaLoader(loader, virtualFiles);
293
293
 
294
- try {
295
- const content = await loader.load("file:///path/to/@file/vega-data.json");
296
- expect(content).toBe('{"values": [1, 2, 3]}');
297
- } catch (error) {
298
- // If it falls back to original loader and fails, that's expected for file:// URLs
299
- // The important thing is that the virtual file lookup was attempted
300
- expect(error).toBeDefined();
301
- }
294
+ const content = await loader
295
+ .load("file:///path/to/@file/vega-data.json")
296
+ .catch(() => undefined);
297
+ expect([undefined, '{"values": [1, 2, 3]}']).toContain(content);
302
298
 
303
299
  unpatch();
304
300
  });
@@ -340,15 +336,10 @@ describe("patchVegaLoader - loader.load", () => {
340
336
  }
341
337
 
342
338
  // Test file:// URL separately since it might fallback
343
- try {
344
- const content = await loader.load(
345
- "file:///local/path/@file/pattern-test.json",
346
- );
347
- expect(content).toBe('{"pattern": "test"}');
348
- } catch (error) {
349
- // Expected if it falls back to original loader
350
- expect(error).toBeDefined();
351
- }
339
+ const fileUrlContent = await loader
340
+ .load("file:///local/path/@file/pattern-test.json")
341
+ .catch(() => undefined);
342
+ expect([undefined, '{"pattern": "test"}']).toContain(fileUrlContent);
352
343
 
353
344
  unpatch();
354
345
  });
@@ -640,12 +631,9 @@ describe("error handling and edge cases", () => {
640
631
  expect(window.fetch).toBe(originalFetch);
641
632
 
642
633
  // Test that the loader functions are functional (they should work normally)
643
- try {
644
- await loader.load("http://example.com/test.json");
645
- } catch (error) {
646
- // Expected to fail for non-existent URLs, but the function should be callable
647
- expect(error).toBeDefined();
648
- }
634
+ // A network failure is expected for this non-existent URL. A custom loader
635
+ // may also handle it, so only verify that the restored method is callable.
636
+ await loader.load("http://example.com/test.json").catch(() => undefined);
649
637
  });
650
638
 
651
639
  it("should handle Request objects in patchFetch", async () => {
@@ -676,13 +664,7 @@ describe("error handling and edge cases", () => {
676
664
  .mockImplementation(Functions.NOOP);
677
665
 
678
666
  // This should catch the error and fallback to original fetch
679
- try {
680
- await window.fetch("not-a-valid-url");
681
- // If it doesn't throw, that's also fine (fallback behavior)
682
- } catch (error) {
683
- // Expected behavior - invalid URLs should be handled gracefully
684
- expect(error).toBeDefined();
685
- }
667
+ await window.fetch("not-a-valid-url").catch(() => undefined);
686
668
 
687
669
  unpatch();
688
670
  loggerSpy.mockRestore();
@@ -47,9 +47,10 @@ describe("classifyCloseEvent", () => {
47
47
  state: WebSocketState.CLOSED,
48
48
  code: WebSocketClosedReason.KERNEL_DISCONNECTED,
49
49
  });
50
- if (decision.kind === "terminal") {
51
- expect(decision.closeTransport).toBe(true);
52
- }
50
+ expect(decision).toMatchObject({
51
+ kind: "terminal",
52
+ closeTransport: true,
53
+ });
53
54
  });
54
55
 
55
56
  it("MARIMO_KERNEL_STARTUP_ERROR → terminal + closeTransport", () => {
@@ -59,9 +60,10 @@ describe("classifyCloseEvent", () => {
59
60
  state: WebSocketState.CLOSED,
60
61
  code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
61
62
  });
62
- if (decision.kind === "terminal") {
63
- expect(decision.closeTransport).toBe(true);
64
- }
63
+ expect(decision).toMatchObject({
64
+ kind: "terminal",
65
+ closeTransport: true,
66
+ });
65
67
  });
66
68
  });
67
69
 
@@ -986,22 +986,15 @@ describe("makeSelectable", () => {
986
986
  expect(paramNames).toContain("legend_selection_Origin");
987
987
 
988
988
  // Nested specs should NOT have params (they should be hoisted)
989
- if ("hconcat" in newSpec) {
990
- for (const subSpec of newSpec.hconcat) {
991
- if ("vconcat" in subSpec) {
992
- invariant("vconcat" in subSpec, "subSpec should have vconcat");
993
- for (const innerSpec of subSpec.vconcat) {
994
- expect("params" in innerSpec).toBe(false);
995
- // But should have opacity encoding
996
- if ("mark" in innerSpec) {
997
- expect(innerSpec.encoding?.opacity).toBeDefined();
998
- }
999
- }
1000
- } else if ("mark" in subSpec) {
1001
- expect(subSpec.params).toBeUndefined();
1002
- // But should have opacity encoding
1003
- expect(subSpec.encoding?.opacity).toBeDefined();
1004
- }
989
+ invariant("hconcat" in newSpec, "expected a horizontal concat spec");
990
+ for (const subSpec of newSpec.hconcat) {
991
+ const innerSpecs = "vconcat" in subSpec ? subSpec.vconcat : [subSpec];
992
+ for (const innerSpec of innerSpecs) {
993
+ expect(
994
+ "params" in innerSpec ? innerSpec.params : undefined,
995
+ ).toBeUndefined();
996
+ invariant("mark" in innerSpec, "expected a marked nested spec");
997
+ expect(innerSpec.encoding?.opacity).toBeDefined();
1005
998
  }
1006
999
  }
1007
1000
  expect(newSpec).toMatchSnapshot();
@@ -1045,10 +1038,9 @@ describe("makeSelectable", () => {
1045
1038
  expect(topLevelParamNames).toContain("select_interval");
1046
1039
 
1047
1040
  // Nested specs should not have params
1048
- if ("hconcat" in newSpec) {
1049
- for (const subSpec of newSpec.hconcat) {
1050
- expect("params" in subSpec).toBe(false);
1051
- }
1041
+ invariant("hconcat" in newSpec, "expected a horizontal concat spec");
1042
+ for (const subSpec of newSpec.hconcat) {
1043
+ expect("params" in subSpec).toBe(false);
1052
1044
  }
1053
1045
  expect(newSpec).toMatchSnapshot();
1054
1046
  expect(parse(newSpec)).toBeDefined();
@@ -1085,12 +1077,11 @@ describe("makeSelectable", () => {
1085
1077
 
1086
1078
  // But chart selection params should NOT be hoisted (different types)
1087
1079
  // Bar gets point+interval with x encoding, area gets point with color encoding
1088
- if ("hconcat" in newSpec) {
1089
- const subspecParams = newSpec.hconcat.flatMap((subSpec) =>
1090
- "params" in subSpec ? subSpec.params : [],
1091
- );
1092
- expect(subspecParams.length).toBeGreaterThan(0);
1093
- }
1080
+ invariant("hconcat" in newSpec, "expected a horizontal concat spec");
1081
+ const subspecParams = newSpec.hconcat.flatMap((subSpec) =>
1082
+ "params" in subSpec ? subSpec.params : [],
1083
+ );
1084
+ expect(subspecParams.length).toBeGreaterThan(0);
1094
1085
  expect(newSpec).toMatchSnapshot();
1095
1086
  expect(parse(newSpec)).toBeDefined();
1096
1087
  });
@@ -1120,13 +1111,12 @@ describe("makeSelectable", () => {
1120
1111
 
1121
1112
  // Chart selection params should NOT be hoisted (different encodings)
1122
1113
  // Point chart uses x,y encodings, arc chart uses color encoding
1123
- if ("hconcat" in newSpec) {
1124
- const subspecParams = newSpec.hconcat.flatMap((subSpec) =>
1125
- "params" in subSpec ? subSpec.params : [],
1126
- );
1127
- // Both subspecs should have their own params
1128
- expect(subspecParams.length).toBeGreaterThan(0);
1129
- }
1114
+ invariant("hconcat" in newSpec, "expected a horizontal concat spec");
1115
+ const subspecParams = newSpec.hconcat.flatMap((subSpec) =>
1116
+ "params" in subSpec ? subSpec.params : [],
1117
+ );
1118
+ // Both subspecs should have their own params
1119
+ expect(subspecParams.length).toBeGreaterThan(0);
1130
1120
  expect(newSpec).toMatchSnapshot();
1131
1121
  expect(parse(newSpec)).toBeDefined();
1132
1122
  });
@@ -1161,13 +1151,12 @@ describe("makeSelectable", () => {
1161
1151
 
1162
1152
  // But chart-specific params may or may not be hoisted depending on if they match
1163
1153
  // The point chart has x,y encodings, bar has x encoding - these differ
1164
- if ("hconcat" in newSpec) {
1165
- const subspecParams = newSpec.hconcat.flatMap((subSpec) =>
1166
- "params" in subSpec ? subSpec.params : [],
1167
- );
1168
- // Each subspec should have its own chart selection params
1169
- expect(subspecParams.length).toBeGreaterThan(0);
1170
- }
1154
+ invariant("hconcat" in newSpec, "expected a horizontal concat spec");
1155
+ const subspecParams = newSpec.hconcat.flatMap((subSpec) =>
1156
+ "params" in subSpec ? subSpec.params : [],
1157
+ );
1158
+ // Each subspec should have its own chart selection params
1159
+ expect(subspecParams.length).toBeGreaterThan(0);
1171
1160
  expect(newSpec).toMatchSnapshot();
1172
1161
  expect(parse(newSpec)).toBeDefined();
1173
1162
  });
@@ -1331,16 +1320,21 @@ describe("pan/zoom modifier key (issue #3812)", () => {
1331
1320
  const newSpec = makeSelectable(spec, {});
1332
1321
  const mod = getPanZoomModifier();
1333
1322
 
1334
- for (const param of newSpec.params ?? []) {
1335
- if (!("select" in param) || typeof param.select !== "object") {
1336
- continue;
1337
- }
1338
- const select = param.select as { on?: string; translate?: string };
1323
+ const eventSelections = (newSpec.params ?? [])
1324
+ .flatMap((param) =>
1325
+ "select" in param && typeof param.select === "object"
1326
+ ? [param.select as { on?: string; translate?: string }]
1327
+ : [],
1328
+ )
1329
+ .filter(
1330
+ (select): select is { on: string; translate?: string } =>
1331
+ typeof select.on === "string" && select.on.includes("event."),
1332
+ );
1333
+ expect(eventSelections).not.toHaveLength(0);
1334
+ for (const select of eventSelections) {
1339
1335
  // The selection gating and pan/zoom must agree on the modifier, otherwise
1340
1336
  // one gesture triggers both.
1341
- if (typeof select.on === "string" && select.on.includes("event.")) {
1342
- expect(select.on).toContain(`event.${mod}`);
1343
- }
1337
+ expect(select.on).toContain(`event.${mod}`);
1344
1338
  }
1345
1339
  });
1346
1340
  });
@@ -213,15 +213,16 @@ describe("PathBuilder", () => {
213
213
  "should handle unicode and spaces in path operations: %s",
214
214
  (filename) => {
215
215
  const baseName = Paths.basename(filename);
216
- const extension = Paths.extension(filename);
217
216
 
218
217
  // Should preserve unicode characters in basename
219
218
  expect(baseName).toContain(filename.split(".")[0]);
219
+ },
220
+ );
220
221
 
221
- // Should correctly extract extension
222
- if (filename.includes(".")) {
223
- expect(extension).toBe(filename.split(".").pop());
224
- }
222
+ it.each(EDGE_CASE_FILENAMES)(
223
+ "should extract the extension from edge-case filenames: %s",
224
+ (filename) => {
225
+ expect(Paths.extension(filename)).toBe("py");
225
226
  },
226
227
  );
227
228
  });