/* * SPDX-FileCopyrightText: syuilo and misskey-project * SPDX-License-Identifier: AGPL-3.0-only */ import { describe, expect, test } from 'vitest'; import { html, joinHtml, raw, Raw } from '../src/html'; describe('html', () => { test('escapes interpolated values by default', () => { const value = ''; expect(String(html`

${value}

`)).toBe('

<script>alert(1)</script>

'); }); test('escapes values used in attribute position', () => { const url = 'x">'; expect(String(html``)).toBe(''); }); test('leaves the static parts of the template untouched', () => { expect(String(html`

x

`)).toBe('

x

'); }); test('renders nullish values as an empty string', () => { expect(String(html`

${null}${undefined}

`)).toBe('

'); }); test('does not double-escape nested fragments', () => { const inner = html`${'a&b'}`; expect(String(html`

${inner}

`)).toBe('

a&b

'); }); // 配列をそのまま文字列化するとカンマ区切りで潰れる。実際に過去これで表が壊れた test('joins arrays without separators instead of stringifying them', () => { const items = [html`
  • 1
  • `, html`
  • 2
  • `]; expect(String(html``)).toBe(''); }); test('escapes array elements that are not fragments', () => { expect(String(html`

    ${['', '']}

    `)).toBe('

    <a><b>

    '); }); }); describe('raw', () => { test('embeds trusted markup without escaping', () => { expect(String(html``)).toBe(''); }); test('produces a Raw fragment', () => { expect(raw('x')).toBeInstanceOf(Raw); expect(html`x`).toBeInstanceOf(Raw); }); }); describe('joinHtml', () => { test('joins fragments with the given separator', () => { expect(String(joinHtml([html`
  • 1
  • `, html`
  • 2
  • `], '\n'))).toBe('
  • 1
  • \n
  • 2
  • '); }); test('returns an empty fragment for an empty list', () => { expect(String(joinHtml([], '\n'))).toBe(''); }); });