// R2「裸 <button> 该用 Button」判据的自测。
//
// 判据真源 = scripts/lib/native-button-r2.mjs，由两个消费方共用：
//   · scripts/audit-canonical-compliance.mjs 的 R2（闸）
//   · scripts/ds-health-scan-consumers.mjs 的 DIM-U1 组件合规率分母（观测器）
// 抽出共享真源的**全部意义就是两边同口径**，所以本文件除了正/负例，还钉住
// 「豁免语义」与「近似边界」—— 后者是刻意保留的行为，不是待修 bug，
// 收紧它必须两个消费方一起动（见 lib 头注释）。

import { describe, expect, it } from 'vitest'
// @ts-expect-error — plain ESM JS lib without .d.ts
import { countNativeButtons, isBareNativeButton, isDisclosureTrigger } from '../scripts/lib/native-button-r2.mjs'

function at(text: string) {
  return text.indexOf('<button')
}

describe('native-button R2 判据', () => {
  it('裸 <button> 命中（= 该用 DS Button 却没用）', () => {
    const t = '<button type="button" class="x">go</button>'
    expect(isBareNativeButton(t, at(t))).toBe(true)
    expect(isDisclosureTrigger(t, at(t))).toBe(false)
  })

  it('开标签带 aria-expanded 的 disclosure trigger 被豁免', () => {
    const t = '<button type="button" aria-expanded="false">menu</button>'
    expect(isBareNativeButton(t, at(t))).toBe(false)
    expect(isDisclosureTrigger(t, at(t))).toBe(true)
  })

  it('Vue 动态绑定 :aria-expanded 同样豁免（原闸行为，未改）', () => {
    const t = '<button type="button" :aria-expanded="isOpen">menu</button>'
    expect(isBareNativeButton(t, at(t))).toBe(false)
  })

  it('aria-expanded 出现在**元素内容里**不算豁免（必须在开标签内）', () => {
    const t = '<button type="button">aria-expanded="false"</button>'
    expect(isBareNativeButton(t, at(t))).toBe(true)
  })

  it('countNativeButtons 三个数并排：bare + disclosure = total', () => {
    const t = `
      <button>a</button>
      <button aria-expanded="true">b</button>
      <button class="c">c</button>
    `
    expect(countNativeButtons(t)).toEqual({ bare: 2, disclosure: 1, total: 3 })
  })

  it('零 <button> 时三个数都是 0（阴性对照 —— 与「判据坏了」可区分）', () => {
    expect(countNativeButtons('<div>no buttons here</div>')).toEqual({ bare: 0, disclosure: 0, total: 0 })
  })

  it('开标签不完整（截断文本）两边都不计，不抛错', () => {
    const t = '<button type="button" aria-'
    expect(isBareNativeButton(t, at(t))).toBe(false)
    expect(isDisclosureTrigger(t, at(t))).toBe(false)
    expect(countNativeButtons(t)).toEqual({ bare: 0, disclosure: 0, total: 0 })
  })

  it('⚠️ 已知近似：属性值里的 `>` 会提前截断开标签 —— 钉住现状，收紧要两个消费方一起动', () => {
    // `v-if="a > b"` 里的 `>` 被当成开标签结束 ⇒ 后面的 aria-expanded 看不见 ⇒ 判为裸。
    // 这是 audit-canonical-compliance 自 R2 落地起的行为，抽取时逐字保留。
    const t = '<button v-if="a > b" aria-expanded="true">x</button>'
    expect(isBareNativeButton(t, at(t))).toBe(true)
  })
})
