import {
  getCategoryGroupsetting,
  getGeneVariantTw,
  getGenesetMutTw,
  getSamplelstTw,
  getScctTw,
  getScgeneexpTw,
  getSsgseaTw
} from "./chunk-7FACFCZK.js";
import {
  detectGte,
  detectLst,
  detectOne,
  sleep,
  whenVisible
} from "./chunk-DJQTUDJM.js";
import {
  getRunPp
} from "./chunk-W55XSG6K.js";
import {
  require_tape
} from "./chunk-QWOE5YTB.js";
import "./chunk-74ZU4BT6.js";
import "./chunk-IW57W7EQ.js";
import "./chunk-ZTYNN6G5.js";
import "./chunk-DKVUOBIE.js";
import "./chunk-PRZWSBMA.js";
import "./chunk-LTOBEUM2.js";
import "./chunk-MKAF2BHB.js";
import "./chunk-WKNI3HRQ.js";
import "./chunk-VGYTAYFK.js";
import "./chunk-67DBIM6H.js";
import {
  fillTermWrapper,
  filterJoin,
  getFilterItemByTag
} from "./chunk-SA7APTJR.js";
import "./chunk-HJ6L54YS.js";
import "./chunk-LSEFWW72.js";
import "./chunk-SKREEF3H.js";
import "./chunk-HYOEWQ5P.js";
import "./chunk-HBW42TDT.js";
import "./chunk-G6O3URDN.js";
import "./chunk-FN5XPUPH.js";
import "./chunk-IIT367QZ.js";
import "./chunk-RZGEKL77.js";
import "./chunk-UI7OCM2A.js";
import "./chunk-YZK37YCC.js";
import "./chunk-7EMWHCVW.js";
import "./chunk-7IYJZZQI.js";
import "./chunk-M3J4MINX.js";
import "./chunk-PF4DSFDR.js";
import "./chunk-QH6W3NVF.js";
import {
  SINGLECELL_CELLTYPE
} from "./chunk-NOEAT6CX.js";
import "./chunk-4UWS5Y3N.js";
import "./chunk-DD4R5P6W.js";
import "./chunk-JNITUVXP.js";
import "./chunk-KSGA62R2.js";
import "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import "./chunk-OAWQ6LOO.js";
import "./chunk-TLT4YIG3.js";
import "./chunk-KYBIQBXE.js";
import "./chunk-I6Y4O3RR.js";
import "./chunk-OMR2DT66.js";
import "./chunk-DQC5FFGV.js";
import {
  __toESM
} from "./chunk-HFNDKYVF.js";

// plots/test/violin.integration.spec.js
var import_tape = __toESM(require_tape(), 1);

// plots/test/helpers.spec.ts
async function testViolinByCount(test, div, count) {
  const groups = await detectLst({ elem: div.node(), selector: "path.sjpp-vp-path", count: count * 2 });
  test.ok(groups, `Detected ${count} violin <path class=sjpp-vp-path>`);
}

