Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 87e7e75

Browse filesBrowse files
committed
add robust lint/testing + upgrade idom
1 parent 0c57513 commit 87e7e75
Copy full SHA for 87e7e75

19 files changed

+334
-57
lines changed

‎.github/ISSUE_TEMPLATE/bug_report.md

Copy file name to clipboard
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: Bug Report
5+
labels: bug
6+
assignees: rmorshea
7+
8+
---
9+
10+
**Describe the bug**
11+
A clear and concise description of what the bug is.
12+
13+
**To Reproduce**
14+
Steps to reproduce the behavior:
15+
1. Go to '...'
16+
2. Click on '....'
17+
3. Scroll down to '....'
18+
4. See error
19+
20+
**Expected behavior**
21+
A clear and concise description of what you expected to happen.
22+
23+
**Additional context**
24+
Add any other context about the problem here.
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
name: Doc enhancement
3+
about: Documentation needs to be fixed or added
4+
title: Doc Enhancement
5+
labels: docs
6+
assignees: rmorshea
7+
8+
---
9+
10+
**Describe what documentation needs to be fixed or added**
11+
Is something missing, worded poorly, or flat out wrong? Tells us about it here.
12+
13+
**Additional context**
14+
Add any other context about the problem here.
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ''
5+
labels: enhancement
6+
assignees: rmorshea
7+
8+
---
9+
10+
**Is your feature request related to a problem? Please describe.**
11+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12+
13+
**Describe the solution you'd like**
14+
A clear and concise description of what you want to happen.
15+
16+
**Describe alternatives you've considered**
17+
A clear and concise description of any alternative solutions or features you've considered.
18+
19+
**Additional context**
20+
Add any other context or screenshots about the feature request here.

‎.github/workflows/release.yaml

