1jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; 2 3describe('PathKit\'s Path Behavior', function() { 4 // Note, don't try to print the PathKit object - it can cause Karma/Jasmine to lock up. 5 var PathKit = null; 6 const LoadPathKit = new Promise(function(resolve, reject) { 7 if (PathKit) { 8 resolve(); 9 } else { 10 PathKitInit({ 11 locateFile: (file) => '/pathkit/'+file, 12 }).ready().then((_PathKit) => { 13 PathKit = _PathKit; 14 resolve(); 15 }); 16 } 17 }); 18 19 describe('Basic Path Features', function() { 20 function drawSimplePath() { 21 let path = PathKit.NewPath(); 22 path.moveTo(0, 0); 23 path.lineTo(10, 0); 24 path.lineTo(10, 10); 25 path.close(); 26 return path; 27 } 28 29 it('supports.equals()', function(done) { 30 LoadPathKit.then(catchException(done, () => { 31 let path = drawSimplePath(); 32 let otherPath = drawSimplePath(); 33 let blank = PathKit.NewPath(); 34 35 expect(path.equals(path)).toBe(true); 36 expect(otherPath.equals(path)).toBe(true); 37 expect(path.equals(otherPath)).toBe(true); 38 39 expect(path.equals(blank)).toBe(false); 40 expect(otherPath.equals(blank)).toBe(false); 41 expect(blank.equals(path)).toBe(false); 42 expect(blank.equals(otherPath)).toBe(false); 43 44 path.delete(); 45 otherPath.delete(); 46 blank.delete(); 47 done(); 48 })); 49 }); 50 51 it('has a copy constructor', function(done) { 52 LoadPathKit.then(catchException(done, () => { 53 let orig = drawSimplePath(); 54 let copy = new PathKit.SkPath(orig); 55 56 expect(orig.toSVGString()).toEqual(copy.toSVGString()); 57 expect(orig.equals(copy)).toBe(true); 58 59 orig.delete(); 60 copy.delete(); 61 done(); 62 })); 63 }); 64 65 it('has a copy method', function(done) { 66 LoadPathKit.then(catchException(done, () => { 67 let orig = drawSimplePath(); 68 let copy = orig.copy(); 69 70 expect(orig.toSVGString()).toEqual(copy.toSVGString()); 71 expect(orig.equals(copy)).toBe(true); 72 73 orig.delete(); 74 copy.delete(); 75 done(); 76 })); 77 }); 78 79 it('can create a copy with MakePath', function(done) { 80 LoadPathKit.then(catchException(done, () => { 81 let orig = drawSimplePath(); 82 let copy = PathKit.NewPath(orig); 83 84 expect(orig.toSVGString()).toEqual(copy.toSVGString()); 85 expect(orig.equals(copy)).toBe(true); 86 87 orig.delete(); 88 copy.delete(); 89 done(); 90 })); 91 }); 92 }); 93 94 function ExpectRectsToBeEqual(actual, expected) { 95 if (PathKit.usingWasm) { 96 // exact match 97 expect(actual).toEqual(expected); 98 } else { 99 // floats get rounded a little bit 100 expect(actual.fLeft).toBeCloseTo(expected.fLeft, 4); 101 expect(actual.fTop).toBeCloseTo(expected.fTop, 4); 102 expect(actual.fRight).toBeCloseTo(expected.fRight, 4); 103 expect(actual.fBottom).toBeCloseTo(expected.fBottom, 4); 104 } 105 } 106 107 function bits2float(str) { 108 return PathKit.SkBits2FloatUnsigned(parseInt(str)) 109 } 110 111 describe('bounds and rect', function(){ 112 it('dynamically updates getBounds()', function(done){ 113 LoadPathKit.then(catchException(done, () => { 114 // Based on test_bounds_crbug_513799 115 let path = PathKit.NewPath(); 116 expect(path.getBounds()).toEqual(PathKit.LTRBRect(0, 0, 0, 0)); 117 path.moveTo(-5, -8); 118 expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, -5, -8)); 119 path.rect(1, 2, 2, 2); 120 expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, 3, 4)); 121 path.moveTo(1, 2); 122 expect(path.getBounds()).toEqual(PathKit.LTRBRect(-5, -8, 3, 4)); 123 path.delete(); 124 done(); 125 })); 126 }); 127 128 it('has getBounds() and computeTightBounds()', function(done){ 129 LoadPathKit.then(catchException(done, () => { 130 // Based on PathOpsTightBoundsIllBehaved 131 let path = PathKit.NewPath(); 132 path.moveTo(1, 1); 133 path.quadraticCurveTo(4, 3, 2, 2); 134 expect(path.getBounds()).toEqual(PathKit.LTRBRect(1, 1, 4, 3)); 135 ExpectRectsToBeEqual(path.computeTightBounds(), 136 PathKit.LTRBRect(1, 1, 137 bits2float("0x40333334"), // 2.8 138 bits2float("0x40155556"))); // 2.3333333 139 path.delete(); 140 141 done(); 142 })); 143 }); 144 }); 145 146 function ExpectCmdsToBeEqual(actual, expected) { 147 if (PathKit.usingWasm) { 148 // exact match 149 expect(actual).toEqual(expected); 150 } else { 151 // lossy match 152 actual.every((cmd, cmdIdx) => { 153 cmd.every((arg, argIdx) => { 154 // The asm.js code is close to the wasm/c++ output, but not quite. 155 expect(arg).toBeCloseTo(expected[cmdIdx][argIdx], 4) 156 }); 157 }); 158 } 159 } 160 161 describe('Command arrays', function(){ 162 it('does NOT approximates conics when dumping as toCmds', function(done) { 163 LoadPathKit.then(catchException(done, () => { 164 let path = PathKit.NewPath(); 165 path.moveTo(20, 120); 166 path.arc(20, 120, 18, 0, 1.75 * Math.PI); 167 path.lineTo(20, 120); 168 169 let expectedCmds = [ 170 [PathKit.MOVE_VERB, 20, 120], 171 [PathKit.LINE_VERB, 38, 120], 172 [PathKit.CONIC_VERB, 38, 138, 20, 138, bits2float("0x3f3504f3)")], // 0.707107f 173 [PathKit.CONIC_VERB, 2, 138, 2, 120, bits2float("0x3f3504f3)")], // 0.707107f 174 [PathKit.CONIC_VERB, 2, 102, 20, 102, bits2float("0x3f3504f3)")], // 0.707107f 175 [PathKit.CONIC_VERB, bits2float("0x41dba58e"), 102, bits2float("0x4202e962"), bits2float("0x42d68b4d"), bits2float("0x3f6c8361")], // 27.4558, 102, 32.7279, 107.272, 0.92388 176 [PathKit.LINE_VERB, 20, 120], 177 ]; 178 ExpectCmdsToBeEqual(path.toCmds(), expectedCmds); 179 180 path.delete(); 181 done(); 182 })); 183 }); 184 }); 185 186}); 187