Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 107 additions & 108 deletions doc/conf.py

Large diffs are not rendered by default.

12 changes: 5 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ build-backend = "setuptools.build_meta"
[tool.ruff]
line-length = 100
output-format = "full"
exclude = [
lint.exclude = [
"venv",
".venv*",
"tests",
Expand All @@ -95,7 +95,7 @@ exclude = [
".pytest_cache",
"temp",
"bugs",
"arcade/examples/platform_tutorial",
"arcade/examples/*",
]
lint.ignore = [
"E731", # E731 do not assign a lambda expression, use a def
Expand All @@ -114,7 +114,7 @@ lint.select = [

[tool.ruff.format]
docstring-code-format = false
exclude = ["arcade/examples/*", "benchmarks/*"]
exclude = ["arcade/examples/*", "benchmarks/*", "doc/*"]

# This ignores __init__.py files and examples for import sorting
[tool.ruff.lint.per-file-ignores]
Expand All @@ -126,9 +126,7 @@ exclude = ["arcade/examples/*", "benchmarks/*"]

[tool.mypy]
disable_error_code = "annotation-unchecked"
exclude = [
"arcade/gl/backends"
]
exclude = ["arcade/gl/backends"]

[tool.pytest.ini_options]
norecursedirs = [
Expand All @@ -143,7 +141,7 @@ norecursedirs = [
]
markers = [
"backendgl: Run OpenGL (or OpenGL ES) backend specific tests",
"backendwebgl: Run WebGL backend specific tests"
"backendwebgl: Run WebGL backend specific tests",
]

[tool.pyright]
Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
# Headless mode
if os.environ.get("ARCADE_HEADLESS_TEST"):
import pyglet

pyglet.options.headless = True
20 changes: 14 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from arcade.clock import GLOBAL_CLOCK, GLOBAL_FIXED_CLOCK
from arcade import Rect, LBWH
from arcade import gl

# from arcade.texture import default_texture_cache
# NOTE: Load liberation fonts in unit tests
arcade.resources.load_liberation_fonts()
Expand All @@ -30,28 +31,30 @@
WINDOW = None
OFFSCREEN = None

POSSIBLE_BACKENDS = [
"backendopengl",
"backendwebgl"
]
POSSIBLE_BACKENDS = ["backendopengl", "backendwebgl"]

arcade.resources.load_kenney_fonts()


def pytest_addoption(parser):
parser.addoption("--gl-backend", default="opengl")


def pytest_configure(config):
global GL_BACKEND
GL_BACKEND = config.option.gl_backend


def pytest_collection_modifyitems(config, items):
desired_backend = "backend" + GL_BACKEND
for item in items:
for backend in POSSIBLE_BACKENDS:
if backend in item.keywords:
if backend != desired_backend:
item.add_marker(pytest.mark.skip(f"Skipping GL backend specific test for {backend}"))
item.add_marker(
pytest.mark.skip(f"Skipping GL backend specific test for {backend}")
)


def make_window_caption(request=None, prefix="Testing", sep=" - ") -> str:
"""Centralizes test name customization.
Expand All @@ -72,7 +75,12 @@ def create_window(width=1280, height=720, caption="Testing", **kwargs):
global WINDOW
if not WINDOW:
WINDOW = REAL_WINDOW_CLASS(
width=width, height=height, title=caption, vsync=False, antialiasing=False, gl_api = GL_BACKEND
width=width,
height=height,
title=caption,
vsync=False,
antialiasing=False,
gl_api=GL_BACKEND,
)
WINDOW.set_vsync(False)
# This value is being monkey-patched into the Window class so that tests can identify if we are using
Expand Down
8 changes: 6 additions & 2 deletions tests/doc/check_examples_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@


def get_references_in_index():
txt = Path('../../doc/example_code/how_to_examples/index.rst').read_text()
txt = Path("../../doc/example_code/how_to_examples/index.rst").read_text()
references_in_index = re.findall(":ref:`(.*)`", txt)
return references_in_index


def get_references_in_rsts():
mypath = Path("../../doc/example_code/how_to_examples/")

Expand All @@ -24,6 +25,7 @@ def get_references_in_rsts():

return references


def main():
references_in_index = get_references_in_index()
files_to_reference = get_references_in_rsts()
Expand All @@ -32,7 +34,9 @@ def main():
if not reference in references_in_index:
print(f"index.rst is missing any mention of '{reference}'")

print("Done with checking to make sure references in doc/examples/*.rst are in doc/examples/index.rst")
print(
"Done with checking to make sure references in doc/examples/*.rst are in doc/examples/index.rst"
)


main()
5 changes: 3 additions & 2 deletions tests/doc/check_samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@ def main():

# See if there are rst files for all the py files
for py_file in python_example_filename_list:
base_name = py_file[:len(py_file) - 3]
base_name = py_file[: len(py_file) - 3]
rst_name = base_name + ".rst"
if rst_name not in python_rst_filename_list:
print("Missing " + rst_name)

# See if there are py files for all the rst files
print()
for rst_file in python_rst_filename_list:
base_name = rst_file[:len(rst_file) - 4]
base_name = rst_file[: len(rst_file) - 4]
py_name = base_name + ".py"
if py_name not in python_example_filename_list:
print("Missing " + py_name)


main()
29 changes: 14 additions & 15 deletions tests/integration/examples/test_examples.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Import and run all examples one frame
"""

import contextlib
import io
import inspect
Expand All @@ -15,24 +16,20 @@

# File path, module path
EXAMPLE_LOCATIONS = [
(
Path(arcade.__file__).parent / "examples",
"arcade.examples"
),
(Path(arcade.__file__).parent / "examples", "arcade.examples"),
(
Path(arcade.__file__).parent / "examples" / "platform_tutorial",
"arcade.examples.platform_tutorial"
),
(
Path(arcade.__file__).parent / "examples" / "gl",
"arcade.examples.gl"
"arcade.examples.platform_tutorial",
),
(Path(arcade.__file__).parent / "examples" / "gl", "arcade.examples.gl"),
]
# These examples are allowed to print to stdout
ALLOW_STDOUT = set([
"arcade.examples.dual_stick_shooter",
"transform_multi",
])
ALLOW_STDOUT = set(
[
"arcade.examples.dual_stick_shooter",
"transform_multi",
]
)
IGNORE_PATTERNS = [
"net_process_animal_facts", # Starts network process
"transform_emit", # Broken
Expand All @@ -42,16 +39,19 @@
"bindless", # Bindless textures cannot be run in unit test
]


def list_examples():
for path, module_path in EXAMPLE_LOCATIONS:
for example in path.glob("*.py"):
if example.stem.startswith("_"):
continue

def is_ignored(example):
for pattern in IGNORE_PATTERNS:
if pattern in example.stem:
return True
return False

if is_ignored(example):
continue
yield f"{module_path}.{example.stem}", example, True
Expand Down Expand Up @@ -85,13 +85,12 @@ def test_examples(window_proxy, module_path, file_path, allow_stdout):
# Manually load the module as __main__ so it runs on import
loader = SourceFileLoader("__main__", str(file_path))
loader.exec_module(loader.load_module())

# Reset the global clock's tick speed
# is this a good argument against a global scope clock?
# yes.
arcade.clock.GLOBAL_CLOCK.set_tick_speed(1.0)


if not allow_stdout:
output = stdout.getvalue()
assert not output, f"Example {module_path} printed to stdout: {output}"
3 changes: 2 additions & 1 deletion tests/integration/tutorials/test_tutorials.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Find and run all tutorials in the doc/tutorials directory
"""

import io
import os
import contextlib
Expand All @@ -11,7 +12,7 @@
import pytest
import arcade

TUTORIAL_DIR = Path(arcade.__file__).parent.parent / "doc" /"tutorials"
TUTORIAL_DIR = Path(arcade.__file__).parent.parent / "doc" / "tutorials"
ALLOW_STDOUT = {}


Expand Down
67 changes: 22 additions & 45 deletions tests/manual_smoke/sprite_collision_inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@

TEX_GREY_PANEL_RAW = load_texture(":resources:gui_basic_assets/window/grey_panel.png")

T = TypeVar('T')
T = TypeVar("T")


def _tname(t: Any) -> str:
if not isinstance(t, builtins.type):
return t.__class__.__name__
return t.__class__.__name__
else:
return t.__name__

Expand Down Expand Up @@ -61,7 +62,7 @@ def __init__(
size_hint=size_hint,
size_hint_min=size_hint_min,
size_hint_max=size_hint_max,
**kwargs
**kwargs,
)
self._error_color = error_color
self._parsed_type: Type[T] = parsed_type
Expand Down Expand Up @@ -102,9 +103,7 @@ def color(self, new_color: RGBOrA255) -> None:
return

self.caret.color = validated
self.doc.set_style(
0, len(self.text), dict(color=validated)
)
self.doc.set_style(0, len(self.text), dict(color=validated))
self.trigger_full_render()

@property
Expand All @@ -123,66 +122,47 @@ def text(self, new_text: str) -> None:
raise e



def draw_crosshair(
where: tuple[float, float],
color=arcade.color.BLACK,
radius: float = 20.0,
border_width: float = 1.0,
) -> None:
x, y = where
arcade.draw.circle.draw_circle_outline(
x, y,
radius,
color=color,
border_width=border_width
)
arcade.draw.draw_line(
x, y - radius, x, y + radius,
color=color, line_width=border_width)
arcade.draw.circle.draw_circle_outline(x, y, radius, color=color, border_width=border_width)
arcade.draw.draw_line(x, y - radius, x, y + radius, color=color, line_width=border_width)

arcade.draw.draw_line(
x - radius, y, x + radius, y,
color=color, line_width=border_width)
arcade.draw.draw_line(x - radius, y, x + radius, y, color=color, line_width=border_width)


class MyGame(arcade.Window):

def add_field_row(self, label_text: str, widget: UIWidget) -> None:
children = (
arcade.gui.widgets.text.UITextArea(
text=label_text,
width=100,
height=20,
color=arcade.color.BLACK,
font_size=12
text=label_text, width=100, height=20, color=arcade.color.BLACK, font_size=12
),
widget
widget,
)
row = UIBoxLayout(vertical=False, space_between=10, children=children)
self.rows.add(row)

def __init__(
self,
width: int = 1280,
height: int = 720,
grid_tile_px: int = 100
):

def __init__(self, width: int = 1280, height: int = 720, grid_tile_px: int = 100):
super().__init__(width, height, "Collision Inspector")
# why does this need a context again?
self.nine_patch = NinePatchTexture(
left=5, right=5, top=5, bottom=5, texture=TEX_GREY_PANEL_RAW)
left=5, right=5, top=5, bottom=5, texture=TEX_GREY_PANEL_RAW
)
self.ui = UIManager()
self.spritelist: SpriteList[Sprite] = arcade.SpriteList()


textbox_template = dict(width=40, height=20, text_color=arcade.color.BLACK)
self.cursor_x_field = UIInputText(
text="1.0", **textbox_template).with_background(texture=self.nine_patch)
self.cursor_x_field = UIInputText(text="1.0", **textbox_template).with_background(
texture=self.nine_patch
)

self.cursor_y_field = UIInputText(
text="1.0", **textbox_template).with_background(texture=self.nine_patch)
self.cursor_y_field = UIInputText(text="1.0", **textbox_template).with_background(
texture=self.nine_patch
)

self.rows = UIBoxLayout(space_between=20).with_background(color=arcade.color.GRAY)

Expand All @@ -206,11 +186,7 @@ def __init__(
self.on_widget = False

def build_sprite_grid(
self,
columns: int,
rows: int,
grid_tile_px: int,
offset: tuple[float, float] = (0, 0)
self, columns: int, rows: int, grid_tile_px: int, offset: tuple[float, float] = (0, 0)
):
offset_x, offset_y = offset
self.spritelist.clear()
Expand Down Expand Up @@ -254,4 +230,5 @@ def on_draw(self):

self.ui.draw()

MyGame().run()

MyGame().run()
Loading
Loading