mirror of
https://github.com/gromlab-ru/svg-sprites.git
synced 2026-07-22 04:40:17 +03:00
143 lines
5.5 KiB
JavaScript
143 lines
5.5 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import fs from 'node:fs'
|
|
import os from 'node:os'
|
|
import path from 'node:path'
|
|
import test from 'node:test'
|
|
|
|
import { generateSprite, isSpriteMode } from '../dist/index.js'
|
|
|
|
const CHECK_SVG = '<svg viewBox="0 0 24 24"><path fill="currentColor" d="M9 16 4 11l2-2 3 3 8-8 2 2z"/></svg>'
|
|
const UNSAFE_SVG = '<svg viewBox="0 0 16 16"><path d="M1 1h14v14H1z"/></svg>'
|
|
|
|
function fixture() {
|
|
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), 'svg-sprites-standalone-'))
|
|
const iconsDir = path.join(rootDir, 'icons')
|
|
fs.mkdirSync(iconsDir)
|
|
fs.writeFileSync(path.join(iconsDir, 'check.svg'), CHECK_SVG)
|
|
fs.writeFileSync(path.join(iconsDir, 'folder open.svg'), UNSAFE_SVG)
|
|
return rootDir
|
|
}
|
|
|
|
function generatedFiles(rootDir) {
|
|
return fs.readdirSync(path.join(rootDir, '.svg-sprite')).sort()
|
|
}
|
|
|
|
test('recognizes all standalone exact modes', () => {
|
|
assert.equal(isSpriteMode('standalone'), true)
|
|
assert.equal(isSpriteMode('standalone@vite'), true)
|
|
assert.equal(isSpriteMode('standalone@webpack'), true)
|
|
assert.equal(isSpriteMode('standalone@rollup'), false)
|
|
})
|
|
|
|
test('standalone generates an asset and deployment-neutral JSON manifest', async () => {
|
|
const rootDir = fixture()
|
|
const result = await generateSprite(rootDir, {
|
|
mode: 'standalone',
|
|
name: 'app-icons',
|
|
generatedNotice: false,
|
|
})
|
|
|
|
assert.equal(result.mode, 'standalone')
|
|
assert.equal(result.target, 'static')
|
|
assert.equal(result.iconCount, 2)
|
|
assert.equal(result.spritePath, path.join(rootDir, '.svg-sprite', 'sprite.svg'))
|
|
assert.equal(result.manifestPath, path.join(rootDir, '.svg-sprite', 'svg-sprite.manifest.json'))
|
|
assert.deepEqual(generatedFiles(rootDir), [
|
|
'sprite.svg',
|
|
'state.json',
|
|
'svg-sprite.manifest.json',
|
|
])
|
|
|
|
const source = fs.readFileSync(result.spritePath, 'utf8')
|
|
assert.match(source, /@generated by @gromlab\/svg-sprites/)
|
|
assert.match(source, /id="check"/)
|
|
|
|
const manifest = JSON.parse(fs.readFileSync(result.manifestPath, 'utf8'))
|
|
assert.equal(manifest.name, 'app-icons')
|
|
assert.equal(manifest.mode, 'standalone')
|
|
assert.equal(manifest.target, 'static')
|
|
assert.match(manifest.generated, /@generated by @gromlab\/svg-sprites/)
|
|
assert.equal('spriteUrl' in manifest, false)
|
|
assert.equal('componentName' in manifest, false)
|
|
assert.equal(manifest.icons.find(({ name }) => name === 'check').id, 'check')
|
|
assert.match(
|
|
manifest.icons.find(({ name }) => name === 'folder open').id,
|
|
/^icon-[a-f0-9]{16}$/,
|
|
)
|
|
|
|
const state = JSON.parse(fs.readFileSync(path.join(rootDir, '.svg-sprite', 'state.json'), 'utf8'))
|
|
assert.deepEqual(state.owner, { mode: 'standalone', contractVersion: 2 })
|
|
})
|
|
|
|
test('standalone Vite generates a typed facade and resolved manifest', async () => {
|
|
const rootDir = fixture()
|
|
const result = await generateSprite(rootDir, {
|
|
mode: 'standalone@vite',
|
|
name: 'icons',
|
|
generatedNotice: false,
|
|
})
|
|
|
|
assert.equal(result.target, 'vite')
|
|
assert.deepEqual(generatedFiles(rootDir), [
|
|
'icon-data.d.ts',
|
|
'icon-data.js',
|
|
'index.d.ts',
|
|
'index.js',
|
|
'sprite.svg',
|
|
'state.json',
|
|
'svg-sprite.manifest.d.ts',
|
|
'svg-sprite.manifest.js',
|
|
])
|
|
|
|
const entry = fs.readFileSync(path.join(rootDir, '.svg-sprite', 'index.js'), 'utf8')
|
|
const declarations = fs.readFileSync(path.join(rootDir, '.svg-sprite', 'index.d.ts'), 'utf8')
|
|
const manifest = fs.readFileSync(result.manifestPath, 'utf8')
|
|
assert.match(entry, /sprite\.svg\?no-inline/)
|
|
assert.match(entry, /export const iconsSpriteUrl = spriteUrl/)
|
|
assert.match(entry, /export function getIconsIconHref\(icon\)/)
|
|
assert.match(declarations, /getIconsIconHref\(icon: IconsIconName\): string/)
|
|
assert.match(manifest, /"mode": "standalone@vite"/)
|
|
assert.match(manifest, /export const spriteManifest = createSpriteManifest\(spriteUrl\)/)
|
|
assert.doesNotMatch(entry, /react|jsx|\.css/)
|
|
})
|
|
|
|
test('standalone Webpack generates a typed facade and resolved manifest', async () => {
|
|
const rootDir = fixture()
|
|
const result = await generateSprite(rootDir, {
|
|
mode: 'standalone@webpack',
|
|
name: 'icons',
|
|
generatedNotice: false,
|
|
})
|
|
|
|
assert.equal(result.target, 'webpack')
|
|
const entry = fs.readFileSync(path.join(rootDir, '.svg-sprite', 'index.js'), 'utf8')
|
|
const manifest = fs.readFileSync(result.manifestPath, 'utf8')
|
|
assert.match(entry, /new URL\('\.\/sprite\.svg', import\.meta\.url\)\.href/)
|
|
assert.match(entry, /export function getIconsIconHref\(icon\)/)
|
|
assert.match(manifest, /"mode": "standalone@webpack"/)
|
|
assert.match(manifest, /new URL\('\.\/sprite\.svg', import\.meta\.url\)\.href/)
|
|
assert.doesNotMatch(entry, /react|jsx|\.css/)
|
|
})
|
|
|
|
test('switching standalone modes removes obsolete managed files', async () => {
|
|
const rootDir = fixture()
|
|
const options = { name: 'icons', generatedNotice: false }
|
|
|
|
await generateSprite(rootDir, { ...options, mode: 'standalone@vite' })
|
|
fs.writeFileSync(path.join(rootDir, '.svg-sprite', 'user.txt'), 'keep')
|
|
await generateSprite(rootDir, { ...options, mode: 'standalone' })
|
|
|
|
assert.deepEqual(generatedFiles(rootDir), [
|
|
'sprite.svg',
|
|
'state.json',
|
|
'svg-sprite.manifest.json',
|
|
'user.txt',
|
|
])
|
|
assert.equal(fs.readFileSync(path.join(rootDir, '.svg-sprite', 'user.txt'), 'utf8'), 'keep')
|
|
|
|
await generateSprite(rootDir, { ...options, mode: 'standalone@webpack' })
|
|
assert.equal(fs.existsSync(path.join(rootDir, '.svg-sprite', 'svg-sprite.manifest.json')), false)
|
|
assert.equal(fs.existsSync(path.join(rootDir, '.svg-sprite', 'index.js')), true)
|
|
assert.equal(fs.existsSync(path.join(rootDir, '.svg-sprite', 'user.txt')), true)
|
|
})
|