Added base test generator class

This commit is contained in:
Kyler Olsen 2025-11-12 13:11:40 -07:00
parent cf5f51ccd8
commit 375c3f2422
6 changed files with 483 additions and 286 deletions

View File

@ -3,35 +3,22 @@ Test case generator for integer literals in the Stack Language.
Generates comprehensive test cases for all integer types and bases. Generates comprehensive test cases for all integer types and bases.
""" """
from .integer_tests import generate_integer_literal_tests from .general_tests import GeneralTestGenerator
from .float_tests import generate_float_literal_tests from .integer_tests import IntegerTestGenerator
from .float_tests import FloatTestGenerator
if __name__ == "__main__": if __name__ == "__main__":
# import json
import yaml import yaml
# Generate tests # Generate tests
tests = [] tests = []
tests += generate_integer_literal_tests() tests += GeneralTestGenerator.generate_tests()
tests += generate_float_literal_tests() tests += IntegerTestGenerator.generate_tests()
tests += FloatTestGenerator.generate_tests()
# Print summary # Print summary
print(f"Generated {len(tests)} test cases") print(f"Generated {len(tests)} test cases")
# # Save as JSON
# with open("integer_literal_tests.json", "w") as f:
# json.dump(tests, f, indent=2)
# print("Saved to integer_literal_tests.json")
# # Save as YAML
# with open("integer_literal_tests.yaml", "w") as f:
# yaml.dump(tests, f, default_flow_style=False, sort_keys=False)
# print("Saved to integer_literal_tests.yaml")
# Save as YAML # Save as YAML
with open("cases.yaml", "w") as f: with open("cases.yaml", "w") as f:
yaml.dump(tests, f, default_flow_style=False, sort_keys=False) yaml.dump(tests, f, default_flow_style=False, sort_keys=False)
# Print first few tests as example
# print("\nFirst 3 test cases:")
# print(yaml.dump(tests[:3], default_flow_style=False, sort_keys=False))

View File

@ -0,0 +1,352 @@
from typing import List, Dict, Any, Optional
from abc import ABC, abstractmethod
from dataclasses import dataclass, asdict
@dataclass
class Token:
type: str
value: Any
@dataclass
class Operation:
function: str
type: str
value: Any
@dataclass
class StackItem:
type: str
value: Any
@dataclass
class RuntimeError:
message: str
@dataclass
class TestCase:
name: str
code: str
tokens: List[Dict[str, Any]]
operations: Optional[List[Dict[str, Any]]] = None
stack_final: Optional[List[Dict[str, Any]]] = None
runtime_error: Optional[Dict[str, str]] = None
def to_dict(obj) -> Dict[str, Any]:
"""Convert dataclass to dict, removing None values."""
if obj is None:
raise ValueError("Obj cannot be None")
d = asdict(obj) if hasattr(obj, '__dataclass_fields__') else obj
return {k: v for k, v in d.items() if v is not None}
class BaseTestGenerator(ABC):
"""
Abstract base class for test case generators.
Provides common functionality for generating test cases including
test creation, operation building, and error handling.
"""
def __init__(self):
"""Initialize the test generator with an empty test list."""
self.tests: List[Dict[str, Any]] = []
# =========================================================================
# Test Case Management
# =========================================================================
def add_test(self, name: str, code: str, tokens: List[Token],
operations: Optional[List[Operation]] = None,
stack_final: Optional[List[StackItem]] = None,
runtime_error: Optional[RuntimeError] = None):
"""
Add a test case to the test suite.
Args:
name: Descriptive name for the test
code: Source code being tested
tokens: List of expected tokens from lexing
operations: Optional list of operations for evaluation phase
stack_final: Optional final stack state after execution
runtime_error: Optional runtime error if test should fail
"""
test = TestCase(
name=name,
code=code,
tokens=[to_dict(t) for t in tokens],
operations=[to_dict(o) for o in operations] if operations else None,
stack_final=[to_dict(s) for s in stack_final] if stack_final else None,
runtime_error=to_dict(runtime_error) if runtime_error else None
)
self.tests.append(to_dict(test))
# =========================================================================
# Factory Methods
# =========================================================================
def make_push_op(self, type_name: str, value: Any) -> Operation:
"""
Create a push operation.
Args:
type_name: Type of the value being pushed
value: The value to push
Returns:
Operation object representing a push
"""
return Operation(function="push", type=type_name, value=value)
def make_stack_item(self, type_name: str, value: Any) -> StackItem:
"""
Create a stack item.
Args:
type_name: Type of the stack item
value: The value of the stack item
Returns:
StackItem object
"""
return StackItem(type=type_name, value=value)
def make_error_token(self, message: str) -> Token:
"""
Create an error token.
Args:
message: Error message
Returns:
Token object with type "error"
"""
return Token(type="error", value=message)
def make_runtime_error(self, message: str) -> RuntimeError:
"""
Create a runtime error.
Args:
message: Error message
Returns:
RuntimeError object
"""
return RuntimeError(message=message)
# =========================================================================
# Convenience Test Creators
# =========================================================================
def make_success_test(self, name: str, code: str, type_name: str, value: Any):
"""
Create a successful test case with standard push operation.
Args:
name: Test name
code: Source code
type_name: Type of the value
value: The value
"""
token = Token(type=type_name, value=value)
op = self.make_push_op(type_name, value)
stack = self.make_stack_item(type_name, value)
self.add_test(name, code, [token], [op], [stack])
def make_error_test(self, name: str, code: str, error_msg: str):
"""
Create an error test case (lexing error).
Args:
name: Test name
code: Source code
error_msg: Expected error message
"""
token = self.make_error_token(error_msg)
self.add_test(name, code, [token])
def make_runtime_error_test(self, name: str, code: str, tokens: List[Token],
operations: List[Operation], error_msg: str):
"""
Create a runtime error test case.
Args:
name: Test name
code: Source code
tokens: Tokens that were successfully lexed
operations: Operations that led to the error
error_msg: Expected runtime error message
"""
runtime_error = self.make_runtime_error(error_msg)
self.add_test(name, code, tokens, operations, None, runtime_error)
def make_empty_test(self, name: str, code: str):
"""
Create a test case with empty result (e.g., comments, whitespace).
Args:
name: Test name
code: Source code
"""
self.add_test(name, code, [], [], [])
# =========================================================================
# Multi-Value Test Helpers
# =========================================================================
def make_multi_value_test(self, name: str, code: str,
values: List[tuple[str, Any]]):
"""
Create a test with multiple values on the stack.
Args:
name: Test name
code: Source code
values: List of (type_name, value) tuples in stack order
"""
tokens = [Token(type=t, value=v) for t, v in values]
operations = [self.make_push_op(t, v) for t, v in values]
stack = [self.make_stack_item(t, v) for t, v in values]
self.add_test(name, code, tokens, operations, stack)
# =========================================================================
# Test Suite Generation
# =========================================================================
@abstractmethod
def generate_all_tests(self) -> List[Dict[str, Any]]:
"""
Generate all test cases for this generator.
Must be implemented by subclasses to define their specific test suite.
Returns:
List of test case dictionaries ready for serialization
"""
pass
def get_tests(self) -> List[Dict[str, Any]]:
"""
Get the current list of tests.
Returns:
List of test case dictionaries
"""
return self.tests
def clear_tests(self):
"""Clear all tests from the generator."""
self.tests = []
def test_count(self) -> int:
"""
Get the number of tests generated.
Returns:
Number of tests
"""
return len(self.tests)
@classmethod
def generate_tests(cls) -> List[Dict[str, Any]]:
gen = cls()
tests = gen.generate_all_tests()
gen.print_statistics()
return tests
# =========================================================================
# Test Organization Helpers
# =========================================================================
def add_test_group_comment(self, comment: str):
"""
Add a comment to organize test groups (for documentation).
Note: This doesn't add an actual test, just tracks organization
in subclass implementations.
Args:
comment: Comment describing the test group
"""
# Subclasses can override to add metadata or logging
pass
# =========================================================================
# Validation Helpers
# =========================================================================
def validate_test_names_unique(self) -> bool:
"""
Check if all test names are unique.
Returns:
True if all test names are unique, False otherwise
"""
names = [test['name'] for test in self.tests]
return len(names) == len(set(names))
def get_duplicate_test_names(self) -> List[str]:
"""
Get list of duplicate test names.
Returns:
List of test names that appear more than once
"""
names = [test['name'] for test in self.tests]
seen = set()
duplicates = set()
for name in names:
if name in seen:
duplicates.add(name)
seen.add(name)
return list(duplicates)
# =========================================================================
# Statistics
# =========================================================================
def get_test_statistics(self) -> Dict[str, int]:
"""
Get statistics about the generated tests.
Returns:
Dictionary with test statistics
"""
stats = {
'total': len(self.tests),
'success': 0,
'lex_error': 0,
'runtime_error': 0,
'empty': 0,
}
for test in self.tests:
if test.get('runtime_error'):
stats['runtime_error'] += 1
elif test.get('tokens') and test['tokens'][0].get('type') == 'error':
stats['lex_error'] += 1
elif not test.get('tokens'):
stats['empty'] += 1
else:
stats['success'] += 1
return stats
def print_statistics(self):
"""Print test statistics to console."""
stats = self.get_test_statistics()
print(f"Test Statistics for {self.__class__.__name__}:")
print(f" Total tests: {stats['total']}")
print(f" Success tests: {stats['success']}")
print(f" Lex error tests: {stats['lex_error']}")
print(f" Runtime error tests: {stats['runtime_error']}")
print(f" Empty tests: {stats['empty']}")
if not self.validate_test_names_unique():
duplicates = self.get_duplicate_test_names()
print(f" WARNING: Duplicate test names found: {duplicates}")

