- name: 2d.text.font.parse.basic
  testing:
  - 2d.text.font.parse
  - 2d.text.font.get
  code: |
    ctx.font = '20px serif';
    @assert ctx.font === '20px serif';

    ctx.font = '20PX   SERIF';
    @assert ctx.font === '20px serif'; @moz-todo

- name: 2d.text.font.parse.tiny
  testing:
  - 2d.text.font.parse
  - 2d.text.font.get
  code: |
    ctx.font = '1px sans-serif';
    @assert ctx.font === '1px sans-serif';

- name: 2d.text.font.parse.complex
  testing:
  - 2d.text.font.parse
  - 2d.text.font.get
  - 2d.text.font.lineheight
  code: |
    ctx.font = 'small-caps italic 400 12px/2 Unknown Font, sans-serif';
    @assert ctx.font === 'italic small-caps 12px "Unknown Font", sans-serif'; @moz-todo

- name: 2d.text.font.parse.family
  testing:
  - 2d.text.font.parse
  - 2d.text.font.get
  - 2d.text.font.lineheight
  code: |
    ctx.font = '20px cursive,fantasy,monospace,sans-serif,serif,UnquotedFont,"QuotedFont\\\\\\","';
    @assert ctx.font === '20px cursive, fantasy, monospace, sans-serif, serif, UnquotedFont, "QuotedFont\\\\\\","';

  # TODO:
  #   2d.text.font.parse.size.absolute
  #     xx-small x-small small medium large x-large xx-large
  #   2d.text.font.parse.size.relative
  #     smaller larger
  #   2d.text.font.parse.size.length.relative
  #     em ex px
  #   2d.text.font.parse.size.length.absolute
  #     in cm mm pt pc

- name: 2d.text.font.parse.size.percentage
  testing:
  - 2d.text.font.parse
  - 2d.text.font.get
  - 2d.text.font.fontsize
  - 2d.text.font.size
  canvas: 'style="font-size: 144px" width="100" height="50"'
  code: |
    ctx.font = '50% serif';
    @assert ctx.font === '72px serif'; @moz-todo
    canvas.setAttribute('style', 'font-size: 100px');
    @assert ctx.font === '72px serif'; @moz-todo

- name: 2d.text.font.parse.size.percentage.default
  testing:
  - 2d.text.font.undefined
  code: |
    var canvas2 = document.createElement('canvas');
    var ctx2 = canvas2.getContext('2d');
    ctx2.font = '1000% serif';
    @assert ctx2.font === '100px serif'; @moz-todo

- name: 2d.text.font.parse.system
  desc: System fonts must be computed to explicit values
  testing:
  - 2d.text.font.parse
  - 2d.text.font.get
  - 2d.text.font.systemfonts
  code: |
    ctx.font = 'message-box';
    @assert ctx.font !== 'message-box';

- name: 2d.text.font.parse.invalid
  testing:
  - 2d.text.font.invalid
  code: |
    ctx.font = '20px serif';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = '';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = 'bogus';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = 'inherit';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = '10px {bogus}';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = '10px initial';
    @assert ctx.font === '20px serif'; @moz-todo

    ctx.font = '20px serif';
    ctx.font = '10px default';
    @assert ctx.font === '20px serif'; @moz-todo

    ctx.font = '20px serif';
    ctx.font = '10px inherit';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = '10px revert';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = 'var(--x)';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = 'var(--x, 10px serif)';
    @assert ctx.font === '20px serif';

    ctx.font = '20px serif';
    ctx.font = '1em serif; background: green; margin: 10px';
    @assert ctx.font === '20px serif';

- name: 2d.text.font.default
  testing:
  - 2d.text.font.default
  code: |
    @assert ctx.font === '10px sans-serif';

- name: 2d.text.font.relative_size
  testing:
  - 2d.text.font.relative_size
  code: |
    var canvas2 = document.createElement('canvas');
    var ctx2 = canvas2.getContext('2d');
    ctx2.font = '1em sans-serif';
    @assert ctx2.font === '10px sans-serif';

- name: 2d.text.align.valid
  testing:
  - 2d.text.align.get
  - 2d.text.align.set
  code: |
    ctx.textAlign = 'start';
    @assert ctx.textAlign === 'start';

    ctx.textAlign = 'end';
    @assert ctx.textAlign === 'end';

    ctx.textAlign = 'left';
    @assert ctx.textAlign === 'left';

    ctx.textAlign = 'right';
    @assert ctx.textAlign === 'right';

    ctx.textAlign = 'center';
    @assert ctx.textAlign === 'center';