// plots/test/violin.integration.spec.js
(0, import_tape.default)("\n", function(test) {
  test.comment("-***- plots/violin -***-");
  test.end();
});
(0, import_tape.default)("agedx/sex, basic rendering", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      plots: [open_state]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    violin.on("postRender.test", null);
    const legendDiv = violin.Inner.dom.legendDiv;
    const violinDiv = violin.Inner.dom.violinDiv;
    const violinDivControls = violin.Inner.dom.controls;
    const violinDivData = violin.Inner.data.charts;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    testPlotTitle(violinDiv, violinDivControls);
    testPvalue(violin, violinDiv, violinDivData);
    testDescrStats(violin, legendDiv);
    await testMedianRendering(violin, violinDiv);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  function testPlotTitle(violinDiv, violinDivControls) {
    const label = violinDiv.node().querySelector(".sjpp-numeric-term-label").innerHTML;
    test.equal(
      violinDivControls.node().querySelector(".ts_pill").innerHTML = label,
      label,
      "Plot title is same as ts-pill label"
    );
  }
  function testPvalue(violin, violinDiv, violinDivData) {
    const violinPvalueDiv = violinDiv.selectAll(".sjpp-tableHolder");
    test.equal(violinPvalueDiv.size(), 1, "Should have 1 p-value table");
    const pvalues = violinDivData[""].pvalues;
    test.equal(
      +pvalues[0][2].html,
      +violinPvalueDiv.node().querySelectorAll(".sjpp_table_item")[5].innerHTML,
      `Should render correct p-value of ${+violinPvalueDiv.node().querySelectorAll(".sjpp_table_item")[5].innerHTML}.`
    );
  }
  function testDescrStats(violin, legendDiv) {
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[0].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.total.value,
      "Should render Total n values."
    );
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[1].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.min.value,
      "Should render Minimum value."
    );
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[2].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.p25.value,
      "Should render 1st quartile value."
    );
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[3].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.median.value,
      "Should render Median value."
    );
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[4].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.p75.value,
      "Should render 3rd quartile value."
    );
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[5].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.max.value,
      "Should render Max value."
    );
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[6].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.mean.value,
      "Should render Mean value."
    );
    test.equal(
      +legendDiv.node().querySelectorAll(".legend-row")[7].innerText.split(":")[1],
      +violin.Inner.config.term.q.descrStats.stdDev.value,
      "Should render Standard deviation."
    );
  }
  async function testMedianRendering(violin, violinDiv) {
    const median = await detectGte({
      elem: violinDiv.node(),
      selector: ".sjpp-median-line",
      count: 2
    });
    test.ok(median, "Should render median line(s)");
    test.equal(median.length, violin.Inner.data.charts[""].plots.length, "Should render correct number of median lines");
    const medianValues = median.map(({ __data__: { summaryStats } }) => {
      const { value } = summaryStats.median;
      return value;
    });
    const sumStatsValues = violin.Inner.data.charts[""].plots.map(({ summaryStats }) => {
      const { value } = summaryStats.median;
      return value;
    });
    test.equal(
      medianValues[0],
      sumStatsValues[0],
      `Should render median correctly for plot ${violin.Inner.data.charts[""].plots[0].label}`
    );
    test.equal(
      medianValues[1],
      sumStatsValues[1],
      `Should render median correctly for plot ${violin.Inner.data.charts[""].plots[1].label}`
    );
  }
});
(0, import_tape.default)("agedx/sex, basic controls", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      plots: [open_state]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    violin.on("postRender.test", null);
    const violinDiv = violin.Inner.dom.violinDiv;
    await changeSvgw(violin, violinDiv);
    await changeMedianSize(violin, violinDiv);
    await changeOrientation(violin, violinDiv);
    await changeDataSymbol(violin, violinDiv);
    await changeStrokeWidth(violin);
    await changeSymbolSize(violin);
    await changeScaleToLog(violin, violinDiv);
    await changeOverlayTerm(violin, violinDiv);
    await changeModeToDiscrete(violin);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  async function changeSvgw(violin, violinDiv) {
    const svgw = 333;
    await violin.Inner.app.dispatch({
      type: "plot_edit",
      id: violin.Inner.id,
      config: {
        settings: {
          violin: { svgw }
        }
      }
    });
    test.equal(violin.Inner.app.Inner.state.plots[0].settings.violin.svgw, svgw, "svgw changed in state");
  }
  async function changeMedianSize(violin, violinDiv) {
    const testMedianLength = 10;
    const testMedianThickness = 10;
    const medianEle = await detectGte({
      elem: violinDiv.node(),
      selector: ".sjpp-median-line",
      count: 1,
      async trigger() {
        await violin.Inner.app.dispatch({
          type: "plot_edit",
          id: violin.Inner.id,
          config: {
            settings: {
              violin: {
                medianLength: testMedianLength,
                medianThickness: testMedianThickness
              }
            }
          }
        });
      }
    });
    test.ok(medianEle, "Median exists");
    test.equal(
      violin.Inner.app.Inner.state.plots[0].settings.violin.medianLength,
      testMedianLength,
      "Should change Median length in state"
    );
    test.equal(
      violin.Inner.app.Inner.state.plots[0].settings.violin.medianLength,
      testMedianLength,
      "Should change Median thickness in state"
    );
  }
  async function changeOrientation(violin, violinDiv) {
    await violin.Inner.app.dispatch({
      type: "plot_edit",
      id: violin.Inner.id,
      config: {
        settings: {
          violin: {
            orientation: "vertical"
          }
        }
      }
    });
    test.equal(
      violin.Inner.app.Inner.state.plots[0].settings.violin.orientation,
      "vertical",
      "Should change orientation to vertical in state"
    );
  }
  async function changeDataSymbol(violin, violinDiv) {
    await violin.Inner.app.dispatch({
      type: "plot_edit",
      id: violin.Inner.id,
      config: {
        settings: {
          violin: {
            datasymbol: "rug"
          }
        }
      }
    });
    test.true(
      violin.Inner.app.Inner.state.plots[0].settings.violin.datasymbol === "rug",
      "Should change Data Symbol to Ticks"
    );
  }
  async function changeStrokeWidth(violin) {
    const testStrokeWidth = 1;
    await violin.Inner.app.dispatch({
      type: "plot_edit",
      id: violin.Inner.id,
      config: {
        settings: {
          violin: {
            strokeWidth: testStrokeWidth
          }
        }
      }
    });
    test.true(
      violin.Inner.app.Inner.state.plots[0].settings.violin.strokeWidth === testStrokeWidth,
      `Should change stroke width to ${testStrokeWidth}`
    );
  }
  async function changeSymbolSize(violin) {
    const testSymSize = 10;
    await violin.Inner.app.dispatch({
      type: "plot_edit",
      id: violin.Inner.id,
      config: {
        settings: {
          violin: {
            radius: testSymSize
          }
        }
      }
    });
    test.true(
      violin.Inner.app.Inner.state.plots[0].settings.violin.radius === testSymSize,
      `Symbol size changed to ${testSymSize}`
    );
  }
  async function changeOverlayTerm(violin, violinDiv) {
    const term2 = await fillTermWrapper({ id: "genetic_race" }, violin.Inner.app.vocabApi);
    await violin.Inner.app.dispatch({
      type: "plot_edit",
      id: violin.Inner.id,
      config: {
        term2
      }
    });
    test.true(violin.Inner.app.Inner.state.plots[0].term2.term.id === "genetic_race", "Overlay term changed");
  }
  async function changeScaleToLog(violin, violinDiv) {
    const showLogScale = await detectOne({
      elem: violinDiv.node(),
      selector: ".sjpp-logscale",
      async trigger() {
        await violin.Inner.app.dispatch({
          type: "plot_edit",
          id: violin.Inner.id,
          config: {
            settings: {
              violin: {
                isLogScale: true,
                plotThickness: 150
              }
            }
          }
        });
      }
    });
    test.ok(showLogScale, "Log scale exists");
    test.true(violin.Inner.app.Inner.state.plots[0].settings.violin.isLogScale, "Axis scale rendered in log");
  }
  async function changeModeToDiscrete(violin, violinDiv) {
    violin.Inner.app.dispatch({
      id: violin.Inner.id,
      type: "plot_edit",
      config: {
        term: await fillTermWrapper({ id: "agedx", q: { mode: "discrete" } }, violin.Inner.app.vocabApi)
      }
    });
    await sleep(20);
    test.true(violin.Inner.app.Inner.state.plots[0].term.q.mode === "discrete", "q.mode changed to 'Discrete' ");
  }
});
(0, import_tape.default)("test label clicking, filtering and hovering", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      nav: {
        header_mode: "hide_search"
      },
      plots: [open_state]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    violin.on("postRender.test", null);
    const violinDiv = violin.Inner.dom.violinDiv;
    const violinDivData = violin.Inner.data.charts[""].plots;
    const violinSettings = violin.Inner.config.settings.violin;
    await testLabelHoverClick(test, violin, violinDiv, 2);
    await testFiltering(violin, violinSettings, violinDivData);
    await testLabelHoverClick(test, violin, violinDiv, 1);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  async function testFiltering(violin) {
    const tvslst = {
      type: "tvslst",
      in: true,
      join: "and",
      lst: [
        {
          tvs: {
            term: {
              groupsetting: { disabled: true },
              id: "sex",
              isleaf: true,
              name: "Sex",
              type: "categorical",
              values: {
                1: { label: "Male" },
                2: { label: "Female" }
              }
            },
            values: [{ key: "2" }]
          },
          type: "tvs"
        },
        {
          type: "tvs",
          tvs: {
            ranges: [
              {
                start: 12.289737495475805,
                stop: 16.794964344698805
              }
            ],
            term: {
              id: "agedx",
              isleaf: true,
              name: "Age (years) at Cancer Diagnosis",
              type: "float",
              bins: {
                default: {
                  type: "regular-bin",
                  bin_size: 5,
                  startinclusive: true,
                  first_bin: {
                    startunbounded: true,
                    stop: 5
                  }
                },
                label_offset: 1
              }
            }
          }
        }
      ]
    };
    const filterUiRoot = getFilterItemByTag(violin.Inner.state.termfilter.filter, "filterUiRoot");
    const filter = filterJoin([filterUiRoot, tvslst]);
    filter.tag = "filterUiRoot";
    await violin.Inner.app.dispatch({
      type: "filter_replace",
      filter
    });
    test.ok(true, "Filtering works as expected upon given range(start, stop) of values");
  }
});
(0, import_tape.default)("test hide option on label clicking", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      nav: {
        header_mode: "hide_search"
      },
      plots: [open_state]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    violin.on("postRender.test", null);
    const legendDiv = violin.Inner.dom.legendDiv;
    const violinDiv = violin.Inner.dom.violinDiv;
    testHideOption(violin, legendDiv);
    await testHiddenValues(violin, legendDiv, violinDiv);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  function testHideOption(violin) {
    const q = {
      hiddenValues: { [violin.Inner.data.charts[""].plots[0].label]: 1 },
      isAtomic: true,
      type: "values"
    };
    violin.Inner.app.dispatch({
      type: "plot_edit",
      id: violin.Inner.id,
      config: {
        term2: {
          isAtomic: true,
          id: violin.Inner.config.term2.id,
          term: violin.Inner.config.term2.term,
          q
        }
      }
    });
    test.ok(true, "label Clicking and Hide option ok!");
  }
  async function testHiddenValues(violin, legendDiv, violinDiv) {
    const htmlLegends = await detectGte({ elem: legendDiv.node(), selector: ".sjpp-htmlLegend" });
    test.ok(htmlLegends, "Legend exists");
    const hiddenKeys = Object.keys(violin.Inner.config.term2.q.hiddenValues);
    test.equal(
      Object.keys(violin.Inner.config.term2.q.hiddenValues)[0],
      htmlLegends[8].innerHTML,
      "q.hiddenValues match legend"
    );
    const unhideLegendValue = htmlLegends.filter((c) => hiddenKeys.find((k) => c.__data__.text === k));
    unhideLegendValue[0].dispatchEvent(new Event("click"), { bubbles: true });
    const hiddenValueRendered = await detectGte({
      elem: violinDiv.node(),
      selector: '[data-testid="sjpp-violin-label"]',
      count: 2
    });
    test.ok(hiddenValueRendered, "hidden value rendered");
    test.equal(
      hiddenValueRendered[0].__data__.label,
      unhideLegendValue[0].innerHTML,
      "Clicking on hidden legend value renders the hidden plot"
    );
  }
});
(0, import_tape.default)("term1=categorical, term2=numeric", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "diaggrp" },
          term2: { id: "agedx", q: { mode: "continuous" } }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testLabelHoverClick(test, violin, violinDiv, 7);
    await testViolinByCount(test, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=numeric, term2=cat groupsetting", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "agedx", q: { mode: "continuous" } },
          term2: getCategoryGroupsetting()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testLabelHoverClick(test, violin, violinDiv, 2);
    await testViolinByCount(test, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=numeric, term2=survival", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "agedx", q: { mode: "continuous" } },
          term2: { id: "efs" }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=numeric, term2=geneVariant", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "agedx", q: { mode: "continuous" } },
          term2: getGeneVariantTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 1);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=numeric, term2=geneVariant geneset", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "agedx", q: { mode: "continuous" } },
          term2: getGenesetMutTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 1);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=numeric, term2=condition", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "agedx", q: { mode: "continuous" } },
          term2: { id: "Hearing loss" }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 1);
    await testConditionTermOrder(violin, violinDiv);
    await testLabelHoverClick(test, violin, violinDiv, 5);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  async function testConditionTermOrder(violin, violinDiv) {
    const groups = await detectGte({ elem: violinDiv.node(), selector: ".sjpp-vp-path", count: 1 });
    test.ok(groups, "Condition groups exist");
    test.deepEqual(
      groups.filter((k, i) => i % 2 == 0).map((k) => k.__data__.label),
      violin.Inner.data.charts[""].plots.filter((plot) => plot.plotValueCount > 5).map((k) => k.label),
      "Order of conditional categories in term2 is accurate"
    );
  }
});
(0, import_tape.default)("term1=geneExp, term2=categorical", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            term: { gene: "TP53", name: "TP53", type: "geneExpression" },
            q: { mode: "continuous" }
          },
          term2: { id: "diaggrp" }
        }
      ]
    },
    violin: { callbacks: { "postRender.test": runTests } }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 7);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=geneExp, term2=cat groupsetting", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            term: { gene: "TP53", name: "TP53", type: "geneExpression" },
            q: { mode: "continuous" }
          },
          term2: getCategoryGroupsetting()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=geneExp, term2=geneVariant", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            term: { gene: "TP53", name: "TP53", type: "geneExpression" },
            q: { mode: "continuous" }
          },
          term2: getGeneVariantTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 1);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=geneExp, term2=geneVariant geneset", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            term: { gene: "TP53", name: "TP53", type: "geneExpression" },
            q: { mode: "continuous" }
          },
          term2: getGenesetMutTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 1);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=ssgsea, term2=categorical", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: getSsgseaTw(),
          term2: {
            id: "diaggrp"
          }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 7);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=ssgsea, term2=cat groupsetting", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: getSsgseaTw(),
          term2: getCategoryGroupsetting()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=ssgsea, term2=geneVariant", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: getSsgseaTw(),
          term2: getGeneVariantTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 1);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=ssgsea, term2=geneVariant geneset", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: getSsgseaTw(),
          term2: getGenesetMutTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 1);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
