diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/spec/types/PathArray.js | 108 | ||||
-rw-r--r-- | spec/spec/types/Point.js | 31 | ||||
-rw-r--r-- | spec/spec/types/PointArray.js | 112 | ||||
-rw-r--r-- | spec/spec/types/SVGArray.js | 89 | ||||
-rw-r--r-- | spec/spec/types/SVGNumber.js (renamed from spec/spec/types/Number.js) | 0 |
5 files changed, 334 insertions, 6 deletions
diff --git a/spec/spec/types/PathArray.js b/spec/spec/types/PathArray.js new file mode 100644 index 0000000..fd43480 --- /dev/null +++ b/spec/spec/types/PathArray.js @@ -0,0 +1,108 @@ +/* globals describe, expect, it, beforeEach */ + +import { PathArray, Box } from '../../../src/main.js' + +describe('PathArray.js', () => { + let p1, p2, p3, p4, p5, p6, p7 + + beforeEach(() => { + p1 = new PathArray('m10 10 h 80 v 80 h -80 l 300 400 z') + p2 = new PathArray('m10 80 c 40 10 65 10 95 80 s 150 150 180 80 t 300 300 q 52 10 95 80 z') + p3 = new PathArray('m80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 z') + p4 = new PathArray('M215.458,245.23c0,0,77.403,0,94.274,0S405,216.451,405,138.054S329.581,15,287.9,15c-41.68,0-139.924,0-170.688,0C86.45,15,15,60.65,15,134.084c0,73.434,96.259,112.137,114.122,112.137C146.984,246.221,215.458,245.23,215.458,245.23z') + p5 = new PathArray('M10 10-45-30.5.5 .89L2e-2.5.5.5-.5C.5.5.5.5.5.5L-3-4z') + p6 = new PathArray('m 0,0 0,3189 2209,0 0,-3189 -2209,0 z m 154,154 1901,0 0,2881 -1901,0 0,-2881 z') + p7 = new PathArray('m 0,0 a 45 45, 0, 0, 0, 125 125') + }) + + it('converts to absolute values', () => { + expect(p1.toString()).toBe('M10 10H90V90H10L310 490Z ') + expect(p2.toString()).toBe('M10 80C50 90 75 90 105 160S255 310 285 240T585 540Q637 550 680 620Z ') + expect(p3.toString()).toBe('M80 80A45 45 0 0 0 125 125L125 80Z ') + expect(p4.toString()).toBe('M215.458 245.23C215.458 245.23 292.861 245.23 309.73199999999997 245.23S405 216.451 405 138.054S329.581 15 287.9 15C246.21999999999997 15 147.97599999999997 15 117.21199999999999 15C86.45 15 15 60.65 15 134.084C15 207.518 111.259 246.221 129.122 246.221C146.984 246.221 215.458 245.23 215.458 245.23Z ') + expect(p6.toString()).toBe('M0 0L0 3189L2209 3189L2209 0L0 0ZM154 154L2055 154L2055 3035L154 3035L154 154Z ') + expect(p7.toString()).toBe('M0 0A45 45 0 0 0 125 125 ') + }) + + it('parses difficult syntax correctly', () => { + expect(p5.toString()).toBe('M10 10L-45 -30.5L0.5 0.89L0.02 0.5L0.5 -0.5C0.5 0.5 0.5 0.5 0.5 0.5L-3 -4Z ') + }) + + it('parses flat arrays correctly', () => { + const arr = new PathArray([ 'M', 0, 0, 'L', 100, 100, 'z' ]) + expect(arr.toString()).toBe('M0 0L100 100Z ') + }) + + it('parses nested arrays correctly', () => { + const arr = new PathArray([ [ 'M', 0, 0 ], [ 'L', 100, 100 ], [ 'z' ] ]) + expect(arr.toString()).toBe('M0 0L100 100Z ') + }) + + // this test is designed to cover a certain line but it doesnt work because of #608 + it('returns the valueOf when PathArray is given', () => { + const p = new PathArray('m10 10 h 80 v 80 h -80 l 300 400 z') + + expect((new PathArray(p))).toEqual(p) + }) + + it('can handle all formats which can be used', () => { + // when no command is specified after move, line is used automatically (specs say so) + expect(new PathArray('M10 10 80 80 30 30 Z').toString()).toBe('M10 10L80 80L30 30Z ') + + // parsing can handle 0.5.3.3.2 stuff + expect(new PathArray('M10 10L.5.5.3.3Z').toString()).toBe('M10 10L0.5 0.5L0.3 0.3Z ') + }) + + describe('move()', () => { + it('moves all points in a straight path', () => { + expect(p1.move(100, 200).toString()).toBe('M100 200H180V280H100L400 680Z ') + }) + + it('moves all points in a curved path', () => { + expect(p2.move(100, 200).toString()).toBe('M100 200C140 210 165 210 195 280S345 430 375 360T675 660Q727 670 770 740Z ') + }) + + it('moves all points in a arc path', () => { + expect(p3.move(100, 200).toString()).toBe('M100 200A45 45 0 0 0 145 245L145 200Z ') + }) + + it('does nothing if passed number is not a number', () => { + expect(p3.move()).toEqual(p3) + }) + }) + + describe('size()', () => { + it('resizes all points in a straight path', () => { + expect(p1.size(600, 200).toString()).toBe('M10 10H170V43.333333333333336H10L610 210Z ') + }) + + it('resizes all points in a curved path', () => { + expect(p2.size(600, 200).toString()).toBe('M10 80C45.82089552238806 83.70370370370371 68.2089552238806 83.70370370370371 95.07462686567165 109.62962962962963S229.40298507462686 165.1851851851852 256.2686567164179 139.25925925925927T524.9253731343283 250.37037037037038Q571.4925373134329 254.07407407407408 610 280Z ') + }) + + it('resizes all points in a arc path', () => { + const expected = [ + [ 'M', 80, 80 ], + [ 'A', 600, 200, 0, 0, 0, 680, 280 ], + [ 'L', 680, 80 ], + [ 'Z' ] + ] + + const toBeTested = p3.size(600, 200) + + for (let i = toBeTested.length; i--;) { + expect(toBeTested[i].shift().toUpperCase()).toBe(expected[i].shift().toUpperCase()) + for (let j = toBeTested[i].length; j--;) { + expect(toBeTested[i][j]).toBeCloseTo(expected[i][j]) + } + } + }) + }) + + describe('bbox()', () => { + it('calculates the bounding box of the PathArray', () => { + const box = new PathArray('M0 0 L 10 10').bbox() + expect(box).toEqual(new Box(0, 0, 10, 10)) + }) + }) +}) diff --git a/spec/spec/types/Point.js b/spec/spec/types/Point.js index ee0bbd4..ef0b6f6 100644 --- a/spec/spec/types/Point.js +++ b/spec/spec/types/Point.js @@ -1,6 +1,6 @@ -/* globals describe, expect, it, beforeEach */ +/* globals describe, expect, it, beforeEach, spyOn */ -import { Point } from '../../../src/main.js' +import { Point, Rect, Matrix } from '../../../src/main.js' describe('Point.js', () => { var point @@ -66,6 +66,16 @@ describe('Point.js', () => { }) }) + describe('transform()', () => { + it('transforms a point with a matrix', () => { + expect(new Point().transform(new Matrix({ translate: [ 10, 10 ] }))).toEqual(new Point(10, 10)) + }) + + it('transforms a point with a transformation object', () => { + expect(new Point().transform({ translate: [ 10, 10 ] })).toEqual(new Point(10, 10)) + }) + }) + describe('clone()', () => { it('returns cloned point', () => { var point1 = new Point(1, 1) @@ -75,4 +85,21 @@ describe('Point.js', () => { expect(point1).not.toBe(point2) }) }) + + describe('toArray()', () => { + it('creates an array representation of Point', () => { + const p = new Point(1, 2) + expect(p.toArray()).toEqual([ 1, 2 ]) + }) + }) + + describe('Element', () => { + describe('point()', () => { + it('transforms a screen point into the coordinate system of the element', () => { + const rect = new Rect() + spyOn(rect, 'screenCTM').and.callFake(() => new Matrix(1, 0, 0, 1, 20, 20)) + expect(rect.point({ x: 10, y: 10 })).toEqual(new Point(-10, -10)) + }) + }) + }) }) diff --git a/spec/spec/types/PointArray.js b/spec/spec/types/PointArray.js index da8675e..cbcc3c1 100644 --- a/spec/spec/types/PointArray.js +++ b/spec/spec/types/PointArray.js @@ -2,24 +2,122 @@ import { PointArray, Matrix, Point } from '../../../src/main.js' -describe('PointArray', () => { +describe('PointArray.js', () => { const squareString = '0,0 1,0 1,1 0,1' - const square = new PointArray(squareString) + + describe('()', () => { + + it('parses a string to a point array', () => { + var array = new PointArray('0,1 -.05,7.95 1000.0001,-200.222') + expect(array.valueOf()).toEqual([ [ 0, 1 ], [ -0.05, 7.95 ], [ 1000.0001, -200.222 ] ]) + }) + + it('parses a points array correctly to string', () => { + var array = new PointArray([ [ 0, 0.15 ], [ -100, -3.141592654 ], [ 50, 100 ] ]) + expect(array + '').toBe('0,0.15 -100,-3.141592654 50,100') + }) + + it('parses a flat array of x/y coordinates to a point array', () => { + var array = new PointArray([ 1, 4, 5, 68, 12, 24 ]) + expect(array.valueOf()).toEqual([ [ 1, 4 ], [ 5, 68 ], [ 12, 24 ] ]) + }) + + it('parses points with space delimitered x/y coordinates', () => { + var array = new PointArray('221.08 191.79 0.46 191.79 0.46 63.92 63.8 0.46 284.46 0.46 284.46 128.37 221.08 191.79') + expect(array + '').toBe('221.08,191.79 0.46,191.79 0.46,63.92 63.8,0.46 284.46,0.46 284.46,128.37 221.08,191.79') + }) + + it('parses points with comma delimitered x/y coordinates', () => { + var array = new PointArray('221.08,191.79,0.46,191.79,0.46,63.92,63.8,0.46,284.46,0.46,284.46,128.37,221.08,191.79') + expect(array + '').toBe('221.08,191.79 0.46,191.79 0.46,63.92 63.8,0.46 284.46,0.46 284.46,128.37 221.08,191.79') + }) + + it('parses points with comma and space delimitered x/y coordinates', () => { + var array = new PointArray('221.08, 191.79, 0.46, 191.79, 0.46, 63.92, 63.8, 0.46, 284.46, 0.46, 284.46, 128.37, 221.08, 191.79') + expect(array + '').toBe('221.08,191.79 0.46,191.79 0.46,63.92 63.8,0.46 284.46,0.46 284.46,128.37 221.08,191.79') + }) + + it('parses points with space and comma delimitered x/y coordinates', () => { + var array = new PointArray('221.08 ,191.79 ,0.46 ,191.79 ,0.46 ,63.92 ,63.8 ,0.46 ,284.46 ,0.46 ,284.46 ,128.37 ,221.08 ,191.79') + expect(array + '').toBe('221.08,191.79 0.46,191.79 0.46,63.92 63.8,0.46 284.46,0.46 284.46,128.37 221.08,191.79') + }) + + it('parses points with redundant spaces at the end', () => { + var array = new PointArray('2176.6,1708.8 2176.4,1755.8 2245.8,1801.5 2297,1787.8 ') + expect(array + '').toBe('2176.6,1708.8 2176.4,1755.8 2245.8,1801.5 2297,1787.8') + }) + + it('parses points with space delimitered x/y coordinates - even with leading or trailing space', () => { + var array = new PointArray(' 1 2 3 4 ') + expect(array + '').toBe('1,2 3,4') + }) + + it('parses odd number of points with space delimitered x/y coordinates and silently remove the odd point', () => { + // this is according to spec: https://svgwg.org/svg2-draft/shapes.html#DataTypePoints + var array = new PointArray('1 2 3') + expect(array + '').toBe('1,2') + }) + + it('parses odd number of points in a flat array of x/y coordinates and silently remove the odd point', () => { + // this is according to spec: https://svgwg.org/svg2-draft/shapes.html#DataTypePoints + var array = new PointArray([ 1, 2, 3 ]) + expect(array.valueOf()).toEqual([ [ 1, 2 ] ]) + }) + + }) + + describe('move()', () => { + it('moves the whole array by the passed value', () => { + const arr = new PointArray([ 1, 2, 3, 4 ]).move(10, 10) + expect(arr.toArray()).toEqual([ 10, 10, 12, 12 ]) + }) + + it('does nothing if values not numbers', () => { + const arr = new PointArray([ 1, 2, 3, 4 ]).move() + expect(arr.toArray()).toEqual([ 1, 2, 3, 4 ]) + }) + }) + + describe('size()', () => { + it('correctly sizes the points over the whole area', () => { + var array = new PointArray([ 10, 10, 20, 20, 30, 30 ]) + expect(array.size(60, 60).valueOf()).toEqual([ [ 10, 10 ], [ 40, 40 ], [ 70, 70 ] ]) + }) + + it('let coordinates untouched when width/height is zero', () => { + var array = new PointArray([ 10, 10, 10, 20, 10, 30 ]) + expect(array.size(60, 60).valueOf()).toEqual([ [ 10, 10 ], [ 10, 40 ], [ 10, 70 ] ]) + + array = new PointArray([ 10, 10, 20, 10, 30, 10 ]) + expect(array.size(60, 60).valueOf()).toEqual([ [ 10, 10 ], [ 40, 10 ], [ 70, 10 ] ]) + }) + + }) describe('toString()', () => { - it('round trips with string', () => { + it('converts to comma sepereated list', () => { + const square = new PointArray(squareString) expect(square.toString()).toEqual(squareString) }) }) + describe('toLine', () => { + it('returns an object which can be passed to a line as point attributes', () => { + const arr = new PointArray([ 1, 2, 3, 4 ]) + expect(arr.toLine()).toEqual({ x1: 1, y1: 2, x2: 3, y2: 4 }) + }) + }) + describe('transform()', () => { it('translates correctly', () => { - const translation = new Matrix().translate(2, 1) + const square = new PointArray(squareString) + const translation = new Matrix({ translate: [ 2, 1 ] }) const newSquare = square.transform(translation) expect(newSquare.toString()).toEqual('2,1 3,1 3,2 2,2') }) it('transforms like Point', () => { + const square = new PointArray(squareString) const matrix = new Matrix(1, 2, 3, 4, 5, 6) const newSquare = square.transform(matrix) for (let i = 0; i < square.length; i++) { @@ -28,5 +126,11 @@ describe('PointArray', () => { expect(squarePoint.transform(matrix)).toEqual(newSquarePoint) } }) + + it('works with transform object instead of matrix', () => { + const square = new PointArray(squareString) + const newSquare = square.transform({ translate: [ 2, 1 ] }) + expect(newSquare.toString()).toEqual('2,1 3,1 3,2 2,2') + }) }) }) diff --git a/spec/spec/types/SVGArray.js b/spec/spec/types/SVGArray.js new file mode 100644 index 0000000..cefc54e --- /dev/null +++ b/spec/spec/types/SVGArray.js @@ -0,0 +1,89 @@ +/* globals describe, expect, it, jasmine */ + +import { Array as SVGArray, PointArray, PathArray } from '../../../src/main.js' + +const { any } = jasmine + +describe('SVGArray.js', () => { + describe('()', () => { + + it('preallocates memory if only number is passed', () => { + const arr = new SVGArray(1) + expect(arr.length).toBe(1) + }) + + it('parses a matrix array correctly to string', () => { + const array = new SVGArray([ + 0.343, 0.669, 0.119, 0, 0, + 0.249, -0.626, 0.130, 0, 0, + 0.172, 0.334, 0.111, 0, 0, + 0.000, 0.000, 0.000, 1, -0 + ]) + + expect(array + '').toBe('0.343 0.669 0.119 0 0 0.249 -0.626 0.13 0 0 0.172 0.334 0.111 0 0 0 0 0 1 0') + }) + + it('parses space seperated string and converts it to array', () => { + expect((new SVGArray('1 2 3 4')).valueOf()).toEqual([ 1, 2, 3, 4 ]) + }) + + it('parses comma seperated string and converts it to array', () => { + expect((new SVGArray('1,2,3,4')).valueOf()).toEqual([ 1, 2, 3, 4 ]) + }) + + }) + + describe('reverse()', () => { + it('reverses the array', () => { + const array = new SVGArray([ 1, 2, 3, 4, 5 ]).reverse() + expect(array.valueOf()).toEqual([ 5, 4, 3, 2, 1 ]) + }) + + it('returns itself', () => { + const array = new SVGArray() + expect(array.reverse()).toBe(array) + }) + }) + + describe('clone()', () => { + it('creates a shallow clone of the array', () => { + const array = new SVGArray([ 1, 2, 3, 4, 5 ]) + const clone = array.clone() + + expect(array).toEqual(clone) + expect(array).not.toBe(clone) + }) + + it('also works with PointArray (one depths clone)', () => { + const array = new PointArray([ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]) + const clone = array.clone() + + expect(array).toEqual(clone) + expect(array).not.toBe(clone) + + for (let i = array.length; i--;) { + expect(array[i]).not.toBe(clone[i]) + } + }) + + it('also works with PathArray (one depths clone)', () => { + const array = new PathArray([ [ 'M', 1, 2 ], [ 'L', 3, 4 ], [ 'L', 5, 6 ] ]) + const clone = array.clone() + + expect(array).toEqual(clone) + expect(array).not.toBe(clone) + + for (let i = array.length; i--;) { + expect(array[i]).not.toBe(clone[i]) + } + }) + }) + + describe('toSet()', () => { + it('creates a Set from the Array', () => { + const set = new SVGArray([ 1, 1, 2, 3 ]).toSet() + expect(set).toEqual(any(Set)) + expect(set).toEqual(new Set([ 1, 2, 3 ])) + }) + }) +}) diff --git a/spec/spec/types/Number.js b/spec/spec/types/SVGNumber.js index d7ef2fd..d7ef2fd 100644 --- a/spec/spec/types/Number.js +++ b/spec/spec/types/SVGNumber.js |