Skip to content

Commit

Permalink
[tests] Rewrite entire test suite using pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
iiPythonx committed Mar 10, 2024
1 parent a223c72 commit f477438
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 131 deletions.
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,9 @@ path = "src/xpp/__init__.py"

[tool.hatch.build.targets.wheel]
packages = ["src/xpp", "src/caffeine"]

[tool.pytest.ini_options]
addopts = [
"--import-mode=importlib",
]
pythonpath = "src"
90 changes: 58 additions & 32 deletions src/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,61 @@
# Copyright (c) 2024 iiPython

# Modules
from rich import print as rp
from rich.table import Table
from typing import Any, List
from types import FunctionType

# Load xpp
from xpp import Interpreter
from xpp.core.sections import Section

# Fake out the x++ interpreter
inter = Interpreter("_tests.xpp", [])
section = Section("_tests.main", "", [], 1, [])
section.initialize(inter.memory)
inter.stack.append(section)

# Start running x++ code
def start_tests(name: str, tests: list) -> None:
table = Table(title = f"x++ {name} Test Results")
[table.add_column(c) for c in ["Expression", "x++", "Expected", "Result"]]
for test in tests:
try:
resp = inter.execute(test[0])

except Exception as e:
resp = type(e).__name__

isf = isinstance(test[1], FunctionType)
table.add_row(
str(test[0]),
str(resp),
str(test[1] if not isf else "<Function>"),
"[green]✓ PASS[/]" if (test[1]() if isf else (resp == test[1])) else "[red]✕ FAIL[/]"
)

rp(table)
# Fake classes
class FakeDatastore():
def __init__(self, value: Any) -> None:
self.raw, self.value = value, value
self.deleted = False

def set(self, value: Any) -> None:
self.value = value

def delete(self) -> None:
self.deleted = True

def refresh(self) -> None:
if isinstance(self.value, bool):
self.value = not self.value

class FakeSection():
def __init__(self) -> None:
self.active = True
self.return_value = []

class FakeInterpreter():
def __init__(self) -> None:
self.stack = [FakeSection()]
self.recently_executed = []

def execute(self, data: Any) -> None:
if data == "_RAISE":
raise ValueError

self.recently_executed.append(data)

def run_section(self, section: str, args: List[Any]) -> List[Any]:
return args

class FakeMemory():
def __init__(self) -> None:
self.interpreter = FakeInterpreter()
self.variables = {}

# Initialization
global_mem = FakeMemory()

# Handle running
def run(function: FunctionType, args: List[Any]) -> Any:
args = [
FakeDatastore(a) if not isinstance(a, FakeDatastore) else a
for a in args
]
return function(global_mem, args)

def full_evaluate(function: FunctionType, args: List[Any], expect: Any) -> None:
output = FakeDatastore("?")
assert run(function, args + [output]) == expect
assert output.value == expect
21 changes: 0 additions & 21 deletions src/tests/test_compare.py

This file was deleted.

37 changes: 0 additions & 37 deletions src/tests/test_file.py

This file was deleted.

20 changes: 20 additions & 0 deletions src/tests/test_fileio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) 2024 iiPython

# Modules
import os
from pathlib import Path

from xpp.modules.ops.stdlib.fileio import XOperators

from . import run

# Begin test definitions
def test_load():
Path("_xpp.test").write_text("hello, world!")
assert run(XOperators.load, ["_xpp.test"]) == "hello, world!"
os.remove("_xpp.test")

def test_save():
run(XOperators.save, ["_xpp.test", "hello, world!"])
assert Path("_xpp.test").read_text() == "hello, world!"
os.remove("_xpp.test")
55 changes: 55 additions & 0 deletions src/tests/test_internal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) 2024 iiPython

# Modules
from xpp.modules.ops.stdlib.internal import XOperators

from . import run, global_mem, FakeDatastore

# Begin test definitions
def test_evl():
run(XOperators.evl, ["mem.variables['_test'] = True"])
assert global_mem.variables.get("_test") is True

def test_if():
run(XOperators.if_, [True, "_1"])
assert global_mem.interpreter.recently_executed[-1] == "_1"
run(XOperators.if_, [False, "_2"])
assert global_mem.interpreter.recently_executed[-1] == "_1"
run(XOperators.if_, [False, "_3", True, "_4"])
assert global_mem.interpreter.recently_executed[-1] == "_4"
run(XOperators.if_, [True, "_5", False, "_6"])
assert global_mem.interpreter.recently_executed[-1] == "_5"

def test_jmp():
assert run(XOperators.jmp, ["_", "a", 1, .25, True]) == ["a", 1, .25, True]

def test_rem():
variable = FakeDatastore("hello world")
run(XOperators.rem, [variable])
assert variable.deleted is True

def test_ret():
run(XOperators.ret, [1, 2])
assert global_mem.interpreter.stack[-1].active is False
assert global_mem.interpreter.stack[-1].return_value == [1, 2]

def test_rep():
run(XOperators.rep, [5, "ooga booga"])
assert global_mem.interpreter.recently_executed[-5:] == ["ooga booga"] * 5

def test_try():
run(XOperators.try_, ["_RAISE"])
assert global_mem.interpreter.recently_executed[-1] != "_RAISE"

run(XOperators.try_, ["_RAISE", "_try"])
assert global_mem.interpreter.recently_executed[-1] == "_try"

