#![ allow( clippy::float_cmp ) ]
#![ allow( clippy::doc_markdown ) ]
#![ allow( clippy::uninlined_format_args ) ]
use api_huggingface::token_counter::{TokenCounter, CountingStrategy};
use api_huggingface::providers::ChatMessage;
#[ test ]
fn test_estimation_strategy_simple_text()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let text = "The quick brown fox jumps over the lazy dog";
let count = counter.count_tokens( text );
assert_eq!( count.strategy, CountingStrategy::Estimation );
assert!( count.total > 0 );
assert_eq!( count.characters, 43 );
assert_eq!( count.total, 11 ); }
#[ test ]
fn test_word_based_strategy()
{
let counter = TokenCounter::new( CountingStrategy::WordBased );
let text = "Hello world from Rust programming";
let count = counter.count_tokens( text );
assert_eq!( count.strategy, CountingStrategy::WordBased );
assert_eq!( count.total, 7 ); }
#[ test ]
fn test_character_based_strategy()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let text = "Test message";
let count = counter.count_tokens( text );
assert_eq!( count.strategy, CountingStrategy::CharacterBased );
assert_eq!( count.characters, 12 );
assert_eq!( count.total, 4 ); }
#[ test ]
fn test_all_strategies_on_same_text()
{
let text = "The quick brown fox jumps";
let est = TokenCounter::new( CountingStrategy::Estimation ).count_tokens( text );
let word = TokenCounter::new( CountingStrategy::WordBased ).count_tokens( text );
let char = TokenCounter::new( CountingStrategy::CharacterBased ).count_tokens( text );
assert_eq!( est.characters, word.characters );
assert_eq!( word.characters, char.characters );
assert_ne!( char.total, est.total );
}
#[ test ]
fn test_count_single_message()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let messages = vec![
ChatMessage {
role : "user".to_string( ),
content : "Hello, how are you?".to_string( ),
tool_calls : None,
tool_call_id : None,
}
];
let count = counter.count_messages( &messages );
assert!( count.total > 0 );
assert!( count.total >= 10 );
}
#[ test ]
fn test_count_multiple_messages()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let messages = vec![
ChatMessage {
role : "user".to_string( ),
content : "Hello".to_string( ),
tool_calls : None,
tool_call_id : None,
},
ChatMessage {
role : "assistant".to_string( ),
content : "Hi there!".to_string( ),
tool_calls : None,
tool_call_id : None,
},
ChatMessage {
role : "user".to_string( ),
content : "How are you?".to_string( ),
tool_calls : None,
tool_call_id : None,
},
];
let count = counter.count_messages( &messages );
assert!( count.total > 10 );
assert!( count.characters > 20 );
}
#[ test ]
fn test_empty_messages()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let messages : Vec< ChatMessage > = vec![ ];
let count = counter.count_messages( &messages );
assert_eq!( count.total, 0 );
assert_eq!( count.characters, 0 );
}
#[ test ]
fn test_message_with_empty_content()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let messages = vec![
ChatMessage {
role : "user".to_string( ),
content : String::new( ),
tool_calls : None,
tool_call_id : None,
}
];
let count = counter.count_messages( &messages );
assert!( count.total >= 4 );
}
#[ test ]
fn test_count_multiple_texts()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let texts = vec!["Hello", "world", "from", "Rust" ];
let count = counter.count_texts( &texts );
assert_eq!( count.characters, 18 );
assert_eq!( count.total, 5 ); }
#[ test ]
fn test_count_empty_texts()
{
let counter = TokenCounter::new( CountingStrategy::WordBased );
let texts : Vec< &str > = vec![ ];
let count = counter.count_texts( &texts );
assert_eq!( count.total, 0 );
assert_eq!( count.characters, 0 );
}
#[ test ]
fn test_count_texts_with_empty_strings()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let texts = vec!["", "", "hello", "" ];
let count = counter.count_texts( &texts );
assert_eq!( count.characters, 5 ); }
#[ test ]
fn test_cost_units_calculation()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let text = "a".repeat( 4000 );
let count = counter.count_tokens( &text );
let cost = count.cost_units( );
assert_eq!( count.total, 1000 );
assert_eq!( cost, 1.0 ); }
#[ test ]
fn test_cost_units_fractional()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let text = "a".repeat( 2000 );
let count = counter.count_tokens( &text );
let cost = count.cost_units( );
assert_eq!( count.total, 500 );
assert_eq!( cost, 0.5 ); }
#[ test ]
fn test_cost_units_large_text()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let text = "a".repeat( 35000 );
let count = counter.count_tokens( &text );
let cost = count.cost_units( );
assert_eq!( count.total, 10000 );
assert_eq!( cost, 10.0 ); }
#[ test ]
fn test_very_large_text()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let text = "a".repeat( 100_000 );
let count = counter.count_tokens( &text );
assert_eq!( count.characters, 100_000 );
assert_eq!( count.total, 25000 ); }
#[ test ]
fn test_large_text_word_based()
{
let counter = TokenCounter::new( CountingStrategy::WordBased );
let text = ( 0..10000 ).map( |_| "word " ).collect::< String >( );
let count = counter.count_tokens( &text );
assert_eq!( count.total, 13000 );
}
#[ test ]
fn test_unicode_characters()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let text = "Hello 世界 🌍";
let count = counter.count_tokens( text );
assert_eq!( count.characters, 10 );
assert_eq!( count.total, 3 ); }
#[ test ]
fn test_emoji_text()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let text = "🚀🌟💻🎉";
let count = counter.count_tokens( text );
assert_eq!( count.characters, 4 );
assert_eq!( count.total, 1 ); }
#[ test ]
fn test_mixed_scripts()
{
let counter = TokenCounter::new( CountingStrategy::WordBased );
let text = "Hello мир world 世界";
let count = counter.count_tokens( text );
assert_eq!( count.total, 6 );
}
#[ test ]
fn test_empty_string()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let count = counter.count_tokens( "" );
assert_eq!( count.total, 0 );
assert_eq!( count.characters, 0 );
}
#[ test ]
fn test_whitespace_only()
{
let counter = TokenCounter::new( CountingStrategy::WordBased );
let text = " ";
let count = counter.count_tokens( text );
assert_eq!( count.total, 0 );
}
#[ test ]
fn test_newlines_and_tabs()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let text = "Hello\n\tWorld";
let count = counter.count_tokens( text );
assert_eq!( count.characters, 12 ); }
#[ test ]
fn test_single_character()
{
let counter = TokenCounter::new( CountingStrategy::Estimation );
let count = counter.count_tokens( "a" );
assert_eq!( count.characters, 1 );
assert_eq!( count.total, 1 ); }
#[ test ]
fn test_change_strategy()
{
let mut counter = TokenCounter::new( CountingStrategy::Estimation );
let text = "Hello world from Rust programming language";
let count1 = counter.count_tokens( text );
assert_eq!( count1.strategy, CountingStrategy::Estimation );
counter.set_strategy( CountingStrategy::CharacterBased );
let count2 = counter.count_tokens( text );
assert_eq!( count2.strategy, CountingStrategy::CharacterBased );
assert_ne!( count1.total, count2.total );
}
#[ test ]
fn test_default_counter()
{
let counter = TokenCounter::default( );
assert_eq!( counter.strategy( ), CountingStrategy::CharacterBased );
}
#[ test ]
fn test_estimation_vs_character_based()
{
let text = "The quick brown fox";
let est = TokenCounter::new( CountingStrategy::Estimation ).count_tokens( text );
let char = TokenCounter::new( CountingStrategy::CharacterBased ).count_tokens( text );
assert!( char.total <= est.total + 2 );
}
#[ test ]
fn test_word_based_with_punctuation()
{
let counter = TokenCounter::new( CountingStrategy::WordBased );
let text1 = "Hello, world!";
let text2 = "Hello world";
let count1 = counter.count_tokens( text1 );
let count2 = counter.count_tokens( text2 );
assert_eq!( count1.total, count2.total );
}
#[ test ]
fn test_repeated_counting_same_text()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let text = "This is a test message";
let count1 = counter.count_tokens( text );
let count2 = counter.count_tokens( text );
assert_eq!( count1.total, count2.total );
assert_eq!( count1.characters, count2.characters );
}
#[ test ]
fn test_count_long_conversation()
{
let counter = TokenCounter::new( CountingStrategy::CharacterBased );
let mut messages = vec![ ];
for i in 0..100
{
messages.push( ChatMessage {
role : if i % 2 == 0 { "user" } else { "assistant" }.to_string( ),
content : format!( "This is message number {}", i ),
tool_calls : None,
tool_call_id : None,
} );
}
let count = counter.count_messages( &messages );
assert!( count.total > 200 );
assert!( count.characters > 1000 );
}