ace-test-runner 0.18.1 → 0.25.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97801800374ba4230c6d4821d63ebf69ea2f9376a85173538fe0fd9c96bd66d8
4
- data.tar.gz: 447e4b7f920d3e0188e81c56bfe3226c5c6ac1688a72f08b5a3a2bfb3303048e
3
+ metadata.gz: 4c042607ae93a0d7b8356b17a8d16e2bf6ce34a90ed2c838da6e3d2424e06fa8
4
+ data.tar.gz: c487ac4faaa171aa7837faf4cec28a61dbc2d2d39a0c169055384155b5be73a8
5
5
  SHA512:
6
- metadata.gz: 1b0e98327d7a0a312a604750106abb08c9ae498b2c354464ce3c1af31d9b5be1bf60203c19882a00233d6affab895b6f2dc3806fbb7f8013b891dbf34eb0f0aa
7
- data.tar.gz: 06257fccd1041208bb10bc6ef7b0ccf22f05468d864ca354e371c88ab0eb1200e6a158766e3a625b46d1d7f1d89d78fa9dcbf0a040a705ad415fe7c56cacbe52
6
+ metadata.gz: ed4309b9fe5b54c64af419ea13933e5b2bac49ea8b658e960c307c4964aa3c8688ef4c23603000f71876bd65ff6b5b2e569a06e4eb037c5e99d60ab8c16ff16f
7
+ data.tar.gz: 27f594fd038d9284173e33373f336e533269925a41a1f84a8aaa9962b3e691a599eaf4c49b36c602a263bb0ad410ea17a9cf7a74a262b12552be97c6efea0d57
@@ -20,16 +20,16 @@ test:
20
20
 
21
21
  # Test file patterns (optional - has good defaults)
22
22
  # patterns:
23
- # smoke: "test/*_test.rb" # Root-level smoke tests
24
- # atoms: "test/atoms/**/*_test.rb"
25
- # molecules: "test/molecules/**/*_test.rb"
26
- # organisms: "test/organisms/**/*_test.rb"
27
- # models: "test/models/**/*_test.rb"
28
- # integration: "test/integration/**/*_test.rb"
29
- # system: "test/system/**/*_test.rb"
23
+ # smoke: "test/{fast/,}smoke/**/*_test.rb"
24
+ # atoms: "test/{fast/,}atoms/**/*_test.rb"
25
+ # molecules: "test/{fast/,}molecules/**/*_test.rb"
26
+ # organisms: "test/{fast/,}organisms/**/*_test.rb"
27
+ # models: "test/{fast/,}models/**/*_test.rb"
28
+ # feat_tests: "test/feat/**/*_test.rb"
30
29
  #
31
30
  # Test groups (optional - has good defaults)
32
31
  # groups:
33
- # unit: [smoke, atoms, molecules, organisms, models]
34
- # all: [unit, integration, system]
32
+ # fast: [smoke, atoms, molecules, organisms, models]
33
+ # feat: [feat_tests]
34
+ # all: [fast, feat]
35
35
  # quick: [atoms, molecules]
@@ -10,25 +10,23 @@
10
10
  version: 1
11
11
 
12
12
  # Test file patterns for each category
13
- # Supports both test/unit/atoms and test/atoms directory structures
14
13
  patterns:
15
- smoke: "test/{unit/,}smoke/**/*_test.rb"
16
- atoms: "test/{unit/,}atoms/**/*_test.rb"
17
- molecules: "test/{unit/,}molecules/**/*_test.rb"
18
- organisms: "test/{unit/,}organisms/**/*_test.rb"
19
- models: "test/{unit/,}models/**/*_test.rb"
20
- commands: "test/{unit/,}commands/**/*_test.rb"
21
- cli: "test/{unit/,}cli/**/*_test.rb"
22
- prompts: "test/{unit/,}prompts/**/*_test.rb"
23
- fixtures: "test/{unit/,}fixtures/**/*_test.rb"
24
- support: "test/{unit/,}support/**/*_test.rb"
25
- edge: "test/{unit/,}edge/**/*_test.rb"
26
- integration: "test/integration/**/*_test.rb"
27
- system: "test/system/**/*_test.rb"
14
+ smoke: "test/{fast/,}smoke/**/*_test.rb"
15
+ atoms: "test/{fast/,}atoms/**/*_test.rb"
16
+ molecules: "test/{fast/,}molecules/**/*_test.rb"
17
+ organisms: "test/{fast/,}organisms/**/*_test.rb"
18
+ models: "test/{fast/,}models/**/*_test.rb"
19
+ commands: "test/{fast/,}commands/**/*_test.rb"
20
+ cli: "test/{fast/,}cli/**/*_test.rb"
21
+ prompts: "test/{fast/,}prompts/**/*_test.rb"
22
+ fixtures: "test/{fast/,}fixtures/**/*_test.rb"
23
+ support: "test/{fast/,}support/**/*_test.rb"
24
+ edge: "test/{fast/,}edge/**/*_test.rb"
25
+ feat_tests: "test/feat/**/*_test.rb"
28
26
 
