cli icon indicating copy to clipboard operation
cli copied to clipboard

Custom matcher for Markdown tables

Open matejchalk opened this issue 1 year ago • 0 comments

Motivation

As a developer, I want a convenient way to test if a Markdown string contains a table with specific cell content.

Because table cells are padded with spaces according to columns alignments (since #755), matching the content of all tables in a row is a bit tricky:

// 👇 this doesn't take into account padding within `| ... |` cells
expect(md).toMatch('|🏷 Category|⭐ Score|🛡 Audits|');

// 👇 this regex ignores the padding, but it isn't very readable
expect(md).toMatch(/\|\s*🏷 Category\s*\|\s*⭐ Score\s*\|\s*🛡 Audits\s*\|/);

Proposed solution

Create a custom matcher which abstracts away the formatting details.

So instead of the /\|\s*...\s*\|\s*...\s*\|\s*...\s*\|/ regular expression above, the tests would be simplified to:

// 👇 checks that there is some MD table row with these cell contents, regardless of spaces between bars 
expect(md).toContainMarkdownTableRow(['🏷 Category', '⭐ Score', '🛡 Audits']);

The matcher should live in the test-setup Nx project and be strongly typed using a declaration file linked via tsconfig.test.json (see docs):

vitest.d.ts example

/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-empty-interface, @typescript-eslint/no-shadow, @typescript-eslint/no-unused-vars */
import type { Assertion, AsymmetricMatchersContaining } from 'vitest';

// see Vitest guide: https://vitest.dev/guide/extending-matchers

interface CustomMatchers<R = unknown> {
  toContainMarkdownTableRow: (cells: string[]) => void;
  // ... declarations of other matchers ...
}

declare module 'vitest' {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}

// HACK: prevents IDEs removing "unused" types in import optimization
const x: Assertion | AsymmetricMatchersContaining = {};

Similar issues

  • #552
  • #744

matejchalk avatar Jul 22 '24 07:07 matejchalk