| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- import assert from 'node:assert/strict'
- import { readFileSync } from 'node:fs'
- import { parse } from '@vue/compiler-sfc'
- import { baseParse } from '@vue/compiler-dom'
- // Focused static/logic checks for the toolbar request; no server or browser.
- const source = readFileSync(new URL('../../../src/modules/cockpit/CockpitShell.vue', import.meta.url), 'utf8')
- const { descriptor, errors } = parse(source)
- assert.deepEqual(errors, [], 'Vue SFC must parse')
- const ast = baseParse(descriptor.template.content)
- const elements = []
- function visit(node, parent = null) {
- if (node.type === 1) elements.push({ node, parent })
- for (const child of node.children || []) visit(child, node.type === 1 ? node : parent)
- }
- visit(ast)
- const has = (node, name) => node.props.some((p) => (p.type === 6 && p.name === name) || (p.type === 7 && p.name === 'bind' && p.arg?.content === name))
- const cls = (node, name) => node.props.some((p) => p.type === 6 && p.name === 'class' && p.value.content.split(/\s+/).includes(name))
- const find = (predicate) => elements.find(({ node }) => predicate(node))?.node
- function within(node, ancestor) {
- while (node) {
- if (node === ancestor) return true
- node = elements.find((entry) => entry.node === node)?.parent
- }
- return false
- }
- const scope = find((n) => cls(n, 'cockpit-shell__scope'))
- const summary = find((n) => cls(n, 'cockpit-shell__status-summary'))
- const details = find((n) => has(n, 'data-status-details'))
- const refresh = find((n) => has(n, 'data-map-refresh'))
- assert.equal(elements.filter(({ node }) => has(node, 'data-status-toggle')).length, 1)
- assert.ok(within(details, summary), 'details belong to summary')
- for (const marker of ['data-map-summary-phase', 'data-section-board', 'data-ws-state', 'data-freshness']) {
- assert.ok(within(find((n) => has(n, marker)), details), `${marker} belongs to details`)
- }
- assert.equal(elements.filter(({ node }) => has(node, 'data-map-refresh')).length, 1)
- assert.ok(!within(refresh, details), 'refresh is outside details')
- assert.equal(scope.children.filter((n) => n.type === 1).at(-1), refresh, 'refresh is final toolbar control')
- assert.ok(!descriptor.template.content.includes('区内限位'))
- assert.ok(!descriptor.template.content.includes('{{ fogText }}'))
- assert.ok(!descriptor.template.content.includes('推送 · {{ runtimeStore.statusText }}'))
- // Execute the actual computed getters against controlled state (not token-presence checks).
- function getter(name) {
- const body = source.match(new RegExp(`const ${name} = computed\\(\\(\\) => \\{([\\s\\S]*?)\\n\\}\\)`))?.[1]
- assert.ok(body, `${name} getter exists`)
- return new Function('runtimeStore', 'overallFreshnessState', 'overallFreshnessLabel', 'mapSummaryView', body)
- }
- const text = getter('statusSummaryText')
- const tone = getter('statusSummaryTone')
- function checkState(view, phase, overall, expected, expectedTone) {
- const runtime = { freshness: { view, text: `fresh:${view}`, lastSuccessClock: '12:00:00' }, status: { state: 'open' }, statusText: 'ws:open' }
- const args = [runtime, { value: overall }, { value: 'partial warning' }, { value: { phase, label: `map:${phase}` } }]
- assert.equal(text(...args), expected)
- assert.equal(tone(...args), expectedTone)
- }
- checkState('current', 'complete', 'partial', 'partial warning', 'is-warning')
- for (const view of ['empty', 'stale', 'unavailable']) checkState(view, 'complete', 'current', `fresh:${view}`, 'is-warning')
- for (const phase of ['idle', 'loading', 'empty', 'failed', 'expired']) checkState('current', phase, 'current', `map:${phase}`, 'is-warning')
- checkState('current', 'complete', 'current', '更新 12:00:00', 'is-ok')
- const style = descriptor.styles.map((s) => s.content).join('\n')
- const rule = (selector) => style.slice(style.indexOf(`${selector} {`)).split('}')[0]
- assert.match(rule('.cockpit-shell__scope-left'), /overflow-x:\s*auto/)
- assert.match(rule('.cockpit-shell__status-details'), /max-height:/)
- assert.match(rule('.cockpit-shell__status-details'), /overflow:\s*auto/)
- assert.match(rule('.cockpit-shell__scope'), /overflow:\s*visible/)
- assert.match(rule('.cockpit-shell__scope'), /z-index:\s*3/)
- console.log('PASS toolbar AST nesting, rightmost refresh, removed diagnostics, summary state cases, and overflow guards')
|