mirror of
https://github.com/1j01/textual-paint.git
synced 2024-08-17 03:40:26 +03:00
Move --recode-samples to an automated test
This commit is contained in:
parent
6f13a5a302
commit
bb047c04e7
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Removed
|
||||
|
||||
- `--recode-samples` option is removed, now covered by the `pytest` test suite.
|
||||
|
||||
### Changed
|
||||
|
||||
- Made radio buttons rounder in `--ascii-only` mode, using parentheses instead of square brackets.
|
||||
|
19
README.md
19
README.md
@ -87,7 +87,6 @@ development options:
|
||||
--clear-screen Clear the screen before starting, to avoid seeing
|
||||
outdated errors
|
||||
--restart-on-changes Restart the app when the source code is changed
|
||||
--recode-samples Open and save each file in samples/, for testing
|
||||
```
|
||||
|
||||
### Keyboard Shortcuts
|
||||
@ -329,22 +328,6 @@ This also makes it run slower.
|
||||
|
||||
Often it's useful to exclude events with `textual console -x EVENT`.
|
||||
|
||||
<details>
|
||||
<summary>Testing file save/load roundtrip</summary>
|
||||
|
||||
> There are at this point lots of files that will change if you run this, so don't worry about it. Some are generated files, so they naturally change somewhat. The `0x0.ans` file saves as 1x1, due to the minimum size. `pathological_character_grid.svg` was free-handed with Inkscape, so naturally changes somewhat when re-saving. There may be actual problems, but they're hard to spot in the noise.
|
||||
|
||||
To test file encoding, run `textual run --dev "src.textual_paint.paint --recode-samples"`.
|
||||
|
||||
If there are differences in the ANSI files, you can set up a special diff like this:
|
||||
```bash
|
||||
git config --local "diff.cat-show-all.textconv" "cat --show-all"
|
||||
```
|
||||
but you should check that `cat --show-all samples/2x2.ans` works on your system first.
|
||||
Also, note that it might not work with your Git GUI of choice; you may need to use the command line.
|
||||
|
||||
</details>
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
> `Unable to import 'app' from module 'src.textual_paint.paint'`
|
||||
@ -373,7 +356,7 @@ PYRIGHT_PYTHON_FORCE_VERSION=1.1.318 pyright
|
||||
# I also tried mypy and fixed some errors it reported, but I'm not targeting zero errors with mypy.
|
||||
mypy src --no-namespace-packages --check-untyped-defs
|
||||
|
||||
# Visual Regression Testing
|
||||
# Visual Regression Testing (and a few other tests)
|
||||
# I use pytest-textual-snapshot, which is a pytest plugin for comparing SVG screenshots of Textual apps over time.
|
||||
pytest
|
||||
# To accept differences, update the baseline with:
|
||||
|
@ -18,6 +18,7 @@ parser.add_argument('--ascii-only', action='store_true', help='Use only ASCII ch
|
||||
parser.add_argument('--backup-folder', default=None, metavar="FOLDER", help='Folder to save backups to. By default a backup is saved alongside the edited file.')
|
||||
|
||||
# TODO: hide development options from help? there's quite a few of them now
|
||||
# (...actually, less of them now, and I've grouped them together)
|
||||
dev_options = parser.add_argument_group('development options')
|
||||
dev_options.add_argument('--inspect-layout', action='store_true', help='Enables DOM inspector (F12) and middle click highlight')
|
||||
# This flag is important for my sanity during development,
|
||||
@ -27,7 +28,6 @@ dev_options.add_argument('--inspect-layout', action='store_true', help='Enables
|
||||
# I really don't want false ones mixed in. You want to reward your brain for finding good solutions, after all.
|
||||
dev_options.add_argument('--clear-screen', action='store_true', help='Clear the screen before starting, to avoid seeing outdated errors')
|
||||
dev_options.add_argument('--restart-on-changes', action='store_true', help='Restart the app when the source code is changed')
|
||||
dev_options.add_argument('--recode-samples', action='store_true', help='Open and save each file in samples/, for testing')
|
||||
|
||||
parser.add_argument('filename', nargs='?', default=None, help='Path to a file to open. File will be created if it doesn\'t exist.')
|
||||
|
||||
|
@ -4131,42 +4131,6 @@ else:
|
||||
# This requires the canvas to exist, hence call_later().
|
||||
app.call_later(app.recover_from_backup)
|
||||
|
||||
if args.recode_samples:
|
||||
# Re-encode the sample files to test for changes/inconsistency in encoding.
|
||||
|
||||
async def recode_sample(file_path: str|Path) -> None:
|
||||
"""Re-encodes a single sample file."""
|
||||
print(f"Re-encoding {file_path}")
|
||||
with open(file_path, "rb") as f:
|
||||
image = AnsiArtDocument.decode_based_on_file_extension(f.read(), str(file_path))
|
||||
with open(file_path, "wb") as f:
|
||||
f.write(image.encode_based_on_file_extension(str(file_path)))
|
||||
print(f"Saved {file_path}")
|
||||
|
||||
async def recode_samples() -> None:
|
||||
"""Re-encodes all sample files in parallel."""
|
||||
samples_folder = os.path.join(os.path.dirname(__file__), "../../samples")
|
||||
tasks: list[Coroutine[Any, Any, None]] = []
|
||||
for file_path in Path(samples_folder).glob("**/*"):
|
||||
# Skip backup files in case some sample file is being edited.
|
||||
if file_path.name.endswith("~"):
|
||||
continue
|
||||
# Skip GIMP Palette files.
|
||||
if file_path.name.endswith(".gpl"):
|
||||
continue
|
||||
# Skip folders.
|
||||
if file_path.is_dir():
|
||||
continue
|
||||
tasks.append(recode_sample(file_path))
|
||||
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
# have to wait for the app to be initialized
|
||||
async def once_running() -> None:
|
||||
await recode_samples()
|
||||
app.exit()
|
||||
app.call_later(once_running)
|
||||
|
||||
if args.clear_screen:
|
||||
os.system("cls||clear")
|
||||
|
||||
|
31
tests/test_encoding.py
Normal file
31
tests/test_encoding.py
Normal file
@ -0,0 +1,31 @@
|
||||
"""Test that files are encoded correctly."""
|
||||
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
|
||||
from textual_paint.ansi_art_document import AnsiArtDocument
|
||||
|
||||
ROUND_TRIP_EXCLUSIONS = [
|
||||
# These files are generated by a script, not the Textual Paint app, so they naturally change.
|
||||
"4x4_font_template.ans",
|
||||
"gradient_test.ans",
|
||||
# This one was free-handed with Inkscape, so naturally changes a lot.
|
||||
"pathological_character_grid.svg",
|
||||
# The `0x0.ans` file saves as 1x1, due to the minimum size.
|
||||
"0x0.ans",
|
||||
# This is a color palette file, meant to be loaded with Get Colors, not Open.
|
||||
"pipe_strip_palette.gpl",
|
||||
# THIS ONE MAYBE SHOULD IDEALLY WORK? But I need a better way of viewing a diff...
|
||||
"cp437_as_utf8.txt",
|
||||
]
|
||||
SAMPLES_DIR = Path(__file__).parent.parent / "samples"
|
||||
SAMPLES = [f for f in SAMPLES_DIR.iterdir() if f.is_file() and "~" not in f.name]
|
||||
ROUND_TRIP_SAMPLES = [f for f in SAMPLES if f.name not in ROUND_TRIP_EXCLUSIONS]
|
||||
|
||||
@pytest.mark.parametrize("file_path", ROUND_TRIP_SAMPLES)
|
||||
def test_round_trip(file_path: Path) -> None:
|
||||
"""Test that files are re-encoded identically when opened and saved."""
|
||||
with open(file_path, "rb") as f:
|
||||
file_content = f.read()
|
||||
image = AnsiArtDocument.decode_based_on_file_extension(file_content, str(file_path))
|
||||
assert image.encode_based_on_file_extension(str(file_path)) == file_content
|
Loading…
Reference in New Issue
Block a user