CC:T final tests migrated

This commit is contained in:
neumond 2023-11-20 01:07:27 +03:00
parent b719fde825
commit f1e4a14425
12 changed files with 331 additions and 158 deletions

View file

@ -59,6 +59,8 @@ def protocol(send, sess_cls=sess.CCSession, oc=False):
sess.on_task_result(next(msg), next(msg))
elif action == b'C':
sess.throw_keyboard_interrupt()
elif action == b'D': # disconnection
return
else:
send(PROTO_ERROR)
return
@ -88,6 +90,13 @@ class CCApplication(web.Application):
if mustquit:
break
if not mustquit: # sudden disconnect
try:
pgen.send(b'D')
except StopIteration:
pass
return ws
async def tcp(self, reader, writer):
@ -195,7 +204,10 @@ def main():
while True:
m = yield
write_frame(b'R', m)
p.send(m)
try:
p.send(m)
except StopIteration as e:
return e.value
return pgen()

View file

@ -1,139 +0,0 @@
from contextlib import contextmanager
from time import monotonic
from types import FunctionType
from cc import eval_lua
@contextmanager
def assert_raises(etype, message=None):
try:
yield
except Exception as e:
assert isinstance(e, etype), repr(e)
if message is not None:
assert e.args == (message, )
else:
raise AssertionError(f'Exception of type {etype} was not raised')
@contextmanager
def assert_takes_time(at_least, at_most):
t = monotonic()
yield
dt = monotonic() - t
# print(at_least, '<=', dt, '<=', at_most)
assert at_least <= dt <= at_most
class AnyInstanceOf:
def __init__(self, cls):
self.c = cls
def __eq__(self, other):
return isinstance(other, self.c)
def step(text):
input(f'{text} [enter]')
def get_object_table(objname):
rp = eval_lua(f"""
local r = {{}}
for k in pairs({objname}) do
local t = type({objname}[k])
if r[t] == nil then r[t] = {{}} end
if t == 'number' or t == 'boolean' or t == 'string' then
r[t][k] = {objname}[k]
else
r[t][k] = true
end
end
return r""", immediate=True)
d = rp.take_dict()
return {
k1.decode('latin1'): {
k2.decode('latin1'): v for k2, v in t.items()
} for k1, t in d.items()
}
def get_class_table(cls):
items = {
k: v for k, v in vars(cls).items()
if not k.startswith('_')
}
nums = {
k: v for k, v in items.items()
if isinstance(v, (int, float))
}
methods = {
k: True for k, v in items.items()
if isinstance(v, FunctionType)
}
r = {}
if nums:
r['number'] = nums
if methods:
r['function'] = methods
return r
def get_multiclass_table(*cls):
result = {}
for c in cls:
for k, v in get_class_table(c).items():
result.setdefault(k, {}).update(v)
return result
def term_step(text):
from cc import colors, term
for color in colors.iter_colors():
r, g, b = term.nativePaletteColor(color)
term.setPaletteColor(color, r, g, b)
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
term.setCursorBlink(True)
step(text)
def _computer_peri(place_thing, thing):
from cc import peripheral
side = 'left'
step(
f'Place {place_thing} on {side} side of computer\n'
"Don't turn it on!",
)
c = peripheral.wrap(side)
assert c is not None
from computercraft.cc.peripheral import ComputerMixin
tbl = get_object_table(f'peripheral.wrap("{side}")')
assert get_class_table(ComputerMixin) == tbl
assert c.isOn() is False
assert isinstance(c.getID(), int)
assert c.getLabel() is None
assert c.turnOn() is None
step(f'{thing.capitalize()} must be turned on now')
assert c.shutdown() is None
step(f'{thing.capitalize()} must shutdown')
step(f'Now turn on {thing} manually and enter some commands')
assert c.reboot() is None
step(f'{thing.capitalize()} must reboot')
print('Test finished successfully')

View file

@ -1,5 +0,0 @@
from cc import os
assert os.reboot() is None
print('Test finished successfully')

View file

@ -1,5 +0,0 @@
from cc import os
assert os.shutdown() is None
print('Test finished successfully')

View file

@ -5,9 +5,6 @@ _lib = import_file('_lib.py', __file__)
assert peripheral.isPresent('back') is False
tbl = _lib.get_object_table('pocket')
assert _lib.get_class_table(pocket) == tbl
_lib.step('Clean inventory from any pocket upgrades')
with _lib.assert_raises(LuaException):

