Worked on getting tests compiling
This commit is contained in:
parent
690155b9a7
commit
4398b3a4bc
|
|
@ -110,9 +110,10 @@ TestResult pass_test(LexerTest *test, LexerResult result);
|
|||
Boolean test_eof_value(LexerTest *test, LexerResult result, size_t i, void *_);
|
||||
Boolean test_identifier_value(LexerTest *test, LexerResult result, size_t i, TestIdentifierValue *value);
|
||||
Boolean test_integer_value(LexerTest *test, LexerResult result, size_t i, TestIntegerValue *value);
|
||||
Boolean test_character_value(LexerTest *test, LexerResult result, size_t i, uint8_t *value);
|
||||
Boolean test_float_value(LexerTest *test, LexerResult result, size_t i, float *value);
|
||||
Boolean test_double_value(LexerTest *test, LexerResult result, size_t i, double *value);
|
||||
Boolean test_string_value(LexerTest *test, LexerResult result, size_t i, SlsStr value);
|
||||
Boolean test_string_value(LexerTest *test, LexerResult result, size_t i, SlsStr *value);
|
||||
Boolean test_boolean_value(LexerTest *test, LexerResult result, size_t i, Boolean *value);
|
||||
Boolean test_array_identifier_value(LexerTest *test, LexerResult result, size_t i, TestArrayIdentifierValue *values);
|
||||
Boolean test_array_integer_value(LexerTest *test, LexerResult result, size_t i, TestArrayIntegerValue *values);
|
||||
|
|
|
|||
|
|
@ -326,16 +326,16 @@ Boolean test_double_value(LexerTest *test, LexerResult result, size_t i, double
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
Boolean test_string_value(LexerTest *test, LexerResult result, size_t i, SlsStr value) {
|
||||
Boolean test_string_value(LexerTest *test, LexerResult result, size_t i, SlsStr *value) {
|
||||
static const TokenType token_type = TOKEN_STRING;
|
||||
LexerTokenResult *head = get_token(result.result, i);
|
||||
if (test_token_type(test, result, i, token_type)) {
|
||||
return TRUE;
|
||||
} if (head->result.string_literal.len == value.len) {
|
||||
logic_fail_test(test, result, token_length_should_be(i + 1, token_type, value.len, head->result.string_literal.len));
|
||||
} if (head->result.string_literal.len == value->len) {
|
||||
logic_fail_test(test, result, token_length_should_be(i + 1, token_type, value->len, head->result.string_literal.len));
|
||||
return TRUE;
|
||||
} if (sls_str_cmp(head->result.string_literal, value) != 0) {
|
||||
logic_fail_test(test, result, token_value_string_should_be(i + 1, token_type, value, head->result.string_literal));
|
||||
} if (sls_str_cmp(head->result.string_literal, *value) != 0) {
|
||||
logic_fail_test(test, result, token_value_string_should_be(i + 1, token_type, *value, head->result.string_literal));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -52,6 +52,8 @@ class BaseTestGenerator(ABC):
|
|||
test creation, operation building, and error handling.
|
||||
"""
|
||||
|
||||
ENABLE_UNICODE = False
|
||||
|
||||
__generators: "ClassVar[List[Type[BaseTestGenerator]]]" = []
|
||||
|
||||
def __init_subclass__(cls):
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ from .base_tests import BaseTestGenerator
|
|||
class CharTestGenerator(BaseTestGenerator):
|
||||
"""Generate test cases for character literals."""
|
||||
|
||||
ENABLE_UNICODE = False
|
||||
|
||||
# Common escape sequences
|
||||
ESCAPE_SEQUENCES = {
|
||||
("Newline", '\\n', '\n',), # Newline
|
||||
|
|
@ -192,16 +190,16 @@ class CharTestGenerator(BaseTestGenerator):
|
|||
|
||||
# Invalid escape sequence
|
||||
self.make_error_test("Char Invalid Escape",
|
||||
"'\\q'",
|
||||
"Invalid character literal: unknown escape sequence '\\q'.")
|
||||
"'\\\\q'",
|
||||
"Invalid character literal: unknown escape sequence '\\\\q'.")
|
||||
|
||||
# Invalid hex escape (not 2 digits)
|
||||
self.make_error_test("Char Hex Escape Too Short",
|
||||
"'\\x4'",
|
||||
"'\\\\x4'",
|
||||
"Invalid character literal: hexadecimal escape must have exactly 2 digits.")
|
||||
|
||||
self.make_error_test("Char Hex Escape Too Long",
|
||||
"'\\x414'",
|
||||
"'\\\\x414'",
|
||||
"Invalid character literal: hexadecimal escape must have exactly 2 digits.")
|
||||
|
||||
# Invalid hex digits
|
||||
|
|
|
|||
|
|
@ -19,301 +19,301 @@ class StringTestGenerator(BaseTestGenerator):
|
|||
def generate_basic_tests(self):
|
||||
"""Generate basic string literal tests."""
|
||||
# Empty string
|
||||
self.make_success_test("String Empty", '""', "String", "")
|
||||
self.make_success_test("String Empty", '""', "string", "")
|
||||
|
||||
# Simple strings
|
||||
self.make_success_test("String Simple", '"hello"', "String", "hello")
|
||||
self.make_success_test("String With Space", '"hello world"', "String", "hello world")
|
||||
self.make_success_test("String Single Char", '"A"', "String", "A")
|
||||
self.make_success_test("String Simple", '"hello"', "string", "hello")
|
||||
self.make_success_test("String With Space", '"hello world"', "string", "hello world")
|
||||
self.make_success_test("String Single Char", '"A"', "string", "A")
|
||||
|
||||
# Multiple words
|
||||
self.make_success_test("String Multiple Words",
|
||||
'"The quick brown fox"', "String", "The quick brown fox")
|
||||
'"The quick brown fox"', "string", "The quick brown fox")
|
||||
|
||||
# Numbers in strings
|
||||
self.make_success_test("String With Numbers", '"abc123"', "String", "abc123")
|
||||
self.make_success_test("String Only Numbers", '"12345"', "String", "12345")
|
||||
self.make_success_test("String With Numbers", '"abc123"', "string", "abc123")
|
||||
self.make_success_test("String Only Numbers", '"12345"', "string", "12345")
|
||||
|
||||
# Mixed case
|
||||
self.make_success_test("String Mixed Case", '"HeLLo WoRLd"', "String", "HeLLo WoRLd")
|
||||
self.make_success_test("String Mixed Case", '"HeLLo WoRLd"', "string", "HeLLo WoRLd")
|
||||
|
||||
# Special characters
|
||||
self.make_success_test("String With Punctuation",
|
||||
'"Hello, World!"', "String", "Hello, World!")
|
||||
'"Hello, World!"', "string", "Hello, World!")
|
||||
self.make_success_test("String With Symbols",
|
||||
'"@#$%^&*()"', "String", "@#$%^&*()")
|
||||
'"@#$%^&*()"', "string", "@#$%^&*()")
|
||||
|
||||
# Spaces
|
||||
self.make_success_test("String Multiple Spaces",
|
||||
'"hello world"', "String", "hello world")
|
||||
self.make_success_test("String Leading Space", '" hello"', "String", " hello")
|
||||
self.make_success_test("String Trailing Space", '"hello "', "String", "hello ")
|
||||
self.make_success_test("String Only Spaces", '" "', "String", " ")
|
||||
'"hello world"', "string", "hello world")
|
||||
self.make_success_test("String Leading Space", '" hello"', "string", " hello")
|
||||
self.make_success_test("String Trailing Space", '"hello "', "string", "hello ")
|
||||
self.make_success_test("String Only Spaces", '" "', "string", " ")
|
||||
|
||||
def generate_escape_sequence_tests(self):
|
||||
"""Generate tests for escape sequences."""
|
||||
# Individual escape sequences
|
||||
self.make_success_test("String Newline", '"hello\\nworld"',
|
||||
"String", "hello\nworld")
|
||||
"string", "hello\\nworld")
|
||||
self.make_success_test("String Tab", '"hello\\tworld"',
|
||||
"String", "hello\tworld")
|
||||
"string", "hello\\tworld")
|
||||
self.make_success_test("String Carriage Return", '"hello\\rworld"',
|
||||
"String", "hello\rworld")
|
||||
"string", "hello\\rworld")
|
||||
self.make_success_test("String Backslash", '"hello\\\\world"',
|
||||
"String", "hello\\world")
|
||||
self.make_success_test("String Double Quote", '"say \\"hello\\""',
|
||||
"String", 'say "hello"')
|
||||
"string", "hello\\\\world")
|
||||
self.make_success_test("String Double Quote", '"say \\\\"hello\\\\""',
|
||||
"string", 'say \\"hello\\"')
|
||||
self.make_success_test("String Single Quote", '"it\\\'s"',
|
||||
"String", "it's")
|
||||
"string", "it's")
|
||||
self.make_success_test("String Null Char", '"hello\\0world"',
|
||||
"String", "hello\0world")
|
||||
"string", "hello\\0world")
|
||||
|
||||
# Multiple escape sequences
|
||||
self.make_success_test("String Multiple Escapes",
|
||||
'"line1\\nline2\\nline3"',
|
||||
"String", "line1\nline2\nline3")
|
||||
"string", "line1\\nline2\\nline3")
|
||||
self.make_success_test("String Mixed Escapes",
|
||||
'"tab\\there\\nnewline\\\\backslash"',
|
||||
"String", "tab\there\nnewline\\backslash")
|
||||
"string", "tab\\there\\nnewline\\\\backslash")
|
||||
|
||||
# Escape at start/end
|
||||
self.make_success_test("String Escape At Start", '"\\nhello"',
|
||||
"String", "\nhello")
|
||||
"string", "\\nhello")
|
||||
self.make_success_test("String Escape At End", '"hello\\n"',
|
||||
"String", "hello\n")
|
||||
"string", "hello\\n")
|
||||
|
||||
# Consecutive escapes
|
||||
self.make_success_test("String Consecutive Escapes", '"\\n\\n\\n"',
|
||||
"String", "\n\n\n")
|
||||
self.make_success_test("String All Escapes", '"\\n\\r\\t\\\\\\"\\\'\\0"',
|
||||
"String", "\n\r\t\\\"\'\0")
|
||||
"string", "\\n\\n\\n")
|
||||
self.make_success_test("String All Escapes", '"\\n\\r\\t\\\\"\\\'\\0"',
|
||||
"string", "\\n\\r\\t\\\\\\\"\\'\\0")
|
||||
|
||||
def generate_hexadecimal_escape_tests(self):
|
||||
"""Generate tests for hexadecimal escape sequences."""
|
||||
# Basic hex escapes
|
||||
self.make_success_test("String Hex Letter A", '"\\x41"', "String", "A")
|
||||
self.make_success_test("String Hex Letter a", '"\\x61"', "String", "a")
|
||||
self.make_success_test("String Hex Space", '"\\x20"', "String", " ")
|
||||
self.make_success_test("String Hex Tab", '"\\x09"', "String", "\t")
|
||||
self.make_success_test("String Hex Newline", '"\\x0A"', "String", "\n")
|
||||
self.make_success_test("String Hex Letter A", '"\\x41"', "string", "A")
|
||||
self.make_success_test("String Hex Letter a", '"\\x61"', "string", "a")
|
||||
self.make_success_test("String Hex Space", '"\\x20"', "string", " ")
|
||||
self.make_success_test("String Hex Tab", '"\\x09"', "string", "\\t")
|
||||
self.make_success_test("String Hex Newline", '"\\x0A"', "string", "\\n")
|
||||
|
||||
# Multiple hex escapes
|
||||
self.make_success_test("String Multiple Hex", '"\\x48\\x65\\x6C\\x6C\\x6F"',
|
||||
"String", "Hello")
|
||||
"string", "Hello")
|
||||
|
||||
# Hex with regular text
|
||||
self.make_success_test("String Hex Mixed", '"Hello\\x20World"',
|
||||
"String", "Hello World")
|
||||
"string", "Hello World")
|
||||
|
||||
# Extended ASCII
|
||||
self.make_success_test("String Hex Extended ASCII", '"\\xA9\\xAE"',
|
||||
"String", "\xA9\xAE")
|
||||
"string", "\xA9\xAE")
|
||||
|
||||
# Case variations
|
||||
self.make_success_test("String Hex Uppercase", '"\\xFF"', "String", "\xFF")
|
||||
self.make_success_test("String Hex Lowercase", '"\\xff"', "String", "\xff")
|
||||
self.make_success_test("String Hex Mixed Case", '"\\xAb"', "String", "\xAb")
|
||||
self.make_success_test("String Hex Uppercase", '"\\xFF"', "string", "\\xFF")
|
||||
self.make_success_test("String Hex Lowercase", '"\\xff"', "string", "\\xff")
|
||||
self.make_success_test("String Hex Mixed Case", '"\\xAb"', "string", "\\xAb")
|
||||
|
||||
# All hex values
|
||||
self.make_success_test("String Hex Zero", '"\\x00"', "String", "\x00")
|
||||
self.make_success_test("String Hex Max", '"\\xFF"', "String", "\xFF")
|
||||
self.make_success_test("String Hex Zero", '"\\x00"', "string", "\\0")
|
||||
self.make_success_test("String Hex Max", '"\\xFF"', "string", "\\xFF")
|
||||
|
||||
def generate_unicode_escape_tests(self):
|
||||
"""Generate tests for Unicode escape sequences."""
|
||||
# Basic Unicode escapes
|
||||
self.make_success_test("String Unicode Letter A", '"\\u{41}"', "String", "A")
|
||||
self.make_success_test("String Unicode Space", '"\\u{20}"', "String", " ")
|
||||
self.make_success_test("String Unicode Letter A", '"\\u{41}"', "string", "A")
|
||||
self.make_success_test("String Unicode Space", '"\\u{20}"', "string", " ")
|
||||
|
||||
# Emoji
|
||||
self.make_success_test("String Unicode Smiley", '"\\u{1F600}"',
|
||||
"String", "😀")
|
||||
"string", "😀")
|
||||
self.make_success_test("String Unicode Heart", '"\\u{2764}"',
|
||||
"String", "❤")
|
||||
"string", "❤")
|
||||
self.make_success_test("String Unicode Star", '"\\u{2B50}"',
|
||||
"String", "⭐")
|
||||
"string", "⭐")
|
||||
|
||||
# Multiple emoji
|
||||
self.make_success_test("String Multiple Emoji",
|
||||
'"\\u{1F600}\\u{2764}\\u{2B50}"',
|
||||
"String", "😀❤⭐")
|
||||
"string", "😀❤⭐")
|
||||
|
||||
# Greek letters
|
||||
self.make_success_test("String Unicode Greek Alpha", '"\\u{03B1}"',
|
||||
"String", "α")
|
||||
"string", "α")
|
||||
self.make_success_test("String Unicode Greek Beta", '"\\u{03B2}"',
|
||||
"String", "β")
|
||||
"string", "β")
|
||||
|
||||
# Chinese characters
|
||||
self.make_success_test("String Unicode Chinese", '"\\u{4E2D}\\u{6587}"',
|
||||
"String", "中文")
|
||||
"string", "中文")
|
||||
|
||||
# Arabic
|
||||
self.make_success_test("String Unicode Arabic", '"\\u{0639}\\u{0631}\\u{0628}"',
|
||||
"String", "عرب")
|
||||
"string", "عرب")
|
||||
|
||||
# Cyrillic
|
||||
self.make_success_test("String Unicode Cyrillic", '"\\u{0420}\\u{0443}\\u{0441}"',
|
||||
"String", "Рус")
|
||||
"string", "Рус")
|
||||
|
||||
# Mathematical symbols
|
||||
self.make_success_test("String Unicode Math", '"\\u{221E}\\u{2211}\\u{222B}"',
|
||||
"String", "∞∑∫")
|
||||
"string", "∞∑∫")
|
||||
|
||||
# Mixed with regular text
|
||||
self.make_success_test("String Unicode Mixed", '"Hello \\u{1F600} World"',
|
||||
"String", "Hello 😀 World")
|
||||
"string", "Hello 😀 World")
|
||||
|
||||
# Case variations in hex digits
|
||||
self.make_success_test("String Unicode Hex Uppercase", '"\\u{1F600}"',
|
||||
"String", "😀")
|
||||
"string", "😀")
|
||||
self.make_success_test("String Unicode Hex Lowercase", '"\\u{1f600}"',
|
||||
"String", "😀")
|
||||
"string", "😀")
|
||||
self.make_success_test("String Unicode Hex Mixed", '"\\u{1F60a}"',
|
||||
"String", "😊")
|
||||
"string", "😊")
|
||||
|
||||
# Variable length code points
|
||||
self.make_success_test("String Unicode 2 Digits", '"\\u{41}"', "String", "A")
|
||||
self.make_success_test("String Unicode 4 Digits", '"\\u{03B1}"', "String", "α")
|
||||
self.make_success_test("String Unicode 5 Digits", '"\\u{1F600}"', "String", "😀")
|
||||
self.make_success_test("String Unicode 2 Digits", '"\\u{41}"', "string", "A")
|
||||
self.make_success_test("String Unicode 4 Digits", '"\\u{03B1}"', "string", "α")
|
||||
self.make_success_test("String Unicode 5 Digits", '"\\u{1F600}"', "string", "😀")
|
||||
self.make_success_test("String Unicode 6 Digits", '"\\u{10FFFF}"',
|
||||
"String", "\U0010FFFF")
|
||||
"string", "\U0010FFFF")
|
||||
|
||||
def generate_direct_unicode_tests(self):
|
||||
"""Generate tests for direct Unicode characters in strings."""
|
||||
# Direct emoji
|
||||
self.make_success_test("String Direct Emoji", '"Hello 😀 World"',
|
||||
"String", "Hello 😀 World")
|
||||
"string", "Hello 😀 World")
|
||||
self.make_success_test("String Multiple Direct Emoji", '"😀❤⭐👍"',
|
||||
"String", "😀❤⭐👍")
|
||||
"string", "😀❤⭐👍")
|
||||
|
||||
# Direct Greek
|
||||
self.make_success_test("String Direct Greek", '"αβγδ"', "String", "αβγδ")
|
||||
self.make_success_test("String Direct Greek", '"αβγδ"', "string", "αβγδ")
|
||||
|
||||
# Direct Chinese
|
||||
self.make_success_test("String Direct Chinese", '"你好世界"',
|
||||
"String", "你好世界")
|
||||
"string", "你好世界")
|
||||
|
||||
# Direct Arabic
|
||||
self.make_success_test("String Direct Arabic", '"مرحبا"', "String", "مرحبا")
|
||||
self.make_success_test("String Direct Arabic", '"مرحبا"', "string", "مرحبا")
|
||||
|
||||
# Direct Cyrillic
|
||||
self.make_success_test("String Direct Cyrillic", '"Привет"',
|
||||
"String", "Привет")
|
||||
"string", "Привет")
|
||||
|
||||
# Direct mathematical
|
||||
self.make_success_test("String Direct Math", '"∞∑∫√π"', "String", "∞∑∫√π")
|
||||
self.make_success_test("String Direct Math", '"∞∑∫√π"', "string", "∞∑∫√π")
|
||||
|
||||
# Mixed scripts
|
||||
self.make_success_test("String Mixed Scripts", '"Hello 世界 Привет"',
|
||||
"String", "Hello 世界 Привет")
|
||||
"string", "Hello 世界 Привет")
|
||||
|
||||
def generate_multiline_tests(self):
|
||||
"""Generate tests for strings with embedded newlines."""
|
||||
# Strings with escape newlines
|
||||
self.make_success_test("String With Escaped Newlines",
|
||||
'"line1\\nline2\\nline3"',
|
||||
"String", "line1\nline2\nline3")
|
||||
"string", "line1\\nline2\\nline3")
|
||||
|
||||
# Paragraph-like text
|
||||
self.make_success_test("String Paragraph",
|
||||
'"First line.\\nSecond line.\\nThird line."',
|
||||
"String", "First line.\nSecond line.\nThird line.")
|
||||
"string", "First line.\\nSecond line.\\nThird line.")
|
||||
|
||||
# Mixed line endings
|
||||
self.make_success_test("String Mixed Line Endings",
|
||||
'"Windows\\r\\nUnix\\nMac\\r"',
|
||||
"String", "Windows\r\nUnix\nMac\r")
|
||||
"string", "Windows\\r\\nUnix\\nMac\\r")
|
||||
|
||||
def generate_whitespace_tests(self):
|
||||
"""Generate tests with various whitespace."""
|
||||
# Leading/trailing whitespace outside quotes
|
||||
self.make_success_test("String Leading Whitespace Outside",
|
||||
' "hello"', "String", "hello")
|
||||
' "hello"', "string", "hello")
|
||||
self.make_success_test("String Trailing Whitespace Outside",
|
||||
'"hello" ', "String", "hello")
|
||||
'"hello" ', "string", "hello")
|
||||
self.make_success_test("String Both Whitespace Outside",
|
||||
' "hello" ', "String", "hello")
|
||||
' "hello" ', "string", "hello")
|
||||
|
||||
# Tabs outside quotes
|
||||
self.make_success_test("String Tab Before", '\t"hello"', "String", "hello")
|
||||
self.make_success_test("String Tab Before", '\t"hello"', "string", "hello")
|
||||
|
||||
# Mixed whitespace
|
||||
self.make_success_test("String Tabs And Newlines Inside",
|
||||
'"hello\\t\\tworld\\n\\ntest"',
|
||||
"String", "hello\t\tworld\n\ntest")
|
||||
"string", "hello\\t\\tworld\\n\\ntest")
|
||||
|
||||
# Only whitespace inside
|
||||
self.make_success_test("String Only Tabs", '"\\t\\t\\t"', "String", "\t\t\t")
|
||||
self.make_success_test("String Only Newlines", '"\\n\\n\\n"', "String", "\n\n\n")
|
||||
self.make_success_test("String Only Tabs", '"\\t\\t\\t"', "string", "\\t\\t\\t")
|
||||
self.make_success_test("String Only Newlines", '"\\n\\n\\n"', "string", "\\n\\n\\n")
|
||||
self.make_success_test("String Mixed Whitespace", '" \\t\\n\\r "',
|
||||
"String", " \t\n\r ")
|
||||
"string", " \\t\\n\\r ")
|
||||
|
||||
def generate_long_string_tests(self):
|
||||
"""Generate tests for longer strings."""
|
||||
# Sentence
|
||||
self.make_success_test("String Sentence",
|
||||
'"The quick brown fox jumps over the lazy dog."',
|
||||
"String", "The quick brown fox jumps over the lazy dog.")
|
||||
"string", "The quick brown fox jumps over the lazy dog.")
|
||||
|
||||
# Multiple sentences
|
||||
self.make_success_test("String Multiple Sentences",
|
||||
'"First sentence. Second sentence. Third sentence."',
|
||||
"String", "First sentence. Second sentence. Third sentence.")
|
||||
"string", "First sentence. Second sentence. Third sentence.")
|
||||
|
||||
# Long string with escapes
|
||||
long_str = "This is a long string.\\nIt has multiple lines.\\nAnd some tabs\\there.\\nPlus quotes \\\"like this\\\"."
|
||||
expected = "This is a long string.\nIt has multiple lines.\nAnd some tabs\there.\nPlus quotes \"like this\"."
|
||||
self.make_success_test("String Long With Escapes", f'"{long_str}"',
|
||||
"String", expected)
|
||||
long_str = '"This is a long string.\\nIt has multiple lines.\\nAnd some tabs\\there.\\nPlus quotes "like this"."'
|
||||
expected = "This is a long string.\\nIt has multiple lines.\\nAnd some tabs\\there.\\nPlus quotes \\\"like this\\\"."
|
||||
self.make_success_test("String Long With Escapes", long_str,
|
||||
"string", expected)
|
||||
|
||||
# Repetitive string
|
||||
self.make_success_test("String Repetitive", '"aaaaaaaaaa"',
|
||||
"String", "aaaaaaaaaa")
|
||||
"string", "aaaaaaaaaa")
|
||||
|
||||
# All ASCII printable characters
|
||||
printable = "".join(chr(i) for i in range(32, 127) if chr(i) not in ['"', '\\'])
|
||||
self.make_success_test("String ASCII Printable",
|
||||
f'"{printable}"', "String", printable)
|
||||
f'"{printable}"', "string", printable)
|
||||
|
||||
def generate_special_content_tests(self):
|
||||
"""Generate tests for strings with special content."""
|
||||
# Code-like strings
|
||||
self.make_success_test("String Code Like",
|
||||
'"int main() { return 0; }"',
|
||||
"String", "int main() { return 0; }")
|
||||
"string", "int main() { return 0; }")
|
||||
|
||||
# JSON-like strings
|
||||
self.make_success_test("String JSON Like",
|
||||
'"{{\\"key\\": \\"value\\"}}"',
|
||||
"String", '{"key": "value"}')
|
||||
'"{{\\\\"key\\\\": \\\\"value\\\\"}}"',
|
||||
"string", '{\\"key\\": \\"value\\"}')
|
||||
|
||||
# URL
|
||||
self.make_success_test("String URL",
|
||||
'"https://example.com/path?query=value"',
|
||||
"String", "https://example.com/path?query=value")
|
||||
"string", "https://example.com/path?query=value")
|
||||
|
||||
# Email
|
||||
self.make_success_test("String Email",
|
||||
'"user@example.com"', "String", "user@example.com")
|
||||
'"user@example.com"', "string", "user@example.com")
|
||||
|
||||
# File path (Unix)
|
||||
self.make_success_test("String Unix Path",
|
||||
'"/home/user/file.txt"',
|
||||
"String", "/home/user/file.txt")
|
||||
"string", "/home/user/file.txt")
|
||||
|
||||
# File path (Windows)
|
||||
self.make_success_test("String Windows Path",
|
||||
'"C:\\\\Users\\\\file.txt"',
|
||||
"String", "C:\\Users\\file.txt")
|
||||
"string", "C:\\\\Users\\\\file.txt")
|
||||
|
||||
# SQL-like
|
||||
self.make_success_test("String SQL Like",
|
||||
'"SELECT * FROM users WHERE id = 1"',
|
||||
"String", "SELECT * FROM users WHERE id = 1")
|
||||
"string", "SELECT * FROM users WHERE id = 1")
|
||||
|
||||
# Regular expression
|
||||
self.make_success_test("String Regex Like",
|
||||
'"[a-zA-Z0-9]+"', "String", "[a-zA-Z0-9]+")
|
||||
'"[a-zA-Z0-9]+"', "string", "[a-zA-Z0-9]+")
|
||||
|
||||
def generate_error_tests(self):
|
||||
"""Generate error test cases."""
|
||||
|
|
@ -324,13 +324,13 @@ class StringTestGenerator(BaseTestGenerator):
|
|||
|
||||
# Unescaped newline
|
||||
self.make_error_test("String Unescaped Newline",
|
||||
'"hello\nworld"',
|
||||
'"hello\\nworld"',
|
||||
"Invalid string literal: unescaped newline in string literal.")
|
||||
|
||||
# Invalid escape sequence
|
||||
self.make_error_test("String Invalid Escape",
|
||||
'"hello\\qworld"',
|
||||
"Invalid string literal: unknown escape sequence '\\q'.")
|
||||
'"hello\\\\qworld"',
|
||||
"Invalid string literal: unknown escape sequence '\\\\q'.")
|
||||
|
||||
# Hex escape too short
|
||||
self.make_error_test("String Hex Too Short",
|
||||
|
|
@ -339,14 +339,15 @@ class StringTestGenerator(BaseTestGenerator):
|
|||
|
||||
# Hex escape too long
|
||||
self.make_error_test("String Hex Too Long",
|
||||
'"\\x414"',
|
||||
'"\\\\x414"',
|
||||
"Invalid string literal: hexadecimal escape must have exactly 2 digits.")
|
||||
|
||||
# Invalid hex digits
|
||||
self.make_error_test("String Hex Invalid Digit",
|
||||
'"\\xGG"',
|
||||
'"\\\\xGG"',
|
||||
"Invalid string literal: invalid hexadecimal digit 'G'.")
|
||||
|
||||
if self.ENABLE_UNICODE:
|
||||
# Unicode no braces
|
||||
self.make_error_test("String Unicode No Braces",
|
||||
'"\\u1F600"',
|
||||
|
|
@ -389,48 +390,49 @@ class StringTestGenerator(BaseTestGenerator):
|
|||
|
||||
# Backslash at end
|
||||
self.make_error_test("String Backslash At End",
|
||||
'"hello\\"',
|
||||
'"hello\\\\"',
|
||||
"Invalid string literal: incomplete escape sequence at end.")
|
||||
|
||||
def generate_edge_case_tests(self):
|
||||
"""Generate edge case tests."""
|
||||
# String with only escape sequences
|
||||
self.make_success_test("String Only Escapes",
|
||||
'"\\n\\t\\r"', "String", "\n\t\r")
|
||||
'"\\n\\t\\r"', "string", "\\n\\t\\r")
|
||||
|
||||
# String with null characters
|
||||
self.make_success_test("String With Nulls",
|
||||
'"a\\0b\\0c"', "String", "a\0b\0c")
|
||||
'"a\\0b\\0c"', "string", "a\\0b\\0c")
|
||||
|
||||
# Very long escape sequence
|
||||
self.make_success_test("String Many Escapes",
|
||||
'"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"',
|
||||
"String", "\n\n\n\n\n\n\n\n\n\n")
|
||||
"string", "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n")
|
||||
|
||||
if self.ENABLE_UNICODE:
|
||||
# Mixed escape types
|
||||
self.make_success_test("String All Escape Types",
|
||||
'"\\n\\x41\\u{42}test"',
|
||||
"String", "\nABtest")
|
||||
"string", "\nABtest")
|
||||
|
||||
# Zero-width characters
|
||||
self.make_success_test("String Zero Width",
|
||||
'"hello\\u{200B}world"',
|
||||
"String", "hello\u200Bworld")
|
||||
"string", "hello\u200Bworld")
|
||||
|
||||
# Combining characters
|
||||
self.make_success_test("String Combining",
|
||||
'"e\\u{0301}"', # é as e + combining acute
|
||||
"String", "e\u0301")
|
||||
"string", "e\u0301")
|
||||
|
||||
# Right-to-left
|
||||
self.make_success_test("String RTL Mark",
|
||||
'"\\u{200F}hello"',
|
||||
"String", "\u200Fhello")
|
||||
"string", "\u200Fhello")
|
||||
|
||||
# Byte order mark
|
||||
self.make_success_test("String BOM",
|
||||
'"\\u{FEFF}hello"',
|
||||
"String", "\uFEFFhello")
|
||||
"string", "\uFEFFhello")
|
||||
|
||||
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
||||
"""Generate all string literal test cases."""
|
||||
|
|
@ -443,6 +445,7 @@ class StringTestGenerator(BaseTestGenerator):
|
|||
# Hexadecimal escapes
|
||||
self.generate_hexadecimal_escape_tests()
|
||||
|
||||
if self.ENABLE_UNICODE:
|
||||
# Unicode escapes
|
||||
self.generate_unicode_escape_tests()
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ def _token_to_c_call(token: dict, idx_var="i") -> str:
|
|||
return f'test_float_value(&test, result, {idx_var}++, &(float){{{value}}})'
|
||||
elif ttype == "char":
|
||||
return f'test_character_value(&test, result, {idx_var}++, &(uint8_t){{{ord(value)}}})' # type: ignore
|
||||
elif ttype == "string":
|
||||
return f'test_string_value(&test, result, {idx_var}++, &SLS_STR("{value}"))' # type: ignore
|
||||
elif ttype == "identifier":
|
||||
return f'test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{FALSE, {len(value)}, "{value}"}})' # type: ignore
|
||||
elif ttype == "identifier_literal":
|
||||
|
|
@ -89,12 +91,13 @@ def token_to_c_call(token: dict, idx_var="i") -> str:
|
|||
|
||||
def generate_c_test(test: dict) -> str:
|
||||
"""Convert a single YAML test entry to a C test function."""
|
||||
name = sanitize_name(test["name"])
|
||||
name = test["name"]
|
||||
c_name = sanitize_name(name)
|
||||
code = c_string_literal(test["code"])
|
||||
tokens = test.get("tokens", [])
|
||||
|
||||
# Function header
|
||||
c_code = [f"static TestResult {name}() {{",
|
||||
c_code = [f"static TestResult {c_name}() {{",
|
||||
f' LexerTest test = start_up_test(SLS_STR("{name}"), SLS_STR("{code}"));',
|
||||
" LexerResult result = lexical_analysis(&test.lexer_info);",
|
||||
" if (result.type == SLS_ERROR) return error_fail_test(&test, result, result.error);",
|
||||
|
|
|
|||
Loading…
Reference in New Issue