29
- # Test groups that combine multiple patterns
30
- groups:
31
- unit:
27
+ # Test targets that combine multiple patterns
28
+ targets:
29
+ fast:
32
30
  - smoke
33
31
  - atoms
34
32
  - molecules
@@ -39,11 +37,12 @@ groups:
39
37
  - prompts
40
38
  - fixtures
41
39
  - support
40
+ feat:
41
+ - feat_tests
42
42
  - edge
43
43
  all:
44
- - unit
45
- - integration
46
- - system
44
+ - fast
45
+ - feat
47
46
  quick:
48
47
  - atoms
49
48
  - molecules
@@ -59,3 +58,8 @@ defaults:
59
58
  # Failure display limits
60
59
  failure_limits:
61
60
  max_display: 7
61
+
62
+ execution:
63
+ mode: by-target
64
+ target_fail_fast: true
65
+ target_isolation: false
data/CHANGELOG.md CHANGED
@@ -7,6 +7,131 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.25.5] - 2026-04-19
11
+
12
+ ### Technical
13
+ - Tightened retained suite failure-propagation runner guidance to persist the injected failing-test path before precheck and cleanup steps.
14
+
15
+ ## [0.25.4] - 2026-04-18
16
+
17
+ ### Technical
18
+ - Strengthened retained suite failure-propagation E2E coverage so Goal 2 now proves the injected failing file through a direct `ace-test` precheck before validating `ace-test-suite` aggregate failure propagation.
19
+
20
+ ## [0.25.3] - 2026-04-16
21
+
22
+ ### Technical
23
+ - Reworked retained suite failure-propagation E2E setup to use a deterministic failing fast-test fixture and require non-zero exit evidence tied to the injected failure path.
24
+
25
+ ## [0.25.2] - 2026-04-16
26
+
27
+ ### Technical
28
+ - Updated `TS-TEST-001` and `TS-TEST-002` sandbox setup to source `mise.toml` from `${ACE_E2E_SOURCE_ROOT:-$PROJECT_ROOT_PATH}` so test-runner E2E flows remain compatible with the shared read-only source-root contract.
29
+
30
+ ## [0.25.1] - 2026-04-15
31
+
32
+ ### Fixed
33
+ - Corrected `TS-TEST-002` suite scenario command contracts to run `ace-test-suite` from sandbox `PATH` and aligned verifier expectations with the same public command surface.
34
+
35
+ ## [0.25.0] - 2026-04-15
36
+
37
+ ### Changed
38
+ - Reworked `ace-test-runner` E2E suites to public-surface goal style by removing duplicate TS-TEST-001 group coverage, enforcing canonical TS-TEST-002 suite invocation, and adding suite `--target` pass-through scenario coverage.
39
+ - Updated `docs/usage.md` with canonical `ace-test-e2e ace-test-runner` guidance and explicit suite E2E invocation constraints.
40
+
41
+ ## [0.24.2] - 2026-04-13
42
+
43
+ ### Fixed
44
+ - Relaxed the removed `unit` target regression assertion so it verifies the canonical target set without depending on display order.
45
+
46
+ ## [0.24.1] - 2026-04-13
47
+
48
+ ### Changed
49
+ - Completed the batch i05 migration follow-through for this package and aligned it with the restarted `fast` / `feat` / `e2e` verification model.
50
+
51
+ ### Technical
52
+ - Included in the coordinated assignment-driven patch release for batch i05 package updates.
53
+
54
+
55
+ ## [0.24.0] - 2026-04-12
56
+
57
+ ### Changed
58
+ - Migrated deterministic package tests to the `test/fast/` and `test/feat/` layout for `ace-test-runner`, including moving former `test/integration/` coverage into `feat`.
59
+ - Updated package defaults, fixture config, E2E scenario coverage references, and usage examples to align with the `fast` / `feat` / `e2e` contract.
60
+
61
+ ### Removed
62
+ - Removed legacy `test/integration/` deterministic test directory from `ace-test-runner`.
63
+
64
+ ## [0.23.0] - 2026-04-11
65
+
66
+ ### Changed
67
+ - Renamed package-level test-scope terminology to `target` across CLI, runtime, docs, and config, with `targets:` replacing `groups:` and `execution.mode: by-target` replacing the old grouped wording.
68
+ - Kept suite package bucketing on `group` so `ace-test-suite --group` continues to mean package selection while `--target` stays package-local test scope.
69
+
70
+ ### Fixed
71
+ - Made `ace-test-suite --target feat` fail closed on current-run subprocess errors instead of reusing stale package summaries, so suite totals now reflect real feat-only execution.
72
+
73
+ ### Technical
74
+ - Renamed sequential-execution and target-model internals to match the public `target` contract and added regression coverage for config loading, resolver cycles, explicit-file execution, and suite summary freshness.
75
+
76
+ ## [0.22.0] - 2026-04-11
77
+
78
+ ### Changed
79
+ - Renamed the public deterministic test contract to `fast` / `feat`, made bare `ace-test` default to `fast`, and made `all` execute `fast` then `feat`.
80
+ - Updated CLI help, configuration defaults, and suite target guidance to teach `ace-test-e2e` as the only scenario E2E entrypoint.
81
+
82
+ ### Technical
83
+ - Kept internal compatibility aliases for `unit` and `integration` during the migration window while updating resolver and config-loader coverage to the new public naming.
84
+
85
+ ## [0.21.0] - 2026-04-10
86
+
87
+ ### Changed
88
+ - Changed bare `ace-test` package runs to default to the `unit` group, added `int` as an alias for `integration`, and narrowed `all` to `unit`, `edge`, and `integration`.
89
+ - Removed legacy `system`, `e2e`, and `all-with-e2e` targets from the CLI/docs surface and directed scenario E2E execution to `ace-test-e2e`.
90
+
91
+ ## [0.20.1] - 2026-04-10
92
+
93
+ ### Fixed
94
+ - Honored an explicitly configured `all` target without widening default package runs into `test/e2e`, restoring the intended non-E2E default selection.
95
+
96
+ ## [0.20.0] - 2026-04-10
97
+
98
+ ### Changed
99
+ - Added a first-class `e2e` target for `ace-test` and `ace-test-suite --target e2e`, while keeping default `all` runs non-E2E.
100
+ - Documented suite-level E2E targeting and updated runner defaults around the restarted deterministic E2E flow.
101
+
102
+ ## [0.19.6] - 2026-04-10
103
+
104
+ ### Fixed
105
+ - Restored suite-enforced `--run-in-single-batch` execution so `ace-test-suite` preserves its package execution contract instead of falling back to grouped runs.
106
+ - Prefer live runtime timeout/failure state over stale `latest/summary.json` data so suite aggregation no longer reports timed-out packages as passed.
107
+ - Detect subprocess-sensitive tests by file content even inside unit directories, preventing single-batch in-process hangs for packages like `ace-test-runner-e2e`.
108
+
109
+ ## [0.19.5] - 2026-04-10
110
+
111
+ ### Fixed
112
+ - Stopped forcing `--run-in-single-batch` in suite package execution so `ace-test-suite` uses the stable grouped package path instead of the hanging single-batch mode.
113
+ - Prefer live runtime timeout/failure state over stale `latest/summary.json` data so suite aggregation no longer reports timed-out packages as passed.
114
+
115
+ ## [0.19.3] - 2026-04-07
116
+
117
+ ### Technical
118
+ - Expanded suite process-monitor timeout coverage for the full-suite integration queue scenario and improved failure-window robustness under concurrent execution.
119
+
120
+ ## [0.19.2] - 2026-04-07
121
+
122
+ ### Technical
123
+ - Stabilized suite process-monitor integration coverage by increasing the timeout budget for the queued-package timeout scenario under full-suite load.
124
+
125
+ ## [0.19.1] - 2026-03-29
126
+
127
+ ### Technical
128
+ - Normalized published gem metadata so RubyGems and Ruby Toolbox use current release information instead of the 1980 fallback date.
129
+
130
+ ### Added
131
+ - **ace-test-runner v0.19.0**: Added suite-level per-package timeout support via `ace-test-suite --timeout` and `test_suite.timeout`, allowing hung package runs to fail and free their worker slot instead of stalling the rest of the suite.
132
+
133
+ ### Fixed
134
+ - **ace-test-runner v0.19.0**: Terminate active package process groups on suite timeout or interrupt so `ace-test-suite` no longer leaves orphaned `ace-test` subprocesses behind after stuck or cancelled runs.
10
135
 