- name: 2d.text.align.invalid
  testing:
  - 2d.text.align.invalid
  code: |
    ctx.textAlign = 'start';
    ctx.textAlign = 'bogus';
    @assert ctx.textAlign === 'start';

    ctx.textAlign = 'start';
    ctx.textAlign = 'END';
    @assert ctx.textAlign === 'start';

    ctx.textAlign = 'start';
    ctx.textAlign = 'end ';
    @assert ctx.textAlign === 'start';

    ctx.textAlign = 'start';
    ctx.textAlign = 'end\0';
    @assert ctx.textAlign === 'start';

- name: 2d.text.align.default
  testing:
  - 2d.text.align.default
  code: |
    @assert ctx.textAlign === 'start';


- name: 2d.text.baseline.valid
  testing:
  - 2d.text.baseline.get
  - 2d.text.baseline.set
  code: |
    ctx.textBaseline = 'top';
    @assert ctx.textBaseline === 'top';

    ctx.textBaseline = 'hanging';
    @assert ctx.textBaseline === 'hanging';

    ctx.textBaseline = 'middle';
    @assert ctx.textBaseline === 'middle';

    ctx.textBaseline = 'alphabetic';
    @assert ctx.textBaseline === 'alphabetic';

    ctx.textBaseline = 'ideographic';
    @assert ctx.textBaseline === 'ideographic';

    ctx.textBaseline = 'bottom';
    @assert ctx.textBaseline === 'bottom';

- name: 2d.text.baseline.invalid
  testing:
  - 2d.text.baseline.invalid
  code: |
    ctx.textBaseline = 'top';
    ctx.textBaseline = 'bogus';
    @assert ctx.textBaseline === 'top';

    ctx.textBaseline = 'top';
    ctx.textBaseline = 'MIDDLE';
    @assert ctx.textBaseline === 'top';

    ctx.textBaseline = 'top';
    ctx.textBaseline = 'middle ';
    @assert ctx.textBaseline === 'top';

    ctx.textBaseline = 'top';
    ctx.textBaseline = 'middle\0';
    @assert ctx.textBaseline === 'top';

- name: 2d.text.baseline.default
  testing:
  - 2d.text.baseline.default
  code: |
    @assert ctx.textBaseline === 'alphabetic';





- name: 2d.text.draw.baseline.top
  desc: textBaseline top is the top of the em square (not the bounding box)
  testing:
  - 2d.text.baseline.top
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.textBaseline = 'top';
        ctx.fillText('CC', 0, 0);
        @assert pixel 5,5 ==~ 0,255,0,255;
        @assert pixel 95,5 ==~ 0,255,0,255;
        @assert pixel 25,25 ==~ 0,255,0,255;
        @assert pixel 75,25 ==~ 0,255,0,255;
        @assert pixel 5,45 ==~ 0,255,0,255;
        @assert pixel 95,45 ==~ 0,255,0,255;
    }), 500);
  expected: green

- name: 2d.text.draw.baseline.bottom
  desc: textBaseline bottom is the bottom of the em square (not the bounding box)
  testing:
  - 2d.text.baseline.bottom
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.textBaseline = 'bottom';
        ctx.fillText('CC', 0, 50);
        @assert pixel 5,5 ==~ 0,255,0,255;
        @assert pixel 95,5 ==~ 0,255,0,255;
        @assert pixel 25,25 ==~ 0,255,0,255;
        @assert pixel 75,25 ==~ 0,255,0,255;
        @assert pixel 5,45 ==~ 0,255,0,255;
        @assert pixel 95,45 ==~ 0,255,0,255;
    }), 500);
  expected: green

- name: 2d.text.draw.baseline.middle
  desc: textBaseline middle is the middle of the em square (not the bounding box)
  testing:
  - 2d.text.baseline.middle
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.textBaseline = 'middle';
        ctx.fillText('CC', 0, 25);
        @assert pixel 5,5 ==~ 0,255,0,255;
        @assert pixel 95,5 ==~ 0,255,0,255;
        @assert pixel 25,25 ==~ 0,255,0,255;
        @assert pixel 75,25 ==~ 0,255,0,255;
        @assert pixel 5,45 ==~ 0,255,0,255;
        @assert pixel 95,45 ==~ 0,255,0,255;
    }), 500);
  expected: green

- name: 2d.text.draw.baseline.alphabetic
  testing:
  - 2d.text.baseline.alphabetic
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.textBaseline = 'alphabetic';
        ctx.fillText('CC', 0, 37.5);
        @assert pixel 5,5 ==~ 0,255,0,255;
        @assert pixel 95,5 ==~ 0,255,0,255;
        @assert pixel 25,25 ==~ 0,255,0,255;
        @assert pixel 75,25 ==~ 0,255,0,255;
        @assert pixel 5,45 ==~ 0,255,0,255;
        @assert pixel 95,45 ==~ 0,255,0,255;
    }), 500);
  expected: green

