|
1 | 1 | """Automate some testing.""" |
2 | 2 | from __future__ import annotations |
3 | 3 |
|
| 4 | +import builtins |
| 5 | +from collections.abc import Callable |
| 6 | +from collections.abc import Generator |
| 7 | +from collections.abc import Iterable |
4 | 8 | from dataclasses import dataclass |
5 | 9 | from dataclasses import field |
6 | 10 | from mimetypes import guess_type |
7 | | -from typing import Callable |
8 | | -from typing import Generator |
9 | 11 | from urllib.parse import urlparse |
10 | 12 |
|
11 | 13 | import pytest |
@@ -180,3 +182,56 @@ def _route_handler(route: Route) -> None: |
180 | 182 | # Don't spend 30 seconds on timeout |
181 | 183 | page.set_default_timeout(12000) |
182 | 184 | return page |
| 185 | + |
| 186 | + |
| 187 | +@dataclass |
| 188 | +class FakeDocument: |
| 189 | + """Pretend to be a DOM that holds values at id's.""" |
| 190 | + |
| 191 | + values: dict[str, str] = field(default_factory=dict) |
| 192 | + log: list[str] = field(default_factory=list) |
| 193 | + |
| 194 | + |
| 195 | +@pytest.fixture |
| 196 | +def fake_document() -> Iterable[FakeDocument]: |
| 197 | + """Yield a document that cleans up.""" |
| 198 | + yield FakeDocument() |
| 199 | + |
| 200 | + |
| 201 | +@dataclass |
| 202 | +class ElementNode: |
| 203 | + """An element node.""" |
| 204 | + |
| 205 | + value: str |
| 206 | + document: FakeDocument |
| 207 | + |
| 208 | + def write(self, value: str) -> None: |
| 209 | + """Collect anything that is written to the node.""" |
| 210 | + self.document.log.append(value) |
| 211 | + |
| 212 | + def removeAttribute(self, name: str) -> None: # noqa |
| 213 | + """Pretend to remove an attribute from this node.""" |
| 214 | + pass |
| 215 | + |
| 216 | + |
| 217 | +@dataclass |
| 218 | +class ElementCallable: |
| 219 | + """A callable that returns an ElementNode.""" |
| 220 | + |
| 221 | + document: FakeDocument |
| 222 | + |
| 223 | + def __call__(self, key: str) -> ElementNode: |
| 224 | + """Return an ElementNode.""" |
| 225 | + value = self.document.values[key] |
| 226 | + node = ElementNode(value, self.document) |
| 227 | + return node |
| 228 | + |
| 229 | + |
| 230 | +@pytest.fixture |
| 231 | +def fake_element(fake_document: FakeDocument) -> None: # type: ignore [misc] |
| 232 | + """Install the stateful Element into builtins.""" |
| 233 | + try: |
| 234 | + builtins.Element = ElementCallable(fake_document) #type: ignore [attr-defined] |
| 235 | + yield |
| 236 | + finally: |
| 237 | + delattr(builtins, "Element") |
0 commit comments