UNPKG

swiftvg

Version:

Convert SVG path data to a Swift 3 UIBezierPath

256 lines (215 loc) 8.59 kB
'use strict' const chai = require('chai') const parse = require('parse-svg-path') const ramda = require('ramda') const swiftvg = require('./index') const expect = chai.expect const head = ramda.head const pipe = ramda.pipe const beginShape = swiftvg.beginShape const roundFloat = swiftvg.roundFloat const cgPoint = swiftvg.cgPoint const convertArc = swiftvg.convertArc const convertArcXY = swiftvg.convertArcXY const convertCCXY = swiftvg.convertCCXY const convertCubicCurve = swiftvg.convertCubicCurve const convertLine = swiftvg.convertLine const convertMove = swiftvg.convertMove const convertPoints = swiftvg.convertPoints const convertQCXY = swiftvg.convertQCXY const convertQuadraticCurve = swiftvg.convertQuadraticCurve const convertXY = swiftvg.convertXY const dispatch = swiftvg.dispatch const endShape = swiftvg.endShape const initialState = swiftvg.initialState const processPathData = swiftvg.processPathData const reducer = swiftvg.reducer const SET_ABSOLUTE = swiftvg.SET_ABSOLUTE const SET_RELATIVE = swiftvg.SET_RELATIVE describe('svgswift state functions', () => { it('should return the state with no matching action', () => { const newState = reducer(initialState, '', {}) expect(newState).to.deep.equal(initialState) }) it('should set new absolute coordinates', () => { const newState = reducer(initialState, SET_ABSOLUTE, { x: 1, y: 2 }) const newState2 = reducer(newState, SET_ABSOLUTE, { x: 3, y: 4 }) expect(newState2).to.deep.equal({ x: 3, y: 4 }) }) it('should set new absolute coordinates when x is null', () => { const newState = reducer(initialState, SET_ABSOLUTE, { x: 1, y: 2 }) const newState2 = reducer(newState, SET_ABSOLUTE, { x: null, y: 4 }) expect(newState2).to.deep.equal({ x: 1, y: 4 }) }) it('should set new absolute coordinates when y is null', () => { const newState = reducer(initialState, SET_ABSOLUTE, { x: 1, y: 2 }) const newState2 = reducer(newState, SET_ABSOLUTE, { x: 3, y: null }) expect(newState2).to.deep.equal({ x: 3, y: 2 }) }) it('should set new relative coordinates', () => { const newState = reducer(initialState, SET_RELATIVE, { x: 1, y: 2 }) const newState2 = reducer(newState, SET_RELATIVE, { x: 3, y: 4 }) expect(newState2).to.deep.equal({ x: 4, y: 6 }) }) it('should set new absolute coordinates with number strings', () => { const newState = reducer(initialState, SET_ABSOLUTE, { x: '1', y: '2' }) const newState2 = reducer(newState, SET_ABSOLUTE, { x: '3', y: '4' }) expect(newState2).to.deep.equal({ x: 3, y: 4 }) }) it('should set new relative coordinates with number strings', () => { const newState = reducer(initialState, SET_RELATIVE, { x: '1', y: '2' }) const newState2 = reducer(newState, SET_RELATIVE, { x: '3', y: '4' }) expect(newState2).to.deep.equal({ x: 4, y: 6 }) }) it('should dispatch updates to state', () => { const absoluteState = dispatch(SET_ABSOLUTE, { x: 1, y: 2 }) const relativeState = dispatch(SET_RELATIVE, { x: 2, y: 3 }) expect(absoluteState).to.deep.equal({ x: 1, y: 2 }) expect(relativeState).to.deep.equal({ x: 3, y: 5 }) }) }) describe('svgswift helper functions', () => { it('should round large numbers', () => { expect(roundFloat('-9.84503095e-15')).to.equal(0) expect(roundFloat('0.80')).to.equal(0.8) expect(roundFloat('0.084')).to.equal(0.08) expect(roundFloat('5')).to.equal(5) expect(roundFloat(-9.84503095e-15)).to.equal(0) expect(roundFloat(0.80)).to.equal(0.8) expect(roundFloat(0.084)).to.equal(0.08) expect(roundFloat(5)).to.equal(5) }) it('should convert an array to x and y coordinates', () => { expect(convertXY([1, 2])).to.deep.equal({ x: 1, y: 2 }) expect(convertXY(['1', '2'])).to.deep.equal({ x: 1, y: 2 }) }) it('should convert an array to cubic curve coordinates', () => { expect(convertCCXY([1, 2, 3, 4, 5, 6])).to.deep.equal({ x: 5, y: 6, cp1x: 1, cp1y: 2, cp2x: 3, cp2y: 4 }) expect(convertCCXY(['1', '2', '3', '4', '5', '6'])).to.deep.equal({ x: 5, y: 6, cp1x: 1, cp1y: 2, cp2x: 3, cp2y: 4 }) }) it('should convert an array to quadratic curve coordinates', () => { expect(convertQCXY([1, 2, 3, 4])).to.deep.equal({ x: 3, y: 4, cpx: 1, cpy: 2 }) expect(convertQCXY(['1', '2', '3', '4'])).to.deep.equal({ x: 3, y: 4, cpx: 1, cpy: 2 }) }) it('should convert an array to arc curve coordinates', () => { expect(convertArcXY([1, 2, 0, 0, 0, 6, 7])).to.deep.equal({ x: 6, y: 7, rx: 1, ry: 2, cw: false }) expect(convertArcXY(['1', '2', '0', '0', '0', '6', '7'])).to.deep.equal({ x: 6, y: 7, rx: 1, ry: 2, cw: false }) }) }) describe('Core Graphic functions', () => { const pointData = convertXY([1, 2]) const point = cgPoint(pointData) it('should produce a UIBezierPath initiator', () => { expect(beginShape()).to.equal('let shape = UIBezierPath()') }) it('should produce a CGPoint', () => { expect(cgPoint(pointData)).to.equal('CGPoint(x: 1, y: 2)') }) it('should produce a move call', () => { expect(convertMove(point)).to.equal(`shape.move(to: ${point})`) }) it('should produce an addLine call', () => { expect(convertLine(point)).to.equal(`shape.addLine(to: ${point})`) }) it('should produce an addCurve call for cubic curves', () => { const anchors = [1, 2] const controls1 = [3, 4] const controls2 = [5, 6] const curveData = convertCCXY([].concat(controls1, controls2, anchors)) const convert = pipe(convertXY, cgPoint) const anchorsCP = convert(anchors) const control1CP = convert(controls1) const control2CP = convert(controls2) expect(convertCubicCurve(curveData)) .to.equal( `shape.addCurve(to: ${anchorsCP}, controlPoint1: ${control1CP}, controlPoint2: ${control2CP})` ) }) it('should produce an addCurve call for quadratic curves', () => { const anchors = [1, 2] const controls = [3, 4] const curveData = convertQCXY([].concat(controls, anchors)) const convert = pipe(convertXY, cgPoint) const anchorsCP = convert(anchors) const controlCP = convert(controls) expect(convertQuadraticCurve(curveData)) .to.equal( `shape.addCurve(to: ${anchorsCP}, controlPoint: ${controlCP})` ) }) it('should produce an addArc call', () => { const center = [1, 2] const radius = [3, 4] const clockwise = [0] const arcData = convertArcXY([].concat(radius, [0, 0], clockwise, center)) const convert = pipe(convertXY, cgPoint) const centerCP = convert(center) const radiusCP = convert(radius) expect(convertArc(arcData)) .to.equal( `shape.addArc(withCenter: ${centerCP}, radius: ${radiusCP}, startAngle: 0, endAngle: 360, clockwise: ${Boolean(head(clockwise))})` ) }) it('should return various calls based on the data', () => { expect(processPathData(head(parse('M37,17')))).to.include('move(') expect(processPathData(head(parse('h37,17')))).to.include('addLine(') expect(processPathData(head(parse('H37,17')))).to.include('addLine(') expect(processPathData(head(parse('v37,17')))).to.include('addLine(') expect(processPathData(head(parse('V37,17')))).to.include('addLine(') expect(processPathData(head(parse('l37,17')))).to.include('addLine(') expect(processPathData(head(parse('L37,17')))).to.include('addLine(') expect(processPathData(head(parse('c27,17 37,17 37,17')))).to.include('addCurve(') expect(processPathData(head(parse('C27,17 37,17 37,17')))).to.include('addCurve(') expect(processPathData(head(parse('q27,17 37,17')))).to.include('addCurve(') expect(processPathData(head(parse('Q27,17 37,17')))).to.include('addCurve(') expect(processPathData(head(parse('A37,17 37 0,0 37,17')))).to.include('addArc(') expect(processPathData(head(parse('Z')))).to.equal(endShape) expect(processPathData(['yolo'])).to.equal(`SVG parsing for yolo data isn't supported yet`) }) it('should convert all the points to strings', () => { const points = convertPoints(parse('M37,17 L10,15 Z')) expect(points).to.be.an('array') expect(points).to.have.length(3) }) it('should export the full swift code from a data string', () => { const points = swiftvg('M37,17 L10,15 Z') expect(points).to.be.an('array') expect(points).to.have.length(4) }) })