<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL2 Methods Test</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<script>
"use strict";
description("This test ensures that the WebGL context has all the methods in the specification.");

const methods = [
  "getContextAttributes",
  "activeTexture",
  "attachShader",
  "bindAttribLocation",
  "bindBuffer",
  "bindFramebuffer",
  "bindRenderbuffer",
  "bindTexture",
  "blendColor",
  "blendEquation",
  "blendEquationSeparate",
  "blendFunc",
  "blendFuncSeparate",
  "bufferData",
  "bufferSubData",
  "checkFramebufferStatus",
  "clear",
  "clearColor",
  "clearDepth",
  "clearStencil",
  "colorMask",
  "compileShader",
  "compressedTexImage2D",
  "compressedTexSubImage2D",
  "copyTexImage2D",
  "copyTexSubImage2D",
  "createBuffer",
  "createFramebuffer",
  "createProgram",
  "createRenderbuffer",
  "createShader",
  "createTexture",
  "cullFace",
  "deleteBuffer",
  "deleteFramebuffer",
  "deleteProgram",
  "deleteRenderbuffer",
  "deleteShader",
  "deleteTexture",
  "depthFunc",
  "depthMask",
  "depthRange",
  "detachShader",
  "disable",
  "disableVertexAttribArray",
  "drawArrays",
  "drawElements",
  "enable",
  "enableVertexAttribArray",
  "finish",
  "flush",
  "framebufferRenderbuffer",
  "framebufferTexture2D",
  "frontFace",
  "generateMipmap",
  "getActiveAttrib",
  "getActiveUniform",
  "getAttachedShaders",
  "getAttribLocation",
  "getParameter",
  "getBufferParameter",
  "getError",
  "getExtension",
  "getFramebufferAttachmentParameter",
  "getProgramParameter",
  "getProgramInfoLog",
  "getRenderbufferParameter",
  "getShaderParameter",
  "getShaderInfoLog",
  "getShaderPrecisionFormat",
  "getShaderSource",
  "getSupportedExtensions",
  "getTexParameter",
  "getUniform",
  "getUniformLocation",
  "getVertexAttrib",
  "getVertexAttribOffset",
  "hint",
  "isBuffer",
  "isContextLost",
  "isEnabled",
  "isFramebuffer",
  "isProgram",
  "isRenderbuffer",
  "isShader",
  "isTexture",
  "lineWidth",
  "linkProgram",
  "pixelStorei",
  "polygonOffset",
  "readPixels",
  "renderbufferStorage",
  "sampleCoverage",
  "scissor",
  "shaderSource",
  "stencilFunc",
  "stencilFuncSeparate",
  "stencilMask",
  "stencilMaskSeparate",
  "stencilOp",
  "stencilOpSeparate",
  "texImage2D",
  "texParameterf",
  "texParameteri",
  "texSubImage2D",
  "uniform1f",
  "uniform1fv",
  "uniform1i",
  "uniform1iv",
  "uniform2f",
  "uniform2fv",
  "uniform2i",
  "uniform2iv",
  "uniform3f",
  "uniform3fv",
  "uniform3i",
  "uniform3iv",
  "uniform4f",
  "uniform4fv",
  "uniform4i",
  "uniform4iv",
  "uniformMatrix2fv",
  "uniformMatrix3fv",
  "uniformMatrix4fv",
  "useProgram",
  "validateProgram",
  "vertexAttrib1f",
  "vertexAttrib1fv",
  "vertexAttrib2f",
  "vertexAttrib2fv",
  "vertexAttrib3f",
  "vertexAttrib3fv",
  "vertexAttrib4f",
  "vertexAttrib4fv",
  "vertexAttribPointer",
  "viewport",

  // WebGL2 methods
  "getBufferSubData",
  "copyBufferSubData",
  "blitFramebuffer",
  "framebufferTextureLayer",
  "getInternalformatParameter",
  "invalidateFramebuffer",
  "invalidateSubFramebuffer",
  "readBuffer",
  "renderbufferStorageMultisample",
  "texImage3D",
  "texStorage2D",
  "texStorage3D",
  "texSubImage3D",
  "copyTexSubImage3D",
  "compressedTexImage3D",
  "compressedTexSubImage3D",
  "getFragDataLocation",
  "uniform1ui",
  "uniform2ui",
  "uniform3ui",
  "uniform4ui",
  "uniform1uiv",
  "uniform2uiv",
  "uniform3uiv",
  "uniform4uiv",
  "uniformMatrix2x3fv",
  "uniformMatrix3x2fv",
  "uniformMatrix2x4fv",
  "uniformMatrix4x2fv",
  "uniformMatrix3x4fv",
  "uniformMatrix4x3fv",
  "vertexAttribI4i",
  "vertexAttribI4iv",
  "vertexAttribI4ui",
  "vertexAttribI4uiv",
  "vertexAttribIPointer",
  "vertexAttribDivisor",
  "drawArraysInstanced",
  "drawElementsInstanced",
  "drawRangeElements",
  "drawBuffers",
  "clearBufferiv",
  "clearBufferuiv",
  "clearBufferfv",
  "clearBufferfi",
  "createQuery",
  "deleteQuery",
  "isQuery",
  "beginQuery",
  "endQuery",
  "getQuery",
  "getQueryParameter",
  "createSampler",
  "deleteSampler",
  "isSampler",
  "bindSampler",
  "samplerParameteri",
  "samplerParameterf",
  "getSamplerParameter",
  "fenceSync",
  "isSync",
  "deleteSync",
  "clientWaitSync",
  "waitSync",
  "getSyncParameter",
  "createTransformFeedback",
  "deleteTransformFeedback",
  "isTransformFeedback",
  "bindTransformFeedback",
  "beginTransformFeedback",
  "endTransformFeedback",
  "transformFeedbackVaryings",
  "getTransformFeedbackVarying",
  "pauseTransformFeedback",
  "resumeTransformFeedback",
  "bindBufferBase",
  "bindBufferRange",
  "getIndexedParameter",
  "getUniformIndices",
  "getActiveUniforms",
  "getUniformBlockIndex",
  "getActiveUniformBlockParameter",
  "getActiveUniformBlockName",
  "uniformBlockBinding",
  "createVertexArray",
  "deleteVertexArray",
  "isVertexArray",
  "bindVertexArray",
];

