From fe2c3d188b3e12f4754297f45a36e7427b4f0b76 Mon Sep 17 00:00:00 2001 From: d3m1d0v Date: Wed, 13 Nov 2024 22:10:28 +0300 Subject: [PATCH] test: add plugin tests --- tests/jest.config.js | 2 +- tests/src/__snapshots__/index.test.ts.snap | 166 +++++++++++++++++++ tests/src/index.test.ts | 179 ++++++++++++++++++++- 3 files changed, 343 insertions(+), 4 deletions(-) create mode 100644 tests/src/__snapshots__/index.test.ts.snap diff --git a/tests/jest.config.js b/tests/jest.config.js index b5d5cfd..f8bcf7e 100644 --- a/tests/jest.config.js +++ b/tests/jest.config.js @@ -2,7 +2,7 @@ module.exports = { testEnvironment: 'jsdom', transformIgnorePatterns: [], - snapshotSerializers: ['jest-serializer-html'], + // snapshotSerializers: ['jest-serializer-html'], transform: { '^.+\\.(j|t)s?$': ['esbuild-jest', {tsconfig: './tsconfig.json'}], }, diff --git a/tests/src/__snapshots__/index.test.ts.snap b/tests/src/__snapshots__/index.test.ts.snap new file mode 100644 index 0000000..57b5f84 --- /dev/null +++ b/tests/src/__snapshots__/index.test.ts.snap @@ -0,0 +1,166 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`File extension - plugin should add extra attrs 1`] = ` +"

file.txt

+" +`; + +exports[`File extension - plugin should add extra attrs by passing them to plugin options 1`] = ` +"

file.txt

+" +`; + +exports[`File extension - plugin should allow quoutes in attribute value 1`] = ` +"

ind"ex.html

+" +`; + +exports[`File extension - plugin should generate yfm-file token 1`] = ` +[ + Token { + "attrs": null, + "block": true, + "children": null, + "content": "", + "hidden": false, + "info": "", + "level": 0, + "map": [ + 0, + 1, + ], + "markup": "", + "meta": null, + "nesting": 1, + "tag": "p", + "type": "paragraph_open", + }, + Token { + "attrs": null, + "block": true, + "children": [ + Token { + "attrs": [ + [ + "href", + "../file", + ], + [ + "download", + "file.txt", + ], + [ + "class", + "yfm-file", + ], + ], + "block": false, + "children": null, + "content": "file.txt", + "hidden": false, + "info": "", + "level": 0, + "map": null, + "markup": "{% file ", + "meta": null, + "nesting": 0, + "tag": "", + "type": "yfm_file", + }, + ], + "content": "{% file src="../file" name="file.txt" %}", + "hidden": false, + "info": "", + "level": 1, + "map": [ + 0, + 1, + ], + "markup": "", + "meta": null, + "nesting": 0, + "tag": "", + "type": "inline", + }, + Token { + "attrs": null, + "block": true, + "children": null, + "content": "", + "hidden": false, + "info": "", + "level": 0, + "map": null, + "markup": "", + "meta": null, + "nesting": -1, + "tag": "p", + "type": "paragraph_close", + }, +] +`; + +exports[`File extension - plugin should ignore additional file markup 1`] = ` +"

{% file index.html %}

+" +`; + +exports[`File extension - plugin should ignore additional special characters 1`] = ` +"

{% index.html %}

+" +`; + +exports[`File extension - plugin should ignore unknown attrs 1`] = ` +"

file.txt

+" +`; + +exports[`File extension - plugin should map all specific file attrs to link html attrs 1`] = ` +"

file2.txt

+" +`; + +exports[`File extension - plugin should parse attrs with single quotes 1`] = ` +"

index.html

+" +`; + +exports[`File extension - plugin should pass allowed link html attrs 1`] = ` +"

file1.txt

+" +`; + +exports[`File extension - plugin should render file 1`] = ` +"

file.txt

+" +`; + +exports[`File extension - plugin should render file between text 1`] = ` +"

text1 file.txt 2text

+" +`; + +exports[`File extension - plugin should render file with different order of attrs 1`] = ` +"

page.html

+" +`; + +exports[`File extension - plugin should render file with extra spaces around attrs 1`] = ` +"

index.html

+" +`; + +exports[`File extension - plugin should render file with text after 1`] = ` +"

file.txt don't download it

+" +`; + +exports[`File extension - plugin should render file with text before 1`] = ` +"

download it file.txt

+" +`; + +exports[`File extension - plugin should render with file markup in attributes 1`] = ` +"

{% file src='a' name='b' %}

+" +`; diff --git a/tests/src/index.test.ts b/tests/src/index.test.ts index 8b6602b..d0b9278 100644 --- a/tests/src/index.test.ts +++ b/tests/src/index.test.ts @@ -1,5 +1,178 @@ -describe('test', () => { - it('should be test', () => { - expect(test).toBe('test'); +import MarkdownIt from 'markdown-it'; +import transform from '@diplodoc/transform'; + +import {type TransformOptions, transform as fileTransformer} from '../../src/plugin'; + +function html(markup: string, opts?: TransformOptions) { + return transform(markup, { + // override the default markdown-it-attrs delimiters, + // to make it easier to check html for non-valid file markup + leftDelimiter: '[', + rightDelimiter: ']', + plugins: [fileTransformer({bundle: false, ...opts})], + }).result.html; +} + +function meta(markup: string, opts?: TransformOptions) { + return transform(markup, { + leftDelimiter: '[', + rightDelimiter: ']', + plugins: [fileTransformer({bundle: false, ...opts})], + }).result.meta; +} + +function tokens(markup: string, opts?: TransformOptions) { + const md = new MarkdownIt().use(fileTransformer({bundle: false, ...opts})); + return md.parse(markup, {}); +} + +describe('File extension - plugin', () => { + it('should render file', () => { + expect(html('{% file src="../file" name="file.txt" %}')).toMatchSnapshot(); + }); + + it('should ignore file markup without params', () => { + expect(html('{% file %}')).toBe('

{% file %}

\n'); + }); + + it('should not render file without all required attrs', () => { + expect(html('{% file src="../file" %}')).toBe('

{% file src="../file" %}

\n'); + expect(html('{% file name="file.txt" %}')).toBe('

{% file name="file.txt" %}

\n'); + }); + + it('should render file with text before', () => { + expect(html('download it {% file src="../file" name="file.txt" %}')).toMatchSnapshot(); + }); + + it('should render file with text after', () => { + expect( + html('{% file src="../file" name="file.txt" %} don\'t download it'), + ).toMatchSnapshot(); + }); + + it('should render file between text', () => { + expect(html('text1 {% file src="../file" name="file.txt" %} 2text')).toMatchSnapshot(); + }); + + it('should map all specific file attrs to link html attrs', () => { + expect(html('{% file src="../file2" name="file2.txt" lang="en" %}')).toMatchSnapshot(); + }); + + it('should pass allowed link html attrs', () => { + expect( + html( + '{% file src="../file1" name="file1.txt" referrerpolicy="origin" rel="help" target="_top" type="text/css" %}', + ), + ).toMatchSnapshot(); + }); + + it('should ignore unknown attrs', () => { + expect( + html('{% file src="../file" name="file.txt" foo="1" bar="2" baz="3" %}'), + ).toMatchSnapshot(); + }); + + it('should add extra attrs', () => { + expect( + html('{% file src="../file" name="file.txt" %}', { + extraAttrs: [['data-yfm-file', 'yes']], + }), + ).toMatchSnapshot(); + }); + + it('should parse attrs with single quotes', () => { + expect(html("{% file src='index.txt' name='index.html' %}")).toMatchSnapshot(); + }); + + it('should render with file markup in attributes', () => { + expect( + html('{% file src="in%}dex.txt" name="{% file src=\'a\' name=\'b\' %}" %}'), + ).toMatchSnapshot(); + }); + + it('should render file with different order of attrs', () => { + expect( + html('{% file type="text/html" name="page.html" src="../index.html" %}'), + ).toMatchSnapshot(); + }); + + it('should ignore additional special characters', () => { + expect(html('{% {% file src="index.txt" name="index.html" %} %}')).toMatchSnapshot(); + }); + + it('should ignore additional file markup', () => { + expect(html('{% file {% file src="index.txt" name="index.html" %} %}')).toMatchSnapshot(); + }); + + it('should allow quoutes in attribute value', () => { + expect(html('{% file src="ind\'ex.txt" name=\'ind"ex.html\' %}')).toMatchSnapshot(); + }); + + it('should render file with extra spaces around attrs', () => { + expect( + html('{% file src="index.txt" name="index.html" type="text/html" %}'), + ).toMatchSnapshot(); + }); + + it('should not render file without spaces around attrs', () => { + expect(html('{% file src="index.txt"name="index.html"type="text/html" %}')).toBe( + `

{% file src="index.txt"name="index.html"type="text/html" %}

\n`, + ); + }); + + it('should not render file with no spaces near borders', () => { + expect(html("{%file src='index.txt' name='index.html'%}")).toBe( + `

{%file src='index.txt' name='index.html'%}

\n`, + ); + }); + + it('should not add meta if file not parsed', () => { + expect(meta('parapraph')).toBeUndefined(); + }); + + it('should add default style assets to meta', () => { + expect(meta('{% file src="../file" name="file.txt" %}')).toStrictEqual({ + style: ['_assets/file-extension.css'], + }); + }); + + it('should override style assets name', () => { + expect( + meta('{% file src="../file" name="file.txt" %}', {runtime: 'file-ext'}), + ).toStrictEqual({style: ['file-ext']}); + }); + + it('should override style assets name 2', () => { + expect( + meta('{% file src="../file" name="file.txt" %}', {runtime: {style: 'yfm-file'}}), + ).toStrictEqual({style: ['yfm-file']}); + }); + + it('should not call onBundle', () => { + const onBundle = jest.fn(() => {}); + html('text', {bundle: true, onBundle}); + expect(onBundle).not.toHaveBeenCalled(); + }); + + it('should call onBundle', () => { + const onBundle = jest.fn(() => {}); + html('{% file src="../file" name="file.txt" %}', {bundle: true, onBundle}); + expect(onBundle).toHaveBeenCalled(); + }); + + it('should generate yfm-file token', () => { + expect(tokens('{% file src="../file" name="file.txt" %}')).toMatchSnapshot(); + }); + + it('should add extra attrs by passing them to plugin options', () => { + const md = new MarkdownIt(); + const filePlugin = fileTransformer({bundle: false}); + filePlugin(md, { + fileExtraAttrs: [ + ['data-yfm', '1'], + ['data-file', '2'], + ], + }); + expect(md.render('{% file src="../file" name="file.txt" %}')).toMatchSnapshot(); }); });