View File

@ -1,9 +1,9 @@
from typing import List, Dict, Any, Optional from typing import List, Dict, Any
from .utils import Token, Operation, StackItem, RuntimeError, TestCase, to_dict from .base_tests import BaseTestGenerator
class FloatTestGenerator: class FloatTestGenerator(BaseTestGenerator):
"""Generate test cases for floating point literals.""" """Generate test cases for floating point literals."""
# Special float values # Special float values
SPECIAL_VALUES = { SPECIAL_VALUES = {
'f32': { 'f32': {
@ -19,49 +19,7 @@ class FloatTestGenerator:
'epsilon': 2.220446049250313e-16, 'epsilon': 2.220446049250313e-16,
} }
} }
def __init__(self):
self.tests = []
def add_test(self, name: str, code: str, tokens: List[Token],
operations: Optional[List[Operation]] = None,
stack_final: Optional[List[StackItem]] = None,
runtime_error: Optional[RuntimeError] = None):
"""Add a test case."""
test = TestCase(
name=name,
code=code,
tokens=[to_dict(t) for t in tokens],
operations=[to_dict(o) for o in operations] if operations else None,
stack_final=[to_dict(s) for s in stack_final] if stack_final else None,
runtime_error=to_dict(runtime_error) if runtime_error else None
)
self.tests.append(to_dict(test))
def make_push_op(self, type_name: str, value: Any) -> Operation:
"""Create a push operation."""
return Operation(function="push", type=type_name, value=value)
def make_stack_item(self, type_name: str, value: Any) -> StackItem:
"""Create a stack item."""
return StackItem(type=type_name, value=value)
def make_error_token(self, message: str) -> Token:
"""Create an error token."""
return Token(type="error", value=message)
def make_success_test(self, name: str, code: str, type_name: str, value: float):
"""Create a successful test case."""
token = Token(type=type_name, value=value)
op = self.make_push_op(type_name, value)
stack = self.make_stack_item(type_name, value)
self.add_test(name, code, [token], [op], [stack])
def make_error_test(self, name: str, code: str, error_msg: str):
"""Create an error test case."""
token = self.make_error_token(error_msg)
self.add_test(name, code, [token])
def generate_basic_tests(self): def generate_basic_tests(self):
"""Generate basic test cases.""" """Generate basic test cases."""
# Simple default floats (f64) # Simple default floats (f64)
@ -69,72 +27,72 @@ class FloatTestGenerator:
self.make_success_test("Float Default Zero", "0.0", "f64", 0.0) self.make_success_test("Float Default Zero", "0.0", "f64", 0.0)
self.make_success_test("Float Default Negative", "-2.5", "f64", -2.5) self.make_success_test("Float Default Negative", "-2.5", "f64", -2.5)
self.make_success_test("Float Default One", "1.0", "f64", 1.0) self.make_success_test("Float Default One", "1.0", "f64", 1.0)
# Simple with type annotation # Simple with type annotation
self.make_success_test("Float f32 Simple", "3.14:f32", "f32", 3.14) self.make_success_test("Float f32 Simple", "3.14:f32", "f32", 3.14)
self.make_success_test("Float f64 Simple", "2.718:f64", "f64", 2.718) self.make_success_test("Float f64 Simple", "2.718:f64", "f64", 2.718)
def generate_format_tests(self): def generate_format_tests(self):
"""Generate tests for different float formats.""" """Generate tests for different float formats."""
# Leading zeros # Leading zeros
self.make_success_test("Float Default Leading Zeros", "00042.5", "f64", 42.5) self.make_success_test("Float Default Leading Zeros", "00042.5", "f64", 42.5)
self.make_success_test("Float Default Leading Zero Decimal", "0.5", "f64", 0.5) self.make_success_test("Float Default Leading Zero Decimal", "0.5", "f64", 0.5)
# Trailing zeros # Trailing zeros
self.make_success_test("Float Default Trailing Zeros", "3.1400", "f64", 3.14) self.make_success_test("Float Default Trailing Zeros", "3.1400", "f64", 3.14)
# No leading digit # No leading digit
self.make_success_test("Float Default No Leading Digit", ".5", "f64", 0.5) self.make_success_test("Float Default No Leading Digit", ".5", "f64", 0.5)
self.make_success_test("Float Default No Leading Digit Negative", "-.25", "f64", -0.25) self.make_success_test("Float Default No Leading Digit Negative", "-.25", "f64", -0.25)
# No trailing digits # No trailing digits
self.make_success_test("Float Default No Trailing Digits", "42.", "f64", 42.0) self.make_success_test("Float Default No Trailing Digits", "42.", "f64", 42.0)
self.make_success_test("Float Default No Trailing Digits Negative", "-7.", "f64", -7.0) self.make_success_test("Float Default No Trailing Digits Negative", "-7.", "f64", -7.0)
# Scientific notation # Scientific notation
self.make_success_test("Float Default Scientific Positive Exp", "1.5e10", "f64", 1.5e10) self.make_success_test("Float Default Scientific Positive Exp", "1.5e10", "f64", 1.5e10)
self.make_success_test("Float Default Scientific Negative Exp", "2.5e-5", "f64", 2.5e-5) self.make_success_test("Float Default Scientific Negative Exp", "2.5e-5", "f64", 2.5e-5)
self.make_success_test("Float Default Scientific Capital E", "3.14E8", "f64", 3.14e8) self.make_success_test("Float Default Scientific Capital E", "3.14E8", "f64", 3.14e8)
self.make_success_test("Float Default Scientific Plus Sign", "1.0e+3", "f64", 1000.0) self.make_success_test("Float Default Scientific Plus Sign", "1.0e+3", "f64", 1000.0)
# Very small numbers # Very small numbers
self.make_success_test("Float Default Very Small", "0.000001", "f64", 0.000001) self.make_success_test("Float Default Very Small", "0.000001", "f64", 0.000001)
self.make_success_test("Float Default Scientific Very Small", "1.0e-20", "f64", 1.0e-20) self.make_success_test("Float Default Scientific Very Small", "1.0e-20", "f64", 1.0e-20)
# Very large numbers # Very large numbers
self.make_success_test("Float Default Very Large", "1000000.0", "f64", 1000000.0) self.make_success_test("Float Default Very Large", "1000000.0", "f64", 1000000.0)
self.make_success_test("Float Default Scientific Very Large", "1.0e20", "f64", 1.0e20) self.make_success_test("Float Default Scientific Very Large", "1.0e20", "f64", 1.0e20)
def generate_underscore_tests(self): def generate_underscore_tests(self):
"""Generate tests for underscores in floats.""" """Generate tests for underscores in floats."""
# Underscores in integer part # Underscores in integer part
self.make_success_test("Float Default Underscore Integer Part", self.make_success_test("Float Default Underscore Integer Part",
"1_000_000.5", "f64", 1000000.5) "1_000_000.5", "f64", 1000000.5)
# Underscores in decimal part # Underscores in decimal part
self.make_success_test("Float Default Underscore Decimal Part", self.make_success_test("Float Default Underscore Decimal Part",
"3.141_592_653", "f64", 3.141592653) "3.141_592_653", "f64", 3.141592653)
# Underscores in both parts # Underscores in both parts
self.make_success_test("Float Default Underscore Both Parts", self.make_success_test("Float Default Underscore Both Parts",
"1_234.567_89", "f64", 1234.56789) "1_234.567_89", "f64", 1234.56789)
# Underscores in scientific notation # Underscores in scientific notation
self.make_success_test("Float Default Underscore Scientific Mantissa", self.make_success_test("Float Default Underscore Scientific Mantissa",
"1_000.5e10", "f64", 1000.5e10) "1_000.5e10", "f64", 1000.5e10)
self.make_success_test("Float Default Underscore Scientific Exponent", self.make_success_test("Float Default Underscore Scientific Exponent",
"1.5e1_0", "f64", 1.5e10) "1.5e1_0", "f64", 1.5e10)
# Trailing underscore # Trailing underscore
self.make_success_test("Float Default Underscore Trailing", "42.5_", "f64", 42.5) self.make_success_test("Float Default Underscore Trailing", "42.5_", "f64", 42.5)
# Double underscore # Double underscore
self.make_success_test("Float Default Underscore Double", "4__2.5", "f64", 42.5) self.make_success_test("Float Default Underscore Double", "4__2.5", "f64", 42.5)
# With type annotation # With type annotation
self.make_success_test("Float f32 With Underscores", self.make_success_test("Float f32 With Underscores",
"1_234.567_89:f32", "f32", 1234.56789) "1_234.567_89:f32", "f32", 1234.56789)
def generate_special_value_tests(self): def generate_special_value_tests(self):
"""Generate tests for special float values.""" """Generate tests for special float values."""
# Infinity # Infinity
@ -142,42 +100,42 @@ class FloatTestGenerator:
self.make_success_test("Float Default Negative Infinity", "-inf", "f64", float('-inf')) self.make_success_test("Float Default Negative Infinity", "-inf", "f64", float('-inf'))
self.make_success_test("Float f32 Positive Infinity", "inf:f32", "f32", float('inf')) self.make_success_test("Float f32 Positive Infinity", "inf:f32", "f32", float('inf'))
self.make_success_test("Float f32 Negative Infinity", "-inf:f32", "f32", float('-inf')) self.make_success_test("Float f32 Negative Infinity", "-inf:f32", "f32", float('-inf'))
# NaN # NaN
self.make_success_test("Float Default NaN", "nan", "f64", float('nan')) self.make_success_test("Float Default NaN", "nan", "f64", float('nan'))
self.make_success_test("Float f32 NaN", "nan:f32", "f32", float('nan')) self.make_success_test("Float f32 NaN", "nan:f32", "f32", float('nan'))
# Note: NaN comparison is special - NaN != NaN, so these tests may need # Note: NaN comparison is special - NaN != NaN, so these tests may need
# special handling in the test runner # special handling in the test runner
def generate_edge_case_tests(self, type_name: str): def generate_edge_case_tests(self, type_name: str):
"""Generate edge case tests for a specific float type.""" """Generate edge case tests for a specific float type."""
values = self.SPECIAL_VALUES[type_name] values = self.SPECIAL_VALUES[type_name]
# Maximum value # Maximum value
self.make_success_test(f"Float {type_name} Max Value", self.make_success_test(f"Float {type_name} Max Value",
f"{values['max']}:{type_name}", type_name, values['max']) f"{values['max']}:{type_name}", type_name, values['max'])
# Minimum value (most negative) # Minimum value (most negative)
self.make_success_test(f"Float {type_name} Min Value", self.make_success_test(f"Float {type_name} Min Value",
f"{values['min']}:{type_name}", type_name, values['min']) f"{values['min']}:{type_name}", type_name, values['min'])
# Smallest positive normalized value # Smallest positive normalized value
self.make_success_test(f"Float {type_name} Min Positive", self.make_success_test(f"Float {type_name} Min Positive",
f"{values['min_positive']}:{type_name}", f"{values['min_positive']}:{type_name}",
type_name, values['min_positive']) type_name, values['min_positive'])
# Machine epsilon # Machine epsilon
self.make_success_test(f"Float {type_name} Epsilon", self.make_success_test(f"Float {type_name} Epsilon",
f"{values['epsilon']}:{type_name}", f"{values['epsilon']}:{type_name}",
type_name, values['epsilon']) type_name, values['epsilon'])
# Near zero # Near zero
self.make_success_test(f"Float {type_name} Near Zero Positive", self.make_success_test(f"Float {type_name} Near Zero Positive",
f"1e-30:{type_name}", type_name, 1e-30) f"1e-30:{type_name}", type_name, 1e-30)
self.make_success_test(f"Float {type_name} Near Zero Negative", self.make_success_test(f"Float {type_name} Near Zero Negative",
f"-1e-30:{type_name}", type_name, -1e-30) f"-1e-30:{type_name}", type_name, -1e-30)
# Subnormal numbers # Subnormal numbers
if type_name == 'f64': if type_name == 'f64':
self.make_success_test("Float f64 Subnormal", self.make_success_test("Float f64 Subnormal",
@ -185,7 +143,7 @@ class FloatTestGenerator:
elif type_name == 'f32': elif type_name == 'f32':
self.make_success_test("Float f32 Subnormal", self.make_success_test("Float f32 Subnormal",
"1e-40:f32", "f32", 1e-40) "1e-40:f32", "f32", 1e-40)
def generate_overflow_tests(self): def generate_overflow_tests(self):
"""Generate overflow tests.""" """Generate overflow tests."""
# f32 overflow # f32 overflow
@ -195,7 +153,7 @@ class FloatTestGenerator:
self.make_error_test("Float f32 Overflow Negative", self.make_error_test("Float f32 Overflow Negative",
"-1e40:f32", "-1e40:f32",
"Float overflow: value exceeds range for f32.") "Float overflow: value exceeds range for f32.")
# f64 overflow (extremely large values) # f64 overflow (extremely large values)
self.make_error_test("Float f64 Overflow Positive", self.make_error_test("Float f64 Overflow Positive",
"1e310:f64", "1e310:f64",
@ -203,7 +161,7 @@ class FloatTestGenerator:
self.make_error_test("Float f64 Overflow Negative", self.make_error_test("Float f64 Overflow Negative",
"-1e310:f64", "-1e310:f64",
"Float overflow: value exceeds range for f64.") "Float overflow: value exceeds range for f64.")
def generate_precision_tests(self): def generate_precision_tests(self):
"""Generate tests for precision limits.""" """Generate tests for precision limits."""
# f32 precision (~7 decimal digits) # f32 precision (~7 decimal digits)
@ -211,19 +169,19 @@ class FloatTestGenerator:
"1.2345678:f32", "f32", 1.2345678) "1.2345678:f32", "f32", 1.2345678)
self.make_success_test("Float f32 High Precision", self.make_success_test("Float f32 High Precision",
"3.141592653589793:f32", "f32", 3.141592653589793) "3.141592653589793:f32", "f32", 3.141592653589793)
# f64 precision (~15 decimal digits) # f64 precision (~15 decimal digits)
self.make_success_test("Float f64 Precision Limit", self.make_success_test("Float f64 Precision Limit",
"1.234567890123456:f64", "f64", 1.234567890123456) "1.234567890123456:f64", "f64", 1.234567890123456)
self.make_success_test("Float f64 High Precision", self.make_success_test("Float f64 High Precision",
"3.141592653589793238:f64", "f64", 3.141592653589793238) "3.141592653589793238:f64", "f64", 3.141592653589793238)
# Very close numbers # Very close numbers
self.make_success_test("Float f64 Close Numbers 1", self.make_success_test("Float f64 Close Numbers 1",
"1.0000000000000001:f64", "f64", 1.0000000000000001) "1.0000000000000001:f64", "f64", 1.0000000000000001)
self.make_success_test("Float f64 Close Numbers 2", self.make_success_test("Float f64 Close Numbers 2",
"1.0000000000000002:f64", "f64", 1.0000000000000002) "1.0000000000000002:f64", "f64", 1.0000000000000002)
def generate_error_tests(self): def generate_error_tests(self):
"""Generate error tests.""" """Generate error tests."""
# Invalid formats # Invalid formats
@ -239,7 +197,7 @@ class FloatTestGenerator:
self.make_error_test("Float Invalid Characters", self.make_error_test("Float Invalid Characters",
"3.1a4", "3.1a4",
"Invalid float literal: unexpected 'a' in float.") "Invalid float literal: unexpected 'a' in float.")
# Invalid scientific notation # Invalid scientific notation
self.make_error_test("Float Invalid Scientific No Exponent", self.make_error_test("Float Invalid Scientific No Exponent",
"3.14e", "3.14e",
@ -250,7 +208,7 @@ class FloatTestGenerator:
self.make_error_test("Float Invalid Scientific Invalid Exponent", self.make_error_test("Float Invalid Scientific Invalid Exponent",
"3.14eX", "3.14eX",
"Invalid float literal: invalid exponent 'X'.") "Invalid float literal: invalid exponent 'X'.")
# Invalid underscores # Invalid underscores
self.make_error_test("Float Invalid Leading Underscore", self.make_error_test("Float Invalid Leading Underscore",
"_3.14", "_3.14",
@ -261,7 +219,7 @@ class FloatTestGenerator:
self.make_error_test("Float Invalid Underscore After Decimal", self.make_error_test("Float Invalid Underscore After Decimal",
"3._14", "3._14",
"Invalid float literal: underscore after decimal point.") "Invalid float literal: underscore after decimal point.")
# Invalid type annotations # Invalid type annotations
self.make_error_test("Float Invalid Type Annotation", self.make_error_test("Float Invalid Type Annotation",
"3.14:i32", "3.14:i32",
@ -269,12 +227,12 @@ class FloatTestGenerator:
self.make_error_test("Float Invalid Type Name", self.make_error_test("Float Invalid Type Name",
"3.14:f16", "3.14:f16",
"Invalid type annotation: unknown type 'f16'.") "Invalid type annotation: unknown type 'f16'.")
# Comma separators not allowed # Comma separators not allowed
self.make_error_test("Float Invalid Comma Separator", self.make_error_test("Float Invalid Comma Separator",
"1,234.56", "1,234.56",
"Invalid float literal: unexpected ',' in float.") "Invalid float literal: unexpected ',' in float.")
def generate_whitespace_tests(self): def generate_whitespace_tests(self):
"""Generate tests with whitespace.""" """Generate tests with whitespace."""
self.make_success_test("Float Default Leading Whitespace", self.make_success_test("Float Default Leading Whitespace",
@ -285,7 +243,7 @@ class FloatTestGenerator:
" 3.14 ", "f64", 3.14) " 3.14 ", "f64", 3.14)
self.make_success_test("Float f32 With Whitespace", self.make_success_test("Float f32 With Whitespace",
" 2.718:f32 ", "f32", 2.718) " 2.718:f32 ", "f32", 2.718)
def generate_mathematical_constants_tests(self): def generate_mathematical_constants_tests(self):
"""Generate tests for common mathematical constants.""" """Generate tests for common mathematical constants."""
# Pi # Pi
@ -293,75 +251,64 @@ class FloatTestGenerator:
"3.141592653589793", "f64", 3.141592653589793) "3.141592653589793", "f64", 3.141592653589793)
self.make_success_test("Float f32 Pi Approximate", self.make_success_test("Float f32 Pi Approximate",
"3.1415927:f32", "f32", 3.1415927) "3.1415927:f32", "f32", 3.1415927)
# Euler's number # Euler's number
self.make_success_test("Float Default Euler Approximate", self.make_success_test("Float Default Euler Approximate",
"2.718281828459045", "f64", 2.718281828459045) "2.718281828459045", "f64", 2.718281828459045)
self.make_success_test("Float f32 Euler Approximate", self.make_success_test("Float f32 Euler Approximate",
"2.7182817:f32", "f32", 2.7182817) "2.7182817:f32", "f32", 2.7182817)
# Golden ratio # Golden ratio
self.make_success_test("Float Default Golden Ratio", self.make_success_test("Float Default Golden Ratio",
"1.618033988749895", "f64", 1.618033988749895) "1.618033988749895", "f64", 1.618033988749895)
# Square root of 2 # Square root of 2
self.make_success_test("Float Default Sqrt2", self.make_success_test("Float Default Sqrt2",
"1.4142135623730951", "f64", 1.4142135623730951) "1.4142135623730951", "f64", 1.4142135623730951)
def generate_signed_zero_tests(self): def generate_signed_zero_tests(self):
"""Generate tests for signed zeros.""" """Generate tests for signed zeros."""
self.make_success_test("Float Default Positive Zero", "0.0", "f64", 0.0) self.make_success_test("Float Default Positive Zero", "0.0", "f64", 0.0)
self.make_success_test("Float Default Negative Zero", "-0.0", "f64", -0.0) self.make_success_test("Float Default Negative Zero", "-0.0", "f64", -0.0)
self.make_success_test("Float f32 Positive Zero", "0.0:f32", "f32", 0.0) self.make_success_test("Float f32 Positive Zero", "0.0:f32", "f32", 0.0)
self.make_success_test("Float f32 Negative Zero", "-0.0:f32", "f32", -0.0) self.make_success_test("Float f32 Negative Zero", "-0.0:f32", "f32", -0.0)
# Note: In IEEE 754, +0.0 and -0.0 are distinct values but compare equal # Note: In IEEE 754, +0.0 and -0.0 are distinct values but compare equal
def generate_all_tests(self) -> List[Dict[str, Any]]: def generate_all_tests(self) -> List[Dict[str, Any]]:
"""Generate all test cases.""" """Generate all test cases."""
# Basic tests # Basic tests
self.generate_basic_tests() self.generate_basic_tests()
# Format variations # Format variations
self.generate_format_tests() self.generate_format_tests()
# Underscores # Underscores
self.generate_underscore_tests() self.generate_underscore_tests()
# Special values (inf, nan) # Special values (inf, nan)
self.generate_special_value_tests() self.generate_special_value_tests()
# Edge cases for each type # Edge cases for each type
for type_name in ['f32', 'f64']: for type_name in ['f32', 'f64']:
self.generate_edge_case_tests(type_name) self.generate_edge_case_tests(type_name)
# Overflow tests # Overflow tests
self.generate_overflow_tests() self.generate_overflow_tests()
# Precision tests # Precision tests
self.generate_precision_tests() self.generate_precision_tests()
# Error tests # Error tests
self.generate_error_tests() self.generate_error_tests()
# Whitespace tests # Whitespace tests
self.generate_whitespace_tests() self.generate_whitespace_tests()
# Mathematical constants # Mathematical constants
self.generate_mathematical_constants_tests() self.generate_mathematical_constants_tests()
# Signed zeros # Signed zeros
self.generate_signed_zero_tests() self.generate_signed_zero_tests()
return self.tests return self.tests
def generate_float_literal_tests() -> List[Dict[str, Any]]:
"""
Main function to generate all floating point literal test cases.
Returns:
List of test case dictionaries ready for serialization
"""
generator = FloatTestGenerator()
return generator.generate_all_tests()

View File

@ -0,0 +1,11 @@
from typing import List, Dict, Any
from .base_tests import BaseTestGenerator
class GeneralTestGenerator(BaseTestGenerator):
def generate_all_tests(self) -> List[Dict[str, Any]]:
"""Generate all test cases."""
self.add_test("Empty_Statement", "", [], [], [])
return self.tests

View File

@ -1,9 +1,9 @@
from typing import List, Dict, Any, Optional from typing import List, Dict, Any
from .utils import Token, Operation, StackItem, RuntimeError, TestCase, to_dict from .base_tests import BaseTestGenerator
class IntegerTestGenerator: class IntegerTestGenerator(BaseTestGenerator):
"""Generate test cases for integer literals.""" """Generate test cases for integer literals."""
# Type ranges # Type ranges
TYPE_RANGES = { TYPE_RANGES = {
'i8': (-128, 127), 'i8': (-128, 127),
@ -15,97 +15,53 @@ class IntegerTestGenerator:
'u32': (0, 4294967295), 'u32': (0, 4294967295),
'u64': (0, 18446744073709551615), 'u64': (0, 18446744073709551615),
} }
def __init__(self):
self.tests = []
def add_test(self, name: str, code: str, tokens: List[Token],
operations: Optional[List[Operation]] = None,
stack_final: Optional[List[StackItem]] = None,
runtime_error: Optional[RuntimeError] = None):
"""Add a test case."""
test = TestCase(
name=name,
code=code,
tokens=[to_dict(t) for t in tokens],
operations=[to_dict(o) for o in operations] if operations else None,
stack_final=[to_dict(s) for s in stack_final] if stack_final else None,
runtime_error=to_dict(runtime_error) if runtime_error else None
)
self.tests.append(to_dict(test))
def make_push_op(self, type_name: str, value: Any) -> Operation:
"""Create a push operation."""
return Operation(function="push", type=type_name, value=value)
def make_stack_item(self, type_name: str, value: Any) -> StackItem:
"""Create a stack item."""
return StackItem(type=type_name, value=value)
def make_error_token(self, message: str) -> Token:
"""Create an error token."""
return Token(type="error", value=message)
def make_success_test(self, name: str, code: str, type_name: str, value: Any):
"""Create a successful test case."""
token = Token(type=type_name, value=value)
op = self.make_push_op(type_name, value)
stack = self.make_stack_item(type_name, value)
self.add_test(name, code, [token], [op], [stack])
def make_error_test(self, name: str, code: str, error_msg: str):
"""Create an error test case."""
token = self.make_error_token(error_msg)
self.add_test(name, code, [token])
def generate_basic_tests(self): def generate_basic_tests(self):
"""Generate basic test cases.""" """Generate basic test cases."""
# Empty statement
self.add_test("Empty_Statement", "", [], [], [])
# Simple default integers # Simple default integers
self.make_success_test("Integer Default Decimal 0", "0", "i64", 0) self.make_success_test("Integer Default Decimal 0", "0", "i64", 0)
self.make_success_test("Integer Default Decimal -1", "-1", "i64", -1) self.make_success_test("Integer Default Decimal -1", "-1", "i64", -1)
self.make_success_test("Integer Default Decimal 42", "42", "i64", 42) self.make_success_test("Integer Default Decimal 42", "42", "i64", 42)
self.make_success_test("Integer Default Decimal Leading Zeros", "00042", "i64", 42) self.make_success_test("Integer Default Decimal Leading Zeros", "00042", "i64", 42)
def generate_default_base_tests(self): def generate_default_base_tests(self):
"""Generate tests for default type with different bases.""" """Generate tests for default type with different bases."""
# Hexadecimal # Hexadecimal
self.make_success_test("Integer Default Hex 0xFF", "0xFF", "i64", 255) self.make_success_test("Integer Default Hex 0xFF", "0xFF", "i64", 255)
self.make_success_test("Integer Default Hex 0xdeadbeef", "0xdeadbeef", "i64", 3735928559) self.make_success_test("Integer Default Hex 0xdeadbeef", "0xdeadbeef", "i64", 3735928559)
self.make_success_test("Integer Default Hex Max", "0x7FFFFFFFFFFFFFFF", "i64", 9223372036854775807) self.make_success_test("Integer Default Hex Max", "0x7FFFFFFFFFFFFFFF", "i64", 9223372036854775807)
# Binary # Binary
self.make_success_test("Integer Default Binary 0b1010", "0b1010", "i64", 10) self.make_success_test("Integer Default Binary 0b1010", "0b1010", "i64", 10)
self.make_success_test("Integer Default Binary All Ones", "0b1111111111111111", "i64", 65535) self.make_success_test("Integer Default Binary All Ones", "0b1111111111111111", "i64", 65535)
# Octal # Octal
self.make_success_test("Integer Default Octal 0o755", "0o755", "i64", 493) self.make_success_test("Integer Default Octal 0o755", "0o755", "i64", 493)
self.make_success_test("Integer Default Octal Max Three Digits", "0o777", "i64", 511) self.make_success_test("Integer Default Octal Max Three Digits", "0o777", "i64", 511)
def generate_default_edge_cases(self): def generate_default_edge_cases(self):
"""Generate edge case tests for default type.""" """Generate edge case tests for default type."""
# Min/max values # Min/max values
self.make_success_test("Integer Default Decimal Max i64", self.make_success_test("Integer Default Decimal Max i64",
"9223372036854775807", "i64", 9223372036854775807) "9223372036854775807", "i64", 9223372036854775807)
self.make_success_test("Integer Default Decimal Min i64", self.make_success_test("Integer Default Decimal Min i64",
"-9223372036854775808", "i64", -9223372036854775808) "-9223372036854775808", "i64", -9223372036854775808)
# Underscores # Underscores
self.make_success_test("Integer Default Decimal with Underscore", self.make_success_test("Integer Default Decimal with Underscore",
"1_000_000", "i64", 1000000) "1_000_000", "i64", 1000000)
self.make_success_test("Integer Default Underscore End", "42_", "i64", 42) self.make_success_test("Integer Default Underscore End", "42_", "i64", 42)
self.make_success_test("Integer Default Underscore Double", "4__2", "i64", 42) self.make_success_test("Integer Default Underscore Double", "4__2", "i64", 42)
# Whitespace # Whitespace
self.make_success_test("Integer Default Whitespace", " 42 ", "i64", 42) self.make_success_test("Integer Default Whitespace", " 42 ", "i64", 42)
# Zeros in different bases # Zeros in different bases
self.make_success_test("Integer Default Hex Zero", "0x0", "i64", 0) self.make_success_test("Integer Default Hex Zero", "0x0", "i64", 0)
self.make_success_test("Integer Default Binary Zero", "0b0", "i64", 0) self.make_success_test("Integer Default Binary Zero", "0b0", "i64", 0)
self.make_success_test("Integer Default Octal Zero", "0o0", "i64", 0) self.make_success_test("Integer Default Octal Zero", "0o0", "i64", 0)
def generate_default_error_tests(self): def generate_default_error_tests(self):
"""Generate error tests for default type.""" """Generate error tests for default type."""
self.make_error_test("Integer Default Decimal with Commas Invalid", self.make_error_test("Integer Default Decimal with Commas Invalid",
@ -117,126 +73,126 @@ class IntegerTestGenerator:
self.make_error_test("Integer Default Invalid Prefix", self.make_error_test("Integer Default Invalid Prefix",
"0b2", "0b2",
"Invalid binary literal: unexpected '2' in binary integer.") "Invalid binary literal: unexpected '2' in binary integer.")
def generate_typed_tests(self, type_name: str): def generate_typed_tests(self, type_name: str):
"""Generate tests for a specific type across all bases.""" """Generate tests for a specific type across all bases."""
min_val, max_val = self.TYPE_RANGES[type_name] min_val, max_val = self.TYPE_RANGES[type_name]
is_unsigned = type_name.startswith('u') is_unsigned = type_name.startswith('u')
# Basic decimal # Basic decimal
test_val = 42 if max_val >= 42 else max_val test_val = 42 if max_val >= 42 else max_val
self.make_success_test(f"Integer {type_name} Decimal Positive", self.make_success_test(f"Integer {type_name} Decimal Positive",
f"{test_val}:{type_name}", type_name, test_val) f"{test_val}:{type_name}", type_name, test_val)
# Zero # Zero
self.make_success_test(f"Integer {type_name} Zero", self.make_success_test(f"Integer {type_name} Zero",
f"0:{type_name}", type_name, 0) f"0:{type_name}", type_name, 0)
# Negative (only for signed types) # Negative (only for signed types)
if not is_unsigned: if not is_unsigned:
neg_val = -100 if min_val <= -100 else min_val neg_val = -100 if min_val <= -100 else min_val
self.make_success_test(f"Integer {type_name} Decimal Negative", self.make_success_test(f"Integer {type_name} Decimal Negative",
f"{neg_val}:{type_name}", type_name, neg_val) f"{neg_val}:{type_name}", type_name, neg_val)
# Hexadecimal # Hexadecimal
hex_val = min(255, max_val) hex_val = min(255, max_val)
self.make_success_test(f"Integer {type_name} Hex", self.make_success_test(f"Integer {type_name} Hex",
f"0x{hex_val:X}:{type_name}", type_name, hex_val) f"0x{hex_val:X}:{type_name}", type_name, hex_val)
# Binary # Binary
bin_val = min(15, max_val) bin_val = min(15, max_val)
self.make_success_test(f"Integer {type_name} Binary", self.make_success_test(f"Integer {type_name} Binary",
f"0b{bin_val:b}:{type_name}", type_name, bin_val) f"0b{bin_val:b}:{type_name}", type_name, bin_val)
# Octal # Octal
oct_val = min(63, max_val) oct_val = min(63, max_val)
self.make_success_test(f"Integer {type_name} Octal", self.make_success_test(f"Integer {type_name} Octal",
f"0o{oct_val:o}:{type_name}", type_name, oct_val) f"0o{oct_val:o}:{type_name}", type_name, oct_val)
# Max value # Max value
self.make_success_test(f"Integer {type_name} Max Value", self.make_success_test(f"Integer {type_name} Max Value",
f"{max_val}:{type_name}", type_name, max_val) f"{max_val}:{type_name}", type_name, max_val)
# Min value # Min value
self.make_success_test(f"Integer {type_name} Min Value", self.make_success_test(f"Integer {type_name} Min Value",
f"{min_val}:{type_name}", type_name, min_val) f"{min_val}:{type_name}", type_name, min_val)
# Overflow # Overflow
overflow_val = max_val + 1 overflow_val = max_val + 1
self.make_error_test(f"Integer {type_name} Overflow", self.make_error_test(f"Integer {type_name} Overflow",
f"{overflow_val}:{type_name}", f"{overflow_val}:{type_name}",
f"Integer overflow: value exceeds range for {type_name}.") f"Integer overflow: value exceeds range for {type_name}.")
# Underflow # Underflow
underflow_val = min_val - 1 underflow_val = min_val - 1
self.make_error_test(f"Integer {type_name} Underflow", self.make_error_test(f"Integer {type_name} Underflow",
f"{underflow_val}:{type_name}", f"{underflow_val}:{type_name}",
f"Integer overflow: value exceeds range for {type_name}.") f"Integer overflow: value exceeds range for {type_name}.")
def generate_special_typed_tests(self, type_name: str): def generate_special_typed_tests(self, type_name: str):
"""Generate special tests for specific types.""" """Generate special tests for specific types."""
min_val, max_val = self.TYPE_RANGES[type_name] min_val, max_val = self.TYPE_RANGES[type_name]
is_unsigned = type_name.startswith('u') is_unsigned = type_name.startswith('u')
# Underscores with type annotation # Underscores with type annotation
if max_val >= 1000000: if max_val >= 1000000:
self.make_success_test(f"Integer {type_name} With Underscores", self.make_success_test(f"Integer {type_name} With Underscores",
f"1_000_000:{type_name}", type_name, 1000000) f"1_000_000:{type_name}", type_name, 1000000)
# Special values for specific types # Special values for specific types
if type_name == 'i8': if type_name == 'i8':
self.make_success_test("Integer i8 Hex Max", "0x7F:i8", "i8", 127) self.make_success_test("Integer i8 Hex Max", "0x7F:i8", "i8", 127)
self.make_success_test("Integer i8 Binary Max", "0b01111111:i8", "i8", 127) self.make_success_test("Integer i8 Binary Max", "0b01111111:i8", "i8", 127)
self.make_success_test("Integer i8 Octal Max", "0o177:i8", "i8", 127) self.make_success_test("Integer i8 Octal Max", "0o177:i8", "i8", 127)
self.make_success_test("Integer i8 Negative Hex", "-0x80:i8", "i8", -128) self.make_success_test("Integer i8 Negative Hex", "-0x80:i8", "i8", -128)
elif type_name == 'u8': elif type_name == 'u8':
self.make_success_test("Integer u8 Hex Max", "0xFF:u8", "u8", 255) self.make_success_test("Integer u8 Hex Max", "0xFF:u8", "u8", 255)
self.make_success_test("Integer u8 Binary Max", "0b11111111:u8", "u8", 255) self.make_success_test("Integer u8 Binary Max", "0b11111111:u8", "u8", 255)
self.make_success_test("Integer u8 Octal Max", "0o377:u8", "u8", 255) self.make_success_test("Integer u8 Octal Max", "0o377:u8", "u8", 255)
elif type_name == 'i16': elif type_name == 'i16':
self.make_success_test("Integer i16 Hex Sample", "0x1234:i16", "i16", 4660) self.make_success_test("Integer i16 Hex Sample", "0x1234:i16", "i16", 4660)
self.make_success_test("Integer i16 Binary Sample", self.make_success_test("Integer i16 Binary Sample",
"0b1111111100000000:i16", "i16", 65280) "0b1111111100000000:i16", "i16", 65280)
self.make_success_test("Integer i16 Octal Sample", "0o1234:i16", "i16", 668) self.make_success_test("Integer i16 Octal Sample", "0o1234:i16", "i16", 668)
elif type_name == 'u16': elif type_name == 'u16':
self.make_success_test("Integer u16 Hex Max", "0xFFFF:u16", "u16", 65535) self.make_success_test("Integer u16 Hex Max", "0xFFFF:u16", "u16", 65535)
self.make_success_test("Integer u16 Binary Max", self.make_success_test("Integer u16 Binary Max",
"0b1111111111111111:u16", "u16", 65535) "0b1111111111111111:u16", "u16", 65535)
self.make_success_test("Integer u16 Octal Max", "0o177777:u16", "u16", 65535) self.make_success_test("Integer u16 Octal Max", "0o177777:u16", "u16", 65535)
self.make_success_test("Integer u16 Decimal Mid", "50000:u16", "u16", 50000) self.make_success_test("Integer u16 Decimal Mid", "50000:u16", "u16", 50000)
elif type_name == 'i32': elif type_name == 'i32':
self.make_success_test("Integer i32 Hex Sample", "0xABCD:i32", "i32", 43981) self.make_success_test("Integer i32 Hex Sample", "0xABCD:i32", "i32", 43981)
self.make_success_test("Integer i32 Binary Sample", self.make_success_test("Integer i32 Binary Sample",
"0b11110000:i32", "i32", 240) "0b11110000:i32", "i32", 240)
elif type_name == 'u32': elif type_name == 'u32':
self.make_success_test("Integer u32 Hex Max", "0xFFFFFFFF:u32", "u32", 4294967295) self.make_success_test("Integer u32 Hex Max", "0xFFFFFFFF:u32", "u32", 4294967295)
self.make_success_test("Integer u32 Binary Sample", self.make_success_test("Integer u32 Binary Sample",
"0b11111111000000001111111100000000:u32", "0b11111111000000001111111100000000:u32",
"u32", 4278255360) "u32", 4278255360)
self.make_success_test("Integer u32 Octal Max", self.make_success_test("Integer u32 Octal Max",
"0o37777777777:u32", "u32", 4294967295) "0o37777777777:u32", "u32", 4294967295)
self.make_success_test("Integer u32 Decimal Mid", "1000000:u32", "u32", 1000000) self.make_success_test("Integer u32 Decimal Mid", "1000000:u32", "u32", 1000000)
elif type_name == 'i64': elif type_name == 'i64':
self.make_success_test("Integer i64 Decimal Positive 42", "42:i64", "i64", 42) self.make_success_test("Integer i64 Decimal Positive 42", "42:i64", "i64", 42)
self.make_success_test("Integer i64 Hex 0xFF", "0xFF:i64", "i64", 255) self.make_success_test("Integer i64 Hex 0xFF", "0xFF:i64", "i64", 255)
self.make_success_test("Integer i64 Binary 0b1010", "0b1010:i64", "i64", 10) self.make_success_test("Integer i64 Binary 0b1010", "0b1010:i64", "i64", 10)
self.make_success_test("Integer i64 Octal 0o755", "0o755:i64", "i64", 493) self.make_success_test("Integer i64 Octal 0o755", "0o755:i64", "i64", 493)
elif type_name == 'u64': elif type_name == 'u64':
self.make_success_test("Integer u64 Hex Max", self.make_success_test("Integer u64 Hex Max",
"0xFFFFFFFFFFFFFFFF:u64", "0xFFFFFFFFFFFFFFFF:u64",
"u64", 18446744073709551615) "u64", 18446744073709551615)
self.make_success_test("Integer u64 Binary Sample", self.make_success_test("Integer u64 Binary Sample",
"0b1010101010101010:u64", "u64", 43690) "0b1010101010101010:u64", "u64", 43690)
self.make_success_test("Integer u64 Octal Sample", "0o7777:u64", "u64", 4095) self.make_success_test("Integer u64 Octal Sample", "0o7777:u64", "u64", 4095)
self.make_success_test("Integer u64 Decimal", "42:u64", "u64", 42) self.make_success_test("Integer u64 Decimal", "42:u64", "u64", 42)
def generate_underscore_tests(self): def generate_underscore_tests(self):
"""Generate tests for underscores in different bases.""" """Generate tests for underscores in different bases."""
self.make_success_test("Integer Hex With Underscores", self.make_success_test("Integer Hex With Underscores",
@ -245,34 +201,23 @@ class IntegerTestGenerator:
"0b1111_0000_1010_0101:i32", "i32", 61605) "0b1111_0000_1010_0101:i32", "i32", 61605)
self.make_success_test("Integer Octal With Underscores", self.make_success_test("Integer Octal With Underscores",
"0o7_7_7:i16", "i16", 511) "0o7_7_7:i16", "i16", 511)
def generate_all_tests(self) -> List[Dict[str, Any]]: def generate_all_tests(self) -> List[Dict[str, Any]]:
"""Generate all test cases.""" """Generate all test cases."""
# Basic tests # Basic tests
self.generate_basic_tests() self.generate_basic_tests()
# Default type (i64) comprehensive tests # Default type (i64) comprehensive tests
self.generate_default_base_tests() self.generate_default_base_tests()
self.generate_default_edge_cases() self.generate_default_edge_cases()
self.generate_default_error_tests() self.generate_default_error_tests()
# Tests for each specific type # Tests for each specific type
for type_name in ['i8', 'i16', 'i32', 'i64', 'u8', 'u16', 'u32', 'u64']: for type_name in ['i8', 'i16', 'i32', 'i64', 'u8', 'u16', 'u32', 'u64']:
self.generate_typed_tests(type_name) self.generate_typed_tests(type_name)
self.generate_special_typed_tests(type_name) self.generate_special_typed_tests(type_name)
# Additional edge cases # Additional edge cases
self.generate_underscore_tests() self.generate_underscore_tests()
return self.tests return self.tests
def generate_integer_literal_tests() -> List[Dict[str, Any]]:
"""
Main function to generate all integer literal test cases.
Returns:
List of test case dictionaries ready for serialization
"""
generator = IntegerTestGenerator()
return generator.generate_all_tests()

View File

@ -1,45 +0,0 @@
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, asdict
@dataclass
class Token:
type: str
value: Any
@dataclass
class Operation:
function: str
type: str
value: Any
@dataclass
class StackItem:
type: str
value: Any
@dataclass
class RuntimeError:
message: str
@dataclass
class TestCase:
name: str
code: str
tokens: List[Dict[str, Any]]
operations: Optional[List[Dict[str, Any]]] = None
stack_final: Optional[List[Dict[str, Any]]] = None
runtime_error: Optional[Dict[str, str]] = None
def to_dict(obj):
"""Convert dataclass to dict, removing None values."""
if obj is None:
return None
d = asdict(obj) if hasattr(obj, '__dataclass_fields__') else obj
return {k: v for k, v in d.items() if v is not None}