11
136
  ## [0.18.1] - 2026-03-29
12
137
 
data/README.md CHANGED
@@ -18,11 +18,11 @@
18
18
 
19
19
  ![ace-test-runner demo](docs/demo/ace-test-runner-getting-started.gif)
20
20
 
21
- `ace-test-runner` wraps [Minitest](https://github.com/minitest/minitest) with smart grouping, cross-package resolution, and persistent reports so both developers and coding agents can run focused checks quickly, diagnose failures with context, and retain searchable execution history. It handles the execution side of testing; use [ace-test](../ace-test) for planning, review, and suite improvement workflows.
21
+ `ace-test-runner` wraps [Minitest](https://github.com/minitest/minitest) with smart target resolution, cross-package execution, and persistent reports so both developers and coding agents can run focused checks quickly, diagnose failures with context, and retain searchable execution history. It handles the execution side of testing; use [ace-test](../ace-test) for planning, review, and suite improvement workflows.
22
22
 
23
23
  ## How It Works
24
24
 
25
- 1. Resolve the target package and test scope from a package name, group (`atoms`, `molecules`, `organisms`, `unit`, `integration`, `system`, `all`, `quick`), or direct `file:line` selector.
25
+ 1. Resolve the target package and test scope from a package name, target (`atoms`, `molecules`, `organisms`, `models`, `fast`, `feat`, `all`, `quick`), or direct `file:line` selector.
26
26
  2. Execute the matching tests with failure-oriented output and optional profiling of the slowest cases.
27
27
  3. Persist structured run reports for historical debugging and searchable triage across runs.
28
28
 
@@ -30,11 +30,13 @@
30
30
 
31
31
  **Run package tests from anywhere in the monorepo** - execute [`ace-test [package]`](docs/usage.md) by name without changing directories, keeping outputs consistent across local and CI environments.
32
32
 
33
- **Target exactly the scope you need** - run by test groups (`ace-test atoms`, `ace-test molecules`) or direct file/line selectors (`ace-test test/file_test.rb:42`) to focus on the code you are changing.
33
+ **Target exactly the scope you need** - run by test targets (`ace-test atoms`, `ace-test molecules`) or direct file/line selectors (`ace-test test/file_test.rb:42`) to focus on the code you are changing.
34
+
35
+ **Keep fast-loop defaults tight** - run `ace-test <package>` for `fast` coverage by default, then opt into `feat` when you need deterministic feature checks with controlled IO.
34
36
 
35
37
  **Speed up triage on broken builds** - use failure-oriented output and persisted reports to locate regressions and continue diagnosis without rerunning broad suites.
36
38
 
37
- **Validate the full monorepo before shipping** - run `ace-test-suite` for cross-package execution orchestration that covers every package in one sweep.
39
+ **Validate the full monorepo before shipping** - run `ace-test-suite` for cross-package execution orchestration, and use `ace-test-e2e <package>` when you need scenario E2E coverage.
38
40
 
39
41
  **Profile slow tests** - run `ace-test molecules --profile 10` to identify the slowest tests and prioritize optimization with [ace-test](../ace-test) performance audit workflows.
40
42
 
data/exe/ace-test-suite CHANGED
@@ -38,6 +38,14 @@ parser = OptionParser.new do |opts|
38
38
  options[:group] = group
39
39
  end
40
40
 
41
+ opts.on("--target TARGET", "Pass target through to package-level ace-test (e.g. feat)") do |target|
42
+ options[:target] = target
43
+ end
44
+
45
+ opts.on("-t", "--timeout SEC", Integer, "Per-package timeout in seconds") do |timeout|
46
+ options[:timeout] = timeout
47
+ end
48
+
41
49
  opts.on("-v", "--verbose", "Show verbose output") do
42
50
  options[:verbose] = true
43
51
  end
@@ -57,7 +65,9 @@ parser = OptionParser.new do |opts|
57
65
  puts " $ ace-test-suite Run all (simple line-by-line output)"
58
66
  puts " $ ace-test-suite --progress Show live animated progress bars"
59
67
  puts " $ ace-test-suite --parallel 16 Run with 16 parallel processes"
68
+ puts " $ ace-test-suite --timeout 10 Fail packages that run over 10s"
60
69
  puts " $ ace-test-suite --group foundation Run only foundation group"
70
+ puts " $ ace-test-suite --target feat Run feat target in each package"
61
71
  puts " $ ace-test-suite --verbose Show detailed test output"
62
72
  exit 0
63
73
  end
@@ -110,6 +120,10 @@ if options[:parallel]
110
120
  config["test_suite"]["max_parallel"] = options[:parallel]
111
121
  end
112
122
 
123
+ if options[:timeout]
124
+ config["test_suite"]["timeout"] = options[:timeout]
125
+ end
126
+
113
127
  if options[:group]
114
128
  config["test_suite"]["packages"].select! { |p| p["group"] == options[:group] }
115
129
  if config["test_suite"]["packages"].empty?
@@ -128,6 +142,11 @@ if options[:verbose]
128
142
  config["test_suite"]["test_options"]["verbose"] = true
129
143
  end
130
144
 
145
+ if options[:target]
146
+ config["test_suite"]["test_options"] ||= {}
147
+ config["test_suite"]["test_options"]["target"] = options[:target]
148
+ end
149
+
131
150
  if options[:progress]
132
151
  config["test_suite"]["progress"] = true
133
152
  end
@@ -11,8 +11,8 @@ module Ace
11
11
  # Returns the parent directory of the test folder + "/test-reports"
12
12
  #
13
13
  # Example:
14
- # files = ["ace-taskflow/test/commands/tasks_command_test.rb"]
15
- # detect_report_dir(files) # => "ace-taskflow/test-reports"
14
+ # files = ["ace-task/test/commands/tasks_command_test.rb"]
15
+ # detect_report_dir(files) # => "ace-task/test-reports"
16
16
  def detect_report_dir(test_files)
17
17
  return nil if test_files.nil? || test_files.empty?
18
18
 
@@ -31,8 +31,8 @@ module Ace
31
31
  # Looks for "/test/" in the path and returns the path up to and including "test"
32
32
  #
33
33
  # Example:
34
- # find_test_folder("ace-taskflow/test/commands/tasks_command_test.rb")
35
- # # => "ace-taskflow/test"
34
+ # find_test_folder("ace-task/test/commands/tasks_command_test.rb")
35
+ # # => "ace-task/test"
36
36
  def find_test_folder(file_path)
37
37
  # Remove line number suffix if present (file:line format)
38
38
  file_path = file_path.sub(/:\d+$/, "")
@@ -39,20 +39,24 @@ module Ace
39
39
  # Check if explicitly marked as needing isolation
40
40
  return true if isolation_directory?(file_path)
41
41
 
42
- # Check if it's clearly a unit test that doesn't need isolation
42
+ # Check file content for patterns that require subprocess
43
+ needs_isolation = check_file_content(file_path)
44
+ return true if needs_isolation
45
+
46
+ # Unit-directory tests default to in-process only when they do not
47
+ # exercise subprocess-sensitive behavior directly.
43
48
  return false if unit_test_directory?(file_path)
44
49
 
45
- # Check file content for patterns that require subprocess
46
- check_file_content(file_path)
50
+ false
47
51
  end
48
52
 
49
53
  def test_type(file_path)
50
54
  if isolation_directory?(file_path)
51
55
  :integration
52
- elsif unit_test_directory?(file_path)
53
- :unit
54
56
  elsif check_file_content(file_path)
55
57
  :subprocess_required
58
+ elsif unit_test_directory?(file_path)
59
+ :unit
56
60
  else
57
61
  :unit
58
62
  end
@@ -30,10 +30,9 @@ module Ace
30
30
  molecules Run molecule tests only
31
31
  organisms Run organism tests only
32
32
  models Run model tests only
33
- unit Run all unit tests (atoms + molecules + organisms + models)
34
- integration Run integration tests
35
- system Run system tests
36
- all Run all tests (default)
33
+ fast Run the default isolated fast loop
34
+ feat Run deterministic feature tests with controlled IO
35
+ all Run fast then feat
37
36
  quick Run quick tests (atoms + molecules)
38
37
 
39
38
  CONFIGURATION:
@@ -53,10 +52,10 @@ module Ace
53
52
  ATOM Architecture Test Layers:
54
53
  - atoms -> Pure functions (no side effects)
55
54
  - molecules -> Composed operations (controlled side effects)
56
- - organisms -> Business logic (complex coordination)
55
+ - organisms -> Business logic with stubbed boundaries
57
56
  - models -> Data structures (no behavior)
58
- - integration -> Cross-component testing
59
- - system -> End-to-end workflows
57
+ - fast -> Default isolated package test loop
58
+ - feat -> Deterministic feature coverage
60
59
  DESC
61
60
 
62
61
  # Examples shown in help output
@@ -79,7 +78,7 @@ module Ace
79
78
  option :fail_fast, type: :boolean, desc: "Stop execution on first failure"
80
79
  option :fix_deprecations, type: :boolean, desc: "Auto-fix deprecated test patterns"
81
80
  option :filter, type: :string, desc: "Run only tests matching pattern"
82
- option :group, type: :string, aliases: %w[-g], desc: "Run specific test group (unit, integration, system, all)"
81
+ option :target, type: :string, aliases: %w[-g], desc: "Run specific test target (fast, feat, all)"
83
82
  option :color, type: :boolean, desc: "Enable/disable colored output (default: enabled)"
84
83
  option :config_path, type: :string, aliases: %w[-c], desc: "Configuration file path (default: .ace/test-runner.yml)"
85
84
 
@@ -93,7 +92,7 @@ module Ace
93
92
  option :per_file, type: :boolean, desc: "Execute each test file separately (slower, for debugging)"
94
93
  option :direct, type: :boolean, desc: "Force in-process execution (faster, less isolation)"
95
94
  option :subprocess, type: :boolean, desc: "Force subprocess execution (slower, full isolation)"
96
- option :run_in_sequence, type: :boolean, aliases: %w[--ris], desc: "Run test groups sequentially (default)"
95
+ option :run_in_sequence, type: :boolean, aliases: %w[--ris], desc: "Run test targets sequentially (default)"
97
96
  option :run_in_single_batch, type: :boolean, aliases: %w[--risb], desc: "Run all tests together in single batch"
98
97
 
99
98
  # Rake integration options
@@ -125,6 +124,10 @@ module Ace
125
124
  options[key] = options[key].to_i if options[key]
126
125
  end
127
126
 
127
+ if options[:target] && args.none? { |arg| !arg.start_with?("-") && !File.exist?(arg) }
128
+ args = [options[:target]] + args
129
+ end
130
+
128
131
  # Build test options with defaults
129
132
  test_options = build_test_options(options)
130
133
 
@@ -169,6 +172,7 @@ module Ace
169
172
  end
170
173
  # Remove the run_in_sequence key as it's only used to set run_in_single_batch
171
174
  symbolized_options.delete(:run_in_sequence)
175
+ symbolized_options.delete(:target)
172
176
 
173
177
  # Default options - symbolized_options will override these for any explicit values
174
178
  {
@@ -185,15 +185,15 @@ module Ace
185
185
  end
186
186
 
187
187
  def on_test_complete(file, success, duration)
188
- # Detect group from file path
189
- group = detect_group(file)
188
+ # Detect target from file path
189
+ target = detect_target(file)
190
190
 
191
- # Print group header if it's a new group and groups are enabled
192
- if @show_groups && group != @current_group
191
+ # Print target header if it's a new target and target headers are enabled
192
+ if @show_groups && target != @current_group
193
193
  puts unless @test_count == 0
194
194
  puts ""
195
- puts colorize("═══ #{group.to_s.capitalize} Tests ═══", :cyan)
196
- @current_group = group
195
+ puts colorize("═══ #{target.to_s.capitalize} Tests ═══", :cyan)
196
+ @current_group = target
197
197
  @test_count = 0 # Reset count for new line
198
198
  end
199
199
 
@@ -207,47 +207,44 @@ module Ace
207
207
  puts if @test_count % @line_width == 0
208
208
  end
209
209
 
210
- # Track group counts
211
- @group_counts[group] += 1 if @show_groups
210
+ # Track target counts
211
+ @group_counts[target] += 1 if @show_groups
212
212
  end
213
213
 
214
- def detect_group(file_path)
214
+ def detect_target(file_path)
215
215
  case file_path
216
- when /test\/unit\/atoms\//
216
+ when /test\/(fast|unit)\/atoms\//
217
217
  :atoms
218
- when /test\/unit\/molecules\//
218
+ when /test\/(fast|unit)\/molecules\//
219
219
  :molecules
220
- when /test\/unit\/organisms\//
220
+ when /test\/(fast|unit)\/organisms\//
221
221
  :organisms
222
- when /test\/unit\/models\//
222
+ when /test\/(fast|unit)\/models\//
223
223
  :models
224
- when /test\/integration\//
225
- :integration
226
- when /test\/system\//
227
- :system
224
+ when /test\/feat\//
225
+ :feat
226
+ when /test\/edge\//
227
+ :edge
228
228
  else
229
229
  :other
230
230
  end
231
231
  end
232
232
 
233
- def on_group_start(group_name, file_count)
234
- # Print visual separator before group
233
+ def on_target_start(target_name, file_count)
235
234
  puts "" unless @test_count == 0
236
235
  puts ""
237
- puts "Running #{group_name} (#{file_count} #{(file_count == 1) ? "file" : "files"})..."
236
+ puts "Running #{target_name} (#{file_count} #{(file_count == 1) ? "file" : "files"})..."
238
237
  @test_count = 0
239
238
  end
240
239
 
241
- def on_group_complete(group_name, success, duration, summary)
242
- # Ensure we're on a new line after dots
240
+ def on_target_complete(target_name, success, duration, summary)
243
241
  puts unless @test_count == 0 || @test_count % @line_width == 0
244
242
 
245
- # Show group completion status
246
243
  status_icon = success ? "✓" : "✗"
247
244
  test_count = summary[:runs] || 0
248
245
  failure_count = summary[:failures] || 0
249
246
 
250
- status_line = "#{status_icon} #{group_name} complete " +
247
+ status_line = "#{status_icon} #{target_name} complete " +
251
248
  "(#{format_duration(duration)}, #{test_count} tests, #{failure_count} failures)"
252
249
 
253
250
  puts colorize(status_line, success ? :green : :red)
@@ -258,12 +255,12 @@ module Ace
258
255
  # Ensure we're on a new line
259
256
  puts unless @test_count == 0 || @test_count % @line_width == 0
260
257
 
261
- # Print group summary if we have groups and groups are enabled
258
+ # Print target summary if we have target headers enabled
262
259
  if @show_groups && @group_counts.any?
263
260
  puts ""
264
- puts colorize("═══ Group Summary ═══", :cyan)
265
- @group_counts.each do |group, count|
266
- puts " #{group.to_s.capitalize}: #{count} #{(count == 1) ? "file" : "files"}"
261
+ puts colorize("═══ Target Summary ═══", :cyan)
262
+ @group_counts.each do |target, count|
263
+ puts " #{target.to_s.capitalize}: #{count} #{(count == 1) ? "file" : "files"}"
267
264
  end
268
265
  end
269
266
 
@@ -7,7 +7,7 @@ module Ace
7
7
  class TestConfiguration
8
8
  attr_accessor :format, :report_dir, :save_reports, :fail_fast,
9
9
  :verbose, :filter, :fix_deprecations, :patterns,
10
- :timeout, :parallel, :color, :per_file, :groups,
10
+ :timeout, :parallel, :color, :per_file, :targets,
11
11
  :target, :config_path, :failure_limits, :profile,
12
12
  :execution, :files, :run_in_single_batch
13
13
 
@@ -20,13 +20,13 @@ module Ace
20
20
  @filter = attributes[:filter]
21
21
  @fix_deprecations = attributes[:fix_deprecations] || false
22
22
  @patterns = attributes[:patterns] || default_patterns
23
- @groups = attributes[:groups] || default_groups
23
+ @targets = attributes[:targets] || default_targets
24
24
  @target = attributes[:target]
25
25
  @config_path = attributes[:config_path]
26
26
  @timeout = attributes[:timeout] # In seconds, nil = no timeout
27
27
  @parallel = attributes[:parallel] || false
28
28
  @color = attributes.fetch(:color, true)
29
- @per_file = attributes[:per_file] || false # Default to grouped execution for performance
29
+ @per_file = attributes[:per_file] || false # Default to by-target execution for performance
30
30
  @failure_limits = attributes[:failure_limits] || {max_display: 7}
31
31
  @profile = attributes[:profile] # nil means no profiling, number means show N slowest tests
32
32
  @execution = attributes[:execution] || {}
@@ -48,8 +48,8 @@ module Ace
48
48
  end
49
49
 
50
50
  # Validate execution_mode if provided
51
- if execution_mode && !%w[grouped all-at-once].include?(execution_mode)
52
- raise ArgumentError, "Unknown execution_mode '#{execution_mode}'. Valid modes: grouped, all-at-once"
51
+ if execution_mode && !%w[by-target all-at-once].include?(execution_mode)
52
+ raise ArgumentError, "Unknown execution_mode '#{execution_mode}'. Valid modes: by-target, all-at-once"
53
53
  end
54
54
 
55
55
  true
@@ -60,11 +60,11 @@ module Ace
60
60
  @execution&.[](:mode) || @execution&.dig("mode") || "all-at-once"
61
61
  end
62
62
 
63
- def group_isolation
64
- # Default to true for better isolation in grouped mode
63
+ def target_isolation
64
+ # Default to true for better isolation in by-target mode
65
65
  # Use fetch to handle false values correctly (|| would treat false as falsy)
66
- mode = @execution&.[](:group_isolation)
67
- mode = @execution&.dig("group_isolation") if mode.nil?
66
+ mode = @execution&.[](:target_isolation)
67
+ mode = @execution&.dig("target_isolation") if mode.nil?
68
68
  mode.nil? || mode
69
69
  end
70
70
 
@@ -83,7 +83,7 @@ module Ace
83
83
  filter: filter,
84
84
  fix_deprecations: fix_deprecations,
85
85
  patterns: patterns,
86
- groups: groups,
86
+ targets: targets,
87
87
  target: target,
88
88
  config_path: config_path,
89
89
  timeout: timeout,
@@ -125,20 +125,26 @@ module Ace
125
125
 
126
126
  def default_patterns
127
127
  {
128
- atoms: "test/unit/atoms/**/*_test.rb",
129
- molecules: "test/unit/molecules/**/*_test.rb",
130
- organisms: "test/unit/organisms/**/*_test.rb",
131
- models: "test/unit/models/**/*_test.rb",
132
- integration: "test/integration/**/*_test.rb",
133
- system: "test/system/**/*_test.rb",
134
- all: "test/**/*_test.rb"
128
+ smoke: "test/{fast/,}*_test.rb",
129
+ atoms: "test/{fast/,}atoms/**/*_test.rb",
130
+ molecules: "test/{fast/,}molecules/**/*_test.rb",
131
+ organisms: "test/{fast/,}organisms/**/*_test.rb",
132
+ models: "test/{fast/,}models/**/*_test.rb",
133
+ commands: "test/{fast/,}commands/**/*_test.rb",
134
+ cli: "test/{fast/,}cli/**/*_test.rb",
135
+ prompts: "test/{fast/,}prompts/**/*_test.rb",
136
+ fixtures: "test/{fast/,}fixtures/**/*_test.rb",
137
+ support: "test/{fast/,}support/**/*_test.rb",
138
+ feat_tests: "test/feat/**/*_test.rb",
139
+ edge: "test/{fast/,}edge/**/*_test.rb"
135
140
  }
136
141
  end
137
142
 
138
- def default_groups
143
+ def default_targets
139
144
  {
140
- unit: %w[atoms molecules organisms models],
141
- all: %w[unit integration system],
145
+ fast: %w[smoke atoms molecules organisms models commands cli prompts fixtures support],
146
+ feat: %w[feat_tests edge],
147
+ all: %w[fast feat],
142
148
  quick: %w[atoms molecules]
143
149
  }
144
150
  end