# #region Test.SqlTableExtractor.Coverage [C:2] [TYPE Module] [SEMANTICS test, sql, table, extractor, coverage, edge, dead-code] # @BRIEF Edge coverage for sql_table_extractor.py uncovered lines: # Line 157: walk_tokens recursion for TokenList # Line 169: stmt is None continue guard # @RELATION BINDS_TO -> [SqlTableExtractorModule] from unittest.mock import MagicMock, patch import pytest from sqlparse.sql import TokenList class FakeTokenList(TokenList): """Minimal TokenList subclass that avoids sqlparse internal setup.""" def __init__(self): self.ttype = None self._groupable = True self.tokens = [] def flatten(self): return iter(self.tokens) class TestExtractTablesFromSqlSpanCoverage: """Cover dead-code paths in extract_tables_from_sql_span.""" # Line 169: stmt is None → continue # sqlparse.parse never returns None elements in practice, but code guards against it. # Must use SQL with schema.table match to get past the early return (line 146). def test_sqlparse_parse_returns_none_skipped(self): """sqlparse.parse returns [None] → stmt is None skipped (line 169).""" with patch("src.services.sql_table_extractor.sqlparse.parse", return_value=[None]): from src.services.sql_table_extractor import extract_tables_from_sql_span # Must have schema.table match to get past line 146 result = extract_tables_from_sql_span("SELECT * FROM raw.sales") # With no walk_tokens output, regex matches are not filtered by string check assert "raw.sales" in result # Line 157: walk_tokens(token.flatten(), offset) — TokenList recursion # Normally walk_tokens is called with stmt.flatten() which yields only leaf tokens. # This test forces a TokenList into the flattened output to exercise the recursive path. def test_walk_tokens_tokenlist_recursion(self): """TokenList in flattened output → recursive walk_tokens call (line 157).""" # Use a concrete TokenList subclass fake_tl = FakeTokenList() # Create a mock statement whose flatten() yields the TokenList stmt_mock = MagicMock() stmt_mock.flatten.return_value = [fake_tl] with patch("src.services.sql_table_extractor.sqlparse.parse", return_value=[stmt_mock]): from src.services.sql_table_extractor import extract_tables_from_sql_span # Must have schema.table match to get past line 146 result = extract_tables_from_sql_span("SELECT * FROM raw.sales") # No string literal ranges → raw.sales should be in result assert "raw.sales" in result # #endregion Test.SqlTableExtractor.Coverage