use api_ollama::{
OllamaClient,
ChatMessage,
MessageRole,
ChatRequest,
GenerateRequest
};
use core::time::Duration;
#[ test ]
fn test_ollama_client_new()
{
let client = OllamaClient::new( "http://test.local:11434".to_string(), OllamaClient::recommended_timeout_fast() );
let _ = client;
}
#[ test ]
fn test_ollama_client_default()
{
let client = OllamaClient::default();
let _ = client;
}
#[ test ]
fn test_ollama_client_with_timeout()
{
let client = OllamaClient::new( "http://test.local:11434".to_string(), OllamaClient::recommended_timeout_fast() )
.with_timeout( Duration::from_secs( 60 ) );
let _ = client;
}
#[ test ]
fn test_message_creation()
{
let message = ChatMessage
{
role : MessageRole::User,
content : "Hello, world!".to_string(),
images : None,
#[ cfg( feature = "tool_calling" ) ]
tool_calls : None,
};
assert_eq!( message.role, MessageRole::User );
assert_eq!( message.content, "Hello, world!" );
}
#[ test ]
fn test_chat_request_creation()
{
let messages = vec!
[
ChatMessage
{
role : MessageRole::User,
content : "Hello".to_string(),
images : None,
#[ cfg( feature = "tool_calling" ) ]
tool_calls : None,
}
];
let request = ChatRequest
{
model : "test-model".to_string(),
messages,
stream : Some( false ),
options : None,
#[ cfg( feature = "tool_calling" ) ]
tools : None,
#[ cfg( feature = "tool_calling" ) ]
tool_messages : None,
};
assert_eq!( request.model, "test-model" );
assert_eq!( request.messages.len(), 1 );
assert_eq!( request.stream, Some( false ) );
}
#[ test ]
fn test_generate_request_creation()
{
let request = GenerateRequest
{
model : "test-model".to_string(),
prompt : "Tell me a joke".to_string(),
stream : Some( false ),
options : None,
};
assert_eq!( request.model, "test-model" );
assert_eq!( request.prompt, "Tell me a joke" );
assert_eq!( request.stream, Some( false ) );
}
#[ test ]
fn test_serialization_deserialization()
{
let message = ChatMessage
{
role : MessageRole::Assistant,
content : "Hello there!".to_string(),
images : None,
#[ cfg( feature = "tool_calling" ) ]
tool_calls : None,
};
let serialized = serde_json::to_string( &message ).expect( "Failed to serialize message" );
let deserialized : ChatMessage = serde_json::from_str( &serialized ).expect( "Failed to deserialize message" );
assert_eq!( deserialized.role, message.role );
assert_eq!( deserialized.content, message.content );
}
#[ tokio::test ]
async fn test_client_is_available_unreachable_server()
{
let mut client = OllamaClient::new( "http://unreachable.test:99999".to_string(), OllamaClient::recommended_timeout_fast() )
.with_timeout( Duration::from_millis( 100 ) );
let result = client.is_available().await;
assert!( !result );
}
#[ test ]
fn chat_request_optional_fields_absent_when_none()
{
let msg = ChatMessage
{
role : MessageRole::User,
content : "hi".to_string(),
images : None,
#[ cfg( feature = "tool_calling" ) ]
tool_calls : None,
};
let request = ChatRequest
{
model : "test-model".to_string(),
messages : vec![ msg ],
stream : None,
options : None,
#[ cfg( feature = "tool_calling" ) ]
tools : None,
#[ cfg( feature = "tool_calling" ) ]
tool_messages : None,
};
let json = serde_json::to_value( &request ).expect( "ChatRequest must serialize" );
assert!( !json.as_object().unwrap().contains_key( "stream" ),
"stream must be absent from JSON when None" );
assert!( !json.as_object().unwrap().contains_key( "options" ),
"options must be absent from JSON when None" );
assert!( json[ "model" ] == "test-model" );
assert!( json[ "messages" ].is_array() );
}
#[ test ]
fn generate_request_optional_fields_absent_when_none()
{
let request = GenerateRequest
{
model : "test-model".to_string(),
prompt : "hello".to_string(),
stream : None,
options : None,
};
let json = serde_json::to_value( &request ).expect( "GenerateRequest must serialize" );
assert!( !json.as_object().unwrap().contains_key( "stream" ),
"stream must be absent when None" );
assert!( !json.as_object().unwrap().contains_key( "options" ),
"options must be absent when None" );
}
#[ test ]
fn chat_request_no_stream_flag_when_not_set()
{
let msg = ChatMessage
{
role : MessageRole::User,
content : "test".to_string(),
images : None,
#[ cfg( feature = "tool_calling" ) ]
tool_calls : None,
};
let request = ChatRequest
{
model : "m".to_string(),
messages : vec![ msg ],
stream : None,
options : None,
#[ cfg( feature = "tool_calling" ) ]
tools : None,
#[ cfg( feature = "tool_calling" ) ]
tool_messages : None,
};
let json_str = serde_json::to_string( &request ).expect( "must serialize" );
assert!( !json_str.contains( "\"stream\"" ),
"stream key must not appear in JSON when field is None" );
}
#[ test ]
fn default_client_uses_localhost_11434()
{
let client = OllamaClient::default();
assert_eq!( client.base_url(), "http://localhost:11434",
"default base URL must be http://localhost:11434" );
}
#[ test ]
fn ollama_host_env_var_is_respected()
{
let expected = "http://localhost:11434";
std::env::set_var( "OLLAMA_HOST", expected );
let resolved = std::env::var( "OLLAMA_HOST" ).expect( "OLLAMA_HOST must be set" );
assert_eq!( resolved, expected );
let client = OllamaClient::new( resolved, OllamaClient::recommended_timeout_fast() );
assert_eq!( client.base_url(), expected );
std::env::remove_var( "OLLAMA_HOST" );
}
#[ test ]
fn missing_ollama_host_env_var_returns_error()
{
std::env::remove_var( "OLLAMA_HOST" );
let result = std::env::var( "OLLAMA_HOST" );
assert!( result.is_err(),
"OLLAMA_HOST must not be set during this test; got {result:?}" );
}
#[ test ]
fn full_features_client_constructs_successfully()
{
let client = OllamaClient::new(
"http://localhost:11434".to_string(),
OllamaClient::recommended_timeout_fast()
);
let _ = client.base_url();
}
#[ tokio::test ]
async fn default_client_fails_immediately_without_enterprise_behaviour()
{
let mut client = OllamaClient::new(
"http://localhost:1".to_string(), Duration::from_millis( 200 ),
);
let start = std::time::Instant::now();
let result = client.list_models().await;
let elapsed = start.elapsed();
assert!( result.is_err(), "call to unreachable host must return Err" );
assert!( elapsed < Duration::from_secs( 5 ),
"default client must fail on first attempt without retry delay; elapsed={elapsed:?}" );
}
#[ test ]
fn crate_root_exports_are_accessible()
{
let _msg : ChatMessage = ChatMessage
{
role : MessageRole::Assistant,
content : "test".to_string(),
images : None,
#[ cfg( feature = "tool_calling" ) ]
tool_calls : None,
};
let _gen = GenerateRequest
{
model : "m".to_string(),
prompt : "p".to_string(),
stream : None,
options : None,
};
let _client = OllamaClient::default();
}