mirror of https://github.com/razor-ai/soup.git
77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
"""Tests for soup chat command."""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from typer.testing import CliRunner
|
|
|
|
from soup_cli.cli import app
|
|
from soup_cli.commands.chat import _detect_base_model
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
def test_chat_missing_model_path():
|
|
"""Chat with nonexistent path should fail."""
|
|
result = runner.invoke(app, ["chat", "--model", "/nonexistent/path"])
|
|
assert result.exit_code == 1
|
|
|
|
|
|
def test_detect_base_model_valid(tmp_path: Path):
|
|
"""Should read base_model_name_or_path from adapter_config.json."""
|
|
config_path = tmp_path / "adapter_config.json"
|
|
config_path.write_text(json.dumps({
|
|
"base_model_name_or_path": "meta-llama/Llama-3.1-8B-Instruct",
|
|
"r": 64,
|
|
"lora_alpha": 16,
|
|
}))
|
|
result = _detect_base_model(config_path)
|
|
assert result == "meta-llama/Llama-3.1-8B-Instruct"
|
|
|
|
|
|
def test_detect_base_model_missing_key(tmp_path: Path):
|
|
"""Should return None if base_model_name_or_path is missing."""
|
|
config_path = tmp_path / "adapter_config.json"
|
|
config_path.write_text(json.dumps({"r": 64}))
|
|
result = _detect_base_model(config_path)
|
|
assert result is None
|
|
|
|
|
|
def test_detect_base_model_invalid_json(tmp_path: Path):
|
|
"""Should return None for malformed JSON."""
|
|
config_path = tmp_path / "adapter_config.json"
|
|
config_path.write_text("not valid json {{{")
|
|
result = _detect_base_model(config_path)
|
|
assert result is None
|
|
|
|
|
|
def test_detect_base_model_missing_file(tmp_path: Path):
|
|
"""Should return None for nonexistent file."""
|
|
config_path = tmp_path / "nonexistent.json"
|
|
result = _detect_base_model(config_path)
|
|
assert result is None
|
|
|
|
|
|
def test_chat_adapter_without_base_model(tmp_path: Path):
|
|
"""Chat with adapter that has no base model info should fail."""
|
|
# Create fake adapter directory with adapter_config.json but no base model
|
|
adapter_dir = tmp_path / "adapter"
|
|
adapter_dir.mkdir()
|
|
config = adapter_dir / "adapter_config.json"
|
|
config.write_text(json.dumps({"r": 64}))
|
|
|
|
result = runner.invoke(app, ["chat", "--model", str(adapter_dir)])
|
|
assert result.exit_code == 1
|
|
assert "Cannot detect base model" in result.output
|
|
|
|
|
|
def test_chat_non_adapter_directory(tmp_path: Path):
|
|
"""Chat with directory that has no adapter_config.json skips base model detection."""
|
|
model_dir = tmp_path / "model"
|
|
model_dir.mkdir()
|
|
# No adapter_config.json → not an adapter, will try to load directly
|
|
# This will fail because there's no actual model, but it should get past validation
|
|
result = runner.invoke(app, ["chat", "--model", str(model_dir)])
|
|
# Should fail during model loading, not during validation
|
|
assert result.exit_code == 1
|