Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions libra/tests/command/fetch_test.rs
Original file line number Diff line number Diff line change
@@ -1 +1,110 @@
use std::process::Command;
use std::time::Duration;
use tempfile::TempDir;
use tokio::process::Command as TokioCommand;
use tokio::time::timeout;

/// Helper function: Initialize a temporary Libra repository
fn init_temp_repo() -> TempDir {
let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
let temp_path = temp_dir.path();

eprintln!("Temporary directory created at: {temp_path:?}");
assert!(temp_path.is_dir(), "Temporary path is not a valid directory");

let output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.arg("init")
.output()
.expect("Failed to execute libra binary");

if !output.status.success() {
panic!(
"Failed to initialize libra repository: {}",
String::from_utf8_lossy(&output.stderr)
);
}

eprintln!("Initialized libra repo at: {temp_path:?}");
temp_dir
}

#[tokio::test]
/// Test fetching from an invalid remote repository with timeout
async fn test_fetch_invalid_remote() {
let temp_repo = init_temp_repo();
let temp_path = temp_repo.path();

eprintln!("Starting test: fetch from invalid remote");

// Configure an invalid remote repository
eprintln!("Adding invalid remote: https://invalid-url.example/repo.git");
let remote_output = TokioCommand::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["remote", "add", "origin", "https://invalid-url.example/repo.git"])
.output()
.await
.expect("Failed to add remote");

assert!(
remote_output.status.success(),
"Failed to add remote: {}",
String::from_utf8_lossy(&remote_output.stderr)
);

// Set upstream branch
eprintln!("Setting upstream to origin/main");
let branch_output = TokioCommand::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["branch", "--set-upstream-to", "origin/main"])
.output()
.await
.expect("Failed to set upstream branch");

assert!(
branch_output.status.success(),
"Failed to set upstream: {}",
String::from_utf8_lossy(&branch_output.stderr)
);

// Attempt to fetch with 15-second timeout to avoid hanging CI
eprintln!("Attempting 'libra fetch' with 15s timeout...");
let fetch_result = timeout(Duration::from_secs(15), async {
TokioCommand::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.arg("fetch")
.output()
.await
})
.await;

match fetch_result {
// Timeout occurred — this is expected for unreachable remotes
Err(_) => {
eprintln!("Fetch timed out after 15 seconds — expected for invalid remote");
}
// Command completed within timeout
Ok(Ok(output)) => {

eprintln!("Fetch completed (status: {:?})", output.status);
assert!(
!output.status.success(),
"Fetch should fail when remote is unreachable"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!stderr.trim().is_empty(),
"Expected error message in stderr, but was empty"
);

eprintln!("Fetch failed as expected: {stderr}");
}
// Failed to start the command
Ok(Err(e)) => {

panic!("Failed to run 'libra fetch' command: {e}");
}
}

eprintln!("test_fetch_invalid_remote passed");
}
106 changes: 106 additions & 0 deletions libra/tests/command/lfs_test.rs
Original file line number Diff line number Diff line change
@@ -1 +1,107 @@
use std::process::Command;
use tempfile::TempDir;

/// Helper function: Initialize a temporary Libra repository
fn init_temp_repo() -> TempDir {
let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
let temp_path = temp_dir.path();

// Variables can be used directly in the `format!` string
// FIX: Removed {:?} and added variable directly with formatting

Copilot AI Jul 31, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is misleading - the code still uses {:?} formatting for temp_path on line 11, but the comment suggests it was removed.

Suggested change
// FIX: Removed {:?} and added variable directly with formatting
// Using {:?} formatting to display the temporary path for debugging

Copilot uses AI. Check for mistakes.
println!("Temporary directory created at: {temp_path:?}");
assert!(temp_path.is_dir(), "Temporary path is not a valid directory");

// Using env!("CARGO_BIN_EXE_libra") to get the path to the libra executable
let output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.arg("init")
.output()
.expect("Failed to execute libra binary");

if !output.status.success() {
panic!(
"Failed to initialize libra repository: {}",
String::from_utf8_lossy(&output.stderr)
);
}

temp_dir
}

#[tokio::test]
/// Test track/untrack path rule management
async fn test_lfs_track_untrack() {
let temp_repo = init_temp_repo();
let temp_path = temp_repo.path();

// Add a path rule
// FIX: Removed & from args
let track_output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "track", "*.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to track path");
assert!(
track_output.status.success(),
"Failed to track path: {}",
String::from_utf8_lossy(&track_output.stderr)
);

// Remove a path rule
// FIX: Removed & from args
let untrack_output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "untrack", "*.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to untrack path");
assert!(
untrack_output.status.success(),
"Failed to untrack path: {}",
String::from_utf8_lossy(&untrack_output.stderr)
);
}

#[tokio::test]
/// Test file status viewing
async fn test_lfs_ls_files() {
let temp_repo = init_temp_repo();
let temp_path = temp_repo.path();

// Create a test file and add it to LFS
let file_path = temp_path.join("tracked_file.txt");
std::fs::write(&file_path, "Tracked content").expect("Failed to create tracked file");

// FIX: Removed & from args
Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "track", "*.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to track file");

// FIX: Removed & from args
Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["add", "tracked_file.txt"]) // Changed &[...] to [...]
.output()
.expect("Failed to add file to LFS");

// View file status
// FIX: Removed & from args
let ls_files_output = Command::new(env!("CARGO_BIN_EXE_libra"))
.current_dir(temp_path)
.args(["lfs", "ls-files"]) // Changed &[...] to [...]
.output()
.expect("Failed to list LFS files");
assert!(
ls_files_output.status.success(),
"Failed to list LFS files: {}",
String::from_utf8_lossy(&ls_files_output.stderr)
);

let stdout = String::from_utf8_lossy(&ls_files_output.stdout);
// FIX: Variables can be used directly in the `format!` string
assert!(
stdout.contains("tracked_file.txt"),
"LFS file list does not contain expected file: {stdout}", // Changed {} to direct variable embed

Copilot AI Jul 31, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is incorrect - the code still uses {} placeholder formatting, not direct variable embedding.

Suggested change
"LFS file list does not contain expected file: {stdout}", // Changed {} to direct variable embed
"LFS file list does not contain expected file: {stdout}", // Using placeholder formatting with `format!`

Copilot uses AI. Check for mistakes.
);
}
Loading
Loading