use std::collections::HashSet;
use gproxy_protocol::{
Dialect, Operation, OperationKey,
spec::{OPERATION_SPECS, OperationTransport},
};
use strum::IntoEnumIterator;
#[test]
fn every_declared_operation_has_a_unique_modelled_surface() {
let mut keys = HashSet::new();
for spec in OPERATION_SPECS {
assert!(
keys.insert(spec.key),
"duplicate specification: {:?}",
spec.key
);
if let OperationTransport::Http { request, response } = spec.transport {
assert!(!request.is_empty());
assert!(!response.is_empty());
}
}
for operation in Operation::iter() {
assert!(
keys.iter().any(|key| key.operation == operation),
"missing {operation:?}"
);
}
}
#[test]
fn websocket_operations_are_not_encoded_as_http_body_formats() {
for key in [
OperationKey {
operation: Operation::GenerateContent,
dialect: Dialect::OpenAiResponsesWebSocket,
},
OperationKey {
operation: Operation::StreamGenerateContent,
dialect: Dialect::OpenAiResponsesWebSocket,
},
OperationKey {
operation: Operation::ConnectRealtime,
dialect: Dialect::OpenAi,
},
OperationKey {
operation: Operation::ConnectRealtime,
dialect: Dialect::Gemini,
},
] {
let spec = OPERATION_SPECS.iter().find(|spec| spec.key == key).unwrap();
assert_eq!(spec.transport, OperationTransport::WebSocket);
}
}
#[test]
fn media_and_realtime_rows_match_wire_formats_without_claiming_codecs() {
use gproxy_protocol::connection::StreamFraming as S;
use gproxy_protocol::spec::HttpBodyFormat as F;
let cases: &[(Operation, Dialect, &[F], &[F])] = &[
(
Operation::CreateImage,
Dialect::OpenAi,
&[F::Json],
&[F::Json, F::JsonStream(S::Sse)],
),
(
Operation::EditImage,
Dialect::OpenAi,
&[F::Json, F::Multipart],
&[F::Json, F::JsonStream(S::Sse)],
),
(
Operation::CreateSpeech,
Dialect::OpenAi,
&[F::Json],
&[F::Binary, F::JsonStream(S::Sse)],
),
(
Operation::CreateTranscription,
Dialect::OpenAi,
&[F::Multipart],
&[F::Json, F::Text, F::JsonStream(S::Sse)],
),
(
Operation::CreateTranslation,
Dialect::OpenAi,
&[F::Multipart],
&[F::Json, F::Text],
),
(
Operation::CreateRealtimeCall,
Dialect::OpenAi,
&[F::Multipart],
&[F::Text],
),
(
Operation::StreamGenerateContent,
Dialect::Gemini,
&[F::Json],
&[F::JsonStream(S::Sse), F::JsonStream(S::JsonArray)],
),
(
Operation::CreateFile,
Dialect::Gemini,
&[F::Multipart, F::Json, F::Binary],
&[F::Json, F::Empty],
),
(
Operation::DeleteFile,
Dialect::Gemini,
&[F::Empty],
&[F::Json],
),
(
Operation::CreateVideo,
Dialect::OpenAi,
&[F::Json, F::Multipart],
&[F::Json],
),
(
Operation::DownloadVideoContent,
Dialect::OpenAi,
&[F::Empty],
&[F::Binary],
),
];
for (operation, dialect, request, response) in cases {
let key = OperationKey {
operation: *operation,
dialect: *dialect,
};
let spec = OPERATION_SPECS.iter().find(|s| s.key == key).unwrap();
assert_eq!(
spec.transport,
OperationTransport::Http { request, response }
);
}
assert!(!OPERATION_SPECS.iter().any(|s| s.key
== OperationKey {
operation: Operation::CreateSpeech,
dialect: Dialect::Claude
}));
}
#[test]
fn conversion_edges_join_distinct_declared_surfaces() {
use gproxy_protocol::adapt::CONVERSION_EDGES;
let declared = |key: OperationKey| OPERATION_SPECS.iter().any(|spec| spec.key == key);
let upstream_only = |key: OperationKey| {
key.dialect == Dialect::Gemini
&& matches!(
key.operation,
Operation::CreateVideo | Operation::RetrieveVideo | Operation::DownloadVideoContent
)
};
let mut seen = HashSet::new();
for edge in CONVERSION_EDGES {
assert!(seen.insert(edge), "duplicate edge {edge:?}");
assert_ne!(edge.source, edge.target, "self edge {edge:?}");
assert!(declared(edge.source), "undeclared source {edge:?}");
assert!(
declared(edge.target) || upstream_only(edge.target),
"undeclared target {edge:?}"
);
}
}