Coverage for tests / unit / ai / test_availability.py: 100%
37 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Tests for AI availability checks."""
3from __future__ import annotations
5import builtins
6from unittest.mock import patch
8import click
9import pytest
10from assertpy import assert_that
12from lintro.ai.availability import (
13 is_ai_available,
14 is_provider_available,
15 require_ai,
16 reset_availability_cache,
17)
19_real_import = builtins.__import__
22def test_availability_available_when_anthropic_installed():
23 """Verify AI is available when the anthropic module is installed."""
24 with patch.dict("sys.modules", {"anthropic": object()}):
25 reset_availability_cache()
26 result = is_ai_available()
27 assert_that(result).is_true()
30def test_availability_caching():
31 """Subsequent calls use the cached result without re-importing."""
32 import_calls: list[str] = []
34 def _tracking_import(name, *args, **kwargs):
35 if name in ("anthropic", "openai"):
36 import_calls.append(name)
37 return _real_import(name, *args, **kwargs)
39 reset_availability_cache()
40 with (
41 patch.dict("sys.modules", {"anthropic": object()}),
42 patch("builtins.__import__", side_effect=_tracking_import),
43 ):
44 result1 = is_ai_available()
46 import_calls.clear()
48 # Second call should return cached True without any import attempt.
49 with patch("builtins.__import__", side_effect=_tracking_import):
50 result2 = is_ai_available()
52 assert_that(result1).is_true()
53 assert_that(result2).is_true()
54 assert_that(import_calls).is_empty()
57def test_availability_unknown_provider():
58 """Verify that an unknown provider is reported as unavailable."""
59 result = is_provider_available("unknown")
60 assert_that(result).is_false()
63def test_availability_require_raises_when_unavailable():
64 """Verify require_ai raises UsageError when AI is not available."""
65 with (
66 patch(
67 "lintro.ai.availability.is_ai_available",
68 return_value=False,
69 ),
70 pytest.raises(click.UsageError, match="lintro\\[ai\\]"),
71 ):
72 require_ai()
75def test_availability_require_passes_when_available():
76 """Verify require_ai succeeds without error when AI is available."""
77 with patch(
78 "lintro.ai.availability.is_ai_available",
79 return_value=True,
80 ):
81 require_ai()