View file

@ -3,11 +3,6 @@ from cc import LuaException, import_file, os, rednet, parallel
_lib = import_file('_lib.py', __file__)
step, assert_raises = _lib.step, _lib.assert_raises
tbl = _lib.get_object_table('rednet')
del tbl['function']['run']
assert _lib.get_class_table(rednet) == tbl
side = 'back'
step(f'Attach modem to {side} side of computer')

View file

@ -0,0 +1,8 @@
from cc import os
if args[-1:] == [b'reboot']:
assert os.reboot() is None
else:
assert os.shutdown() is None
print('Test finished successfully')

View file

@ -0,0 +1,113 @@
R671:0[5]{:[1]<9>pocket.py:[0]<2>py}<9>pocket.py<623>from cc import LuaException, import_file, pocket, peripheral
_lib = import_file('_lib.py', __file__)
assert peripheral.isPresent('back') is False
_lib.step('Clean inventory from any pocket upgrades')
with _lib.assert_raises(LuaException):
pocket.equipBack()
with _lib.assert_raises(LuaException):
pocket.unequipBack()
assert peripheral.isPresent('back') is False
_lib.step('Put any pocket upgrade to inventory')
assert pocket.equipBack() is None
assert peripheral.isPresent('back') is True
assert pocket.unequipBack() is None
assert peripheral.isPresent('back') is False
print('Test finished successfully')
S257:T<1>1<215>local p, rel = ...
if rel ~= nil then
p = fs.combine(fs.getDir(rel), p)
end
if not fs.exists(p) then return nil end
if fs.isDir(p) then return nil end
f = fs.open(p, "r")
local src = f.readAll()
f.close()
return src{:[1]<7>_lib.py:[2]<9>pocket.py}
R1162:T<1>1<1151>{:[1]T:[2]<1134>from contextlib import contextmanager
from cc import os
@contextmanager
def assert_raises(etype, message=None):
try:
yield
except Exception as e:
assert isinstance(e, etype), repr(e)
if message is not None:
assert e.args == (message, )
else:
raise AssertionError(f'Exception of type {etype} was not raised')
@contextmanager
def assert_takes_time(at_least, at_most):
t = os.epoch('utc') / 1000
yield
dt = os.epoch('utc') / 1000 - t
# print(at_least, '<=', dt, '<=', at_most)
assert at_least <= dt <= at_most
class AnyInstanceOf:
def __init__(self, cls):
self.c = cls
def __eq__(self, other):
return isinstance(other, self.c)
def step(text):
input(f'{text} [enter]')
def term_step(text):
from cc import colors, term
for color in colors.iter_colors():
r, g, b = term.nativePaletteColor(color)
term.setPaletteColor(color, r, g, b)
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
term.setCursorBlink(True)
step(text)}
S46:T<1>1<24>G:peripheral:M:isPresent{:[1]<4>back}
R21:T<1>1<12>{:[1]T:[2]F}
S80:T<1>1<13>io.write(...){:[1]<48>Clean inventory from any pocket upgrades [enter]}
R15:T<1>1<7>{:[1]T}
S22:T<1>1<11>G:io:M:read{}
R23:T<1>1<14>{:[1]T:[2]<0>}
S31:T<1>1<20>G:pocket:M:equipBack{}
R56:T<1>1<47>{:[1]T:[2]F:[3]<27>Cannot find a valid upgrade}
S33:T<1>1<22>G:pocket:M:unequipBack{}
R47:T<1>1<38>{:[1]T:[2]F:[3]<18>Nothing to unequip}
S46:T<1>1<24>G:peripheral:M:isPresent{:[1]<4>back}
R21:T<1>1<12>{:[1]T:[2]F}
S75:T<1>1<13>io.write(...){:[1]<43>Put any pocket upgrade to inventory [enter]}
R15:T<1>1<7>{:[1]T}
S22:T<1>1<11>G:io:M:read{}
R23:T<1>1<14>{:[1]T:[2]<0>}
S31:T<1>1<20>G:pocket:M:equipBack{}
R21:T<1>1<12>{:[1]T:[2]T}
S46:T<1>1<24>G:peripheral:M:isPresent{:[1]<4>back}
R21:T<1>1<12>{:[1]T:[2]T}
S33:T<1>1<22>G:pocket:M:unequipBack{}
R21:T<1>1<12>{:[1]T:[2]T}
S46:T<1>1<24>G:peripheral:M:isPresent{:[1]<4>back}
R21:T<1>1<12>{:[1]T:[2]F}
S58:T<1>1<13>io.write(...){:[1]<26>Test finished successfully}
R15:T<1>1<7>{:[1]T}
S32:T<1>1<13>io.write(...){:[1]<1>
}
R15:T<1>1<7>{:[1]T}
S2:CN

