mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-24 00:44:21 +00:00
171 lines
4.6 KiB
Python
171 lines
4.6 KiB
Python
import pytest
|
|
from isledecomp.parser.parser import (
|
|
ReaderState,
|
|
DecompParser,
|
|
)
|
|
from isledecomp.parser.util import DecompMarker
|
|
from isledecomp.parser.error import ParserError
|
|
|
|
|
|
@pytest.fixture
|
|
def parser():
|
|
return DecompParser()
|
|
|
|
|
|
@pytest.mark.skip(reason="todo")
|
|
def test_missing_sig(parser):
|
|
"""Bad syntax: function signature is missing"""
|
|
parser.read_lines(["// FUNCTION: TEST 0x1234", "{"])
|
|
assert parser.state == ReaderState.IN_FUNC
|
|
assert len(parser.alerts) == 1
|
|
parser.read_line("}")
|
|
assert len(parser.functions) == 1
|
|
assert parser.functions[0] != "{"
|
|
|
|
|
|
def test_not_exact_syntax(parser):
|
|
"""Alert to inexact syntax right here in the parser instead of kicking it downstream.
|
|
Doing this means we don't have to save the actual text."""
|
|
parser.read_line("// function: test 1234")
|
|
assert len(parser.alerts) == 1
|
|
assert parser.alerts[0].code == ParserError.BAD_DECOMP_MARKER
|
|
|
|
|
|
def test_invalid_marker(parser):
|
|
"""We matched a decomp marker, but it's not one we care about"""
|
|
parser.read_line("// BANANA: TEST 0x1234")
|
|
assert parser.state == ReaderState.SEARCH
|
|
|
|
assert len(parser.alerts) == 1
|
|
assert parser.alerts[0].code == ParserError.BOGUS_MARKER
|
|
|
|
|
|
def test_unexpected_marker(parser):
|
|
parser.read_lines(
|
|
[
|
|
"// FUNCTION: TEST 0x1234",
|
|
"// GLOBAL: TEST 0x5000",
|
|
]
|
|
)
|
|
assert parser.state == ReaderState.SEARCH
|
|
assert len(parser.alerts) == 1
|
|
assert parser.alerts[0].code == ParserError.INCOMPATIBLE_MARKER
|
|
|
|
|
|
def test_variable(parser):
|
|
parser.read_lines(
|
|
[
|
|
"// GLOBAL: HELLO 0x1234",
|
|
"int g_value = 5;",
|
|
]
|
|
)
|
|
assert len(parser.variables) == 1
|
|
|
|
|
|
def test_synthetic_plus_marker(parser):
|
|
"""Should fail with error and not log the synthetic"""
|
|
parser.read_lines(
|
|
[
|
|
"// SYNTHETIC: HEY 0x555",
|
|
"// FUNCTION: HOWDY 0x1234",
|
|
]
|
|
)
|
|
assert len(parser.functions) == 0
|
|
assert len(parser.alerts) == 1
|
|
assert parser.alerts[0].code == ParserError.INCOMPATIBLE_MARKER
|
|
|
|
|
|
def test_different_markers_different_module(parser):
|
|
"""Does it make any sense for a function to be a stub in one module,
|
|
but not in another? I don't know. But it's no problem for us."""
|
|
parser.read_lines(
|
|
[
|
|
"// FUNCTION: HOWDY 0x1234",
|
|
"// STUB: SUP 0x5555",
|
|
"void interesting_function() {",
|
|
"}",
|
|
]
|
|
)
|
|
|
|
assert len(parser.alerts) == 0
|
|
assert len(parser.functions) == 2
|
|
|
|
|
|
def test_different_markers_same_module(parser):
|
|
"""Now, if something is a regular function but then a stub,
|
|
what do we say about that?"""
|
|
parser.read_lines(
|
|
[
|
|
"// FUNCTION: HOWDY 0x1234",
|
|
"// STUB: HOWDY 0x5555",
|
|
"void interesting_function() {",
|
|
"}",
|
|
]
|
|
)
|
|
|
|
# Use first marker declaration, don't replace
|
|
assert len(parser.functions) == 1
|
|
assert parser.functions[0].is_stub is False
|
|
|
|
# Should alert to this
|
|
assert len(parser.alerts) == 1
|
|
assert parser.alerts[0].code == ParserError.DUPLICATE_MODULE
|
|
|
|
|
|
def test_unexpected_synthetic(parser):
|
|
"""FUNCTION then SYNTHETIC should fail to report either one"""
|
|
parser.read_lines(
|
|
[
|
|
"// FUNCTION: HOWDY 0x1234",
|
|
"// SYNTHETIC: HOWDY 0x5555",
|
|
"void interesting_function() {",
|
|
"}",
|
|
]
|
|
)
|
|
|
|
assert parser.state == ReaderState.SEARCH
|
|
assert len(parser.functions) == 0
|
|
assert len(parser.alerts) == 1
|
|
assert parser.alerts[0].code == ParserError.INCOMPATIBLE_MARKER
|
|
|
|
|
|
@pytest.mark.skip(reason="not implemented yet")
|
|
def test_duplicate_offset(parser):
|
|
"""Repeating the same module/offset in the same file is probably a typo"""
|
|
parser.read_lines(
|
|
[
|
|
"// GLOBAL: HELLO 0x1234",
|
|
"int x = 1;",
|
|
"// GLOBAL: HELLO 0x1234",
|
|
"int y = 2;",
|
|
]
|
|
)
|
|
|
|
assert len(parser.alerts) == 1
|
|
assert parser.alerts[0].code == ParserError.DUPLICATE_OFFSET
|
|
|
|
|
|
def test_multiple_variables(parser):
|
|
"""Theoretically the same global variable can appear in multiple modules"""
|
|
parser.read_lines(
|
|
[
|
|
"// GLOBAL: HELLO 0x1234",
|
|
"// GLOBAL: WUZZUP 0x555",
|
|
"const char *g_greeting;",
|
|
]
|
|
)
|
|
assert len(parser.alerts) == 0
|
|
assert len(parser.variables) == 2
|
|
|
|
|
|
def test_multiple_vtables(parser):
|
|
parser.read_lines(
|
|
[
|
|
"// VTABLE: HELLO 0x1234",
|
|
"// VTABLE: TEST 0x5432",
|
|
"class MxString : public MxCore {",
|
|
]
|
|
)
|
|
assert len(parser.alerts) == 0
|
|
assert len(parser.vtables) == 2
|