382 lines
17 KiB
Python
382 lines
17 KiB
Python
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")
|
|
|
|
# Others
|
|
self.make_success_test("Identifier With Dash", "my-var",
|
|
"identifier_literal", "my-var")
|
|
|
|
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 decimal literal: unexpected 'a' in decimal integer.")
|
|
|
|
# Invalid characters
|
|
self.make_error_test("Identifier With Hash",
|
|
"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_success_test("Bool True Capitalized", "True",
|
|
"identifier", "True")
|
|
|
|
self.make_success_test("Bool False Capitalized", "False",
|
|
"identifier", "False")
|
|
|
|
# All caps
|
|
self.make_success_test("Bool True All Caps", "TRUE",
|
|
"identifier", "TRUE")
|
|
|
|
self.make_success_test("Bool False All Caps", "FALSE",
|
|
"identifier", "FALSE")
|
|
|
|
# Mixed case
|
|
self.make_success_test("Bool True Mixed Case", "tRuE",
|
|
"identifier", "tRuE")
|
|
|
|
self.make_success_test("Bool False Mixed Case", "fAlSe",
|
|
"identifier", "fAlSe")
|
|
|
|
# Numeric representations
|
|
self.make_success_test("Bool Numeric 1", "1", "i64", 1)
|
|
|
|
self.make_success_test("Bool Numeric 0", "0", "i64", 0)
|
|
|
|
# String representations
|
|
self.make_success_test("Bool String True", '"true"',
|
|
"string", "true")
|
|
|
|
self.make_success_test("Bool String False", '"false"',
|
|
"string", "false")
|
|
|
|
# Other languages
|
|
self.make_success_test("Bool Yes", "yes",
|
|
"identifier", "yes")
|
|
|
|
self.make_success_test("Bool No", "no",
|
|
"identifier", "no")
|
|
|
|
# Typos
|
|
self.make_success_test("Bool Typo Ture", "ture",
|
|
"identifier", "ture")
|
|
|
|
self.make_success_test("Bool Typo Flase", "flase",
|
|
"identifier", "flase")
|
|
|
|
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()
|