#![ allow( clippy::doc_markdown ) ]
#![ allow( clippy::float_cmp ) ]
#![ allow( clippy::single_char_pattern ) ]
use api_huggingface::
{
Client,
environment::HuggingFaceEnvironmentImpl,
secret::Secret,
audio::
{
AudioInput, TranscriptionResult, AudioClassificationResult,
SpeechGenerationResult, AudioTransformResult,
},
error::Result,
};
use base64::Engine;
fn create_test_client() -> Result< Client< HuggingFaceEnvironmentImpl > >
{
let api_key = Secret::new( "test-api-key".to_string() );
let env = HuggingFaceEnvironmentImpl::build( api_key, None )?;
Client::build( env )
}
#[ tokio::test ]
async fn test_audio_api_creation()
{
let client = create_test_client().expect( "Client creation should succeed" );
let audio = client.audio();
assert!( core::mem::size_of_val( &audio ) > 0, "Audio API group should be created" );
}
#[ test ]
fn test_audio_input_from_bytes()
{
let audio_data = vec![ 0x52, 0x49, 0x46, 0x46 ];
let input = AudioInput::from_bytes( audio_data.clone() );
match input
{
AudioInput::Bytes( data ) => assert_eq!( data, audio_data ),
_ => panic!( "Expected Bytes variant" ),
}
}
#[ test ]
fn test_audio_input_from_base64()
{
let base64_data = "UklGRg==";
let input = AudioInput::from_base64( base64_data );
match input
{
AudioInput::Base64( data ) => assert_eq!( data, base64_data ),
_ => panic!( "Expected Base64 variant" ),
}
}
#[ test ]
fn test_audio_input_from_url()
{
let url = "https://example.com/audio.wav";
let input = AudioInput::from_url( url );
match input
{
AudioInput::Url( data ) => assert_eq!( data, url ),
_ => panic!( "Expected Url variant" ),
}
}
#[ test ]
fn test_audio_input_to_base64_from_bytes()
{
let audio_data = vec![ 0x52, 0x49, 0x46, 0x46 ]; let input = AudioInput::from_bytes( audio_data );
let base64 = input.to_base64();
assert!( !base64.is_empty(), "Base64 encoding should not be empty" );
assert_eq!( base64, "UklGRg==" ); }
#[ test ]
fn test_audio_input_to_base64_from_base64()
{
let original_base64 = "UklGRg==";
let input = AudioInput::from_base64( original_base64 );
let base64 = input.to_base64();
assert_eq!( base64, original_base64, "Base64 should be returned unchanged" );
}
#[ test ]
fn test_audio_input_to_base64_from_url()
{
let url = "https://example.com/audio.wav";
let input = AudioInput::from_url( url );
let base64 = input.to_base64();
assert_eq!( base64, url, "URL should be returned unchanged" );
}
#[ test ]
fn test_transcription_result_creation()
{
let text = "Hello world".to_string();
let result = TranscriptionResult { text : text.clone() };
assert_eq!( result.text, text );
}
#[ test ]
fn test_transcription_result_deserialization()
{
let json = r#"{"text": "Test transcription"}"#;
let result : TranscriptionResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( result.text, "Test transcription" );
}
#[ test ]
fn test_audio_classification_result_creation()
{
let label = "speech".to_string();
let score = 0.95;
let result = AudioClassificationResult
{
label : label.clone(),
score,
};
assert_eq!( result.label, label );
assert_eq!( result.score, score );
}
#[ test ]
fn test_audio_classification_result_deserialization()
{
let json = r#"{"label": "music", "score": 0.87}"#;
let result : AudioClassificationResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( result.label, "music" );
assert_eq!( result.score, 0.87 );
}
#[ test ]
fn test_speech_generation_result_creation()
{
let audio_data = vec![ 1, 2, 3, 4, 5 ];
let sample_rate = Some( 22050 );
let format = Some( "wav".to_string() );
let result = SpeechGenerationResult
{
audio_data : audio_data.clone(),
sample_rate,
format : format.clone(),
};
assert_eq!( result.audio_data, audio_data );
assert_eq!( result.sample_rate, sample_rate );
assert_eq!( result.format, format );
}
#[ test ]
fn test_audio_transform_result_creation()
{
let audio_data = vec![ 6, 7, 8, 9, 10 ];
let sample_rate = Some( 16000 );
let format = Some( "mp3".to_string() );
let result = AudioTransformResult
{
audio_data : audio_data.clone(),
sample_rate,
format : format.clone(),
};
assert_eq!( result.audio_data, audio_data );
assert_eq!( result.sample_rate, sample_rate );
assert_eq!( result.format, format );
}
#[ test ]
fn test_base64_encoding_wav_header()
{
let wav_header = vec![ 0x52, 0x49, 0x46, 0x46 ]; let input = AudioInput::from_bytes( wav_header );
let base64 = input.to_base64();
assert!( base64.starts_with( "UklG" ), "WAV header should encode to base64 starting with 'UklG'" );
}
#[ test ]
fn test_base64_encoding_mp3_header()
{
let mp3_header = vec![ 0xFF, 0xFB ]; let input = AudioInput::from_bytes( mp3_header );
let base64 = input.to_base64();
assert!( base64.starts_with( "//" ), "MP3 header should encode to base64 starting with '//'" );
}
#[ test ]
fn test_base64_roundtrip()
{
let original_data = b"Test audio data for encoding";
let input = AudioInput::from_bytes( original_data.to_vec() );
let encoded = input.to_base64();
let decoded = base64::prelude::BASE64_STANDARD.decode( &encoded )
.expect( "Base64 decode should succeed" );
assert_eq!( decoded, original_data, "Roundtrip encoding should preserve data" );
}
#[ test ]
fn test_transcription_response_format()
{
let json = r#"{"text": "This is a test transcription"}"#;
let result : TranscriptionResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( result.text, "This is a test transcription" );
}
#[ test ]
fn test_audio_classification_response_format()
{
let json = r#"[
{"label": "speech", "score": 0.95},
{"label": "music", "score": 0.03},
{"label": "noise", "score": 0.02}
]"#;
let results : Vec< AudioClassificationResult > = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( results.len(), 3 );
assert_eq!( results[ 0 ].label, "speech" );
assert_eq!( results[ 0 ].score, 0.95 );
assert_eq!( results[ 1 ].label, "music" );
assert_eq!( results[ 2 ].label, "noise" );
}
#[ test ]
fn test_empty_transcription_text()
{
let json = r#"{"text": ""}"#;
let result : TranscriptionResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( result.text, "" );
}
#[ test ]
fn test_long_transcription_text()
{
let long_text = "word ".repeat( 500 );
let json = format!( r#"{{"text": "{long_text}"}}"# );
let result : TranscriptionResult = serde_json::from_str( &json )
.expect( "Deserialization should succeed" );
assert!( result.text.len() > 500 );
assert!( result.text.starts_with( "word " ) );
}
#[ test ]
fn test_audio_classification_zero_score()
{
let json = r#"{"label": "unknown", "score": 0.0}"#;
let result : AudioClassificationResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( result.label, "unknown" );
assert_eq!( result.score, 0.0 );
}
#[ test ]
fn test_audio_classification_perfect_score()
{
let json = r#"{"label": "certain", "score": 1.0}"#;
let result : AudioClassificationResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( result.label, "certain" );
assert_eq!( result.score, 1.0 );
}
#[ test ]
fn test_empty_classification_results()
{
let json = "[]";
let results : Vec< AudioClassificationResult > = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( results.len(), 0, "Empty results should deserialize" );
}
#[ test ]
fn test_speech_generation_result_no_metadata()
{
let audio_data = vec![ 1, 2, 3 ];
let result = SpeechGenerationResult
{
audio_data : audio_data.clone(),
sample_rate : None,
format : None,
};
assert_eq!( result.audio_data, audio_data );
assert!( result.sample_rate.is_none() );
assert!( result.format.is_none() );
}
#[ test ]
fn test_audio_transform_result_large_data()
{
let large_data = vec![ 0u8; 10000 ];
let result = AudioTransformResult
{
audio_data : large_data.clone(),
sample_rate : Some( 44100 ),
format : Some( "wav".to_string() ),
};
assert_eq!( result.audio_data.len(), 10000 );
assert_eq!( result.sample_rate, Some( 44100 ) );
}
#[ test ]
fn test_transcription_with_special_characters()
{
let json = r#"{"text": "Hello, world! How are you? It's nice."}"#;
let result : TranscriptionResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert!( result.text.contains( "," ) );
assert!( result.text.contains( "!" ) );
assert!( result.text.contains( "?" ) );
assert!( result.text.contains( "'" ) );
}
#[ test ]
fn test_transcription_with_unicode()
{
let json = r#"{"text": "Héllo wörld 你好"}"#;
let result : TranscriptionResult = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert!( result.text.contains( "é" ) );
assert!( result.text.contains( "ö" ) );
assert!( result.text.contains( "你好" ) );
}
#[ test ]
fn test_audio_classification_multiple_high_scores()
{
let json = r#"[
{"label": "speech", "score": 0.48},
{"label": "music", "score": 0.47},
{"label": "ambient", "score": 0.05}
]"#;
let results : Vec< AudioClassificationResult > = serde_json::from_str( json )
.expect( "Deserialization should succeed" );
assert_eq!( results.len(), 3 );
assert!( results[ 0 ].score > 0.4 );
assert!( results[ 1 ].score > 0.4 );
assert!( results[ 2 ].score < 0.1 );
}