Return to plain LaTeX typing mode
This commit is contained in:
@@ -17,13 +17,13 @@ def test_load_default_config(tmp_path):
|
||||
assert "Réponds directement" in cfg.system_prompt
|
||||
|
||||
|
||||
def test_accept_word_equation_format(tmp_path):
|
||||
def test_accept_unicode_format(tmp_path):
|
||||
path = tmp_path / "config.json"
|
||||
path.write_text(json.dumps({"provider": "ollama", "math_text_format": "word_equation"}), encoding="utf-8")
|
||||
path.write_text(json.dumps({"provider": "ollama", "math_text_format": "unicode"}), encoding="utf-8")
|
||||
|
||||
cfg = load_config(path)
|
||||
|
||||
assert cfg.math_text_format == "word_equation"
|
||||
assert cfg.math_text_format == "unicode"
|
||||
|
||||
|
||||
def test_timeout_zero_disables_timeout(tmp_path):
|
||||
|
||||
@@ -3,7 +3,7 @@ from types import SimpleNamespace
|
||||
from ai_typewriter.key_stepper import KeyStepper
|
||||
|
||||
|
||||
def test_start_types_first_character_immediately_then_hooks_remaining(monkeypatch):
|
||||
def test_start_installs_hook_without_typing_immediately(monkeypatch):
|
||||
typed = []
|
||||
hooked = []
|
||||
|
||||
@@ -13,37 +13,57 @@ def test_start_types_first_character_immediately_then_hooks_remaining(monkeypatc
|
||||
stepper = KeyStepper("abc")
|
||||
stepper.start()
|
||||
|
||||
assert typed == ["a"]
|
||||
assert typed == []
|
||||
assert hooked and hooked[0][1] is True
|
||||
assert stepper.remaining_characters == 2
|
||||
assert stepper.remaining_characters == 3
|
||||
|
||||
|
||||
def test_single_character_response_does_not_install_hook(monkeypatch):
|
||||
def test_single_character_response_waits_for_key_then_unhooks(monkeypatch):
|
||||
typed = []
|
||||
hooks = []
|
||||
hook = {}
|
||||
unhooked = []
|
||||
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.write", lambda char, delay=0, exact=True: typed.append(char))
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.hook", lambda callback, suppress=True: hooks.append(callback))
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.hook", lambda callback, suppress=True: hook.update({"callback": callback}) or "hook")
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.unhook", lambda value: unhooked.append(value))
|
||||
|
||||
stepper = KeyStepper("x")
|
||||
stepper.start()
|
||||
hook["callback"](SimpleNamespace(event_type="down"))
|
||||
|
||||
assert typed == ["x"]
|
||||
assert hooks == []
|
||||
assert unhooked == ["hook"]
|
||||
assert stepper.remaining_characters == 0
|
||||
|
||||
|
||||
def test_key_down_types_next_character_after_auto_first(monkeypatch):
|
||||
def test_each_key_down_types_next_character(monkeypatch):
|
||||
typed = []
|
||||
hook = {}
|
||||
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.write", lambda char, delay=0, exact=True: typed.append(char))
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.hook", lambda callback, suppress=True: hook.setdefault("callback", callback) or "hook")
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.hook", lambda callback, suppress=True: hook.update({"callback": callback}) or "hook")
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.unhook", lambda value: None)
|
||||
|
||||
stepper = KeyStepper("ab")
|
||||
stepper.start()
|
||||
hook["callback"](SimpleNamespace(event_type="down"))
|
||||
hook["callback"](SimpleNamespace(event_type="down"))
|
||||
|
||||
assert typed == ["a", "b"]
|
||||
assert stepper.remaining_characters == 0
|
||||
|
||||
|
||||
def test_latex_markers_are_typed_literally_character_by_character(monkeypatch):
|
||||
typed = []
|
||||
hook = {}
|
||||
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.write", lambda char, delay=0, exact=True: typed.append(char))
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.hook", lambda callback, suppress=True: hook.update({"callback": callback}) or "hook")
|
||||
monkeypatch.setattr("ai_typewriter.key_stepper.keyboard.unhook", lambda value: None)
|
||||
|
||||
stepper = KeyStepper(r"[EQ]\frac{a}{b}[/EQ]")
|
||||
stepper.start()
|
||||
for _ in range(len(stepper.text)):
|
||||
hook["callback"](SimpleNamespace(event_type="down"))
|
||||
|
||||
assert "".join(typed) == r"[EQ]\frac{a}{b}[/EQ]"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import pytest
|
||||
|
||||
from ai_typewriter.math_format import format_math_text, split_word_equation_segments
|
||||
from ai_typewriter.math_format import format_math_text
|
||||
|
||||
|
||||
def test_plain_mode_keeps_linear_math_literal():
|
||||
assert format_math_text("z_1 + x^2", "plain") == "z_1 + x^2"
|
||||
def test_plain_mode_keeps_latex_and_markers_literal():
|
||||
assert format_math_text(r"[EQ]\frac{a}{b}[/EQ]", "plain") == r"[EQ]\frac{a}{b}[/EQ]"
|
||||
|
||||
|
||||
def test_unicode_mode_converts_indices_exponents_and_symbols():
|
||||
@@ -13,35 +13,6 @@ def test_unicode_mode_converts_indices_exponents_and_symbols():
|
||||
assert result == "z₁ + x² + xᵢ₊₁ + α + ∞"
|
||||
|
||||
|
||||
def test_marker_mode_only_uses_explicit_equation_blocks():
|
||||
segments = split_word_equation_segments(r"On pose [EQ]z_1 = x + iy[/EQ]. Puis [EQ]\alpha = 2[/EQ].")
|
||||
|
||||
assert [(segment.kind, segment.value) for segment in segments] == [
|
||||
("text", "On pose "),
|
||||
("equation", "z_1 = x + iy"),
|
||||
("text", ". Puis "),
|
||||
("equation", r"\alpha = 2"),
|
||||
("text", "."),
|
||||
]
|
||||
|
||||
|
||||
def test_marker_mode_does_not_guess_math_without_markers():
|
||||
segments = split_word_equation_segments(r"z_1 reste du texte normal sans marqueur.")
|
||||
|
||||
assert [(segment.kind, segment.value) for segment in segments] == [
|
||||
("text", r"z_1 reste du texte normal sans marqueur."),
|
||||
]
|
||||
|
||||
|
||||
def test_unclosed_equation_marker_consumes_the_rest():
|
||||
segments = split_word_equation_segments(r"Résultat: [EQ]x^2 + 1")
|
||||
|
||||
assert [(segment.kind, segment.value) for segment in segments] == [
|
||||
("text", "Résultat: "),
|
||||
("equation", "x^2 + 1"),
|
||||
]
|
||||
|
||||
|
||||
def test_invalid_math_text_format_is_rejected():
|
||||
with pytest.raises(ValueError):
|
||||
format_math_text("x_1", "bad")
|
||||
|
||||
Reference in New Issue
Block a user