tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

line-styles.yaml (23925B)


      1 - name: 2d.line.defaults
      2  code: |
      3    @assert ctx.lineWidth === 1;
      4    @assert ctx.lineCap === 'butt';
      5    @assert ctx.lineJoin === 'miter';
      6    @assert ctx.miterLimit === 10;
      7 
      8 - name: 2d.line.width.basic
      9  desc: lineWidth determines the width of line strokes
     10  code: |
     11    ctx.fillStyle = '#0f0';
     12    ctx.fillRect(0, 0, 100, 50);
     13 
     14    ctx.lineWidth = 20;
     15    // Draw a green line over a red box, to check the line is not too small
     16    ctx.fillStyle = '#f00';
     17    ctx.strokeStyle = '#0f0';
     18    ctx.fillRect(15, 15, 20, 20);
     19    ctx.beginPath();
     20    ctx.moveTo(25, 15);
     21    ctx.lineTo(25, 35);
     22    ctx.stroke();
     23 
     24    // Draw a green box over a red line, to check the line is not too large
     25    ctx.fillStyle = '#0f0';
     26    ctx.strokeStyle = '#f00';
     27    ctx.beginPath();
     28    ctx.moveTo(75, 15);
     29    ctx.lineTo(75, 35);
     30    ctx.stroke();
     31    ctx.fillRect(65, 15, 20, 20);
     32 
     33    @assert pixel 14,25 == 0,255,0,255;
     34    @assert pixel 15,25 == 0,255,0,255;
     35    @assert pixel 16,25 == 0,255,0,255;
     36    @assert pixel 25,25 == 0,255,0,255;
     37    @assert pixel 34,25 == 0,255,0,255;
     38    @assert pixel 35,25 == 0,255,0,255;
     39    @assert pixel 36,25 == 0,255,0,255;
     40 
     41    @assert pixel 64,25 == 0,255,0,255;
     42    @assert pixel 65,25 == 0,255,0,255;
     43    @assert pixel 66,25 == 0,255,0,255;
     44    @assert pixel 75,25 == 0,255,0,255;
     45    @assert pixel 84,25 == 0,255,0,255;
     46    @assert pixel 85,25 == 0,255,0,255;
     47    @assert pixel 86,25 == 0,255,0,255;
     48  expected: green
     49 
     50 - name: 2d.line.width.transformed
     51  desc: Line stroke widths are affected by scale transformations
     52  code: |
     53    ctx.fillStyle = '#0f0';
     54    ctx.fillRect(0, 0, 100, 50);
     55 
     56    ctx.lineWidth = 4;
     57    // Draw a green line over a red box, to check the line is not too small
     58    ctx.fillStyle = '#f00';
     59    ctx.strokeStyle = '#0f0';
     60    ctx.fillRect(15, 15, 20, 20);
     61    ctx.save();
     62     ctx.scale(5, 1);
     63     ctx.beginPath();
     64     ctx.moveTo(5, 15);
     65     ctx.lineTo(5, 35);
     66     ctx.stroke();
     67    ctx.restore();
     68 
     69    // Draw a green box over a red line, to check the line is not too large
     70    ctx.fillStyle = '#0f0';
     71    ctx.strokeStyle = '#f00';
     72    ctx.save();
     73     ctx.scale(-5, 1);
     74     ctx.beginPath();
     75     ctx.moveTo(-15, 15);
     76     ctx.lineTo(-15, 35);
     77     ctx.stroke();
     78    ctx.restore();
     79    ctx.fillRect(65, 15, 20, 20);
     80 
     81    @assert pixel 14,25 == 0,255,0,255;
     82    @assert pixel 15,25 == 0,255,0,255;
     83    @assert pixel 16,25 == 0,255,0,255;
     84    @assert pixel 25,25 == 0,255,0,255;
     85    @assert pixel 34,25 == 0,255,0,255;
     86    @assert pixel 35,25 == 0,255,0,255;
     87    @assert pixel 36,25 == 0,255,0,255;
     88 
     89    @assert pixel 64,25 == 0,255,0,255;
     90    @assert pixel 65,25 == 0,255,0,255;
     91    @assert pixel 66,25 == 0,255,0,255;
     92    @assert pixel 75,25 == 0,255,0,255;
     93    @assert pixel 84,25 == 0,255,0,255;
     94    @assert pixel 85,25 == 0,255,0,255;
     95    @assert pixel 86,25 == 0,255,0,255;
     96  expected: green
     97 
     98 - name: 2d.line.width.scaledefault
     99  desc: Default lineWidth strokes are affected by scale transformations
    100  code: |
    101    ctx.fillStyle = '#f00';
    102    ctx.fillRect(0, 0, 100, 50);
    103 
    104    ctx.scale(50, 50);
    105    ctx.strokeStyle = '#0f0';
    106    ctx.moveTo(0, 0.5);
    107    ctx.lineTo(2, 0.5);
    108    ctx.stroke();
    109 
    110    @assert pixel 25,25 == 0,255,0,255;
    111    @assert pixel 50,25 == 0,255,0,255;
    112    @assert pixel 75,25 == 0,255,0,255;
    113    @assert pixel 50,5 == 0,255,0,255;
    114    @assert pixel 50,45 == 0,255,0,255;
    115  expected: green
    116 
    117 - name: 2d.line.width.valid
    118  desc: Setting lineWidth to valid values works
    119  code: |
    120    ctx.lineWidth = 1.5;
    121    @assert ctx.lineWidth === 1.5;
    122 
    123    ctx.lineWidth = "1e1";
    124    @assert ctx.lineWidth === 10;
    125 
    126    ctx.lineWidth = 1/1024;
    127    @assert ctx.lineWidth === 1/1024;
    128 
    129    ctx.lineWidth = 1000;
    130    @assert ctx.lineWidth === 1000;
    131 
    132 - name: 2d.line.width.invalid
    133  desc: Setting lineWidth to invalid values is ignored
    134  code: |
    135    ctx.lineWidth = 1.5;
    136    @assert ctx.lineWidth === 1.5;
    137 
    138    ctx.lineWidth = 1.5;
    139    ctx.lineWidth = 0;
    140    @assert ctx.lineWidth === 1.5;
    141 
    142    ctx.lineWidth = 1.5;
    143    ctx.lineWidth = -1;
    144    @assert ctx.lineWidth === 1.5;
    145 
    146    ctx.lineWidth = 1.5;
    147    ctx.lineWidth = Infinity;
    148    @assert ctx.lineWidth === 1.5;
    149 
    150    ctx.lineWidth = 1.5;
    151    ctx.lineWidth = -Infinity;
    152    @assert ctx.lineWidth === 1.5;
    153 
    154    ctx.lineWidth = 1.5;
    155    ctx.lineWidth = NaN;
    156    @assert ctx.lineWidth === 1.5;
    157 
    158    ctx.lineWidth = 1.5;
    159    ctx.lineWidth = 'string';
    160    @assert ctx.lineWidth === 1.5;
    161 
    162    ctx.lineWidth = 1.5;
    163    ctx.lineWidth = true;
    164    @assert ctx.lineWidth === 1;
    165 
    166    ctx.lineWidth = 1.5;
    167    ctx.lineWidth = false;
    168    @assert ctx.lineWidth === 1.5;
    169 
    170 - name: 2d.line.cap.butt
    171  desc: lineCap 'butt' is rendered correctly
    172  code: |
    173    ctx.fillStyle = '#0f0';
    174    ctx.fillRect(0, 0, 100, 50);
    175 
    176    ctx.lineCap = 'butt';
    177    ctx.lineWidth = 20;
    178 
    179    ctx.fillStyle = '#f00';
    180    ctx.strokeStyle = '#0f0';
    181    ctx.fillRect(15, 15, 20, 20);
    182    ctx.beginPath();
    183    ctx.moveTo(25, 15);
    184    ctx.lineTo(25, 35);
    185    ctx.stroke();
    186 
    187    ctx.fillStyle = '#0f0';
    188    ctx.strokeStyle = '#f00';
    189    ctx.beginPath();
    190    ctx.moveTo(75, 15);
    191    ctx.lineTo(75, 35);
    192    ctx.stroke();
    193    ctx.fillRect(65, 15, 20, 20);
    194 
    195    @assert pixel 25,14 == 0,255,0,255;
    196    @assert pixel 25,15 == 0,255,0,255;
    197    @assert pixel 25,16 == 0,255,0,255;
    198    @assert pixel 25,34 == 0,255,0,255;
    199    @assert pixel 25,35 == 0,255,0,255;
    200    @assert pixel 25,36 == 0,255,0,255;
    201 
    202    @assert pixel 75,14 == 0,255,0,255;
    203    @assert pixel 75,15 == 0,255,0,255;
    204    @assert pixel 75,16 == 0,255,0,255;
    205    @assert pixel 75,34 == 0,255,0,255;
    206    @assert pixel 75,35 == 0,255,0,255;
    207    @assert pixel 75,36 == 0,255,0,255;
    208  expected: green
    209 
    210 - name: 2d.line.cap.round
    211  desc: lineCap 'round' is rendered correctly
    212  code: |
    213    ctx.fillStyle = '#0f0';
    214    ctx.fillRect(0, 0, 100, 50);
    215 
    216    var tol = 1; // tolerance to avoid antialiasing artifacts
    217 
    218    ctx.lineCap = 'round';
    219    ctx.lineWidth = 20;
    220 
    221 
    222    ctx.fillStyle = '#f00';
    223    ctx.strokeStyle = '#0f0';
    224 
    225    ctx.beginPath();
    226    ctx.moveTo(35-tol, 15);
    227    ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
    228    ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
    229    ctx.fill();
    230 
    231    ctx.beginPath();
    232    ctx.moveTo(25, 15);
    233    ctx.lineTo(25, 35);
    234    ctx.stroke();
    235 
    236 
    237    ctx.fillStyle = '#0f0';
    238    ctx.strokeStyle = '#f00';
    239 
    240    ctx.beginPath();
    241    ctx.moveTo(75, 15);
    242    ctx.lineTo(75, 35);
    243    ctx.stroke();
    244 
    245    ctx.beginPath();
    246    ctx.moveTo(85+tol, 15);
    247    ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
    248    ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
    249    ctx.fill();
    250 
    251    @assert pixel 17,6 == 0,255,0,255;
    252    @assert pixel 25,6 == 0,255,0,255;
    253    @assert pixel 32,6 == 0,255,0,255;
    254    @assert pixel 17,43 == 0,255,0,255;
    255    @assert pixel 25,43 == 0,255,0,255;
    256    @assert pixel 32,43 == 0,255,0,255;
    257 
    258    @assert pixel 67,6 == 0,255,0,255;
    259    @assert pixel 75,6 == 0,255,0,255;
    260    @assert pixel 82,6 == 0,255,0,255;
    261    @assert pixel 67,43 == 0,255,0,255;
    262    @assert pixel 75,43 == 0,255,0,255;
    263    @assert pixel 82,43 == 0,255,0,255;
    264  expected: green
    265 
    266 - name: 2d.line.cap.square
    267  desc: lineCap 'square' is rendered correctly
    268  code: |
    269    ctx.fillStyle = '#0f0';
    270    ctx.fillRect(0, 0, 100, 50);
    271 
    272    ctx.lineCap = 'square';
    273    ctx.lineWidth = 20;
    274 
    275    ctx.fillStyle = '#f00';
    276    ctx.strokeStyle = '#0f0';
    277    ctx.fillRect(15, 5, 20, 40);
    278    ctx.beginPath();
    279    ctx.moveTo(25, 15);
    280    ctx.lineTo(25, 35);
    281    ctx.stroke();
    282 
    283    ctx.fillStyle = '#0f0';
    284    ctx.strokeStyle = '#f00';
    285    ctx.beginPath();
    286    ctx.moveTo(75, 15);
    287    ctx.lineTo(75, 35);
    288    ctx.stroke();
    289    ctx.fillRect(65, 5, 20, 40);
    290 
    291    @assert pixel 25,4 == 0,255,0,255;
    292    @assert pixel 25,5 == 0,255,0,255;
    293    @assert pixel 25,6 == 0,255,0,255;
    294    @assert pixel 25,44 == 0,255,0,255;
    295    @assert pixel 25,45 == 0,255,0,255;
    296    @assert pixel 25,46 == 0,255,0,255;
    297 
    298    @assert pixel 75,4 == 0,255,0,255;
    299    @assert pixel 75,5 == 0,255,0,255;
    300    @assert pixel 75,6 == 0,255,0,255;
    301    @assert pixel 75,44 == 0,255,0,255;
    302    @assert pixel 75,45 == 0,255,0,255;
    303    @assert pixel 75,46 == 0,255,0,255;
    304  expected: green
    305 
    306 - name: 2d.line.cap.open
    307  desc: Line caps are drawn at the corners of an unclosed rectangle
    308  code: |
    309    ctx.fillStyle = '#f00';
    310    ctx.strokeStyle = '#0f0';
    311    ctx.fillRect(0, 0, 100, 50);
    312 
    313    ctx.lineJoin = 'bevel';
    314    ctx.lineCap = 'square';
    315    ctx.lineWidth = 400;
    316 
    317    ctx.beginPath();
    318    ctx.moveTo(200, 200);
    319    ctx.lineTo(200, 1000);
    320    ctx.lineTo(1000, 1000);
    321    ctx.lineTo(1000, 200);
    322    ctx.lineTo(200, 200);
    323    ctx.stroke();
    324 
    325    @assert pixel 1,1 == 0,255,0,255;
    326    @assert pixel 48,1 == 0,255,0,255;
    327    @assert pixel 48,48 == 0,255,0,255;
    328    @assert pixel 1,48 == 0,255,0,255;
    329  expected: green
    330 
    331 - name: 2d.line.cap.closed
    332  desc: Line caps are not drawn at the corners of an unclosed rectangle
    333  code: |
    334    ctx.fillStyle = '#0f0';
    335    ctx.strokeStyle = '#f00';
    336    ctx.fillRect(0, 0, 100, 50);
    337 
    338    ctx.lineJoin = 'bevel';
    339    ctx.lineCap = 'square';
    340    ctx.lineWidth = 400;
    341 
    342    ctx.beginPath();
    343    ctx.moveTo(200, 200);
    344    ctx.lineTo(200, 1000);
    345    ctx.lineTo(1000, 1000);
    346    ctx.lineTo(1000, 200);
    347    ctx.closePath();
    348    ctx.stroke();
    349 
    350    @assert pixel 1,1 == 0,255,0,255;
    351    @assert pixel 48,1 == 0,255,0,255;
    352    @assert pixel 48,48 == 0,255,0,255;
    353    @assert pixel 1,48 == 0,255,0,255;
    354  expected: green
    355 
    356 - name: 2d.line.cap.valid
    357  desc: Setting lineCap to valid values works
    358  code: |
    359    ctx.lineCap = 'butt'
    360    @assert ctx.lineCap === 'butt';
    361 
    362    ctx.lineCap = 'round';
    363    @assert ctx.lineCap === 'round';
    364 
    365    ctx.lineCap = 'square';
    366    @assert ctx.lineCap === 'square';
    367 
    368 - name: 2d.line.cap.invalid
    369  desc: Setting lineCap to invalid values is ignored
    370  code: |
    371    ctx.lineCap = 'butt'
    372    @assert ctx.lineCap === 'butt';
    373 
    374    ctx.lineCap = 'butt';
    375    ctx.lineCap = 'invalid';
    376    @assert ctx.lineCap === 'butt';
    377 
    378    ctx.lineCap = 'butt';
    379    ctx.lineCap = 'ROUND';
    380    @assert ctx.lineCap === 'butt';
    381 
    382    ctx.lineCap = 'butt';
    383    ctx.lineCap = 'round\0';
    384    @assert ctx.lineCap === 'butt';
    385 
    386    ctx.lineCap = 'butt';
    387    ctx.lineCap = 'round ';
    388    @assert ctx.lineCap === 'butt';
    389 
    390    ctx.lineCap = 'butt';
    391    ctx.lineCap = "";
    392    @assert ctx.lineCap === 'butt';
    393 
    394    ctx.lineCap = 'butt';
    395    ctx.lineCap = 'bevel';
    396    @assert ctx.lineCap === 'butt';
    397 
    398 - name: 2d.line.fill.noop
    399  desc: Filling a line draws nothing
    400  code: |
    401    ctx.fillStyle = '#0f0';
    402    ctx.fillRect(0, 0, 100, 50);
    403    ctx.fillStyle = '#f00';
    404    ctx.lineWidth = 20;
    405    ctx.beginPath();
    406    ctx.moveTo(10, 20);
    407    ctx.lineTo(90, 30);
    408    ctx.fill();
    409    @assert pixel 50,24 == 0,255,0,255;
    410    @assert pixel 50,25 == 0,255,0,255;
    411    @assert pixel 50,26 == 0,255,0,255;
    412 
    413 - name: 2d.line.join.bevel
    414  desc: lineJoin 'bevel' is rendered correctly
    415  code: |
    416    ctx.fillStyle = '#0f0';
    417    ctx.fillRect(0, 0, 100, 50);
    418 
    419    var tol = 1; // tolerance to avoid antialiasing artifacts
    420 
    421    ctx.lineJoin = 'bevel';
    422    ctx.lineWidth = 20;
    423 
    424    ctx.fillStyle = '#f00';
    425    ctx.strokeStyle = '#0f0';
    426 
    427    ctx.fillRect(10, 10, 20, 20);
    428    ctx.fillRect(20, 20, 20, 20);
    429    ctx.beginPath();
    430    ctx.moveTo(30, 20);
    431    ctx.lineTo(40-tol, 20);
    432    ctx.lineTo(30, 10+tol);
    433    ctx.fill();
    434 
    435    ctx.beginPath();
    436    ctx.moveTo(10, 20);
    437    ctx.lineTo(30, 20);
    438    ctx.lineTo(30, 40);
    439    ctx.stroke();
    440 
    441 
    442    ctx.fillStyle = '#0f0';
    443    ctx.strokeStyle = '#f00';
    444 
    445    ctx.beginPath();
    446    ctx.moveTo(60, 20);
    447    ctx.lineTo(80, 20);
    448    ctx.lineTo(80, 40);
    449    ctx.stroke();
    450 
    451    ctx.fillRect(60, 10, 20, 20);
    452    ctx.fillRect(70, 20, 20, 20);
    453    ctx.beginPath();
    454    ctx.moveTo(80, 20);
    455    ctx.lineTo(90+tol, 20);
    456    ctx.lineTo(80, 10-tol);
    457    ctx.fill();
    458 
    459    @assert pixel 34,16 == 0,255,0,255;
    460    @assert pixel 34,15 == 0,255,0,255;
    461    @assert pixel 35,15 == 0,255,0,255;
    462    @assert pixel 36,15 == 0,255,0,255;
    463    @assert pixel 36,14 == 0,255,0,255;
    464 
    465    @assert pixel 84,16 == 0,255,0,255;
    466    @assert pixel 84,15 == 0,255,0,255;
    467    @assert pixel 85,15 == 0,255,0,255;
    468    @assert pixel 86,15 == 0,255,0,255;
    469    @assert pixel 86,14 == 0,255,0,255;
    470  expected: green
    471 
    472 - name: 2d.line.join.round
    473  desc: lineJoin 'round' is rendered correctly
    474  code: |
    475    ctx.fillStyle = '#0f0';
    476    ctx.fillRect(0, 0, 100, 50);
    477 
    478    var tol = 1; // tolerance to avoid antialiasing artifacts
    479 
    480    ctx.lineJoin = 'round';
    481    ctx.lineWidth = 20;
    482 
    483    ctx.fillStyle = '#f00';
    484    ctx.strokeStyle = '#0f0';
    485 
    486    ctx.fillRect(10, 10, 20, 20);
    487    ctx.fillRect(20, 20, 20, 20);
    488    ctx.beginPath();
    489    ctx.moveTo(30, 20);
    490    ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
    491    ctx.fill();
    492 
    493    ctx.beginPath();
    494    ctx.moveTo(10, 20);
    495    ctx.lineTo(30, 20);
    496    ctx.lineTo(30, 40);
    497    ctx.stroke();
    498 
    499 
    500    ctx.fillStyle = '#0f0';
    501    ctx.strokeStyle = '#f00';
    502 
    503    ctx.beginPath();
    504    ctx.moveTo(60, 20);
    505    ctx.lineTo(80, 20);
    506    ctx.lineTo(80, 40);
    507    ctx.stroke();
    508 
    509    ctx.fillRect(60, 10, 20, 20);
    510    ctx.fillRect(70, 20, 20, 20);
    511    ctx.beginPath();
    512    ctx.moveTo(80, 20);
    513    ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
    514    ctx.fill();
    515 
    516    @assert pixel 36,14 == 0,255,0,255;
    517    @assert pixel 36,13 == 0,255,0,255;
    518    @assert pixel 37,13 == 0,255,0,255;
    519    @assert pixel 38,13 == 0,255,0,255;
    520    @assert pixel 38,12 == 0,255,0,255;
    521 
    522    @assert pixel 86,14 == 0,255,0,255;
    523    @assert pixel 86,13 == 0,255,0,255;
    524    @assert pixel 87,13 == 0,255,0,255;
    525    @assert pixel 88,13 == 0,255,0,255;
    526    @assert pixel 88,12 == 0,255,0,255;
    527  expected: green
    528 
    529 - name: 2d.line.join.miter
    530  desc: lineJoin 'miter' is rendered correctly
    531  code: |
    532    ctx.fillStyle = '#0f0';
    533    ctx.fillRect(0, 0, 100, 50);
    534 
    535    ctx.lineJoin = 'miter';
    536    ctx.lineWidth = 20;
    537 
    538    ctx.fillStyle = '#f00';
    539    ctx.strokeStyle = '#0f0';
    540 
    541    ctx.fillStyle = '#f00';
    542    ctx.strokeStyle = '#0f0';
    543 
    544    ctx.fillRect(10, 10, 30, 20);
    545    ctx.fillRect(20, 10, 20, 30);
    546 
    547    ctx.beginPath();
    548    ctx.moveTo(10, 20);
    549    ctx.lineTo(30, 20);
    550    ctx.lineTo(30, 40);
    551    ctx.stroke();
    552 
    553 
    554    ctx.fillStyle = '#0f0';
    555    ctx.strokeStyle = '#f00';
    556 
    557    ctx.beginPath();
    558    ctx.moveTo(60, 20);
    559    ctx.lineTo(80, 20);
    560    ctx.lineTo(80, 40);
    561    ctx.stroke();
    562 
    563    ctx.fillRect(60, 10, 30, 20);
    564    ctx.fillRect(70, 10, 20, 30);
    565 
    566    @assert pixel 38,12 == 0,255,0,255;
    567    @assert pixel 39,11 == 0,255,0,255;
    568    @assert pixel 40,10 == 0,255,0,255;
    569    @assert pixel 41,9 == 0,255,0,255;
    570    @assert pixel 42,8 == 0,255,0,255;
    571 
    572    @assert pixel 88,12 == 0,255,0,255;
    573    @assert pixel 89,11 == 0,255,0,255;
    574    @assert pixel 90,10 == 0,255,0,255;
    575    @assert pixel 91,9 == 0,255,0,255;
    576    @assert pixel 92,8 == 0,255,0,255;
    577  expected: green
    578 
    579 - name: 2d.line.join.open
    580  desc: Line joins are not drawn at the corner of an unclosed rectangle
    581  code: |
    582    ctx.fillStyle = '#0f0';
    583    ctx.strokeStyle = '#f00';
    584    ctx.fillRect(0, 0, 100, 50);
    585 
    586    ctx.lineJoin = 'miter';
    587    ctx.lineWidth = 200;
    588 
    589    ctx.beginPath();
    590    ctx.moveTo(100, 50);
    591    ctx.lineTo(100, 1000);
    592    ctx.lineTo(1000, 1000);
    593    ctx.lineTo(1000, 50);
    594    ctx.lineTo(100, 50);
    595    ctx.stroke();
    596 
    597    @assert pixel 1,1 == 0,255,0,255;
    598    @assert pixel 48,1 == 0,255,0,255;
    599    @assert pixel 48,48 == 0,255,0,255;
    600    @assert pixel 1,48 == 0,255,0,255;
    601  expected: green
    602 
    603 - name: 2d.line.join.closed
    604  desc: Line joins are drawn at the corner of a closed rectangle
    605  code: |
    606    ctx.fillStyle = '#f00';
    607    ctx.strokeStyle = '#0f0';
    608    ctx.fillRect(0, 0, 100, 50);
    609 
    610    ctx.lineJoin = 'miter';
    611    ctx.lineWidth = 200;
    612 
    613    ctx.beginPath();
    614    ctx.moveTo(100, 50);
    615    ctx.lineTo(100, 1000);
    616    ctx.lineTo(1000, 1000);
    617    ctx.lineTo(1000, 50);
    618    ctx.closePath();
    619    ctx.stroke();
    620 
    621    @assert pixel 1,1 == 0,255,0,255;
    622    @assert pixel 48,1 == 0,255,0,255;
    623    @assert pixel 48,48 == 0,255,0,255;
    624    @assert pixel 1,48 == 0,255,0,255;
    625  expected: green
    626 
    627 - name: 2d.line.join.parallel
    628  desc: Line joins are drawn at 180-degree joins
    629  code: |
    630    ctx.fillStyle = '#f00';
    631    ctx.fillRect(0, 0, 100, 50);
    632 
    633    ctx.strokeStyle = '#0f0';
    634    ctx.lineWidth = 300;
    635    ctx.lineJoin = 'round';
    636    ctx.beginPath();
    637    ctx.moveTo(-100, 25);
    638    ctx.lineTo(0, 25);
    639    ctx.lineTo(-100, 25);
    640    ctx.stroke();
    641 
    642    @assert pixel 1,1 == 0,255,0,255;
    643    @assert pixel 48,1 == 0,255,0,255;
    644    @assert pixel 48,48 == 0,255,0,255;
    645    @assert pixel 1,48 == 0,255,0,255;
    646  expected: green
    647 
    648 - name: 2d.line.join.valid
    649  desc: Setting lineJoin to valid values works
    650  code: |
    651    ctx.lineJoin = 'bevel'
    652    @assert ctx.lineJoin === 'bevel';
    653 
    654    ctx.lineJoin = 'round';
    655    @assert ctx.lineJoin === 'round';
    656 
    657    ctx.lineJoin = 'miter';
    658    @assert ctx.lineJoin === 'miter';
    659 
    660 - name: 2d.line.join.invalid
    661  desc: Setting lineJoin to invalid values is ignored
    662  code: |
    663    ctx.lineJoin = 'bevel'
    664    @assert ctx.lineJoin === 'bevel';
    665 
    666    ctx.lineJoin = 'bevel';
    667    ctx.lineJoin = 'invalid';
    668    @assert ctx.lineJoin === 'bevel';
    669 
    670    ctx.lineJoin = 'bevel';
    671    ctx.lineJoin = 'ROUND';
    672    @assert ctx.lineJoin === 'bevel';
    673 
    674    ctx.lineJoin = 'bevel';
    675    ctx.lineJoin = 'round\0';
    676    @assert ctx.lineJoin === 'bevel';
    677 
    678    ctx.lineJoin = 'bevel';
    679    ctx.lineJoin = 'round ';
    680    @assert ctx.lineJoin === 'bevel';
    681 
    682    ctx.lineJoin = 'bevel';
    683    ctx.lineJoin = "";
    684    @assert ctx.lineJoin === 'bevel';
    685 
    686    ctx.lineJoin = 'bevel';
    687    ctx.lineJoin = 'butt';
    688    @assert ctx.lineJoin === 'bevel';
    689 
    690 - name: 2d.line.miter.exceeded
    691  desc: Miter joins are not drawn when the miter limit is exceeded
    692  code: |
    693    ctx.fillStyle = '#0f0';
    694    ctx.fillRect(0, 0, 100, 50);
    695 
    696    ctx.lineWidth = 400;
    697    ctx.lineJoin = 'miter';
    698 
    699    ctx.strokeStyle = '#f00';
    700    ctx.miterLimit = 1.414;
    701    ctx.beginPath();
    702    ctx.moveTo(200, 1000);
    703    ctx.lineTo(200, 200);
    704    ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
    705    ctx.stroke();
    706 
    707    @assert pixel 1,1 == 0,255,0,255;
    708    @assert pixel 48,1 == 0,255,0,255;
    709    @assert pixel 48,48 == 0,255,0,255;
    710    @assert pixel 1,48 == 0,255,0,255;
    711  expected: green
    712 
    713 - name: 2d.line.miter.acute
    714  desc: Miter joins are drawn correctly with acute angles
    715  code: |
    716    ctx.fillStyle = '#f00';
    717    ctx.fillRect(0, 0, 100, 50);
    718 
    719    ctx.lineWidth = 200;
    720    ctx.lineJoin = 'miter';
    721 
    722    ctx.strokeStyle = '#0f0';
    723    ctx.miterLimit = 2.614;
    724    ctx.beginPath();
    725    ctx.moveTo(100, 1000);
    726    ctx.lineTo(100, 100);
    727    ctx.lineTo(1000, 1000);
    728    ctx.stroke();
    729 
    730    ctx.strokeStyle = '#f00';
    731    ctx.miterLimit = 2.613;
    732    ctx.beginPath();
    733    ctx.moveTo(100, 1000);
    734    ctx.lineTo(100, 100);
    735    ctx.lineTo(1000, 1000);
    736    ctx.stroke();
    737 
    738    @assert pixel 1,1 == 0,255,0,255;
    739    @assert pixel 48,1 == 0,255,0,255;
    740    @assert pixel 48,48 == 0,255,0,255;
    741    @assert pixel 1,48 == 0,255,0,255;
    742  expected: green
    743 
    744 - name: 2d.line.miter.obtuse
    745  desc: Miter joins are drawn correctly with obtuse angles
    746  code: |
    747    ctx.fillStyle = '#f00';
    748    ctx.fillRect(0, 0, 100, 50);
    749 
    750    ctx.lineWidth = 1600;
    751    ctx.lineJoin = 'miter';
    752 
    753    ctx.strokeStyle = '#0f0';
    754    ctx.miterLimit = 1.083;
    755    ctx.beginPath();
    756    ctx.moveTo(800, 10000);
    757    ctx.lineTo(800, 300);
    758    ctx.lineTo(10000, -8900);
    759    ctx.stroke();
    760 
    761    ctx.strokeStyle = '#f00';
    762    ctx.miterLimit = 1.082;
    763    ctx.beginPath();
    764    ctx.moveTo(800, 10000);
    765    ctx.lineTo(800, 300);
    766    ctx.lineTo(10000, -8900);
    767    ctx.stroke();
    768 
    769    @assert pixel 1,1 == 0,255,0,255;
    770    @assert pixel 48,1 == 0,255,0,255;
    771    @assert pixel 48,48 == 0,255,0,255;
    772    @assert pixel 1,48 == 0,255,0,255;
    773  expected: green
    774 
    775 - name: 2d.line.miter.rightangle
    776  desc: Miter joins are not drawn when the miter limit is exceeded, on exact right
    777    angles
    778  code: |
    779    ctx.fillStyle = '#0f0';
    780    ctx.fillRect(0, 0, 100, 50);
    781 
    782    ctx.lineWidth = 400;
    783    ctx.lineJoin = 'miter';
    784 
    785    ctx.strokeStyle = '#f00';
    786    ctx.miterLimit = 1.414;
    787    ctx.beginPath();
    788    ctx.moveTo(200, 1000);
    789    ctx.lineTo(200, 200);
    790    ctx.lineTo(1000, 200);
    791    ctx.stroke();
    792 
    793    @assert pixel 1,1 == 0,255,0,255;
    794    @assert pixel 48,1 == 0,255,0,255;
    795    @assert pixel 48,48 == 0,255,0,255;
    796    @assert pixel 1,48 == 0,255,0,255;
    797  expected: green
    798 
    799 - name: 2d.line.miter.lineedge
    800  desc: Miter joins are not drawn when the miter limit is exceeded at the corners
    801    of a zero-height rectangle
    802  code: |
    803    ctx.fillStyle = '#0f0';
    804    ctx.fillRect(0, 0, 100, 50);
    805 
    806    ctx.lineWidth = 200;
    807    ctx.lineJoin = 'miter';
    808 
    809    ctx.strokeStyle = '#f00';
    810    ctx.miterLimit = 1.414;
    811    ctx.beginPath();
    812    ctx.strokeRect(100, 25, 200, 0);
    813 
    814    @assert pixel 1,1 == 0,255,0,255;
    815    @assert pixel 48,1 == 0,255,0,255;
    816    @assert pixel 48,48 == 0,255,0,255;
    817    @assert pixel 1,48 == 0,255,0,255;
    818  expected: green
    819 
    820 - name: 2d.line.miter.within
    821  desc: Miter joins are drawn when the miter limit is not quite exceeded
    822  code: |
    823    ctx.fillStyle = '#f00';
    824    ctx.fillRect(0, 0, 100, 50);
    825 
    826    ctx.lineWidth = 400;
    827    ctx.lineJoin = 'miter';
    828 
    829    ctx.strokeStyle = '#0f0';
    830    ctx.miterLimit = 1.416;
    831    ctx.beginPath();
    832    ctx.moveTo(200, 1000);
    833    ctx.lineTo(200, 200);
    834    ctx.lineTo(1000, 201);
    835    ctx.stroke();
    836 
    837    @assert pixel 1,1 == 0,255,0,255;
    838    @assert pixel 48,1 == 0,255,0,255;
    839    @assert pixel 48,48 == 0,255,0,255;
    840    @assert pixel 1,48 == 0,255,0,255;
    841  expected: green
    842 
    843 - name: 2d.line.miter.valid
    844  desc: Setting miterLimit to valid values works
    845  code: |
    846    ctx.miterLimit = 1.5;
    847    @assert ctx.miterLimit === 1.5;
    848 
    849    ctx.miterLimit = "1e1";
    850    @assert ctx.miterLimit === 10;
    851 
    852    ctx.miterLimit = 1/1024;
    853    @assert ctx.miterLimit === 1/1024;
    854 
    855    ctx.miterLimit = 1000;
    856    @assert ctx.miterLimit === 1000;
    857 
    858 - name: 2d.line.miter.invalid
    859  desc: Setting miterLimit to invalid values is ignored
    860  code: |
    861    ctx.miterLimit = 1.5;
    862    @assert ctx.miterLimit === 1.5;
    863 
    864    ctx.miterLimit = 1.5;
    865    ctx.miterLimit = 0;
    866    @assert ctx.miterLimit === 1.5;
    867 
    868    ctx.miterLimit = 1.5;
    869    ctx.miterLimit = -1;
    870    @assert ctx.miterLimit === 1.5;
    871 
    872    ctx.miterLimit = 1.5;
    873    ctx.miterLimit = Infinity;
    874    @assert ctx.miterLimit === 1.5;
    875 
    876    ctx.miterLimit = 1.5;
    877    ctx.miterLimit = -Infinity;
    878    @assert ctx.miterLimit === 1.5;
    879 
    880    ctx.miterLimit = 1.5;
    881    ctx.miterLimit = NaN;
    882    @assert ctx.miterLimit === 1.5;
    883 
    884    ctx.miterLimit = 1.5;
    885    ctx.miterLimit = 'string';
    886    @assert ctx.miterLimit === 1.5;
    887 
    888    ctx.miterLimit = 1.5;
    889    ctx.miterLimit = true;
    890    @assert ctx.miterLimit === 1;
    891 
    892    ctx.miterLimit = 1.5;
    893    ctx.miterLimit = false;
    894    @assert ctx.miterLimit === 1.5;
    895 
    896 - name: 2d.line.cross
    897  code: |
    898    ctx.fillStyle = '#0f0';
    899    ctx.fillRect(0, 0, 100, 50);
    900 
    901    ctx.lineWidth = 200;
    902    ctx.lineJoin = 'bevel';
    903 
    904    ctx.strokeStyle = '#f00';
    905    ctx.beginPath();
    906    ctx.moveTo(110, 50);
    907    ctx.lineTo(110, 60);
    908    ctx.lineTo(100, 60);
    909    ctx.stroke();
    910 
    911    @assert pixel 1,1 == 0,255,0,255;
    912    @assert pixel 48,1 == 0,255,0,255;
    913    @assert pixel 48,48 == 0,255,0,255;
    914    @assert pixel 1,48 == 0,255,0,255;
    915  expected: green
    916 
    917 - name: 2d.line.union
    918  code: |
    919    ctx.fillStyle = '#f00';
    920    ctx.fillRect(0, 0, 100, 50);
    921 
    922    ctx.lineWidth = 100;
    923    ctx.lineCap = 'round';
    924 
    925    ctx.strokeStyle = '#0f0';
    926    ctx.beginPath();
    927    ctx.moveTo(0, 24);
    928    ctx.lineTo(100, 25);
    929    ctx.lineTo(0, 26);
    930    ctx.closePath();
    931    ctx.stroke();
    932 
    933    @assert pixel 1,1 == 0,255,0,255;
    934    @assert pixel 25,1 == 0,255,0,255;
    935    @assert pixel 48,1 == 0,255,0,255;
    936    @assert pixel 1,48 == 0,255,0,255;
    937    @assert pixel 25,1 == 0,255,0,255;
    938    @assert pixel 48,48 == 0,255,0,255;
    939  expected: green
    940 
    941 - name: 2d.line.invalid.strokestyle
    942  desc: Verify correct behavior of canvas on an invalid strokeStyle()
    943  code: |
    944    ctx.strokeStyle = 'rgb(0, 255, 0)';
    945    ctx.strokeStyle = 'nonsense';
    946    ctx.lineWidth = 200;
    947    ctx.moveTo(0,100);
    948    ctx.lineTo(200,100);
    949    ctx.stroke();
    950    var imageData = ctx.getImageData(0, 0, 200, 200);
    951    var imgdata = imageData.data;
    952    @assert imgdata[4] == 0;
    953    @assert imgdata[5] == 255;
    954    @assert imgdata[6] == 0;