diff --git a/core/tests/test_shipped_hints.py b/core/tests/test_shipped_hints.py new file mode 100644 index 00000000..0bf229f8 --- /dev/null +++ b/core/tests/test_shipped_hints.py @@ -0,0 +1,43 @@ +"""Every setting a module offers says what it does, and the words match the control. + +A setting with no hint leaves the person guessing; a hint that names a control that is not +there ("set it in the inspector") sends them looking for something that does not exist. +""" + +import pytest + + +@pytest.fixture(scope="module") +def shipped(comfyui): + from core import registry as registry_mod + return registry_mod.scan() + + +def _settings(registry): + for spec in registry.specs.values(): + for name, setting in (spec.settings or {}).items(): + yield spec.id, name, setting + + +def test_every_setting_has_a_hint(shipped): + bare = [f"{mod}.{name}" for mod, name, s in _settings(shipped) if not str(s.get("hint") or "").strip()] + assert not bare, f"settings with no hint: {bare}" + + +def test_no_two_rows_of_one_module_share_a_label(shipped): + from collections import Counter + twins = [] + for spec in shipped.specs.values(): + count = Counter(s.get("label") or n for n, s in (spec.settings or {}).items()) + twins += [f"{spec.id}: {label}" for label, n in count.items() if n > 1] + assert not twins, twins + + +def test_no_hint_points_at_the_inspector_for_a_control_it_does_not_have(): + from modules.output.render import library + text = " ".join(str(e.get("description", "")) for e in library.EFFECTS) + assert "inspector" not in text.lower() + + +def test_no_setting_hint_points_at_the_inspector(shipped): + assert not [f"{m}.{n}" for m, n, s in _settings(shipped) if "inspector" in str(s.get("hint", "")).lower()] diff --git a/modules/system/appearance/__init__.py b/modules/system/appearance/__init__.py deleted file mode 100644 index eb18473d..00000000 --- a/modules/system/appearance/__init__.py +++ /dev/null @@ -1,40 +0,0 @@ -"""Appearance: theme and grid density. - -The first real vertical slice, and deliberately the smallest one that exercises -the whole path -- announcement, schema, panel, values -- with no model, no -sampler and nothing that needs a GPU to be seen working. -""" - -ID = "appearance" -TITLE = "Appearance" -MOUNT = "settings.general" -STAGE = "load" -CATEGORY = "system" -STATUS = "proven" - -SETTINGS = { - "theme": { - "type": "enum", "default": "auto", - "label": "Colour scheme", "ui": "segmented", - "options": [ - {"value": "dark", "label": "Dark"}, - {"value": "light", "label": "Light"}, - {"value": "auto", "label": "Auto"}, - ], - }, - "density": { - "type": "int", "default": 0, "min": 0, "max": 4, "step": 1, - "label": "Media columns", - "hint": "0 fits as many as the panel allows.", - "ui": "stepper", - }, -} - - -def apply(values, context=None): - """Nothing to do at generation time: appearance is the browser's business. - - Declared anyway so the module has the same shape as every other one -- a - module core has to special-case is a module that will be forgotten. - """ - return context diff --git a/modules/system/appearance/ui.js b/modules/system/appearance/ui.js deleted file mode 100644 index 41a7efc0..00000000 --- a/modules/system/appearance/ui.js +++ /dev/null @@ -1,22 +0,0 @@ -// Appearance needs a little JavaScript, because its settings change the app -// rather than the generation. Most modules have no ui.js at all. - -export function setup({ values, on, shell }) { - const apply = (key, value) => { - if (key === "theme") shell.theme.set(value); - if (key === "density") shell.density.set(value); - }; - - // ADOPT what the app is already set to, rather than applying this module's - // declared defaults over it. - // - // Both of these are remembered by the browser and applied before any module - // exists -- the theme in the document head, so the first paint is already - // right. Writing the default back over that threw away an explicit choice on - // every single page load: pick Dark, reload, and the app came up in Auto with - // nothing said and nothing to see. - values.set("theme", shell.theme.get()); - values.set("density", shell.density.get()); - - return on(apply); -}