//! Tests for version module

use governor_core::domain::version::{BumpType, SemanticVersion};
use semver::Version;

#[test]
fn test_parse_version() {
    let v = SemanticVersion::parse("1.2.3").unwrap();
    assert_eq!(v.major(), 1);
    assert_eq!(v.minor(), 2);
    assert_eq!(v.patch(), 3);
}

#[test]
fn test_parse_version_with_prerelease() {
    let v = SemanticVersion::parse("1.2.3-alpha.1").unwrap();
    assert_eq!(v.major(), 1);
    assert_eq!(v.minor(), 2);
    assert_eq!(v.patch(), 3);
    assert!(v.is_prerelease);
    assert_eq!(v.prerelease_type, Some("alpha".to_string()));
}

#[test]
fn test_parse_version_with_build() {
    let v = SemanticVersion::parse("1.2.3+build.123").unwrap();
    assert_eq!(v.major(), 1);
    assert_eq!(v.minor(), 2);
    assert_eq!(v.patch(), 3);
}

#[test]
fn test_parse_version_invalid() {
    assert!(SemanticVersion::parse("invalid").is_err());
    assert!(SemanticVersion::parse("1.2").is_err());
    assert!(SemanticVersion::parse("a.b.c").is_err());
}

#[test]
fn test_version_display() {
    let v = SemanticVersion::parse("1.2.3").unwrap();
    assert_eq!(v.to_string(), "1.2.3");
}

#[test]
fn test_version_with_prerelease_display() {
    let v = SemanticVersion::parse("1.2.3-alpha.1").unwrap();
    assert_eq!(v.to_string(), "1.2.3-alpha.1");
}

#[test]
fn test_bump_major() {
    let v = SemanticVersion::from(Version::new(1, 2, 3));
    let bumped = BumpType::Major.apply_to(&v);
    assert_eq!(bumped.to_string(), "2.0.0");
}

#[test]
fn test_bump_minor() {
    let v = SemanticVersion::from(Version::new(1, 2, 3));
    let bumped = BumpType::Minor.apply_to(&v);
    assert_eq!(bumped.to_string(), "1.3.0");
}

#[test]
fn test_bump_patch() {
    let v = SemanticVersion::from(Version::new(1, 2, 3));
    let bumped = BumpType::Patch.apply_to(&v);
    assert_eq!(bumped.to_string(), "1.2.4");
}

#[test]
fn test_bump_none() {
    let v = SemanticVersion::from(Version::new(1, 2, 3));
    let bumped = BumpType::None.apply_to(&v);
    assert_eq!(bumped.to_string(), "1.2.3");
}

#[test]
fn test_bump_type_apply() {
    let v = SemanticVersion::from(Version::new(1, 2, 3));
    assert_eq!(BumpType::Major.apply_to(&v).to_string(), "2.0.0");
    assert_eq!(BumpType::Minor.apply_to(&v).to_string(), "1.3.0");
    assert_eq!(BumpType::Patch.apply_to(&v).to_string(), "1.2.4");
}

#[test]
fn test_version_from_semver() {
    let v = SemanticVersion::from(Version::new(1, 2, 3));
    assert_eq!(v.major(), 1);
    assert_eq!(v.minor(), 2);
    assert_eq!(v.patch(), 3);
}

#[test]
fn test_version_equality() {
    let v1 = SemanticVersion::from(Version::new(1, 2, 3));
    let v2 = SemanticVersion::parse("1.2.3").unwrap();
    assert_eq!(v1, v2);
}

#[test]
fn test_prerelease_version() {
    let v = SemanticVersion::from(Version::new(1, 2, 3)).with_prerelease("alpha.1");
    assert!(v.is_prerelease);
    assert_eq!(v.prerelease_type, Some("alpha".to_string()));
    assert_eq!(v.to_string(), "1.2.3-alpha.1");
}

#[test]
fn test_bump_type_display() {
    assert_eq!(format!("{:?}", BumpType::Major), "Major");
    assert_eq!(format!("{:?}", BumpType::Minor), "Minor");
    assert_eq!(format!("{:?}", BumpType::Patch), "Patch");
    assert_eq!(format!("{:?}", BumpType::None), "None");
}

#[test]
fn test_parse_prerelease() {
    let v = SemanticVersion::parse("1.0.0-beta").unwrap();
    assert!(v.is_prerelease);
    assert_eq!(v.prerelease_type, Some("beta".to_string()));
}

#[test]
fn test_bump_methods() {
    let v = SemanticVersion::from(Version::new(1, 2, 3));
    assert_eq!(v.bump_major().to_string(), "2.0.0");
    assert_eq!(v.bump_minor().to_string(), "1.3.0");
    assert_eq!(v.bump_patch().to_string(), "1.2.4");
}

#[test]
fn test_version_from_str() {
    let v = SemanticVersion::from(Version::new(0, 1, 0));
    assert_eq!(v.major(), 0);
    assert_eq!(v.minor(), 1);
    assert_eq!(v.patch(), 0);
}
