Working on Formating DSL completion
This commit is contained in:
261
tests/core/dsl/test_utils.py
Normal file
261
tests/core/dsl/test_utils.py
Normal file
@@ -0,0 +1,261 @@
|
||||
"""
|
||||
Tests for DSL autocompletion utilities.
|
||||
|
||||
Tests for line extraction, word boundaries, comment/string detection,
|
||||
and indentation functions.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from myfasthtml.core.dsl.types import Position, WordRange
|
||||
from myfasthtml.core.dsl.utils import (
|
||||
get_line_at,
|
||||
get_line_up_to_cursor,
|
||||
get_lines_up_to,
|
||||
find_word_boundaries,
|
||||
get_prefix,
|
||||
is_in_comment,
|
||||
is_in_string,
|
||||
get_indentation,
|
||||
is_indented,
|
||||
strip_quotes,
|
||||
)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Line Extraction Tests
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def test_i_can_get_line_at_valid_index():
|
||||
"""Test that get_line_at returns the correct line."""
|
||||
text = "line0\nline1\nline2"
|
||||
assert get_line_at(text, 0) == "line0"
|
||||
assert get_line_at(text, 1) == "line1"
|
||||
assert get_line_at(text, 2) == "line2"
|
||||
|
||||
|
||||
def test_i_can_get_line_at_invalid_index():
|
||||
"""Test that get_line_at returns empty string for invalid index."""
|
||||
text = "line0\nline1"
|
||||
assert get_line_at(text, -1) == ""
|
||||
assert get_line_at(text, 5) == ""
|
||||
|
||||
|
||||
def test_i_can_get_line_up_to_cursor():
|
||||
"""Test that get_line_up_to_cursor truncates at cursor position."""
|
||||
text = "hello world\nfoo bar"
|
||||
cursor = Position(line=0, ch=5)
|
||||
assert get_line_up_to_cursor(text, cursor) == "hello"
|
||||
|
||||
cursor = Position(line=1, ch=3)
|
||||
assert get_line_up_to_cursor(text, cursor) == "foo"
|
||||
|
||||
|
||||
def test_i_can_get_lines_up_to():
|
||||
"""Test that get_lines_up_to returns lines 0..N."""
|
||||
text = "line0\nline1\nline2\nline3"
|
||||
assert get_lines_up_to(text, 0) == ["line0"]
|
||||
assert get_lines_up_to(text, 2) == ["line0", "line1", "line2"]
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Word Boundaries Tests
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def test_i_can_find_word_boundaries_in_middle():
|
||||
"""Test word boundaries when cursor is in middle of word."""
|
||||
line = "hello world"
|
||||
result = find_word_boundaries(line, 3) # hel|lo
|
||||
assert result.start == 0
|
||||
assert result.end == 5
|
||||
assert result.text == "hello"
|
||||
|
||||
|
||||
def test_i_can_find_word_boundaries_at_start():
|
||||
"""Test word boundaries when cursor is at start of word."""
|
||||
line = "hello world"
|
||||
result = find_word_boundaries(line, 0) # |hello
|
||||
assert result.start == 0
|
||||
assert result.end == 5
|
||||
assert result.text == "hello"
|
||||
|
||||
|
||||
def test_i_can_find_word_boundaries_at_end():
|
||||
"""Test word boundaries when cursor is at end of word."""
|
||||
line = "hello world"
|
||||
result = find_word_boundaries(line, 5) # hello|
|
||||
assert result.start == 0
|
||||
assert result.end == 5
|
||||
assert result.text == "hello"
|
||||
|
||||
|
||||
def test_i_can_find_word_boundaries_with_delimiters():
|
||||
"""Test word boundaries with delimiter characters like parentheses and quotes."""
|
||||
line = 'style("error")'
|
||||
result = find_word_boundaries(line, 10) # style("err|or")
|
||||
assert result.start == 7
|
||||
assert result.end == 12
|
||||
assert result.text == "error"
|
||||
|
||||
|
||||
def test_i_can_find_word_boundaries_empty_line():
|
||||
"""Test word boundaries on empty line."""
|
||||
line = ""
|
||||
result = find_word_boundaries(line, 0)
|
||||
assert result.start == 0
|
||||
assert result.end == 0
|
||||
assert result.text == ""
|
||||
|
||||
|
||||
def test_i_can_get_prefix():
|
||||
"""Test that get_prefix returns text from word start to cursor."""
|
||||
line = "style"
|
||||
prefix = get_prefix(line, 3) # sty|le
|
||||
assert prefix == "sty"
|
||||
|
||||
|
||||
def test_i_can_get_prefix_at_word_start():
|
||||
"""Test that get_prefix returns empty at word start."""
|
||||
line = "style"
|
||||
prefix = get_prefix(line, 0) # |style
|
||||
assert prefix == ""
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Comment Detection Tests
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def test_i_can_detect_comment():
|
||||
"""Test that cursor after # is detected as in comment."""
|
||||
line = "text # comment"
|
||||
assert is_in_comment(line, 12) is True # In "comment"
|
||||
assert is_in_comment(line, 7) is True # Right after #
|
||||
|
||||
|
||||
def test_i_cannot_detect_comment_before_hash():
|
||||
"""Test that cursor before # is not detected as in comment."""
|
||||
line = "text # comment"
|
||||
assert is_in_comment(line, 4) is False # Before #
|
||||
assert is_in_comment(line, 0) is False # At start
|
||||
|
||||
|
||||
def test_i_cannot_detect_comment_hash_in_string():
|
||||
"""Test that # inside a string is not detected as comment start."""
|
||||
line = '"#hash" text'
|
||||
assert is_in_comment(line, 9) is False # After the string
|
||||
|
||||
|
||||
def test_i_can_detect_comment_hash_after_string():
|
||||
"""Test that # after a string is detected as comment."""
|
||||
line = '"text" # comment'
|
||||
assert is_in_comment(line, 10) is True
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# String Detection Tests
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def test_i_can_detect_string_double_quote():
|
||||
"""Test detection of cursor inside double-quoted string."""
|
||||
line = 'style("error")'
|
||||
in_string, quote_char = is_in_string(line, 10) # Inside "error"
|
||||
assert in_string is True
|
||||
assert quote_char == '"'
|
||||
|
||||
|
||||
def test_i_can_detect_string_single_quote():
|
||||
"""Test detection of cursor inside single-quoted string."""
|
||||
line = "style('error')"
|
||||
in_string, quote_char = is_in_string(line, 10) # Inside 'error'
|
||||
assert in_string is True
|
||||
assert quote_char == "'"
|
||||
|
||||
|
||||
def test_i_cannot_detect_string_outside_quotes():
|
||||
"""Test that cursor outside quotes is not detected as in string."""
|
||||
line = 'style("error")'
|
||||
in_string, quote_char = is_in_string(line, 3) # In "style"
|
||||
assert in_string is False
|
||||
assert quote_char is None
|
||||
|
||||
|
||||
def test_i_cannot_detect_string_after_closing_quote():
|
||||
"""Test that cursor after closing quote is not in string."""
|
||||
line = '"text" other'
|
||||
in_string, quote_char = is_in_string(line, 8)
|
||||
assert in_string is False
|
||||
assert quote_char is None
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Indentation Tests
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def test_i_can_get_indentation_spaces():
|
||||
"""Test that spaces are counted correctly."""
|
||||
line = " text"
|
||||
assert get_indentation(line) == 4
|
||||
|
||||
|
||||
def test_i_can_get_indentation_tabs():
|
||||
"""Test that tabs are converted to 4 spaces."""
|
||||
line = "\ttext"
|
||||
assert get_indentation(line) == 4
|
||||
|
||||
|
||||
def test_i_can_get_indentation_mixed():
|
||||
"""Test mixed spaces and tabs."""
|
||||
line = " \t text" # 2 spaces + tab (4) + 2 spaces = 8
|
||||
assert get_indentation(line) == 8
|
||||
|
||||
|
||||
def test_i_can_detect_indented_line():
|
||||
"""Test that indented line is detected."""
|
||||
assert is_indented(" text") is True
|
||||
assert is_indented("\ttext") is True
|
||||
|
||||
|
||||
def test_i_cannot_detect_indented_for_non_indented():
|
||||
"""Test that non-indented line is not detected as indented."""
|
||||
assert is_indented("text") is False
|
||||
|
||||
|
||||
def test_i_cannot_detect_indented_for_empty_line():
|
||||
"""Test that empty line is not detected as indented."""
|
||||
assert is_indented("") is False
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Quote Stripping Tests
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def test_i_can_strip_quotes_double():
|
||||
"""Test stripping double quotes."""
|
||||
assert strip_quotes('"text"') == "text"
|
||||
|
||||
|
||||
def test_i_can_strip_quotes_single():
|
||||
"""Test stripping single quotes."""
|
||||
assert strip_quotes("'text'") == "text"
|
||||
|
||||
|
||||
def test_i_cannot_strip_quotes_unquoted():
|
||||
"""Test that unquoted text is returned unchanged."""
|
||||
assert strip_quotes("text") == "text"
|
||||
|
||||
|
||||
def test_i_cannot_strip_quotes_mismatched():
|
||||
"""Test that mismatched quotes are not stripped."""
|
||||
assert strip_quotes('"text\'') == '"text\''
|
||||
assert strip_quotes("'text\"") == "'text\""
|
||||
|
||||
|
||||
def test_i_cannot_strip_quotes_too_short():
|
||||
"""Test that text shorter than 2 chars is returned unchanged."""
|
||||
assert strip_quotes('"') == '"'
|
||||
assert strip_quotes("") == ""
|
||||
Reference in New Issue
Block a user