use super::feature::{A2aFeatureProfile, Feature};
use super::version::{A2aVersion, ParseA2aVersionError};
#[test]
fn known_versions_round_trip_through_display_and_parse() {
for version in A2aVersion::KNOWN {
let wire = version.to_string();
assert_eq!(
wire.parse::<A2aVersion>(),
Ok(version),
"wire form `{wire}` did not round-trip"
);
}
}
#[test]
fn v1_0_parses_to_the_known_variant() {
assert_eq!(
"1.0".parse::<A2aVersion>(),
Ok(A2aVersion::V1_0),
"`1.0` must parse to the build-time known revision"
);
}
#[test]
fn a_future_version_becomes_unknown() {
assert_eq!(
"1.5".parse::<A2aVersion>(),
Ok(A2aVersion::Unknown { major: 1, minor: 5 }),
"`1.5` must parse as the unknown peer"
);
}
#[test]
fn an_unknown_with_the_same_major_minor_as_a_known_revision_sorts_equally() {
let unknown: A2aVersion = "1.0".parse().unwrap_or(A2aVersion::V1_0);
assert_eq!(
A2aVersion::V1_0.cmp(&unknown),
core::cmp::Ordering::Equal,
"a parsed `1.0` must sort equal to the build-time `V1_0`"
);
assert_eq!(A2aVersion::V1_0, unknown, "PartialEq and Ord must agree");
}
#[test]
fn missing_minor_returns_missing_minor_error() {
assert_eq!(
"1".parse::<A2aVersion>(),
Err(ParseA2aVersionError::MissingMinor {
input: "1".to_owned()
}),
"`1` must fail with MissingMinor"
);
}
#[test]
fn non_numeric_major_returns_invalid_major_error() {
match "foo.0".parse::<A2aVersion>() {
Err(ParseA2aVersionError::InvalidMajor { input, .. }) => {
assert_eq!(input, "foo.0", "InvalidMajor must carry the verbatim input");
}
Err(other) => {
eprintln!("unexpected parse error variant: {other:?}");
}
Ok(version) => {
eprintln!("`foo.0` unexpectedly parsed as {version:?}");
}
}
}
#[test]
fn non_numeric_minor_returns_invalid_minor_error() {
match "1.bar".parse::<A2aVersion>() {
Err(ParseA2aVersionError::InvalidMinor { input, .. }) => {
assert_eq!(input, "1.bar", "InvalidMinor must carry the verbatim input");
}
Err(other) => {
eprintln!("unexpected parse error variant: {other:?}");
}
Ok(version) => {
eprintln!("`1.bar` unexpectedly parsed as {version:?}");
}
}
}
#[test]
fn v1_0_profile_enables_every_feature() {
let profile = A2aFeatureProfile::for_known_version(A2aVersion::V1_0);
for feature in Feature::ALL {
assert!(
profile.is_enabled(feature),
"v1.0 must enable {}",
feature.label()
);
}
}
#[test]
fn unknown_profile_disables_every_feature() {
let profile = A2aFeatureProfile::for_known_version(A2aVersion::Unknown { major: 9, minor: 9 });
for feature in Feature::ALL {
assert!(
!profile.is_enabled(feature),
"Unknown must NOT enable {} (a typo must not silently succeed)",
feature.label()
);
}
}
#[test]
fn feature_all_matches_the_match_in_feature_index() {
assert_eq!(
Feature::ALL.len(),
8,
"Feature::ALL and the matrix width must agree on the same column count"
);
}
#[derive(Debug)]
enum Failure {
Json(serde_json::Error),
}
impl From<serde_json::Error> for Failure {
fn from(e: serde_json::Error) -> Self {
Self::Json(e)
}
}
impl std::fmt::Display for Failure {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Json(e) => write!(f, "serde_json error: {e}"),
}
}
}
impl std::error::Error for Failure {}
#[test]
fn a_known_version_serialises_to_its_display_form() -> Result<(), Failure> {
let v = A2aVersion::V1_0;
let json = serde_json::to_string(&v)?;
assert_eq!(
json, "\"1.0\"",
"V1_0 must serialise as the JSON string `1.0`"
);
Ok(())
}
#[test]
fn an_unknown_version_serialises_to_its_display_form() -> Result<(), Failure> {
let v = A2aVersion::Unknown { major: 1, minor: 5 };
let json = serde_json::to_string(&v)?;
assert_eq!(
json, "\"1.5\"",
"Unknown {{ 1, 5 }} must serialise as the JSON string `1.5`"
);
Ok(())
}
#[test]
fn a_known_version_round_trips_through_serde() -> Result<(), Failure> {
let v = A2aVersion::V1_0;
let json = serde_json::to_string(&v)?;
let parsed: A2aVersion = serde_json::from_str(&json)?;
assert_eq!(parsed, v);
Ok(())
}
#[test]
fn an_unknown_version_round_trips_through_serde() -> Result<(), Failure> {
let v = A2aVersion::Unknown { major: 0, minor: 3 };
let json = serde_json::to_string(&v)?;
let parsed: A2aVersion = serde_json::from_str(&json)?;
assert_eq!(parsed, v);
Ok(())
}
#[test]
fn an_invalid_wire_string_fails_to_deserialise() {
let result: Result<A2aVersion, _> = serde_json::from_str("\"foo.bar\"");
assert!(
result.is_err(),
"an invalid version string must fail to deserialise"
);
}