mirror of
https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git
synced 2026-08-14 16:58:42 +00:00
Overhaul BM25 relevance, reasoning and data-quality contracts; refresh UI styles and framework guidance; add resilient text, chip, badge and micro-interaction guidance; strengthen release, provenance and catalog refresh gates; update bilingual documentation.
177 lines
8.0 KiB
Python
177 lines
8.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Freshness and migration contracts for native, desktop, and 3D stacks."""
|
|
|
|
import csv
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from urllib.parse import urlsplit
|
|
|
|
SCRIPTS_DIR = Path(__file__).resolve().parents[1]
|
|
if str(SCRIPTS_DIR) not in sys.path:
|
|
sys.path.insert(0, str(SCRIPTS_DIR))
|
|
|
|
from core import (DATA_DIR, STACK_CONFIG, STACK_CURRENT_APPLICABILITY,
|
|
search_stack) # noqa: E402
|
|
from validate_data import STACK_OFFICIAL_HOSTS # noqa: E402
|
|
|
|
STACKS = {
|
|
"react-native", "flutter", "swiftui", "jetpack-compose", "avalonia",
|
|
"uwp", "winui", "wpf", "uno", "javafx", "threejs", "laravel",
|
|
}
|
|
|
|
|
|
def _rows(stack):
|
|
path = DATA_DIR / STACK_CONFIG[stack]["file"]
|
|
with path.open(encoding="utf-8", newline="") as handle:
|
|
return list(csv.DictReader(handle))
|
|
|
|
|
|
class TestNativeDesktopStackFreshness(unittest.TestCase):
|
|
def test_rows_have_final_freshness_metadata(self):
|
|
for stack in STACKS:
|
|
for row in _rows(stack):
|
|
with self.subTest(stack=stack, row=row["No"]):
|
|
expected = "deprecated" if stack == "uwp" else "active"
|
|
self.assertEqual(row["Status"], expected)
|
|
self.assertTrue(row["Applies To"].startswith(
|
|
STACK_CURRENT_APPLICABILITY[stack]))
|
|
self.assertRegex(row["Verified At"], r"^\d{4}-\d{2}-\d{2}$")
|
|
self.assertEqual("legacy" in row["Applies To"], stack == "uwp")
|
|
|
|
def test_high_impact_rows_use_official_sources(self):
|
|
for stack in STACKS:
|
|
for row in _rows(stack):
|
|
if row["Severity"] not in {"Critical", "High"}:
|
|
continue
|
|
with self.subTest(stack=stack, row=row["No"]):
|
|
parsed = urlsplit(row["Docs URL"])
|
|
self.assertEqual(parsed.scheme, "https")
|
|
self.assertIn(parsed.hostname, STACK_OFFICIAL_HOSTS[stack])
|
|
|
|
def test_current_mobile_contracts(self):
|
|
cases = {
|
|
("react-native", "Hermes bundled default engine"): "hermes",
|
|
("flutter", "predictive back result callback"): "onpopinvokedwithresult",
|
|
("flutter", "accessible nonlinear text scaling"): "textscaler",
|
|
("swiftui", "multicolumn navigation sidebar detail"): "navigationsplitview",
|
|
}
|
|
for (stack, query), expected in cases.items():
|
|
with self.subTest(stack=stack):
|
|
result = search_stack(query, stack, max_results=1)
|
|
self.assertEqual(result["count"], 1)
|
|
recommended = " ".join(
|
|
result["results"][0][field]
|
|
for field in ("Guideline", "Do", "Code Good")
|
|
).casefold()
|
|
self.assertIn(expected, recommended)
|
|
|
|
def test_windows_current_and_maintenance_lanes_are_visible(self):
|
|
current = search_stack("new Windows desktop app Windows App SDK", "winui")
|
|
legacy = search_stack("UWP maintenance x:Bind migration", "uwp")
|
|
self.assertGreater(current["count"], 0)
|
|
self.assertGreater(legacy["count"], 0)
|
|
self.assertEqual({row["Status"] for row in current["results"]}, {"active"})
|
|
self.assertEqual({row["Status"] for row in legacy["results"]}, {"deprecated"})
|
|
self.assertTrue(any("winui" in " ".join(row.values()).casefold()
|
|
for row in legacy["results"]))
|
|
successor = search_stack(
|
|
"which Windows UI framework should a brand new app choose instead of legacy UWP",
|
|
"uwp", max_results=1,
|
|
)
|
|
self.assertEqual("Prefer WinUI 3 for new projects", successor["results"][0]["Guideline"])
|
|
|
|
def test_old_version_without_curated_rows_abstains(self):
|
|
cases = {
|
|
"react-native": "React Native 0.75 Hermes",
|
|
"flutter": "Flutter SDK 3.22 back navigation",
|
|
"swiftui": "iOS 15 SwiftUI navigation",
|
|
"avalonia": "Avalonia UI v11 storage picker",
|
|
"winui": "WinUI SDK 2 desktop app",
|
|
"javafx": "JavaFX SDK 21 table view",
|
|
"threejs": "Three.js r128 OrbitControls",
|
|
"laravel": "Laravel 12 validation",
|
|
}
|
|
for stack, query in cases.items():
|
|
with self.subTest(stack=stack):
|
|
self.assertEqual(search_stack(query, stack)["count"], 0)
|
|
|
|
def test_migration_intent_returns_current_replacements(self):
|
|
cases = {
|
|
"flutter": "replace deprecated WillPopScope with current Flutter API",
|
|
"react-native": "upgrade legacy Hermes configuration",
|
|
"threejs": "replace deprecated outputEncoding with current color space",
|
|
}
|
|
for stack, query in cases.items():
|
|
with self.subTest(stack=stack):
|
|
result = search_stack(query, stack)
|
|
self.assertGreater(result["count"], 0)
|
|
self.assertEqual({row["Status"] for row in result["results"]}, {"active"})
|
|
|
|
versioned_cases = {
|
|
"react-native": "upgrade React Native 0.75 to React Native 0.86 Hermes",
|
|
"flutter": "upgrade Flutter 3.22 to Flutter 3.44 predictive back",
|
|
"threejs": "upgrade Three.js r128 to r185 outputColorSpace",
|
|
}
|
|
for stack, query in versioned_cases.items():
|
|
with self.subTest(stack=stack, query=query):
|
|
result = search_stack(query, stack)
|
|
self.assertGreater(result["count"], 0)
|
|
self.assertEqual({row["Status"] for row in result["results"]}, {"active"})
|
|
|
|
def test_standalone_current_and_deprecated_identifiers_resolve_replacement(self):
|
|
cases = {
|
|
("flutter", "onPopInvokedWithResult"): "PopScope",
|
|
("flutter", "TextScaler"): "large fonts",
|
|
("threejs", "outputColorSpace"): "Color Space",
|
|
("threejs", "outputEncoding"): "Color Space",
|
|
}
|
|
for (stack, query), guideline in cases.items():
|
|
with self.subTest(stack=stack, query=query):
|
|
result = search_stack(query, stack, max_results=1)
|
|
self.assertEqual(result["count"], 1)
|
|
self.assertIn(guideline.casefold(), result["results"][0]["Guideline"].casefold())
|
|
|
|
def test_current_threejs_uses_supported_module_and_color_apis(self):
|
|
cases = {
|
|
"Three.js current OrbitControls addon import": "three/addons/",
|
|
"Three.js current renderer color space": "outputcolorspace",
|
|
}
|
|
for query, expected in cases.items():
|
|
with self.subTest(query=query):
|
|
result = search_stack(query, "threejs", max_results=1)
|
|
self.assertEqual(result["count"], 1)
|
|
recommended = " ".join(
|
|
result["results"][0][field]
|
|
for field in ("Guideline", "Do", "Code Good")
|
|
).casefold()
|
|
self.assertIn(expected, recommended)
|
|
|
|
def test_deprecated_symbols_are_not_recommended_by_current_rows(self):
|
|
forbidden = {
|
|
"react-native": ("hermes_enabled",),
|
|
"flutter": ("willpopscope", "onpopinvoked:", "textscalefactor"),
|
|
"swiftui": ("navigationview", "presentationmode"),
|
|
"winui": ("dispatcher.runasync", "system.windows"),
|
|
"uno": ("system.windows", 'requestedtheme="default"'),
|
|
"javafx": ("fxpermission", "javadoc/21"),
|
|
"threejs": (
|
|
"r128", "three.orbitcontrols", "outputencoding",
|
|
"three.srgbencoding", "examples/js/controls",
|
|
),
|
|
}
|
|
for stack, tokens in forbidden.items():
|
|
for row in _rows(stack):
|
|
if row["Status"] != "active":
|
|
continue
|
|
recommended = " ".join(
|
|
row[field] for field in ("Guideline", "Do", "Code Good")
|
|
).casefold()
|
|
for token in tokens:
|
|
with self.subTest(stack=stack, row=row["No"], token=token):
|
|
self.assertNotIn(token, recommended)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|