Setting up float and character tests
This commit is contained in:
parent
db14867474
commit
60925dab53
|
|
@ -10,6 +10,7 @@
|
||||||
- `u` uint64_t
|
- `u` uint64_t
|
||||||
- `z` size_t
|
- `z` size_t
|
||||||
- `f` double
|
- `f` double
|
||||||
|
- `n` unicode uint8_t\[4\] (Not Implemented)
|
||||||
- `s` string.h SlsStr
|
- `s` string.h SlsStr
|
||||||
- `t` lexer.h TokenType
|
- `t` lexer.h TokenType
|
||||||
- `a` lexer.h ArrayType
|
- `a` lexer.h ArrayType
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,11 @@ static SlsStr integer_value_should_be(size_t i, uint64_t should, uint64_t found)
|
||||||
return sls_format(SLS_STR("Token #%z integer value should be %i, but found %i"), i, should, found);
|
return sls_format(SLS_STR("Token #%z integer value should be %i, but found %i"), i, should, found);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SlsStr character_value_should_be(size_t i, uint8_t should, uint8_t found) {
|
||||||
|
return sls_format(SLS_STR("Token #%z integer value should be %i, but found %i"), i, should, found);
|
||||||
|
// return sls_format(SLS_STR("Token #%z character value should be '', but found ''"), i, should[0], found[0]);
|
||||||
|
}
|
||||||
|
|
||||||
static SlsStr float_value_should_be(size_t i, double should, double found) {
|
static SlsStr float_value_should_be(size_t i, double should, double found) {
|
||||||
return sls_format(SLS_STR("Token #%z float value should be %f, but found %f"), i, should, found);
|
return sls_format(SLS_STR("Token #%z float value should be %f, but found %f"), i, should, found);
|
||||||
}
|
}
|
||||||
|
|
@ -285,6 +290,18 @@ Boolean test_integer_value(LexerTest *test, LexerResult result, size_t i, TestIn
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Boolean test_character_value(LexerTest *test, LexerResult result, size_t i, uint8_t *value) {
|
||||||
|
static const TokenType token_type = TOKEN_INTEGER;
|
||||||
|
LexerTokenResult *head = get_token(result.result, i);
|
||||||
|
if (test_token_type(test, result, i, token_type)) {
|
||||||
|
return TRUE;
|
||||||
|
} if (head->result.integer_literal.value != *value) {
|
||||||
|
logic_fail_test(test, result, character_value_should_be(i + 1, *value, head->result.float_literal));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
Boolean test_float_value(LexerTest *test, LexerResult result, size_t i, float *value) {
|
Boolean test_float_value(LexerTest *test, LexerResult result, size_t i, float *value) {
|
||||||
static const TokenType token_type = TOKEN_FLOAT;
|
static const TokenType token_type = TOKEN_FLOAT;
|
||||||
LexerTokenResult *head = get_token(result.result, i);
|
LexerTokenResult *head = get_token(result.result, i);
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,17 @@ from .base_tests import BaseTestGenerator
|
||||||
class CharTestGenerator(BaseTestGenerator):
|
class CharTestGenerator(BaseTestGenerator):
|
||||||
"""Generate test cases for character literals."""
|
"""Generate test cases for character literals."""
|
||||||
|
|
||||||
|
ENABLE_UNICODE = False
|
||||||
|
|
||||||
# Common escape sequences
|
# Common escape sequences
|
||||||
ESCAPE_SEQUENCES = {
|
ESCAPE_SEQUENCES = {
|
||||||
'\\n': '\n', # Newline
|
("Newline", '\\n', '\n',), # Newline
|
||||||
'\\r': '\r', # Carriage return
|
("Carriage return", '\\r', '\r',), # Carriage return
|
||||||
'\\t': '\t', # Tab
|
("Tab", '\\t', '\t',), # Tab
|
||||||
'\\\\': '\\', # Backslash
|
("Backslash", '\\\\', '\\',), # Backslash
|
||||||
'\\"': '"', # Double quote
|
("Double quote", '\\\\"', '"',), # Double quote
|
||||||
"\\'": "'", # Single quote
|
("Single quote", "\\'", "'",), # Single quote
|
||||||
'\\0': '\0', # Null character
|
("Null character", '\\0', '\0',), # Null character
|
||||||
}
|
}
|
||||||
|
|
||||||
# Hexadecimal escape examples
|
# Hexadecimal escape examples
|
||||||
|
|
@ -77,8 +79,8 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
def generate_escape_sequence_tests(self):
|
def generate_escape_sequence_tests(self):
|
||||||
"""Generate tests for escape sequences."""
|
"""Generate tests for escape sequences."""
|
||||||
# Standard escape sequences
|
# Standard escape sequences
|
||||||
for escape_str, char_val in self.ESCAPE_SEQUENCES.items():
|
for escape_name, escape_str, char_val in self.ESCAPE_SEQUENCES:
|
||||||
name = f"Char Escape {escape_str}"
|
name = f"Char Escape {escape_name}"
|
||||||
code = f"'{escape_str}'"
|
code = f"'{escape_str}'"
|
||||||
self.make_success_test(name, code, "char", char_val)
|
self.make_success_test(name, code, "char", char_val)
|
||||||
|
|
||||||
|
|
@ -88,7 +90,7 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
("Carriage Return", "'\\r'", '\r'),
|
("Carriage Return", "'\\r'", '\r'),
|
||||||
("Tab", "'\\t'", '\t'),
|
("Tab", "'\\t'", '\t'),
|
||||||
("Backslash", "'\\\\'", '\\'),
|
("Backslash", "'\\\\'", '\\'),
|
||||||
("Double Quote", "'\\\"'", '"'),
|
("Double Quote", "'\\\\\"'", '"'),
|
||||||
("Single Quote", "'\\''", "'"),
|
("Single Quote", "'\\''", "'"),
|
||||||
("Null", "'\\0'", '\0'),
|
("Null", "'\\0'", '\0'),
|
||||||
]
|
]
|
||||||
|
|
@ -163,8 +165,8 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
self.make_success_test("Char With Leading Whitespace", " 'A'", "char", 'A')
|
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 Trailing Whitespace", "'A' ", "char", 'A')
|
||||||
self.make_success_test("Char With Both 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 Tab Before", "\\t'B'", "char", 'B')
|
||||||
self.make_success_test("Char Newline Before", "\n'C'", "char", 'C')
|
self.make_success_test("Char Newline Before", "\\n'C'", "char", 'C')
|
||||||
|
|
||||||
def generate_error_tests(self):
|
def generate_error_tests(self):
|
||||||
"""Generate error test cases."""
|
"""Generate error test cases."""
|
||||||
|
|
@ -185,7 +187,7 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
|
|
||||||
# Unescaped newline
|
# Unescaped newline
|
||||||
self.make_error_test("Char Unescaped Newline",
|
self.make_error_test("Char Unescaped Newline",
|
||||||
"'\n'",
|
"'\\n'",
|
||||||
"Invalid character literal: unescaped newline in character literal.")
|
"Invalid character literal: unescaped newline in character literal.")
|
||||||
|
|
||||||
# Invalid escape sequence
|
# Invalid escape sequence
|
||||||
|
|
@ -204,42 +206,43 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
|
|
||||||
# Invalid hex digits
|
# Invalid hex digits
|
||||||
self.make_error_test("Char Hex Invalid Digit",
|
self.make_error_test("Char Hex Invalid Digit",
|
||||||
"'\\xGG'",
|
"'\\\\xGG'",
|
||||||
"Invalid character literal: invalid hexadecimal digit 'G'.")
|
"Invalid character literal: invalid hexadecimal digit 'G'.")
|
||||||
|
|
||||||
# Invalid Unicode escape (no braces)
|
if self.ENABLE_UNICODE:
|
||||||
self.make_error_test("Char Unicode No Braces",
|
# Invalid Unicode escape (no braces)
|
||||||
"'\\u1F600'",
|
self.make_error_test("Char Unicode No Braces",
|
||||||
"Invalid character literal: Unicode escape must use braces \\u{...}.")
|
"'\\u1F600'",
|
||||||
|
"Invalid character literal: Unicode escape must use braces \\u{...}.")
|
||||||
# Invalid Unicode escape (empty)
|
|
||||||
self.make_error_test("Char Unicode Empty",
|
# Invalid Unicode escape (empty)
|
||||||
"'\\u{}'",
|
self.make_error_test("Char Unicode Empty",
|
||||||
"Invalid character literal: empty Unicode escape sequence.")
|
"'\\u{}'",
|
||||||
|
"Invalid character literal: empty Unicode escape sequence.")
|
||||||
# Invalid Unicode escape (too many digits)
|
|
||||||
self.make_error_test("Char Unicode Too Many Digits",
|
# Invalid Unicode escape (too many digits)
|
||||||
"'\\u{1234567}'",
|
self.make_error_test("Char Unicode Too Many Digits",
|
||||||
"Invalid character literal: Unicode escape sequence too long (max 6 hex 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",
|
# Invalid Unicode escape (invalid code point)
|
||||||
"'\\u{D800}'",
|
self.make_error_test("Char Unicode Invalid Code Point",
|
||||||
"Invalid character literal: invalid Unicode code point (surrogate range).")
|
"'\\u{D800}'",
|
||||||
|
"Invalid character literal: invalid Unicode code point (surrogate range).")
|
||||||
self.make_error_test("Char Unicode Out Of Range",
|
|
||||||
"'\\u{110000}'",
|
self.make_error_test("Char Unicode Out Of Range",
|
||||||
"Invalid character literal: Unicode code point out of range (max 0x10FFFF).")
|
"'\\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",
|
# Invalid Unicode escape (non-hex digits)
|
||||||
"'\\u{GGGG}'",
|
self.make_error_test("Char Unicode Invalid Hex",
|
||||||
"Invalid character literal: invalid hexadecimal digit 'G' in Unicode escape.")
|
"'\\u{GGGG}'",
|
||||||
|
"Invalid character literal: invalid hexadecimal digit 'G' in Unicode escape.")
|
||||||
# Unclosed Unicode escape
|
|
||||||
self.make_error_test("Char Unicode Unclosed",
|
# Unclosed Unicode escape
|
||||||
"'\\u{1F600'",
|
self.make_error_test("Char Unicode Unclosed",
|
||||||
"Invalid character literal: unclosed Unicode escape sequence.")
|
"'\\u{1F600'",
|
||||||
|
"Invalid character literal: unclosed Unicode escape sequence.")
|
||||||
|
|
||||||
# Double quotes instead of single
|
# Double quotes instead of single
|
||||||
self.make_error_test("Char Double Quotes",
|
self.make_error_test("Char Double Quotes",
|
||||||
|
|
@ -263,29 +266,30 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
self.make_success_test("Char Extended ASCII Lower", "'\\x80'", "char", '\x80')
|
self.make_success_test("Char Extended ASCII Lower", "'\\x80'", "char", '\x80')
|
||||||
self.make_success_test("Char Extended ASCII Upper", "'\\xFF'", "char", '\xFF')
|
self.make_success_test("Char Extended ASCII Upper", "'\\xFF'", "char", '\xFF')
|
||||||
|
|
||||||
# Zero-width characters
|
if self.ENABLE_UNICODE:
|
||||||
self.make_success_test("Char Zero Width Space", "'\\u{200B}'", "char", '\u200B')
|
# Zero-width characters
|
||||||
self.make_success_test("Char Zero Width Joiner", "'\\u{200D}'", "char", '\u200D')
|
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')
|
# 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')
|
# 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')
|
# Low Unicode values
|
||||||
self.make_success_test("Char Unicode One", "'\\u{1}'", "char", '\x01')
|
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')
|
# High Unicode values (but valid)
|
||||||
|
self.make_success_test("Char Unicode High Valid", "'\\u{10FFFF}'", "char", '\U0010FFFF')
|
||||||
|
|
||||||
# Backslash before valid character
|
# Backslash before valid character
|
||||||
self.make_success_test("Char Backslash Literal", "'\\\\'", "char", '\\')
|
self.make_success_test("Char Backslash Literal", "'\\\\'", "char", '\\')
|
||||||
|
|
||||||
# Quote escaping
|
# Quote escaping
|
||||||
self.make_success_test("Char Single Quote Escaped", "'\\''", "char", "'")
|
self.make_success_test("Char Single Quote Escaped", "'\\''", "char", "'")
|
||||||
self.make_success_test("Char Double Quote Escaped", "'\\\"'", "char", '"')
|
# self.make_success_test("Char Double Quote Escaped", "'\\\"'", "char", '"')
|
||||||
|
|
||||||
def generate_case_sensitivity_tests(self):
|
def generate_case_sensitivity_tests(self):
|
||||||
"""Generate tests for case sensitivity in escape sequences."""
|
"""Generate tests for case sensitivity in escape sequences."""
|
||||||
|
|
@ -297,13 +301,14 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
self.make_success_test("Char Hex Digits Lowercase", "'\\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')
|
self.make_success_test("Char Hex Digits Mixed", "'\\xAb'", "char", '\xAB')
|
||||||
|
|
||||||
# Unicode escapes - lowercase u
|
if self.ENABLE_UNICODE:
|
||||||
self.make_success_test("Char Unicode Lowercase u", "'\\u{41}'", "char", 'A')
|
# 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", '😀')
|
# Unicode hex digits - both cases
|
||||||
self.make_success_test("Char Unicode Hex Lowercase", "'\\u{1f600}'", "char", '😀')
|
self.make_success_test("Char Unicode Hex Uppercase", "'\\u{1F600}'", "char", '😀')
|
||||||
self.make_success_test("Char Unicode Hex Mixed", "'\\u{1F60a}'", "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]]:
|
def generate_all_tests(self) -> List[Dict[str, Any]]:
|
||||||
"""Generate all character literal test cases."""
|
"""Generate all character literal test cases."""
|
||||||
|
|
@ -316,11 +321,12 @@ class CharTestGenerator(BaseTestGenerator):
|
||||||
# Hexadecimal escapes
|
# Hexadecimal escapes
|
||||||
self.generate_hexadecimal_escape_tests()
|
self.generate_hexadecimal_escape_tests()
|
||||||
|
|
||||||
# Unicode escapes
|
if self.ENABLE_UNICODE:
|
||||||
self.generate_unicode_escape_tests()
|
# Unicode escapes
|
||||||
|
self.generate_unicode_escape_tests()
|
||||||
# Direct Unicode characters
|
|
||||||
self.generate_unicode_direct_tests()
|
# Direct Unicode characters
|
||||||
|
self.generate_unicode_direct_tests()
|
||||||
|
|
||||||
# Whitespace handling
|
# Whitespace handling
|
||||||
self.generate_whitespace_tests()
|
self.generate_whitespace_tests()
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ class FloatTestGenerator(BaseTestGenerator):
|
||||||
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']:
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,12 @@ def _token_to_c_call(token: dict, idx_var="i") -> str:
|
||||||
return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U16, {value}}})'
|
return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U16, {value}}})'
|
||||||
elif ttype == "u8":
|
elif ttype == "u8":
|
||||||
return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U8, {value}}})'
|
return f'test_integer_value(&test, result, {idx_var}++, &(TestIntegerValue){{INTEGER_U8, {value}}})'
|
||||||
|
elif ttype == "f64":
|
||||||
|
return f'test_double_value(&test, result, {idx_var}++, &(double){{{value}}})'
|
||||||
|
elif ttype == "f32":
|
||||||
|
return f'test_float_value(&test, result, {idx_var}++, &(float){{{value}}})'
|
||||||
|
elif ttype == "char":
|
||||||
|
return f'test_character_value(&test, result, {idx_var}++, &(uint8_t){{{ord(value)}}})' # type: ignore
|
||||||
elif ttype == "identifier":
|
elif ttype == "identifier":
|
||||||
return f'test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{FALSE, {len(value)}, "{value}"}})' # type: ignore
|
return f'test_identifier_value(&test, result, {idx_var}++, &(TestIdentifierValue){{FALSE, {len(value)}, "{value}"}})' # type: ignore
|
||||||
elif ttype == "identifier_literal":
|
elif ttype == "identifier_literal":
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue