300 lines
14 KiB
Python
300 lines
14 KiB
Python
from typing import List, Dict, Any
|
||
from .base_tests import BaseTestGenerator
|
||
|
||
|
||
class CharTestGenerator(BaseTestGenerator):
|
||
"""Generate test cases for character literals."""
|
||
|
||
# Common escape sequences
|
||
ESCAPE_SEQUENCES = {
|
||
("Newline", '\\\\n', '\n',), # Newline
|
||
("Carriage return", '\\\\r', '\r',), # Carriage return
|
||
("Tab", '\\\\t', '\t',), # Tab
|
||
("Backslash", '\\\\\\\\', '\\',), # Backslash
|
||
("Single quote", "\\\\'", "'",), # Single quote
|
||
("Null character", '\\\\0', '\0',), # Null character
|
||
}
|
||
|
||
# Unicode escape examples
|
||
UNICODE_ESCAPES = {
|
||
'\\u{41}': 'A',
|
||
'\\u{1F600}': '😀',
|
||
'\\u{2764}': '❤',
|
||
'\\u{0041}': 'A',
|
||
'\\u{03B1}': 'α',
|
||
'\\u{4E2D}': '中',
|
||
}
|
||
|
||
def generate_basic_tests(self):
|
||
"""Generate basic character literal tests."""
|
||
# Simple ASCII letters
|
||
self.make_success_test("Char Simple Letter A", "'A'", "char", 'A')
|
||
self.make_success_test("Char Simple Letter a", "'a'", "char", 'a')
|
||
self.make_success_test("Char Simple Letter Z", "'Z'", "char", 'Z')
|
||
self.make_success_test("Char Simple Letter z", "'z'", "char", 'z')
|
||
|
||
# Digits
|
||
self.make_success_test("Char Digit 0", "'0'", "char", '0')
|
||
self.make_success_test("Char Digit 5", "'5'", "char", '5')
|
||
self.make_success_test("Char Digit 9", "'9'", "char", '9')
|
||
|
||
# Special characters
|
||
self.make_success_test("Char Space", "' '", "char", ' ')
|
||
self.make_success_test("Char Exclamation", "'!'", "char", '!')
|
||
self.make_success_test("Char Question Mark", "'?'", "char", '?')
|
||
self.make_success_test("Char Period", "'.'", "char", '.')
|
||
self.make_success_test("Char Comma", "','", "char", ',')
|
||
self.make_success_test("Char Semicolon", "';'", "char", ';')
|
||
self.make_success_test("Char Colon", "':'", "char", ':')
|
||
|
||
# Operators and symbols
|
||
self.make_success_test("Char Plus", "'+'", "char", '+')
|
||
self.make_success_test("Char Minus", "'-'", "char", '-')
|
||
self.make_success_test("Char Asterisk", "'*'", "char", '*')
|
||
self.make_success_test("Char Slash", "'/'", "char", '/')
|
||
self.make_success_test("Char Equals", "'='", "char", '=')
|
||
self.make_success_test("Char Less Than", "'<'", "char", '<')
|
||
self.make_success_test("Char Greater Than", "'>'", "char", '>')
|
||
|
||
# Brackets and braces
|
||
self.make_success_test("Char Left Paren", "'('", "char", '(')
|
||
self.make_success_test("Char Right Paren", "')'", "char", ')')
|
||
self.make_success_test("Char Left Bracket", "'['", "char", '[')
|
||
self.make_success_test("Char Right Bracket", "']'", "char", ']')
|
||
self.make_success_test("Char Left Brace", "'{'", "char", '{')
|
||
self.make_success_test("Char Right Brace", "'}'", "char", '}')
|
||
|
||
def generate_escape_sequence_tests(self):
|
||
"""Generate tests for escape sequences."""
|
||
# Standard escape sequences
|
||
for escape_name, escape_str, char_val in self.ESCAPE_SEQUENCES:
|
||
name = f"Char Escape {escape_name}"
|
||
code = f"'{escape_str}'"
|
||
self.make_success_test(name, code, "char", char_val)
|
||
|
||
def generate_hexadecimal_escape_tests(self):
|
||
"""Generate tests for hexadecimal escape sequences."""
|
||
if self.ENABLE_CHAR_HEX_ESCAPE:
|
||
# Additional specific hex escapes
|
||
self.make_success_test("Char Hex Lowercase A", "'\\\\x61'", "char", 'a')
|
||
self.make_success_test("Char Hex Uppercase A", "'\\\\x41'", "char", 'A')
|
||
self.make_success_test("Char Hex Space", "'\\\\x20'", "char", ' ')
|
||
self.make_success_test("Char Hex Tab", "'\\\\x09'", "char", '\t')
|
||
self.make_success_test("Char Hex Newline", "'\\\\x0A'", "char", '\n')
|
||
self.make_success_test("Char Hex Max ASCII", "'\\\\x7F'", "char", '\x7F')
|
||
|
||
def generate_unicode_escape_tests(self):
|
||
"""Generate tests for Unicode escape sequences."""
|
||
for escape_str, char_val in self.UNICODE_ESCAPES.items():
|
||
name = f"Char Unicode {escape_str}"
|
||
code = f"'{escape_str}'"
|
||
self.make_success_test(name, code, "char", char_val)
|
||
|
||
# Additional Unicode tests
|
||
self.make_success_test("Char Unicode Smiley", "'\\u{1F600}'", "char", '😀')
|
||
self.make_success_test("Char Unicode Heart", "'\\u{2764}'", "char", '❤')
|
||
self.make_success_test("Char Unicode Star", "'\\u{2B50}'", "char", '⭐')
|
||
self.make_success_test("Char Unicode Greek Alpha", "'\\u{03B1}'", "char", 'α')
|
||
self.make_success_test("Char Unicode Greek Beta", "'\\u{03B2}'", "char", 'β')
|
||
self.make_success_test("Char Unicode Chinese", "'\\u{4E2D}'", "char", '中')
|
||
self.make_success_test("Char Unicode Arabic", "'\\u{0639}'", "char", 'ع')
|
||
self.make_success_test("Char Unicode Cyrillic", "'\\u{0410}'", "char", 'А')
|
||
|
||
def generate_unicode_direct_tests(self):
|
||
"""Generate tests for direct Unicode characters."""
|
||
# Emoji
|
||
self.make_success_test("Char Direct Emoji Smiley", "'😀'", "char", '😀')
|
||
self.make_success_test("Char Direct Emoji Heart", "'❤'", "char", '❤')
|
||
self.make_success_test("Char Direct Emoji Star", "'⭐'", "char", '⭐')
|
||
self.make_success_test("Char Direct Emoji Thumbs Up", "'👍'", "char", '👍')
|
||
|
||
# Greek letters
|
||
self.make_success_test("Char Direct Greek Alpha", "'α'", "char", 'α')
|
||
self.make_success_test("Char Direct Greek Beta", "'β'", "char", 'β')
|
||
self.make_success_test("Char Direct Greek Pi", "'π'", "char", 'π')
|
||
self.make_success_test("Char Direct Greek Omega", "'Ω'", "char", 'Ω')
|
||
|
||
# Chinese characters
|
||
self.make_success_test("Char Direct Chinese Middle", "'中'", "char", '中')
|
||
self.make_success_test("Char Direct Chinese Character", "'文'", "char", '文')
|
||
|
||
# Arabic
|
||
self.make_success_test("Char Direct Arabic Letter", "'ع'", "char", 'ع')
|
||
|
||
# Cyrillic
|
||
self.make_success_test("Char Direct Cyrillic A", "'А'", "char", 'А')
|
||
self.make_success_test("Char Direct Cyrillic Ya", "'Я'", "char", 'Я')
|
||
|
||
# Mathematical symbols
|
||
self.make_success_test("Char Direct Infinity", "'∞'", "char", '∞')
|
||
self.make_success_test("Char Direct Sum", "'∑'", "char", '∑')
|
||
self.make_success_test("Char Direct Integral", "'∫'", "char", '∫')
|
||
|
||
def generate_whitespace_tests(self):
|
||
"""Generate tests with whitespace around character literals."""
|
||
self.make_success_test("Char With Leading Whitespace", " 'A'", "char", 'A')
|
||
self.make_success_test("Char With Trailing Whitespace", "'A' ", "char", 'A')
|
||
self.make_success_test("Char With Both Whitespace", " 'A' ", "char", 'A')
|
||
self.make_success_test("Char Tab Before", "\\t'B'", "char", 'B')
|
||
self.make_success_test("Char Newline Before", "\\n'C'", "char", 'C')
|
||
|
||
def generate_error_tests(self):
|
||
"""Generate error test cases."""
|
||
# Empty character literal
|
||
self.make_error_test("Char Empty Literal",
|
||
"''",
|
||
"Invalid character literal: empty character literal.")
|
||
|
||
# Multiple characters (no escape)
|
||
self.make_error_test("Char Multiple Characters",
|
||
"'AB'",
|
||
"Invalid character literal: unexpected 'B' in character.")
|
||
|
||
# Unclosed quote
|
||
self.make_error_test("Char Unclosed Quote",
|
||
"'A",
|
||
"Invalid character literal: unclosed character literal.")
|
||
|
||
# Unescaped newline
|
||
self.make_error_test("Char Unescaped Newline",
|
||
"'\\n'",
|
||
"Invalid character literal: unclosed character literal.")
|
||
|
||
# Invalid escape sequence
|
||
self.make_error_test("Char Invalid Escape",
|
||
"'\\\\q'",
|
||
"Invalid character literal: unknown escape sequence '\\\\q'.")
|
||
|
||
# Invalid hex escape (not 2 digits)
|
||
if self.ENABLE_CHAR_HEX_ESCAPE:
|
||
self.make_error_test("Char Hex Escape Too Short",
|
||
"'\\\\x4'",
|
||
"Invalid character literal: hexadecimal escape must have exactly 2 digits.")
|
||
|
||
self.make_error_test("Char Hex Escape Too Long",
|
||
"'\\\\x414'",
|
||
"Invalid character literal: hexadecimal escape must have exactly 2 digits.")
|
||
|
||
# Invalid hex digits
|
||
self.make_error_test("Char Hex Invalid Digit",
|
||
"'\\\\xGG'",
|
||
"Invalid character literal: invalid hexadecimal digit 'G'.")
|
||
|
||
if self.ENABLE_UNICODE:
|
||
# Invalid Unicode escape (no braces)
|
||
self.make_error_test("Char Unicode No Braces",
|
||
"'\\u1F600'",
|
||
"Invalid character literal: Unicode escape must use braces \\u{...}.")
|
||
|
||
# Invalid Unicode escape (empty)
|
||
self.make_error_test("Char Unicode Empty",
|
||
"'\\u{}'",
|
||
"Invalid character literal: empty Unicode escape sequence.")
|
||
|
||
# Invalid Unicode escape (too many digits)
|
||
self.make_error_test("Char Unicode Too Many Digits",
|
||
"'\\u{1234567}'",
|
||
"Invalid character literal: Unicode escape sequence too long (max 6 hex digits).")
|
||
|
||
# Invalid Unicode escape (invalid code point)
|
||
self.make_error_test("Char Unicode Invalid Code Point",
|
||
"'\\u{D800}'",
|
||
"Invalid character literal: invalid Unicode code point (surrogate range).")
|
||
|
||
self.make_error_test("Char Unicode Out Of Range",
|
||
"'\\u{110000}'",
|
||
"Invalid character literal: Unicode code point out of range (max 0x10FFFF).")
|
||
|
||
# Invalid Unicode escape (non-hex digits)
|
||
self.make_error_test("Char Unicode Invalid Hex",
|
||
"'\\u{GGGG}'",
|
||
"Invalid character literal: invalid hexadecimal digit 'G' in Unicode escape.")
|
||
|
||
# Unclosed Unicode escape
|
||
self.make_error_test("Char Unicode Unclosed",
|
||
"'\\u{1F600'",
|
||
"Invalid character literal: unclosed Unicode escape sequence.")
|
||
|
||
def generate_edge_case_tests(self):
|
||
"""Generate edge case tests."""
|
||
if self.ENABLE_CHAR_HEX_ESCAPE:
|
||
# ASCII control characters
|
||
self.make_success_test("Char ASCII Control SOH", "'\\\\x01'", "char", '\x01')
|
||
self.make_success_test("Char ASCII Control BEL", "'\\\\x07'", "char", '\x07')
|
||
self.make_success_test("Char ASCII Control ESC", "'\\\\x1B'", "char", '\x1B')
|
||
self.make_success_test("Char ASCII Control DEL", "'\\\\x7F'", "char", '\x7F')
|
||
|
||
# Extended ASCII
|
||
self.make_success_test("Char Extended ASCII Lower", "'\\\\x80'", "char", '\x80')
|
||
self.make_success_test("Char Extended ASCII Upper", "'\\\\xFF'", "char", '\xFF')
|
||
|
||
if self.ENABLE_UNICODE:
|
||
# Zero-width characters
|
||
self.make_success_test("Char Zero Width Space", "'\\u{200B}'", "char", '\u200B')
|
||
self.make_success_test("Char Zero Width Joiner", "'\\u{200D}'", "char", '\u200D')
|
||
|
||
# Right-to-left marks
|
||
self.make_success_test("Char RTL Mark", "'\\u{200F}'", "char", '\u200F')
|
||
|
||
# Combining characters
|
||
self.make_success_test("Char Combining Acute", "'\\u{0301}'", "char", '\u0301')
|
||
|
||
# Low Unicode values
|
||
self.make_success_test("Char Unicode Zero", "'\\u{0}'", "char", '\0')
|
||
self.make_success_test("Char Unicode One", "'\\u{1}'", "char", '\x01')
|
||
|
||
# High Unicode values (but valid)
|
||
self.make_success_test("Char Unicode High Valid", "'\\u{10FFFF}'", "char", '\U0010FFFF')
|
||
|
||
def generate_case_sensitivity_tests(self):
|
||
"""Generate tests for case sensitivity in escape sequences."""
|
||
if self.ENABLE_CHAR_HEX_ESCAPE:
|
||
# Hex escapes - lowercase x
|
||
self.make_success_test("Char Hex Lowercase x", "'\\\\x41'", "char", 'A')
|
||
|
||
# Hex digits - both cases
|
||
self.make_success_test("Char Hex Digits Uppercase", "'\\\\xFF'", "char", '\xFF')
|
||
self.make_success_test("Char Hex Digits Lowercase", "'\\\\xff'", "char", '\xff')
|
||
self.make_success_test("Char Hex Digits Mixed", "'\\\\xAb'", "char", '\xAB')
|
||
|
||
if self.ENABLE_UNICODE:
|
||
# Unicode escapes - lowercase u
|
||
self.make_success_test("Char Unicode Lowercase u", "'\\u{41}'", "char", 'A')
|
||
|
||
# Unicode hex digits - both cases
|
||
self.make_success_test("Char Unicode Hex Uppercase", "'\\u{1F600}'", "char", '😀')
|
||
self.make_success_test("Char Unicode Hex Lowercase", "'\\u{1f600}'", "char", '😀')
|
||
self.make_success_test("Char Unicode Hex Mixed", "'\\u{1F60a}'", "char", '😊')
|
||
|
||
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
||
"""Generate all character literal test cases."""
|
||
# Basic tests
|
||
self.generate_basic_tests()
|
||
|
||
# Escape sequences
|
||
self.generate_escape_sequence_tests()
|
||
|
||
# Hexadecimal escapes
|
||
self.generate_hexadecimal_escape_tests()
|
||
|
||
if self.ENABLE_UNICODE:
|
||
# Unicode escapes
|
||
self.generate_unicode_escape_tests()
|
||
|
||
# Direct Unicode characters
|
||
self.generate_unicode_direct_tests()
|
||
|
||
# Whitespace handling
|
||
self.generate_whitespace_tests()
|
||
|
||
# Error cases
|
||
self.generate_error_tests()
|
||
|
||
# Edge cases
|
||
self.generate_edge_case_tests()
|
||
|
||
# Case sensitivity
|
||
self.generate_case_sensitivity_tests()
|
||
|
||
return self.get_tests()
|