|
1 | 1 | import { describe, test, expect } from '@jest/globals'; |
2 | 2 | import { SVGPathData } from '../index.js'; |
3 | 3 |
|
4 | | -describe('qt to c', () => { |
| 4 | +function testQtToC(input: string) { |
| 5 | + const data = new SVGPathData(input).qtToC(); |
| 6 | + return data.round().encode(); |
| 7 | +} |
| 8 | + |
| 9 | +describe('Quadratic to cubic bezier conversion', () => { |
5 | 10 | test('absolute Q and T commands should be converted', () => { |
6 | | - expect( |
7 | | - new SVGPathData(`M0 0 |
8 | | - Q0,9 9,9 |
9 | | - T9,18`) |
10 | | - .qtToC() |
11 | | - .encode(), |
12 | | - ).toEqual( |
13 | | - new SVGPathData(`M0 0 |
14 | | - C0,6 3,9 9,9 |
15 | | - C15,9 15,12 9,18`).encode(), |
| 11 | + expect(testQtToC('M0 0 Q0,9 9,9 T9,18')).toEqual( |
| 12 | + 'M0 0C0 6 3 9 9 9C15 9 15 12 9 18', |
16 | 13 | ); |
17 | 14 | }); |
18 | 15 |
|
19 | 16 | test('relative Q and T commands should be converted', () => { |
| 17 | + expect(testQtToC('M9 18 q0,9 9,9 t9,18')).toEqual( |
| 18 | + 'M9 18c0 6 3 9 9 9c6 0 9 6 9 18', |
| 19 | + ); |
| 20 | + }); |
| 21 | + |
| 22 | + test('multiple consecutive T commands should calculate correct control points', () => { |
| 23 | + expect(testQtToC('M10 10 Q20,10 30,20 T50,30 T70,20 T90,30')).toEqual( |
| 24 | + 'M10 10C16.6666666666667 10 23.3333333333333 13.3333333333333 30 20C36.6666666666667 26.6666666666667 43.3333333333333 30 50 30C56.6666666666667 30 63.3333333333333 26.6666666666667 70 20C76.6666666666667 13.3333333333333 83.3333333333333 16.6666666666667 90 30', |
| 25 | + ); |
| 26 | + }); |
| 27 | + |
| 28 | + test('mixed absolute and relative Q/T commands', () => { |
| 29 | + expect(testQtToC('M10 10 Q20,20 30,30 t10,10 T50,60 q10,-10 20,0')).toEqual( |
| 30 | + 'M10 10C16.6666666666667 16.6666666666667 23.3333333333333 23.3333333333333 30 30c6.6666666666667 6.6666666666667 10 10 10 10C40 40 43.3333333333333 46.6666666666667 50 60c6.6666666666667 -6.6666666666667 13.3333333333333 -6.6666666666667 20 0', |
| 31 | + ); |
| 32 | + }); |
| 33 | + |
| 34 | + test('Q/T commands after other path commands', () => { |
| 35 | + expect(testQtToC('M10 10 L20,20 H30 V40 Q40,20 50,40 T70,40')).toEqual( |
| 36 | + 'M10 10L20 20H30V40C36.6666666666667 26.6666666666667 43.3333333333333 26.6666666666667 50 40C56.6666666666667 53.3333333333333 63.3333333333333 53.3333333333333 70 40', |
| 37 | + ); |
| 38 | + }); |
| 39 | + |
| 40 | + test('edge cases with zero-length or small paths', () => { |
| 41 | + // Q command with coincident points |
| 42 | + expect(testQtToC('M10 10 Q10,10 10,10')).toEqual( |
| 43 | + 'M10 10C10 10 10 10 10 10', |
| 44 | + ); |
| 45 | + |
| 46 | + // Q command with very small distances |
| 47 | + expect(testQtToC('M10 10 Q10.1,10.1 10.2,10.2')).toEqual( |
| 48 | + 'M10 10C10.0666666666667 10.0666666666667 10.1333333333333 10.1333333333333 10.2 10.2', |
| 49 | + ); |
| 50 | + }); |
| 51 | + |
| 52 | + test('extreme coordinate values', () => { |
| 53 | + expect(testQtToC('M0 0 Q1000,1000 2000,0')).toEqual( |
| 54 | + 'M0 0C666.6666666666666 666.6666666666666 1333.3333333333333 666.6666666666666 2000 0', |
| 55 | + ); |
| 56 | + }); |
| 57 | + |
| 58 | + test('Q/T combined with closepath', () => { |
| 59 | + expect(testQtToC('M10 10 Q20,0 30,10 T50,10 Z')).toEqual( |
| 60 | + 'M10 10C16.6666666666667 3.3333333333333 23.3333333333333 3.3333333333333 30 10C36.6666666666667 16.6666666666667 43.3333333333333 16.6666666666667 50 10z', |
| 61 | + ); |
| 62 | + }); |
| 63 | + |
| 64 | + test('should handle paths with a mix of various commands', () => { |
20 | 65 | expect( |
21 | | - new SVGPathData(`M9 18 |
22 | | - q0,9 9,9 |
23 | | - t9,18`) |
24 | | - .qtToC() |
25 | | - .encode(), |
| 66 | + testQtToC( |
| 67 | + 'M5 5 L10,10 Q15,20 20,10 C25,5 30,0 35,5 T45,15 H55 V25 Q60,30 65,25 Z', |
| 68 | + ), |
26 | 69 | ).toEqual( |
27 | | - new SVGPathData(`M9 18 |
28 | | - c0,6 3,9 9,9 |
29 | | - c6,0 9,6 9,18`).encode(), |
| 70 | + 'M5 5L10 10C13.3333333333333 16.6666666666667 16.6666666666667 16.6666666666667 20 10C25 5 30 0 35 5C35 5 38.3333333333333 8.3333333333333 45 15H55V25C58.3333333333333 28.3333333333333 61.6666666666667 28.3333333333333 65 25z', |
30 | 71 | ); |
31 | 72 | }); |
32 | 73 | }); |
0 commit comments