import_tape.default.skip("term1=geneExp, term2=survival (SKIPPED)", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            term: { gene: "TP53", name: "TP53", type: "geneExpression" },
            q: { mode: "continuous" }
          },
          term2: {
            id: "efs"
          }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolin(violin, violinDiv);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  async function testViolin(violin, violinDiv) {
    const groups = await detectGte({ elem: violinDiv.node(), selector: ".sjpp-vp-path", count: 2 });
    test.ok(groups, "survival groups exist");
  }
});
(0, import_tape.default)("term1=numeric, term2=samplelst", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "agedx", q: { mode: "continuous" } },
          term2: getSamplelstTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=geneexp, term2=samplelst", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            term: { gene: "TP53", name: "TP53", type: "geneExpression" },
            q: { mode: "continuous" }
          },
          term2: getSamplelstTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=ssgsea, term2=samplelst", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: getSsgseaTw(),
          term2: getSamplelstTw()
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 2);
    await testLabelHoverClick(test, violin, violinDiv, 2);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term=agedx, term2=geneExp with regular bins", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            id: "agedx",
            q: { mode: "continuous" }
          },
          term2: {
            term: { gene: "TP53", name: "TP53", type: "geneExpression" },
            q: {
              type: "regular-bin",
              startinclusive: true,
              bin_size: 5,
              first_bin: {
                stop: 5
              },
              last_bin: {
                start: 35
              },
              mode: "discrete"
            }
          }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 4);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term=agedx, term2=geneExp with custom bins", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: { id: "agedx", q: { mode: "continuous" } },
          term2: {
            term: { gene: "TP53", type: "geneExpression", bins: { type: "custom-bin" } },
            q: {
              type: "custom-bin",
              mode: "discrete",
              lst: [
                {
                  startunbounded: true,
                  stop: 10,
                  startinclusive: true,
                  stopinclusive: false,
                  label: "<10"
                },
                {
                  start: 10,
                  startinclusive: true,
                  stopinclusive: false,
                  stop: 15,
                  label: "10 to <15"
                },
                {
                  start: 15,
                  startinclusive: true,
                  stopinclusive: false,
                  stopunbounded: true,
                  label: "\u226515"
                }
              ],
              startinclusive: true
            }
          }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 3);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("term1=numeric, term0=categorical", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            id: "agedx",
            q: { mode: "continuous" }
          },
          term0: {
            id: "sex",
            isAtomic: true
          }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolin(violin, violinDiv);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  async function testViolin(violin, violinDiv) {
    const chartDivs = await detectGte({ elem: violinDiv.node(), selector: ".sjpp-vp-chartDiv" });
    test.equal(chartDivs.length, 2, "Should have 2 charts");
    const violinPaths = await detectGte({ elem: violinDiv.node(), selector: ".sjpp-vp-path" });
    test.equal(violinPaths.length, 4, "Should have 4 paths");
  }
});
(0, import_tape.default)("term1=numeric, term2=numeric, term0=categorical", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            id: "agedx",
            q: { mode: "continuous" }
          },
          term2: {
            id: "aaclassic_5",
            isAtomic: true
          },
          term0: {
            id: "sex",
            isAtomic: true
          }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolin(violin, violinDiv);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  async function testViolin(violin, violinDiv) {
    const chartDivs = await detectGte({ elem: violinDiv.node(), selector: ".sjpp-vp-chartDiv" });
    test.equal(chartDivs.length, 2, "Should have 2 charts");
    const violinPaths = await detectGte({ elem: violinDiv.node(), selector: ".sjpp-vp-path" });
    test.equal(violinPaths.length, 6, "Should have 6 paths");
  }
});
(0, import_tape.default)("test uncomputable categories legend", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      nav: {
        header_mode: "hide_search"
      },
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            id: "aaclassic_5",
            isAtomic: true,
            q: {
              mode: "continuous"
            }
          }
        }
      ]
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    const legendDiv = violin.Inner.dom.legendDiv;
    violin.on("postRender.test", null);
    await testUncomputableCategories(violin, legendDiv);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
  async function testUncomputableCategories(violin, legendDiv) {
    const keys = Object.keys(violin.Inner.data.uncomputableValues);
    const categories = await detectGte({ elem: legendDiv.node(), selector: ".legend-row", count: 9 });
    test.ok(categories, "Uncomputable categories exist");
    const uncomputableLegend = categories.filter((c) => keys.find((k) => c.__data__.text.startsWith(k)));
    test.equal(keys.length, uncomputableLegend.length, "should have the correct number of uncomputable legend entries");
    test.equal(
      uncomputableLegend.find((c) => c.__data__.text.startsWith(keys[0]))?.__data__.text.split(",").pop(),
      " n = " + violin.Inner.data.uncomputableValues[keys[0]],
      `Uncomputable category '${keys[0]}' rendered with the correct count`
    );
    test.equal(
      uncomputableLegend.find((c) => c.__data__.text.startsWith(keys[1]))?.__data__.text.split(",").pop(),
      " n = " + violin.Inner.data.uncomputableValues[keys[1]],
      `Uncomputable category '${keys[1]}' rendered with the correct count`
    );
  }
});
(0, import_tape.default)("Load linear regression-violin UI", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      plots: [
        {
          chartType: "regression",
          hasUnsubmittedEdits: true,
          regressionType: "linear",
          outcome: {
            id: "hrtavg",
            isAtomic: true
          }
        }
      ]
    },
    regression: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(regression) {
    regression.on("postRender.test", null);
    await testViolinByCount(test, regression.Inner.inputs.outcome.dom.holder, 1);
    if (test._ok) regression.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("Test violin render with term1=singleCellExpression, term2=singleCellCellType", function(test) {
  test.timeoutAfter(3e3);
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          term: getScgeneexpTw(),
          term2: getScctTw()
        }
      ],
      vocab: {
        genome: "hg38-test",
        dslabel: "TermdbTest"
      }
    },
    violin: {
      callbacks: {
        "postRender.test": runTests
      }
    }
  });
  async function runTests(violin) {
    violin.on("postRender.test", null);
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 3);
    await testLabelHoverClick(test, violin, violinDiv, 3);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
