Просмотр исходного кода

Merge pull request #8964 from weseek/imprv/148445-150048-vitest-reamrk-growi-directive

imprv: Convert unit test by tape to Vitest in remark-growi-directive
Yuki Takei 1 год назад
Родитель
Сommit
f880aacf7d

+ 5 - 0
.changeset/real-onions-vanish.md

@@ -0,0 +1,5 @@
+---
+"@growi/remark-growi-directive": minor
+---
+
+Convert unit test by tape to Vitest

+ 1 - 3
packages/remark-growi-directive/package.json

@@ -22,7 +22,7 @@
     "dev": "yarn build",
     "dev": "yarn build",
     "watch": "yarn tsc -w",
     "watch": "yarn tsc -w",
     "test": "cross-env NODE_ENV=test npm run test-coverage",
     "test": "cross-env NODE_ENV=test npm run test-coverage",
-    "test-api": "tape --conditions development test/**.test.js",
+    "test-api": "vitest run --coverage",
     "test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov npm run test-api",
     "test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov npm run test-api",
     "lint": "yarn eslint \"**/*.{cjs, js,jsx,ts,tsx}\"",
     "lint": "yarn eslint \"**/*.{cjs, js,jsx,ts,tsx}\"",
     "lint:fix": "yarn eslint \"**/*.{cjs, js,jsx,ts,tsx}\" --fix"
     "lint:fix": "yarn eslint \"**/*.{cjs, js,jsx,ts,tsx}\" --fix"
@@ -43,7 +43,6 @@
     "uvu": "^0.5.0"
     "uvu": "^0.5.0"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@types/tape": "^4.0.0",
     "c8": "^8.0.0",
     "c8": "^8.0.0",
     "html-void-elements": "^2.0.0",
     "html-void-elements": "^2.0.0",
     "is-hidden": "^2.0.0",
     "is-hidden": "^2.0.0",
@@ -51,7 +50,6 @@
     "micromark": "^4.0.0",
     "micromark": "^4.0.0",
     "remark": "^15.0.1",
     "remark": "^15.0.1",
     "rimraf": "^3.0.0",
     "rimraf": "^3.0.0",
-    "tape": "^5.0.0",
     "to-vfile": "^7.0.0",
     "to-vfile": "^7.0.0",
     "type-coverage": "^2.0.0",
     "type-coverage": "^2.0.0",
     "unist-util-remove-position": "^5.0.0"
     "unist-util-remove-position": "^5.0.0"

+ 411 - 457
packages/remark-growi-directive/test/mdast-util-growi-directive.test.js

@@ -1,19 +1,21 @@
 import { fromMarkdown } from 'mdast-util-from-markdown';
 import { fromMarkdown } from 'mdast-util-from-markdown';
 import { toMarkdown } from 'mdast-util-to-markdown';
 import { toMarkdown } from 'mdast-util-to-markdown';
-import test from 'tape';
 import { removePosition } from 'unist-util-remove-position';
 import { removePosition } from 'unist-util-remove-position';
+import { describe, it, expect } from 'vitest';
 
 
 import { DirectiveType } from '../src/mdast-util-growi-directive/consts.js';
 import { DirectiveType } from '../src/mdast-util-growi-directive/consts.js';
 import { directiveFromMarkdown, directiveToMarkdown } from '../src/mdast-util-growi-directive/index.js';
 import { directiveFromMarkdown, directiveToMarkdown } from '../src/mdast-util-growi-directive/index.js';
 import { directive } from '../src/micromark-extension-growi-directive/index.js';
 import { directive } from '../src/micromark-extension-growi-directive/index.js';
 
 