def test_var():
variable = FakeDatastore(None)
run(XOperators.var, [variable, "hello world"])
assert variable.value == "hello world" and variable.raw is None

def test_whl():
variable = FakeDatastore(True)
run(XOperators.whl, [variable, "whip and nae nae"])
assert variable.value is False and global_mem.interpreter.recently_executed[-1] == "whip and nae nae"
77 changes: 36 additions & 41 deletions src/tests/test_math.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,38 @@
# Copyright 2023-2024 iiPython
# Copyright (c) 2024 iiPython

# Modules
import sys
import pathlib
sys.path.insert(1, str(pathlib.Path(__file__).parent.parent.resolve()))

# Start testing
from tests import start_tests
start_tests("Math", [

# Addition testing
("add 2 3", 5),
("add 0.1 0.2", .1 + .2),
("add 0.25 (add 1 0.5)", 1.75),
("add 2 (8 + 10)", 20),
("add 1 (.1 + .2 + .3 + .4)", 2),
("add (7 + 4 + (2 + (5 + 2))) (8 + 9 + 2)", 39),

# Subtraction testing
("sub 2 3", -1),
("sub 0.1 0.2", -.1),
("sub 0.25 (sub 1 0.5)", -.25),
("sub 2 (8 - 10)", 4),
("sub 1 (.1 - .2 - .3 - .4)", 1.8),
("sub (7 - 4 - (2 - (5 - 2))) (8 - 9 - 2)", 7),

# Multiplication testing
("mul 2 3", 6),
("mul 0.1 0.2", .1 * .2),
("mul 0.25 (mul 1 0.5)", .125),
("mul 2 (8 * 10)", 160),
("mul 1 (.1 * .2 * .3 * .4)", .1 * .2 * .3 * .4),
("mul (7 * 4 * (2 * (5 * 2))) (8 * 9 * 2)", 80640),

# Division testing
("div 2 3", 2 / 3),
("div 0.1 0.2", .1 / .2),
("div 0.25 (div 1 0.5)", .125),
("div 2 (8 / 10)", 2.5),
("div 1 (.1 / .2 / .3 / .4)", .24),
("div (7 / 4 / (2 / (5 / 2))) (8 / 9 / 2)", 4.921875),
])
from xpp.modules.ops.stdlib.math import XOperators

from . import run, full_evaluate

# Begin test definitions
def test_add():
full_evaluate(XOperators.add, [1, 2, 3], 6)

def test_dec():
full_evaluate(XOperators.dec, [5], 4)

def test_div():
full_evaluate(XOperators.div, [1, 2], .5)

def test_inc():
full_evaluate(XOperators.inc, [5], 6)

def test_mul():
full_evaluate(XOperators.mul, [5, 3], 15)

def test_pow():
full_evaluate(XOperators.pow, [5, 2], 25)

def test_rnd():
full_evaluate(XOperators.rnd, [0.3], 0)
full_evaluate(XOperators.rnd, [0.7], 1)
full_evaluate(XOperators.rnd, [0.5666, 2], .57)
full_evaluate(XOperators.rnd, [0.203, 3], .203)

def test_rng():
assert isinstance(run(XOperators.rng, [1, 5]), int)
full_evaluate(XOperators.rng, [1, 1], 1)

def test_sub():
full_evaluate(XOperators.sub, [1, 2], -1)
32 changes: 32 additions & 0 deletions src/tests/test_objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (c) 2024 iiPython

# Modules
from xpp.modules.ops.stdlib.objects import XOperators

from . import run, full_evaluate, FakeDatastore

# Begin test definitions
def test_new():
assert isinstance(run(XOperators.new, ["list"]), list)
assert isinstance(run(XOperators.new, ["dict"]), dict)

full_evaluate(XOperators.new, ["list"], [])
full_evaluate(XOperators.new, ["dict"], {})

def test_psh():
variable = FakeDatastore([1, 2])
run(XOperators.psh, [variable, 3])
assert variable.value == [1, 2, 3]

def test_pop():
full_evaluate(XOperators.pop, [[1, 2, 3]], 3)

def test_get():
full_evaluate(XOperators.get, [{"a": 5}, "a"], 5)

def test_set():
variable = FakeDatastore({"a": 5})
assert variable.value["a"] == 5
run(XOperators.set_, [variable, "a", 6])
assert variable.value["a"] == 6

34 changes: 34 additions & 0 deletions src/tests/test_strman.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) 2024 iiPython

# Modules
from xpp.modules.ops.stdlib.strman import XOperators

from . import run, full_evaluate

# Begin test definitions
def test_chr():
full_evaluate(XOperators.chr_, ["hello", 0], "h")
full_evaluate(XOperators.chr_, ["hello", 0, 2], "hel")

def test_flt():
full_evaluate(XOperators.flt_, ["0.5"], 0.5)
full_evaluate(XOperators.flt_, ["-0.5"], -0.5)

def test_idx():
full_evaluate(XOperators.idx, ["hello world", "world"], 6)

def test_int():
full_evaluate(XOperators.int_, ["5"], 5)

def test_len():
full_evaluate(XOperators.len_, ["hello"], 5)

def test_lwr():
full_evaluate(XOperators.lwr, ["HELLO"], "hello")

def test_str():
assert run(XOperators.str_, [1]) == "1"
assert run(XOperators.str_, [0.5]) == "0.5"

def test_upr():
full_evaluate(XOperators.upr, ["hello"], "HELLO")

0 comments on commit f477438

Please sign in to comment.