init
This commit is contained in:
185
.opencode/skills/ai-multimodal/scripts/tests/test_minimax_cli.py
Normal file
185
.opencode/skills/ai-multimodal/scripts/tests/test_minimax_cli.py
Normal file
@@ -0,0 +1,185 @@
|
||||
"""
|
||||
Tests for minimax_cli.py - CLI argument parsing and task dispatch.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock, patch, MagicMock
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
import minimax_cli as cli
|
||||
|
||||
|
||||
class TestTaskDefaults:
|
||||
"""Test task-to-model default mapping."""
|
||||
|
||||
def test_generate_defaults_to_image_01(self):
|
||||
assert cli.TASK_DEFAULTS['generate'] == 'image-01'
|
||||
|
||||
def test_generate_video_defaults_to_hailuo(self):
|
||||
assert cli.TASK_DEFAULTS['generate-video'] == 'MiniMax-Hailuo-2.3'
|
||||
|
||||
def test_generate_speech_defaults_to_speech_28_hd(self):
|
||||
assert cli.TASK_DEFAULTS['generate-speech'] == 'speech-2.8-hd'
|
||||
|
||||
def test_generate_music_defaults_to_music_25(self):
|
||||
assert cli.TASK_DEFAULTS['generate-music'] == 'music-2.5'
|
||||
|
||||
|
||||
class TestPrintResult:
|
||||
"""Test result formatting."""
|
||||
|
||||
def test_success_image(self, capsys):
|
||||
result = {
|
||||
"status": "success",
|
||||
"generated_images": ["/path/to/img.png"],
|
||||
"model": "image-01"
|
||||
}
|
||||
cli.print_result(result, "generate")
|
||||
output = capsys.readouterr().out
|
||||
assert "success" in output.lower()
|
||||
assert "/path/to/img.png" in output
|
||||
assert "image-01" in output
|
||||
|
||||
def test_success_video(self, capsys):
|
||||
result = {
|
||||
"status": "success",
|
||||
"generated_video": "/path/to/vid.mp4",
|
||||
"generation_time": 45.2,
|
||||
"model": "MiniMax-Hailuo-2.3"
|
||||
}
|
||||
cli.print_result(result, "generate-video")
|
||||
output = capsys.readouterr().out
|
||||
assert "/path/to/vid.mp4" in output
|
||||
assert "45.2s" in output
|
||||
|
||||
def test_success_audio(self, capsys):
|
||||
result = {
|
||||
"status": "success",
|
||||
"generated_audio": "/path/to/audio.mp3",
|
||||
"duration_ms": 140000,
|
||||
"model": "music-2.5"
|
||||
}
|
||||
cli.print_result(result, "generate-music")
|
||||
output = capsys.readouterr().out
|
||||
assert "/path/to/audio.mp3" in output
|
||||
assert "140.0s" in output
|
||||
|
||||
def test_error_result(self, capsys):
|
||||
result = {"status": "error", "error": "Rate limit exceeded"}
|
||||
cli.print_result(result, "generate")
|
||||
output = capsys.readouterr().out
|
||||
assert "Rate limit exceeded" in output
|
||||
|
||||
def test_unknown_status(self, capsys):
|
||||
result = {"model": "image-01"}
|
||||
cli.print_result(result, "generate")
|
||||
output = capsys.readouterr().out
|
||||
assert "unknown" in output.lower()
|
||||
|
||||
|
||||
class TestMainCLI:
|
||||
"""Test CLI main() argument parsing and dispatch."""
|
||||
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value=None)
|
||||
def test_no_api_key_exits(self, mock_key, capsys):
|
||||
with patch('sys.argv', ['cli', '--task', 'generate', '--prompt', 'x']):
|
||||
with pytest.raises(SystemExit) as exc_info:
|
||||
cli.main()
|
||||
assert exc_info.value.code == 1
|
||||
|
||||
@patch('minimax_cli.generate_image')
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_generate_image_dispatch(self, mock_key, mock_gen):
|
||||
mock_gen.return_value = {"status": "success", "generated_images": [],
|
||||
"model": "image-01"}
|
||||
with patch('sys.argv', ['cli', '--task', 'generate',
|
||||
'--prompt', 'A cat']):
|
||||
cli.main()
|
||||
mock_gen.assert_called_once()
|
||||
args = mock_gen.call_args
|
||||
assert args[0][0] == 'test-key'
|
||||
assert args[0][1] == 'A cat'
|
||||
|
||||
@patch('minimax_cli.generate_speech')
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_generate_speech_dispatch(self, mock_key, mock_gen):
|
||||
mock_gen.return_value = {"status": "success",
|
||||
"generated_audio": "/x.mp3",
|
||||
"model": "speech-2.8-hd"}
|
||||
with patch('sys.argv', ['cli', '--task', 'generate-speech',
|
||||
'--text', 'Hello world']):
|
||||
cli.main()
|
||||
mock_gen.assert_called_once()
|
||||
|
||||
@patch('minimax_cli.generate_speech')
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_speech_uses_text_or_prompt(self, mock_key, mock_gen):
|
||||
mock_gen.return_value = {"status": "success",
|
||||
"generated_audio": "/x.mp3",
|
||||
"model": "speech-2.8-hd"}
|
||||
# --prompt should work as fallback for --text
|
||||
with patch('sys.argv', ['cli', '--task', 'generate-speech',
|
||||
'--prompt', 'Fallback text']):
|
||||
cli.main()
|
||||
call_args = mock_gen.call_args
|
||||
assert call_args[0][1] == 'Fallback text'
|
||||
|
||||
@patch('minimax_cli.generate_music')
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_generate_music_dispatch(self, mock_key, mock_gen):
|
||||
mock_gen.return_value = {"status": "success",
|
||||
"generated_audio": "/x.mp3",
|
||||
"duration_ms": 60000,
|
||||
"model": "music-2.5"}
|
||||
with patch('sys.argv', ['cli', '--task', 'generate-music',
|
||||
'--lyrics', 'La la la']):
|
||||
cli.main()
|
||||
mock_gen.assert_called_once()
|
||||
|
||||
@patch('minimax_cli.generate_video')
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_generate_video_dispatch(self, mock_key, mock_gen):
|
||||
mock_gen.return_value = {"status": "success",
|
||||
"generated_video": "/x.mp4",
|
||||
"generation_time": 30.0,
|
||||
"model": "MiniMax-Hailuo-2.3"}
|
||||
with patch('sys.argv', ['cli', '--task', 'generate-video',
|
||||
'--prompt', 'A dancer']):
|
||||
cli.main()
|
||||
mock_gen.assert_called_once()
|
||||
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_auto_model_detection(self, mock_key):
|
||||
with patch('sys.argv', ['cli', '--task', 'generate-speech',
|
||||
'--text', 'hi']):
|
||||
with patch('minimax_cli.generate_speech') as mock_gen:
|
||||
mock_gen.return_value = {"status": "success",
|
||||
"generated_audio": "/x.mp3",
|
||||
"model": "speech-2.8-hd"}
|
||||
cli.main()
|
||||
# Model should be auto-detected
|
||||
assert mock_gen.call_args[0][2] == 'speech-2.8-hd'
|
||||
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_explicit_model_override(self, mock_key):
|
||||
with patch('sys.argv', ['cli', '--task', 'generate-speech',
|
||||
'--text', 'hi', '--model', 'speech-2.8-turbo']):
|
||||
with patch('minimax_cli.generate_speech') as mock_gen:
|
||||
mock_gen.return_value = {"status": "success",
|
||||
"generated_audio": "/x.mp3",
|
||||
"model": "speech-2.8-turbo"}
|
||||
cli.main()
|
||||
assert mock_gen.call_args[0][2] == 'speech-2.8-turbo'
|
||||
|
||||
@patch('minimax_cli.generate_image')
|
||||
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
|
||||
def test_exception_exits_with_1(self, mock_key, mock_gen):
|
||||
mock_gen.side_effect = Exception("API timeout")
|
||||
with patch('sys.argv', ['cli', '--task', 'generate',
|
||||
'--prompt', 'test']):
|
||||
with pytest.raises(SystemExit) as exc_info:
|
||||
cli.main()
|
||||
assert exc_info.value.code == 1
|
||||
Reference in New Issue
Block a user