Merge remote-tracking branch 'origin/main' into r7256
This commit is contained in:
commit
96d8b99e65
24 changed files with 730 additions and 106 deletions
|
|
@ -208,6 +208,14 @@ def main():
|
|||
# text-ui-12p5 at scale 0.75; 16px means twMerge dropped the token.
|
||||
if not near(tab_font, 12.5 * 12 / 16):
|
||||
fail(f"hub tab font did not scale (twMerge drop?): {tab_font}")
|
||||
icon_w = page.evaluate(
|
||||
"() => { const el = document.querySelector('.size-icon');"
|
||||
" return el ? parseFloat(getComputedStyle(el).width) : null; }"
|
||||
)
|
||||
# Standard icons render at the UI font size itself below the
|
||||
# default, so setting 12 gives 12px glyphs.
|
||||
if not near(icon_w, 12):
|
||||
fail(f"size-icon did not match the UI font size below 16: {icon_w}")
|
||||
page.goto(BASE, wait_until = "domcontentloaded")
|
||||
page.wait_for_timeout(1500)
|
||||
open_appearance(page)
|
||||
|
|
|
|||
26
tests/studio/test_generation_length_ui_contract.py
Normal file
26
tests/studio/test_generation_length_ui_contract.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
CHAT_API = (
|
||||
Path(__file__).resolve().parents[2]
|
||||
/ "studio"
|
||||
/ "frontend"
|
||||
/ "src"
|
||||
/ "features"
|
||||
/ "chat"
|
||||
/ "api"
|
||||
/ "chat-api.ts"
|
||||
)
|
||||
|
||||
|
||||
def test_length_detection_classifies_visible_and_reasoning_content():
|
||||
source = CHAT_API.read_text(encoding = "utf-8")
|
||||
|
||||
assert "return value.trim().length > 0;" in source
|
||||
assert 'record.type === "thinking" || record.type === "reasoning"' in source
|
||||
assert 'record.type === "text" || record.type === "output_text"' in source
|
||||
assert "sawAssistantContent ||= contentState.hasAssistantContent;" in source
|
||||
assert "sawReasoningContent ||= contentState.hasReasoningContent;" in source
|
||||
|
|
@ -217,6 +217,24 @@ def test_local_picker_rows_require_chat_capability():
|
|||
assert "row.capabilities.canChat" in memo.group(0)
|
||||
|
||||
|
||||
def test_model_picker_toolbar_reflows_before_crossing_picker_edge():
|
||||
"""The content-sized section tabs and fixed-width dropdowns must reflow,
|
||||
while an oversized tab group must shrink labels but preserve its icons."""
|
||||
picker = _read("features/model-picker/components/model-selector/pickers.tsx")
|
||||
assert '"flex flex-wrap items-center gap-2"' in picker
|
||||
assert 'hasConnected ? "-mr-4" : "-mr-2"' in picker
|
||||
assert '"flex max-w-full min-w-0 flex-wrap items-center gap-2"' in picker
|
||||
|
||||
tabs = _read("features/model-picker/components/model-selector/pill-tabs.tsx")
|
||||
assert 'fit ? "min-w-0 shrink" : "min-w-0 flex-1"' in tabs
|
||||
assert '<span className="min-w-0 truncate">{tab.label}</span>' in tabs
|
||||
|
||||
selector = _read("features/model-picker/components/model-selector.tsx")
|
||||
assert 'icon={StarIcon} className="size-3.5 shrink-0"' in selector
|
||||
assert 'icon={Download01Icon} className="size-3.5 shrink-0"' in selector
|
||||
assert 'icon={CloudIcon} className="size-3.5 shrink-0"' in selector
|
||||
|
||||
|
||||
def test_native_picked_gguf_template_read_through_lease():
|
||||
"""A native (picked / drag-drop) GGUF's path lives only in its signed lease,
|
||||
and the picker chat-template GET has no lease plumbing, so the default
|
||||
|
|
|
|||
|
|
@ -98,6 +98,39 @@ def test_cn_knows_the_ui_typography_tokens():
|
|||
assert "/^ui-\\d+(p5)?$/.test(value)" in UTILS
|
||||
|
||||
|
||||
def test_icons_follow_the_ui_font_size_itself():
|
||||
"""Standard glyphs render at --ui-icon-size, which follows the UI font
|
||||
size itself: matches it below the 16px default and grows at half the
|
||||
change above it (setting 20 gives 18px icons), so icons track the text
|
||||
when shrinking and read slightly smaller than it when growing. Sub 16px
|
||||
glyphs keep their proportions through the same curve as a factor.
|
||||
Sonner toast text and action labels are text, so they follow at full
|
||||
rate everywhere."""
|
||||
assert (
|
||||
"--ui-icon-size: min(calc(1rem * var(--ui-font-scale, 1)), "
|
||||
"calc(0.5rem + 0.5rem * var(--ui-font-scale, 1)));"
|
||||
) in INDEX_CSS
|
||||
assert "--icon-size: var(--ui-icon-size);" in INDEX_CSS
|
||||
assert "& svg.size-4 { width: var(--ui-icon-size); height: var(--ui-icon-size); }" in INDEX_CSS
|
||||
assert "font-size: calc(13px * var(--ui-font-scale, 1)) !important;" in INDEX_CSS
|
||||
assert "font-size: calc(12px * var(--ui-font-scale, 1)) !important;" in INDEX_CSS
|
||||
# Menu rules that outrank the scoped block must carry the token too,
|
||||
# without flattening the smaller thinking ticks.
|
||||
assert "width: var(--ui-icon-size) !important;" in INDEX_CSS
|
||||
assert "svg:not(.unsloth-tick) {" in INDEX_CSS
|
||||
# Oversized art glyphs stay proportional instead of uniform.
|
||||
assert "& svg.size-6 { width: min(calc(1.5rem" in INDEX_CSS
|
||||
for scope in (
|
||||
"[data-slot='dropdown-menu-content']",
|
||||
"[data-slot='select-content']",
|
||||
"[data-slot='select-trigger']",
|
||||
"[data-slot='combobox-content']",
|
||||
"[data-sonner-toast]",
|
||||
".aui-root",
|
||||
):
|
||||
assert scope in INDEX_CSS
|
||||
|
||||
|
||||
def test_no_raw_pixel_text_utilities():
|
||||
offenders = []
|
||||
for path in _frontend_sources():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue