import { t as importAssembler } from "../utils-1rNipeII.js";
import { o as args, p as BaseCommand, u as flags } from "../main-DvUje0hm.js";
import { t as __decorate } from "../decorate-DcF3lt7P.js";
//#region commands/test.ts
/**
* Command to run application tests using the Japa test runner.
* Supports filtering tests by suites, files, tags, groups, and individual tests.
* Can run in watch mode to automatically re-run tests when files change.
*
* @example
* ```
* ace test
* ace test unit integration
* ace test --watch
* ace test --files=user.spec.ts
* ace test --tags=slow --groups="User tests"
* ace test --reporters=spec,dot
* ace test --timeout=5000 --retries=2
* ```
*/
var Test = class extends BaseCommand {
	/**
	* The command name
	*/
	static commandName = "test";
	/**
	* The command description
	*/
	static description = "Run tests using Japa test runner. Supports filtering by suite, file, tag, and group. Use --watch for re-runs on file change";
	/**
	* Command options configuration.
	* Allows unknown flags to be passed to Japa and keeps the process alive.
	*/
	static options = {
		allowUnknownFlags: true,
		staysAlive: true
	};
	/**
	* Log an error message when a required development dependency is missing.
	* Provides helpful instructions for resolving the issue.
	*
	* @param dependency - The name of the missing dependency package
	*/
	#logMissingDevelopmentDependency(dependency) {
		this.logger.error([
			`Cannot find package "${dependency}"`,
			"",
			`The "${dependency}" package is a development dependency and therefore you should run tests with development dependencies installed.`,
			"",
			"If you are run tests inside a CI, make sure the NODE_ENV is set to \"development\""
		].join("\n"));
	}
	/**
	* Collect unknown flags and format them to pass to the Japa test runner.
	* Handles boolean flags, arrays, and single values appropriately.
	*
	* @returns Array of formatted command-line arguments for Japa
	*/
	#getPassthroughFlags() {
		return this.parsed.unknownFlags.map((flag) => {
			const value = this.parsed.flags[flag];
			/**
			* Not mentioning value when value is "true"
			*/
			if (value === true) return [`--${flag}`];
			/**
			* Repeating flag multiple times when value is an array
			*/
			if (Array.isArray(value)) return value.map((v) => [`--${flag}`, v]);
			return [`--${flag}`, value];
		}).flat(2);
	}
	/**
	* Execute the test command. Sets up the test runner with all configured options
	* and filters, then runs tests either once or in watch mode. Handles missing
	* dependencies and properly configures the test environment.
	*/
	async run() {
		process.env.NODE_ENV = "test";
		const assembler = await importAssembler(this.app);
		if (!assembler) {
			this.#logMissingDevelopmentDependency("@adonisjs/assembler");
			this.exitCode = 1;
			return;
		}
		this.testsRunner = new assembler.TestRunner(this.app.appRoot, {
			clearScreen: this.clear === false ? false : true,
			nodeArgs: this.parsed.nodeArgs,
			scriptArgs: this.#getPassthroughFlags(),
			filters: {
				suites: this.suites,
				files: this.files,
				groups: this.groups,
				tags: this.tags,
				tests: this.tests
			},
			failed: this.failed,
			retries: this.retries,
			timeout: this.timeout,
			reporters: this.reporters,
			suites: this.app.rcFile.tests.suites.map((suite) => {
				return {
					name: suite.name,
					files: suite.files
				};
			}),
			env: { NODE_ENV: "test" },
			hooks: this.app.rcFile.hooks,
			metaFiles: this.app.rcFile.metaFiles
		});
		/**
		* Share command logger with assembler, so that CLI flags like --no-ansi has
		* similar impact for assembler logs as well.
		*/
		this.testsRunner.ui.logger = this.logger;
		/**
		* Exit command when the test runner is closed
		*/
		this.testsRunner.onClose((exitCode) => {
			this.exitCode = exitCode;
			this.terminate();
		});
		/**
		* Exit command when the dev server crashes
		*/
		this.testsRunner.onError(() => {
			this.exitCode = 1;
			this.terminate();
		});
		/**
		* Start the test runner in watch mode
		*/
		if (this.watch) await this.testsRunner.runAndWatch({ poll: this.poll || false });
		else await this.testsRunner.run();
	}
};
__decorate([args.spread({
	description: "Mention suite names to run tests for selected suites",
	required: false
})], Test.prototype, "suites", void 0);
__decorate([flags.array({ description: "Filter tests by the filename" })], Test.prototype, "files", void 0);
__decorate([flags.array({ description: "Filter tests by tags" })], Test.prototype, "tags", void 0);
__decorate([flags.array({ description: "Filter tests by parent group title" })], Test.prototype, "groups", void 0);
__decorate([flags.array({ description: "Filter tests by test title" })], Test.prototype, "tests", void 0);
__decorate([flags.array({ description: "Activate one or more test reporters" })], Test.prototype, "reporters", void 0);
__decorate([flags.boolean({ description: "Watch filesystem and re-run tests on file change" })], Test.prototype, "watch", void 0);
__decorate([flags.boolean({ description: "Use polling to detect filesystem changes" })], Test.prototype, "poll", void 0);
__decorate([flags.number({ description: "Define default timeout for all tests" })], Test.prototype, "timeout", void 0);
__decorate([flags.number({ description: "Define default retries for all tests" })], Test.prototype, "retries", void 0);
__decorate([flags.boolean({ description: "Execute tests failed during the last run" })], Test.prototype, "failed", void 0);
__decorate([flags.boolean({
	description: "Clear the terminal for new logs after file change",
	showNegatedVariantInHelp: true,
	default: true
})], Test.prototype, "clear", void 0);
//#endregion
export { Test as default };