-test('markdown -> mdast', (t) => {
-  t.deepEqual(
-    fromMarkdown('a $b[c](d) e.', {
-      extensions: [directive()],
-      mdastExtensions: [directiveFromMarkdown],
-    }).children[0],
-    {
+
+describe('markdown -> mdast', () => {
+  it('should support directives (text)', () => {
+    expect(
+      fromMarkdown('a $b[c](d) e.', {
+        extensions: [directive()],
+        mdastExtensions: [directiveFromMarkdown],
+      }).children[0],
+    ).toEqual({
       type: 'paragraph',
       type: 'paragraph',
       children: [
       children: [
         {
         {
@@ -56,16 +58,16 @@ test('markdown -> mdast', (t) => {
         start: { line: 1, column: 1, offset: 0 },
         start: { line: 1, column: 1, offset: 0 },
         end: { line: 1, column: 14, offset: 13 },
         end: { line: 1, column: 14, offset: 13 },
       },
       },
-    },
-    'should support directives (text)',
-  );
+    });
+  });
 
 
-  t.deepEqual(
-    fromMarkdown('$a[b](c)', {
-      extensions: [directive()],
-      mdastExtensions: [directiveFromMarkdown],
-    }).children[0],
-    {
+  it('should support directives (leaf)', () => {
+    expect(
+      fromMarkdown('$a[b](c)', {
+        extensions: [directive()],
+        mdastExtensions: [directiveFromMarkdown],
+      }).children[0],
+    ).toEqual({
       type: DirectiveType.Leaf,
       type: DirectiveType.Leaf,
       name: 'a',
       name: 'a',
       attributes: { c: '' },
       attributes: { c: '' },
@@ -83,20 +85,53 @@ test('markdown -> mdast', (t) => {
         start: { line: 1, column: 1, offset: 0 },
         start: { line: 1, column: 1, offset: 0 },
         end: { line: 1, column: 9, offset: 8 },
         end: { line: 1, column: 9, offset: 8 },
       },
       },
-    },
-    'should support directives (leaf)',
-  );
+    });
+  });
+
+
+  it('should support content in a label', () => {
+    const tree = fromMarkdown('x $a[b *c*\nd]', {
+      extensions: [directive()],
+      mdastExtensions: [directiveFromMarkdown],
+    });
+
+    removePosition(tree, { force: true });
 
 
-  let tree = fromMarkdown('x $a[b *c*\nd]', {
-    extensions: [directive()],
-    mdastExtensions: [directiveFromMarkdown],
+    expect(tree).toEqual(
+      {
+        type: 'root',
+        children: [
+          {
+            type: 'paragraph',
+            children: [
+              { type: 'text', value: 'x ' },
+              {
+                type: DirectiveType.Text,
+                name: 'a',
+                attributes: {},
+                children: [
+                  { type: 'text', value: 'b ' },
+                  { type: 'emphasis', children: [{ type: 'text', value: 'c' }] },
+                  { type: 'text', value: '\nd' },
+                ],
+              },
+            ],
+          },
+        ],
+      },
+    );
   });
   });
 
 
-  removePosition(tree, { force: true });
 
 
-  t.deepEqual(
-    tree,
-    {
+  it('should support attributes', () => {
+    const tree = fromMarkdown('x $a(#b.c.d e=f g="h&i&unknown;j")', {
+      extensions: [directive()],
+      mdastExtensions: [directiveFromMarkdown],
+    });
+
+    removePosition(tree, { force: true });
+
+    expect(tree).toEqual({
       type: 'root',
       type: 'root',
       children: [
       children: [
         {
         {
@@ -106,485 +141,404 @@ test('markdown -> mdast', (t) => {
             {
             {
               type: DirectiveType.Text,
               type: DirectiveType.Text,
               name: 'a',
               name: 'a',
-              attributes: {},
-              children: [
-                { type: 'text', value: 'b ' },
-                { type: 'emphasis', children: [{ type: 'text', value: 'c' }] },
-                { type: 'text', value: '\nd' },
-              ],
+              attributes: {
+                '#b.c.d': '', e: 'f', g: 'h&i&unknown;j',
+              },
+              children: [],
             },
             },
           ],
           ],
         },
         },
       ],
       ],
-    },
-    'should support content in a label',
-  );
-
-  tree = fromMarkdown('x $a(#b.c.d e=f g="h&i&unknown;j")', {
-    extensions: [directive()],
-    mdastExtensions: [directiveFromMarkdown],
+    });
   });
   });
 
 
-  removePosition(tree, { force: true });
 
 
-  t.deepEqual(
-    tree,
-    {
+  it('should support EOLs in attributes', () => {
+    const tree = fromMarkdown('$a(b\nc="d\ne")', {
+      extensions: [directive()],
+      mdastExtensions: [directiveFromMarkdown],
+    });
+
+    removePosition(tree, { force: true });
+
+    expect(tree).toEqual({
       type: 'root',
       type: 'root',
       children: [
       children: [
         {
         {
           type: 'paragraph',
           type: 'paragraph',
           children: [
           children: [
-            { type: 'text', value: 'x ' },
             {
             {
               type: DirectiveType.Text,
               type: DirectiveType.Text,
               name: 'a',
               name: 'a',
-              attributes: {
-                '#b.c.d': '', e: 'f', g: 'h&i&unknown;j',
-              },
+              attributes: { b: '', c: 'd\ne' },
               children: [],
               children: [],
             },
             },
           ],
           ],
         },
         },
       ],
       ],
-    },
-    'should support attributes',
-  );
+    });
+  });
+});
 
 
-  tree = fromMarkdown('$a(b\nc="d\ne")', {
-    extensions: [directive()],
-    mdastExtensions: [directiveFromMarkdown],
+describe('mdast -> markdown', () => {
+  it('should try to serialize a directive (text) w/o `name`', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            // @ts-expect-error: `children`, `name` missing.
+            { type: DirectiveType.Text },
+            { type: 'text', value: ' b.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $ b.\n');
   });
   });
 
 
-  removePosition(tree, { force: true });
+  it('should serialize a directive (text) w/ `name`', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            // @ts-expect-error: `children` missing.
+            { type: DirectiveType.Text, name: 'b' },
+            { type: 'text', value: ' c.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b c.\n');
+  });
 
 
-  t.deepEqual(
-    tree,
-    {
-      type: 'root',
-      children: [
+  it('should serialize a directive (text) w/ `children`', () => {
+    expect(
+      toMarkdown(
         {
         {
           type: 'paragraph',
           type: 'paragraph',
           children: [
           children: [
+            { type: 'text', value: 'a ' },
             {
             {
               type: DirectiveType.Text,
               type: DirectiveType.Text,
-              name: 'a',
-              attributes: { b: '', c: 'd\ne' },
+              name: 'b',
+              children: [{ type: 'text', value: 'c' }],
+            },
+            { type: 'text', value: ' d.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b[c] d.\n');
+  });
+
+  it('should escape brackets in a directive (text) label', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              children: [{ type: 'text', value: 'c[d]e' }],
+            },
+            { type: 'text', value: ' f.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b[c\\[d\\]e] f.\n');
+  });
+
+  it('should support EOLs in a directive (text) label', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              children: [{ type: 'text', value: 'c\nd' }],
+            },
+            { type: 'text', value: ' e.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b[c\nd] e.\n');
+  });
+
+  it('should serialize a directive (text) w/ `attributes`', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              // @ts-expect-error: should contain only `string`s
+              attributes: {
+                c: 'd', e: 'f', g: '', h: null, i: undefined, j: 2,
+              },
               children: [],
               children: [],
             },
             },
+            { type: 'text', value: ' k.' },
           ],
           ],
         },
         },
-      ],
-    },
-    'should support EOLs in attributes',
-  );
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b(c="d" e="f" g j="2") k.\n');
+  });
 
 
-  t.end();
-});
+  it('should serialize a directive (text) w/ hash, dot notation attributes', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              attributes: { '#d': '', '.a.b.c': '', key: 'value' },
+              children: [],
+            },
+            { type: 'text', value: ' k.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b(#d .a.b.c key="value") k.\n');
+  });
 
 
-test('mdast -> markdown', (t) => {
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          // @ts-expect-error: `children`, `name` missing.
-          { type: DirectiveType.Text },
-          { type: 'text', value: ' b.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $ b.\n',
-    'should try to serialize a directive (text) w/o `name`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          // @ts-expect-error: `children` missing.
-          { type: DirectiveType.Text, name: 'b' },
-          { type: 'text', value: ' c.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b c.\n',
-    'should serialize a directive (text) w/ `name`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            children: [{ type: 'text', value: 'c' }],
-          },
-          { type: 'text', value: ' d.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b[c] d.\n',
-    'should serialize a directive (text) w/ `children`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            children: [{ type: 'text', value: 'c[d]e' }],
-          },
-          { type: 'text', value: ' f.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b[c\\[d\\]e] f.\n',
-    'should escape brackets in a directive (text) label',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            children: [{ type: 'text', value: 'c\nd' }],
-          },
-          { type: 'text', value: ' e.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b[c\nd] e.\n',
-    'should support EOLs in a directive (text) label',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            // @ts-expect-error: should contain only `string`s
-            attributes: {
-              c: 'd', e: 'f', g: '', h: null, i: undefined, j: 2,
+  it('should encode the quote in an attribute value (text)', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              attributes: { x: 'y"\'\r\nz' },
+              children: [],
             },
             },
-            children: [],
-          },
-          { type: 'text', value: ' k.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b(c="d" e="f" g j="2") k.\n',
-    'should serialize a directive (text) w/ `attributes`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            attributes: { '#d': '', '.a.b.c': '', key: 'value' },
-            children: [],
-          },
-          { type: 'text', value: ' k.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b(#d .a.b.c key="value") k.\n',
-    'should serialize a directive (text) w/ hash, dot notation attributes',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            attributes: { x: 'y"\'\r\nz' },
-            children: [],
-          },
-          { type: 'text', value: ' k.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b(x="y"\'\r\nz") k.\n',
-    'should encode the quote in an attribute value (text)',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            attributes: { x: 'y"\'\r\nz' },
-            children: [],
-          },
-          { type: 'text', value: ' k.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b(x="y"\'\r\nz") k.\n',
-    'should encode the quote in an attribute value (text)',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            attributes: { id: 'c#d' },
-            children: [],
-          },
-          { type: 'text', value: ' e.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b(id="c#d") e.\n',
-    'should not use the `id` shortcut if impossible characters exist',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            attributes: { 'c.d': '', 'e<f': '' },
-            children: [],
-          },
-          { type: 'text', value: ' g.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b(c.d e<f) g.\n',
-    'should not use the `class` shortcut if impossible characters exist',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [
-          { type: 'text', value: 'a ' },
-          {
-            type: DirectiveType.Text,
-            name: 'b',
-            attributes: {
-              'c.d': '', e: '', 'f<g': '', hij: '',
+            { type: 'text', value: ' k.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b(x="y&#x22;\'\r\nz") k.\n');
+  });
+
+  it('should not use the `id` shortcut if impossible characters exist', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              attributes: { id: 'c#d' },
+              children: [],
             },
             },
-            children: [],
-          },
-          { type: 'text', value: ' k.' },
-        ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a $b(c.d e f<g hij) k.\n',
-    'should not use the `class` shortcut if impossible characters exist (but should use it for classes that don’t)',
-  );
+            { type: 'text', value: ' e.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b(id="c#d") e.\n');
+  });
+
+  it('should not use the `class` shortcut if impossible characters exist', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              attributes: { 'c.d': '', 'e<f': '' },
+              children: [],
+            },
+            { type: 'text', value: ' g.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b(c.d e<f) g.\n');
+  });
 
 
-  t.deepEqual(
+  it('should not use the `class` shortcut if impossible characters exist (but should use it for classes that don\'t)', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [
+            { type: 'text', value: 'a ' },
+            {
+              type: DirectiveType.Text,
+              name: 'b',
+              attributes: {
+                'c.d': '', e: '', 'f<g': '', hij: '',
+              },
+              children: [],
+            },
+            { type: 'text', value: ' k.' },
+          ],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a $b(c.d e f<g hij) k.\n');
+  });
+
+  it('should try to serialize a directive (leaf) w/o `name`', () => {
     // @ts-expect-error: `children`, `name` missing.
     // @ts-expect-error: `children`, `name` missing.
-    toMarkdown({ type: DirectiveType.Leaf }, { extensions: [directiveToMarkdown] }),
-    '$\n',
-    'should try to serialize a directive (leaf) w/o `name`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      // @ts-expect-error: `children` missing.
-      { type: DirectiveType.Leaf, name: 'a' },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$a\n',
-    'should serialize a directive (leaf) w/ `name`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: DirectiveType.Leaf,
-        name: 'a',
-        children: [{ type: 'text', value: 'b' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$a[b]\n',
-    'should serialize a directive (leaf) w/ `children`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: DirectiveType.Leaf,
-        name: 'a',
-        children: [{ type: 'text', value: 'b' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$a[b]\n',
-    'should serialize a directive (leaf) w/ `children`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: DirectiveType.Leaf,
-        name: 'a',
-        children: [{ type: 'text', value: 'b\nc' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$a[b&#xA;c]\n',
-    'should serialize a directive (leaf) w/ EOLs in `children`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: DirectiveType.Leaf,
-        name: 'a',
-        attributes: { '#b': '', '.c.d': '', key: 'e\nf' },
-        children: [],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$a(#b .c.d key="e&#xA;f")\n',
-    'should serialize a directive (leaf) w/ EOLs in `attributes`',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [{ type: 'text', value: 'a$b' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a\\$b\n',
-    'should escape a `:` in phrasing when followed by an alpha',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
+    expect(
+      toMarkdown(
+        { type: DirectiveType.Leaf },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('$\n');
+  });
+
+  it('should serialize a directive (leaf) w/ `name`', () => {
+    // @ts-expect-error: `children` missing.
+    expect(
+      toMarkdown(
+        { type: DirectiveType.Leaf, name: 'a' },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('$a\n');
+  });
+
+  it('should serialize a directive (leaf) w/ `children`', () => {
+    expect(
+      toMarkdown(
+        {
+          type: DirectiveType.Leaf,
+          name: 'a',
+          children: [{ type: 'text', value: 'b' }],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('$a[b]\n');
+  });
+
+  it('should serialize a directive (leaf) w/ EOLs in `children`', () => {
+    expect(
+      toMarkdown(
+        {
+          type: DirectiveType.Leaf,
+          name: 'a',
+          children: [{ type: 'text', value: 'b\nc' }],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('$a[b&#xA;c]\n');
+  });
+
+  it('should serialize a directive (leaf) w/ EOLs in `attributes`', () => {
+    expect(
+      toMarkdown(
+        {
+          type: DirectiveType.Leaf,
+          name: 'a',
+          attributes: { '#b': '', '.c.d': '', key: 'e\nf' },
+          children: [],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('$a(#b .c.d key="e&#xA;f")\n');
+  });
+
+  it('should escape a `:` in phrasing when followed by an alpha', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [{ type: 'text', value: 'a$b' }],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('a\\$b\n');
+  });
+
+  it('should not escape a `:` in phrasing when followed by a non-alpha', () => {
+    expect(
+      toMarkdown({
         type: 'paragraph',
         type: 'paragraph',
         children: [{ type: 'text', value: 'a$9' }],
         children: [{ type: 'text', value: 'a$9' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a$9\n',
-    'should not escape a `:` in phrasing when followed by a non-alpha',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
+      }, { extensions: [directiveToMarkdown] }),
+    ).toBe('a$9\n');
+  });
+
+  it('should not escape a `:` in phrasing when preceded by a colon', () => {
+    expect(
+      toMarkdown({
         type: 'paragraph',
         type: 'paragraph',
         children: [{ type: 'text', value: 'a$c' }],
         children: [{ type: 'text', value: 'a$c' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    'a\\$c\n',
-    'should not escape a `:` in phrasing when preceded by a colon',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [{ type: 'text', value: '$\na' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$\na\n',
-    'should not escape a `:` at a break',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
-        type: 'paragraph',
-        children: [{ type: 'text', value: '$a' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '\\$a\n',
-    'should not escape a `:` at a break when followed by an alpha',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
+      }, { extensions: [directiveToMarkdown] }),
+    ).toBe('a\\$c\n');
+  });
+
+  it('should not escape a `:` at a break', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [{ type: 'text', value: '$\na' }],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('$\na\n');
+  });
+
+  it('should not escape a `:` at a break when followed by an alpha', () => {
+    expect(
+      toMarkdown(
+        {
+          type: 'paragraph',
+          children: [{ type: 'text', value: '$a' }],
+        },
+        { extensions: [directiveToMarkdown] },
+      ),
+    ).toBe('\\$a\n');
+  });
+
+  it('should escape a `:` at a break when followed by a colon', () => {
+    expect(
+      toMarkdown({
         type: 'paragraph',
         type: 'paragraph',
         children: [{ type: 'text', value: '$\na' }],
         children: [{ type: 'text', value: '$\na' }],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$\na\n',
-    'should escape a `:` at a break when followed by a colon',
-  );
-
-  t.deepEqual(
-    toMarkdown(
-      {
+      }, { extensions: [directiveToMarkdown] }),
+    ).toBe('$\na\n');
+  });
+
+  it('should escape a `:` after a text directive', () => {
+    expect(
+      toMarkdown({
         type: 'paragraph',
         type: 'paragraph',
         children: [
         children: [
           { type: DirectiveType.Text, name: 'red', children: [] },
           { type: DirectiveType.Text, name: 'red', children: [] },
           { type: 'text', value: '$' },
           { type: 'text', value: '$' },
         ],
         ],
-      },
-      { extensions: [directiveToMarkdown] },
-    ),
-    '$red$\n',
-    'should escape a `:` after a text directive',
-  );
+      }, { extensions: [directiveToMarkdown] }),
+    ).toBe('$red$\n');
+  });
 
 
-  t.end();
 });
 });

+ 693 - 904
packages/remark-growi-directive/test/micromark-extension-growi-directive.test.js

@@ -5,1048 +5,837 @@
 
 
 import { htmlVoidElements } from 'html-void-elements';
 import { htmlVoidElements } from 'html-void-elements';
 import { micromark } from 'micromark';
 import { micromark } from 'micromark';
-import test from 'tape';
+import { describe, it, expect } from 'vitest';
 
 
 import { DirectiveType } from '../src/mdast-util-growi-directive/consts.js';
 import { DirectiveType } from '../src/mdast-util-growi-directive/consts.js';
 import { directive as syntax, directiveHtml as html } from '../src/micromark-extension-growi-directive/index.js';
 import { directive as syntax, directiveHtml as html } from '../src/micromark-extension-growi-directive/index.js';
 
 
+
 const own = {}.hasOwnProperty;
 const own = {}.hasOwnProperty;
 
 
-test('micromark-extension-directive (syntax)', (t) => {
-  t.test('text', (t) => {
-    t.equal(
-      micromark('\\$a', options()),
-      '<p>$a</p>',
-      'should support an escaped colon which would otherwise be a directive',
-    );
 
 
-    t.equal(
-      micromark('\\$$a', options()),
-      '<p>$</p>',
-      'should support a directive after an escaped colon',
-    );
+describe('micromark-extension-directive (syntax)', () => {
+  describe('text', () => {
+    it('should support an escaped colon which would otherwise be a directive', () => {
+      expect(micromark('\\$a', options())).toBe('<p>$a</p>');
+    });
 
 
-    // t.equal(
-    //   micromark('a :$b', options()),
-    //   '<p>a :$b</p>',
-    //   'should not support a directive after a colon',
-    // );
+    it('should support a directive after an escaped colon', () => {
+      expect(micromark('\\$$a', options())).toBe('<p>$</p>');
+    });
 
 
-    t.equal(
-      micromark('$', options()),
-      '<p>$</p>',
-      'should not support a colon not followed by an alpha',
-    );
+    // it('should not support a directive after a colon', () => {
+    //   expect(micromark('a :$b', options())).toBe('<p>a :$b</p>');
+    // });
 
 
-    t.equal(
-      micromark('a $a', options()),
-      '<p>a </p>',
-      'should support a colon followed by an alpha',
-    );
+    it('should not support a colon not followed by an alpha', () => {
+      expect(micromark('$', options())).toBe('<p>$</p>');
+    });
 
 
-    t.equal(
-      micromark('$9', options()),
-      '<p>$9</p>',
-      'should not support a colon followed by a digit',
-    );
+    it('should support a colon followed by an alpha', () => {
+      expect(micromark('a $a', options())).toBe('<p>a </p>');
+    });
 
 
-    t.equal(
-      micromark('$-', options()),
-      '<p>$-</p>',
-      'should not support a colon followed by a dash',
-    );
+    it('should not support a colon followed by a digit', () => {
+      expect(micromark('$9', options())).toBe('<p>$9</p>');
+    });
 
 
-    t.equal(
-      micromark('$_', options()),
-      '<p>$_</p>',
-      'should not support a colon followed by an underscore',
-    );
+    it('should not support a colon followed by a dash', () => {
+      expect(micromark('$-', options())).toBe('<p>$-</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a9', options()),
-      '<p>a </p>',
-      'should support a digit in a name',
-    );
+    it('should not support a colon followed by an underscore', () => {
+      expect(micromark('$_', options())).toBe('<p>$_</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a-b', options()),
-      '<p>a </p>',
-      'should support a dash in a name',
-    );
+    it('should support a digit in a name', () => {
+      expect(micromark('a $a9', options())).toBe('<p>a </p>');
+    });
 
 
-    t.equal(
-      micromark('$a-', options()),
-      '<p>$a-</p>',
-      'should *not* support a dash at the end of a name',
-    );
+    it('should support a dash in a name', () => {
+      expect(micromark('a $a-b', options())).toBe('<p>a </p>');
+    });
 
 
-    t.equal(
-      micromark('a $a_b', options()),
-      '<p>a </p>',
-      'should support an underscore in a name',
-    );
+    it('should *not* support a dash at the end of a name', () => {
+      expect(micromark('$a-', options())).toBe('<p>$a-</p>');
+    });
 
 
-    t.equal(
-      micromark('$a_', options()),
-      '<p>$a_</p>',
-      'should *not* support an underscore at the end of a name',
-    );
+    it('should support an underscore in a name', () => {
+      expect(micromark('a $a_b', options())).toBe('<p>a </p>');
+    });
 
 
-    t.equal(
-      micromark('$a$', options()),
-      '<p>$a$</p>',
-      'should *not* support a colon right after a name',
-    );
+    it('should *not* support an underscore at the end of a name', () => {
+      expect(micromark('$a_', options())).toBe('<p>$a_</p>');
+    });
 
 
-    t.equal(
-      micromark('_$directive_', options()),
-      '<p><em>$directive</em></p>',
-      'should not interfere w/ emphasis (`_`)',
-    );
+    it('should *not* support a colon right after a name', () => {
+      expect(micromark('$a$', options())).toBe('<p>$a$</p>');
+    });
 
 
-    t.equal(
-      micromark('$a[', options()),
-      '<p>[</p>',
-      'should support a name followed by an unclosed `[`',
-    );
+    it('should not interfere w/ emphasis (`_`)', () => {
+      expect(micromark('_$directive_', options())).toBe('<p><em>$directive</em></p>');
+    });
 
 
-    t.equal(
-      micromark('$a(', options()),
-      '<p>(</p>',
-      'should support a name followed by an unclosed `(`',
-    );
+    it('should support a name followed by an unclosed `[`', () => {
+      expect(micromark('$a[', options())).toBe('<p>[</p>');
+    });
 
 
-    t.equal(
-      micromark('$a[b', options()),
-      '<p>[b</p>',
-      'should support a name followed by an unclosed `[` w/ content',
-    );
+    it('should support a name followed by an unclosed `(`', () => {
+      expect(micromark('$a(', options())).toBe('<p>(</p>');
+    });
 
 
-    t.equal(
-      micromark('$a(b', options()),
-      '<p>(b</p>',
-      'should support a name followed by an unclosed `(` w/ content',
-    );
+    it('should support a name followed by an unclosed `[` w/ content', () => {
+      expect(micromark('$a[b', options())).toBe('<p>[b</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a[]', options()),
-      '<p>a </p>',
-      'should support an empty label',
-    );
+    it('should support a name followed by an unclosed `(` w/ content', () => {
+      expect(micromark('$a(b', options())).toBe('<p>(b</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a[ \t]', options()),
-      '<p>a </p>',
-      'should support a whitespace only label',
-    );
+    it('should support an empty label', () => {
+      expect(micromark('a $a[]', options())).toBe('<p>a </p>');
+    });
 
 
-    t.equal(
-      micromark('$a[\n]', options()),
-      '<p></p>',
-      'should support an eol in an label',
-    );
+    it('should support a whitespace only label', () => {
+      expect(micromark('a $a[ \t]', options())).toBe('<p>a </p>');
+    });
 
 
-    t.equal(
-      micromark('$a[a b c]asd', options()),
-      '<p>asd</p>',
-      'should support content in an label',
-    );
+    it('should support an eol in an label', () => {
+      expect(micromark('$a[\n]', options())).toBe('<p></p>');
+    });
 
 
-    t.equal(
-      micromark('$a[a *b* c]asd', options()),
-      '<p>asd</p>',
-      'should support markdown in an label',
-    );
+    it('should support content in an label', () => {
+      expect(micromark('$a[a b c]asd', options())).toBe('<p>asd</p>');
+    });
 
 
-    t.equal(
-      micromark('a $b[c :d[e] f] g', options()),
-      '<p>a  g</p>',
-      'should support a directive in an label',
-    );
+    it('should support markdown in an label', () => {
+      expect(micromark('$a[a *b* c]asd', options())).toBe('<p>asd</p>');
+    });
 
 
-    t.equal(
-      micromark('$a[]asd', options()),
-      '<p>asd</p>',
-      'should support content after a label',
-    );
+    // == Resolved as text directive
+    // t.equal(
+    //   micromark('$a[]asd', options()),
+    //   '<p>$a[]asd</p>',
+    //   'should not support content after a label',
+    // );
 
 
-    t.equal(
-      micromark('a $a()', options()),
-      '<p>a </p>',
-      'should support empty attributes',
-    );
+    it('should support a directive in an label', () => {
+      expect(
+        micromark('a $b[c :d[e] f] g', options()),
+      ).toBe('<p>a  g</p>');
+    });
+
+    it('should support content after a label', () => {
+      expect(
+        micromark('$a[]asd', options()),
+      ).toBe('<p>asd</p>');
+    });
+
+    it('should support empty attributes', () => {
+      expect(
+        micromark('a $a()', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support whitespace only attributes', () => {
+      expect(
+        micromark('a $a( \t)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support an eol in attributes', () => {
+      expect(micromark('$a(\n)', options())).toBe('<p></p>');
+    });
+
+    it('should support attributes w/o values', () => {
+      expect(micromark('a $a(a b c)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attributes w/ unquoted values', () => {
+      expect(micromark('a $a(a=b c=d)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attributes w/ class shortcut', () => {
+      expect(micromark('a $a(.a .b)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attributes w/ class shortcut w/o whitespace between', () => {
+      expect(micromark('a $a(.a.b)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attributes w/ id shortcut', () => {
+      expect(micromark('a $a(#a #b)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attributes w/ id shortcut w/o whitespace between', () => {
+      expect(micromark('a $a(#a#b)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attributes w/ shortcuts combined w/ other attributes', () => {
+      expect(micromark('a $a(#a.b.c#d e f=g #h.i.j)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attrs which starts w/ continuous dots', () => {
+      expect(micromark('a $a(..b)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attrs which start w/ `#`', () => {
+      expect(micromark('a $a(.#b)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support attrs w/ (`.`)', () => {
+      expect(micromark('a $a(.)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support with the attr `(.a=b)`', () => {
+      expect(micromark('a $a(.a=b)', options())).toBe('<p>a </p>');
+    });
+
+    it('should support with the attr `(.a"b)`', () => {
+      expect(
+        micromark('a $a(.a"b)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support with the attr `(.a<b)`', () => {
+      expect(
+        micromark('a $a(.a<b)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support most characters in shortcuts', () => {
+      expect(
+        micromark('a $a(.a💚b)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support an underscore in attribute names', () => {
+      expect(
+        micromark('a $a(_)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support a colon in attribute names', () => {
+      expect(
+        micromark('a $a(xml:lang)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support double quoted attributes', () => {
+      expect(
+        micromark('a $a(a="b" c="d e f")', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support single quoted attributes', () => {
+      expect(
+        micromark("a $a(a='b' c='d e f')", options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support whitespace around initializers', () => {
+      expect(
+        micromark('a $a(a = b c\t=\t\'d\' f  =\r"g")', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should not support `=` to start an unquoted attribute value', () => {
+      expect(micromark('$a(b==)', options())).toBe('<p>(b==)</p>');
+    });
+
+    it('should not support a missing attribute value after `=`', () => {
+      expect(micromark('$a(b=)', options())).toBe('<p>(b=)</p>');
+    });
+
+    it('should not support an apostrophe in an unquoted attribute value', () => {
+      expect(micromark("$a(b=c')", options())).toBe("<p>(b=c')</p>");
+    });
+
+    it('should not support a grave accent in an unquoted attribute value', () => {
+      expect(micromark('$a(b=c`)', options())).toBe('<p>(b=c`)</p>');
+    });
+
+    it('should support most other characters in attribute keys', () => {
+      expect(
+        micromark('a $a(b💚=a💚b)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support most other characters in unquoted attribute values', () => {
+      expect(
+        micromark('a $a(b=a💚b)', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should not support an EOF in a quoted attribute value', () => {
+      expect(
+        micromark('$a(b="c', options()),
+      ).toBe('<p>(b=&quot;c</p>');
+    });
+
+    it('should support most other characters in quoted attribute values', () => {
+      expect(
+        micromark('a $a(b="a💚b")', options()),
+      ).toBe('<p>a </p>');
+    });
+
+    it('should support EOLs in quoted attribute values', () => {
+      expect(
+        micromark('$a(b="\nc\r  d")', options()),
+      ).toBe(
+        '<p></p>',
+      );
+    });
+
+    it('should not support an EOF after a quoted attribute value', () => {
+      expect(
+        micromark('$a(b="c"', options()),
+      ).toBe(
+        '<p>(b=&quot;c&quot;</p>',
+      );
+    });
 
 
-    t.equal(
-      micromark('a $a( \t)', options()),
-      '<p>a </p>',
-      'should support whitespace only attributes',
-    );
+  });
 
 
-    t.equal(
-      micromark('$a(\n)', options()),
-      '<p></p>',
-      'should support an eol in attributes',
-    );
+  describe('leaf', () => {
 
 
-    t.equal(
-      micromark('a $a(a b c)', options()),
-      '<p>a </p>',
-      'should support attributes w/o values',
-    );
+    it('should support a directive', () => {
+      expect(micromark('$b', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(a=b c=d)', options()),
-      '<p>a </p>',
-      'should support attributes w/ unquoted values',
-    );
+    it('should not support one colon', () => {
+      expect(micromark(':', options())).toBe('<p>:</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a(.a .b)', options()),
-      '<p>a </p>',
-      'should support attributes w/ class shortcut',
-    );
+    it('should not support two colons not followed by an alpha', () => {
+      expect(micromark('::', options())).toBe('<p>::</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a(.a.b)', options()),
-      '<p>a </p>',
-      'should support attributes w/ class shortcut w/o whitespace between',
-    );
+    it('should support two colons followed by an alpha', () => {
+      expect(micromark('$a', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(#a #b)', options()),
-      '<p>a </p>',
-      'should support attributes w/ id shortcut',
-    );
+    it('should not support two colons followed by a digit', () => {
+      expect(micromark('$9', options())).toBe('<p>$9</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a(#a#b)', options()),
-      '<p>a </p>',
-      'should support attributes w/ id shortcut w/o whitespace between',
-    );
+    it('should not support two colons followed by a dash', () => {
+      expect(micromark('$-', options())).toBe('<p>$-</p>');
+    });
 
 
-    t.equal(
-      micromark('a $a(#a.b.c#d e f=g #h.i.j)', options()),
-      '<p>a </p>',
-      'should support attributes w/ shortcuts combined w/ other attributes',
-    );
+    it('should support a digit in a name', () => {
+      expect(micromark('$a9', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(..b)', options()),
-      '<p>a </p>',
-      'should support attrs which starts w/ continuous dots',
-    );
+    it('should support a dash in a name', () => {
+      expect(micromark('$a-b', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(.#b)', options()),
-      '<p>a </p>',
-      'should support attrs which start w/ `#`',
-    );
+    // == Resolved as text directive
+    // it('should not support a name followed by an unclosed `[`', () => {
+    //   expect(micromark('$a[', options())).toBe('<p>$a[</p>');
+    // });
 
 
-    t.equal(
-      micromark('a $a(.)', options()),
-      '<p>a </p>',
-      'should support attrs w/ (`.`)',
-    );
+    // == Resolved as text directive
+    // it('should not support a name followed by an unclosed `{`', () => {
+    //   expect(micromark('$a{', options())).toBe('<p>$a{</p>');
+    // });
 
 
-    t.equal(
-      micromark('a $a(.a=b)', options()),
-      '<p>a </p>',
-      'should support with the attr `(.a=b)`',
-    );
+    // == Resolved as text directive
+    // it('should not support a name followed by an unclosed `[` w/ content', () => {
+    //   expect(micromark('$a[b', options())).toBe('<p>$a[b</p>');
+    // });
 
 
-    t.equal(
-      micromark('a $a(.a"b)', options()),
-      '<p>a </p>',
-      'should support with the attr `(.a"b)`',
-    );
+    // == Resolved as text directive
+    // it('should not support a name followed by an unclosed `{` w/ content', () => {
+    //   expect(micromark('$a{b', options())).toBe('<p>$a{b</p>');
+    // });
 
 
-    t.equal(
-      micromark('a $a(.a<b)', options()),
-      '<p>a </p>',
-      'should support with the attr `(.a<b)`',
-    );
+    it('should support an empty label', () => {
+      expect(micromark('$a[]', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(.a💚b)', options()),
-      '<p>a </p>',
-      'should support most characters in shortcuts',
-    );
+    it('should support a whitespace only label', () => {
+      expect(micromark('$a[ \t]', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(_)', options()),
-      '<p>a </p>',
-      'should support an underscore in attribute names',
-    );
+    // == Resolved as text directive
+    // it('should not support an eol in an label', () => {
+    //   expect(micromark('$a[\n]', options())).toBe('<p>$a[\n]</p>');
+    // });
 
 
-    t.equal(
-      micromark('a $a(xml:lang)', options()),
-      '<p>a </p>',
-      'should support a colon in attribute names',
-    );
+    it('should support content in an label', () => {
+      expect(micromark('$a[a b c]', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(a="b" c="d e f")', options()),
-      '<p>a </p>',
-      'should support double quoted attributes',
-    );
+    it('should support markdown in an label', () => {
+      expect(micromark('$a[a *b* c]', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark("a $a(a='b' c='d e f')", options()),
-      '<p>a </p>',
-      'should support single quoted attributes',
-    );
+    // == Resolved as text directive
+    // it('should not support content after a label', () => {
+    //   expect(micromark('$a[]asd', options())).toBe('<p>$a[]asd</p>');
+    // });
 
 
-    t.equal(
-      micromark('a $a(a = b c\t=\t\'d\' f  =\r"g")', options()),
-      '<p>a </p>',
-      'should support whitespace around initializers',
-    );
+    it('should support empty attributes', () => {
+      expect(micromark('$a()', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a(b==)', options()),
-      '<p>(b==)</p>',
-      'should not support `=` to start an unquoted attribute value',
-    );
+    it('should support whitespace only attributes', () => {
+      expect(micromark('$a( \t)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a(b=)', options()),
-      '<p>(b=)</p>',
-      'should not support a missing attribute value after `=`',
-    );
+    // == Resolved as text directive
+    // it('should not support an eol in attributes', () => {
+    //   expect(micromark('$a(\n)', options())).toBe('<p>$a(\n)</p>');
+    // });
 
 
-    t.equal(
-      micromark("$a(b=c')", options()),
-      "<p>(b=c')</p>",
-      'should not support an apostrophe in an unquoted attribute value',
-    );
+    it('should support attributes w/o values', () => {
+      expect(micromark('$a(a b c)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a(b=c`)', options()),
-      '<p>(b=c`)</p>',
-      'should not support a grave accent in an unquoted attribute value',
-    );
+    it('should support attributes w/ unquoted values', () => {
+      expect(micromark('$a(a=b c=d)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(b💚=a💚b)', options()),
-      '<p>a </p>',
-      'should support most other characters in attribute keys',
-    );
+    it('should support attributes w/ class shortcut', () => {
+      expect(micromark('$a(.a .b)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(b=a💚b)', options()),
-      '<p>a </p>',
-      'should support most other characters in unquoted attribute values',
-    );
+    it('should support attributes w/ id shortcut', () => {
+      expect(micromark('$a(#a #b)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a(b="c', options()),
-      '<p>(b=&quot;c</p>',
-      'should not support an EOF in a quoted attribute value',
-    );
+    it('should support most characters in shortcuts', () => {
+      expect(micromark('$a(.a💚b)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('a $a(b="a💚b")', options()),
-      '<p>a </p>',
-      'should support most other characters in quoted attribute values',
-    );
+    it('should support double quoted attributes', () => {
+      expect(micromark('$a(a="b" c="d e f")', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a(b="\nc\r  d")', options()),
-      '<p></p>',
-      'should support EOLs in quoted attribute values',
-    );
+    it('should support single quoted attributes', () => {
+      expect(micromark("$a(a='b' c='d e f')", options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a(b="c"', options()),
-      '<p>(b=&quot;c&quot;</p>',
-      'should not support an EOF after a quoted attribute value',
-    );
+    it('should support whitespace around initializers', () => {
+      expect(micromark("$a(a = b c\t=\t'd')", options())).toBe('');
+    });
 
 
-    t.end();
-  });
+    // == Resolved as text directive
+    // it('should not support EOLs around initializers', () => {
+    //   expect(micromark('$a(f  =\rg)', options())).toBe('<p>$a(f  =\rg)</p>');
+    // });
 
 
-  t.test('leaf', (t) => {
-    t.equal(micromark('$b', options()), '', 'should support a directive');
+    // == Resolved as text directive
+    // it('should not support `=` to start an unquoted attribute value', () => {
+    //   expect(micromark('$a(b==)', options())).toBe('<p>$a(b==)</p>');
+    // });
 
 
-    t.equal(
-      micromark(':', options()),
-      '<p>:</p>',
-      'should not support one colon',
-    );
+    it('should support most other characters in attribute keys', () => {
+      expect(micromark('$a(b💚=a💚b)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('::', options()),
-      '<p>::</p>',
-      'should not support two colons not followed by an alpha',
-    );
+    it('should support most other characters in unquoted attribute values', () => {
+      expect(micromark('$a(b=a💚b)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a', options()),
-      '',
-      'should support two colons followed by an alpha',
-    );
+    it('should not support an EOF in a quoted attribute value', () => {
+      expect(micromark('$a(b="c', options())).toBe('<p>(b=&quot;c</p>');
+    });
 
 
-    t.equal(
-      micromark('$9', options()),
-      '<p>$9</p>',
-      'should not support two colons followed by a digit',
-    );
+    it('should support most other characters in quoted attribute values', () => {
+      expect(micromark('$a(b="a💚b")', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$-', options()),
-      '<p>$-</p>',
-      'should not support two colons followed by a dash',
-    );
+    it('should not support EOLs in quoted attribute values', () => {
+      expect(micromark('$a(b="\nc\r  d")', options())).toBe('<p></p>');
+    });
 
 
-    t.equal(
-      micromark('$a9', options()),
-      '',
-      'should support a digit in a name',
-    );
+    it('should not support an EOF after a quoted attribute value', () => {
+      expect(micromark('$a(b="c"', options())).toBe('<p>(b=&quot;c&quot;</p>');
+    });
 
 
-    t.equal(
-      micromark('$a-b', options()),
-      '',
-      'should support a dash in a name',
-    );
+    it('should support whitespace after directives', () => {
+      expect(micromark('$a(b=c) \t ', options())).toBe('');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a[', options()),
-    //   '<p>$a[</p>',
-    //   'should not support a name followed by an unclosed `[`',
-    // );
+    it('should support a block quote after a leaf', () => {
+      expect(micromark('$a(b=c)\n>a', options())).toBe('<blockquote>\n<p>a</p>\n</blockquote>');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a{', options()),
-    //   '<p>$a{</p>',
-    //   'should not support a name followed by an unclosed `{`',
-    // );
+    it('should support code (fenced) after a leaf', () => {
+      expect(micromark('$a(b=c)\n```js\na', options())).toBe('<pre><code class="language-js">a\n</code></pre>\n');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a[b', options()),
-    //   '<p>$a[b</p>',
-    //   'should not support a name followed by an unclosed `[` w/ content',
-    // );
+    it('should support code (indented) after a leaf', () => {
+      expect(micromark('$a(b=c)\n    a', options())).toBe('<pre><code>a\n</code></pre>');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a{b', options()),
-    //   '<p>$a{b</p>',
-    //   'should not support a name followed by an unclosed `{` w/ content',
-    // );
+    it('should support a definition after a leaf', () => {
+      expect(micromark('$a(b=c)\n[a]: b', options())).toBe('');
+    });
 
 
-    t.equal(micromark('$a[]', options()), '', 'should support an empty label');
+    it('should support a heading (atx) after a leaf', () => {
+      expect(micromark('$a(b=c)\n# a', options())).toBe('<h1>a</h1>');
+    });
 
 
-    t.equal(
-      micromark('$a[ \t]', options()),
-      '',
-      'should support a whitespace only label',
-    );
+    it('should support a heading (setext) after a leaf', () => {
+      expect(micromark('$a(b=c)\na\n=', options())).toBe('<h1>a</h1>');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a[\n]', options()),
-    //   '<p>$a[\n]</p>',
-    //   'should not support an eol in an label',
-    // );
+    it('should support html after a leaf', () => {
+      expect(micromark('$a(b=c)\n<!-->', options())).toBe('<!-->');
+    });
 
 
-    t.equal(
-      micromark('$a[a b c]', options()),
-      '',
-      'should support content in an label',
-    );
+    it('should support a list after a leaf', () => {
+      expect(micromark('$a(b=c)\n* a', options())).toBe('<ul>\n<li>a</li>\n</ul>');
+    });
 
 
-    t.equal(
-      micromark('$a[a *b* c]', options()),
-      '',
-      'should support markdown in an label',
-    );
+    it('should support a paragraph after a leaf', () => {
+      expect(micromark('$a(b=c)\na', options())).toBe('<p>a</p>');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a[]asd', options()),
-    //   '<p>$a[]asd</p>',
-    //   'should not support content after a label',
-    // );
+    it('should support a thematic break after a leaf', () => {
+      expect(micromark('$a(b=c)\n***', options())).toBe('<hr />');
+    });
 
 
-    t.equal(
-      micromark('$a()', options()),
-      '',
-      'should support empty attributes',
-    );
+    it('should support a block quote before a leaf', () => {
+      expect(micromark('>a\n$a(b=c)', options())).toBe('<blockquote>\n<p>a</p>\n</blockquote>\n');
+    });
 
 
-    t.equal(
-      micromark('$a( \t)', options()),
-      '',
-      'should support whitespace only attributes',
-    );
+    it('should support code (fenced) before a leaf', () => {
+      expect(micromark('```js\na\n```\n$a(b=c)', options())).toBe('<pre><code class="language-js">a\n</code></pre>\n');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a(\n)', options()),
-    //   '<p>$a(\n)</p>',
-    //   'should not support an eol in attributes',
-    // );
+    it('should support code (indented) before a leaf', () => {
+      expect(micromark('    a\n$a(b=c)', options())).toBe('<pre><code>a\n</code></pre>\n');
+    });
 
 
-    t.equal(
-      micromark('$a(a b c)', options()),
-      '',
-      'should support attributes w/o values',
-    );
+    it('should support a definition before a leaf', () => {
+      expect(micromark('[a]: b\n$a(b=c)', options())).toBe('');
+    });
 
 
-    t.equal(
-      micromark('$a(a=b c=d)', options()),
-      '',
-      'should support attributes w/ unquoted values',
-    );
+    it('should support a heading (atx) before a leaf', () => {
+      expect(micromark('# a\n$a(b=c)', options())).toBe('<h1>a</h1>\n');
+    });
 
 
-    t.equal(
-      micromark('$a(.a .b)', options()),
-      '',
-      'should support attributes w/ class shortcut',
-    );
+    it('should support a heading (setext) before a leaf', () => {
+      expect(micromark('a\n=\n$a(b=c)', options())).toBe('<h1>a</h1>\n');
+    });
 
 
-    t.equal(
-      micromark('$a(#a #b)', options()),
-      '',
-      'should support attributes w/ id shortcut',
-    );
+    it('should support html before a leaf', () => {
+      expect(micromark('<!-->\n$a(b=c)', options())).toBe('<!-->\n');
+    });
 
 
-    t.equal(
-      micromark('$a(.a💚b)', options()),
-      '',
-      'should support most characters in shortcuts',
-    );
+    it('should support a list before a leaf', () => {
+      expect(micromark('* a\n$a(b=c)', options())).toBe('<ul>\n<li>a</li>\n</ul>\n');
+    });
 
 
-    t.equal(
-      micromark('$a(a="b" c="d e f")', options()),
-      '',
-      'should support double quoted attributes',
-    );
+    it('should support a paragraph before a leaf', () => {
+      expect(micromark('a\n$a(b=c)', options())).toBe('<p>a</p>\n');
+    });
 
 
-    t.equal(
-      micromark("$a(a='b' c='d e f')", options()),
-      '',
-      'should support single quoted attributes',
-    );
+    it('should support a thematic break before a leaf', () => {
+      expect(micromark('***\n$a(b=c)', options())).toBe('<hr />\n');
+    });
 
 
-    t.equal(
-      micromark("$a(a = b c\t=\t'd')", options()),
-      '',
-      'should support whitespace around initializers',
-    );
+    it('should not support lazyness (1)', () => {
+      expect(micromark('> $a\nb', options({ '*': h }))).toBe('<blockquote><a></a>\n</blockquote>\n<p>b</p>');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a(f  =\rg)', options()),
-    //   '<p>$a(f  =\rg)</p>',
-    //   'should not support EOLs around initializers',
-    // );
+    it('should not support lazyness (2)', () => {
+      expect(micromark('> a\n$b', options({ '*': h }))).toBe('<blockquote>\n<p>a</p>\n</blockquote>\n<b></b>');
+    });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a(b==)', options()),
-    //   '<p>$a(b==)</p>',
-    //   'should not support `=` to start an unquoted attribute value',
-    // );
+  });
 
 
-    t.equal(
-      micromark('$a(b💚=a💚b)', options()),
-      '',
-      'should support most other characters in attribute keys',
-    );
+});
 
 
-    t.equal(
-      micromark('$a(b=a💚b)', options()),
-      '',
-      'should support most other characters in unquoted attribute values',
+describe('micromark-extension-directive (compile)', () => {
+
+  it('should support a directives (abbr)', () => {
+    expect(
+      micromark(
+        [
+          'a $abbr',
+          'a $abbr[HTML]',
+          'a $abbr(title="HyperText Markup Language")',
+          'a $abbr[HTML](title="HyperText Markup Language")',
+        ].join('\n\n'),
+        options({ abbr }),
+      ),
+    ).toBe(
+      [
+        '<p>a <abbr></abbr></p>',
+        '<p>a <abbr>HTML</abbr></p>',
+        '<p>a <abbr title="HyperText Markup Language"></abbr></p>',
+        '<p>a <abbr title="HyperText Markup Language">HTML</abbr></p>',
+      ].join('\n'),
     );
     );
+  });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a(b="c', options()),
-    //   '<p>$a(b=&quot;c</p>',
-    //   'should not support an EOF in a quoted attribute value',
-    // );
-
-    t.equal(
-      micromark('$a(b="a💚b")', options()),
-      '',
-      'should support most other characters in quoted attribute values',
+  it('should support directives (youtube)', () => {
+    expect(
+      micromark(
+        [
+          'Text:',
+          'a $youtube',
+          'a $youtube[Cat in a box a]',
+          'a $youtube(v=1)',
+          'a $youtube[Cat in a box b](v=2)',
+          'Leaf:',
+          '$youtube',
+          '$youtube[Cat in a box c]',
+          '$youtube(v=3)',
+          '$youtube[Cat in a box d](v=4)',
+        ].join('\n\n'),
+        options({ youtube }),
+      ),
+    ).toBe(
+      [
+        '<p>Text:</p>',
+        '<p>a </p>',
+        '<p>a </p>',
+        '<p>a <iframe src="https://www.youtube.com/embed/1" allowfullscreen></iframe></p>',
+        '<p>a <iframe src="https://www.youtube.com/embed/2" allowfullscreen title="Cat in a box b"></iframe></p>',
+        '<p>Leaf:</p>',
+        '<iframe src="https://www.youtube.com/embed/3" allowfullscreen></iframe>',
+        '<iframe src="https://www.youtube.com/embed/4" allowfullscreen title="Cat in a box d"></iframe>',
+      ].join('\n'),
     );
     );
+  });
 
 
-    // == Resolved as text directive
-    // t.equal(
-    //   micromark('$a(b="\nc\r  d")', options()),
-    //   '<p>$a(b=&quot;\nc\rd&quot;)</p>',
-    //   'should not support EOLs in quoted attribute values',
-    // );
-
-    // t.equal(
-    //   micromark('$a(b="c"', options()),
-    //   '<p>$a(b=&quot;c&quot;</p>',
-    //   'should not support an EOF after a quoted attribute value',
-    // );
-
-    t.equal(
-      micromark('$a(b=c) \t ', options()),
-      '',
-      'should support whitespace after directives',
+  it('should support directives (lsx)', () => {
+    expect(
+      micromark(
+        [
+          'Text:',
+          'a $lsx',
+          'a $lsx()',
+          'a $lsx(num=1)',
+          'a $lsx(/)',
+          'a $lsx(/,num=5,depth=1)',
+          'a $lsx(/, num=5, depth=1)',
+          'a $lsx(💚)',
+          'Leaf:',
+          '$lsx',
+          '$lsx()',
+          '$lsx(num=1)',
+          '$lsx(/)',
+          '$lsx(/,num=5,depth=1)',
+          '$lsx(/, num=5, depth=1)',
+          '$lsx(💚)',
+        ].join('\n\n'),
+        options({ lsx }),
+      ),
+    ).toBe(
+      [
+        '<p>Text:</p>',
+        '<p>a <lsx ></lsx></p>',
+        '<p>a <lsx ></lsx></p>',
+        '<p>a <lsx num="1"></lsx></p>',
+        '<p>a <lsx prefix="/"></lsx></p>',
+        '<p>a <lsx prefix="/" num="5" depth="1"></lsx></p>',
+        '<p>a <lsx prefix="/" num="5" depth="1"></lsx></p>',
+        '<p>a <lsx prefix="💚"></lsx></p>',
+        '<p>Leaf:</p>',
+        '<lsx ></lsx>',
+        '<lsx ></lsx>',
+        '<lsx num="1"></lsx>',
+        '<lsx prefix="/"></lsx>',
+        '<lsx prefix="/" num="5" depth="1"></lsx>',
+        '<lsx prefix="/" num="5" depth="1"></lsx>',
+        '<lsx prefix="💚"></lsx>',
+      ].join('\n'),
     );
     );
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\n>a', options()),
-      '<blockquote>\n<p>a</p>\n</blockquote>',
-      'should support a block quote after a leaf',
-    );
+  it('should support fall through directives (`*`)', () => {
+    expect(
+      micromark('a $youtube[Cat in a box]\n$br a', options({ youtube, '*': h })),
+    ).toBe('<p>a <youtube>Cat in a box</youtube>\n<br> a</p>');
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\n```js\na', options()),
-      '<pre><code class="language-js">a\n</code></pre>\n',
-      'should support code (fenced) after a leaf',
-    );
+  it('should support fall through directives (`*`)', () => {
+    expect(
+      micromark('a $a[$img(src="x" alt=y)](href="z")', options({ '*': h })),
+    ).toBe('<p>a <a href="z"><img src="x" alt="y"></a></p>');
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\n    a', options()),
-      '<pre><code>a\n</code></pre>',
-      'should support code (indented) after a leaf',
-    );
+});
 
 
-    t.equal(
-      micromark('$a(b=c)\n[a]: b', options()),
-      '',
-      'should support a definition after a leaf',
-    );
+describe('content', () => {
 
 
-    t.equal(
-      micromark('$a(b=c)\n# a', options()),
-      '<h1>a</h1>',
-      'should support a heading (atx) after a leaf',
-    );
+  it('should support character escapes and character references in label', () => {
+    expect(micromark('a $abbr[x\\&y&amp;z]', options({ abbr })))
+      .toBe('<p>a <abbr>x&amp;y&amp;z</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\na\n=', options()),
-      '<h1>a</h1>',
-      'should support a heading (setext) after a leaf',
-    );
+  it('should support escaped brackets in a label', () => {
+    expect(micromark('a $abbr[x\\[y\\]z]', options({ abbr })))
+      .toBe('<p>a <abbr>x[y]z</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\n<!-->', options()),
-      '<!-->',
-      'should support html after a leaf',
-    );
+  it('should support balanced brackets in a label', () => {
+    expect(micromark('a $abbr[x[y]z]', options({ abbr })))
+      .toBe('<p>a <abbr>x[y]z</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\n* a', options()),
-      '<ul>\n<li>a</li>\n</ul>',
-      'should support a list after a leaf',
-    );
+  it('should support balanced brackets in a label, 32 levels deep', () => {
+    expect(micromark(
+      'a $abbr[1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]',
+      options({ abbr }),
+    )).toBe('<p>a <abbr>1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\na', options()),
-      '<p>a</p>',
-      'should support a paragraph after a leaf',
+  it('should *not* support balanced brackets in a label, 33 levels deep', () => {
+    expect(micromark(
+      '$abbr[1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[33[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]',
+      options({ abbr }),
+    )).toBe(
+      '<p><abbr></abbr>[1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[33[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]</p>',
     );
     );
+  });
 
 
-    t.equal(
-      micromark('$a(b=c)\n***', options()),
-      '<hr />',
-      'should support a thematic break after a leaf',
-    );
+  it('should support EOLs in a label', () => {
+    expect(micromark('$abbr[a\nb\rc]', options({ abbr })))
+      .toBe('<p><abbr>a\nb\rc</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('>a\n$a(b=c)', options()),
-      '<blockquote>\n<p>a</p>\n</blockquote>\n',
-      'should support a block quote before a leaf',
-    );
+  it('should support EOLs at the edges of a label (1)', () => {
+    expect(micromark('$abbr[\na\r]', options({ abbr })))
+      .toBe('<p><abbr>\na\r</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('```js\na\n```\n$a(b=c)', options()),
-      '<pre><code class="language-js">a\n</code></pre>\n',
-      'should support code (fenced) before a leaf',
-    );
+  it('should support EOLs at the edges of a label (2)', () => {
+    expect(micromark('$abbr[\n]', options({ abbr })))
+      .toBe('<p><abbr>\n</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('    a\n$a(b=c)', options()),
-      '<pre><code>a\n</code></pre>\n',
-      'should support code (indented) before a leaf',
-    );
+  // == does not work but I don't know why.. -- 2022.08.12 Yuki Takei
+  // it('should support EOLs around nested directives', () => {
+  //   expect(micromark('$abbr[a\n$abbr[b]\nc]', options({ abbr })))
+  //     .toBe('<p><abbr>a\n<abbr>b</abbr>\nc</abbr></p>');
+  // });
+
+  it('should support EOLs inside nested directives (1)', () => {
+    expect(micromark('$abbr[$abbr[\n]]', options({ abbr })))
+      .toBe('<p><abbr><abbr>\n</abbr></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('[a]: b\n$a(b=c)', options()),
-      '',
-      'should support a definition before a leaf',
-    );
+  it('should support EOLs inside nested directives (2)', () => {
+    expect(micromark('$abbr[$abbr[a\nb]]', options({ abbr })))
+      .toBe('<p><abbr><abbr>a\nb</abbr></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('# a\n$a(b=c)', options()),
-      '<h1>a</h1>\n',
-      'should support a heading (atx) before a leaf',
-    );
+  it('should support EOLs inside nested directives (3)', () => {
+    expect(micromark('$abbr[$abbr[\nb\n]]', options({ abbr })))
+      .toBe('<p><abbr><abbr>\nb\n</abbr></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('a\n=\n$a(b=c)', options()),
-      '<h1>a</h1>\n',
-      'should support a heading (setext) before a leaf',
-    );
+  it('should support EOLs inside nested directives (4)', () => {
+    expect(micromark('$abbr[$abbr[\\\n]]', options({ abbr })))
+      .toBe('<p><abbr><abbr><br />\n</abbr></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('<!-->\n$a(b=c)', options()),
-      '<!-->\n',
-      'should support html before a leaf',
-    );
+  it('should support markdown in a label', () => {
+    expect(micromark('a $abbr[a *b* **c** d]', options({ abbr })))
+      .toBe('<p>a <abbr>a <em>b</em> <strong>c</strong> d</abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('* a\n$a(b=c)', options()),
-      '<ul>\n<li>a</li>\n</ul>\n',
-      'should support a list before a leaf',
-    );
+  it('should support character references in unquoted attribute values', () => {
+    expect(micromark('a $abbr(title=a&apos;b)', options({ abbr })))
+      .toBe('<p>a <abbr title="a\'b"></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('a\n$a(b=c)', options()),
-      '<p>a</p>\n',
-      'should support a paragraph before a leaf',
-    );
+  it('should support character references in double attribute values', () => {
+    expect(micromark('a $abbr(title="a&apos;b")', options({ abbr })))
+      .toBe('<p>a <abbr title="a\'b"></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('***\n$a(b=c)', options()),
-      '<hr />\n',
-      'should support a thematic break before a leaf',
-    );
+  it('should support character references in single attribute values', () => {
+    expect(micromark("a $abbr(title='a&apos;b')", options({ abbr })))
+      .toBe('<p>a <abbr title="a\'b"></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('> $a\nb', options({ '*': h })),
-      '<blockquote><a></a>\n</blockquote>\n<p>b</p>',
-      'should not support lazyness (1)',
-    );
+  it('should support unknown character references in attribute values', () => {
+    expect(micromark('a $abbr(title="a&somethingelse;b")', options({ abbr })))
+      .toBe('<p>a <abbr title="a&amp;somethingelse;b"></abbr></p>');
+  });
 
 
-    t.equal(
-      micromark('> a\n$b', options({ '*': h })),
-      '<blockquote>\n<p>a</p>\n</blockquote>\n<b></b>',
-      'should not support lazyness (2)',
-    );
+  it('should support EOLs between attributes', () => {
+    expect(micromark('$span(a\nb)', options({ '*': h })))
+      .toBe('<p><span a="" b=""></span></p>');
+  });
 
 
-    t.end();
+  it('should support EOLs at the edges of attributes', () => {
+    expect(micromark('$span(\na\n)', options({ '*': h })))
+      .toBe('<p><span a=""></span></p>');
   });
   });
 
 
-  t.end();
-});
+  it('should support EOLs before initializer', () => {
+    expect(micromark('$span(a\r= b)', options({ '*': h })))
+      .toBe('<p><span a="b"></span></p>');
+  });
 
 
-test('micromark-extension-directive (compile)', (t) => {
-  t.equal(
-    micromark(
-      [
-        'a $abbr',
-        'a $abbr[HTML]',
-        'a $abbr(title="HyperText Markup Language")',
-        'a $abbr[HTML](title="HyperText Markup Language")',
-      ].join('\n\n'),
-      options({ abbr }),
-    ),
-    [
-      '<p>a <abbr></abbr></p>',
-      '<p>a <abbr>HTML</abbr></p>',
-      '<p>a <abbr title="HyperText Markup Language"></abbr></p>',
-      '<p>a <abbr title="HyperText Markup Language">HTML</abbr></p>',
-    ].join('\n'),
-    'should support a directives (abbr)',
-  );
-
-  t.equal(
-    micromark(
-      [
-        'Text:',
-        'a $youtube',
-        'a $youtube[Cat in a box a]',
-        'a $youtube(v=1)',
-        'a $youtube[Cat in a box b](v=2)',
-        'Leaf:',
-        '$youtube',
-        '$youtube[Cat in a box c]',
-        '$youtube(v=3)',
-        '$youtube[Cat in a box d](v=4)',
-      ].join('\n\n'),
-      options({ youtube }),
-    ),
-    [
-      '<p>Text:</p>',
-      '<p>a </p>',
-      '<p>a </p>',
-      '<p>a <iframe src="https://www.youtube.com/embed/1" allowfullscreen></iframe></p>',
-      '<p>a <iframe src="https://www.youtube.com/embed/2" allowfullscreen title="Cat in a box b"></iframe></p>',
-      '<p>Leaf:</p>',
-      '<iframe src="https://www.youtube.com/embed/3" allowfullscreen></iframe>',
-      '<iframe src="https://www.youtube.com/embed/4" allowfullscreen title="Cat in a box d"></iframe>',
-    ].join('\n'),
-    'should support directives (youtube)',
-  );
-
-  t.equal(
-    micromark(
-      [
-        'Text:',
-        'a $lsx',
-        'a $lsx()',
-        'a $lsx(num=1)',
-        'a $lsx(/)',
-        'a $lsx(/,num=5,depth=1)',
-        'a $lsx(/, num=5, depth=1)',
-        'a $lsx(💚)',
-        'Leaf:',
-        '$lsx',
-        '$lsx()',
-        '$lsx(num=1)',
-        '$lsx(/)',
-        '$lsx(/,num=5,depth=1)',
-        '$lsx(/, num=5, depth=1)',
-        '$lsx(💚)',
-      ].join('\n\n'),
-      options({ lsx }),
-    ),
-    [
-      '<p>Text:</p>',
-      '<p>a <lsx ></lsx></p>',
-      '<p>a <lsx ></lsx></p>',
-      '<p>a <lsx num="1"></lsx></p>',
-      '<p>a <lsx prefix="/"></lsx></p>',
-      '<p>a <lsx prefix="/" num="5" depth="1"></lsx></p>',
-      '<p>a <lsx prefix="/" num="5" depth="1"></lsx></p>',
-      '<p>a <lsx prefix="💚"></lsx></p>',
-      '<p>Leaf:</p>',
-      '<lsx ></lsx>',
-      '<lsx ></lsx>',
-      '<lsx num="1"></lsx>',
-      '<lsx prefix="/"></lsx>',
-      '<lsx prefix="/" num="5" depth="1"></lsx>',
-      '<lsx prefix="/" num="5" depth="1"></lsx>',
-      '<lsx prefix="💚"></lsx>',
-    ].join('\n'),
-    'should support directives (lsx)',
-  );
-
-  t.equal(
-    micromark('a $youtube[Cat in a box]\n$br a', options({ youtube, '*': h })),
-    '<p>a <youtube>Cat in a box</youtube>\n<br> a</p>',
-    'should support fall through directives (`*`)',
-  );
-
-  t.equal(
-    micromark('a $a[$img(src="x" alt=y)](href="z")', options({ '*': h })),
-    '<p>a <a href="z"><img src="x" alt="y"></a></p>',
-    'should support fall through directives (`*`)',
-  );
-
-  t.end();
-});
+  it('should support EOLs after initializer', () => {
+    expect(micromark('$span(a=\r\nb)', options({ '*': h })))
+      .toBe('<p><span a="b"></span></p>');
+  });
 
 
-test('content', (t) => {
-  t.equal(
-    micromark('a $abbr[x\\&y&amp;z]', options({ abbr })),
-    '<p>a <abbr>x&amp;y&amp;z</abbr></p>',
-    'should support character escapes and character references in label',
-  );
-
-  t.equal(
-    micromark('a $abbr[x\\[y\\]z]', options({ abbr })),
-    '<p>a <abbr>x[y]z</abbr></p>',
-    'should support escaped brackets in a label',
-  );
-
-  t.equal(
-    micromark('a $abbr[x[y]z]', options({ abbr })),
-    '<p>a <abbr>x[y]z</abbr></p>',
-    'should support balanced brackets in a label',
-  );
-
-  t.equal(
-    micromark(
-      'a $abbr[1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]',
-      options({ abbr }),
-    ),
-    '<p>a <abbr>1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]</abbr></p>',
-    'should support balanced brackets in a label, 32 levels deep',
-  );
+  it('should support EOLs between an unquoted attribute value and a next attribute name', () => {
+    expect(micromark('$span(a=b\nc)', options({ '*': h })))
+      .toBe('<p><span a="b" c=""></span></p>');
+  });
 
 
-  t.equal(
-    micromark(
-      '$abbr[1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[33[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]',
-      options({ abbr }),
-    ),
-    '<p><abbr></abbr>[1[2[3[4[5[6[7[8[9[10[11[12[13[14[15[16[17[18[19[20[21[22[23[24[25[26[27[28[29[30[31[32[33[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]</p>',
-    'should *not* support balanced brackets in a label, 33 levels deep',
-  );
-
-  t.equal(
-    micromark('$abbr[a\nb\rc]', options({ abbr })),
-    '<p><abbr>a\nb\rc</abbr></p>',
-    'should support EOLs in a label',
-  );
-
-  t.equal(
-    micromark('$abbr[\na\r]', options({ abbr })),
-    '<p><abbr>\na\r</abbr></p>',
-    'should support EOLs at the edges of a label (1)',
-  );
-
-  t.equal(
-    micromark('$abbr[\n]', options({ abbr })),
-    '<p><abbr>\n</abbr></p>',
-    'should support EOLs at the edges of a label (2)',
-  );
+  it('should support EOLs in a double quoted attribute value', () => {
+    expect(micromark('$span(a="b\nc")', options({ '*': h })))
+      .toBe('<p><span a="b\nc"></span></p>');
+  });
 
 
-  // == does not work but I don't know why.. -- 2022.08.12 Yuki Takei
-  // t.equal(
-  //   micromark('$abbr[a\n$abbr[b]\nc]', options({ abbr })),
-  //   '<p>a <abbr>a\n<abbr>b</abbr>\nc</abbr> a</p>',
-  //   'should support EOLs around nested directives',
-  // );
-
-  t.equal(
-    micromark('$abbr[$abbr[\n]]', options({ abbr })),
-    '<p><abbr><abbr>\n</abbr></abbr></p>',
-    'should support EOLs inside nested directives (1)',
-  );
-
-  t.equal(
-    micromark('$abbr[$abbr[a\nb]]', options({ abbr })),
-    '<p><abbr><abbr>a\nb</abbr></abbr></p>',
-    'should support EOLs inside nested directives (2)',
-  );
-
-  t.equal(
-    micromark('$abbr[$abbr[\nb\n]]', options({ abbr })),
-    '<p><abbr><abbr>\nb\n</abbr></abbr></p>',
-    'should support EOLs inside nested directives (3)',
-  );
-
-  t.equal(
-    micromark('$abbr[$abbr[\\\n]]', options({ abbr })),
-    '<p><abbr><abbr><br />\n</abbr></abbr></p>',
-    'should support EOLs inside nested directives (4)',
-  );
-
-  t.equal(
-    micromark('a $abbr[a *b* **c** d]', options({ abbr })),
-    '<p>a <abbr>a <em>b</em> <strong>c</strong> d</abbr></p>',
-    'should support markdown in a label',
-  );
-
-  t.equal(
-    micromark('a $abbr(title=a&apos;b)', options({ abbr })),
-    '<p>a <abbr title="a\'b"></abbr></p>',
-    'should support character references in unquoted attribute values',
-  );
-
-  t.equal(
-    micromark('a $abbr(title="a&apos;b")', options({ abbr })),
-    '<p>a <abbr title="a\'b"></abbr></p>',
-    'should support character references in double attribute values',
-  );
-
-  t.equal(
-    micromark("a $abbr(title='a&apos;b')", options({ abbr })),
-    '<p>a <abbr title="a\'b"></abbr></p>',
-    'should support character references in single attribute values',
-  );
-
-  t.equal(
-    micromark('a $abbr(title="a&somethingelse;b")', options({ abbr })),
-    '<p>a <abbr title="a&amp;somethingelse;b"></abbr></p>',
-    'should support unknown character references in attribute values',
-  );
-
-  t.equal(
-    micromark('$span(a\nb)', options({ '*': h })),
-    '<p><span a="" b=""></span></p>',
-    'should support EOLs between attributes',
-  );
-
-  t.equal(
-    micromark('$span(\na\n)', options({ '*': h })),
-    '<p><span a=""></span></p>',
-    'should support EOLs at the edges of attributes',
-  );
-
-  t.equal(
-    micromark('$span(a\r= b)', options({ '*': h })),
-    '<p><span a="b"></span></p>',
-    'should support EOLs before initializer',
-  );
-
-  t.equal(
-    micromark('$span(a=\r\nb)', options({ '*': h })),
-    '<p><span a="b"></span></p>',
-    'should support EOLs after initializer',
-  );
-
-  t.equal(
-    micromark('$span(a=b\nc)', options({ '*': h })),
-    '<p><span a="b" c=""></span></p>',
-    'should support EOLs between an unquoted attribute value and a next attribute name',
-  );
-
-  t.equal(
-    micromark('$span(a="b\nc")', options({ '*': h })),
-    '<p><span a="b\nc"></span></p>',
-    'should support EOLs in a double quoted attribute value',
-  );
-
-  t.equal(
-    micromark("$span(a='b\nc')", options({ '*': h })),
-    '<p><span a="b\nc"></span></p>',
-    'should support EOLs in a single quoted attribute value',
-  );
-
-  t.equal(
-    micromark('a $span(#a#b)', options({ '*': h })),
-    '<p>a <span #a#b=""></span></p>',
-    'should support attrs which contains `#` (1)',
-  );
-
-  t.equal(
-    micromark('a $span(id=a id="b" #c#d)', options({ '*': h })),
-    '<p>a <span id="b" #c#d=""></span></p>',
-    'should support attrs which contains `#` (2)',
-  );
-
-  t.equal(
-    micromark('a $span(.a.b)', options({ '*': h })),
-    '<p>a <span .a.b=""></span></p>',
-    'should support attrs with dot notation',
-  );
-
-  t.test('spec for growi plugin', (t) => {
-    t.equal(
-      micromark('a $lsx(/Sandbox)', options()),
-      '<p>a </p>',
-      'should support name with slash',
-    );
+  it('should support EOLs in a single quoted attribute value', () => {
+    expect(micromark("$span(a='b\nc')", options({ '*': h })))
+      .toBe('<p><span a="b\nc"></span></p>');
+  });
 
 
-    t.equal(
-      micromark('a $lsx(key=value, reverse)', options()),
-      '<p>a </p>',
-      'should support name=value and an attribute w/o value',
-    );
+  it('should support attrs which contains `#` (1)', () => {
+    expect(micromark('a $span(#a#b)', options({ '*': h })))
+      .toBe('<p>a <span #a#b=""></span></p>');
+  });
 
 
-    t.equal(
-      micromark('a $lsx(key=value, reverse, reverse2)', options()),
-      '<p>a </p>',
-      'should support consecutive attributes w/o value',
-    );
+  it('should support attrs which contains `#` (2)', () => {
+    expect(micromark('a $span(id=a id="b" #c#d)', options({ '*': h })))
+      .toBe('<p>a <span id="b" #c#d=""></span></p>');
+  });
 
 
-    t.equal(
-      micromark('a $lsx(/Sandbox, key=value, reverse)', options()),
-      '<p>a </p>',
-      'should support name=value after an empty value attribute',
-    );
+  it('should support attrs with dot notation', () => {
+    expect(micromark('a $span(.a.b)', options({ '*': h })))
+      .toBe('<p>a <span .a.b=""></span></p>');
+  });
 
 
-    t.end();
+  describe('spec for growi plugin', () => {
+    it('should support name with slash', () => {
+      expect(micromark('a $lsx(/Sandbox)', options()))
+        .toBe('<p>a </p>');
+    });
+
+    it('should support name=value and an attribute w/o value', () => {
+      expect(micromark('a $lsx(key=value, reverse)', options()))
+        .toBe('<p>a </p>');
+    });
+
+    it('should support consecutive attributes w/o value', () => {
+      expect(micromark('a $lsx(key=value, reverse, reverse2)', options()))
+        .toBe('<p>a </p>');
+    });
+
+    it('should support name=value after an empty value attribute', () => {
+      expect(micromark('a $lsx(/Sandbox, key=value, reverse)', options()))
+        .toBe('<p>a </p>');
+    });
   });
   });
 
 
-  t.end();
 });
 });
 
 
 /** @type {Handle} */
 /** @type {Handle} */

+ 19 - 22
packages/remark-growi-directive/test/remark-growi-directive.test.js

@@ -5,36 +5,35 @@
 import fs from 'node:fs';
 import fs from 'node:fs';
 import path from 'node:path';
 import path from 'node:path';
 
 
+
 import { isHidden } from 'is-hidden';
 import { isHidden } from 'is-hidden';
 import { remark } from 'remark';
 import { remark } from 'remark';
-import test from 'tape';
 import { readSync } from 'to-vfile';
 import { readSync } from 'to-vfile';
 import { unified } from 'unified';
 import { unified } from 'unified';
+import { describe, it, expect } from 'vitest';
 
 
 import { remarkGrowiDirectivePlugin } from '../src/remark-growi-directive.js';
 import { remarkGrowiDirectivePlugin } from '../src/remark-growi-directive.js';
 
 
-test('directive()', (t) => {
-  t.doesNotThrow(() => {
-    remark().use(remarkGrowiDirectivePlugin).freeze();
-  }, 'should not throw if not passed options');
-
-  t.doesNotThrow(() => {
-    unified().use(remarkGrowiDirectivePlugin).freeze();
-  }, 'should not throw if without parser or compiler');
+describe('directive()', () => {
+  it('should not throw if not passed options', () => {
+    expect(() => {
+      remark().use(remarkGrowiDirectivePlugin).freeze();
+    }).not.toThrow();
+  });
 
 
-  t.end();
+  it('should not throw if without parser or compiler', () => {
+    expect(() => {
+      unified().use(remarkGrowiDirectivePlugin).freeze();
+    }).not.toThrow();
+  });
 });
 });
 
 
-test('fixtures', (t) => {
+describe('fixtures', () => {
   const base = path.join('test', 'fixtures');
   const base = path.join('test', 'fixtures');
   const entries = fs.readdirSync(base).filter(d => !isHidden(d));
   const entries = fs.readdirSync(base).filter(d => !isHidden(d));
 
 
-  t.plan(entries.length);
-
-  let index = -1;
-  while (++index < entries.length) {
-    const fixture = entries[index];
-    t.test(fixture, (st) => {
+  entries.forEach((fixture) => {
+    it(`should handle ${fixture}`, () => {
       const file = readSync(path.join(base, fixture, 'input.md'));
       const file = readSync(path.join(base, fixture, 'input.md'));
       const input = String(file);
       const input = String(file);
       const outputPath = path.join(base, fixture, 'output.md');
       const outputPath = path.join(base, fixture, 'output.md');
@@ -62,10 +61,8 @@ test('fixtures', (t) => {
         output = input;
         output = input;
       }
       }
 
 
-      st.deepEqual(actual, expected, 'tree');
-      st.equal(String(proc.processSync(file)), output, 'process');
-
-      st.end();
+      expect(actual).toEqual(expected);
+      expect(String(proc.processSync(file))).toBe(output);
     });
     });
-  }
+  });
 });
 });

+ 5 - 0
packages/remark-growi-directive/tsconfig.json

@@ -1,6 +1,11 @@
 {
 {
   "$schema": "http://json.schemastore.org/tsconfig",
   "$schema": "http://json.schemastore.org/tsconfig",
   "extends": "../../tsconfig.base.json",
   "extends": "../../tsconfig.base.json",
+  "compilerOptions": {
+    "types": [
+      "vitest/globals"
+    ],
+  },
   "include": [
   "include": [
     "src"
     "src"
   ],
   ],

+ 13 - 0
packages/remark-growi-directive/vitest.config.ts

@@ -0,0 +1,13 @@
+import tsconfigPaths from 'vite-tsconfig-paths';
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+  plugins: [
+    tsconfigPaths(),
+  ],
+  test: {
+    environment: 'node',
+    clearMocks: true,
+    globals: true,
+  },
+});

+ 8 - 109
yarn.lock

@@ -4705,13 +4705,6 @@
   dependencies:
   dependencies:
     "@types/node" "*"
     "@types/node" "*"
 
 
-"@types/tape@^4.0.0":
-  version "4.13.2"
-  resolved "https://registry.yarnpkg.com/@types/tape/-/tape-4.13.2.tgz#77215c065b1c7840da3ca5e061337bb4c7258122"
-  integrity sha512-V1ez/RtYRGN9cNYApw5xf27DpMkTB0033X6a2i3KUmKhSojBfbWN0i3EgZxboUG96WJLHLdOyZ01aiZwVW5aSA==
-  dependencies:
-    "@types/node" "*"
-
 "@types/throttle-debounce@^5.0.1":
 "@types/throttle-debounce@^5.0.1":
   version "5.0.1"
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-5.0.1.tgz#8ce917e41580b2cf16f8ee840e227947f4152b04"
   resolved "https://registry.yarnpkg.com/@types/throttle-debounce/-/throttle-debounce-5.0.1.tgz#8ce917e41580b2cf16f8ee840e227947f4152b04"
@@ -5457,16 +5450,6 @@ array-unique@^0.3.2:
   resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
   resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
   integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==
   integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==
 
 
-array.prototype.every@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/array.prototype.every/-/array.prototype.every-1.1.3.tgz#31f01b48e1160bc4b49ecab246bf7f765c6686f9"
-  integrity sha512-vWnriJI//SOMOWtXbU/VXhJ/InfnNHPF6BLKn5WfY8xXy+NWql0fUy20GO3sdqBhCAO+qw8S/E5nJiZX+QFdCA==
-  dependencies:
-    call-bind "^1.0.2"
-    define-properties "^1.1.3"
-    es-abstract "^1.19.0"
-    is-string "^1.0.7"
-
 array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5:
 array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5:
   version "1.3.2"
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18"
   resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18"
@@ -7872,11 +7855,6 @@ define-property@^2.0.2:
     is-descriptor "^1.0.2"
     is-descriptor "^1.0.2"
     isobject "^3.0.1"
     isobject "^3.0.1"
 
 
-defined@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
-  integrity sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==
-
 del@6.0.0:
 del@6.0.0:
   version "6.0.0"
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952"
   resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952"
@@ -8134,13 +8112,6 @@ dotenv@^8.0.0, dotenv@^8.1.0, dotenv@^8.2.0:
   resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
   resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
   integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
   integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
 
 
-dotignore@^0.1.2:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905"
-  integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==
-  dependencies:
-    minimatch "^3.0.4"
-
 downshift@^8.2.3:
 downshift@^8.2.3:
   version "8.2.3"
   version "8.2.3"
   resolved "https://registry.yarnpkg.com/downshift/-/downshift-8.2.3.tgz#27106a5d9f408a6f6f9350ca465801d07e52db87"
   resolved "https://registry.yarnpkg.com/downshift/-/downshift-8.2.3.tgz#27106a5d9f408a6f6f9350ca465801d07e52db87"
@@ -8371,7 +8342,7 @@ error-ex@^1.2.0, error-ex@^1.3.1:
   dependencies:
   dependencies:
     is-arrayish "^0.2.1"
     is-arrayish "^0.2.1"
 
 
-es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.4.3:
+es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.4.3:
   version "1.23.3"
   version "1.23.3"
   resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0"
   resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0"
   integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==
   integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==
@@ -9674,11 +9645,6 @@ get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@
     has-symbols "^1.0.3"
     has-symbols "^1.0.3"
     hasown "^2.0.0"
     hasown "^2.0.0"
 
 
-get-package-type@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
-  integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
-
 get-stdin@^4.0.1:
 get-stdin@^4.0.1:
   version "4.0.1"
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
   resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
@@ -10039,14 +10005,6 @@ has-bigints@^1.0.2:
   resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
   resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
   integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
   integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
 
 
-has-dynamic-import@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/has-dynamic-import/-/has-dynamic-import-2.0.1.tgz#9bca87846aa264f2ad224fcd014946f5e5182f52"
-  integrity sha512-X3fbtsZmwb6W7fJGR9o7x65fZoodygCrZ3TVycvghP62yYQfS0t4RS0Qcz+j5tQYUKeSWS09tHkWW6WhFV3XhQ==
-  dependencies:
-    call-bind "^1.0.2"
-    get-intrinsic "^1.1.1"
-
 has-flag@^3.0.0:
 has-flag@^3.0.0:
   version "3.0.0"
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -14358,12 +14316,12 @@ object-hash@>=2.0.3, object-hash@^2.0.1:
   resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
   resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
   integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
   integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
 
 
-object-inspect@^1.12.0, object-inspect@^1.13.1, object-inspect@^1.9.0:
+object-inspect@^1.13.1, object-inspect@^1.9.0:
   version "1.13.1"
   version "1.13.1"
   resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
   resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
   integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
   integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
 
 
-object-is@^1.1.4, object-is@^1.1.5:
+object-is@^1.1.4:
   version "1.1.5"
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
   resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
   integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==
   integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==
@@ -16387,13 +16345,6 @@ restore-cursor@^3.1.0:
     onetime "^5.1.0"
     onetime "^5.1.0"
     signal-exit "^3.0.2"
     signal-exit "^3.0.2"
 
 
-resumer@^0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759"
-  integrity sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w==
-  dependencies:
-    through "~2.3.4"
-
 ret@~0.1.10:
 ret@~0.1.10:
   version "0.1.15"
   version "0.1.15"
   resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
   resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
@@ -17394,7 +17345,7 @@ string-template@>=1.0.0:
   resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
   resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
   integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
   integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
 
 
-"string-width-cjs@npm:string-width@^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
   version "4.2.3"
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -17412,15 +17363,6 @@ string-width@=4.2.2:
     is-fullwidth-code-point "^3.0.0"
     is-fullwidth-code-point "^3.0.0"
     strip-ansi "^6.0.0"
     strip-ansi "^6.0.0"
 
 
-"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
-  version "4.2.3"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
-  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
-  dependencies:
-    emoji-regex "^8.0.0"
-    is-fullwidth-code-point "^3.0.0"
-    strip-ansi "^6.0.1"
-
 string-width@^5.0.1, string-width@^5.1.2:
 string-width@^5.0.1, string-width@^5.1.2:
   version "5.1.2"
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
@@ -17452,7 +17394,7 @@ string.prototype.padend@^3.0.0:
     es-abstract "^1.4.3"
     es-abstract "^1.4.3"
     function-bind "^1.0.2"
     function-bind "^1.0.2"
 
 
-string.prototype.trim@^1.2.5, string.prototype.trim@^1.2.9:
+string.prototype.trim@^1.2.9:
   version "1.2.9"
   version "1.2.9"
   resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4"
   resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4"
   integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==
   integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==
@@ -17504,7 +17446,7 @@ stringify-entities@^4.0.0:
     character-entities-html4 "^2.0.0"
     character-entities-html4 "^2.0.0"
     character-entities-legacy "^3.0.0"
     character-entities-legacy "^3.0.0"
 
 
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
   version "6.0.1"
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -17518,13 +17460,6 @@ strip-ansi@^3.0.0:
   dependencies:
   dependencies:
     ansi-regex "^2.0.0"
     ansi-regex "^2.0.0"
 
 
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
-  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
-  dependencies:
-    ansi-regex "^5.0.1"
-
 strip-ansi@^7.0.1, strip-ansi@^7.1.0:
 strip-ansi@^7.0.1, strip-ansi@^7.1.0:
   version "7.1.0"
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -17934,33 +17869,6 @@ tapable@^2.2.0:
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
   resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
   integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
   integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
 
 
-tape@^5.0.0:
-  version "5.5.3"
-  resolved "https://registry.yarnpkg.com/tape/-/tape-5.5.3.tgz#b6d6f3c99a7bade12b9dcf6ee2234b1dd35e5003"
-  integrity sha512-hPBJZBL9S7bH9vECg/KSM24slGYV589jJr4dmtiJrLD71AL66+8o4b9HdZazXZyvnilqA7eE8z5/flKiy0KsBg==
-  dependencies:
-    array.prototype.every "^1.1.3"
-    call-bind "^1.0.2"
-    deep-equal "^2.0.5"
-    defined "^1.0.0"
-    dotignore "^0.1.2"
-    for-each "^0.3.3"
-    get-package-type "^0.1.0"
-    glob "^7.2.0"
-    has "^1.0.3"
-    has-dynamic-import "^2.0.1"
-    inherits "^2.0.4"
-    is-regex "^1.1.4"
-    minimist "^1.2.6"
-    object-inspect "^1.12.0"
-    object-is "^1.1.5"
-    object-keys "^1.1.1"
-    object.assign "^4.1.2"
-    resolve "^2.0.0-next.3"
-    resumer "^0.0.0"
-    string.prototype.trim "^1.2.5"
-    through "^2.3.8"
-
 tar-stream@^2.2.0:
 tar-stream@^2.2.0:
   version "2.2.0"
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
   resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
@@ -18062,7 +17970,7 @@ through2@^2.0.0, through2@~2.0.0:
     readable-stream "~2.3.6"
     readable-stream "~2.3.6"
     xtend "~4.0.1"
     xtend "~4.0.1"
 
 
-"through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8, through@~2.3.4:
+"through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8:
   version "2.3.8"
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
 
 
@@ -19348,7 +19256,7 @@ word-wrap@^1.2.3:
   resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
   resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
 
 
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
   version "7.0.0"
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -19366,15 +19274,6 @@ wrap-ansi@^6.2.0:
     string-width "^4.1.0"
     string-width "^4.1.0"
     strip-ansi "^6.0.0"
     strip-ansi "^6.0.0"
 
 
-wrap-ansi@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
-  integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
-  dependencies:
-    ansi-styles "^4.0.0"
-    string-width "^4.1.0"
-    strip-ansi "^6.0.0"
-
 wrap-ansi@^8.1.0:
 wrap-ansi@^8.1.0:
   version "8.1.0"
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"