/**
 * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
 **/ export const description = `
API validation tests for dynamic state commands (setViewport/ScissorRect/BlendColor...).

TODO: ensure existing tests cover these notes. Note many of these may be operation tests instead.
> - setViewport
>     - {x, y} = {0, invalid values if any}
>     - {width, height, minDepth, maxDepth} = {
>         - least possible value that's valid
>         - greatest possible negative value that's invalid
>         - greatest possible positive value that's valid
>         - least possible positive value that's invalid if any
>         - }
>     - minDepth {<, =, >} maxDepth
> - setScissorRect
>     - {width, height} = 0
>     - {x+width, y+height} = attachment size + 1
> - setBlendColor
>     - color {slightly, very} out of range
>     - used with a simple pipeline that {does, doesn't} use it
> - setStencilReference
>     - {0, max}
>     - used with a simple pipeline that {does, doesn't} use it
`;
import { params } from '../../../../../../common/framework/params_builder.js';
import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
import { ValidationTest } from '../../../validation_test.js';

class F extends ValidationTest {
  testViewportCall(success, v, attachmentSize = { width: 1, height: 1, depth: 1 }) {
    const attachment = this.device.createTexture({
      format: 'rgba8unorm',
      size: attachmentSize,
      usage: GPUTextureUsage.OUTPUT_ATTACHMENT,
    });

    const encoder = this.device.createCommandEncoder();
    const pass = encoder.beginRenderPass({
      colorAttachments: [
        {
          attachment: attachment.createView(),
          loadValue: 'load',
        },
      ],
    });

    pass.setViewport(v.x, v.y, v.w, v.h, v.minDepth, v.maxDepth);
    pass.endPass();

    this.expectValidationError(() => {
      encoder.finish();
    }, !success);
  }

  testScissorCall(success, s, attachmentSize = { width: 1, height: 1, depth: 1 }) {
    const attachment = this.device.createTexture({
      format: 'rgba8unorm',
      size: attachmentSize,
      usage: GPUTextureUsage.OUTPUT_ATTACHMENT,
    });

    const encoder = this.device.createCommandEncoder();
    const pass = encoder.beginRenderPass({
      colorAttachments: [
        {
          attachment: attachment.createView(),
          loadValue: 'load',
        },
      ],
    });

    if (success === 'type-error') {
      this.shouldThrow('TypeError', () => {
        pass.setScissorRect(s.x, s.y, s.w, s.h);
      });
    } else {
      pass.setScissorRect(s.x, s.y, s.w, s.h);
      pass.endPass();

      this.expectValidationError(() => {
        encoder.finish();
      }, !success);
    }
  }

  createDummyRenderPassEncoder() {
    const attachment = this.device.createTexture({
      format: 'rgba8unorm',
      size: [1, 1, 1],
      usage: GPUTextureUsage.OUTPUT_ATTACHMENT,
    });

    const encoder = this.device.createCommandEncoder();
    const pass = encoder.beginRenderPass({
      colorAttachments: [
        {
          attachment: attachment.createView(),
          loadValue: 'load',
        },
      ],
    });

    return { encoder, pass };
  }
}

export const g = makeTestGroup(F);

g.test('setViewport,x_y_width_height_nonnegative')
  .desc('Test that the parameters of setViewport to define the box must be non-negative.')
  .params([
    // Control case: everything to 0 is ok, covers the empty viewport case.
    { x: 0, y: 0, w: 0, h: 0 },

    // Test -1
    { x: -1, y: 0, w: 0, h: 0 },
    { x: 0, y: -1, w: 0, h: 0 },
    { x: 0, y: 0, w: -1, h: 0 },
    { x: 0, y: 0, w: 0, h: -1 },

    // TODO Test -0 (it should be valid) but can't be tested because the harness complains about duplicate parameters.
    // TODO Test the first value smaller than -0
  ])
  .fn(t => {
    const { x, y, w, h } = t.params;
    const success = x >= 0 && y >= 0 && w >= 0 && h >= 0;
    t.testViewportCall(success, { x, y, w, h, minDepth: 0, maxDepth: 1 });
  });

g.test('setViewport,xy_rect_contained_in_attachment')
  .desc(
    'Test that the rectangle defined by x, y, width, height must be contained in the attachments'
  )
  .params(
    params()
      .combine([
        { attachmentWidth: 3, attachmentHeight: 5 },
        { attachmentWidth: 5, attachmentHeight: 3 },
        { attachmentWidth: 1024, attachmentHeight: 1 },
        { attachmentWidth: 1, attachmentHeight: 1024 },
      ])
      .combine([
        // Control case: a full viewport is valid.
        { dx: 0, dy: 0, dw: 0, dh: 0 },

        // Other valid cases with a partial viewport.
        { dx: 1, dy: 0, dw: -1, dh: 0 },
        { dx: 0, dy: 1, dw: 0, dh: -1 },
        { dx: 0, dy: 0, dw: -1, dh: 0 },
        { dx: 0, dy: 0, dw: 0, dh: -1 },

        // Test with a small value that causes the viewport to go outside the attachment.
        { dx: 1, dy: 0, dw: 0, dh: 0 },
        { dx: 0, dy: 1, dw: 0, dh: 0 },
        { dx: 0, dy: 0, dw: 1, dh: 0 },
        { dx: 0, dy: 0, dw: 0, dh: 1 },
      ])
  )
  .fn(t => {
    const { attachmentWidth, attachmentHeight, dx, dy, dw, dh } = t.params;
    const x = dx;
    const y = dy;
    const w = attachmentWidth + dw;
    const h = attachmentWidth + dh;

    const success = x + w <= attachmentWidth && y + h <= attachmentHeight;
    t.testViewportCall(
      success,
      { x, y, w, h, minDepth: 0, maxDepth: 1 },
      { width: attachmentWidth, height: attachmentHeight, depth: 1 }
    );
  });

g.test('setViewport,depth_rangeAndOrder')
  .desc('Test that 0 <= minDepth <= maxDepth <= 1')
  .params([
    // Success cases
    { minDepth: 0, maxDepth: 1 },
    { minDepth: -0, maxDepth: -0 },
    { minDepth: 1, maxDepth: 1 },
    { minDepth: 0.3, maxDepth: 0.7 },
    { minDepth: 0.7, maxDepth: 0.7 },
    { minDepth: 0.3, maxDepth: 0.3 },

    // Invalid cases
    { minDepth: -0.1, maxDepth: 1 },
    { minDepth: 0, maxDepth: 1.1 },
    { minDepth: 0.5, maxDepth: 0.49999 },
  ])
  .fn(t => {
    const { minDepth, maxDepth } = t.params;
    const success =
      0 <= minDepth && minDepth <= 1 && 0 <= maxDepth && maxDepth <= 1 && minDepth <= maxDepth;
    t.testViewportCall(success, { x: 0, y: 0, w: 1, h: 1, minDepth, maxDepth });
  });

g.test('setScissorRect,x_y_width_height_nonnegative')
  .desc(
    'Test that the parameters of setScissorRect to define the box must be non-negative or a TypeError is thrown.'
  )
  .params([
    // Control case: everything to 0 is ok, covers the empty scissor case.
    { x: 0, y: 0, w: 0, h: 0 },

    // Test -1
    { x: -1, y: 0, w: 0, h: 0 },
    { x: 0, y: -1, w: 0, h: 0 },
    { x: 0, y: 0, w: -1, h: 0 },
    { x: 0, y: 0, w: 0, h: -1 },

    // TODO Test -0 (it should be valid) but can't be tested because the harness complains about duplicate parameters.
    // TODO Test the first value smaller than -0
  ])
  .fn(t => {
    const { x, y, w, h } = t.params;
    const success = x >= 0 && y >= 0 && w >= 0 && h >= 0;
    t.testScissorCall(success ? true : 'type-error', { x, y, w, h });
  });

g.test('setScissorRect,xy_rect_contained_in_attachment')
  .desc(
    'Test that the rectangle defined by x, y, width, height must be contained in the attachments'
  )
  .params(
    params()
      .combine([
        { attachmentWidth: 3, attachmentHeight: 5 },
        { attachmentWidth: 5, attachmentHeight: 3 },
        { attachmentWidth: 1024, attachmentHeight: 1 },
        { attachmentWidth: 1, attachmentHeight: 1024 },
      ])
      .combine([
        // Control case: a full scissor is valid.
        { dx: 0, dy: 0, dw: 0, dh: 0 },

        // Other valid cases with a partial scissor.
        { dx: 1, dy: 0, dw: -1, dh: 0 },
        { dx: 0, dy: 1, dw: 0, dh: -1 },
        { dx: 0, dy: 0, dw: -1, dh: 0 },
        { dx: 0, dy: 0, dw: 0, dh: -1 },

        // Test with a small value that causes the scissor to go outside the attachment.
        { dx: 1, dy: 0, dw: 0, dh: 0 },
        { dx: 0, dy: 1, dw: 0, dh: 0 },
        { dx: 0, dy: 0, dw: 1, dh: 0 },
        { dx: 0, dy: 0, dw: 0, dh: 1 },
      ])
  )
  .fn(t => {
    const { attachmentWidth, attachmentHeight, dx, dy, dw, dh } = t.params;
    const x = dx;
    const y = dy;
    const w = attachmentWidth + dw;
    const h = attachmentWidth + dh;

    const success = x + w <= attachmentWidth && y + h <= attachmentHeight;
    t.testScissorCall(
      success,
      { x, y, w, h },
      { width: attachmentWidth, height: attachmentHeight, depth: 1 }
    );
  });

g.test('setBlendColor')
  .desc('Test that almost any color value is valid for setBlendColor')
  .params([
    { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
    { r: -1.0, g: -1.0, b: -1.0, a: -1.0 },
    { r: Number.MAX_SAFE_INTEGER, g: Number.MIN_SAFE_INTEGER, b: -0, a: 100000 },
  ])
  .fn(t => {
    const { r, g, b, a } = t.params;
    const encoders = t.createDummyRenderPassEncoder();
    encoders.pass.setBlendColor({ r, g, b, a });
    encoders.pass.endPass();
    encoders.encoder.finish();
  });

g.test('setStencilReference')
  .desc('Test that almost any stencil reference value is valid for setStencilReference')
  .params([
    { value: 1 }, //
    { value: 0 },
    { value: 1000 },
    { value: 0xffffffff },
  ])
  .fn(t => {
    const { value } = t.params;
    const encoders = t.createDummyRenderPassEncoder();
    encoders.pass.setStencilReference(value);
    encoders.pass.endPass();
    encoders.encoder.finish();
  });
