CampBuddy/Camp.Buddy v2.2.1/Camp_Buddy-2.2.1-pc/renpy/test/testexecution.py
2025-03-03 23:00:33 +01:00

197 lines
4.8 KiB
Python

# Copyright 2004-2019 Tom Rothamel <pytom@bishoujo.us>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from __future__ import print_function
import renpy.display
import renpy.test
import pygame_sdl2
# A map from the name of a testcase to the testcase.
testcases = { }
# The root node.
node = None
# The location of the currently execution TL node.
node_loc = None
# The state of the root node.
state = None
# The previous state and location in the game script.
old_state = None
old_loc = None
# The last time the state changed.
last_state_change = 0
# The time the root node started executing.
start_time = None
# An action to run before executing another command.
action = None
# The set of labels that have been reached since the last time execute
# has been called.
labels = set()
def take_name(name):
"""
Takes the name of a statement that is about to run.
"""
if node is None:
return
if isinstance(name, basestring):
labels.add(name)
class TestJump(Exception):
"""
An exception that is raised in order to jump to `node`.
"""
def __init__(self, node):
self.node = node
def lookup(name, from_node):
"""
Tries to look up the name with `target`. If found, returns it, otherwise
raises an exception.
"""
if name in testcases:
return testcases[name]
raise Exception("Testcase {} not found at {}:{}.".format(name, from_node.filename, from_node.linenumber))
def execute_node(now, node, state, start):
"""
Performs one execution cycle of a node.
"""
while True:
try:
if state is None:
state = node.start()
start = now
if state is None:
break
state = node.execute(state, now - start)
break
except TestJump as e:
node = e.node
state = None
if state is None:
node = None
return node, state, start
def execute():
"""
Called periodically by the test code to generate events, if desired.
"""
global node
global state
global start_time
global action
global old_state
global old_loc
global last_state_change
_test = renpy.test.testast._test
if node is None:
return
if renpy.display.interface.suppress_underlay and (not _test.force):
return
if _test.maximum_framerate:
renpy.exports.maximum_framerate(10.0)
else:
renpy.exports.maximum_framerate(None)
# Make sure there are no test events in the event queue.
for e in pygame_sdl2.event.copy_event_queue(): # @UndefinedVariable
if getattr(e, "test", False):
return
if action:
old_action = action
action = None
renpy.display.behavior.run(old_action)
now = renpy.display.core.get_time()
node, state, start_time = execute_node(now, node, state, start_time)
labels.clear()
if node is None:
renpy.test.testmouse.reset()
return
loc = renpy.exports.get_filename_line()
if (old_state != state) or (old_loc != loc):
last_state_change = now
old_state = state
old_loc = loc
if (now - last_state_change) > _test.timeout:
raise Exception("Testcase stuck at {}:{}.".format(node_loc[0], node_loc[1]))
def test_command():
"""
The dialogue command. This updates dialogue.txt, a file giving all the dialogue
in the game.
"""
ap = renpy.arguments.ArgumentParser(description="Runs a testcase.")
ap.add_argument("testcase", help="The name of a testcase to run.", nargs='?', default="default")
args = ap.parse_args()
if args.testcase not in testcases:
raise Exception("Testcase {} was not found.".format(args.testcase))
global node
node = testcases[args.testcase]
return True
renpy.arguments.register_command("test", test_command)