// Properties to be ignored because they were added in versions of the
// spec that are backward-compatible with this version
const ignoredMethods = [
  // There is no official spec for the commit API yet, the proposal link is:
  // https://wiki.whatwg.org/wiki/OffscreenCanvas
  "commit"
];

const optionalMethods = [
  "makeXRCompatible"
];

function assertFunction(v, f) {
  try {
    if (typeof v[f] != "function") {
      testFailed(`Property either does not exist or is not a function: ${f}`);
      return false;
    } else {
      return true;
    }
  } catch(e) {
    testFailed(`Trying to access the property '${f}' threw an error: ${e.toString()}`);
  }
}

debug("");
debug("Canvas.getContext");

const wtu = WebGLTestUtils;
const canvas = document.getElementById("canvas");
const gl = wtu.create3DContext(canvas, null, 2);
let passed = true;
methods.forEach(method => {
  const r = assertFunction(gl, method);
  passed = passed && r;
});
if (passed) {
  testPassed("All WebGL methods found.");
}
let extended = false;
for (let propertyName of Object.getOwnPropertyNames(gl)) {
  if (typeof gl[propertyName] == "function" && !methods.includes(propertyName) && !ignoredMethods.includes(propertyName) && !optionalMethods.includes(propertyName)) {
    if (!extended) {
      extended = true;
      testFailed("Also found the following extra methods:");
    }
    testFailed(propertyName);
  }
}

if (!extended) {
  testPassed("No extra methods found on WebGL context.");
}

debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>

</body>
</html>
