From 87ba892839582cb161abe88f6741d140ef7a9444 Mon Sep 17 00:00:00 2001 From: Kyler Date: Wed, 12 Nov 2025 15:22:20 -0700 Subject: [PATCH] Added more test generators --- SLS_Tests/generate_tests/__init__.py | 7 + SLS_Tests/generate_tests/base_tests.py | 6 +- SLS_Tests/generate_tests/char_tests.py | 337 +++++++++++++ .../generate_tests/idents_and_bools_tests.py | 397 +++++++++++++++ SLS_Tests/generate_tests/string_tests.py | 470 ++++++++++++++++++ 5 files changed, 1214 insertions(+), 3 deletions(-) create mode 100644 SLS_Tests/generate_tests/char_tests.py create mode 100644 SLS_Tests/generate_tests/idents_and_bools_tests.py create mode 100644 SLS_Tests/generate_tests/string_tests.py diff --git a/SLS_Tests/generate_tests/__init__.py b/SLS_Tests/generate_tests/__init__.py index 092fd96..4102bd9 100644 --- a/SLS_Tests/generate_tests/__init__.py +++ b/SLS_Tests/generate_tests/__init__.py @@ -2,10 +2,17 @@ from .base_tests import BaseTestGenerator from .general_tests import GeneralTestGenerator from .integer_tests import IntegerTestGenerator from .float_tests import FloatTestGenerator +from .char_tests import CharTestGenerator +from .string_tests import StringTestGenerator +from .idents_and_bools_tests import IdentifierTestGenerator, BooleanTestGenerator __all__ = [ "BaseTestGenerator", "GeneralTestGenerator", "IntegerTestGenerator", "FloatTestGenerator", + "CharTestGenerator", + "StringTestGenerator", + "IdentifierTestGenerator", + "BooleanTestGenerator", ] diff --git a/SLS_Tests/generate_tests/base_tests.py b/SLS_Tests/generate_tests/base_tests.py index 3d1433c..f70881a 100644 --- a/SLS_Tests/generate_tests/base_tests.py +++ b/SLS_Tests/generate_tests/base_tests.py @@ -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 dataclasses import dataclass, asdict @@ -52,10 +52,10 @@ class BaseTestGenerator(ABC): test creation, operation building, and error handling. """ - __generators: "ClassVar[Set[Type[BaseTestGenerator]]]" = set() + __generators: "ClassVar[List[Type[BaseTestGenerator]]]" = [] def __init_subclass__(cls): - BaseTestGenerator.__generators.add(cls) + BaseTestGenerator.__generators.append(cls) def __init__(self): """Initialize the test generator with an empty test list.""" diff --git a/SLS_Tests/generate_tests/char_tests.py b/SLS_Tests/generate_tests/char_tests.py new file mode 100644 index 0000000..8ef9043 --- /dev/null +++ b/SLS_Tests/generate_tests/char_tests.py @@ -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() diff --git a/SLS_Tests/generate_tests/idents_and_bools_tests.py b/SLS_Tests/generate_tests/idents_and_bools_tests.py new file mode 100644 index 0000000..36db72d --- /dev/null +++ b/SLS_Tests/generate_tests/idents_and_bools_tests.py @@ -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() diff --git a/SLS_Tests/generate_tests/string_tests.py b/SLS_Tests/generate_tests/string_tests.py new file mode 100644 index 0000000..ce02816 --- /dev/null +++ b/SLS_Tests/generate_tests/string_tests.py @@ -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()