jbuild 0.1.8

High-performance Java build tool supporting Maven and Gradle
Documentation
use jbuild::common::{compare_versions, version_key, is_snapshot, base_version};

/// Test version comparison
#[test]
fn test_version_comparison() {
    // Equal versions
    assert_eq!(compare_versions("1.0.0", "1.0.0"), 0);

    // Simple version comparisons
    assert!(compare_versions("1.0.0", "1.0.1") < 0);
    assert!(compare_versions("1.0.1", "1.0.0") > 0);
    assert!(compare_versions("1.1.0", "1.0.9") > 0);

    // Different number of components
    assert_eq!(compare_versions("1.0", "1.0.0"), 0);
    assert_eq!(compare_versions("1.0.0", "1.0"), 0);
    assert!(compare_versions("1.0", "1.0.1") < 0);

    // Current implementation ignores qualifiers, so versions with same numeric parts are equal
    assert_eq!(compare_versions("1.0.0-alpha", "1.0.0"), 0);
    assert_eq!(compare_versions("1.0.0-SNAPSHOT", "1.0.0"), 0);
}

/// Test version key generation for sorting
#[test]
fn test_version_key_generation() {
    // Basic version keys
    assert_eq!(version_key("1.0.0"), (1, 0, 0, String::new()));
    assert_eq!(version_key("2.1.3"), (2, 1, 3, String::new()));

    // Versions with different component counts
    assert_eq!(version_key("1.0"), (1, 0, 0, String::new()));
    assert_eq!(version_key("1.0.0.1"), (1, 0, 0, "1".to_string()));

    // Versions with qualifiers
    assert_eq!(version_key("1.0.0-alpha"), (1, 0, 0, String::new()));
    assert_eq!(version_key("1.0.0-SNAPSHOT"), (1, 0, 0, String::new()));
}

/// Test snapshot version detection
#[test]
fn test_snapshot_version_detection() {
    assert!(is_snapshot("1.0.0-SNAPSHOT"));
    assert!(is_snapshot("2.1.3-SNAPSHOT"));
    assert!(is_snapshot("1.0-SNAPSHOT"));
    assert!(is_snapshot("1.0.0.1-SNAPSHOT"));

    assert!(!is_snapshot("1.0.0"));
    assert!(!is_snapshot("2.1.3"));
    assert!(!is_snapshot("1.0.0-alpha"));
    assert!(!is_snapshot("1.0.0-beta.1"));
    assert!(!is_snapshot("1.0.0-rc.1"));
    assert!(is_snapshot("snapshot")); // lowercase detected (converted to uppercase)
    assert!(is_snapshot("SNAPSHOT")); // uppercase detected
    assert!(!is_snapshot("snap")); // partial match not detected
}

/// Test base version extraction
#[test]
fn test_base_version_extraction() {
    assert_eq!(base_version("1.0.0-SNAPSHOT"), "1.0.0");
    assert_eq!(base_version("2.1.3-SNAPSHOT"), "2.1.3");
    assert_eq!(base_version("1.0-SNAPSHOT"), "1.0");
    assert_eq!(base_version("1.0.0.1-SNAPSHOT"), "1.0.0.1");

    // Non-snapshot versions should return unchanged
    assert_eq!(base_version("1.0.0"), "1.0.0");
    assert_eq!(base_version("2.1.3"), "2.1.3");
    assert_eq!(base_version("1.0.0-alpha"), "1.0.0-alpha");
    assert_eq!(base_version("1.0.0-beta.1"), "1.0.0-beta.1");
}

/// Test version sorting
#[test]
fn test_version_sorting() {
    let mut versions = ["1.0.0",
        "1.0.1",
        "1.0.0-SNAPSHOT",
        "1.0.0-alpha",
        "1.0.0-beta",
        "2.0.0",
        "1.1.0"];

    versions.sort_by(|a, b| compare_versions(a, b).cmp(&0));

    // With current implementation, versions with same numeric parts are equal
    // So the relative order depends on the original order for equal elements
    // But different major/minor/patch versions should be properly ordered
    assert!(versions.iter().position(|&v| v == "2.0.0").unwrap() >
            versions.iter().position(|&v| v == "1.1.0").unwrap());
    assert!(versions.iter().position(|&v| v == "1.1.0").unwrap() >
            versions.iter().position(|&v| v == "1.0.1").unwrap());
}

/// Test version comparison with qualifiers
#[test]
fn test_version_comparison_complex_qualifiers() {
    // Current implementation ignores qualifiers completely
    // All versions with same numeric parts compare as equal
    assert_eq!(compare_versions("1.0-alpha", "1.0-beta"), 0);
    assert_eq!(compare_versions("1.0-beta", "1.0-rc"), 0);
    assert_eq!(compare_versions("1.0-rc", "1.0"), 0);
}

/// Test version key generation
#[test]
fn test_version_key_numeric_qualifiers() {
    // Basic version keys
    assert_eq!(version_key("1.0.0"), (1, 0, 0, String::new()));
    assert_eq!(version_key("2.1.3"), (2, 1, 3, String::new()));

    // Versions with qualifiers are treated the same as base versions
    assert_eq!(version_key("1.0.0-alpha"), (1, 0, 0, String::new()));
    assert_eq!(version_key("1.0.0-SNAPSHOT"), (1, 0, 0, String::new()));
}

