mirror of
https://github.com/neumond/python-computer-craft.git
synced 2024-05-20 08:03:57 -04:00
CC:T final tests migrated
This commit is contained in:
parent
b719fde825
commit
f1e4a14425
|
@ -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()
|
||||
|
||||
|
|
139
examples/_lib.py
139
examples/_lib.py
|
@ -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')
|
|
@ -1,5 +0,0 @@
|
|||
from cc import os
|
||||
|
||||
|
||||
assert os.reboot() is None
|
||||
print('Test finished successfully')
|
|
@ -1,5 +0,0 @@
|
|||
from cc import os
|
||||
|
||||
|
||||
assert os.shutdown() is None
|
||||
print('Test finished successfully')
|
|
@ -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):
|
|
@ -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')
|
8
tests/cc_programs/shutdown.py
Normal file
8
tests/cc_programs/shutdown.py
Normal 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')
|
113
tests/proto/m_1.20.1/cc_1.108.3/pocket.txt
Normal file
113
tests/proto/m_1.20.1/cc_1.108.3/pocket.txt
Normal 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
|
175
tests/proto/m_1.20.1/cc_1.108.3/rednet.txt
Normal file
175
tests/proto/m_1.20.1/cc_1.108.3/rednet.txt
Normal 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
|
10
tests/proto/m_1.20.1/cc_1.108.3/shutdown.txt
Normal file
10
tests/proto/m_1.20.1/cc_1.108.3/shutdown.txt
Normal 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
|
10
tests/proto/m_1.20.1/cc_1.108.3/shutdown_reboot.txt
Normal file
10
tests/proto/m_1.20.1/cc_1.108.3/shutdown_reboot.txt
Normal 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
|
|
@ -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':
|
||||
|
|
Loading…
Reference in a new issue