150 lines
5.9 KiB
JavaScript
150 lines
5.9 KiB
JavaScript
import { test, expect } from '../fixtures.js'
|
|
|
|
test.describe('SVG core utilities', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/tests/unit-harness.html')
|
|
await page.waitForFunction(() => Boolean(window.svgHarness))
|
|
})
|
|
|
|
test('units.convertAttrs appends base unit', async ({ page }) => {
|
|
const attrs = await page.evaluate(() => {
|
|
const { units } = window.svgHarness
|
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
|
|
rect.setAttribute('x', '10')
|
|
rect.setAttribute('y', '20')
|
|
rect.setAttribute('width', '30')
|
|
rect.setAttribute('height', '40')
|
|
svg.append(rect)
|
|
units.init({
|
|
getRoundDigits: () => 2,
|
|
getBaseUnit: () => 'cm'
|
|
})
|
|
units.convertAttrs(rect)
|
|
return {
|
|
x: rect.getAttribute('x'),
|
|
y: rect.getAttribute('y'),
|
|
width: rect.getAttribute('width'),
|
|
height: rect.getAttribute('height')
|
|
}
|
|
})
|
|
expect(attrs.x?.endsWith('cm')).toBe(true)
|
|
expect(attrs.y?.endsWith('cm')).toBe(true)
|
|
expect(attrs.width?.endsWith('cm')).toBe(true)
|
|
expect(attrs.height?.endsWith('cm')).toBe(true)
|
|
})
|
|
|
|
test('utilities.getStrokedBBox returns finite numbers', async ({ page }) => {
|
|
const bbox = await page.evaluate(() => {
|
|
const { utilities, units } = window.svgHarness
|
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
svg.setAttribute('width', '200')
|
|
svg.setAttribute('height', '200')
|
|
document.body.append(svg)
|
|
units.init({
|
|
getRoundDigits: () => 2,
|
|
getBaseUnit: () => 'px'
|
|
})
|
|
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
|
|
rect.setAttribute('x', '10')
|
|
rect.setAttribute('y', '20')
|
|
rect.setAttribute('width', '30')
|
|
rect.setAttribute('height', '40')
|
|
rect.setAttribute('stroke', '#000')
|
|
rect.setAttribute('stroke-width', '10')
|
|
svg.append(rect)
|
|
const addSvg = (json) => {
|
|
const el = document.createElementNS('http://www.w3.org/2000/svg', json.element)
|
|
Object.entries(json.attr).forEach(([k, v]) => el.setAttribute(k, v))
|
|
svg.append(el)
|
|
return el
|
|
}
|
|
const res = utilities.getStrokedBBox([rect], addSvg, { resetOrientation: () => {} })
|
|
return { x: res.x, y: res.y, width: res.width, height: res.height }
|
|
})
|
|
expect(Number.isFinite(bbox.x)).toBe(true)
|
|
expect(Number.isFinite(bbox.y)).toBe(true)
|
|
expect(Number.isFinite(bbox.width)).toBe(true)
|
|
expect(Number.isFinite(bbox.height)).toBe(true)
|
|
})
|
|
|
|
test('utilities XML and base64 helpers escape and roundtrip correctly', async ({ page }) => {
|
|
const result = await page.evaluate(() => {
|
|
const { utilities } = window.svgHarness
|
|
return {
|
|
escaped: utilities.toXml("PB&J '\"<>"),
|
|
encoded: utilities.encode64('abcdef'),
|
|
decoded: utilities.decode64('MTIzNDU='),
|
|
xmlRefs: utilities.convertToXMLReferences('ABC')
|
|
}
|
|
})
|
|
expect(result.escaped).toBe('PB&J '"<>')
|
|
expect(result.encoded).toBe('YWJjZGVm')
|
|
expect(result.decoded).toBe('12345')
|
|
expect(result.xmlRefs).toBe('ABC')
|
|
})
|
|
|
|
test('utilities.getPathDFromSegments and getPathDFromElement build expected d strings', async ({ page }) => {
|
|
const result = await page.evaluate(() => {
|
|
const { utilities } = window.svgHarness
|
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
document.body.append(svg)
|
|
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
|
|
rect.setAttribute('x', '0')
|
|
rect.setAttribute('y', '1')
|
|
rect.setAttribute('width', '5')
|
|
rect.setAttribute('height', '10')
|
|
svg.append(rect)
|
|
const line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
|
|
line.setAttribute('x1', '0')
|
|
line.setAttribute('y1', '1')
|
|
line.setAttribute('x2', '5')
|
|
line.setAttribute('y2', '6')
|
|
svg.append(line)
|
|
const dSegments = utilities.getPathDFromSegments([
|
|
['M', [1, 2]],
|
|
['Z', []]
|
|
])
|
|
return {
|
|
segments: dSegments.trim(),
|
|
rect: utilities.getPathDFromElement(rect),
|
|
line: utilities.getPathDFromElement(line)
|
|
}
|
|
})
|
|
expect(result.segments).toBe('M1,2 Z')
|
|
expect(result.rect).toBe('M0,1 L5,1 L5,11 L0,11 L0,1 Z')
|
|
expect(result.line).toBe('M0,1L5,6')
|
|
})
|
|
|
|
test('utilities.getBBoxOfElementAsPath mirrors element geometry', async ({ page }) => {
|
|
const bbox = await page.evaluate(() => {
|
|
const { utilities } = window.svgHarness
|
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
|
document.body.append(svg)
|
|
const create = (tag, attrs) => {
|
|
const el = document.createElementNS('http://www.w3.org/2000/svg', tag)
|
|
Object.entries(attrs).forEach(([k, v]) => el.setAttribute(k, v))
|
|
return el
|
|
}
|
|
const addSvg = (json) => {
|
|
const el = create(json.element, json.attr)
|
|
svg.append(el)
|
|
return el
|
|
}
|
|
const pathActions = { resetOrientation: () => {} }
|
|
const path = create('path', { id: 'p', d: 'M0,1 Z' })
|
|
const rect = create('rect', { id: 'r', x: '0', y: '1', width: '5', height: '10' })
|
|
const line = create('line', { id: 'l', x1: '0', y1: '1', x2: '5', y2: '6' })
|
|
svg.append(path, rect, line)
|
|
return {
|
|
path: utilities.bboxToObj(utilities.getBBoxOfElementAsPath(path, addSvg, pathActions)),
|
|
rect: utilities.bboxToObj(utilities.getBBoxOfElementAsPath(rect, addSvg, pathActions)),
|
|
line: utilities.bboxToObj(utilities.getBBoxOfElementAsPath(line, addSvg, pathActions))
|
|
}
|
|
})
|
|
expect(bbox.path).toEqual({ x: 0, y: 1, width: 0, height: 0 })
|
|
expect(bbox.rect).toEqual({ x: 0, y: 1, width: 5, height: 10 })
|
|
expect(bbox.line).toEqual({ x: 0, y: 1, width: 5, height: 5 })
|
|
})
|
|
})
|