View file

@ -0,0 +1,175 @@
R1474:0[5]{:[1]<9>rednet.py:[0]<2>py}<9>rednet.py<1425>from cc import LuaException, import_file, os, rednet, parallel
_lib = import_file('_lib.py', __file__)
step, assert_raises = _lib.step, _lib.assert_raises
side = 'back'
step(f'Attach modem to {side} side of computer')
assert rednet.close() is None
assert rednet.isOpen(side) is False
assert rednet.isOpen() is False
with assert_raises(LuaException):
rednet.close('doesnotexist')
assert rednet.close(side) is None
with assert_raises(LuaException):
rednet.open('doesnotexist')
assert rednet.open(side) is None
assert rednet.isOpen(side) is True
with assert_raises(LuaException):
# disallowed hostname
rednet.host('helloproto', 'localhost')
assert rednet.host('helloproto', 'alpha') is None
cid = os.getComputerID()
assert rednet.lookup('helloproto', 'localhost') == cid
assert rednet.lookup('helloproto') == [cid]
assert rednet.lookup('nonexistent', 'localhost') is None
assert rednet.lookup('nonexistent') == []
assert rednet.unhost('helloproto') is None
assert rednet.send(cid + 100, b'message', 'anyproto') is True
assert rednet.broadcast(b'message', 'anyproto') is None
assert rednet.receive(timeout=1) is None
def _send():
assert rednet.send(cid, b'message') is True
def _recv():
assert rednet.receive(timeout=1) == (cid, b'message', None)
parallel.waitForAll(_send, _recv)
assert rednet.close() is None
assert rednet.isOpen(side) is False
print('Test finished successfully')
S257:T<1>1<215>local p, rel = ...
if rel ~= nil then
p = fs.combine(fs.getDir(rel), p)
end
if not fs.exists(p) then return nil end
if fs.isDir(p) then return nil end
f = fs.open(p, "r")
local src = f.readAll()
f.close()
return src{:[1]<7>_lib.py:[2]<9>rednet.py}
R1162:T<1>1<1151>{:[1]T:[2]<1134>from contextlib import contextmanager
from cc import os
@contextmanager
def assert_raises(etype, message=None):
try:
yield
except Exception as e:
assert isinstance(e, etype), repr(e)
if message is not None:
assert e.args == (message, )
else:
raise AssertionError(f'Exception of type {etype} was not raised')
@contextmanager
def assert_takes_time(at_least, at_most):
t = os.epoch('utc') / 1000
yield
dt = os.epoch('utc') / 1000 - t
# print(at_least, '<=', dt, '<=', at_most)
assert at_least <= dt <= at_most
class AnyInstanceOf:
def __init__(self, cls):
self.c = cls
def __eq__(self, other):
return isinstance(other, self.c)
def step(text):
input(f'{text} [enter]')
def term_step(text):
from cc import colors, term
for color in colors.iter_colors():
r, g, b = term.nativePaletteColor(color)
term.setPaletteColor(color, r, g, b)
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
term.setCursorBlink(True)
step(text)}
S77:T<1>1<13>io.write(...){:[1]<45>Attach modem to back side of computer [enter]}
R15:T<1>1<7>{:[1]T}
S22:T<1>1<11>G:io:M:read{}
R23:T<1>1<14>{:[1]T:[2]<0>}
S32:T<1>1<16>G:rednet:M:close{:[1]N}
R15:T<1>1<7>{:[1]T}
S39:T<1>1<17>G:rednet:M:isOpen{:[1]<4>back}
R21:T<1>1<12>{:[1]T:[2]F}
S33:T<1>1<17>G:rednet:M:isOpen{:[1]N}
R21:T<1>1<12>{:[1]T:[2]F}
S47:T<1>1<16>G:rednet:M:close{:[1]<12>doesnotexist}
R51:T<1>1<42>{:[1]F:[2]<27>No such modem: doesnotexist}
S38:T<1>1<16>G:rednet:M:close{:[1]<4>back}
R15:T<1>1<7>{:[1]T}
S46:T<1>1<15>G:rednet:M:open{:[1]<12>doesnotexist}
R51:T<1>1<42>{:[1]F:[2]<27>No such modem: doesnotexist}
S37:T<1>1<15>G:rednet:M:open{:[1]<4>back}
R15:T<1>1<7>{:[1]T}
S39:T<1>1<17>G:rednet:M:isOpen{:[1]<4>back}
R21:T<1>1<12>{:[1]T:[2]T}
S60:T<1>1<15>G:rednet:M:host{:[1]<10>helloproto:[2]<9>localhost}
R41:T<1>1<32>{:[1]F:[2]<17>Reserved hostname}
S56:T<1>1<15>G:rednet:M:host{:[1]<10>helloproto:[2]<5>alpha}
R15:T<1>1<7>{:[1]T}
S31:T<1>1<20>G:os:M:getComputerID{}
R23:T<1>1<14>{:[1]T:[2][1]}
S62:T<1>1<17>G:rednet:M:lookup{:[1]<10>helloproto:[2]<9>localhost}
R23:T<1>1<14>{:[1]T:[2][1]}
S51:T<1>1<17>G:rednet:M:lookup{:[1]<10>helloproto:[2]N}
R23:T<1>1<14>{:[1]T:[2][1]}
S63:T<1>1<17>G:rednet:M:lookup{:[1]<11>nonexistent:[2]<9>localhost}
R15:T<1>1<7>{:[1]T}
S52:T<1>1<17>G:rednet:M:lookup{:[1]<11>nonexistent:[2]N}
R15:T<1>1<7>{:[1]T}
S46:T<1>1<17>G:rednet:M:unhost{:[1]<10>helloproto}
R15:T<1>1<7>{:[1]T}
S64:T<1>1<15>G:rednet:M:send{:[1][101]:[2]<7>message:[3]<8>anyproto}
R21:T<1>1<12>{:[1]T:[2]T}
S60:T<1>1<20>G:rednet:M:broadcast{:[1]<7>message:[2]<8>anyproto}
R15:T<1>1<7>{:[1]T}
S41:T<1>1<18>G:rednet:M:receive{:[1]N:[2][1]}
R15:T<1>1<7>{:[1]T}
S52:T<1>2<15>G:rednet:M:send{:[1][1]:[2]<7>message:[3]N}
S41:T<1>3<18>G:rednet:M:receive{:[1]N:[2][1]}
R21:T<1>2<12>{:[1]T:[2]T}
R37:T<1>3<28>{:[1]T:[2][1]:[3]<7>message}
S5:D<1>3
S32:T<1>1<16>G:rednet:M:close{:[1]N}
R15:T<1>1<7>{:[1]T}
S39:T<1>1<17>G:rednet:M:isOpen{:[1]<4>back}
R21:T<1>1<12>{:[1]T:[2]F}
S58:T<1>1<13>io.write(...){:[1]<26>Test finished successfully}
R15:T<1>1<7>{:[1]T}
S32:T<1>1<13>io.write(...){:[1]<1>
}
R15:T<1>1<7>{:[1]T}
S2:CN

View file

@ -0,0 +1,10 @@
R208:0[5]{:[1]<11>shutdown.py:[0]<2>py}<11>shutdown.py<154>from cc import os
if args[-1:] == [b'reboot']:
assert os.reboot() is None
else:
assert os.shutdown() is None
print('Test finished successfully')
S26:T<1>1<15>G:os:M:shutdown{}
R1:D

View file

@ -0,0 +1,10 @@
R221:0[5]{:[1]<11>shutdown.py:[2]<6>reboot:[0]<2>py}<11>shutdown.py<154>from cc import os
if args[-1:] == [b'reboot']:
assert os.reboot() is None
else:
assert os.shutdown() is None
print('Test finished successfully')
S24:T<1>1<13>G:os:M:reboot{}
R1:D

View file

@ -53,6 +53,8 @@ def test_proto(logfile):
try:
pgen.send(frame)
except StopIteration:
if frame == b'D':
break
pytest.fail(
'Protocol prematurely finished on frame ' + repr(frame))
elif t == b'S':