use arch_toolkit::error::{ArchToolkitError, Result};
use arch_toolkit::types::{AurComment, AurPackage, AurPackageDetails};
use arch_toolkit::{AurApi, MockAurApi};
async fn count_packages(api: &dyn AurApi, query: &str) -> Result<usize> {
let packages = api.search(query).await?;
Ok(packages.len())
}
async fn get_package_descriptions(api: &dyn AurApi, package_names: &[&str]) -> Result<Vec<String>> {
let details = api.info(package_names).await?;
Ok(details.into_iter().map(|p| p.description).collect())
}
#[tokio::main]
#[allow(clippy::too_many_lines, clippy::uninlined_format_args)] async fn main() -> Result<()> {
println!("╔═══════════════════════════════════════════════════════════════╗");
println!("║ arch-toolkit: Mock Testing Example ║");
println!("╚═══════════════════════════════════════════════════════════════╝\n");
println!("┌─ Example 1: Basic Mock Setup ───────────────────────────────┐");
println!("│ Creating a mock with predefined search results │");
println!("└──────────────────────────────────────────────────────────────┘");
let mock = MockAurApi::new()
.with_search_result(
"yay",
Ok(vec![
AurPackage {
name: "yay".to_string(),
version: "12.0.0".to_string(),
description: "Yet Another Yaourt".to_string(),
popularity: Some(100.0),
out_of_date: None,
orphaned: false,
maintainer: Some("Jguer".to_string()),
},
AurPackage {
name: "yay-bin".to_string(),
version: "12.0.0".to_string(),
description: "Yet Another Yaourt (binary)".to_string(),
popularity: Some(50.0),
out_of_date: None,
orphaned: false,
maintainer: Some("Jguer".to_string()),
},
]),
)
.with_search_result(
"paru",
Ok(vec![AurPackage {
name: "paru".to_string(),
version: "2.0.0".to_string(),
description: "Feature packed AUR helper".to_string(),
popularity: Some(95.0),
out_of_date: None,
orphaned: false,
maintainer: Some("Morganamilo".to_string()),
}]),
);
let count = count_packages(&mock, "yay").await?;
println!("✓ Found {count} packages matching 'yay'\n");
println!("┌─ Example 2: Testing Error Scenarios ────────────────────────┐");
println!("│ Configuring mock to return errors for testing error handling │");
println!("└──────────────────────────────────────────────────────────────┘");
let error_mock = MockAurApi::new().with_search_result(
"error",
Err(ArchToolkitError::Parse(
"Network error for testing".to_string(),
)),
);
match count_packages(&error_mock, "error").await {
Ok(_) => println!("✗ Unexpected success"),
Err(e) => println!("✓ Correctly handled error: {e}\n"),
}
println!("┌─ Example 3: Default Results ─────────────────────────────────┐");
println!("│ Using default results for unmatched queries │");
println!("└──────────────────────────────────────────────────────────────┘");
let default_mock = MockAurApi::new().with_default_search_result(Ok(vec![AurPackage {
name: "default-package".to_string(),
version: "1.0.0".to_string(),
description: "Default result".to_string(),
popularity: None,
out_of_date: None,
orphaned: false,
maintainer: None,
}]));
let count = count_packages(&default_mock, "any-query").await?;
println!("✓ Default result returned: {count} packages\n");
println!("┌─ Example 4: Info Operation Mocking ─────────────────────────┐");
println!("│ Mocking package info responses │");
println!("└──────────────────────────────────────────────────────────────┘");
let info_mock = MockAurApi::new().with_info_result(
&["yay"],
Ok(vec![AurPackageDetails {
name: "yay".to_string(),
version: "12.0.0".to_string(),
description: "Yet Another Yaourt - A simple AUR helper written in Go".to_string(),
url: "https://github.com/Jguer/yay".to_string(),
licenses: vec!["GPL".to_string(), "MIT".to_string()],
groups: vec![],
provides: vec![],
depends: vec!["git".to_string(), "go".to_string()],
make_depends: vec![],
opt_depends: vec![],
conflicts: vec![],
replaces: vec![],
maintainer: Some("Jguer".to_string()),
first_submitted: Some(1_500_000_000),
last_modified: Some(1_700_000_000),
popularity: Some(100.0),
num_votes: Some(5000),
out_of_date: None,
orphaned: false,
}]),
);
let descriptions = get_package_descriptions(&info_mock, &["yay"]).await?;
println!("✓ Got description: {}\n", descriptions[0]);
println!("┌─ Example 5: Comments Mocking ────────────────────────────────┐");
println!("│ Mocking package comments │");
println!("└──────────────────────────────────────────────────────────────┘");
let comments_mock = MockAurApi::new().with_comments_result(
"yay",
Ok(vec![
AurComment {
id: Some("1".to_string()),
author: "user1".to_string(),
date: "2024-01-15".to_string(),
date_timestamp: Some(1_705_132_800),
date_url: None,
content: "Great package! Works perfectly.".to_string(),
pinned: true,
},
AurComment {
id: Some("2".to_string()),
author: "user2".to_string(),
date: "2024-01-20".to_string(),
date_timestamp: Some(1_705_564_800),
date_url: None,
content: "Thanks for maintaining this!".to_string(),
pinned: false,
},
]),
);
let comments = comments_mock.comments("yay").await?;
println!("✓ Found {} comments", comments.len());
for comment in &comments {
println!(" - {}: {}", comment.author, comment.content);
}
println!();
println!("┌─ Example 6: PKGBUILD Mocking ───────────────────────────────┐");
println!("│ Mocking PKGBUILD content │");
println!("└──────────────────────────────────────────────────────────────┘");
let pkgbuild_mock = MockAurApi::new().with_pkgbuild_result(
"yay",
Ok(r#"pkgname=yay
pkgver=12.0.0
pkgrel=1
pkgdesc="Yet Another Yaourt - A simple AUR helper written in Go"
arch=('x86_64')
url="https://github.com/Jguer/yay"
license=('GPL' 'MIT')
depends=('git' 'go')
makedepends=()
"#
.to_string()),
);
let pkgbuild = pkgbuild_mock.pkgbuild("yay").await?;
println!("✓ PKGBUILD content (first 100 chars):");
println!(" {}\n", &pkgbuild.chars().take(100).collect::<String>());
println!("┌─ Example 7: Complex Mock Configuration ─────────────────────┐");
println!("│ Setting up multiple operations with different results │");
println!("└──────────────────────────────────────────────────────────────┘");
let complex_mock = MockAurApi::new()
.with_search_result(
"yay",
Ok(vec![AurPackage {
name: "yay".to_string(),
version: "12.0.0".to_string(),
description: "AUR helper".to_string(),
popularity: Some(100.0),
out_of_date: None,
orphaned: false,
maintainer: Some("Jguer".to_string()),
}]),
)
.with_info_result(
&["yay"],
Ok(vec![AurPackageDetails {
name: "yay".to_string(),
version: "12.0.0".to_string(),
description: "AUR helper".to_string(),
url: String::new(),
licenses: vec![],
groups: vec![],
provides: vec![],
depends: vec![],
make_depends: vec![],
opt_depends: vec![],
conflicts: vec![],
replaces: vec![],
maintainer: Some("Jguer".to_string()),
first_submitted: None,
last_modified: None,
popularity: Some(100.0),
num_votes: None,
out_of_date: None,
orphaned: false,
}]),
)
.with_comments_result("yay", Ok(vec![]))
.with_pkgbuild_result("yay", Ok("pkgname=yay".to_string()));
let _packages = complex_mock.search("yay").await?;
let _info = complex_mock.info(&["yay"]).await?;
let _comments = complex_mock.comments("yay").await?;
let _pkgbuild = complex_mock.pkgbuild("yay").await?;
println!("✓ All operations completed successfully\n");
println!("╔═══════════════════════════════════════════════════════════════╗");
println!("║ Example Complete! ║");
println!("╚═══════════════════════════════════════════════════════════════╝");
println!("\nThis example demonstrated:");
println!(" • Creating mocks with predefined results");
println!(" • Testing error scenarios");
println!(" • Using default results for unmatched queries");
println!(" • Mocking all AUR operations (search, info, comments, pkgbuild)");
println!(" • Writing testable code using the AurApi trait");
println!("\nKey benefits:");
println!(" • Fast tests (no network requests)");
println!(" • Deterministic behavior");
println!(" • Easy error scenario testing");
println!(" • No external dependencies for tests");
Ok(())
}