- name: 2d.text.draw.baseline.ideographic
  testing:
  - 2d.text.baseline.ideographic
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.textBaseline = 'ideographic';
        ctx.fillText('CC', 0, 31.25);
        @assert pixel 5,5 ==~ 0,255,0,255;
        @assert pixel 95,5 ==~ 0,255,0,255;
        @assert pixel 25,25 ==~ 0,255,0,255;
        @assert pixel 75,25 ==~ 0,255,0,255;
        @assert pixel 5,45 ==~ 0,255,0,255; @moz-todo
        @assert pixel 95,45 ==~ 0,255,0,255; @moz-todo
    }), 500);
  expected: green

- name: 2d.text.draw.baseline.hanging
  testing:
  - 2d.text.baseline.hanging
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.textBaseline = 'hanging';
        ctx.fillText('CC', 0, 12.5);
        @assert pixel 5,5 ==~ 0,255,0,255; @moz-todo
        @assert pixel 95,5 ==~ 0,255,0,255; @moz-todo
        @assert pixel 25,25 ==~ 0,255,0,255;
        @assert pixel 75,25 ==~ 0,255,0,255;
        @assert pixel 5,45 ==~ 0,255,0,255;
        @assert pixel 95,45 ==~ 0,255,0,255;
    }), 500);
  expected: green

- name: 2d.text.draw.space.collapse.space
  desc: Space characters are converted to U+0020, and collapsed (per CSS)
  testing:
  - 2d.text.draw.spaces
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.fillText('E  EE', -100, 37.5);
        @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo
        @assert pixel 75,25 ==~ 0,255,0,255;
    }), 500);
  expected: green

- name: 2d.text.draw.space.collapse.other
  desc: Space characters are converted to U+0020, and collapsed (per CSS)
  testing:
  - 2d.text.draw.spaces
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.fillText('E \x09\x0a\x0c\x0d  \x09\x0a\x0c\x0dEE', -100, 37.5);
        @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo
        @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo
    }), 500);
  expected: green

- name: 2d.text.draw.space.collapse.start
  desc: Space characters at the start of a line are collapsed (per CSS)
  testing:
  - 2d.text.draw.spaces
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.fillText(' EE', 0, 37.5);
        @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo
        @assert pixel 75,25 ==~ 0,255,0,255;
    }), 500);
  expected: green

- name: 2d.text.draw.space.collapse.end
  desc: Space characters at the end of a line are collapsed (per CSS)
  testing:
  - 2d.text.draw.spaces
  fonts:
  - CanvasTest
  code: |
    ctx.font = '50px CanvasTest';
    deferTest();
    step_timeout(t.step_func_done(function () {
        ctx.fillStyle = '#f00';
        ctx.fillRect(0, 0, 100, 50);
        ctx.fillStyle = '#0f0';
        ctx.textAlign = 'right';
        ctx.fillText('EE ', 100, 37.5);
        @assert pixel 25,25 ==~ 0,255,0,255;
        @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo
    }), 500);
  expected: green


- name: 2d.text.measure.width.space
  desc: Space characters are converted to U+0020 and collapsed (per CSS)
  testing:
  - 2d.text.measure.spaces
  fonts:
  - CanvasTest
  code: |
    deferTest();
    var f = new FontFace("CanvasTest", "/fonts/CanvasTest.ttf");
    document.fonts.add(f);
    document.fonts.ready.then(() => {
        step_timeout(t.step_func_done(function () {
            ctx.font = '50px CanvasTest';
            @assert ctx.measureText('A B').width === 150;
            @assert ctx.measureText('A  B').width === 200;
            @assert ctx.measureText('A \x09\x0a\x0c\x0d  \x09\x0a\x0c\x0dB').width === 150; @moz-todo
            @assert ctx.measureText('A \x0b B').width >= 200;

            @assert ctx.measureText(' AB').width === 100; @moz-todo
            @assert ctx.measureText('AB ').width === 100; @moz-todo
        }), 500);
    });

- name: 2d.text.measure.rtl.text
  desc: Measurement should follow canvas direction instead text direction
  testing:
  - 2d.text.measure.rtl.text
  fonts:
  - CanvasTest
  code: |
    metrics = ctx.measureText('اَلْعَرَبِيَّةُ');
    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;

    metrics = ctx.measureText('hello');
    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;

- name: 2d.text.measure.boundingBox.textAlign
  desc: Measurement should be related to textAlignment
  testing:
  - 2d.text.measure.boundingBox.textAlign
  code: |
    ctx.textAlign = "right";
    metrics = ctx.measureText('hello');
    @assert metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight;

    ctx.textAlign = "left"
    metrics = ctx.measureText('hello');
    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;

- name: 2d.text.measure.boundingBox.direction
  desc: Measurement should follow text direction
  testing:
  - 2d.text.measure.boundingBox.direction
  code: |
    ctx.direction = "ltr";
    metrics = ctx.measureText('hello');
    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;

    ctx.direction = "rtl";
    metrics = ctx.measureText('hello');
    @assert metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight;
