🐐 SCRIPTA
This commit is contained in:
150
tests.py
150
tests.py
@@ -655,6 +655,9 @@ error_tests = [
|
||||
("SENATVS(I)", CentvrionError), # SENATVS requires booleans
|
||||
("SENATVS(VERITAS, I)", CentvrionError), # SENATVS mixed types
|
||||
("SENATVS([I, II, III])", CentvrionError), # SENATVS array of non-bools
|
||||
('LEGE("x.txt")', CentvrionError), # SCRIPTA required for LEGE
|
||||
('SCRIBE("x.txt", "hi")', CentvrionError), # SCRIPTA required for SCRIBE
|
||||
('ADIVNGE("x.txt", "hi")', CentvrionError), # SCRIPTA required for ADIVNGE
|
||||
("DESIGNA x VT I\nINVOCA x ()", CentvrionError), # invoking a non-function
|
||||
("SI I TVNC { DESIGNA r VT I }", CentvrionError), # non-bool SI condition: int
|
||||
("IIIS", CentvrionError), # fraction without FRACTIO module
|
||||
@@ -2329,5 +2332,152 @@ class TestDormi(unittest.TestCase):
|
||||
os.unlink(tmp_bin_path)
|
||||
|
||||
|
||||
class TestScripta(unittest.TestCase):
|
||||
def _run_scripta(self, source):
|
||||
lexer = Lexer().get_lexer()
|
||||
tokens = lexer.lex(source + "\n")
|
||||
program = Parser().parse(tokens)
|
||||
# printer round-trip
|
||||
new_text = program.print()
|
||||
new_tokens = Lexer().get_lexer().lex(new_text + "\n")
|
||||
new_nodes = Parser().parse(new_tokens)
|
||||
self.assertEqual(program, new_nodes, f"Printer test\n{source}\n{new_text}")
|
||||
return program
|
||||
|
||||
def _compile_and_run(self, program):
|
||||
c_source = compile_program(program)
|
||||
with tempfile.NamedTemporaryFile(suffix=".c", delete=False, mode="w") as tmp_c:
|
||||
tmp_c.write(c_source)
|
||||
tmp_c_path = tmp_c.name
|
||||
with tempfile.NamedTemporaryFile(suffix="", delete=False) as tmp_bin:
|
||||
tmp_bin_path = tmp_bin.name
|
||||
try:
|
||||
subprocess.run(
|
||||
["gcc", "-O2", tmp_c_path, _RUNTIME_C, "-o", tmp_bin_path],
|
||||
check=True, capture_output=True,
|
||||
)
|
||||
proc = subprocess.run([tmp_bin_path], capture_output=True, text=True)
|
||||
self.assertEqual(proc.returncode, 0, f"Compiler binary exited non-zero:\n{proc.stderr}")
|
||||
return proc.stdout
|
||||
finally:
|
||||
os.unlink(tmp_c_path)
|
||||
os.unlink(tmp_bin_path)
|
||||
|
||||
def test_scribe_and_lege(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE MVNDE")\nDICE(LEGE("{path}"))'
|
||||
program = self._run_scripta(source)
|
||||
captured = StringIO()
|
||||
with patch("sys.stdout", captured):
|
||||
program.eval()
|
||||
self.assertEqual(captured.getvalue(), "SALVE MVNDE\n")
|
||||
with open(path) as f:
|
||||
self.assertEqual(f.read(), "SALVE MVNDE")
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
|
||||
def test_scribe_and_lege_compiled(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE MVNDE")\nDICE(LEGE("{path}"))'
|
||||
program = self._run_scripta(source)
|
||||
output = self._compile_and_run(program)
|
||||
self.assertEqual(output, "SALVE MVNDE\n")
|
||||
with open(path) as f:
|
||||
self.assertEqual(f.read(), "SALVE MVNDE")
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
|
||||
def test_adivnge(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE")\nADIVNGE("{path}", " MVNDE")\nDICE(LEGE("{path}"))'
|
||||
program = self._run_scripta(source)
|
||||
captured = StringIO()
|
||||
with patch("sys.stdout", captured):
|
||||
program.eval()
|
||||
self.assertEqual(captured.getvalue(), "SALVE MVNDE\n")
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
|
||||
def test_adivnge_compiled(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nSCRIBE("{path}", "SALVE")\nADIVNGE("{path}", " MVNDE")\nDICE(LEGE("{path}"))'
|
||||
program = self._run_scripta(source)
|
||||
output = self._compile_and_run(program)
|
||||
self.assertEqual(output, "SALVE MVNDE\n")
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
|
||||
def test_scribe_overwrites(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nSCRIBE("{path}", "first")\nSCRIBE("{path}", "second")\nLEGE("{path}")'
|
||||
program = self._run_scripta(source)
|
||||
result = program.eval()
|
||||
self.assertEqual(result, ValStr("second"))
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
|
||||
def test_lege_empty_file(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False, mode="w") as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nLEGE("{path}")'
|
||||
program = self._run_scripta(source)
|
||||
result = program.eval()
|
||||
self.assertEqual(result, ValStr(""))
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_lege_preexisting_content(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False, mode="w") as f:
|
||||
f.write("hello from python")
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nLEGE("{path}")'
|
||||
program = self._run_scripta(source)
|
||||
result = program.eval()
|
||||
self.assertEqual(result, ValStr("hello from python"))
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
def test_scribe_returns_nullus(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nSCRIBE("{path}", "x")'
|
||||
program = self._run_scripta(source)
|
||||
result = program.eval()
|
||||
self.assertEqual(result, ValNul())
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
|
||||
def test_adivnge_returns_nullus(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
|
||||
path = f.name
|
||||
try:
|
||||
source = f'CVM SCRIPTA\nADIVNGE("{path}", "x")'
|
||||
program = self._run_scripta(source)
|
||||
result = program.eval()
|
||||
self.assertEqual(result, ValNul())
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user