Files
lidar_rendu/lidar_pipeline/tests/test_cli.py
Antoine Jacquin 8ca65155db Add web map with zone generation API, side job queue, and restore historical DTM hole rendering
- webapp.py: FastAPI serving the continuous map (port 8973) with
  /api/preview, /api/generate and /api/status; tiles are downloaded
  from IGN and processed in a logged subprocess, tracked live in a
  side "File de génération" panel that survives page reloads
- fetch_ign.py: download missing 1 km LiDAR HD tiles from the IGN
  geoplateforme before processing
- index.py: tile thumbnails and 500 m subtiles are now invalidated by
  mtime so regenerating a tile refreshes its cached images; progress
  logging per tile
- dtm.py: back to the historical gap handling (small gaps filled by
  fillnodata only, larger holes left as nodata rendered black);
  lowest-return floor only via --bare-earth, IGN class selection via
  --ign-classes
- cli.py: positional input now optional (--rebuild-index works alone)
- docker-compose.yml: serve (GPU, port 8973) and process services;
  launch via docker compose only (documented in AGENTS.md/AGENTS.md)
- tests: 131 passing, incl. regressions for thumbnail staleness,
  --rebuild-index without input, and nodata rendering
2026-08-31 18:07:14 +02:00

105 lines
3.9 KiB
Python

"""Tests for CLI argument parsing."""
import pytest
import sys
class TestCLIParsing:
def test_default_args(self):
"""Default arguments are set correctly."""
from lidar_pipeline.cli import main
# We can't easily call main() without files, so test argparse directly
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("input", help="Input directory")
parser.add_argument("-o", "--output", default="/data/output")
parser.add_argument("-r", "--resolution", type=float, default=0.5)
parser.add_argument("-w", "--workers", type=int, default=1)
parser.add_argument("-f", "--force", action="store_true")
parser.add_argument("--file", nargs="+", type=str, default=None)
parser.add_argument("--keep-tif", action="store_true")
args = parser.parse_args(["./input"])
assert args.input == "./input"
assert args.output == "/data/output"
assert args.resolution == 0.5
assert args.workers == 1
assert args.force is False
assert args.file is None
assert args.keep_tif is False
def test_file_flag_single(self):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--file", nargs="+", type=str, default=None)
args = parser.parse_args(["--file", "test_file"])
assert args.file == ["test_file"]
def test_file_flag_multiple(self):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--file", nargs="+", type=str, default=None)
args = parser.parse_args(["--file", "file1", "file2", "file3"])
assert args.file == ["file1", "file2", "file3"]
def test_force_flag(self):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--force", action="store_true")
args = parser.parse_args(["-f"])
assert args.force is True
def test_resolution_custom(self):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--resolution", type=float, default=0.5)
args = parser.parse_args(["-r", "0.2"])
assert args.resolution == 0.2
class TestSetupLogging:
def test_default_logging(self):
"""Default logging shows messages without timestamps."""
import logging
from lidar_pipeline.cli import setup_logging
logger = setup_logging(verbose=False, debug=False)
assert logger.level == logging.INFO
assert len(logger.handlers) == 1
# Format should not include timestamps
fmt = logger.handlers[0].formatter._fmt
assert "%(asctime)s" not in fmt
def test_verbose_logging(self):
"""Verbose logging includes timestamps."""
import logging
from lidar_pipeline.cli import setup_logging
logger = setup_logging(verbose=True, debug=False)
fmt = logger.handlers[0].formatter._fmt
assert "%(asctime)s" in fmt
def test_debug_logging(self):
"""Debug logging includes file:line info."""
import logging
from lidar_pipeline.cli import setup_logging
logger = setup_logging(verbose=False, debug=True)
assert logger.level == logging.DEBUG
fmt = logger.handlers[0].formatter._fmt
assert "%(filename)s" in fmt
assert "%(lineno)d" in fmt
def test_rebuild_index_without_input_arg(tmp_path):
"""--rebuild-index fonctionne sans l'argument positionnel input.
Régression : input était obligatoire alors que --rebuild-index ne
l'utilise pas (erreur argparse « the following arguments are required »).
"""
import subprocess
r = subprocess.run(
[sys.executable, "-m", "lidar_pipeline", "--rebuild-index",
"-o", str(tmp_path)],
capture_output=True, text=True, timeout=180,
)
assert r.returncode == 0, r.stderr
assert "the following arguments are required" not in r.stderr