Copy file name to clipboard
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This workflows will upload a Python Package using Twine when a release is created
2+
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
3+
4+
name: Release
5+
6+
on:
7+
release:
8+
types:
9+
- created
10+
11+
jobs:
12+
publish-package:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v2
16+
- name: Set up Python
17+
uses: actions/setup-python@v1
18+
with:
19+
python-version: "3.x"
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install setuptools wheel twine
24+
- name: Build and publish
25+
env:
26+
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
27+
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
28+
run: |
29+
python setup.py bdist_wheel
30+
twine upload dist/*

‎.github/workflows/test.yaml

Copy file name to clipboard
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Test
2+
3+
on: [push]
4+
5+
jobs:
6+
coverage:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
- name: Use Latest Python
11+
uses: actions/setup-python@v2
12+
with:
13+
python-version: "3.10"
14+
- name: Install Python Dependencies
15+
run: pip install -r requirements/nox-deps.txt
16+
- name: Run Tests
17+
run: nox -s test
18+
19+
environments:
20+
runs-on: ubuntu-latest
21+
strategy:
22+
matrix:
23+
python-version: ["3.7", "3.8", "3.9", "3.10"]
24+
steps:
25+
- uses: actions/checkout@v2
26+
- name: Use Python ${{ matrix.python-version }}
27+
uses: actions/setup-python@v2
28+
with:
29+
python-version: ${{ matrix.python-version }}
30+
- name: Install Python Dependencies
31+
run: pip install -r requirements/nox-deps.txt
32+
- name: Run Tests
33+
run: nox -s test -- --no-cov

‎idom_router/__init__.py

Copy file name to clipboard
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
11
# the version is statically loaded by setup.py
22
__version__ = "0.0.1"
3+
4+
from .router import Link, Route, Routes, configure, use_location
5+
6+
__all__ = [
7+
"configure",
8+
"Link",
9+
"Route",
10+
"Routes",
11+
"use_location",
12+
]

‎idom_router/router.py

Copy file name to clipboardExpand all lines: idom_router/router.py
+58-32Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,85 @@
11
from __future__ import annotations
2-
from dataclasses import dataclass
32

3+
import re
4+
from dataclasses import dataclass
45
from fnmatch import translate as fnmatch_translate
56
from pathlib import Path
6-
import re
7-
from typing import Any, Iterator, Protocol, Callable, Sequence
7+
from typing import Any, Callable, Iterator, Sequence
88

9-
from idom import create_context, component, use_context, use_state
10-
from idom.web.module import export, module_from_file
11-
from idom.core.vdom import coalesce_attributes_and_children, VdomAttributesAndChildren
9+
from idom import component, create_context, use_context, use_state
10+
from idom.core.types import VdomAttributesAndChildren, VdomDict
11+
from idom.core.vdom import coalesce_attributes_and_children
1212
from idom.types import BackendImplementation, ComponentType, Context, Location
13+
from idom.web.module import export, module_from_file
1314

15+
try:
16+
from typing import Protocol
17+
except ImportError:
18+
from typing_extensions import Protocol
1419

15-
class Router(Protocol):
20+
21+
class Routes(Protocol):
1622
def __call__(self, *routes: Route) -> ComponentType:
1723
...
1824

1925

20-
def bind(backend: BackendImplementation) -> Router:
26+
def configure(
27+
implementation: BackendImplementation[Any] | Callable[[], Location]
28+
) -> Routes:
29+
if isinstance(implementation, BackendImplementation):
30+
use_location = implementation.use_location
31+
elif callable(implementation):
32+
use_location = implementation
33+
else:
34+
raise TypeError(
35+
"Expected a BackendImplementation or "
36+
f"`use_location` hook, not {implementation}"
37+
)
38+
2139
@component
22-
def Router(*routes: Route):
23-
initial_location = backend.use_location()
40+
def Router(*routes: Route) -> ComponentType | None:
41+
initial_location = use_location()
2442
location, set_location = use_state(initial_location)
2543
for p, r in _compile_routes(routes):
26-
if p.match(location.pathname):
44+
match = p.match(location.pathname)
45+
if match:
2746
return _LocationStateContext(
2847
r.element,
29-
value=(location, set_location),
30-
key=r.path,
48+
value=_LocationState(location, set_location, match),
49+
key=p.pattern,
3150
)
3251
return None
3352

3453
return Router
3554

3655

37-
def use_location() -> str:
38-
return _use_location_state()[0]
56+
def use_location() -> Location:
57+
return _use_location_state().location
58+
59+
60+
def use_match() -> re.Match[str]:
61+
return _use_location_state().match
3962

4063

4164
@dataclass
4265
class Route:
43-
path: str | re.Pattern
66+
path: str | re.Pattern[str]
4467
element: Any
4568

4669

4770
@component
48-
def Link(*attributes_or_children: VdomAttributesAndChildren, to: str) -> None:
71+
def Link(*attributes_or_children: VdomAttributesAndChildren, to: str) -> VdomDict:
4972
attributes, children = coalesce_attributes_and_children(attributes_or_children)
50-
set_location = _use_location_state()[1]
51-
return _Link(
52-
{
53-
**attributes,
54-
"to": to,
55-
"onClick": lambda event: set_location(Location(**event)),
56-
},
57-
*children,
58-
)
59-
60-
61-
def _compile_routes(routes: Sequence[Route]) -> Iterator[tuple[re.Pattern, Route]]:
73+
set_location = _use_location_state().set_location
74+
attrs = {
75+
**attributes,
76+
"to": to,
77+
"onClick": lambda event: set_location(Location(**event)),
78+
}
79+
return _Link(attrs, *children)
80+
81+
82+
def _compile_routes(routes: Sequence[Route]) -> Iterator[tuple[re.Pattern[str], Route]]:
6283
for r in routes:
6384
if isinstance(r.path, re.Pattern):
6485
yield r.path, r
@@ -75,9 +96,14 @@ def _use_location_state() -> _LocationState:
7596
return location_state
7697

7798

78-
_LocationSetter = Callable[[str], None]
79-
_LocationState = tuple[Location, _LocationSetter]
80-
_LocationStateContext: type[Context[_LocationState | None]] = create_context(None)
99+
@dataclass
100+
class _LocationState:
101+
location: Location
102+
set_location: Callable[[Location], None]
103+
match: re.Match[str]
104+
105+
106+
_LocationStateContext: Context[_LocationState | None] = create_context(None)
81107

82108
_Link = export(
83109
module_from_file(

‎noxfile.py

Copy file name to clipboard
+56Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from pathlib import Path
2+
3+
from nox import Session, session
4+
5+
ROOT = Path(".")
6+
REQUIREMENTS_DIR = ROOT / "requirements"
7+
8+
9+
@session
10+
def format(session: Session) -> None:
11+
install_requirements(session, "style")
12+
session.run("black", ".")
13+
session.run("isort", ".")
14+
15+
16+
@session
17+
def test(session: Session) -> None:
18+
session.notify("test_style")
19+
session.notify("test_types")
20+
session.notify("test_suite")
21+
22+
23+
@session
24+
def test_style(session: Session) -> None:
25+
install_requirements(session, "check-style")
26+
session.run("black", "--check", ".")
27+
session.run("isort", "--check", ".")
28+
session.run("flake8", ".")
29+
30+
31+
@session
32+
def test_types(session: Session) -> None:
33+
install_requirements(session, "check-types")
34+
session.run("mypy", "--strict", "idom_router")
35+
36+
37+
@session
38+
def test_suite(session: Session) -> None:
39+
install_requirements(session, "test-env")
40+
session.run("playwright", "install", "chromium")
41+
42+
posargs = session.posargs[:]
43+
44+
if "--no-cov" in session.posargs:
45+
posargs.remove("--no-cov")
46+
session.log("Coverage won't be checked")
47+
session.install(".")
48+
else:
49+
posargs += ["--cov=idom_router", "--cov-report=term"]
50+
session.install("-e", ".")
51+
52+
session.run("pytest", "tests", *posargs)
53+
54+
55+
def install_requirements(session: Session, name: str) -> None:
56+
session.install("-r", str(REQUIREMENTS_DIR / f"{name}.txt"))

‎pyproject.toml

Copy file name to clipboardExpand all lines: pyproject.toml
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,14 @@ build-backend = "setuptools.build_meta"
66
[tool.pytest.ini_options]
77
testpaths = "tests"
88
asyncio_mode = "auto"
9+
10+
11+
[tool.isort]
12+
profile = "black"
13+
14+
15+
[tool.mypy]
16+
ignore_missing_imports = true
17+
warn_unused_configs = true
18+
warn_redundant_casts = true
19+
warn_unused_ignores = true

‎requirements.txt

Copy file name to clipboard
+5-4Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
twine
2-
pytest
3-
pytest-asyncio
4-
idom[testing,starlette]
1+
-r requirements/check-style.txt
2+
-r requirements/check-types.txt
3+
-r requirements/nox-deps.txt
4+
-r requirements/pkg-deps.txt
5+
-r requirements/test-env.txt

‎requirements/check-style.txt

Copy file name to clipboard
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
black
2+
flake8
3+
flake8_idom_hooks
4+
isort

‎requirements/check-types.txt

Copy file name to clipboard
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mypy
2+
idom

‎requirements/nox-deps.txt

Copy file name to clipboard
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nox

‎requirements/pkg-deps.txt

Copy file name to clipboard
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
idom >=0.40.2,<0.41
2+
typing_extensions

‎requirements/test-env.txt

Copy file name to clipboard
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
twine
2+
pytest
3+
pytest-asyncio
4+
pytest-cov
5+
idom[testing,starlette]

‎setup.cfg

Copy file name to clipboard
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,21 @@
11
[bdist_wheel]
22
universal=1
3+
4+
[flake8]
5+
ignore = E203, E266, E501, W503, F811, N802
6+
max-line-length = 88
7+
extend-exclude =
8+
.nox
9+
venv
10+
.venv
11+
tests/cases/*
12+
13+
[coverage:report]
14+
fail_under = 100
15+
show_missing = True
16+
skip_covered = True
17+
sort = Miss
18+
exclude_lines =
19+
pragma: no cover
20+
\.\.\.
21+
raise NotImplementedError

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.