(0, import_tape.default)("Test violin rendering with term1=dnameth, term2=geneExp", function(test) {
  runpp({
    state: {
      plots: [
        {
          chartType: "summary",
          childType: "violin",
          term: {
            term: {
              type: "dnaMethylation",
              chr: "chr17",
              start: 7673484,
              stop: 7681953,
              genomicFeatureType: "promoter"
            },
            q: { mode: "continuous" }
          },
          term2: { term: { gene: "TP53", name: "TP53", type: "geneExpression" } }
        }
      ]
    },
    violin: { callbacks: { "postRender.test": runTests } }
  });
  async function runTests(violin) {
    const violinDiv = violin.Inner.dom.violinDiv;
    await testViolinByCount(test, violinDiv, 4);
    await testLabelHoverClick(test, violin, violinDiv, 8);
    if (test._ok) violin.Inner.app.destroy();
    test.end();
  }
});
var runpp = getRunPp("mass", {
  state: {
    nav: { activeTab: 1 },
    vocab: { dslabel: "TermdbTest", genome: "hg38-test" }
  },
  debug: 1
});
var open_state = {
  chartType: "summary",
  childType: "violin",
  term: {
    id: "agedx",
    q: { mode: "continuous" }
  },
  term2: { id: "sex" }
};
async function testLabelHoverClick(test, violin, violinDiv, labelcount) {
  const labs = await detectLst({
    elem: violinDiv.node(),
    selector: '[data-testid="sjpp-violin-label"]',
    count: labelcount
  });
  test.ok(labs, `Detected ${labelcount} violin labels`);
  for (let i = 0; i < labelcount; i++) {
    const n = violin.Inner.data.charts[""].plots[i].values.length;
    test.ok(labs[i].innerHTML.endsWith("n=" + n), `violin #${i} label text ends with "n=${n}"`);
  }
  labs[0].dispatchEvent(new Event("mouseover"), { bubbles: true });
  {
    const tip2 = violin.Inner.dom.hovertip;
    await whenVisible(tip2.d);
    const table = await detectOne({ elem: tip2.dnode, selector: '[data-testid="sja_simpletable"]' });
    test.pass("summary stat table found in hover tooltip");
    tip2.hide();
  }
  labs[0].dispatchEvent(new Event("click"), { bubbles: true });
  const tip = violin.Inner.dom.clicktip;
  if (!violin.Inner.state.config.term2 || violin.Inner.state.config.term2.term.type == SINGLECELL_CELLTYPE) {
    test.equal(tip.d.style("display"), "none", "Clicked on first label and app.tip will not show");
  } else {
    await whenVisible(tip.d);
    test.pass("Clicked on first label and app.tip will show");
    await detectOne({ elem: tip.dnode, selector: '[data-testid="sjpp-violinLabOpt-addf"]' });
    test.pass("Add filter option is in menu");
    await detectOne({ elem: tip.dnode, selector: '[data-testid="sjpp-violinLabOpt-hide"]' });
    test.pass("Hide option is in menu");
    const lab = await detectOne({ elem: tip.dnode, selector: '[data-testid="sjpp-violinLabOpt-list"]' });
    test.pass("List option is in menu");
    await whenVisible(violin.Inner.dom.sampletabletip.d);
    lab.dispatchEvent(new Event("click"));
    await detectOne({ elem: violin.Inner.dom.sampletabletip.dnode, selector: '[data-testid="sjpp-listsampletable"]' });
    test.pass('Tip with sample table displayed after clicking "List sample"');
    violin.Inner.dom.sampletabletip.hide();
    tip.hide();
  }
}
//# sourceMappingURL=violin.integration.spec-RJATDLQH.js.map
