import { assertTypes, filterOutComments, ordinal, createDefer, isNegativeNaN, isObject, toArray, objectAttr, unique } from "../../utils/dist/helpers.js";
import { getSafeTimers } from "../../utils/dist/timers.js";
import { format, formatRegExp, objDisplay } from "../../utils/dist/display.js";
import { a as createChainable, w as getChainableContext, v as validateTags, e as createTaskName, x as createNoTagsError, f as findTestFileStackTrace } from "./chunk-tasks.js";
class PendingError extends Error {
  code = "VITEST_PENDING";
  taskId;
  constructor(message, task, note) {
    super(message);
    this.message = message;
    this.note = note;
    this.taskId = task.id;
  }
}
class FixtureDependencyError extends Error {
  name = "FixtureDependencyError";
}
class FixtureAccessError extends Error {
  name = "FixtureAccessError";
}
class FixtureParseError extends Error {
  name = "FixtureParseError";
}
const fnMap = /* @__PURE__ */ new WeakMap();
const testFixtureMap = /* @__PURE__ */ new WeakMap();
const hooksMap = /* @__PURE__ */ new WeakMap();
function setFn(key, fn) {
  fnMap.set(key, fn);
}
function setTestFixture(key, fixture) {
  testFixtureMap.set(key, fixture);
}
function getTestFixtures(key) {
  return testFixtureMap.get(key);
}
function setHooks(key, hooks) {
  hooksMap.set(key, hooks);
}
function getHooks(key) {
  return hooksMap.get(key);
}
class TestFixtures {
  _suiteContexts;
  _overrides = /* @__PURE__ */ new WeakMap();
  _registrations;
  static _definitions = [];
  static _builtinFixtures = [
    "task",
    "signal",
    "onTestFailed",
    "onTestFinished",
    "skip",
    "annotate"
  ];
  static _fixtureOptionKeys = [
    "auto",
    "injected",
    "scope"
  ];
  static _fixtureScopes = [
    "test",
    "file",
    "worker"
  ];
  static _workerContextSuite = { type: "worker" };
  static clearDefinitions() {
    TestFixtures._definitions.length = 0;
  }
  static getWorkerContexts() {
    return TestFixtures._definitions.map((f) => f.getWorkerContext());
  }
  static getFileContexts(file) {
    return TestFixtures._definitions.map((f) => f.getFileContext(file));
  }
  constructor(registrations) {
    this._registrations = registrations ?? /* @__PURE__ */ new Map();
    this._suiteContexts = /* @__PURE__ */ new WeakMap();
    TestFixtures._definitions.push(this);
  }
  extend(runner2, userFixtures) {
    const { suite: suite2 } = getCurrentSuite();
    const isTopLevel = !suite2 || suite2.file === suite2;
    const registrations = this.parseUserFixtures(runner2, userFixtures, isTopLevel);
    return new TestFixtures(registrations);
  }
  get(suite2) {
    let currentSuite = suite2;
    while (currentSuite) {
      const overrides = this._overrides.get(currentSuite);
      if (overrides) {
        return overrides;
      }
      if (currentSuite === currentSuite.file) {
        break;
      }
      currentSuite = currentSuite.suite || currentSuite.file;
    }
    return this._registrations;
  }
  override(runner2, userFixtures) {
    const { suite: currentSuite, file } = getCurrentSuite();
    const suite2 = currentSuite || file;
    const isTopLevel = !currentSuite || currentSuite.file === currentSuite;
    const suiteRegistrations = new Map(this.get(suite2));
    const registrations = this.parseUserFixtures(runner2, userFixtures, isTopLevel, suiteRegistrations);
    if (isTopLevel) {
      this._registrations = registrations;
    } else {
      this._overrides.set(suite2, registrations);
    }
  }
  getFileContext(file) {
    if (!this._suiteContexts.has(file)) {
      this._suiteContexts.set(file, /* @__PURE__ */ Object.create(null));
    }
    return this._suiteContexts.get(file);
  }
  getWorkerContext() {
    if (!this._suiteContexts.has(TestFixtures._workerContextSuite)) {
      this._suiteContexts.set(TestFixtures._workerContextSuite, /* @__PURE__ */ Object.create(null));
    }
    return this._suiteContexts.get(TestFixtures._workerContextSuite);
  }
  parseUserFixtures(runner2, userFixtures, supportNonTest, registrations = new Map(this._registrations)) {
    const errors = [];
    Object.entries(userFixtures).forEach(([name, fn]) => {
      let options;
      let value;
      let _options;
      if (Array.isArray(fn) && fn.length >= 2 && isObject(fn[1]) && Object.keys(fn[1]).some((key) => TestFixtures._fixtureOptionKeys.includes(key))) {
        _options = fn[1];
        options = {
          auto: _options.auto ?? false,
          scope: _options.scope ?? "test",
          injected: _options.injected ?? false
        };
        value = options.injected ? runner2.injectValue?.(name) ?? fn[0] : fn[0];
      } else {
        value = fn;
      }
      const parent = registrations.get(name);
      if (parent && options) {
        if (parent.scope !== options.scope) {
          errors.push(new FixtureDependencyError(`The "${name}" fixture was already registered with a "${options.scope}" scope.`));
        }
        if (parent.auto !== options.auto) {
          errors.push(new FixtureDependencyError(`The "${name}" fixture was already registered as { auto: ${options.auto} }.`));
        }
      } else if (parent) {
        options = {
          auto: parent.auto,
          scope: parent.scope,
          injected: parent.injected
        };
      } else if (!options) {
        options = {
          auto: false,
          injected: false,
          scope: "test"
        };
      }
      if (options.scope && !TestFixtures._fixtureScopes.includes(options.scope)) {
        errors.push(new FixtureDependencyError(`The "${name}" fixture has unknown scope "${options.scope}".`));
      }
      if (!supportNonTest && options.scope !== "test") {
        errors.push(new FixtureDependencyError(`The "${name}" fixture cannot be defined with a ${options.scope} scope${!_options?.scope && parent?.scope ? " (inherited from the base fixture)" : ""} inside the describe block. Define it at the top level of the file instead.`));
      }
      const deps = isFixtureFunction(value) ? getUsedProps(value) : /* @__PURE__ */ new Set();
      const item = {
        name,
        value,
        auto: options.auto ?? false,
        injected: options.injected ?? false,
        scope: options.scope ?? "test",
        deps,
        parent
      };
      registrations.set(name, item);
      if (item.scope === "worker" && (runner2.pool === "vmThreads" || runner2.pool === "vmForks")) {
        item.scope = "file";
      }
    });
    for (const fixture of registrations.values()) {
      for (const depName of fixture.deps) {
        if (TestFixtures._builtinFixtures.includes(depName)) {
          continue;
        }
        const dep = registrations.get(depName);
        if (!dep) {
          errors.push(new FixtureDependencyError(`The "${fixture.name}" fixture depends on unknown fixture "${depName}".`));
          continue;
        }
        if (depName === fixture.name && !fixture.parent) {
          errors.push(new FixtureDependencyError(`The "${fixture.name}" fixture depends on itself, but does not have a base implementation.`));
          continue;
        }
        if (TestFixtures._fixtureScopes.indexOf(fixture.scope) > TestFixtures._fixtureScopes.indexOf(dep.scope)) {
          errors.push(new FixtureDependencyError(`The ${fixture.scope} "${fixture.name}" fixture cannot depend on a ${dep.scope} fixture "${dep.name}".`));
          continue;
        }
      }
    }
    if (errors.length === 1) {
      throw errors[0];
    } else if (errors.length > 1) {
      throw new AggregateError(errors, "Cannot resolve user fixtures. See errors for more information.");
    }
    return registrations;
  }
}
const cleanupFnArrayMap = /* @__PURE__ */ new WeakMap();
const contextHasFixturesCache = /* @__PURE__ */ new WeakMap();
function withFixtures(fn, options) {
  const collector = getCurrentSuite();
  const suite2 = options?.suite || collector.suite || collector.file;
  return async (hookContext) => {
    const context = hookContext || options?.context;
    if (!context) {
      if (options?.suiteHook) {
        validateSuiteHook(fn, options.suiteHook, options.stackTraceError);
      }
      return fn({});
    }
    const fixtures = options?.fixtures || getTestFixtures(context);
    if (!fixtures) {
      return fn(context);
    }
    const registrations = fixtures.get(suite2);
    if (!registrations.size) {
      return fn(context);
    }
    const usedFixtures = [];
    const usedProps = getUsedProps(fn);
    for (const fixture of registrations.values()) {
      if (fixture.auto || usedProps.has(fixture.name)) {
        usedFixtures.push(fixture);
      }
    }
    if (!usedFixtures.length) {
      return fn(context);
    }
    if (!cleanupFnArrayMap.has(context)) {
      cleanupFnArrayMap.set(context, []);
    }
    const cleanupFnArray = cleanupFnArrayMap.get(context);
    const pendingFixtures = resolveDeps(usedFixtures, registrations);
    if (!pendingFixtures.length) {
      return fn(context);
    }
    if (options?.suiteHook) {
      const testScopedFixtures = pendingFixtures.filter((f) => f.scope === "test");
      if (testScopedFixtures.length > 0) {
        const fixtureNames = testScopedFixtures.map((f) => `"${f.name}"`).join(", ");
        const alternativeHook = {
          aroundAll: "aroundEach",
          beforeAll: "beforeEach",
          afterAll: "afterEach"
        };
        const error = new FixtureDependencyError(`Test-scoped fixtures cannot be used inside ${options.suiteHook} hook. The following fixtures are test-scoped: ${fixtureNames}. Use { scope: 'file' } or { scope: 'worker' } fixtures instead, or move the logic to ${alternativeHook[options.suiteHook]} hook.`);
        if (options.stackTraceError?.stack) {
          error.stack = error.message + options.stackTraceError.stack.replace(options.stackTraceError.message, "");
        }
        throw error;
      }
    }
    if (!contextHasFixturesCache.has(context)) {
      contextHasFixturesCache.set(context, /* @__PURE__ */ new WeakSet());
    }
    const cachedFixtures = contextHasFixturesCache.get(context);
    for (const fixture of pendingFixtures) {
      if (fixture.scope === "test") {
        if (cachedFixtures.has(fixture)) {
          continue;
        }
        cachedFixtures.add(fixture);
        const resolvedValue = await resolveTestFixtureValue(fixture, context, cleanupFnArray);
        context[fixture.name] = resolvedValue;
        cleanupFnArray.push(() => {
          cachedFixtures.delete(fixture);
        });
      } else {
        const resolvedValue = await resolveScopeFixtureValue(fixtures, suite2, fixture);
        context[fixture.name] = resolvedValue;
      }
    }
    return fn(context);
  };
}
function isFixtureFunction(value) {
  return typeof value === "function";
}
function resolveTestFixtureValue(fixture, context, cleanupFnArray) {
  if (!isFixtureFunction(fixture.value)) {
    return fixture.value;
  }
  return resolveFixtureFunction(fixture.value, context, cleanupFnArray);
}
const scopedFixturePromiseCache = /* @__PURE__ */ new WeakMap();
async function resolveScopeFixtureValue(fixtures, suite2, fixture) {
  const workerContext = fixtures.getWorkerContext();
  const fileContext = fixtures.getFileContext(suite2.file);
  const fixtureContext = fixture.scope === "worker" ? workerContext : fileContext;
  if (!isFixtureFunction(fixture.value)) {
    fixtureContext[fixture.name] = fixture.value;
    return fixture.value;
  }
  if (fixture.name in fixtureContext) {
    return fixtureContext[fixture.name];
  }
  if (scopedFixturePromiseCache.has(fixture)) {
    return scopedFixturePromiseCache.get(fixture);
  }
  if (!cleanupFnArrayMap.has(fixtureContext)) {
    cleanupFnArrayMap.set(fixtureContext, []);
  }
  const cleanupFnFileArray = cleanupFnArrayMap.get(fixtureContext);
  const promise = resolveFixtureFunction(fixture.value, fixture.scope === "file" ? {
    ...workerContext,
    ...fileContext
  } : fixtureContext, cleanupFnFileArray).then((value) => {
    fixtureContext[fixture.name] = value;
    scopedFixturePromiseCache.delete(fixture);
    return value;
  });
  scopedFixturePromiseCache.set(fixture, promise);
  return promise;
}
async function resolveFixtureFunction(fixtureFn, context, cleanupFnArray) {
  const useFnArgPromise = createDefer();
  let isUseFnArgResolved = false;
  const fixtureReturn = fixtureFn(context, async (useFnArg) => {
    isUseFnArgResolved = true;
    useFnArgPromise.resolve(useFnArg);
    const useReturnPromise = createDefer();
    cleanupFnArray.push(async () => {
      useReturnPromise.resolve();
      await fixtureReturn;
    });
    await useReturnPromise;
  }).catch((e) => {
    if (!isUseFnArgResolved) {
      useFnArgPromise.reject(e);
      return;
    }
    throw e;
  });
  return useFnArgPromise;
}
function resolveDeps(usedFixtures, registrations, depSet = /* @__PURE__ */ new Set(), pendingFixtures = []) {
  usedFixtures.forEach((fixture) => {
    if (pendingFixtures.includes(fixture)) {
      return;
    }
    if (!isFixtureFunction(fixture.value) || !fixture.deps) {
      pendingFixtures.push(fixture);
      return;
    }
    if (depSet.has(fixture)) {
      if (fixture.parent) {
        fixture = fixture.parent;
      } else {
        throw new Error(`Circular fixture dependency detected: ${fixture.name} <- ${[...depSet].reverse().map((d) => d.name).join(" <- ")}`);
      }
    }
    depSet.add(fixture);
    resolveDeps([...fixture.deps].map((n) => n === fixture.name ? fixture.parent : registrations.get(n)).filter((n) => !!n), registrations, depSet, pendingFixtures);
    pendingFixtures.push(fixture);
    depSet.clear();
  });
  return pendingFixtures;
}
function validateSuiteHook(fn, hook, suiteError) {
  const usedProps = getUsedProps(fn, {
    sourceError: suiteError,
    suiteHook: hook
  });
  if (usedProps.size) {
    const error = new FixtureAccessError(`The ${hook} hook uses fixtures "${[...usedProps].join('", "')}", but has no access to context. Did you forget to call it as "test.${hook}()" instead of "${hook}()"?
If you used internal "suite" task as the first argument previously, access it in the second argument instead. See https://vitest.dev/guide/test-context#suite-level-hooks`);
    if (suiteError) {
      error.stack = suiteError.stack?.replace(suiteError.message, error.message);
    }
    throw error;
  }
}
const kPropsSymbol = /* @__PURE__ */ Symbol("$vitest:fixture-props");
const kPropNamesSymbol = /* @__PURE__ */ Symbol("$vitest:fixture-prop-names");
function configureProps(fn, options) {
  Object.defineProperty(fn, kPropsSymbol, {
    value: options,
    enumerable: false
  });
}
function memoProps(fn, props) {
  fn[kPropNamesSymbol] = props;
  return props;
}
function getUsedProps(fn, { sourceError, suiteHook } = {}) {
  if (kPropNamesSymbol in fn) {
    return fn[kPropNamesSymbol];
  }
  const { index: fixturesIndex = 0, original: implementation = fn } = kPropsSymbol in fn ? fn[kPropsSymbol] : {};
  let fnString = filterOutComments(implementation.toString());
  if (/__async\((?:this|null), (?:null|arguments|\[[_0-9, ]*\]), function\*/.test(fnString)) {
    fnString = fnString.split(/__async\((?:this|null),/)[1];
  }
  const match = fnString.match(/[^(]*\(([^)]*)/);
  if (!match) {
    return memoProps(fn, /* @__PURE__ */ new Set());
  }
  const args = splitByComma(match[1]);
  if (!args.length) {
    return memoProps(fn, /* @__PURE__ */ new Set());
  }
  const fixturesArgument = args[fixturesIndex];
  if (!fixturesArgument) {
    return memoProps(fn, /* @__PURE__ */ new Set());
  }
  if (!(fixturesArgument[0] === "{" && fixturesArgument.endsWith("}"))) {
    const ordinalArgument = ordinal(fixturesIndex + 1);
    const error = new FixtureParseError(`The ${ordinalArgument} argument inside a fixture must use object destructuring pattern, e.g. ({ task } => {}). Instead, received "${fixturesArgument}".${suiteHook ? ` If you used internal "suite" task as the ${ordinalArgument} argument previously, access it in the ${ordinal(fixturesIndex + 2)} argument instead.` : ""}`);
    if (sourceError) {
      error.stack = sourceError.stack?.replace(sourceError.message, error.message);
    }
    throw error;
  }
  const _first = fixturesArgument.slice(1, -1).replace(/\s/g, "");
  const props = splitByComma(_first).map((prop) => {
    return prop.replace(/:.*|=.*/g, "");
  });
  const last = props.at(-1);
  if (last && last.startsWith("...")) {
    const error = new FixtureParseError(`Rest parameters are not supported in fixtures, received "${last}".`);
    if (sourceError) {
      error.stack = sourceError.stack?.replace(sourceError.message, error.message);
    }
    throw error;
  }
  return memoProps(fn, new Set(props));
}
function splitByComma(s) {
  const result = [];
  const stack = [];
  let start = 0;
  for (let i = 0; i < s.length; i++) {
    if (s[i] === "{" || s[i] === "[") {
      stack.push(s[i] === "{" ? "}" : "]");
    } else if (s[i] === stack.at(-1)) {
      stack.pop();
    } else if (!stack.length && s[i] === ",") {
      const token = s.substring(start, i).trim();
      if (token) {
        result.push(token);
      }
      start = i + 1;
    }
  }
  const lastToken = s.substring(start).trim();
  if (lastToken) {
    result.push(lastToken);
  }
  return result;
}
function getDefaultHookTimeout() {
  return getRunner().config.hookTimeout;
}
const CLEANUP_TIMEOUT_KEY = /* @__PURE__ */ Symbol.for("VITEST_CLEANUP_TIMEOUT");
const CLEANUP_STACK_TRACE_KEY = /* @__PURE__ */ Symbol.for("VITEST_CLEANUP_STACK_TRACE");
const AROUND_TIMEOUT_KEY = /* @__PURE__ */ Symbol.for("VITEST_AROUND_TIMEOUT");
const AROUND_STACK_TRACE_KEY = /* @__PURE__ */ Symbol.for("VITEST_AROUND_STACK_TRACE");
function beforeAll(fn, timeout = getDefaultHookTimeout()) {
  assertTypes(fn, '"beforeAll" callback', ["function"]);
  const stackTraceError = new Error("STACK_TRACE_ERROR");
  const context = getChainableContext(this);
  return getCurrentSuite().on("beforeAll", Object.assign(withTimeout(withSuiteFixtures("beforeAll", fn, context, stackTraceError), timeout, true, stackTraceError), {
    [CLEANUP_TIMEOUT_KEY]: timeout,
    [CLEANUP_STACK_TRACE_KEY]: stackTraceError
  }));
}
function afterAll(fn, timeout) {
  assertTypes(fn, '"afterAll" callback', ["function"]);
  const context = getChainableContext(this);
  const stackTraceError = new Error("STACK_TRACE_ERROR");
  return getCurrentSuite().on("afterAll", withTimeout(withSuiteFixtures("afterAll", fn, context, stackTraceError), timeout ?? getDefaultHookTimeout(), true, stackTraceError));
}
function beforeEach(fn, timeout = getDefaultHookTimeout()) {
  assertTypes(fn, '"beforeEach" callback', ["function"]);
  const stackTraceError = new Error("STACK_TRACE_ERROR");
  const wrapper = (context, suite2) => {
    const fixtureResolver = withFixtures(fn, { suite: suite2 });
    return fixtureResolver(context);
  };
  return getCurrentSuite().on("beforeEach", Object.assign(withTimeout(wrapper, timeout ?? getDefaultHookTimeout(), true, stackTraceError, abortIfTimeout), {
    [CLEANUP_TIMEOUT_KEY]: timeout,
    [CLEANUP_STACK_TRACE_KEY]: stackTraceError
  }));
}
function afterEach(fn, timeout) {
  assertTypes(fn, '"afterEach" callback', ["function"]);
  const wrapper = (context, suite2) => {
    const fixtureResolver = withFixtures(fn, { suite: suite2 });
    return fixtureResolver(context);
  };
  return getCurrentSuite().on("afterEach", withTimeout(wrapper, timeout ?? getDefaultHookTimeout(), true, new Error("STACK_TRACE_ERROR"), abortIfTimeout));
}
function aroundAll(fn, timeout) {
  assertTypes(fn, '"aroundAll" callback', ["function"]);
  const stackTraceError = new Error("STACK_TRACE_ERROR");
  const resolvedTimeout = timeout ?? getDefaultHookTimeout();
  const context = getChainableContext(this);
  return getCurrentSuite().on("aroundAll", Object.assign(withSuiteFixtures("aroundAll", fn, context, stackTraceError, 1), {
    [AROUND_TIMEOUT_KEY]: resolvedTimeout,
    [AROUND_STACK_TRACE_KEY]: stackTraceError
  }));
}
function aroundEach(fn, timeout) {
  assertTypes(fn, '"aroundEach" callback', ["function"]);
  const stackTraceError = new Error("STACK_TRACE_ERROR");
  const resolvedTimeout = timeout ?? getDefaultHookTimeout();
  const wrapper = (runTest, context, suite2) => {
    const innerFn = (ctx) => fn(runTest, ctx, suite2);
    configureProps(innerFn, {
      index: 1,
      original: fn
    });
    const fixtureResolver = withFixtures(innerFn, { suite: suite2 });
    return fixtureResolver(context);
  };
  return getCurrentSuite().on("aroundEach", Object.assign(wrapper, {
    [AROUND_TIMEOUT_KEY]: resolvedTimeout,
    [AROUND_STACK_TRACE_KEY]: stackTraceError
  }));
}
function withSuiteFixtures(suiteHook, fn, context, stackTraceError, contextIndex = 0) {
  return (...args) => {
    const suite2 = args.at(-1);
    const prefix = args.slice(0, -1);
    const wrapper = (ctx) => fn(...prefix, ctx, suite2);
    configureProps(wrapper, {
      index: contextIndex,
      original: fn
    });
    const fixtures = context?.getFixtures();
    const fileContext = fixtures?.getFileContext(suite2.file);
    const fixtured = withFixtures(wrapper, {
      suiteHook,
      fixtures,
      context: fileContext,
      stackTraceError
    });
    return fixtured();
  };
}
const suite = createSuite();
const test = createTest(function(name, optionsOrFn, optionsOrTest) {
  getCurrentSuite().test.fn.call(this, formatName(name), optionsOrFn, optionsOrTest);
});
const describe = suite;
const it = test;
let runner;
let defaultSuite;
let currentTestFilepath;
function assert(condition, message) {
  if (!condition) {
    throw new Error(`Vitest failed to find ${message}. One of the following is possible:
- "vitest" is imported directly without running "vitest" command
- "vitest" is imported inside "globalSetup" (to fix this, use "setupFiles" instead, because "globalSetup" runs in a different context)
- "vitest" is imported inside Vite / Vitest config file
- Otherwise, it might be a Vitest bug. Please report it to https://github.com/vitest-dev/vitest/issues
`);
  }
}
function getRunner() {
  assert(runner, "the runner");
  return runner;
}
function getCurrentSuite() {
  const currentSuite = collectorContext.currentSuite || defaultSuite;
  assert(currentSuite, "the current suite");
  return currentSuite;
}
function createSuiteHooks() {
  return {
    beforeAll: [],
    afterAll: [],
    beforeEach: [],
    afterEach: [],
    aroundEach: [],
    aroundAll: []
  };
}
const POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
function parseArguments(optionsOrFn, timeoutOrTest) {
  if (timeoutOrTest != null && typeof timeoutOrTest === "object") {
    throw new TypeError(`Signature "test(name, fn, { ... })" was deprecated in Vitest 3 and removed in Vitest 4. Please, provide options as a second argument instead.`);
  }
  let options = {};
  let fn;
  if (typeof timeoutOrTest === "number") {
    options = { timeout: timeoutOrTest };
  } else if (typeof optionsOrFn === "object") {
    options = optionsOrFn;
  }
  if (typeof optionsOrFn === "function") {
    if (typeof timeoutOrTest === "function") {
      throw new TypeError("Cannot use two functions as arguments. Please use the second argument for options.");
    }
    fn = optionsOrFn;
  } else if (typeof timeoutOrTest === "function") {
    fn = timeoutOrTest;
  }
  return {
    options,
    handler: fn
  };
}
function createSuiteCollector(name, factory = () => {
}, mode, each, suiteOptions) {
  const tasks = [];
  let suite2;
  initSuite();
  const task = function(name2 = "", options = {}) {
    const currentSuite = collectorContext.currentSuite?.suite;
    const parentTask = currentSuite ?? collectorContext.currentSuite?.file;
    const parentTags = parentTask?.tags || [];
    const testTags = unique([...parentTags, ...toArray(options.tags)]);
    const tagsOptions = testTags.map((tag) => {
      const tagDefinition = runner.config.tags?.find((t) => t.name === tag);
      if (!tagDefinition && runner.config.strictTags) {
        throw createNoTagsError(runner.config.tags, tag);
      }
      return tagDefinition;
    }).filter((r) => r != null).sort((tag1, tag2) => (tag2.priority ?? POSITIVE_INFINITY) - (tag1.priority ?? POSITIVE_INFINITY)).reduce((acc, tag) => {
      const { name: name3, description, priority, meta, ...options2 } = tag;
      Object.assign(acc, options2);
      if (meta) {
        acc.meta = Object.assign(acc.meta ?? /* @__PURE__ */ Object.create(null), meta);
      }
      return acc;
    }, {});
    const testOwnMeta = options.meta;
    options = {
      ...tagsOptions,
      ...options
    };
    const timeout = options.timeout ?? runner.config.testTimeout;
    const parentMeta = currentSuite?.meta;
    const tagMeta = tagsOptions.meta;
    const testMeta = /* @__PURE__ */ Object.create(null);
    if (tagMeta) {
      Object.assign(testMeta, tagMeta);
    }
    if (parentMeta) {
      Object.assign(testMeta, parentMeta);
    }
    if (testOwnMeta) {
      Object.assign(testMeta, testOwnMeta);
    }
    const task2 = {
      id: "",
      name: name2,
      fullName: createTaskName([currentSuite?.fullName ?? collectorContext.currentSuite?.file?.fullName, name2]),
      fullTestName: createTaskName([currentSuite?.fullTestName, name2]),
      suite: currentSuite,
      each: options.each,
      fails: options.fails,
      context: void 0,
      type: "test",
      file: currentSuite?.file ?? collectorContext.currentSuite?.file,
      timeout,
      retry: options.retry ?? runner.config.retry,
      repeats: options.repeats,
      mode: options.only ? "only" : options.skip ? "skip" : options.todo ? "todo" : "run",
      meta: testMeta,
      annotations: [],
      artifacts: [],
      tags: testTags
    };
    const handler = options.handler;
    if (task2.mode === "run" && !handler) {
      task2.mode = "todo";
    }
    if (options.concurrent || !options.sequential && runner.config.sequence.concurrent) {
      task2.concurrent = true;
    }
    task2.shuffle = suiteOptions?.shuffle;
    const context = createTestContext(task2, runner);
    Object.defineProperty(task2, "context", {
      value: context,
      enumerable: false
    });
    setTestFixture(context, options.fixtures ?? new TestFixtures());
    const limit = Error.stackTraceLimit;
    Error.stackTraceLimit = 10;
    const stackTraceError = new Error("STACK_TRACE_ERROR");
    Error.stackTraceLimit = limit;
    if (handler) {
      setFn(task2, withTimeout(withCancel(withAwaitAsyncAssertions(withFixtures(handler, { context }), task2), task2.context.signal), timeout, false, stackTraceError, (_, error) => abortIfTimeout([context], error)));
    }
    if (runner.config.includeTaskLocation) {
      const error = stackTraceError.stack;
      const stack = findTestFileStackTrace(currentTestFilepath, error);
      if (stack) {
        task2.location = {
          line: stack.line,
          column: stack.column
        };
      }
    }
    tasks.push(task2);
    return task2;
  };
  const test2 = createTest(function(name2, optionsOrFn, timeoutOrTest) {
    let { options, handler } = parseArguments(optionsOrFn, timeoutOrTest);
    if (typeof suiteOptions === "object") {
      options = Object.assign({}, suiteOptions, options);
    }
    const concurrent = this.concurrent ?? (!this.sequential && options?.concurrent);
    if (options.concurrent != null && concurrent != null) {
      options.concurrent = concurrent;
    }
    const sequential = this.sequential ?? (!this.concurrent && options?.sequential);
    if (options.sequential != null && sequential != null) {
      options.sequential = sequential;
    }
    const test3 = task(formatName(name2), {
      ...this,
      ...options,
      handler
    });
    test3.type = "test";
  });
  const collector = {
    type: "collector",
    name,
    mode,
    suite: suite2,
    options: suiteOptions,
    test: test2,
    file: suite2.file,
    tasks,
    collect,
    task,
    clear,
    on: addHook
  };
  function addHook(name2, ...fn) {
    getHooks(suite2)[name2].push(...fn);
  }
  function initSuite(includeLocation) {
    if (typeof suiteOptions === "number") {
      suiteOptions = { timeout: suiteOptions };
    }
    const currentSuite = collectorContext.currentSuite?.suite;
    const parentTask = currentSuite ?? collectorContext.currentSuite?.file;
    const suiteTags = toArray(suiteOptions?.tags);
    validateTags(runner.config, suiteTags);
    suite2 = {
      id: "",
      type: "suite",
      name,
      fullName: createTaskName([currentSuite?.fullName ?? collectorContext.currentSuite?.file?.fullName, name]),
      fullTestName: createTaskName([currentSuite?.fullTestName, name]),
      suite: currentSuite,
      mode,
      each,
      file: currentSuite?.file ?? collectorContext.currentSuite?.file,
      shuffle: suiteOptions?.shuffle,
      tasks: [],
      meta: suiteOptions?.meta ?? /* @__PURE__ */ Object.create(null),
      concurrent: suiteOptions?.concurrent,
      tags: unique([...parentTask?.tags || [], ...suiteTags])
    };
    setHooks(suite2, createSuiteHooks());
  }
  function clear() {
    tasks.length = 0;
    initSuite();
  }
  async function collect(file) {
    if (!file) {
      throw new TypeError("File is required to collect tasks.");
    }
    if (factory) {
      await runWithSuite(collector, () => factory(test2));
    }
    const allChildren = [];
    for (const i of tasks) {
      allChildren.push(i.type === "collector" ? await i.collect(file) : i);
    }
    suite2.tasks = allChildren;
    return suite2;
  }
  collectTask(collector);
  return collector;
}
function withAwaitAsyncAssertions(fn, task) {
  return (async (...args) => {
    const fnResult = await fn(...args);
    if (task.promises) {
      const result = await Promise.allSettled(task.promises);
      const errors = result.map((r) => r.status === "rejected" ? r.reason : void 0).filter(Boolean);
      if (errors.length) {
        throw errors;
      }
    }
    return fnResult;
  });
}
function createSuite() {
  function suiteFn(name, factoryOrOptions, optionsOrFactory) {
    const currentSuite = collectorContext.currentSuite || defaultSuite;
    let { options, handler: factory } = parseArguments(factoryOrOptions, optionsOrFactory);
    const isConcurrentSpecified = options.concurrent || this.concurrent || options.sequential === false;
    const isSequentialSpecified = options.sequential || this.sequential || options.concurrent === false;
    const { meta: parentMeta, ...parentOptions } = currentSuite?.options || {};
    options = {
      ...parentOptions,
      ...options
    };
    const shuffle = this.shuffle ?? options.shuffle ?? currentSuite?.options?.shuffle ?? runner?.config.sequence.shuffle;
    if (shuffle != null) {
      options.shuffle = shuffle;
    }
    let mode = this.only ?? options.only ? "only" : this.skip ?? options.skip ? "skip" : this.todo ?? options.todo ? "todo" : "run";
    if (mode === "run" && !factory) {
      mode = "todo";
    }
    const isConcurrent = isConcurrentSpecified || options.concurrent && !isSequentialSpecified;
    const isSequential = isSequentialSpecified || options.sequential && !isConcurrentSpecified;
    if (isConcurrent != null) {
      options.concurrent = isConcurrent && !isSequential;
    }
    if (isSequential != null) {
      options.sequential = isSequential && !isConcurrent;
    }
    if (parentMeta) {
      options.meta = Object.assign(/* @__PURE__ */ Object.create(null), parentMeta, options.meta);
    }
    return createSuiteCollector(formatName(name), factory, mode, this.each, options);
  }
  suiteFn.each = function(cases, ...args) {
    const context = getChainableContext(this);
    const suite2 = context.withContext();
    context.setContext("each", true);
    if (Array.isArray(cases) && args.length) {
      cases = formatTemplateString(cases, args);
    }
    return (name, optionsOrFn, fnOrOptions) => {
      const _name = formatName(name);
      const arrayOnlyCases = cases.every(Array.isArray);
      const { options, handler } = parseArguments(optionsOrFn, fnOrOptions);
      const fnFirst = typeof optionsOrFn === "function";
      cases.forEach((i, idx) => {
        const items = Array.isArray(i) ? i : [i];
        if (fnFirst) {
          if (arrayOnlyCases) {
            suite2(formatTitle(_name, items, idx), handler ? () => handler(...items) : void 0, options.timeout);
          } else {
            suite2(formatTitle(_name, items, idx), handler ? () => handler(i) : void 0, options.timeout);
          }
        } else {
          if (arrayOnlyCases) {
            suite2(formatTitle(_name, items, idx), options, handler ? () => handler(...items) : void 0);
          } else {
            suite2(formatTitle(_name, items, idx), options, handler ? () => handler(i) : void 0);
          }
        }
      });
      context.setContext("each", void 0);
    };
  };
  suiteFn.for = function(cases, ...args) {
    if (Array.isArray(cases) && args.length) {
      cases = formatTemplateString(cases, args);
    }
    return (name, optionsOrFn, fnOrOptions) => {
      const name_ = formatName(name);
      const { options, handler } = parseArguments(optionsOrFn, fnOrOptions);
      cases.forEach((item, idx) => {
        suite(formatTitle(name_, toArray(item), idx), options, handler ? () => handler(item) : void 0);
      });
    };
  };
  suiteFn.skipIf = (condition) => condition ? suite.skip : suite;
  suiteFn.runIf = (condition) => condition ? suite : suite.skip;
  return createChainable([
    "concurrent",
    "sequential",
    "shuffle",
    "skip",
    "only",
    "todo"
  ], suiteFn);
}
function createTaskCollector(fn) {
  const taskFn = fn;
  taskFn.each = function(cases, ...args) {
    const context = getChainableContext(this);
    const test2 = context.withContext();
    context.setContext("each", true);
    if (Array.isArray(cases) && args.length) {
      cases = formatTemplateString(cases, args);
    }
    return (name, optionsOrFn, fnOrOptions) => {
      const _name = formatName(name);
      const arrayOnlyCases = cases.every(Array.isArray);
      const { options, handler } = parseArguments(optionsOrFn, fnOrOptions);
      const fnFirst = typeof optionsOrFn === "function";
      cases.forEach((i, idx) => {
        const items = Array.isArray(i) ? i : [i];
        if (fnFirst) {
          if (arrayOnlyCases) {
            test2(formatTitle(_name, items, idx), handler ? () => handler(...items) : void 0, options.timeout);
          } else {
            test2(formatTitle(_name, items, idx), handler ? () => handler(i) : void 0, options.timeout);
          }
        } else {
          if (arrayOnlyCases) {
            test2(formatTitle(_name, items, idx), options, handler ? () => handler(...items) : void 0);
          } else {
            test2(formatTitle(_name, items, idx), options, handler ? () => handler(i) : void 0);
          }
        }
      });
      context.setContext("each", void 0);
    };
  };
  taskFn.for = function(cases, ...args) {
    const context = getChainableContext(this);
    const test2 = context.withContext();
    if (Array.isArray(cases) && args.length) {
      cases = formatTemplateString(cases, args);
    }
    return (name, optionsOrFn, fnOrOptions) => {
      const _name = formatName(name);
      const { options, handler } = parseArguments(optionsOrFn, fnOrOptions);
      cases.forEach((item, idx) => {
        const handlerWrapper = handler ? (ctx) => handler(item, ctx) : void 0;
        if (handlerWrapper) {
          configureProps(handlerWrapper, {
            index: 1,
            original: handler
          });
        }
        test2(formatTitle(_name, toArray(item), idx), options, handlerWrapper);
      });
    };
  };
  taskFn.skipIf = function(condition) {
    return condition ? this.skip : this;
  };
  taskFn.runIf = function(condition) {
    return condition ? this : this.skip;
  };
  function parseBuilderFixtures(fixturesOrName, optionsOrFn, maybeFn) {
    if (typeof fixturesOrName !== "string") {
      return fixturesOrName;
    }
    const fixtureName = fixturesOrName;
    let fixtureOptions;
    let fixtureValue;
    if (maybeFn !== void 0) {
      fixtureOptions = optionsOrFn;
      fixtureValue = maybeFn;
    } else {
      if (optionsOrFn !== null && typeof optionsOrFn === "object" && !Array.isArray(optionsOrFn) && ("scope" in optionsOrFn || "auto" in optionsOrFn)) {
        fixtureOptions = optionsOrFn;
        fixtureValue = {};
      } else {
        fixtureOptions = void 0;
        fixtureValue = optionsOrFn;
      }
    }
    if (typeof fixtureValue === "function") {
      const builderFn = fixtureValue;
      const fixture = async (ctx, use) => {
        let cleanup;
        const onCleanup = (fn2) => {
          if (cleanup !== void 0) {
            throw new Error(`onCleanup can only be called once per fixture. Define separate fixtures if you need multiple cleanup functions.`);
          }
          cleanup = fn2;
        };
        const value = await builderFn(ctx, { onCleanup });
        await use(value);
        if (cleanup) {
          await cleanup();
        }
      };
      configureProps(fixture, { original: builderFn });
      if (fixtureOptions) {
        return { [fixtureName]: [fixture, fixtureOptions] };
      }
      return { [fixtureName]: fixture };
    }
    if (fixtureOptions) {
      return { [fixtureName]: [fixtureValue, fixtureOptions] };
    }
    return { [fixtureName]: fixtureValue };
  }
  taskFn.override = function(fixturesOrName, optionsOrFn, maybeFn) {
    const userFixtures = parseBuilderFixtures(fixturesOrName, optionsOrFn, maybeFn);
    getChainableContext(this).getFixtures().override(runner, userFixtures);
    return this;
  };
  taskFn.scoped = function(fixtures) {
    console.warn(`test.scoped() is deprecated and will be removed in future versions. Please use test.override() instead.`);
    return this.override(fixtures);
  };
  taskFn.extend = function(fixturesOrName, optionsOrFn, maybeFn) {
    const userFixtures = parseBuilderFixtures(fixturesOrName, optionsOrFn, maybeFn);
    const fixtures = getChainableContext(this).getFixtures().extend(runner, userFixtures);
    const _test2 = createTest(function(name, optionsOrFn2, optionsOrTest) {
      fn.call(this, formatName(name), optionsOrFn2, optionsOrTest);
    });
    getChainableContext(_test2).mergeContext({ fixtures });
    return _test2;
  };
  taskFn.describe = suite;
  taskFn.suite = suite;
  taskFn.beforeEach = beforeEach;
  taskFn.afterEach = afterEach;
  taskFn.beforeAll = beforeAll;
  taskFn.afterAll = afterAll;
  taskFn.aroundEach = aroundEach;
  taskFn.aroundAll = aroundAll;
  const _test = createChainable([
    "concurrent",
    "sequential",
    "skip",
    "only",
    "todo",
    "fails"
  ], taskFn, { fixtures: new TestFixtures() });
  return _test;
}
function createTest(fn) {
  return createTaskCollector(fn);
}
function formatName(name) {
  return typeof name === "string" ? name : typeof name === "function" ? name.name || "<anonymous>" : String(name);
}
function formatTitle(template, items, idx) {
  if (template.includes("%#") || template.includes("%$")) {
    template = template.replace(/%%/g, "__vitest_escaped_%__").replace(/%#/g, `${idx}`).replace(/%\$/g, `${idx + 1}`).replace(/__vitest_escaped_%__/g, "%%");
  }
  const count = template.split("%").length - 1;
  if (template.includes("%f")) {
    const placeholders = template.match(/%f/g) || [];
    placeholders.forEach((_, i2) => {
      if (isNegativeNaN(items[i2]) || Object.is(items[i2], -0)) {
        let occurrence = 0;
        template = template.replace(/%f/g, (match) => {
          occurrence++;
          return occurrence === i2 + 1 ? "-%f" : match;
        });
      }
    });
  }
  const isObjectItem = isObject(items[0]);
  function formatAttribute(s) {
    return s.replace(/\$([$\w.]+)/g, (_, key) => {
      const isArrayKey = /^\d+$/.test(key);
      if (!isObjectItem && !isArrayKey) {
        return `$${key}`;
      }
      const arrayElement = isArrayKey ? objectAttr(items, key) : void 0;
      const value = isObjectItem ? objectAttr(items[0], key, arrayElement) : arrayElement;
      return objDisplay(value, { truncate: runner?.config?.chaiConfig?.truncateThreshold });
    });
  }
  let output = "";
  let i = 0;
  handleRegexMatch(
    template,
    formatRegExp,
    // format "%"
    (match) => {
      if (i < count) {
        output += format(match[0], items[i++]);
      } else {
        output += match[0];
      }
    },
    // format "$"
    (nonMatch) => {
      output += formatAttribute(nonMatch);
    }
  );
  return output;
}
function handleRegexMatch(input, regex, onMatch, onNonMatch) {
  let lastIndex = 0;
  for (const m of input.matchAll(regex)) {
    if (lastIndex < m.index) {
      onNonMatch(input.slice(lastIndex, m.index));
    }
    onMatch(m);
    lastIndex = m.index + m[0].length;
  }
  if (lastIndex < input.length) {
    onNonMatch(input.slice(lastIndex));
  }
}
function formatTemplateString(cases, args) {
  const header = cases.join("").trim().replace(/ /g, "").split("\n").map((i) => i.split("|"))[0];
  const res = [];
  for (let i = 0; i < Math.floor(args.length / header.length); i++) {
    const oneCase = {};
    for (let j = 0; j < header.length; j++) {
      oneCase[header[j]] = args[i * header.length + j];
    }
    res.push(oneCase);
  }
  return res;
}
const now$2 = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
const collectorContext = {
  currentSuite: null
};
function collectTask(task) {
  collectorContext.currentSuite?.tasks.push(task);
}
async function runWithSuite(suite2, fn) {
  const prev = collectorContext.currentSuite;
  collectorContext.currentSuite = suite2;
  await fn();
  collectorContext.currentSuite = prev;
}
function withTimeout(fn, timeout, isHook = false, stackTraceError, onTimeout) {
  if (timeout <= 0 || timeout === Number.POSITIVE_INFINITY) {
    return fn;
  }
  const { setTimeout, clearTimeout } = getSafeTimers();
  return (function runWithTimeout(...args) {
    const startTime = now$2();
    const runner2 = getRunner();
    runner2._currentTaskStartTime = startTime;
    runner2._currentTaskTimeout = timeout;
    return new Promise((resolve_, reject_) => {
      const timer = setTimeout(() => {
        clearTimeout(timer);
        rejectTimeoutError();
      }, timeout);
      timer.unref?.();
      function rejectTimeoutError() {
        const error = makeTimeoutError(isHook, timeout, stackTraceError);
        onTimeout?.(args, error);
        reject_(error);
      }
      function resolve(result) {
        runner2._currentTaskStartTime = void 0;
        runner2._currentTaskTimeout = void 0;
        clearTimeout(timer);
        if (now$2() - startTime >= timeout) {
          rejectTimeoutError();
          return;
        }
        resolve_(result);
      }
      function reject(error) {
        runner2._currentTaskStartTime = void 0;
        runner2._currentTaskTimeout = void 0;
        clearTimeout(timer);
        reject_(error);
      }
      try {
        const result = fn(...args);
        if (typeof result === "object" && result != null && typeof result.then === "function") {
          result.then(resolve, reject);
        } else {
          resolve(result);
        }
      } catch (error) {
        reject(error);
      }
    });
  });
}
function withCancel(fn, signal) {
  return (function runWithCancel(...args) {
    return new Promise((resolve, reject) => {
      signal.addEventListener("abort", () => reject(signal.reason));
      try {
        const result = fn(...args);
        if (typeof result === "object" && result != null && typeof result.then === "function") {
          result.then(resolve, reject);
        } else {
          resolve(result);
        }
      } catch (error) {
        reject(error);
      }
    });
  });
}
const abortControllers = /* @__PURE__ */ new WeakMap();
function abortIfTimeout([context], error) {
  if (context) {
    abortContextSignal(context, error);
  }
}
function abortContextSignal(context, error) {
  const abortController = abortControllers.get(context);
  abortController?.abort(error);
}
function createTestContext(test2, runner2) {
  const context = function() {
    throw new Error("done() callback is deprecated, use promise instead");
  };
  let abortController = abortControllers.get(context);
  if (!abortController) {
    abortController = new AbortController();
    abortControllers.set(context, abortController);
  }
  context.signal = abortController.signal;
  context.task = test2;
  context.skip = (condition, note) => {
    if (condition === false) {
      return void 0;
    }
    test2.result ??= { state: "skip" };
    test2.result.pending = true;
    throw new PendingError("test is skipped; abort execution", test2, typeof condition === "string" ? condition : note);
  };
  context.annotate = ((message, type, attachment) => {
    if (test2.result && test2.result.state !== "run") {
      throw new Error(`Cannot annotate tests outside of the test run. The test "${test2.name}" finished running with the "${test2.result.state}" state already.`);
    }
    const annotation = {
      message,
      type: typeof type === "object" || type === void 0 ? "notice" : type
    };
    const annotationAttachment = typeof type === "object" ? type : attachment;
    if (annotationAttachment) {
      annotation.attachment = annotationAttachment;
      manageArtifactAttachment(annotation.attachment);
    }
    return recordAsyncOperation(test2, recordArtifact(test2, {
      type: "internal:annotation",
      annotation
    }).then(async ({ annotation: annotation2 }) => {
      if (!runner2.onTestAnnotate) {
        throw new Error(`Test runner doesn't support test annotations.`);
      }
      await finishSendTasksUpdate(runner2);
      const resolvedAnnotation = await runner2.onTestAnnotate(test2, annotation2);
      test2.annotations.push(resolvedAnnotation);
      return resolvedAnnotation;
    }));
  });
  context.onTestFailed = (handler, timeout) => {
    test2.onFailed ||= [];
    test2.onFailed.push(withTimeout(handler, timeout ?? runner2.config.hookTimeout, true, new Error("STACK_TRACE_ERROR"), (_, error) => abortController.abort(error)));
  };
  context.onTestFinished = (handler, timeout) => {
    test2.onFinished ||= [];
    test2.onFinished.push(withTimeout(handler, timeout ?? runner2.config.hookTimeout, true, new Error("STACK_TRACE_ERROR"), (_, error) => abortController.abort(error)));
  };
  return runner2.extendTaskContext?.(context) || context;
}
function makeTimeoutError(isHook, timeout, stackTraceError) {
  const message = `${isHook ? "Hook" : "Test"} timed out in ${timeout}ms.
If this is a long-running ${isHook ? "hook" : "test"}, pass a timeout value as the last argument or configure it globally with "${isHook ? "hookTimeout" : "testTimeout"}".`;
  const error = new Error(message);
  if (stackTraceError?.stack) {
    error.stack = stackTraceError.stack.replace(error.message, stackTraceError.message);
  }
  return error;
}
globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
getSafeTimers();
const packs = /* @__PURE__ */ new Map();
const eventsPacks = [];
const pendingTasksUpdates = [];
function sendTasksUpdate(runner2) {
  if (packs.size) {
    const taskPacks = Array.from(packs).map(([id, task]) => {
      return [
        id,
        task[0],
        task[1]
      ];
    });
    const p = runner2.onTaskUpdate?.(taskPacks, eventsPacks);
    if (p) {
      pendingTasksUpdates.push(p);
      p.then(() => pendingTasksUpdates.splice(pendingTasksUpdates.indexOf(p), 1), () => {
      });
    }
    eventsPacks.length = 0;
    packs.clear();
  }
}
async function finishSendTasksUpdate(runner2) {
  sendTasksUpdate(runner2);
  await Promise.all(pendingTasksUpdates);
}
async function recordArtifact(task, artifact) {
  const runner2 = getRunner();
  const stack = findTestFileStackTrace(task.file.filepath, new Error("STACK_TRACE").stack);
  if (stack) {
    artifact.location = {
      file: stack.file,
      line: stack.line,
      column: stack.column
    };
    if (artifact.type === "internal:annotation") {
      artifact.annotation.location = artifact.location;
    }
  }
  if (Array.isArray(artifact.attachments)) {
    for (const attachment of artifact.attachments) {
      manageArtifactAttachment(attachment);
    }
  }
  if (artifact.type === "internal:annotation") {
    return artifact;
  }
  if (!runner2.onTestArtifactRecord) {
    throw new Error(`Test runner doesn't support test artifacts.`);
  }
  await finishSendTasksUpdate(runner2);
  const resolvedArtifact = await runner2.onTestArtifactRecord(task, artifact);
  task.artifacts.push(resolvedArtifact);
  return resolvedArtifact;
}
const table = [];
for (let i = 65; i < 91; i++) {
  table.push(String.fromCharCode(i));
}
for (let i = 97; i < 123; i++) {
  table.push(String.fromCharCode(i));
}
for (let i = 0; i < 10; i++) {
  table.push(i.toString(10));
}
table.push("+", "/");
function encodeUint8Array(bytes) {
  let base64 = "";
  const len = bytes.byteLength;
  for (let i = 0; i < len; i += 3) {
    if (len === i + 1) {
      const a = (bytes[i] & 252) >> 2;
      const b = (bytes[i] & 3) << 4;
      base64 += table[a];
      base64 += table[b];
      base64 += "==";
    } else if (len === i + 2) {
      const a = (bytes[i] & 252) >> 2;
      const b = (bytes[i] & 3) << 4 | (bytes[i + 1] & 240) >> 4;
      const c = (bytes[i + 1] & 15) << 2;
      base64 += table[a];
      base64 += table[b];
      base64 += table[c];
      base64 += "=";
    } else {
      const a = (bytes[i] & 252) >> 2;
      const b = (bytes[i] & 3) << 4 | (bytes[i + 1] & 240) >> 4;
      const c = (bytes[i + 1] & 15) << 2 | (bytes[i + 2] & 192) >> 6;
      const d = bytes[i + 2] & 63;
      base64 += table[a];
      base64 += table[b];
      base64 += table[c];
      base64 += table[d];
    }
  }
  return base64;
}
function recordAsyncOperation(test2, promise) {
  promise = promise.finally(() => {
    if (!test2.promises) {
      return;
    }
    const index = test2.promises.indexOf(promise);
    if (index !== -1) {
      test2.promises.splice(index, 1);
    }
  });
  if (!test2.promises) {
    test2.promises = [];
  }
  test2.promises.push(promise);
  return promise;
}
function manageArtifactAttachment(attachment) {
  if (attachment.body == null && !attachment.path) {
    throw new TypeError(`Test attachment requires "body" or "path" to be set. Both are missing.`);
  }
  if (attachment.body && attachment.path) {
    throw new TypeError(`Test attachment requires only one of "body" or "path" to be set. Both are specified.`);
  }
  if (attachment.body instanceof Uint8Array) {
    attachment.body = encodeUint8Array(attachment.body);
  }
}
export {
  afterAll,
  afterEach,
  aroundAll,
  aroundEach,
  beforeAll,
  beforeEach,
  createTaskCollector,
  describe,
  getCurrentSuite,
  getHooks,
  it,
  recordArtifact,
  setFn,
  setHooks,
  suite,
  test
};
//# sourceMappingURL=index.js.map
