import { describe, expect, it, vi } from 'vitest' import { normalizeRules } from '../src/normalizeRules.js' import { isMatchUrl, replacementAssetWithRules, transformAssets } from '../src/unplugin/transform.js' import { createAssetPattern } from '../src/unplugin/utils.js' describe('plugin-replace-assets > isMatchUrl', () => { it.each([ { name: 'string like regexp with ^ and $', find: '^/images/.*\\.(jpe?g|png|gif|svg)(\\?.*)?$', expects: [ ['/images/foo.jpg', true], ['/images/foo.png', true], ['/images/foo.gif', true], ['/images/foo.svg', true], ['/images/foo.jpg?a=1', true], ['/images/foo.txt', false], ['/medias/foo.mp4', false], ] as const, }, { name: 'string like regexp start with ^', find: '^/medias/', expects: [ ['/medias/foo.mp4', true], ['/medias/foo.ogg', true], ['/medias/foo.ogv', true], ['/medias/foo.webm', true], ['/images/foo.jpg', false], ] as const, }, { name: 'string like regexp end with $', find: '\\.(jpe?g|png|gif|svg)$', expects: [ ['/images/foo.jpg', true], ['/images/foo.png', true], ['/images/foo.gif', true], ['/images/foo.svg', true], ['/images/foo.txt', false], ['/medias/foo.mp4', false], ] as const, }, { name: 'string start width pathname', find: '/images/', expects: [ ['/images/foo.jpg', true], ['/images/foo.png', true], ['/images/foo.gif', true], ['/images/foo', true], ['/medias/foo.mp4', false], ] as const, }, { name: 'string end width extension', find: '.jpg', expects: [ ['/images/foo.jpg', true], ['/images/foo.png', false], ['/images/foo.gif', false], ['/images/foo', false], ['/medias/foo.mp4', false], ] as const, }, { name: 'regexp', find: /^\/images\/.*\.(jpe?g|png|gif|svg)$/, expects: [ ['/images/foo.jpg', true], ['/images/foo.png', true], ['/images/foo.gif', true], ['/images/foo.svg', true], ['/images/foo.txt', false], ['/medias/foo.mp4', false], ] as const, }, ])('$name', ({ find, expects }) => { for (const [url, expected] of expects) { expect(isMatchUrl(find, url)).toBe(expected) } }) }) describe('plugin-replace-assets > replacementAssetWithRules', () => { const IMAGE_SUPPORTED = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'avif'] const MEDIA_SUPPORTED = ['mp4', 'webm', 'ogg', 'mp3', 'wav', 'flac', 'aac', 'm3u8', 'm3u', 'flv', 'pdf'] const replacementFn = vi.fn(url => `https://example.com/assets${url}`) it.each([ { name: 'string replacement', rules: normalizeRules('https://example.com/assets/'), expects: [ // images ...IMAGE_SUPPORTED.map(ext => [ `/images/foo.${ext}`, `https://example.com/assets/images/foo.${ext}`, ]), // media ...MEDIA_SUPPORTED.map(ext => [ `/medias/foo.${ext}`, `https://example.com/assets/medias/foo.${ext}`, ]), // have query string ['/images/foo.jpg?a=1', 'https://example.com/assets/images/foo.jpg?a=1'], // cached images ['/images/foo.jpg', 'https://example.com/assets/images/foo.jpg'], // no supported ['/images/foo.txt', undefined], ['/medias/foo', undefined], ] as const, }, { name: 'function replacement', rules: normalizeRules(replacementFn), expects: [ // images ...IMAGE_SUPPORTED.map(ext => [ `/images-1/foo.${ext}`, `https://example.com/assets/images-1/foo.${ext}`, ]), // media ...MEDIA_SUPPORTED.map(ext => [ `/medias-1/foo.${ext}`, `https://example.com/assets/medias-1/foo.${ext}`, ]), // have query string ['/images-1/foo.jpg?a=1', 'https://example.com/assets/images-1/foo.jpg?a=1'], // cached images ['/images-1/foo.jpg', 'https://example.com/assets/images-1/foo.jpg'], // no supported ['/images-1/foo.txt', undefined], ['/medias-1/foo', undefined], ] as const, }, ])('$name', ({ name, rules, expects }) => { for (const [url, expected] of expects) { expect(replacementAssetWithRules(rules, url)).toBe(expected) } if (name === 'function replacement') { // should not called with cached, and not called with no supported expect(replacementFn).toBeCalledTimes(expects.length - 3) } }) }) describe('plugin-replace-assets > transformAssets', () => { const rules = normalizeRules('https://example.com/assets/') const pattern = createAssetPattern('/[^/]') it('should work with like html', () => { const source = `\