mirror of
https://github.com/d-k-patel/ai-ffmpeg-cli.git
synced 2025-10-09 13:42:56 +03:00
Add comprehensive token usage tracking and beautiful ASCII art interface to enhance user experience and provide cost transparency. - Add TokenTracker class for real-time token usage monitoring - Implement ASCII art banner with pyfiglet integration - Add cost estimation based on OpenAI pricing models - Display real-time token usage after each AI operation - Add 'tokens' command in interactive mode for usage statistics - Show session summary with detailed analytics at session end - Integrate token tracking into OpenAIProvider with optional TokenTracker - Add pyfiglet and tiktoken dependencies to pyproject.toml - Create ascii_art.py module for banner display functionality - Update main.py to initialize and manage token tracking sessions - Add session management with unique session IDs - Implement detailed usage tables with rich formatting - Update README.md with token tracking features and examples - Add ASCII art banner to welcome screen documentation - Include cost transparency and usage analytics sections - Update version to 0.2.5 in README examples - Remove Windows from supported OS list in bug report template - Add comprehensive unit tests for TokenTracker functionality - Add unit tests for ASCII art display features - Ensure proper error handling and edge cases covered - Real-time cost estimates displayed after each operation - Beautiful ASCII art welcome banner that adapts to terminal width - Session-based token tracking with detailed summaries - Interactive 'tokens' command for on-demand usage statistics - Rich formatted tables for better readability Breaking Changes: None Dependencies Added: pyfiglet>=1.0.0, tiktoken>=0.5.0
139 lines
5.3 KiB
Python
139 lines
5.3 KiB
Python
"""Tests for ASCII art functionality."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
from ai_ffmpeg_cli.ascii_art import center_text
|
|
from ai_ffmpeg_cli.ascii_art import display_colored_ascii_art
|
|
from ai_ffmpeg_cli.ascii_art import display_dynamic_banner
|
|
from ai_ffmpeg_cli.ascii_art import display_welcome_banner
|
|
from ai_ffmpeg_cli.ascii_art import get_ascii_art
|
|
from ai_ffmpeg_cli.ascii_art import get_random_font
|
|
from ai_ffmpeg_cli.ascii_art import get_terminal_width
|
|
|
|
|
|
class TestAsciiArt:
|
|
"""Test cases for ASCII art functionality."""
|
|
|
|
def test_get_ascii_art_default(self):
|
|
"""Test getting ASCII art with default parameters."""
|
|
result = get_ascii_art()
|
|
# Check that it's a non-empty string with ASCII art characters
|
|
assert isinstance(result, str)
|
|
assert len(result) > 0
|
|
# Should contain some ASCII art characters
|
|
assert any(char in result for char in ["/", "\\", "_", "|", "#", "="])
|
|
|
|
def test_get_ascii_art_custom_text(self):
|
|
"""Test getting ASCII art with custom text."""
|
|
result = get_ascii_art("TEST")
|
|
assert isinstance(result, str)
|
|
assert len(result) > 0
|
|
# Should contain some ASCII art characters
|
|
assert any(char in result for char in ["/", "\\", "_", "|", "#", "="])
|
|
|
|
def test_get_ascii_art_custom_font(self):
|
|
"""Test getting ASCII art with custom font."""
|
|
result = get_ascii_art("TEST", "banner")
|
|
assert isinstance(result, str)
|
|
assert len(result) > 0
|
|
# Should contain some ASCII art characters
|
|
assert any(char in result for char in ["/", "\\", "_", "|", "#", "="])
|
|
|
|
def test_get_ascii_art_fallback(self):
|
|
"""Test ASCII art fallback when pyfiglet fails."""
|
|
with patch("ai_ffmpeg_cli.ascii_art.pyfiglet.Figlet") as mock_figlet:
|
|
mock_figlet.side_effect = Exception("Font not found")
|
|
result = get_ascii_art("TEST")
|
|
assert "TEST" in result
|
|
assert "╔" in result # Check for fallback box characters
|
|
|
|
def test_get_random_font(self):
|
|
"""Test getting a random font."""
|
|
font = get_random_font()
|
|
assert isinstance(font, str)
|
|
assert len(font) > 0
|
|
|
|
def test_get_random_font_returns_valid_font(self):
|
|
"""Test that random font is from the valid font list."""
|
|
font = get_random_font()
|
|
# Since it's random, we can't guarantee it's in our small test list
|
|
# But we can test that it's a string and not empty
|
|
assert isinstance(font, str)
|
|
assert len(font) > 0
|
|
|
|
@patch("ai_ffmpeg_cli.ascii_art.console")
|
|
def test_display_colored_ascii_art(self, mock_console):
|
|
"""Test displaying colored ASCII art."""
|
|
display_colored_ascii_art("TEST")
|
|
# Verify that console.print was called
|
|
assert mock_console.print.called
|
|
|
|
@patch("ai_ffmpeg_cli.ascii_art.console")
|
|
def test_display_colored_ascii_art_custom_colors(self, mock_console):
|
|
"""Test displaying colored ASCII art with custom colors."""
|
|
display_colored_ascii_art(
|
|
"TEST", primary_color="red", secondary_color="yellow", accent_color="blue"
|
|
)
|
|
# Verify that console.print was called
|
|
assert mock_console.print.called
|
|
|
|
@patch("ai_ffmpeg_cli.ascii_art.console")
|
|
def test_display_welcome_banner(self, mock_console):
|
|
"""Test displaying welcome banner."""
|
|
display_welcome_banner()
|
|
# Verify that console.print was called multiple times
|
|
assert mock_console.print.call_count >= 2
|
|
|
|
@patch("ai_ffmpeg_cli.ascii_art.console")
|
|
def test_display_dynamic_banner(self, mock_console):
|
|
"""Test displaying dynamic banner."""
|
|
display_dynamic_banner()
|
|
# Verify that console.print was called
|
|
assert mock_console.print.called
|
|
|
|
def test_ascii_art_with_empty_text(self):
|
|
"""Test ASCII art with empty text."""
|
|
result = get_ascii_art("")
|
|
assert isinstance(result, str)
|
|
# Should still produce some output even with empty text
|
|
|
|
def test_ascii_art_with_special_characters(self):
|
|
"""Test ASCII art with special characters."""
|
|
result = get_ascii_art("AICLIP-123!")
|
|
assert isinstance(result, str)
|
|
assert len(result) > 0
|
|
|
|
@patch("ai_ffmpeg_cli.ascii_art.console")
|
|
def test_display_colored_ascii_art_with_long_text(self, mock_console):
|
|
"""Test displaying colored ASCII art with long text."""
|
|
long_text = "VERY_LONG_TEXT_FOR_TESTING"
|
|
display_colored_ascii_art(long_text)
|
|
# Verify that console.print was called
|
|
assert mock_console.print.called
|
|
|
|
def test_get_terminal_width(self):
|
|
"""Test getting terminal width."""
|
|
width = get_terminal_width()
|
|
assert isinstance(width, int)
|
|
assert width > 0
|
|
|
|
def test_center_text(self):
|
|
"""Test centering text."""
|
|
text = "Hello\nWorld"
|
|
centered = center_text(text, 20)
|
|
assert isinstance(centered, str)
|
|
assert "Hello" in centered
|
|
assert "World" in centered
|
|
|
|
def test_center_text_empty(self):
|
|
"""Test centering empty text."""
|
|
text = ""
|
|
centered = center_text(text, 20)
|
|
assert centered == ""
|
|
|
|
def test_center_text_short_width(self):
|
|
"""Test centering text when width is shorter than text."""
|
|
text = "Hello World"
|
|
centered = center_text(text, 5)
|
|
assert "Hello World" in centered
|