- name: 2d.getcontext.exists
  desc: The 2D context is implemented
  testing:
  - context.2d
  code: |
    @assert canvas.getContext('2d') !== null;

- name: 2d.getcontext.invalid.args
  desc: Calling getContext with invalid arguments.
  testing:
  - context.2d
  code: |
    @assert canvas.getContext('') === null;
    @assert canvas.getContext('2d#') === null;
    @assert canvas.getContext('This is clearly not a valid context name.') === null;
    @assert canvas.getContext('2d\0') === null;
    @assert canvas.getContext('2\uFF44') === null;
    @assert canvas.getContext('2D') === null;
    @assert throws TypeError canvas.getContext();
    @assert canvas.getContext('null') === null;
    @assert canvas.getContext('undefined') === null;

- name: 2d.getcontext.extraargs.create
  desc: The 2D context doesn't throw with extra getContext arguments (new context)
  testing:
  - context.2d.extraargs
  code: |
    @assert document.createElement("canvas").getContext('2d', false, {}, [], 1, "2") !== null;
    @assert document.createElement("canvas").getContext('2d', 123) !== null;
    @assert document.createElement("canvas").getContext('2d', "test") !== null;
    @assert document.createElement("canvas").getContext('2d', undefined) !== null;
    @assert document.createElement("canvas").getContext('2d', null) !== null;
    @assert document.createElement("canvas").getContext('2d', Symbol.hasInstance) !== null;

- name: 2d.getcontext.extraargs.cache
  desc: The 2D context doesn't throw with extra getContext arguments (cached)
  testing:
  - context.2d.extraargs
  code: |
    @assert canvas.getContext('2d', false, {}, [], 1, "2") !== null;
    @assert canvas.getContext('2d', 123) !== null;
    @assert canvas.getContext('2d', "test") !== null;
    @assert canvas.getContext('2d', undefined) !== null;
    @assert canvas.getContext('2d', null) !== null;
    @assert canvas.getContext('2d', Symbol.hasInstance) !== null;

- name: 2d.type.exists
  desc: The 2D context interface is a property of 'window'
  notes: &bindings Defined in "Web IDL" (draft)
  testing:
  - context.2d.type
  code: |
    @assert window.CanvasRenderingContext2D;

- name: 2d.type.prototype
  desc: window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]],
    and its methods are [[Configurable]].
  notes: *bindings
  testing:
  - context.2d.type
  code: |
    @assert window.CanvasRenderingContext2D.prototype;
    @assert window.CanvasRenderingContext2D.prototype.fill;
    window.CanvasRenderingContext2D.prototype = null;
    @assert window.CanvasRenderingContext2D.prototype;
    delete window.CanvasRenderingContext2D.prototype;
    @assert window.CanvasRenderingContext2D.prototype;
    window.CanvasRenderingContext2D.prototype.fill = 1;
    @assert window.CanvasRenderingContext2D.prototype.fill === 1;
    delete window.CanvasRenderingContext2D.prototype.fill;
    @assert window.CanvasRenderingContext2D.prototype.fill === undefined;

- name: 2d.type.replace
  desc: Interface methods can be overridden
  notes: *bindings
  testing:
  - context.2d.type
  code: |
    var fillRect = window.CanvasRenderingContext2D.prototype.fillRect;
    window.CanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h)
    {
        this.fillStyle = '#0f0';
        fillRect.call(this, x, y, w, h);
    };
    ctx.fillStyle = '#f00';
    ctx.fillRect(0, 0, 100, 50);
    @assert pixel 50,25 == 0,255,0,255;
  expected: green

- name: 2d.type.extend
  desc: Interface methods can be added
  notes: *bindings
  testing:
  - context.2d.type
  code: |
    window.CanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h)
    {
        this.fillStyle = '#0f0';
        this.fillRect(x, y, w, h);
    };
    ctx.fillStyle = '#f00';
    ctx.fillRectGreen(0, 0, 100, 50);
    @assert pixel 50,25 == 0,255,0,255;
  expected: green

- name: 2d.getcontext.unique
  desc: getContext('2d') returns the same object
  testing:
  - context.unique
  code: |
    @assert canvas.getContext('2d') === canvas.getContext('2d');

- name: 2d.getcontext.shared
  desc: getContext('2d') returns objects which share canvas state
  testing:
  - context.unique
  code: |
    var ctx2 = canvas.getContext('2d');
    ctx.fillStyle = '#f00';
    ctx2.fillStyle = '#0f0';
    ctx.fillRect(0, 0, 100, 50);
    @assert pixel 50,25 == 0,255,0,255;
  expected: green

- name: 2d.scaled
  desc: CSS-scaled canvases get drawn correctly
  canvas: 'width="50" height="25" style="width: 100px; height: 50px"'
  manual:
  code: |
    ctx.fillStyle = '#00f';
    ctx.fillRect(0, 0, 50, 25);
    ctx.fillStyle = '#0ff';
    ctx.fillRect(0, 0, 25, 10);
  expected: |
    size 100 50
    cr.set_source_rgb(0, 0, 1)
    cr.rectangle(0, 0, 100, 50)
    cr.fill()
    cr.set_source_rgb(0, 1, 1)
    cr.rectangle(0, 0, 50, 20)
    cr.fill()

- name: 2d.canvas.reference
  desc: CanvasRenderingContext2D.canvas refers back to its canvas
  testing:
  - 2d.canvas
  code: |
    @assert ctx.canvas === canvas;

- name: 2d.canvas.readonly
  desc: CanvasRenderingContext2D.canvas is readonly
  testing:
  - 2d.canvas.attribute
  code: |
    var c = document.createElement('canvas');
    var d = ctx.canvas;
    @assert c !== d;
    ctx.canvas = c;
    @assert ctx.canvas === d;

- name: 2d.canvas.context
  desc: checks CanvasRenderingContext2D prototype
  testing:
  - 2d.path.contexttypexxx.basic
  code: |
    @assert Object.getPrototypeOf(CanvasRenderingContext2D.prototype) === Object.prototype;
    @assert Object.getPrototypeOf(ctx) === CanvasRenderingContext2D.prototype;
    t.done();

