import PatternedLine from './PatternedLine.mjs'; describe('PatternedLine', () => { function simplify(path, dp) { return path.replace(/[0-9.]+/g, (v) => Number(v).toFixed(dp)); } describe('unpatterned', () => { it('connects points with simple lines', () => { const ln = new PatternedLine() .move(10, 20) .line(30, 50) .line(1, 2); expect(ln.asPath()).toEqual( 'M10 20' + 'L30 50' + 'L1 2' ); }); it('supports simple (circular) arcs', () => { const ln = new PatternedLine() .move(10, 20) .arc(10, 30, Math.PI); expect(simplify(ln.asPath(), 0)).toEqual( 'M10 20' + 'A10 10 0 1 1 10 40' ); }); it('supports quarter arcs', () => { const ln = new PatternedLine() .move(10, 20) .arc(10, 30, Math.PI / 2) .arc(10, 30, Math.PI / 2) .arc(10, 30, Math.PI / 2) .arc(10, 30, Math.PI / 2); expect(simplify(ln.asPath(), 0)).toEqual( 'M10 20' + 'A10 10 0 0 1 20 30' + 'L20 30' + 'A10 10 0 0 1 10 40' + 'L10 40' + 'A10 10 0 0 1 0 30' + 'L0 30' + 'A10 10 0 0 1 10 20' ); }); it('can combine lines and arcs', () => { const ln = new PatternedLine() .move(10, 20) .line(20, 20) .arc(20, 30, Math.PI) .line(10, 40); expect(simplify(ln.asPath(), 0)).toEqual( 'M10 20' + 'L20 20' + 'A10 10 0 1 1 20 40' + 'L10 40' ); }); it('ignores cap()', () => { const ln1 = new PatternedLine() .move(10, 20) .line(10, 40) .cap(); expect(ln1.asPath()).toEqual( 'M10 20' + 'L10 40' ); const ln2 = new PatternedLine() .move(10, 20) .arc(10, 30, Math.PI) .cap(); expect(simplify(ln2.asPath(), 0)).toEqual( 'M10 20' + 'A10 10 0 1 1 10 40' ); }); }); describe('patterned', () => { const patternDeltas = [-1, 1, -2]; const pattern = { getDelta: (p) => patternDeltas[p % 3], partWidth: 5, }; it('draws lines using the given pattern', () => { const ln = new PatternedLine(pattern) .move(10, 20) .line(30, 20); /* * Last segment of line is not rendered to avoid high * frequencies near line segment joins */ expect(ln.asPath()).toEqual( 'M10 19' + 'L15 21' + 'L20 18' + 'L25 19' ); }); it('maintains phase between line segments', () => { const ln = new PatternedLine(pattern) .move(10, 20) .line(30, 20) .line(30, 33); expect(ln.asPath()).toEqual( 'M10 19' + 'L15 21' + 'L20 18' + 'L25 19' + 'L29 20' + 'L32 25' ); }); it('completes the line beyond the pattern with cap()', () => { const ln = new PatternedLine(pattern) .move(10, 20) .line(30, 20) .line(30, 33) .cap(); expect(ln.asPath()).toEqual( 'M10 19' + 'L15 21' + 'L20 18' + 'L25 19' + 'L29 20' + 'L32 25' + 'L30 33' ); }); it('supports simple (circular) arcs using straight segments', () => { const ln = new PatternedLine(pattern) .move(10, 20) .arc(10, 30, Math.PI) .line(0, 40); expect(simplify(ln.asPath(), 1)).toEqual( 'M10.0 19.0' + 'L14.3 22.1' + 'L20.1 23.5' + 'L21.0 29.2' + 'L18.2 33.7' + 'L17.2 39.6' + 'L10.0 41.0' + 'L5.0 39.0' ); }); }); });