mirror of
https://github.com/1j01/textual-paint.git
synced 2024-09-11 23:57:12 +03:00
Use pyfakefs for file dialog tests
- The app's directory structure is not a constant, and shouldn't play into this test. Aside from codebase restructuring, directories like `__pycache__` can come and go. - Even if a temporary directory were created with files enough to fill the view, the scrollbar would still change based on the folder structure outside of the temporary folder. - pyfakefs is one way to ensure a consistent view of a folder structure for testing. It allows adding real folders in a readonly way. It's more complicated than I thought it would be going in, since I had to add workarounds for pyfiglet and pytest-textual-snapshot, and handle an edge case in my EnhancedDirectoryTree (which got an error which seems to be swallowed?), not to mention pyfakefs raises an error saying "No such file or directory in the fake filesystem" when actually it's the real directory not existing when trying to add it to the fake filesystem, and VS Code was hiding stack frames and refusing to step into library code, and it turned out that I was resolving the absolute path wrong, but it looked right to me because the only part that was missing was "textual-paint", when, at a glance it seemed present, since the "textual_paint" part was present. Ay-ay-ay! - I don't know if this will fix the problem I saw where these tests' snapshots all changed with no visual or even structural changes, just the IDs of elements changing. I don't know what caused that. Oh yeah and this is still actually a problem: ============================================= short test summary info ============================================== FAILED tests/test_snapshots.py::test_paint_open_dialog[light_unicode] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? FAILED tests/test_snapshots.py::test_paint_open_dialog[dark_unicode] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? FAILED tests/test_snapshots.py::test_paint_open_dialog[light_ascii] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? FAILED tests/test_snapshots.py::test_paint_open_dialog[dark_ascii] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? FAILED tests/test_snapshots.py::test_paint_save_dialog[light_unicode] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? FAILED tests/test_snapshots.py::test_paint_save_dialog[dark_unicode] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? FAILED tests/test_snapshots.py::test_paint_save_dialog[light_ascii] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? FAILED tests/test_snapshots.py::test_paint_save_dialog[dark_ascii] - AttributeError: 'EnhancedDirectoryTree' object has no attribute '_id'. Did you mean: 'id'? ========================== 8 failed, 56 passed, 1 xfailed, 1 warning in 152.86s (0:02:32) ========================== It worked when running in debug, but not when running normally.
This commit is contained in:
parent
370b497cc6
commit
7f91138a63
@ -118,6 +118,7 @@
|
|||||||
"psutil",
|
"psutil",
|
||||||
"pybabel",
|
"pybabel",
|
||||||
"pycache",
|
"pycache",
|
||||||
|
"pyfakefs",
|
||||||
"pyfiglet",
|
"pyfiglet",
|
||||||
"Pylance",
|
"Pylance",
|
||||||
"pyobjc",
|
"pyobjc",
|
||||||
|
@ -14,3 +14,4 @@ types-Pillow==10.0.0.1 # for development
|
|||||||
types-psutil==5.9.5.15 # for development
|
types-psutil==5.9.5.15 # for development
|
||||||
pytest==7.4.1 # for development
|
pytest==7.4.1 # for development
|
||||||
pytest-textual-snapshot==0.4.0 # for development
|
pytest-textual-snapshot==0.4.0 # for development
|
||||||
|
pyfakefs==5.2.4 # for development
|
||||||
|
@ -163,7 +163,11 @@ class EnhancedDirectoryTree(DirectoryTree):
|
|||||||
|
|
||||||
if callback is None:
|
if callback is None:
|
||||||
callback = lambda: None
|
callback = lambda: None
|
||||||
self._expand_matching_child(self.root, target_path.parts[1:], callback)
|
|
||||||
|
remaining_parts = target_path.parts[1:]
|
||||||
|
# True unless target_path is the root (edge case which occurs when testing with pyfakefs).
|
||||||
|
if len(remaining_parts) > 1:
|
||||||
|
self._expand_matching_child(self.root, remaining_parts, callback)
|
||||||
|
|
||||||
def render_label(
|
def render_label(
|
||||||
self, node: TreeNode[DirEntry], base_style: Style, style: Style
|
self, node: TreeNode[DirEntry], base_style: Style, style: Style
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
from typing import TYPE_CHECKING, Awaitable, Callable, Iterable, Protocol
|
from typing import (TYPE_CHECKING, Awaitable, Callable, Generator, Iterable,
|
||||||
|
Protocol)
|
||||||
|
|
||||||
|
import pyfakefs
|
||||||
import pytest
|
import pytest
|
||||||
|
from pyfakefs.fake_file import FakeDirectory
|
||||||
|
from pyfakefs.fake_filesystem import FakeFilesystem
|
||||||
from textual.geometry import Offset
|
from textual.geometry import Offset
|
||||||
from textual.pilot import Pilot
|
from textual.pilot import Pilot
|
||||||
from textual.widgets import Input
|
from textual.widgets import Input
|
||||||
|
|
||||||
from tests.pilot_helpers import click_by_attr, click_by_index, drag
|
from tests.pilot_helpers import click_by_attr, click_by_index, drag
|
||||||
|
from textual_paint.figlet_font_writer import FIGletFontWriter
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
# When tests are run, paint.py is re-evaluated,
|
# When tests are run, paint.py is re-evaluated,
|
||||||
@ -58,6 +63,38 @@ def each_theme(request: pytest.FixtureRequest):
|
|||||||
args.theme = "light"
|
args.theme = "light"
|
||||||
args.ascii_only = False
|
args.ascii_only = False
|
||||||
|
|
||||||
|
APPS_DIR_ABSOLUTE = (Path(__file__).parent / APPS_DIR).resolve()
|
||||||
|
TESTS_DIR_ABSOLUTE = Path(__file__).parent.resolve()
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def my_fs(fs: FakeFilesystem) -> Generator[FakeFilesystem, None, None]:
|
||||||
|
print("adding real directory", APPS_DIR_ABSOLUTE)
|
||||||
|
fs.add_real_directory(APPS_DIR_ABSOLUTE)
|
||||||
|
|
||||||
|
# Without this, pytest-textual-snapshot will show "No history for this test"
|
||||||
|
print("adding real directory", TESTS_DIR_ABSOLUTE)
|
||||||
|
fs.add_real_directory(TESTS_DIR_ABSOLUTE)
|
||||||
|
|
||||||
|
# TODO: use proper mocking or figure out how to get FigletFont to find the real font files.
|
||||||
|
# This folder doesn't actually exist on my system, so it's not getting them from there.
|
||||||
|
# from pyfiglet import SHARED_DIRECTORY
|
||||||
|
# fs.add_real_directory(SHARED_DIRECTORY)
|
||||||
|
|
||||||
|
# Don't fail trying to load the default font "standard", we don't need it!
|
||||||
|
# `pkg_resources` doesn't seem to work with pyfakefs.
|
||||||
|
from pyfiglet import FigletFont
|
||||||
|
def preloadFont(self: FigletFont, font: str):
|
||||||
|
dumb_font = FIGletFontWriter(commentLines=["Stupid font for testing"])
|
||||||
|
for ordinal in dumb_font.charOrder:
|
||||||
|
dumb_font.figChars[ordinal] = "fallback font for testing"
|
||||||
|
return dumb_font.createFigFileData()
|
||||||
|
FigletFont.preloadFont = preloadFont
|
||||||
|
|
||||||
|
# Add an extra file to show how a file looks in the EnhancedDirectoryTree widget.
|
||||||
|
fs.create_file("/pyfakefs_added_file.txt", contents="pyfakefs ate ur FS")
|
||||||
|
|
||||||
|
yield fs
|
||||||
|
|
||||||
|
|
||||||
def test_paint_app(snap_compare: SnapCompareType, each_theme: None):
|
def test_paint_app(snap_compare: SnapCompareType, each_theme: None):
|
||||||
assert snap_compare(PAINT, terminal_size=LARGER)
|
assert snap_compare(PAINT, terminal_size=LARGER)
|
||||||
@ -71,10 +108,10 @@ def test_paint_flip_rotate_dialog(snap_compare: SnapCompareType, each_theme: Non
|
|||||||
def test_paint_image_attributes_dialog(snap_compare: SnapCompareType, each_theme: None):
|
def test_paint_image_attributes_dialog(snap_compare: SnapCompareType, each_theme: None):
|
||||||
assert snap_compare(PAINT, press=["ctrl+e"])
|
assert snap_compare(PAINT, press=["ctrl+e"])
|
||||||
|
|
||||||
def test_paint_open_dialog(snap_compare: SnapCompareType, each_theme: None):
|
def test_paint_open_dialog(snap_compare: SnapCompareType, each_theme: None, my_fs: None):
|
||||||
assert snap_compare(PAINT, press=["ctrl+o"], terminal_size=LARGER)
|
assert snap_compare(PAINT, press=["ctrl+o"], terminal_size=LARGER)
|
||||||
|
|
||||||
def test_paint_save_dialog(snap_compare: SnapCompareType, each_theme: None):
|
def test_paint_save_dialog(snap_compare: SnapCompareType, each_theme: None, my_fs: None):
|
||||||
assert snap_compare(PAINT, press=["ctrl+s"], terminal_size=LARGER)
|
assert snap_compare(PAINT, press=["ctrl+s"], terminal_size=LARGER)
|
||||||
|
|
||||||
def test_paint_help_dialog(snap_compare: SnapCompareType, each_theme: None):
|
def test_paint_help_dialog(snap_compare: SnapCompareType, each_theme: None):
|
||||||
|
Loading…
Reference in New Issue
Block a user