diff --git a/data/samples/html/dark_dev.html b/data/samples/html/dark_dev.html index 292e3ac..d1ccd0b 100644 --- a/data/samples/html/dark_dev.html +++ b/data/samples/html/dark_dev.html @@ -1,25 +1,208 @@ - + + + + Dev Notes - -

Dev Notes

- -
+
+

~/blog $ cat README.md

+

Dev Notes

+

Ship small PRs. Keep the feedback loop tight. Debug in the dark.

+
+ +
-

Ship small PRs

Keep changes reviewable and tested.

+
+

Ship small PRs

+

2026-07-28 · 4 min read

+

Keep changes reviewable and tested. Prefer a focused diff over a weekend mega-merge that nobody can reason about.

+
fn main() {
+    println!("reviewable > clever");
+}
+
+ rust + ci +
+
+
+

Typed boundaries beat tribal knowledge

+

2026-07-12 · 6 min read

+

Document contracts in types and tests. When onboarding gets expensive, your interfaces were never clear enough.

+
export function claim(issue: number) {
+  return { status: "claimed", issue };
+}
+
+ typescript + python +
+
+
+

Night-shift checklist

+

2026-06-30 · 3 min read

+

Reproduce once. Fix once. Leave a regression test. Push before sunrise.

+
+ go + ops +
+
- +
- + diff --git a/docs/screenshots/dark_dev-desktop.png b/docs/screenshots/dark_dev-desktop.png new file mode 100644 index 0000000..c35ea59 Binary files /dev/null and b/docs/screenshots/dark_dev-desktop.png differ diff --git a/docs/screenshots/dark_dev-mobile.png b/docs/screenshots/dark_dev-mobile.png new file mode 100644 index 0000000..e97de2d Binary files /dev/null and b/docs/screenshots/dark_dev-mobile.png differ diff --git a/docs/screenshots/demo-dark_dev.png b/docs/screenshots/demo-dark_dev.png index c289c5e..8a0e62c 100644 Binary files a/docs/screenshots/demo-dark_dev.png and b/docs/screenshots/demo-dark_dev.png differ diff --git a/src/bloggereasy/cli.py b/src/bloggereasy/cli.py index 716a03a..8f9d0ef 100644 --- a/src/bloggereasy/cli.py +++ b/src/bloggereasy/cli.py @@ -129,7 +129,7 @@ def demo_cmd( template_for = { "portfolio.html": "portfolio", "news_portal.html": "news", - "dark_dev.html": "dark", + "dark_dev.html": "dark_dev", } for path in samples: out = root / f"{path.stem}.xml" @@ -329,6 +329,7 @@ def _validate_widgets(widgets: str) -> None: def _sample_for_template(template: str) -> Path: sample_map = { "dark": "dark_dev.html", + "dark_dev": "dark_dev.html", "docs": "docs_blog.html", "food_recipe": "food_recipe.html", "from-image": "portfolio.html", diff --git a/src/bloggereasy/gui/main_window.py b/src/bloggereasy/gui/main_window.py index ffece22..68da795 100644 --- a/src/bloggereasy/gui/main_window.py +++ b/src/bloggereasy/gui/main_window.py @@ -420,7 +420,7 @@ def _pick_sample(self) -> None: mapping = { "portfolio.html": "portfolio", "news_portal.html": "news", - "dark_dev.html": "dark", + "dark_dev.html": "dark_dev", "magazine.html": "magazine", } self.template.setCurrentText(mapping.get(self._html_path.name, "simple")) @@ -672,7 +672,7 @@ def run_demo_batch(self) -> None: template_for = { "portfolio.html": "portfolio", "news_portal.html": "news", - "dark_dev.html": "dark", + "dark_dev.html": "dark_dev", "magazine.html": "magazine", } for path in samples: diff --git a/src/bloggereasy/theme/presets.py b/src/bloggereasy/theme/presets.py index 36bae81..e638f44 100644 --- a/src/bloggereasy/theme/presets.py +++ b/src/bloggereasy/theme/presets.py @@ -62,6 +62,12 @@ "dense": False, "accent": "#0055aa", }, + "dark_dev": { + "layout_hint": "two-column", + "dark": True, + "dense": False, + "accent": "#38bdf8", + }, } @@ -77,7 +83,7 @@ def apply_preset(structure: PageStructure | dict, template: str) -> dict: out["features"] = feats if preset.get("dark"): out = apply_dark_variant(out) - if preset.get("accent") and not preset.get("dark"): + if preset.get("accent"): colors = dict(out.get("colors") or {}) colors["primary"] = preset["accent"] out["colors"] = colors diff --git a/tests/test_theme_dark_dev.py b/tests/test_theme_dark_dev.py new file mode 100644 index 0000000..416ed3f --- /dev/null +++ b/tests/test_theme_dark_dev.py @@ -0,0 +1,56 @@ +"""Theme pack sample: dark_dev (Fixes #24). + +Verifies the dark_dev preset generates valid Blogger XML from the +self-contained HTML fixture, containing a b:skin block and a Blog widget. +""" + +from __future__ import annotations + +from pathlib import Path + +from bloggereasy.integrations.sdk import generate_from_html +from bloggereasy.theme.presets import PRESETS +from bloggereasy.theme.validate import validate_theme_file + +SAMPLES = Path(__file__).resolve().parents[1] / "data" / "samples" / "html" + + +def test_dark_dev_preset_registered() -> None: + assert "dark_dev" in PRESETS + assert PRESETS["dark_dev"]["dark"] is True + assert PRESETS["dark_dev"]["accent"] == "#38bdf8" + assert PRESETS["dark_dev"]["layout_hint"] == "two-column" + + +def test_dark_dev_sample_exists() -> None: + src = SAMPLES / "dark_dev.html" + assert src.is_file() + html = src.read_text(encoding="utf-8") + assert "Dev Notes" in html + assert "#0b1220" in html or "#0B1220" in html + assert "sidebar" in html + + +def test_gen_html_dark_dev_produces_skin_and_blog_widget(tmp_path: Path) -> None: + src = SAMPLES / "dark_dev.html" + out = tmp_path / "dark_dev.xml" + result = generate_from_html(src, out, template="dark_dev") + + assert result["validation"]["ok"], result["validation"] + assert out.exists() + + structure = result["structure"] + assert structure["layout"] == "two-column" + assert structure.get("features", {}).get("dark") is True + + xml = out.read_text(encoding="utf-8") + assert "xmlns:b=" in xml + assert "b:skin" in xml + assert "type='Blog'" in xml or 'type="Blog"' in xml + # dark_dev accent + dark surface should land in the skin + assert "38bdf8" in xml + assert "#0f172a" in xml or "0f172a" in xml + assert "Template: dark_dev" in xml + + v = validate_theme_file(out) + assert v["ok"] is True diff --git a/tests/test_theme_snapshots.py b/tests/test_theme_snapshots.py index fd434f6..84ba98f 100644 --- a/tests/test_theme_snapshots.py +++ b/tests/test_theme_snapshots.py @@ -9,7 +9,7 @@ def test_dark_and_magazine_generate_valid_xml(tmp_path: Path) -> None: samples = Path("data/samples/html") cases = [ - ("dark_dev.html", "dark"), + ("dark_dev.html", "dark_dev"), ("magazine.html", "magazine"), ("contact_card.html", "simple"), ("resume_cv.html", "simple"), @@ -26,8 +26,8 @@ def test_dark_and_magazine_generate_valid_xml(tmp_path: Path) -> None: xml = out.read_text(encoding="utf-8") assert "b:skin" in xml or "skin" in xml.lower() assert "Blog" in xml - # dark preset should push dark-ish background into skin - if tmpl == "dark": + # dark / dark_dev presets should push dark-ish background into skin + if tmpl in {"dark", "dark_dev"}: assert "#0f172a" in xml or "0f172a" in xml v = validate_theme_file(out) assert v["ok"] is True