Skip to content

Commit 3f6e2b3

Browse files
committed
Merge #125: Centralize test infrastructure for UserOutput to eliminate duplication
f5dfeb8 fix: add clippy annotations and panics documentation to TestUserOutput (copilot-swe-agent[bot]) eb5088a refactor: update all remaining test files to use TestUserOutput (copilot-swe-agent[bot]) a3a9cb8 refactor: update factory, context, and destroy/handler tests to use TestUserOutput (copilot-swe-agent[bot]) 160c403 refactor: update progress.rs to use TestUserOutput helper (copilot-swe-agent[bot]) 895be5c feat: add TestUserOutput helper for simplified test infrastructure (copilot-swe-agent[bot]) 807a682 Initial plan (copilot-swe-agent[bot]) Pull request description: Eight test files each maintained duplicate `create_test_user_output()` helpers and `SharedWriter` implementations for capturing `UserOutput` in tests. This created maintenance burden and verbose test code requiring manual buffer lock management. ## Changes - **Created centralized `test_support` module** in `src/presentation/user_output.rs` - `TestUserOutput`: Wrapper providing clean API for test output capture - `TestWriter`: Write trait implementation using `Arc<Mutex<Vec<u8>>>` - Helper methods: `wrapped()`, `into_wrapped()`, `stdout()`, `stderr()`, `clear()` - **Updated 9 test files** to use centralized infrastructure - `user_output.rs`, `progress.rs`, `factory.rs`, `context.rs` - `destroy/handler.rs`, `destroy/tests/integration.rs` - `create/subcommands/environment.rs`, `create/tests/{template,integration}.rs` - **Removed duplicate code** - 8 `create_test_user_output()` functions - 2 `SharedWriter` implementations ## Example **Before:** ```rust let (mut output, stdout_buf, stderr_buf) = create_test_user_output(VerbosityLevel::Normal); output.progress("Processing..."); let stderr_content = String::from_utf8(stderr_buf.lock().unwrap().clone()).unwrap(); assert_eq!(stderr_content, "⏳ Processing...\n"); ``` **After:** ```rust let mut test_output = TestUserOutput::new(VerbosityLevel::Normal); test_output.output.progress("Processing..."); assert_eq!(test_output.stderr(), "⏳ Processing...\n"); ``` For tests requiring `Arc<Mutex<UserOutput>>`: ```rust let output = TestUserOutput::wrapped(VerbosityLevel::Normal); ``` <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Simplify Test Infrastructure for UserOutput</issue_title> > <issue_description>## Overview > > Simplify the test infrastructure for `UserOutput` by replacing complex `Arc<Mutex<Vec<u8>>>` and custom `SharedWriter` with a simpler, more maintainable `TestUserOutput` wrapper. This makes test code easier to understand and reduces cognitive load for contributors. > > ## Specification > > See detailed specification: [docs/issues/TBD-simplify-test-infrastructure.md](https://github.com/torrust/torrust-tracker-deployer/blob/main/docs/issues/TBD-simplify-test-infrastructure.md) > > (Link will be updated after file rename) > > ## 🏗️ Architecture Requirements > > **DDD Layer**: Presentation (Test Support Module) > **Module Path**: `src/presentation/user_output.rs` (test module) > **Pattern**: Test Helper Struct > > ### Module Structure Requirements > > - [ ] Keep test infrastructure in `#[cfg(test)]` module within `user_output.rs` > - [ ] Create `TestUserOutput` helper struct for test scenarios > - [ ] Maintain separation between production code and test helpers > - [ ] Follow module organization conventions (see [docs/contributing/module-organization.md](https://github.com/torrust/torrust-tracker-deployer/blob/main/docs/contributing/module-organization.md)) > > ### Architectural Constraints > > - [ ] **Test-only code**: All changes confined to `#[cfg(test)]` modules > - [ ] **No breaking changes**: Production `UserOutput` API unchanged > - [ ] **Standard library preference**: Use `Vec<u8>` and standard types over complex wrappers > - [ ] **Simplicity over cleverness**: Favor readable code over minimal boilerplate > > ### Anti-Patterns to Avoid > > - ❌ **Over-engineering test infrastructure** - Don't add unnecessary abstractions > - ❌ **Leaking test code to production** - Keep test helpers in test modules only > - ❌ **Complex synchronization primitives** - Avoid `Arc<Mutex<>>` unless truly needed > > ## Implementation Plan > > ### Phase 1: Create New Test Infrastructure (1-2 hours) > > - [ ] Create `test_support` module in `#[cfg(test)]` section > - [ ] Implement `TestUserOutput` struct with accessor methods > - [ ] Implement `TestWriter` with `Write` trait > - [ ] Add documentation for test infrastructure > > ### Phase 2: Update Existing Tests (2-3 hours) > > - [ ] Identify all tests using `create_test_user_output()` > - [ ] Update tests to use `TestUserOutput::new()` > - [ ] Simplify test code with new cleaner API > - [ ] Verify all tests pass > > ### Phase 3: Remove Old Infrastructure (30 minutes) > > - [ ] Remove `SharedWriter` struct > - [ ] Remove `create_test_user_output()` function > - [ ] Run linter and fix warnings > > ### Phase 4: Documentation and Verification (30 minutes) > > - [ ] Add module documentation > - [ ] Run full test suite > - [ ] Run pre-commit checks: `./scripts/pre-commit.sh` > > ## Acceptance Criteria > > > **Note for Contributors**: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR to minimize back-and-forth iterations. > > **Quality Checks**: > > - [ ] Pre-commit checks pass: `./scripts/pre-commit.sh` > > **Infrastructure Checks**: > > - [ ] `TestUserOutput` struct exists in test module > - [ ] All accessor methods implemented: `stdout()`, `stderr()`, `output()`, `clear()` > - [ ] Old `SharedWriter` and `create_test_user_output()` removed > > **Test Migration Checks**: > > - [ ] All tests updated to new infrastructure > - [ ] No remaining references to old helpers > - [ ] All tests pass > - [ ] Test code is simpler and more readable > > **Code Quality Checks**: > > - [ ] Test infrastructure well-documented > - [ ] Usage examples provided > - [ ] Standard library types used (`Rc<RefCell<>>` instead of `Arc<Mutex<>>`) > > ## Related > > - Parent: #102 (Epic: User Output Architecture Improvements) > - Roadmap: N/A (Code quality improvement) > - Specification: docs/issues/TBD-simplify-test-infrastructure.md</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> - Fixes #123 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. ACKs for top commit: josecelano: ACK f5dfeb8 Tree-SHA512: e21725010f45d282e65e365dde82235748270f161cc0d59a88bcd86c64d69e20bc799a6426d6166c71982f4014920570584be929ae7cab298a68572b78439dd4
2 parents 7fe118f + f5dfeb8 commit 3f6e2b3

File tree

9 files changed

+326
-242
lines changed

9 files changed

+326
-242
lines changed

src/presentation/commands/context.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -292,23 +292,17 @@ mod tests {
292292
use super::*;
293293
use tempfile::TempDir;
294294

295+
use crate::presentation::user_output::test_support::TestUserOutput;
295296
use crate::presentation::user_output::VerbosityLevel;
296297

297-
/// Test helper to create a test user output
298-
fn create_test_user_output() -> Arc<std::sync::Mutex<UserOutput>> {
299-
Arc::new(std::sync::Mutex::new(UserOutput::new(
300-
VerbosityLevel::Normal,
301-
)))
302-
}
303-
304298
/// Test helper to create a test context with temporary directory
305299
///
306300
/// Returns a tuple of (`TempDir`, `PathBuf`, `Arc<Mutex<UserOutput>>`)
307301
/// The `TempDir` must be kept alive for the duration of the test.
308302
fn create_test_setup() -> (TempDir, PathBuf, Arc<std::sync::Mutex<UserOutput>>) {
309303
let temp_dir = TempDir::new().unwrap();
310304
let working_dir = temp_dir.path().to_path_buf();
311-
let user_output = create_test_user_output();
305+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
312306
(temp_dir, working_dir, user_output)
313307
}
314308

src/presentation/commands/create/subcommands/environment.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -234,15 +234,11 @@ fn display_creation_results(user_output: &Arc<Mutex<UserOutput>>, environment: &
234234
#[cfg(test)]
235235
mod tests {
236236
use super::*;
237+
use crate::presentation::user_output::test_support::TestUserOutput;
237238
use crate::presentation::user_output::VerbosityLevel;
238239
use std::fs;
239240
use tempfile::TempDir;
240241

241-
/// Test helper to create a test user output
242-
fn create_test_user_output() -> Arc<Mutex<UserOutput>> {
243-
Arc::new(Mutex::new(UserOutput::new(VerbosityLevel::Normal)))
244-
}
245-
246242
#[test]
247243
fn it_should_create_environment_from_valid_config() {
248244
let temp_dir = TempDir::new().unwrap();
@@ -268,7 +264,7 @@ mod tests {
268264
fs::write(&config_path, config_json).unwrap();
269265

270266
let working_dir = temp_dir.path();
271-
let user_output = create_test_user_output();
267+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
272268
let result = handle_environment_creation(&config_path, working_dir, &user_output);
273269

274270
assert!(
@@ -292,7 +288,7 @@ mod tests {
292288
let temp_dir = TempDir::new().unwrap();
293289
let config_path = temp_dir.path().join("nonexistent.json");
294290
let working_dir = temp_dir.path();
295-
let user_output = create_test_user_output();
291+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
296292

297293
let result = handle_environment_creation(&config_path, working_dir, &user_output);
298294

@@ -314,7 +310,7 @@ mod tests {
314310
fs::write(&config_path, r#"{"invalid json"#).unwrap();
315311

316312
let working_dir = temp_dir.path();
317-
let user_output = create_test_user_output();
313+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
318314
let result = handle_environment_creation(&config_path, working_dir, &user_output);
319315

320316
assert!(result.is_err());
@@ -350,7 +346,7 @@ mod tests {
350346
fs::write(&config_path, config_json).unwrap();
351347

352348
let working_dir = temp_dir.path();
353-
let user_output = create_test_user_output();
349+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
354350

355351
// Create environment first time
356352
let result1 = handle_environment_creation(&config_path, working_dir, &user_output);
@@ -394,7 +390,7 @@ mod tests {
394390
);
395391
fs::write(&config_path, config_json).unwrap();
396392

397-
let user_output = create_test_user_output();
393+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
398394
let result = handle_environment_creation(&config_path, &custom_working_dir, &user_output);
399395

400396
assert!(result.is_ok(), "Should create in custom working dir");
@@ -438,7 +434,7 @@ mod tests {
438434
);
439435
fs::write(&config_path, config_json).unwrap();
440436

441-
let user_output = create_test_user_output();
437+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
442438
let result = load_configuration(&user_output, &config_path);
443439

444440
assert!(result.is_ok(), "Should load valid configuration");
@@ -451,7 +447,7 @@ mod tests {
451447
let temp_dir = TempDir::new().unwrap();
452448
let config_path = temp_dir.path().join("missing.json");
453449

454-
let user_output = create_test_user_output();
450+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
455451
let result = load_configuration(&user_output, &config_path);
456452

457453
assert!(result.is_err());
@@ -469,7 +465,7 @@ mod tests {
469465
let config_path = temp_dir.path().join("invalid.json");
470466
fs::write(&config_path, r#"{"broken json"#).unwrap();
471467

472-
let user_output = create_test_user_output();
468+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
473469
let result = load_configuration(&user_output, &config_path);
474470

475471
assert!(result.is_err());
@@ -507,7 +503,7 @@ mod tests {
507503
);
508504
fs::write(&config_path, config_json).unwrap();
509505

510-
let user_output = create_test_user_output();
506+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
511507
let loader = ConfigLoader;
512508
let config = loader.load_from_file(&config_path).unwrap();
513509

@@ -543,7 +539,7 @@ mod tests {
543539
);
544540
fs::write(&config_path, config_json).unwrap();
545541

546-
let user_output = create_test_user_output();
542+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
547543
let loader = ConfigLoader;
548544
let config = loader.load_from_file(&config_path).unwrap();
549545

@@ -597,7 +593,7 @@ mod tests {
597593
fs::write(&config_path, config_json).unwrap();
598594

599595
// Create environment
600-
let user_output = create_test_user_output();
596+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
601597
let factory = CommandHandlerFactory::new();
602598
let ctx = factory.create_context(temp_dir.path().to_path_buf(), user_output.clone());
603599
let loader = ConfigLoader;

src/presentation/commands/create/tests/integration.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,14 @@
33
//! This module tests the complete create command workflow including
44
//! configuration loading, validation, and command execution.
55
6-
use std::sync::{Arc, Mutex};
7-
86
use crate::presentation::cli::CreateAction;
97
use crate::presentation::commands::create;
108
use crate::presentation::commands::tests::{
119
create_config_with_invalid_name, create_config_with_missing_keys, create_invalid_json_config,
1210
create_valid_config, TestContext,
1311
};
14-
use crate::presentation::user_output::{UserOutput, VerbosityLevel};
15-
16-
/// Helper to create test `UserOutput`
17-
fn create_test_user_output() -> Arc<Mutex<UserOutput>> {
18-
Arc::new(Mutex::new(UserOutput::new(VerbosityLevel::Normal)))
19-
}
12+
use crate::presentation::user_output::test_support::TestUserOutput;
13+
use crate::presentation::user_output::VerbosityLevel;
2014

2115
/// Helper function to call the environment creation handler
2216
fn handle_environment_creation(
@@ -26,7 +20,7 @@ fn handle_environment_creation(
2620
let action = CreateAction::Environment {
2721
env_file: config_path.to_path_buf(),
2822
};
29-
let user_output = create_test_user_output();
23+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
3024
create::handle_create_command(action, working_dir, &user_output)
3125
}
3226

src/presentation/commands/create/tests/template.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
//! Integration Tests for Template Generation
22
3-
use std::sync::{Arc, Mutex};
4-
53
use crate::presentation::cli::CreateAction;
64
use crate::presentation::commands::create;
75
use crate::presentation::commands::tests::TestContext;
8-
use crate::presentation::user_output::{UserOutput, VerbosityLevel};
9-
10-
/// Helper to create test `UserOutput`
11-
fn create_test_user_output() -> Arc<Mutex<UserOutput>> {
12-
Arc::new(Mutex::new(UserOutput::new(VerbosityLevel::Normal)))
13-
}
6+
use crate::presentation::user_output::test_support::TestUserOutput;
7+
use crate::presentation::user_output::VerbosityLevel;
148

159
#[test]
1610
fn it_should_generate_template_with_default_path() {
@@ -21,7 +15,7 @@ fn it_should_generate_template_with_default_path() {
2115
std::env::set_current_dir(test_context.working_dir()).unwrap();
2216

2317
let action = CreateAction::Template { output_path: None };
24-
let user_output = create_test_user_output();
18+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
2519

2620
let result = create::handle_create_command(action, test_context.working_dir(), &user_output);
2721

@@ -65,7 +59,7 @@ fn it_should_generate_template_with_custom_path() {
6559
let action = CreateAction::Template {
6660
output_path: Some(custom_path.clone()),
6761
};
68-
let user_output = create_test_user_output();
62+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
6963

7064
let result = create::handle_create_command(action, test_context.working_dir(), &user_output);
7165

@@ -90,7 +84,7 @@ fn it_should_generate_valid_json_template() {
9084
let action = CreateAction::Template {
9185
output_path: Some(template_path.clone()),
9286
};
93-
let user_output = create_test_user_output();
87+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
9488

9589
create::handle_create_command(action, test_context.working_dir(), &user_output).unwrap();
9690

@@ -135,7 +129,7 @@ fn it_should_create_parent_directories() {
135129
let action = CreateAction::Template {
136130
output_path: Some(deep_path.clone()),
137131
};
138-
let user_output = create_test_user_output();
132+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
139133

140134
let result = create::handle_create_command(action, test_context.working_dir(), &user_output);
141135

src/presentation/commands/destroy/handler.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,20 +233,16 @@ pub fn handle_destroy_command(
233233
#[cfg(test)]
234234
mod tests {
235235
use super::*;
236+
use crate::presentation::user_output::test_support::TestUserOutput;
236237
use crate::presentation::user_output::VerbosityLevel;
237238
use std::fs;
238239
use tempfile::TempDir;
239240

240-
/// Test helper to create a test user output
241-
fn create_test_user_output() -> Arc<Mutex<UserOutput>> {
242-
Arc::new(Mutex::new(UserOutput::new(VerbosityLevel::Normal)))
243-
}
244-
245241
#[test]
246242
fn it_should_return_error_for_invalid_environment_name() {
247243
let temp_dir = TempDir::new().unwrap();
248244
let working_dir = temp_dir.path();
249-
let user_output = create_test_user_output();
245+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
250246

251247
// Test with invalid environment name (contains underscore)
252248
let result = handle_destroy_command("invalid_name", working_dir, &user_output);
@@ -264,7 +260,7 @@ mod tests {
264260
fn it_should_return_error_for_empty_environment_name() {
265261
let temp_dir = TempDir::new().unwrap();
266262
let working_dir = temp_dir.path();
267-
let user_output = create_test_user_output();
263+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
268264

269265
let result = handle_destroy_command("", working_dir, &user_output);
270266

@@ -281,7 +277,7 @@ mod tests {
281277
fn it_should_return_error_for_nonexistent_environment() {
282278
let temp_dir = TempDir::new().unwrap();
283279
let working_dir = temp_dir.path();
284-
let user_output = create_test_user_output();
280+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
285281

286282
// Try to destroy an environment that doesn't exist
287283
let result = handle_destroy_command("nonexistent-env", working_dir, &user_output);
@@ -300,7 +296,7 @@ mod tests {
300296
fn it_should_accept_valid_environment_name() {
301297
let temp_dir = TempDir::new().unwrap();
302298
let working_dir = temp_dir.path();
303-
let user_output = create_test_user_output();
299+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
304300

305301
// Create a mock environment directory to test validation
306302
let env_dir = working_dir.join("test-env");

src/presentation/commands/destroy/tests/integration.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,11 @@
44
//! including user interaction, error handling, and command orchestration.
55
66
use std::fs;
7-
use std::sync::{Arc, Mutex};
87

98
use crate::presentation::commands::destroy::{handle_destroy_command, DestroySubcommandError};
109
use crate::presentation::commands::tests::TestContext;
11-
use crate::presentation::user_output::{UserOutput, VerbosityLevel};
12-
13-
/// Helper to create test `UserOutput`
14-
fn create_test_user_output() -> Arc<Mutex<UserOutput>> {
15-
Arc::new(Mutex::new(UserOutput::new(VerbosityLevel::Normal)))
16-
}
10+
use crate::presentation::user_output::test_support::TestUserOutput;
11+
use crate::presentation::user_output::VerbosityLevel;
1712

1813
#[test]
1914
fn it_should_reject_invalid_environment_names() {
@@ -27,7 +22,7 @@ fn it_should_reject_invalid_environment_names() {
2722
];
2823

2924
for name in invalid_names {
30-
let user_output = create_test_user_output();
25+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
3126
let result = handle_destroy_command(name, context.working_dir(), &user_output);
3227
assert!(
3328
result.is_err(),
@@ -44,7 +39,7 @@ fn it_should_reject_invalid_environment_names() {
4439
// Test too long name separately due to String allocation
4540
// The actual max length depends on domain validation rules
4641
let too_long_name = "a".repeat(64);
47-
let user_output = create_test_user_output();
42+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
4843
let result = handle_destroy_command(&too_long_name, context.working_dir(), &user_output);
4944
assert!(result.is_err(), "Should get some error for 64-char name");
5045
// Accept either InvalidEnvironmentName OR DestroyOperationFailed
@@ -64,7 +59,7 @@ fn it_should_accept_valid_environment_names() {
6459
];
6560

6661
for name in valid_names {
67-
let user_output = create_test_user_output();
62+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
6863
let result = handle_destroy_command(name, context.working_dir(), &user_output);
6964

7065
// Will fail at operation since environment doesn't exist,
@@ -77,7 +72,7 @@ fn it_should_accept_valid_environment_names() {
7772

7873
// Test max length separately due to String allocation
7974
let max_length_name = "a".repeat(63);
80-
let user_output = create_test_user_output();
75+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
8176
let result = handle_destroy_command(&max_length_name, context.working_dir(), &user_output);
8277
if let Err(DestroySubcommandError::InvalidEnvironmentName { .. }) = result {
8378
panic!("Should not reject valid 63-char environment name");
@@ -88,7 +83,7 @@ fn it_should_accept_valid_environment_names() {
8883
#[test]
8984
fn it_should_fail_for_nonexistent_environment() {
9085
let context = TestContext::new();
91-
let user_output = create_test_user_output();
86+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
9287

9388
let result = handle_destroy_command("nonexistent-env", context.working_dir(), &user_output);
9489

src/presentation/commands/factory.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,10 @@ impl CommandHandlerFactory {
242242
#[cfg(test)]
243243
mod tests {
244244
use super::*;
245+
use crate::presentation::user_output::test_support::TestUserOutput;
245246
use crate::presentation::user_output::VerbosityLevel;
246247
use tempfile::TempDir;
247248

248-
/// Test helper to create a test user output
249-
fn create_test_user_output() -> Arc<Mutex<UserOutput>> {
250-
Arc::new(Mutex::new(UserOutput::new(VerbosityLevel::Normal)))
251-
}
252-
253249
/// Test helper to create a test setup with factory, temp directory, and user output
254250
///
255251
/// Returns a tuple of (`CommandHandlerFactory`, `TempDir`, `PathBuf`, `Arc<Mutex<UserOutput>>`)
@@ -263,7 +259,7 @@ mod tests {
263259
let factory = CommandHandlerFactory::new();
264260
let temp_dir = TempDir::new().unwrap();
265261
let working_dir = temp_dir.path().to_path_buf();
266-
let user_output = create_test_user_output();
262+
let user_output = TestUserOutput::wrapped(VerbosityLevel::Normal);
267263
(factory, temp_dir, working_dir, user_output)
268264
}
269265

@@ -321,8 +317,12 @@ mod tests {
321317
let (factory, _temp_dir, working_dir, _user_output) = create_test_setup();
322318

323319
// Should be able to create multiple contexts
324-
let context1 = factory.create_context(working_dir.clone(), create_test_user_output());
325-
let context2 = factory.create_context(working_dir, create_test_user_output());
320+
let context1 = factory.create_context(
321+
working_dir.clone(),
322+
TestUserOutput::wrapped(VerbosityLevel::Normal),
323+
);
324+
let context2 =
325+
factory.create_context(working_dir, TestUserOutput::wrapped(VerbosityLevel::Normal));
326326

327327
// Both contexts should be functional
328328
let _ = context1.repository();

0 commit comments

Comments
 (0)