/// Test version comparison edge cases
#[test]
fn test_version_comparison_edge_cases() {
    // Empty versions
    assert_eq!(compare_versions("", ""), 0);
    assert!(compare_versions("", "1.0.0") < 0);
    assert!(compare_versions("1.0.0", "") > 0);

    // Versions with only major version
    assert_eq!(compare_versions("1", "1.0.0"), 0);
    assert!(compare_versions("2", "1.0.0") > 0);

    // Very large version numbers
    assert!(compare_versions("999999", "1000000") < 0);

    // Versions with leading zeros
    assert_eq!(compare_versions("1.01", "1.1"), 0);
    assert_eq!(compare_versions("1.001", "1.1"), 0);
}

/// Test is_snapshot with various formats
#[test]
fn test_snapshot_detection_various_formats() {
    // Standard SNAPSHOT
    assert!(is_snapshot("1.0.0-SNAPSHOT"));

    // Case variations (though Maven standardizes to uppercase)
    assert!(is_snapshot("1.0.0-snapshot"));
    assert!(is_snapshot("1.0.0-Snapshot"));

    // SNAPSHOT with qualifiers
    assert!(is_snapshot("1.0.0-alpha-SNAPSHOT"));
    assert!(is_snapshot("1.0.0-SNAPSHOT-beta"));

    // Non-SNAPSHOT cases
    assert!(!is_snapshot("1.0.0"));
    assert!(!is_snapshot("1.0.0-alpha"));
    assert!(!is_snapshot("1.0.0-beta"));
    assert!(!is_snapshot("1.0.0-rc"));
    assert!(is_snapshot("snapshot"));
    assert!(is_snapshot("SNAPSHOT"));
}

/// Test base_version with various formats
#[test]
fn test_base_version_various_formats() {
    // Standard cases
    assert_eq!(base_version("1.0.0-SNAPSHOT"), "1.0.0");
    assert_eq!(base_version("2.1.3-SNAPSHOT"), "2.1.3");

    // SNAPSHOT with qualifiers
    assert_eq!(base_version("1.0.0-alpha-SNAPSHOT"), "1.0.0-alpha");
    assert_eq!(base_version("1.0.0-SNAPSHOT-beta"), "1.0.0-beta"); // Removes -SNAPSHOT suffix

    // Non-SNAPSHOT versions unchanged
    assert_eq!(base_version("1.0.0"), "1.0.0");
    assert_eq!(base_version("1.0.0-alpha"), "1.0.0-alpha");
    assert_eq!(base_version("1.0.0-beta.1"), "1.0.0-beta.1");

    // Edge cases
    assert_eq!(base_version("SNAPSHOT"), "SNAPSHOT"); // No -SNAPSHOT suffix
    assert_eq!(base_version("-SNAPSHOT"), "");
    assert_eq!(base_version("1.0-SNAPSHOT"), "1.0");
}

/// Test version comparison with different formats
#[test]
fn test_maven_style_version_comparison() {
    // Basic comparisons work
    assert_eq!(compare_versions("1.0", "1.0.0"), 0);
    assert_eq!(compare_versions("1.0.0", "1.0.0.0"), 0);

    // Qualifiers are ignored
    assert_eq!(compare_versions("1.0-alpha", "1.0-beta"), 0);
    assert_eq!(compare_versions("1.0-rc", "1.0"), 0);
}

/// Test version key consistency with comparison
#[test]
fn test_version_key_consistency() {
    let test_versions = vec![
        "1.0.0-SNAPSHOT",
        "1.0.0-alpha",
        "1.0.0-beta",
        "1.0.0-rc.1",
        "1.0.0",
        "1.0.1",
        "1.1.0",
        "2.0.0",
    ];

    // Sort using version keys
    let mut sorted_by_key = test_versions.clone();
    sorted_by_key.sort_by_key(|v| version_key(v));

    // Sort using comparison function
    let mut sorted_by_compare = test_versions.clone();
    sorted_by_compare.sort_by(|a, b| compare_versions(a, b).cmp(&0));

    // With current implementation, both should produce the same relative ordering
    // where numeric differences matter more than qualifiers
    assert_eq!(sorted_by_key, sorted_by_compare);
}

/// Test version key with empty and invalid versions
#[test]
fn test_version_key_edge_cases() {
    // Empty version
    assert_eq!(version_key(""), (0, 0, 0, String::new()));

    // Single number
    assert_eq!(version_key("1"), (1, 0, 0, String::new()));

    // Non-numeric components (should default to 0)
    assert_eq!(version_key("abc"), (0, 0, 0, String::new()));
    assert_eq!(version_key("1.abc.2"), (1, 0, 2, String::new()));

    // Very long version strings
    let long_version = "1.2.3.4.5.6.7.8.9.10-alpha-beta-gamma";
    let (major, minor, patch, suffix) = version_key(long_version);
    assert_eq!((major, minor, patch), (1, 2, 3));
    assert_eq!(suffix, "4");
}

/// Test basic version comparison properties
#[test]
fn test_version_comparison_performance() {
    // Test basic ordering properties
    assert!(compare_versions("1.0.0", "1.0.1") < 0);
    assert!(compare_versions("1.0.1", "1.0.0") > 0);
    assert!(compare_versions("1.1.0", "1.0.9") > 0);
    assert!(compare_versions("2.0.0", "1.9.9") > 0);

    // Test that equal versions return 0
    assert_eq!(compare_versions("1.0.0", "1.0.0"), 0);
    assert_eq!(compare_versions("1.0", "1.0.0"), 0);

    // Test that versions with qualifiers are treated as equal to base versions
    assert_eq!(compare_versions("1.0.0-alpha", "1.0.0"), 0);
    assert_eq!(compare_versions("1.0.0", "1.0.0-SNAPSHOT"), 0);
}