Compare commits
8 commits
9728e764e9
...
f41f8e28e5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f41f8e28e5 | ||
|
|
c3b749ec37 | ||
|
|
9b04902825 | ||
|
|
49a21ca9cf | ||
|
|
0ae116afa9 | ||
|
|
b0e7089389 | ||
|
|
eb51024ca0 | ||
|
|
c3d5983d23 |
7 changed files with 69 additions and 11 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[project]
|
||||
name = "teilchensammler-cli"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
description = "Build up and maintain an inventory of electronics parts and tools."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12,<4.0"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from sqlmodel import SQLModel, create_engine
|
|||
|
||||
|
||||
sqlite_url = os.environ.get("DATABASE_URL", "sqlite:///database.db")
|
||||
engine = create_engine(sqlite_url, echo=True)
|
||||
engine = create_engine(sqlite_url, echo=False)
|
||||
|
||||
|
||||
def create_db_and_tables():
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ logging.basicConfig(
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SammlerApp(App[None]):
|
||||
class SammlerApp(App):
|
||||
async def on_mount(self) -> None:
|
||||
create_db_and_tables()
|
||||
_ = self.push_screen(AddInventoryScreen())
|
||||
|
|
|
|||
|
|
@ -37,14 +37,22 @@ async def make_teilchen_input(text: str) -> TeilchenCreate | None:
|
|||
import re
|
||||
from natsort import natsorted
|
||||
|
||||
text = text.strip()
|
||||
|
||||
if not text:
|
||||
logger.error("Empty text.")
|
||||
return None
|
||||
|
||||
name_end = text.find(".")
|
||||
if name_end == -1: # "." not in text
|
||||
logger.warning("Missing period '.' from text.")
|
||||
logger.debug("Could not find period symbol in input: %s", text)
|
||||
return None
|
||||
else:
|
||||
name = text[0:name_end]
|
||||
|
||||
if not name:
|
||||
logger.error("Could not extract name.")
|
||||
logger.warning("Could not extract name.")
|
||||
logger.debug("Could not extract name from input: %s", text)
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from textual.widgets import Button, DataTable, Footer, Header, Input, Static
|
|||
from .models import load_initial_data
|
||||
|
||||
|
||||
FAKE_DATA_HEADER = "pk Name Description Number Tags".split()
|
||||
TEILCHEN_DATA_HEADER = "pk Name Description Number Tags".split()
|
||||
|
||||
|
||||
class SearchBar(Static):
|
||||
|
|
@ -46,12 +46,12 @@ class SearchResults(Widget):
|
|||
yield DataTable(id="table-search-result", cursor_type="row", zebra_stripes=True)
|
||||
|
||||
async def on_mount(self) -> None:
|
||||
table: DataTable[None] = self.query_one(DataTable[None])
|
||||
_ = table.add_columns(*FAKE_DATA_HEADER)
|
||||
_ = table.add_rows(await load_initial_data())
|
||||
table: DataTable = self.query_one(DataTable)
|
||||
table.add_columns(*TEILCHEN_DATA_HEADER)
|
||||
table.add_rows(await load_initial_data())
|
||||
|
||||
|
||||
class AddInventoryScreen(Screen[None]):
|
||||
class AddInventoryScreen(Screen):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Header()
|
||||
yield SearchBar()
|
||||
|
|
|
|||
50
tests.py
50
tests.py
|
|
@ -1,4 +1,54 @@
|
|||
from typing import TypedDict
|
||||
import pytest
|
||||
import logging
|
||||
|
||||
from teilchensammler_cli.models import TeilchenCreate, make_teilchen_input
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def test_initial_layout(snap_compare):
|
||||
from teilchensammler_cli.main import app
|
||||
|
||||
assert snap_compare(app, terminal_size=(130, 40))
|
||||
|
||||
|
||||
class Teilchen(TypedDict):
|
||||
"""The things I do for my LSP..."""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
tags: str
|
||||
text: str
|
||||
number: int
|
||||
|
||||
|
||||
empty_teilchen: Teilchen = {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"tags": "",
|
||||
"text": "",
|
||||
"number": 1,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"example_input,expected",
|
||||
[
|
||||
("", None),
|
||||
("a", None),
|
||||
("a.", {"name": "a", "text": "a."}),
|
||||
("aa", None),
|
||||
("aa.", {"name": "aa", "text": "aa."}),
|
||||
],
|
||||
)
|
||||
async def test_teilchendata_must_include_period(
|
||||
example_input: str, expected: dict[str, str | int] | None
|
||||
) -> None:
|
||||
|
||||
thing = expected
|
||||
if expected:
|
||||
arguments = empty_teilchen | expected
|
||||
thing = TeilchenCreate(**arguments) # ty:ignore[invalid-argument-type]
|
||||
|
||||
assert await make_teilchen_input(example_input) == thing
|
||||
|
|
|
|||
2
uv.lock
generated
2
uv.lock
generated
|
|
@ -1249,7 +1249,7 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "teilchensammler-cli"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "ciso8601" },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue