Added more test generators
This commit is contained in:
parent
25d2202ebd
commit
87ba892839
|
|
@ -2,10 +2,17 @@ from .base_tests import BaseTestGenerator
|
||||||
from .general_tests import GeneralTestGenerator
|
from .general_tests import GeneralTestGenerator
|
||||||
from .integer_tests import IntegerTestGenerator
|
from .integer_tests import IntegerTestGenerator
|
||||||
from .float_tests import FloatTestGenerator
|
from .float_tests import FloatTestGenerator
|
||||||
|
from .char_tests import CharTestGenerator
|
||||||
|
from .string_tests import StringTestGenerator
|
||||||
|
from .idents_and_bools_tests import IdentifierTestGenerator, BooleanTestGenerator
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"BaseTestGenerator",
|
"BaseTestGenerator",
|
||||||
"GeneralTestGenerator",
|
"GeneralTestGenerator",
|
||||||
"IntegerTestGenerator",
|
"IntegerTestGenerator",
|
||||||
"FloatTestGenerator",
|
"FloatTestGenerator",
|
||||||
|
"CharTestGenerator",
|
||||||
|
"StringTestGenerator",
|
||||||
|
"IdentifierTestGenerator",
|
||||||
|
"BooleanTestGenerator",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import ClassVar, List, Dict, Any, Optional, Set, Type
|
from typing import ClassVar, List, Dict, Any, Optional, Type
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from dataclasses import dataclass, asdict
|
from dataclasses import dataclass, asdict
|
||||||
|
|
||||||
|
|
@ -52,10 +52,10 @@ class BaseTestGenerator(ABC):
|
||||||
test creation, operation building, and error handling.
|
test creation, operation building, and error handling.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__generators: "ClassVar[Set[Type[BaseTestGenerator]]]" = set()
|
__generators: "ClassVar[List[Type[BaseTestGenerator]]]" = []
|
||||||
|
|
||||||
def __init_subclass__(cls):
|
def __init_subclass__(cls):
|
||||||
BaseTestGenerator.__generators.add(cls)
|
BaseTestGenerator.__generators.append(cls)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Initialize the test generator with an empty test list."""
|
"""Initialize the test generator with an empty test list."""
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,337 @@
|
||||||
|
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 = {
|
||||||
|
'\\n': '\n', # Newline
|
||||||
|
'\\r': '\r', # Carriage return
|
||||||
|
'\\t': '\t', # Tab
|
||||||
|
'\\\\': '\\', # Backslash
|
||||||
|
'\\"': '"', # Double quote
|
||||||
|
"\\'": "'", # Single quote
|
||||||
|
'\\0': '\0', # Null character
|
||||||
|
}
|
||||||
|
|
||||||
|
# Hexadecimal escape examples
|
||||||
|
HEX_ESCAPES = {
|
||||||
|
'\\x41': 'A',
|
||||||
|
'\\x61': 'a',
|
||||||
|
'\\x20': ' ',
|
||||||
|
'\\x00': '\0',
|
||||||
|
'\\xFF': 'ÿ',
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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_str, char_val in self.ESCAPE_SEQUENCES.items():
|
||||||
|
name = f"Char Escape {escape_str}"
|
||||||
|
code = f"'{escape_str}'"
|
||||||
|
self.make_success_test(name, code, "char", char_val)
|
||||||
|
|
||||||
|
# Additional escape sequences with descriptions
|
||||||
|
test_cases = [
|
||||||
|
("Newline", "'\\n'", '\n'),
|
||||||
|
("Carriage Return", "'\\r'", '\r'),
|
||||||
|
("Tab", "'\\t'", '\t'),
|
||||||
|
("Backslash", "'\\\\'", '\\'),
|
||||||
|
("Double Quote", "'\\\"'", '"'),
|
||||||
|
("Single Quote", "'\\''", "'"),
|
||||||
|
("Null", "'\\0'", '\0'),
|
||||||
|
]
|
||||||
|
|
||||||
|
for desc, code, char_val in test_cases:
|
||||||
|
self.make_success_test(f"Char {desc}", code, "char", char_val)
|
||||||
|
|
||||||
|
def generate_hexadecimal_escape_tests(self):
|
||||||
|
"""Generate tests for hexadecimal escape sequences."""
|
||||||
|
for escape_str, char_val in self.HEX_ESCAPES.items():
|
||||||
|
name = f"Char Hex Escape {escape_str}"
|
||||||
|
code = f"'{escape_str}'"
|
||||||
|
self.make_success_test(name, code, "char", char_val)
|
||||||
|
|
||||||
|
# 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: multiple characters without escape sequence.")
|
||||||
|
|
||||||
|
# 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: unescaped newline in 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)
|
||||||
|
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'.")
|
||||||
|
|
||||||
|
# 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.")
|
||||||
|
|
||||||
|
# Double quotes instead of single
|
||||||
|
self.make_error_test("Char Double Quotes",
|
||||||
|
'"A"',
|
||||||
|
"Invalid character literal: character literals must use single quotes.")
|
||||||
|
|
||||||
|
# No quotes
|
||||||
|
self.make_error_test("Char No Quotes",
|
||||||
|
"A",
|
||||||
|
"Not a character literal: missing quotes.")
|
||||||
|
|
||||||
|
def generate_edge_case_tests(self):
|
||||||
|
"""Generate edge case tests."""
|
||||||
|
# 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')
|
||||||
|
|
||||||
|
# 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')
|
||||||
|
|
||||||
|
# Backslash before valid character
|
||||||
|
self.make_success_test("Char Backslash Literal", "'\\\\'", "char", '\\')
|
||||||
|
|
||||||
|
# Quote escaping
|
||||||
|
self.make_success_test("Char Single Quote Escaped", "'\\''", "char", "'")
|
||||||
|
self.make_success_test("Char Double Quote Escaped", "'\\\"'", "char", '"')
|
||||||
|
|
||||||
|
def generate_case_sensitivity_tests(self):
|
||||||
|
"""Generate tests for case sensitivity in escape sequences."""
|
||||||
|
# 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')
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
|
@ -0,0 +1,397 @@
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
from .base_tests import BaseTestGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class IdentifierTestGenerator(BaseTestGenerator):
|
||||||
|
"""Generate test cases for identifiers and identifier literals."""
|
||||||
|
|
||||||
|
# Reserved words that might be operators or keywords
|
||||||
|
RESERVED_WORDS = [
|
||||||
|
'true', 'false', 'if', 'while', 'for', 'match', 'break', 'continue',
|
||||||
|
'fn', 'struct', 'union', 'enum', 'trait', 'impl', 'inher',
|
||||||
|
'dup', 'drop', 'swap', 'over', 'rot', 'pick', 'roll', 'depth',
|
||||||
|
]
|
||||||
|
|
||||||
|
def generate_basic_identifier_tests(self):
|
||||||
|
"""Generate basic identifier tests."""
|
||||||
|
# Simple identifiers
|
||||||
|
self.make_success_test("Identifier Simple Lowercase", "hello",
|
||||||
|
"identifier", "hello")
|
||||||
|
self.make_success_test("Identifier Simple Uppercase", "HELLO",
|
||||||
|
"identifier", "HELLO")
|
||||||
|
self.make_success_test("Identifier Mixed Case", "HelloWorld",
|
||||||
|
"identifier", "HelloWorld")
|
||||||
|
self.make_success_test("Identifier Single Letter", "x",
|
||||||
|
"identifier", "x")
|
||||||
|
self.make_success_test("Identifier Single Letter Upper", "X",
|
||||||
|
"identifier", "X")
|
||||||
|
|
||||||
|
# Identifiers with numbers
|
||||||
|
self.make_success_test("Identifier With Numbers", "var123",
|
||||||
|
"identifier", "var123")
|
||||||
|
self.make_success_test("Identifier Numbers End", "myVar2",
|
||||||
|
"identifier", "myVar2")
|
||||||
|
self.make_success_test("Identifier Mixed Numbers", "a1b2c3",
|
||||||
|
"identifier", "a1b2c3")
|
||||||
|
|
||||||
|
# Identifiers with underscores
|
||||||
|
self.make_success_test("Identifier With Underscore", "hello_world",
|
||||||
|
"identifier", "hello_world")
|
||||||
|
self.make_success_test("Identifier Leading Underscore", "_private",
|
||||||
|
"identifier", "_private")
|
||||||
|
self.make_success_test("Identifier Multiple Underscores", "my_long_var_name",
|
||||||
|
"identifier", "my_long_var_name")
|
||||||
|
self.make_success_test("Identifier Double Underscore", "my__var",
|
||||||
|
"identifier", "my__var")
|
||||||
|
self.make_success_test("Identifier Trailing Underscore", "var_",
|
||||||
|
"identifier", "var_")
|
||||||
|
self.make_success_test("Identifier Only Underscores", "___",
|
||||||
|
"identifier", "___")
|
||||||
|
|
||||||
|
# Snake case
|
||||||
|
self.make_success_test("Identifier Snake Case", "my_variable_name",
|
||||||
|
"identifier", "my_variable_name")
|
||||||
|
|
||||||
|
# Camel case
|
||||||
|
self.make_success_test("Identifier Camel Case", "myVariableName",
|
||||||
|
"identifier", "myVariableName")
|
||||||
|
|
||||||
|
# Pascal case
|
||||||
|
self.make_success_test("Identifier Pascal Case", "MyClassName",
|
||||||
|
"identifier", "MyClassName")
|
||||||
|
|
||||||
|
# All caps with underscores
|
||||||
|
self.make_success_test("Identifier All Caps", "MY_CONSTANT",
|
||||||
|
"identifier", "MY_CONSTANT")
|
||||||
|
|
||||||
|
def generate_identifier_literal_tests(self):
|
||||||
|
"""Generate identifier literal tests (with :: prefix)."""
|
||||||
|
# Simple identifier literals
|
||||||
|
self.make_success_test("Identifier Literal Simple", "::hello",
|
||||||
|
"identifier_literal", "hello")
|
||||||
|
self.make_success_test("Identifier Literal Uppercase", "::Point",
|
||||||
|
"identifier_literal", "Point")
|
||||||
|
self.make_success_test("Identifier Literal Snake Case", "::my_var",
|
||||||
|
"identifier_literal", "my_var")
|
||||||
|
|
||||||
|
# Type names
|
||||||
|
self.make_success_test("Identifier Literal Type i64", "::i64",
|
||||||
|
"identifier_literal", "i64")
|
||||||
|
self.make_success_test("Identifier Literal Type String", "::String",
|
||||||
|
"identifier_literal", "String")
|
||||||
|
self.make_success_test("Identifier Literal Type Point", "::Point",
|
||||||
|
"identifier_literal", "Point")
|
||||||
|
|
||||||
|
# Trait names
|
||||||
|
self.make_success_test("Identifier Literal Trait Addable", "::Addable",
|
||||||
|
"identifier_literal", "Addable")
|
||||||
|
self.make_success_test("Identifier Literal Trait Drawable", "::Drawable",
|
||||||
|
"identifier_literal", "Drawable")
|
||||||
|
|
||||||
|
# Field names
|
||||||
|
self.make_success_test("Identifier Literal Field x", "::x",
|
||||||
|
"identifier_literal", "x")
|
||||||
|
self.make_success_test("Identifier Literal Field width", "::width",
|
||||||
|
"identifier_literal", "width")
|
||||||
|
|
||||||
|
# With underscores
|
||||||
|
self.make_success_test("Identifier Literal With Underscore", "::_private",
|
||||||
|
"identifier_literal", "_private")
|
||||||
|
self.make_success_test("Identifier Literal Multiple Underscores", "::my_long_name",
|
||||||
|
"identifier_literal", "my_long_name")
|
||||||
|
|
||||||
|
# With numbers
|
||||||
|
self.make_success_test("Identifier Literal With Numbers", "::var123",
|
||||||
|
"identifier_literal", "var123")
|
||||||
|
|
||||||
|
def generate_whitespace_tests(self):
|
||||||
|
"""Generate tests with whitespace around identifiers."""
|
||||||
|
# Regular identifiers with whitespace
|
||||||
|
self.make_success_test("Identifier Leading Whitespace", " hello",
|
||||||
|
"identifier", "hello")
|
||||||
|
self.make_success_test("Identifier Trailing Whitespace", "hello ",
|
||||||
|
"identifier", "hello")
|
||||||
|
self.make_success_test("Identifier Both Whitespace", " hello ",
|
||||||
|
"identifier", "hello")
|
||||||
|
self.make_success_test("Identifier Tab Before", "\thello",
|
||||||
|
"identifier", "hello")
|
||||||
|
|
||||||
|
# Identifier literals with whitespace
|
||||||
|
self.make_success_test("Identifier Literal Leading Whitespace", " ::hello",
|
||||||
|
"identifier_literal", "hello")
|
||||||
|
self.make_success_test("Identifier Literal Trailing Whitespace", "::hello ",
|
||||||
|
"identifier_literal", "hello")
|
||||||
|
self.make_success_test("Identifier Literal Both Whitespace", " ::hello ",
|
||||||
|
"identifier_literal", "hello")
|
||||||
|
|
||||||
|
def generate_long_identifier_tests(self):
|
||||||
|
"""Generate tests for longer identifiers."""
|
||||||
|
# Moderately long
|
||||||
|
self.make_success_test("Identifier Moderate Length",
|
||||||
|
"thisIsAReasonablyLongVariableName",
|
||||||
|
"identifier", "thisIsAReasonablyLongVariableName")
|
||||||
|
|
||||||
|
# Very long
|
||||||
|
long_name = "this_is_a_very_long_identifier_name_that_someone_might_use_for_some_reason"
|
||||||
|
self.make_success_test("Identifier Very Long", long_name,
|
||||||
|
"identifier", long_name)
|
||||||
|
|
||||||
|
# Long with numbers
|
||||||
|
long_with_nums = "variable_with_many_numbers_123_456_789_000"
|
||||||
|
self.make_success_test("Identifier Long With Numbers", long_with_nums,
|
||||||
|
"identifier", long_with_nums)
|
||||||
|
|
||||||
|
def generate_error_tests(self):
|
||||||
|
"""Generate error test cases for identifiers."""
|
||||||
|
# Starting with number
|
||||||
|
self.make_error_test("Identifier Starting With Number",
|
||||||
|
"123abc",
|
||||||
|
"Invalid identifier: cannot start with digit.")
|
||||||
|
|
||||||
|
# Invalid characters
|
||||||
|
self.make_error_test("Identifier With Hash",
|
||||||
|
"my#var",
|
||||||
|
"Invalid identifier: '#' is not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Dash",
|
||||||
|
"my-var",
|
||||||
|
"Invalid identifier: '-' is not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Dot",
|
||||||
|
"my.var",
|
||||||
|
"Invalid identifier: '.' is not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Space",
|
||||||
|
"my var",
|
||||||
|
"Invalid identifier: whitespace not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Colon",
|
||||||
|
"my:var",
|
||||||
|
"Invalid identifier: ':' is not allowed in identifiers.")
|
||||||
|
|
||||||
|
# Note: :: is allowed only as prefix for identifier literals
|
||||||
|
self.make_error_test("Identifier Double Colon Inside",
|
||||||
|
"my::var",
|
||||||
|
"Invalid identifier: '::' only allowed as prefix for identifier literals.")
|
||||||
|
|
||||||
|
# Special characters
|
||||||
|
self.make_error_test("Identifier With At",
|
||||||
|
"@variable",
|
||||||
|
"Invalid identifier: '@' is not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Dollar",
|
||||||
|
"$variable",
|
||||||
|
"Invalid identifier: '$' is not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Percent",
|
||||||
|
"%variable",
|
||||||
|
"Invalid identifier: '%' is not allowed in identifiers.")
|
||||||
|
|
||||||
|
# Brackets not allowed
|
||||||
|
self.make_error_test("Identifier With Brackets",
|
||||||
|
"my[var]",
|
||||||
|
"Invalid identifier: brackets not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Braces",
|
||||||
|
"my{var}",
|
||||||
|
"Invalid identifier: braces not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Parens",
|
||||||
|
"my(var)",
|
||||||
|
"Invalid identifier: parentheses not allowed in identifiers.")
|
||||||
|
|
||||||
|
# Quotes not allowed
|
||||||
|
self.make_error_test("Identifier With Single Quote",
|
||||||
|
"my'var",
|
||||||
|
"Invalid identifier: quotes not allowed in identifiers.")
|
||||||
|
|
||||||
|
self.make_error_test("Identifier With Double Quote",
|
||||||
|
'my"var',
|
||||||
|
"Invalid identifier: quotes not allowed in identifiers.")
|
||||||
|
|
||||||
|
# Only numbers (not valid identifier)
|
||||||
|
self.make_error_test("Identifier Only Numbers",
|
||||||
|
"123",
|
||||||
|
"Not an identifier: numeric literal.")
|
||||||
|
|
||||||
|
# Empty identifier literal
|
||||||
|
self.make_error_test("Identifier Literal Empty",
|
||||||
|
"::",
|
||||||
|
"Invalid identifier literal: empty identifier after '::'.")
|
||||||
|
|
||||||
|
def generate_case_sensitivity_tests(self):
|
||||||
|
"""Generate tests showing case sensitivity."""
|
||||||
|
# These should all be different identifiers
|
||||||
|
self.make_success_test("Identifier Case Lower", "variable",
|
||||||
|
"identifier", "variable")
|
||||||
|
self.make_success_test("Identifier Case Upper", "VARIABLE",
|
||||||
|
"identifier", "VARIABLE")
|
||||||
|
self.make_success_test("Identifier Case Mixed", "Variable",
|
||||||
|
"identifier", "Variable")
|
||||||
|
self.make_success_test("Identifier Case Camel", "variableName",
|
||||||
|
"identifier", "variableName")
|
||||||
|
self.make_success_test("Identifier Case Pascal", "VariableName",
|
||||||
|
"identifier", "VariableName")
|
||||||
|
|
||||||
|
def generate_reserved_word_tests(self):
|
||||||
|
"""Generate tests for words that might be reserved."""
|
||||||
|
# Note: In the spec, these are treated as identifiers/operators
|
||||||
|
# This tests that they're recognized correctly
|
||||||
|
for word in self.RESERVED_WORDS:
|
||||||
|
self.make_success_test(f"Identifier Reserved Word {word}",
|
||||||
|
word, "identifier", word)
|
||||||
|
|
||||||
|
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
||||||
|
"""Generate all identifier test cases."""
|
||||||
|
# Basic identifiers
|
||||||
|
self.generate_basic_identifier_tests()
|
||||||
|
|
||||||
|
# Identifier literals
|
||||||
|
self.generate_identifier_literal_tests()
|
||||||
|
|
||||||
|
# Whitespace handling
|
||||||
|
self.generate_whitespace_tests()
|
||||||
|
|
||||||
|
# Long identifiers
|
||||||
|
self.generate_long_identifier_tests()
|
||||||
|
|
||||||
|
# Error cases
|
||||||
|
self.generate_error_tests()
|
||||||
|
|
||||||
|
# Case sensitivity
|
||||||
|
self.generate_case_sensitivity_tests()
|
||||||
|
|
||||||
|
# Reserved words
|
||||||
|
self.generate_reserved_word_tests()
|
||||||
|
|
||||||
|
return self.get_tests()
|
||||||
|
|
||||||
|
|
||||||
|
class BooleanTestGenerator(BaseTestGenerator):
|
||||||
|
"""Generate test cases for boolean literals."""
|
||||||
|
|
||||||
|
def generate_basic_tests(self):
|
||||||
|
"""Generate basic boolean literal tests."""
|
||||||
|
# True
|
||||||
|
self.make_success_test("Bool True", "true", "bool", True)
|
||||||
|
|
||||||
|
# False
|
||||||
|
self.make_success_test("Bool False", "false", "bool", False)
|
||||||
|
|
||||||
|
def generate_whitespace_tests(self):
|
||||||
|
"""Generate tests with whitespace around booleans."""
|
||||||
|
# True with whitespace
|
||||||
|
self.make_success_test("Bool True Leading Whitespace", " true",
|
||||||
|
"bool", True)
|
||||||
|
self.make_success_test("Bool True Trailing Whitespace", "true ",
|
||||||
|
"bool", True)
|
||||||
|
self.make_success_test("Bool True Both Whitespace", " true ",
|
||||||
|
"bool", True)
|
||||||
|
self.make_success_test("Bool True Tab Before", "\ttrue",
|
||||||
|
"bool", True)
|
||||||
|
|
||||||
|
# False with whitespace
|
||||||
|
self.make_success_test("Bool False Leading Whitespace", " false",
|
||||||
|
"bool", False)
|
||||||
|
self.make_success_test("Bool False Trailing Whitespace", "false ",
|
||||||
|
"bool", False)
|
||||||
|
self.make_success_test("Bool False Both Whitespace", " false ",
|
||||||
|
"bool", False)
|
||||||
|
self.make_success_test("Bool False Tab Before", "\tfalse",
|
||||||
|
"bool", False)
|
||||||
|
|
||||||
|
def generate_error_tests(self):
|
||||||
|
"""Generate error test cases for booleans."""
|
||||||
|
# Capitalized (case sensitive)
|
||||||
|
self.make_error_test("Bool True Capitalized",
|
||||||
|
"True",
|
||||||
|
"Invalid boolean: 'True' is not a boolean literal (use lowercase 'true').")
|
||||||
|
|
||||||
|
self.make_error_test("Bool False Capitalized",
|
||||||
|
"False",
|
||||||
|
"Invalid boolean: 'False' is not a boolean literal (use lowercase 'false').")
|
||||||
|
|
||||||
|
# All caps
|
||||||
|
self.make_error_test("Bool True All Caps",
|
||||||
|
"TRUE",
|
||||||
|
"Invalid boolean: 'TRUE' is not a boolean literal (use lowercase 'true').")
|
||||||
|
|
||||||
|
self.make_error_test("Bool False All Caps",
|
||||||
|
"FALSE",
|
||||||
|
"Invalid boolean: 'FALSE' is not a boolean literal (use lowercase 'false').")
|
||||||
|
|
||||||
|
# Mixed case
|
||||||
|
self.make_error_test("Bool True Mixed Case",
|
||||||
|
"tRuE",
|
||||||
|
"Invalid boolean: 'tRuE' is not a boolean literal (use lowercase 'true').")
|
||||||
|
|
||||||
|
self.make_error_test("Bool False Mixed Case",
|
||||||
|
"fAlSe",
|
||||||
|
"Invalid boolean: 'fAlSe' is not a boolean literal (use lowercase 'false').")
|
||||||
|
|
||||||
|
# Numeric representations
|
||||||
|
self.make_error_test("Bool Numeric 1",
|
||||||
|
"1",
|
||||||
|
"Not a boolean: numeric literal.")
|
||||||
|
|
||||||
|
self.make_error_test("Bool Numeric 0",
|
||||||
|
"0",
|
||||||
|
"Not a boolean: numeric literal.")
|
||||||
|
|
||||||
|
# String representations
|
||||||
|
self.make_error_test("Bool String True",
|
||||||
|
'"true"',
|
||||||
|
"Not a boolean: string literal.")
|
||||||
|
|
||||||
|
self.make_error_test("Bool String False",
|
||||||
|
'"false"',
|
||||||
|
"Not a boolean: string literal.")
|
||||||
|
|
||||||
|
# Other languages
|
||||||
|
self.make_error_test("Bool Yes",
|
||||||
|
"yes",
|
||||||
|
"Invalid boolean: 'yes' is not a boolean literal.")
|
||||||
|
|
||||||
|
self.make_error_test("Bool No",
|
||||||
|
"no",
|
||||||
|
"Invalid boolean: 'no' is not a boolean literal.")
|
||||||
|
|
||||||
|
# Typos
|
||||||
|
self.make_error_test("Bool Typo Ture",
|
||||||
|
"ture",
|
||||||
|
"Invalid boolean: 'ture' is not a boolean literal.")
|
||||||
|
|
||||||
|
self.make_error_test("Bool Typo Flase",
|
||||||
|
"flase",
|
||||||
|
"Invalid boolean: 'flase' is not a boolean literal.")
|
||||||
|
|
||||||
|
def generate_multiple_bool_tests(self):
|
||||||
|
"""Generate tests with multiple boolean values."""
|
||||||
|
# Multiple values on stack
|
||||||
|
self.make_multi_value_test("Bool Multiple True False",
|
||||||
|
"true false",
|
||||||
|
[("bool", True), ("bool", False)])
|
||||||
|
|
||||||
|
self.make_multi_value_test("Bool Multiple Same",
|
||||||
|
"true true",
|
||||||
|
[("bool", True), ("bool", True)])
|
||||||
|
|
||||||
|
self.make_multi_value_test("Bool Three Values",
|
||||||
|
"true false true",
|
||||||
|
[("bool", True), ("bool", False), ("bool", True)])
|
||||||
|
|
||||||
|
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
||||||
|
"""Generate all boolean test cases."""
|
||||||
|
# Basic tests
|
||||||
|
self.generate_basic_tests()
|
||||||
|
|
||||||
|
# Whitespace handling
|
||||||
|
self.generate_whitespace_tests()
|
||||||
|
|
||||||
|
# Error cases
|
||||||
|
self.generate_error_tests()
|
||||||
|
|
||||||
|
# Multiple booleans
|
||||||
|
self.generate_multiple_bool_tests()
|
||||||
|
|
||||||
|
return self.get_tests()
|
||||||
|
|
@ -0,0 +1,470 @@
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
from .base_tests import BaseTestGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class StringTestGenerator(BaseTestGenerator):
|
||||||
|
"""Generate test cases for string literals."""
|
||||||
|
|
||||||
|
# Common escape sequences
|
||||||
|
ESCAPE_SEQUENCES = {
|
||||||
|
'\\n': '\n', # Newline
|
||||||
|
'\\r': '\r', # Carriage return
|
||||||
|
'\\t': '\t', # Tab
|
||||||
|
'\\\\': '\\', # Backslash
|
||||||
|
'\\"': '"', # Double quote
|
||||||
|
"\\'": "'", # Single quote
|
||||||
|
'\\0': '\0', # Null character
|
||||||
|
}
|
||||||
|
|
||||||
|
def generate_basic_tests(self):
|
||||||
|
"""Generate basic string literal tests."""
|
||||||
|
# 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")
|
||||||
|
|
||||||
|
# Multiple words
|
||||||
|
self.make_success_test("String Multiple Words",
|
||||||
|
'"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")
|
||||||
|
|
||||||
|
# Mixed case
|
||||||
|
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!")
|
||||||
|
self.make_success_test("String With Symbols",
|
||||||
|
'"@#$%^&*()"', "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", " ")
|
||||||
|
|
||||||
|
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")
|
||||||
|
self.make_success_test("String Tab", '"hello\\tworld"',
|
||||||
|
"String", "hello\tworld")
|
||||||
|
self.make_success_test("String Carriage Return", '"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"')
|
||||||
|
self.make_success_test("String Single Quote", '"it\\\'s"',
|
||||||
|
"String", "it's")
|
||||||
|
self.make_success_test("String Null Char", '"hello\\0world"',
|
||||||
|
"String", "hello\0world")
|
||||||
|
|
||||||
|
# Multiple escape sequences
|
||||||
|
self.make_success_test("String Multiple Escapes",
|
||||||
|
'"line1\\nline2\\nline3"',
|
||||||
|
"String", "line1\nline2\nline3")
|
||||||
|
self.make_success_test("String Mixed Escapes",
|
||||||
|
'"tab\\there\\nnewline\\\\backslash"',
|
||||||
|
"String", "tab\there\nnewline\\backslash")
|
||||||
|
|
||||||
|
# Escape at start/end
|
||||||
|
self.make_success_test("String Escape At Start", '"\\nhello"',
|
||||||
|
"String", "\nhello")
|
||||||
|
self.make_success_test("String Escape At End", '"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")
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
# Multiple hex escapes
|
||||||
|
self.make_success_test("String Multiple Hex", '"\\x48\\x65\\x6C\\x6C\\x6F"',
|
||||||
|
"String", "Hello")
|
||||||
|
|
||||||
|
# Hex with regular text
|
||||||
|
self.make_success_test("String Hex Mixed", '"Hello\\x20World"',
|
||||||
|
"String", "Hello World")
|
||||||
|
|
||||||
|
# Extended ASCII
|
||||||
|
self.make_success_test("String Hex Extended ASCII", '"\\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")
|
||||||
|
|
||||||
|
# All hex values
|
||||||
|
self.make_success_test("String Hex Zero", '"\\x00"', "String", "\x00")
|
||||||
|
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", " ")
|
||||||
|
|
||||||
|
# Emoji
|
||||||
|
self.make_success_test("String Unicode Smiley", '"\\u{1F600}"',
|
||||||
|
"String", "😀")
|
||||||
|
self.make_success_test("String Unicode Heart", '"\\u{2764}"',
|
||||||
|
"String", "❤")
|
||||||
|
self.make_success_test("String Unicode Star", '"\\u{2B50}"',
|
||||||
|
"String", "⭐")
|
||||||
|
|
||||||
|
# Multiple emoji
|
||||||
|
self.make_success_test("String Multiple Emoji",
|
||||||
|
'"\\u{1F600}\\u{2764}\\u{2B50}"',
|
||||||
|
"String", "😀❤⭐")
|
||||||
|
|
||||||
|
# Greek letters
|
||||||
|
self.make_success_test("String Unicode Greek Alpha", '"\\u{03B1}"',
|
||||||
|
"String", "α")
|
||||||
|
self.make_success_test("String Unicode Greek Beta", '"\\u{03B2}"',
|
||||||
|
"String", "β")
|
||||||
|
|
||||||
|
# Chinese characters
|
||||||
|
self.make_success_test("String Unicode Chinese", '"\\u{4E2D}\\u{6587}"',
|
||||||
|
"String", "中文")
|
||||||
|
|
||||||
|
# Arabic
|
||||||
|
self.make_success_test("String Unicode Arabic", '"\\u{0639}\\u{0631}\\u{0628}"',
|
||||||
|
"String", "عرب")
|
||||||
|
|
||||||
|
# Cyrillic
|
||||||
|
self.make_success_test("String Unicode Cyrillic", '"\\u{0420}\\u{0443}\\u{0441}"',
|
||||||
|
"String", "Рус")
|
||||||
|
|
||||||
|
# Mathematical symbols
|
||||||
|
self.make_success_test("String Unicode Math", '"\\u{221E}\\u{2211}\\u{222B}"',
|
||||||
|
"String", "∞∑∫")
|
||||||
|
|
||||||
|
# Mixed with regular text
|
||||||
|
self.make_success_test("String Unicode Mixed", '"Hello \\u{1F600} World"',
|
||||||
|
"String", "Hello 😀 World")
|
||||||
|
|
||||||
|
# Case variations in hex digits
|
||||||
|
self.make_success_test("String Unicode Hex Uppercase", '"\\u{1F600}"',
|
||||||
|
"String", "😀")
|
||||||
|
self.make_success_test("String Unicode Hex Lowercase", '"\\u{1f600}"',
|
||||||
|
"String", "😀")
|
||||||
|
self.make_success_test("String Unicode Hex Mixed", '"\\u{1F60a}"',
|
||||||
|
"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 6 Digits", '"\\u{10FFFF}"',
|
||||||
|
"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")
|
||||||
|
self.make_success_test("String Multiple Direct Emoji", '"😀❤⭐👍"',
|
||||||
|
"String", "😀❤⭐👍")
|
||||||
|
|
||||||
|
# Direct Greek
|
||||||
|
self.make_success_test("String Direct Greek", '"αβγδ"', "String", "αβγδ")
|
||||||
|
|
||||||
|
# Direct Chinese
|
||||||
|
self.make_success_test("String Direct Chinese", '"你好世界"',
|
||||||
|
"String", "你好世界")
|
||||||
|
|
||||||
|
# Direct Arabic
|
||||||
|
self.make_success_test("String Direct Arabic", '"مرحبا"', "String", "مرحبا")
|
||||||
|
|
||||||
|
# Direct Cyrillic
|
||||||
|
self.make_success_test("String Direct Cyrillic", '"Привет"',
|
||||||
|
"String", "Привет")
|
||||||
|
|
||||||
|
# Direct mathematical
|
||||||
|
self.make_success_test("String Direct Math", '"∞∑∫√π"', "String", "∞∑∫√π")
|
||||||
|
|
||||||
|
# Mixed scripts
|
||||||
|
self.make_success_test("String Mixed Scripts", '"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")
|
||||||
|
|
||||||
|
# Paragraph-like text
|
||||||
|
self.make_success_test("String Paragraph",
|
||||||
|
'"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")
|
||||||
|
|
||||||
|
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")
|
||||||
|
self.make_success_test("String Trailing Whitespace Outside",
|
||||||
|
'"hello" ', "String", "hello")
|
||||||
|
self.make_success_test("String Both Whitespace Outside",
|
||||||
|
' "hello" ', "String", "hello")
|
||||||
|
|
||||||
|
# Tabs outside quotes
|
||||||
|
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")
|
||||||
|
|
||||||
|
# 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 Mixed Whitespace", '" \\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.")
|
||||||
|
|
||||||
|
# Multiple sentences
|
||||||
|
self.make_success_test("String Multiple Sentences",
|
||||||
|
'"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)
|
||||||
|
|
||||||
|
# Repetitive string
|
||||||
|
self.make_success_test("String Repetitive", '"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)
|
||||||
|
|
||||||
|
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; }")
|
||||||
|
|
||||||
|
# JSON-like strings
|
||||||
|
self.make_success_test("String JSON Like",
|
||||||
|
'"{{\\"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")
|
||||||
|
|
||||||
|
# Email
|
||||||
|
self.make_success_test("String Email",
|
||||||
|
'"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")
|
||||||
|
|
||||||
|
# File path (Windows)
|
||||||
|
self.make_success_test("String Windows Path",
|
||||||
|
'"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")
|
||||||
|
|
||||||
|
# Regular expression
|
||||||
|
self.make_success_test("String Regex Like",
|
||||||
|
'"[a-zA-Z0-9]+"', "String", "[a-zA-Z0-9]+")
|
||||||
|
|
||||||
|
def generate_error_tests(self):
|
||||||
|
"""Generate error test cases."""
|
||||||
|
# Unclosed string
|
||||||
|
self.make_error_test("String Unclosed",
|
||||||
|
'"hello',
|
||||||
|
"Invalid string literal: unclosed string literal.")
|
||||||
|
|
||||||
|
# Unescaped newline
|
||||||
|
self.make_error_test("String Unescaped Newline",
|
||||||
|
'"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'.")
|
||||||
|
|
||||||
|
# Hex escape too short
|
||||||
|
self.make_error_test("String Hex Too Short",
|
||||||
|
'"\\x4"',
|
||||||
|
"Invalid string literal: hexadecimal escape must have exactly 2 digits.")
|
||||||
|
|
||||||
|
# Hex escape too long
|
||||||
|
self.make_error_test("String Hex Too Long",
|
||||||
|
'"\\x414"',
|
||||||
|
"Invalid string literal: hexadecimal escape must have exactly 2 digits.")
|
||||||
|
|
||||||
|
# Invalid hex digits
|
||||||
|
self.make_error_test("String Hex Invalid Digit",
|
||||||
|
'"\\xGG"',
|
||||||
|
"Invalid string literal: invalid hexadecimal digit 'G'.")
|
||||||
|
|
||||||
|
# Unicode no braces
|
||||||
|
self.make_error_test("String Unicode No Braces",
|
||||||
|
'"\\u1F600"',
|
||||||
|
"Invalid string literal: Unicode escape must use braces \\u{...}.")
|
||||||
|
|
||||||
|
# Unicode empty
|
||||||
|
self.make_error_test("String Unicode Empty",
|
||||||
|
'"\\u{}"',
|
||||||
|
"Invalid string literal: empty Unicode escape sequence.")
|
||||||
|
|
||||||
|
# Unicode too long
|
||||||
|
self.make_error_test("String Unicode Too Long",
|
||||||
|
'"\\u{1234567}"',
|
||||||
|
"Invalid string literal: Unicode escape sequence too long (max 6 hex digits).")
|
||||||
|
|
||||||
|
# Unicode invalid code point (surrogate)
|
||||||
|
self.make_error_test("String Unicode Surrogate",
|
||||||
|
'"\\u{D800}"',
|
||||||
|
"Invalid string literal: invalid Unicode code point (surrogate range).")
|
||||||
|
|
||||||
|
# Unicode out of range
|
||||||
|
self.make_error_test("String Unicode Out Of Range",
|
||||||
|
'"\\u{110000}"',
|
||||||
|
"Invalid string literal: Unicode code point out of range (max 0x10FFFF).")
|
||||||
|
|
||||||
|
# Unicode invalid hex
|
||||||
|
self.make_error_test("String Unicode Invalid Hex",
|
||||||
|
'"\\u{GGGG}"',
|
||||||
|
"Invalid string literal: invalid hexadecimal digit 'G' in Unicode escape.")
|
||||||
|
|
||||||
|
# Unclosed Unicode escape
|
||||||
|
self.make_error_test("String Unicode Unclosed",
|
||||||
|
'"\\u{1F600"',
|
||||||
|
"Invalid string literal: unclosed Unicode escape sequence.")
|
||||||
|
|
||||||
|
# Single quotes instead of double
|
||||||
|
self.make_error_test("String Single Quotes",
|
||||||
|
"'hello'",
|
||||||
|
"Invalid string literal: string literals must use double quotes.")
|
||||||
|
|
||||||
|
# Backslash at end
|
||||||
|
self.make_error_test("String Backslash At End",
|
||||||
|
'"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")
|
||||||
|
|
||||||
|
# String with null characters
|
||||||
|
self.make_success_test("String With Nulls",
|
||||||
|
'"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")
|
||||||
|
|
||||||
|
# Mixed escape types
|
||||||
|
self.make_success_test("String All Escape Types",
|
||||||
|
'"\\n\\x41\\u{42}test"',
|
||||||
|
"String", "\nABtest")
|
||||||
|
|
||||||
|
# Zero-width characters
|
||||||
|
self.make_success_test("String Zero Width",
|
||||||
|
'"hello\\u{200B}world"',
|
||||||
|
"String", "hello\u200Bworld")
|
||||||
|
|
||||||
|
# Combining characters
|
||||||
|
self.make_success_test("String Combining",
|
||||||
|
'"e\\u{0301}"', # é as e + combining acute
|
||||||
|
"String", "e\u0301")
|
||||||
|
|
||||||
|
# Right-to-left
|
||||||
|
self.make_success_test("String RTL Mark",
|
||||||
|
'"\\u{200F}hello"',
|
||||||
|
"String", "\u200Fhello")
|
||||||
|
|
||||||
|
# Byte order mark
|
||||||
|
self.make_success_test("String BOM",
|
||||||
|
'"\\u{FEFF}hello"',
|
||||||
|
"String", "\uFEFFhello")
|
||||||
|
|
||||||
|
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
||||||
|
"""Generate all string literal test cases."""
|
||||||
|
# Basic tests
|
||||||
|
self.generate_basic_tests()
|
||||||
|
|
||||||
|
# Escape sequences
|
||||||
|
self.generate_escape_sequence_tests()
|
||||||
|
|
||||||
|
# Hexadecimal escapes
|
||||||
|
self.generate_hexadecimal_escape_tests()
|
||||||
|
|
||||||
|
# Unicode escapes
|
||||||
|
self.generate_unicode_escape_tests()
|
||||||
|
|
||||||
|
# Direct Unicode
|
||||||
|
self.generate_direct_unicode_tests()
|
||||||
|
|
||||||
|
# Multiline strings
|
||||||
|
self.generate_multiline_tests()
|
||||||
|
|
||||||
|
# Whitespace handling
|
||||||
|
self.generate_whitespace_tests()
|
||||||
|
|
||||||
|
# Long strings
|
||||||
|
self.generate_long_string_tests()
|
||||||
|
|
||||||
|
# Special content
|
||||||
|
self.generate_special_content_tests()
|
||||||
|
|
||||||
|
# Error cases
|
||||||
|
self.generate_error_tests()
|
||||||
|
|
||||||
|
# Edge cases
|
||||||
|
self.generate_edge_case_tests()
|
||||||
|
|
||||||
|
return self.get_tests()
|
||||||
Loading…
Reference in New Issue