import { test } from 'node:test';
import assert from 'node:assert/strict';
import {
  escapeMarkdownInlineSequences,
  unescapeMarkdownInlineSequences,
  escapeMarkdownBlockSequences,
  unescapeMarkdownBlockSequences,
} from './utils';

const identity = (t: string): string => t;

test('escapeMarkdownInlineSequences backslash-escapes inline markdown chars', () => {
  assert.equal(escapeMarkdownInlineSequences('a*b'), 'a\\*b');
  assert.equal(escapeMarkdownInlineSequences('under_score'), 'under\\_score');
  // plain text without markdown chars is unchanged
  assert.equal(escapeMarkdownInlineSequences('plain text'), 'plain text');
});

test('inline escape/unescape round-trips', () => {
  for (const s of ['a*b*c', 'under_score', 'plain', 'mix *a* _b_']) {
    assert.equal(unescapeMarkdownInlineSequences(escapeMarkdownInlineSequences(s)), s);
  }
});

test('escapeMarkdownBlockSequences escapes leading block markers', () => {
  assert.equal(escapeMarkdownBlockSequences('# heading', identity), '\\# heading');
  assert.equal(escapeMarkdownBlockSequences('> quote', identity), '\\> quote');
});

test('block unescape passes non-escaped text through processPart', () => {
  assert.equal(unescapeMarkdownBlockSequences('plain', identity), 'plain');
  // a custom processPart is applied to the (non-escaped) text
  assert.equal(
    unescapeMarkdownBlockSequences('plain', (t) => t.toUpperCase()),
    'PLAIN',
  );
});

test('block escape/unescape round-trips', () => {
  for (const s of ['# h', '> quote', 'plain line']) {
    assert.equal(
      unescapeMarkdownBlockSequences(escapeMarkdownBlockSequences(s, identity), identity),
      s,
    );
  }
});
