tor-browser

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

es3fNegativeStateApiTests.js (46300B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES 3.0 Module
      3 * -------------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the 'License');
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a copy of the License at
     10 *
     11 *      http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an 'AS IS' BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 *//*!
     20 * \file
     21 * \brief Negative GL State API tests.
     22 *//*--------------------------------------------------------------------*/
     23 'use strict';
     24 goog.provide('functional.gles3.es3fNegativeStateApiTests');
     25 
     26 goog.require('framework.common.tcuTestCase');
     27 goog.require('functional.gles3.es3fApiCase');
     28 goog.require('framework.opengl.gluShaderProgram');
     29 
     30 goog.scope(function() {
     31 
     32    var es3fNegativeStateApiTests = functional.gles3.es3fNegativeStateApiTests;
     33    var es3fApiCase = functional.gles3.es3fApiCase;
     34    var tcuTestCase = framework.common.tcuTestCase;
     35    var gluShaderProgram = framework.opengl.gluShaderProgram;
     36 
     37    /**
     38    * @type {string}
     39    * @const
     40    */
     41    var uniformTestVertSource = '#version 300 es\n' +
     42    'uniform mediump vec4 vUnif_vec4;\n' +
     43    'in mediump vec4 attr;\n' +
     44    'layout(std140) uniform Block { mediump vec4 blockVar; };\n' +
     45    'void main (void)\n' +
     46    '{\n' +
     47    ' gl_Position = vUnif_vec4 + blockVar + attr;\n' +
     48    '}\n';
     49 
     50    /**
     51    * @type {string}
     52    * @const
     53    */
     54    var uniformTestFragSource = '#version 300 es\n' +
     55    'uniform mediump ivec4 fUnif_ivec4;\n' +
     56    'uniform mediump uvec4 fUnif_uvec4;\n' +
     57    'layout(location = 0) out mediump vec4 fragColor;\n' +
     58    'void main (void)\n' +
     59    '{\n' +
     60    ' fragColor = vec4(vec4(fUnif_ivec4) + vec4(fUnif_uvec4));\n' +
     61    '}\n';
     62 
     63    /**
     64    * @param {WebGL2RenderingContext} gl
     65    */
     66    es3fNegativeStateApiTests.init = function(gl) {
     67 
     68        var testGroup = tcuTestCase.runner.testCases;
     69 
     70        // Enabling & disabling states
     71 
     72        testGroup.addChild(new es3fApiCase.ApiCaseCallback('enable', 'Invalid gl.enable() usage', gl, function() {
     73            bufferedLogToConsole('gl.INVALID_ENUM is generated if cap is not one of the allowed values.');
     74            gl.enable(-1);
     75            this.expectError(gl.INVALID_ENUM);
     76 
     77        }));
     78        testGroup.addChild(new es3fApiCase.ApiCaseCallback('disable', 'Invalid gl.disable() usage', gl, function() {
     79            bufferedLogToConsole('gl.INVALID_ENUM is generated if cap is not one of the allowed values.');
     80            gl.disable(-1);
     81            this.expectError(gl.INVALID_ENUM);
     82 
     83        }));
     84 
     85        // Simple state queries
     86 
     87        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_parameter', 'Invalid gl.getParameter() usage', gl, function() {
     88            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the allowed values.');
     89            /** @type{boolean} */ var params = false;
     90            //glGetBooleanv(-1, params);
     91            params = /** @type{boolean} */ (gl.getParameter(-1));
     92            this.expectError(gl.INVALID_ENUM);
     93 
     94        }));
     95 
     96        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_indexed_parameter', 'Invalid gl.getIndexedParameter() usage', gl, function() {
     97            /** @type{number} */ var data = -1;
     98            /** @type{number} */ var maxUniformBufferBindings;
     99 
    100            bufferedLogToConsole('gl.INVALID_ENUM is generated if name is not an accepted value.');
    101            data = /** @type{number} */ (gl.getIndexedParameter(-1, 0));
    102            this.expectError(gl.INVALID_ENUM);
    103 
    104            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is outside of the valid range for the indexed state target.');
    105            maxUniformBufferBindings = /** @type{number} */ (gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS));
    106            this.expectError(gl.NO_ERROR);
    107            data = /** @type{number} */ (gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, maxUniformBufferBindings));
    108            this.expectError(gl.INVALID_VALUE);
    109 
    110        }));
    111 
    112        // Enumerated state queries: Shaders
    113 
    114        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_attached_shaders', 'Invalid gl.getAttachedShaders() usage', gl, function() {
    115            /** @type{WebGLShader} */ var shaderObject = gl.createShader(gl.VERTEX_SHADER);
    116            /** @type{WebGLProgram} */ var program = gl.createProgram();
    117 
    118            bufferedLogToConsole('An exception is thrown if program is null.');
    119            this.expectThrowNoError(function() {
    120                gl.getAttachedShaders(null);
    121            });
    122 
    123            gl.deleteShader(shaderObject);
    124            gl.deleteProgram(program);
    125        }));
    126 
    127        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_parameter', 'Invalid gl.getShaderParameter() usage', gl, function() {
    128            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    129            /** @type{WebGLProgram} */ var program = gl.createProgram();
    130            /** @type{number} */ var param = -1;
    131 
    132            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
    133            param = /** @type{number} */ (gl.getShaderParameter(shader, -1));
    134            this.expectError(gl.INVALID_ENUM);
    135 
    136            bufferedLogToConsole('An exception is thrown if shader is null.');
    137            this.expectThrowNoError(function() {
    138                gl.getShaderParameter(null, gl.SHADER_TYPE);
    139            });
    140 
    141            gl.deleteShader(shader);
    142            gl.deleteProgram(program);
    143        }));
    144 
    145        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_info_log', 'Invalid gl.getShaderInfoLog() usage', gl, function() {
    146            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    147            /** @type{WebGLProgram} */ var program = gl.createProgram();
    148 
    149            bufferedLogToConsole('An exception is thrown if shader is null.');
    150            this.expectThrowNoError(function() {
    151                gl.getShaderInfoLog(null);
    152            });
    153 
    154            gl.deleteShader(shader);
    155            gl.deleteProgram(program);
    156        }));
    157 
    158        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_precision_format', 'Invalid gl.getShaderPrecisionFormat() usage', gl, function() {
    159            /** @type{WebGLShaderPrecisionFormat } */ var precision;
    160 
    161            bufferedLogToConsole('gl.INVALID_ENUM is generated if shaderType or precisionType is not an accepted value.');
    162            precision = gl.getShaderPrecisionFormat (-1, gl.MEDIUM_FLOAT);
    163            this.expectError(gl.INVALID_ENUM);
    164            precision = gl.getShaderPrecisionFormat (gl.VERTEX_SHADER, -1);
    165            this.expectError(gl.INVALID_ENUM);
    166            precision = gl.getShaderPrecisionFormat (-1, -1);
    167            this.expectError(gl.INVALID_ENUM);
    168 
    169        }));
    170 
    171        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_source', 'Invalid gl.getShaderSource() usage', gl, function() {
    172            /** @type{WebGLProgram} */ var program = gl.createProgram();
    173            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    174 
    175            bufferedLogToConsole('An exception is thrown if shader is null.');
    176            this.expectThrowNoError(function() {
    177                gl.getShaderSource(null);
    178            });
    179 
    180            gl.deleteProgram(program);
    181            gl.deleteShader(shader);
    182        }));
    183 
    184        // Enumerated state queries: Programs
    185 
    186        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_program_parameter', 'Invalid gl.getProgramParameter() usage', gl, function() {
    187            /** @type{WebGLProgram} */ var program = gl.createProgram();
    188            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    189            /** @type{boolean} */ var params;
    190 
    191            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
    192            params = /** @type{boolean} */ (gl.getProgramParameter(program, -1));
    193            this.expectError(gl.INVALID_ENUM);
    194 
    195            bufferedLogToConsole('An exception is thrown if program is null.');
    196            this.expectThrowNoError(function() {
    197                gl.getProgramParameter(null, gl.LINK_STATUS);
    198            });
    199 
    200            gl.deleteProgram(program);
    201            gl.deleteShader(shader);
    202        }));
    203 
    204        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_program_info_log', 'Invalid gl.getProgramInfoLog() usage', gl, function() {
    205            /** @type{WebGLProgram} */ var program = gl.createProgram();
    206            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    207 
    208            bufferedLogToConsole('An exception is thrown if program is null.');
    209            this.expectThrowNoError(function() {
    210                gl.getProgramInfoLog (null);
    211            });
    212 
    213            gl.deleteProgram(program);
    214            gl.deleteShader(shader);
    215        }));
    216 
    217        // Enumerated state queries: Shader variables
    218 
    219        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_tex_parameter', 'Invalid gl.getTexParameter() usage', gl, function() {
    220            /** @type{WebGLTexture} */ var texture = gl.createTexture();
    221            gl.bindTexture(gl.TEXTURE_2D, texture);
    222 
    223            bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not an accepted value.');
    224            gl.getTexParameter (-1, gl.TEXTURE_MAG_FILTER);
    225            this.expectError(gl.INVALID_ENUM);
    226            gl.getTexParameter (gl.TEXTURE_2D, -1);
    227            this.expectError(gl.INVALID_ENUM);
    228            gl.getTexParameter (-1, -1);
    229            this.expectError(gl.INVALID_ENUM);
    230 
    231            gl.deleteTexture(texture);
    232 
    233        }));
    234 
    235        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_uniform', 'Invalid gl.getUniform() usage', gl, function() {
    236            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    237            gl.useProgram(program.getProgram());
    238 
    239            /** @type{WebGLUniformLocation} */ var unif = gl.getUniformLocation(program.getProgram(), 'vUnif_vec4'); // vec4
    240            assertMsgOptions(unif != null, 'Failed to retrieve uniform location', false, true);
    241 
    242            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    243            /** @type{WebGLProgram} */ var programEmpty = gl.createProgram();
    244            /** @type{*} */ var params;
    245 
    246            bufferedLogToConsole('An exception is thrown if program is null.');
    247            this.expectThrowNoError(function() {
    248                gl.getUniform (null, unif);
    249            });
    250 
    251            bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been successfully linked.');
    252            params = gl.getUniform (programEmpty, unif);
    253            this.expectError(gl.INVALID_OPERATION);
    254 
    255            bufferedLogToConsole('An exception is thrown if location is null.');
    256            this.expectThrowNoError(function() {
    257                gl.getUniform (program.getProgram(), null);
    258            });
    259 
    260            gl.deleteShader(shader);
    261            gl.deleteProgram(programEmpty);
    262        }));
    263 
    264        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniform', 'Invalid gl.getActiveUniform() usage', gl, function() {
    265            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    266            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    267            /** @type{number} */ var numActiveUniforms = -1;
    268 
    269            numActiveUniforms = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORMS));
    270            bufferedLogToConsole('// gl.ACTIVE_UNIFORMS = ' + numActiveUniforms + ' (expected 4).');
    271 
    272            bufferedLogToConsole('An exception is thrown if program is null.');
    273            this.expectThrowNoError(function() {
    274                gl.getActiveUniform(null, 0);
    275            });
    276 
    277            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to the number of active uniform variables in program.');
    278            gl.useProgram(program.getProgram());
    279            gl.getActiveUniform(program.getProgram(), numActiveUniforms);
    280            this.expectError(gl.INVALID_VALUE);
    281 
    282            gl.useProgram(null);
    283            gl.deleteShader(shader);
    284        }));
    285 
    286        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniforms', 'Invalid gl.getActiveUniforms() usage', gl, function() {
    287            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    288            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    289            /** @type{Array<number>} */ var dummyUniformIndex = [1];
    290            /** @type{Array<number>} */ var dummyParamDst;
    291            /** @type{number} */ var numActiveUniforms = -1;
    292 
    293            gl.useProgram(program.getProgram());
    294 
    295            numActiveUniforms = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORMS));
    296            bufferedLogToConsole('// gl.ACTIVE_UNIFORMS = ' + numActiveUniforms + ' (expected 4).');
    297 
    298            bufferedLogToConsole('An exception is thrown if program is null.');
    299            this.expectThrowNoError(function() {
    300                gl.getActiveUniforms(null, dummyUniformIndex, gl.UNIFORM_TYPE);
    301            });
    302 
    303            bufferedLogToConsole('gl.INVALID_VALUE is generated if any value in uniformIndices is greater than or equal to the value of gl.ACTIVE_UNIFORMS for program.');
    304            /** @type{Array<number>} */ var invalidUniformIndices;
    305            /** @type{Array<number>} */ var dummyParamsDst;
    306            for (var excess = 0; excess <= 2; excess++) {
    307                invalidUniformIndices = [1, numActiveUniforms - 1 + excess, 1];
    308                dummyParamsDst = gl.getActiveUniforms(program.getProgram(), invalidUniformIndices, gl.UNIFORM_TYPE);
    309                this.expectError(excess == 0 ? gl.NO_ERROR : gl.INVALID_VALUE);
    310            }
    311 
    312            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted token.');
    313            dummyParamDst = gl.getActiveUniforms(program.getProgram(), dummyUniformIndex, -1);
    314            this.expectError(gl.INVALID_ENUM);
    315 
    316            gl.useProgram(null);
    317            gl.deleteShader(shader);
    318        }));
    319 
    320        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniform_block_parameter', 'Invalid gl.getActiveUniformBlockParameter() usage', gl, function() {
    321            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    322            /** @type{*} */ var params;
    323            /** @type{number} */ var numActiveBlocks = -1;
    324 
    325            numActiveBlocks = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
    326            bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks + ' (expected 1).');
    327            this.expectError(gl.NO_ERROR);
    328 
    329            bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockIndex is greater than or equal to the value of gl.ACTIVE_UNIFORM_BLOCKS or is not the index of an active uniform block in program.');
    330            gl.useProgram(program.getProgram());
    331            this.expectError(gl.NO_ERROR);
    332            params = gl.getActiveUniformBlockParameter(program.getProgram(), numActiveBlocks, gl.UNIFORM_BLOCK_BINDING);
    333            this.expectError(gl.INVALID_VALUE);
    334 
    335            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the accepted tokens.');
    336            params = gl.getActiveUniformBlockParameter(program.getProgram(), 0, -1);
    337            this.expectError(gl.INVALID_ENUM);
    338 
    339            gl.useProgram(null);
    340        }));
    341 
    342        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniform_block_name', 'Invalid gl.getActiveUniformBlockName() usage', gl, function() {
    343            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    344            /** @type{number} */ var length = -1;
    345            /** @type{number} */ var numActiveBlocks = -1;
    346            /** @type{string} */ var uniformBlockName;
    347 
    348            numActiveBlocks = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
    349            bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks + ' (expected 1).');
    350            this.expectError(gl.NO_ERROR);
    351 
    352            bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockIndex is greater than or equal to the value of gl.ACTIVE_UNIFORM_BLOCKS or is not the index of an active uniform block in program.');
    353            gl.useProgram(program.getProgram());
    354            this.expectError(gl.NO_ERROR);
    355            uniformBlockName = gl.getActiveUniformBlockName(program.getProgram(), numActiveBlocks);
    356            this.expectError(gl.INVALID_VALUE);
    357 
    358            gl.useProgram(null);
    359        }));
    360 
    361        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_attrib', 'Invalid gl.getActiveAttrib() usage', gl, function() {
    362            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    363            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    364            /** @type{number} */ var numActiveAttributes = -1;
    365 
    366            /** @type{WebGLActiveInfo} */ var activeInfo;
    367            /** @type{number} */ var size = -1;
    368            /** @type{number} */ var type = -1;
    369            /** @type{string} */ var name;
    370 
    371            numActiveAttributes = /** @type{number} */(gl.getProgramParameter(program.getProgram(), gl.ACTIVE_ATTRIBUTES));
    372            bufferedLogToConsole('// gl.ACTIVE_ATTRIBUTES = ' + numActiveAttributes + ' (expected 1).');
    373 
    374            gl.useProgram(program.getProgram());
    375 
    376            bufferedLogToConsole('An exception is thrown if program is null.');
    377            this.expectThrowNoError(function() {
    378                gl.getActiveAttrib(null, 0);
    379            });
    380 
    381            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.ACTIVE_ATTRIBUTES.');
    382            activeInfo = gl.getActiveAttrib(program.getProgram(), numActiveAttributes);
    383            this.expectError(gl.INVALID_VALUE);
    384 
    385            gl.useProgram(null);
    386            gl.deleteShader(shader);
    387        }));
    388 
    389        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_uniform_indices', 'Invalid gl.getUniformIndices() usage', gl, function() {
    390            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    391            /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
    392            gl.useProgram(program.getProgram());
    393            /** @type{number} */ var numActiveBlocks = -1;
    394            /** @type{Array<string>} */ var uniformName = ['Block.blockVar'];
    395            /** @type{Array<number>} */ var uniformIndices = [-1];
    396 
    397            numActiveBlocks = /** @type{number} */(gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
    398            bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks);
    399            this.expectError (gl.NO_ERROR);
    400 
    401            bufferedLogToConsole('An exception is thrown if program is null.');
    402            this.expectThrowNoError(function() {
    403                gl.getUniformIndices(null, uniformName);
    404            });
    405 
    406            gl.useProgram(null);
    407            gl.deleteShader(shader);
    408        }));
    409 
    410        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_vertex_attrib', 'Invalid gl.getVertexAttrib() usage', gl, function() {
    411            /** @type{*} */ var params;
    412 
    413            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
    414            params = gl.getVertexAttrib(0, -1);
    415            this.expectError(gl.INVALID_ENUM);
    416 
    417            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    418            /** @type{number} */ var maxVertexAttribs;
    419            maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    420            params = gl.getVertexAttrib(maxVertexAttribs, gl.VERTEX_ATTRIB_ARRAY_ENABLED);
    421            this.expectError(gl.INVALID_VALUE);
    422 
    423        }));
    424 
    425        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_vertex_attrib_offset', 'Invalid gl.getVertexAttribOffset() usage', gl, function() {
    426            /** @type{number} */ var ptr;
    427 
    428            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
    429            ptr = gl.getVertexAttribOffset(0, -1);
    430            this.expectError(gl.INVALID_ENUM);
    431 
    432            bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
    433            /** @type{number} */ var maxVertexAttribs;
    434            maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
    435            ptr = gl.getVertexAttribOffset(maxVertexAttribs, gl.VERTEX_ATTRIB_ARRAY_POINTER);
    436            this.expectError(gl.INVALID_VALUE);
    437 
    438        }));
    439 
    440        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_frag_data_location', 'Invalid gl.getFragDataLocation() usage', gl, function() {
    441            /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
    442            /** @type{WebGLProgram} */ var program = gl.createProgram();
    443 
    444            bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been linked.');
    445            gl.getFragDataLocation(program, 'gl_FragColor');
    446            this.expectError(gl.INVALID_OPERATION);
    447 
    448            gl.deleteProgram(program);
    449            gl.deleteShader(shader);
    450        }));
    451 
    452        // Enumerated state queries: Buffers
    453 
    454        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_buffer_parameter', 'Invalid gl.getBufferParameter() usage', gl, function() {
    455            /** @type{number} */ var params = -1;
    456            /** @type{WebGLBuffer} */ var buf;
    457            buf = gl.createBuffer();
    458            gl.bindBuffer(gl.ARRAY_BUFFER, buf);
    459 
    460            bufferedLogToConsole('gl.INVALID_ENUM is generated if target or value is not an accepted value.');
    461            params = /** @type{number} */ (gl.getBufferParameter(-1, gl.BUFFER_SIZE));
    462            this.expectError(gl.INVALID_ENUM);
    463            params = /** @type{number} */ (gl.getBufferParameter(gl.ARRAY_BUFFER, -1));
    464            this.expectError(gl.INVALID_ENUM);
    465            params = /** @type{number} */ (gl.getBufferParameter(-1, -1));
    466            this.expectError(gl.INVALID_ENUM);
    467 
    468            bufferedLogToConsole('gl.INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target.');
    469            gl.bindBuffer(gl.ARRAY_BUFFER, null);
    470            params = /** @type{number} */ (gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE));
    471            this.expectError(gl.INVALID_OPERATION);
    472 
    473            gl.deleteBuffer(buf);
    474        }));
    475 
    476        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_framebuffer_attachment_parameter', 'Invalid gl.getFramebufferAttachmentParameter() usage', gl, function() {
    477            /** @type{*} */ var params;
    478            /** @type{WebGLFramebuffer} */ var fbo;
    479            /** @type{Array<WebGLRenderbuffer>} */ var rbo = [];
    480 
    481            fbo = gl.createFramebuffer();
    482            rbo[0] = gl.createRenderbuffer();
    483            rbo[1] = gl.createRenderbuffer();
    484 
    485            gl.bindFramebuffer (gl.FRAMEBUFFER, fbo);
    486            gl.bindRenderbuffer (gl.RENDERBUFFER, rbo[0]);
    487            gl.renderbufferStorage (gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 16, 16);
    488            gl.framebufferRenderbuffer (gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo[0]);
    489            gl.bindRenderbuffer (gl.RENDERBUFFER, rbo[1]);
    490            gl.renderbufferStorage (gl.RENDERBUFFER, gl.STENCIL_INDEX8, 16, 16);
    491            gl.framebufferRenderbuffer (gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo[1]);
    492            gl.checkFramebufferStatus (gl.FRAMEBUFFER);
    493            this.expectError (gl.NO_ERROR);
    494 
    495            bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted tokens.');
    496            gl.getFramebufferAttachmentParameter(-1, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE); // TYPE is gl.RENDERBUFFER
    497            this.expectError(gl.INVALID_ENUM);
    498 
    499            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not valid for the value of gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE.');
    500            gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL); // TYPE is gl.RENDERBUFFER
    501            this.expectError(gl.INVALID_ENUM);
    502            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    503            gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // TYPE is gl.FRAMEBUFFER_DEFAULT
    504            this.expectError(gl.INVALID_ENUM);
    505            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    506 
    507            bufferedLogToConsole('gl.INVALID_OPERATION is generated if attachment is gl.DEPTH_STENCIL_ATTACHMENT and different objects are bound to the depth and stencil attachment points of target.');
    508            gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
    509            this.expectError(gl.INVALID_OPERATION);
    510 
    511            bufferedLogToConsole('gl.INVALID_OPERATION is generated if the value of gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is gl.NONE and pname is not gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME.');
    512            gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // TYPE is gl.NONE
    513            this.expectError(gl.NO_ERROR);
    514            gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE); // TYPE is gl.NONE
    515            this.expectError(gl.INVALID_OPERATION);
    516 
    517            bufferedLogToConsole('gl.INVALID_OPERATION or gl.INVALID_ENUM is generated if attachment is not one of the accepted values for the current binding of target.');
    518            gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // A FBO is bound so gl.BACK is invalid
    519            this.expectError([gl.INVALID_OPERATION, gl.INVALID_ENUM]);
    520            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    521            gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // Default framebuffer is bound so gl.COLOR_ATTACHMENT0 is invalid
    522            this.expectError([gl.INVALID_OPERATION, gl.INVALID_ENUM]);
    523 
    524            gl.deleteFramebuffer(fbo);
    525        }));
    526 
    527        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_renderbuffer_parameter', 'Invalid gl.getRenderbufferParameter() usage', gl, function() {
    528            /** @type{number} */ var params = -1;
    529            /** @type{WebGLRenderbuffer} */ var rbo;
    530            rbo = gl.createRenderbuffer();
    531            gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
    532 
    533            bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.RENDERBUFFER.');
    534            gl.getRenderbufferParameter(-1, gl.RENDERBUFFER_WIDTH);
    535            this.expectError(gl.INVALID_ENUM);
    536 
    537            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the accepted tokens.');
    538            gl.getRenderbufferParameter(gl.RENDERBUFFER, -1);
    539            this.expectError(gl.INVALID_ENUM);
    540 
    541            gl.deleteRenderbuffer(rbo);
    542            gl.bindRenderbuffer(gl.RENDERBUFFER, null);
    543        }));
    544 
    545        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_internalformat_parameter', 'Invalid gl.getInternalformatParameter() usage', gl, function() {
    546            /** @type{WebGLRenderbuffer} */ var rbo = gl.createRenderbuffer();
    547            /** @type{WebGLFramebuffer} */ var fbo = gl.createFramebuffer();
    548            /** @type{WebGLTexture} */ var tex = gl.createTexture();
    549            gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
    550            gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    551            gl.bindTexture(gl.TEXTURE_2D, tex);
    552 
    553            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not gl.SAMPLES or gl.NUM_SAMPLE_COUNTS.');
    554            gl.getInternalformatParameter (gl.RENDERBUFFER, gl.RGBA8, -1);
    555            this.expectError (gl.INVALID_ENUM);
    556 
    557            bufferedLogToConsole('gl.INVALID_ENUM is generated if internalformat is not color-, depth-, or stencil-renderable.');
    558            gl.getInternalformatParameter (gl.RENDERBUFFER, gl.RG8_SNORM, gl.NUM_SAMPLE_COUNTS);
    559            this.expectError (gl.INVALID_ENUM);
    560            gl.getInternalformatParameter (gl.RENDERBUFFER, gl.COMPRESSED_RGB8_ETC2, gl.NUM_SAMPLE_COUNTS);
    561            this.expectError (gl.INVALID_ENUM);
    562 
    563            bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.RENDERBUFFER.');
    564            gl.getInternalformatParameter (-1, gl.RGBA8, gl.NUM_SAMPLE_COUNTS);
    565            this.expectError (gl.INVALID_ENUM);
    566            gl.getInternalformatParameter (gl.FRAMEBUFFER, gl.RGBA8, gl.NUM_SAMPLE_COUNTS);
    567            this.expectError (gl.INVALID_ENUM);
    568            gl.getInternalformatParameter (gl.TEXTURE_2D, gl.RGBA8, gl.NUM_SAMPLE_COUNTS);
    569            this.expectError (gl.INVALID_ENUM);
    570 
    571            gl.deleteRenderbuffer(rbo);
    572            gl.deleteFramebuffer(fbo);
    573            gl.deleteTexture(tex);
    574 
    575        }));
    576 
    577        // Query object queries
    578 
    579        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_query', 'Invalid gl.getQuery() usage', gl, function() {
    580            /** @type{number} */ var params = -1;
    581 
    582            bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not an accepted value.');
    583            gl.getQuery (gl.ANY_SAMPLES_PASSED, -1);
    584            this.expectError (gl.INVALID_ENUM);
    585            gl.getQuery (-1, gl.CURRENT_QUERY);
    586            this.expectError (gl.INVALID_ENUM);
    587            gl.getQuery (-1, -1);
    588            this.expectError (gl.INVALID_ENUM);
    589 
    590        }));
    591 
    592        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_query_parameter', 'Invalid gl.getQueryParameter() usage', gl, function() {
    593 
    594            /** @type{WebGLQuery} */ var id;
    595            id = gl.createQuery();
    596 
    597            bufferedLogToConsole('An exception is thrown if the query object is null.');
    598            this.expectThrowNoError(function() {
    599                gl.getQueryParameter (null, gl.QUERY_RESULT_AVAILABLE);
    600            });
    601 
    602            bufferedLogToConsole('// Note: ' + id + ' is not a query object yet, since it hasn\'t been used by gl.beginQuery');
    603            gl.getQueryParameter (id, gl.QUERY_RESULT_AVAILABLE);
    604            this.expectError (gl.INVALID_OPERATION);
    605 
    606            gl.beginQuery (gl.ANY_SAMPLES_PASSED, id);
    607            gl.endQuery (gl.ANY_SAMPLES_PASSED);
    608 
    609            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
    610            gl.getQueryParameter (id, -1);
    611            this.expectError (gl.INVALID_ENUM);
    612 
    613            bufferedLogToConsole('gl.INVALID_OPERATION is generated if id is the name of a currently active query object.');
    614            gl.beginQuery (gl.ANY_SAMPLES_PASSED, id);
    615            this.expectError (gl.NO_ERROR);
    616            gl.getQueryParameter (id, gl.QUERY_RESULT_AVAILABLE);
    617            this.expectError (gl.INVALID_OPERATION);
    618            gl.endQuery (gl.ANY_SAMPLES_PASSED);
    619            this.expectError (gl.NO_ERROR);
    620 
    621            gl.deleteQuery(id);
    622        }));
    623 
    624        // Sync object queries
    625 
    626        testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_sync_parameter', 'Invalid gl.getSyncParameter() usage', gl, function() {
    627            /** @type{WebGLSync} */ var sync;
    628 
    629            bufferedLogToConsole('An exception is thrown if sync is null.');
    630            this.expectThrowNoError(function() {
    631                gl.getSyncParameter (null, gl.OBJECT_TYPE);
    632            });
    633 
    634            bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the accepted tokens.');
    635            sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
    636            this.expectError (gl.NO_ERROR);
    637            gl.getSyncParameter (sync, -1);
    638            this.expectError (gl.INVALID_ENUM);
    639 
    640        }));
    641 
    642        // Enumerated boolean state queries
    643 
    644        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_enabled', 'Invalid gl.isEnabled() usage', gl, function() {
    645            bufferedLogToConsole('gl.INVALID_ENUM is generated if cap is not an accepted value.');
    646            gl.isEnabled(-1);
    647            this.expectError(gl.INVALID_ENUM);
    648            gl.isEnabled(gl.TRIANGLES);
    649            this.expectError(gl.INVALID_ENUM);
    650 
    651        }));
    652 
    653        // Named Object Usage
    654 
    655        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_buffer', 'Invalid gl.isBuffer() usage', gl, function() {
    656            /** @type{WebGLBuffer} */ var buffer;
    657            /** @type{boolean} */ var isBuffer;
    658 
    659            bufferedLogToConsole('A name returned by glGenBuffers, but not yet associated with a buffer object by calling glBindBuffer, is not the name of a buffer object.');
    660            isBuffer = gl.isBuffer(buffer);
    661            assertMsgOptions(!isBuffer, 'Got invalid boolean value', false, true);
    662 
    663            buffer = gl.createBuffer();
    664            isBuffer = gl.isBuffer(buffer);
    665            assertMsgOptions(!isBuffer, 'Got invalid boolean value', false, true);
    666 
    667            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    668            isBuffer = gl.isBuffer(buffer);
    669            assertMsgOptions(isBuffer, 'Got invalid boolean value', false, true);
    670 
    671            gl.bindBuffer(gl.ARRAY_BUFFER, null);
    672            gl.deleteBuffer(buffer);
    673            isBuffer = gl.isBuffer(buffer);
    674            assertMsgOptions(!isBuffer, 'Got invalid boolean value', false, true);
    675 
    676            this.expectError (gl.NO_ERROR);
    677        }));
    678 
    679        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_framebuffer', 'Invalid gl.isFramebuffer() usage', gl, function() {
    680            /** @type{WebGLFramebuffer} */ var fbo;
    681            /** @type{boolean} */ var isFbo;
    682 
    683            bufferedLogToConsole('A name returned by glGenFramebuffers, but not yet bound through a call to gl.bindFramebuffer is not the name of a framebuffer object.');
    684            isFbo = gl.isFramebuffer(fbo);
    685            assertMsgOptions(!isFbo, 'Got invalid boolean value', false, true);
    686 
    687            fbo = gl.createFramebuffer();
    688            isFbo = gl.isFramebuffer(fbo);
    689            assertMsgOptions(!isFbo, 'Got invalid boolean value', false, true);
    690 
    691            gl.bindFramebuffer (gl.FRAMEBUFFER, fbo);
    692            isFbo = gl.isFramebuffer(fbo);
    693            assertMsgOptions(isFbo, 'Got invalid boolean value', false, true);
    694 
    695            gl.bindFramebuffer (gl.FRAMEBUFFER, null);
    696            gl.deleteFramebuffer(fbo);
    697            isFbo = gl.isFramebuffer(fbo);
    698            assertMsgOptions(!isFbo, 'Got invalid boolean value', false, true);
    699 
    700            this.expectError (gl.NO_ERROR);
    701        }));
    702 
    703        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_program', 'Invalid gl.isProgram() usage', gl, function() {
    704            /** @type{WebGLProgram} */ var program;
    705            /** @type{boolean} */ var isProgram;
    706 
    707            bufferedLogToConsole('A name created with gl.createProgram, and not yet deleted with glDeleteProgram is a name of a program object.');
    708            isProgram = gl.isProgram(program);
    709            assertMsgOptions(!isProgram, 'Got invalid boolean value', false, true);
    710 
    711            program = gl.createProgram();
    712            isProgram = gl.isProgram(program);
    713            assertMsgOptions(isProgram, 'Got invalid boolean value', false, true);
    714 
    715            gl.deleteProgram(program);
    716            isProgram = gl.isProgram(program);
    717            assertMsgOptions(!isProgram, 'Got invalid boolean value', false, true);
    718 
    719            this.expectError (gl.NO_ERROR);
    720        }));
    721 
    722        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_renderbuffer', 'Invalid gl.isRenderbuffer() usage', gl, function() {
    723            /** @type{WebGLRenderbuffer} */ var rbo;
    724            /** @type{boolean} */ var isRbo;
    725 
    726            bufferedLogToConsole('A name returned by glGenRenderbuffers, but not yet bound through a call to gl.bindRenderbuffer or gl.framebufferRenderbuffer is not the name of a renderbuffer object.');
    727            isRbo = gl.isRenderbuffer(rbo);
    728            assertMsgOptions(!isRbo, 'Got invalid boolean value', false, true);
    729 
    730            rbo = gl.createRenderbuffer();
    731            isRbo = gl.isRenderbuffer(rbo);
    732            assertMsgOptions(!isRbo, 'Got invalid boolean value', false, true);
    733 
    734            gl.bindRenderbuffer (gl.RENDERBUFFER, rbo);
    735            isRbo = gl.isRenderbuffer(rbo);
    736            assertMsgOptions(isRbo, 'Got invalid boolean value', false, true);
    737 
    738            gl.bindRenderbuffer (gl.RENDERBUFFER, null);
    739            gl.deleteRenderbuffer(rbo);
    740            isRbo = gl.isRenderbuffer(rbo);
    741            assertMsgOptions(!isRbo, 'Got invalid boolean value', false, true);
    742 
    743            this.expectError (gl.NO_ERROR);
    744        }));
    745 
    746        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_shader', 'Invalid gl.isShader() usage', gl, function() {
    747            /** @type{WebGLShader} */ var shader;
    748            /** @type{boolean} */ var isShader;
    749 
    750            bufferedLogToConsole('A name created with glCreateShader, and not yet deleted with glDeleteShader is a name of a shader object.');
    751            isShader = gl.isProgram(shader);
    752            assertMsgOptions(!isShader, 'Got invalid boolean value', false, true);
    753 
    754            shader = gl.createShader(gl.VERTEX_SHADER);
    755            isShader = gl.isShader(shader);
    756            assertMsgOptions(isShader, 'Got invalid boolean value', false, true);
    757 
    758            gl.deleteShader (shader);
    759            isShader = gl.isShader(shader);
    760            assertMsgOptions(!isShader, 'Got invalid boolean value', false, true);
    761 
    762            this.expectError (gl.NO_ERROR);
    763        }));
    764 
    765        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_texture', 'Invalid gl.isTexture() usage', gl, function() {
    766            /** @type{WebGLTexture} */ var texture;
    767            /** @type{boolean} */ var isTexture;
    768 
    769            bufferedLogToConsole('A name returned by glGenTextures, but not yet bound through a call to glBindTexture is not the name of a texture.');
    770            isTexture = gl.isTexture(texture);
    771            assertMsgOptions(!isTexture, 'Got invalid boolean value', false, true);
    772 
    773            texture = gl.createTexture();
    774            isTexture = gl.isTexture(texture);
    775            assertMsgOptions(!isTexture, 'Got invalid boolean value', false, true);
    776 
    777            gl.bindTexture (gl.TEXTURE_2D, texture);
    778            isTexture = gl.isTexture(texture);
    779            assertMsgOptions(isTexture, 'Got invalid boolean value', false, true);
    780 
    781            gl.bindTexture (gl.TEXTURE_2D, null);
    782            gl.deleteTexture(texture);
    783            isTexture = gl.isTexture(texture);
    784            assertMsgOptions(!isTexture, 'Got invalid boolean value', false, true);
    785 
    786            this.expectError (gl.NO_ERROR);
    787        }));
    788 
    789        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_query', 'Invalid gl.isQuery() usage', gl, function() {
    790            /** @type{WebGLQuery} */ var query;
    791            /** @type{boolean} */ var isQuery;
    792 
    793            bufferedLogToConsole('A name returned by glGenQueries, but not yet associated with a query object by calling gl.beginQuery, is not the name of a query object.');
    794            isQuery = gl.isQuery(query);
    795            assertMsgOptions(!isQuery, 'Got invalid boolean value', false, true);
    796 
    797            query = gl.createQuery();
    798            isQuery = gl.isQuery(query);
    799            assertMsgOptions(!isQuery, 'Got invalid boolean value', false, true);
    800 
    801            gl.beginQuery (gl.ANY_SAMPLES_PASSED, query);
    802            isQuery = gl.isQuery(query);
    803            assertMsgOptions(isQuery, 'Got invalid boolean value', false, true);
    804 
    805            gl.endQuery (gl.ANY_SAMPLES_PASSED);
    806            gl.deleteQuery (query);
    807            isQuery = gl.isQuery(query);
    808            assertMsgOptions(!isQuery, 'Got invalid boolean value', false, true);
    809 
    810            this.expectError (gl.NO_ERROR);
    811        }));
    812 
    813        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_sampler', 'Invalid gl.isSampler() usage', gl, function() {
    814            /** @type{WebGLSampler} */ var sampler;
    815            /** @type{boolean} */ var isSampler;
    816 
    817            bufferedLogToConsole('A name returned by glGenSamplers is the name of a sampler object.');
    818            isSampler = gl.isSampler(sampler);
    819            assertMsgOptions(!isSampler, 'Got invalid boolean value', false, true);
    820 
    821            sampler = gl.createSampler();
    822            isSampler = gl.isSampler(sampler);
    823            assertMsgOptions(isSampler, 'Got invalid boolean value', false, true);
    824 
    825            gl.bindSampler(0, sampler);
    826            isSampler = gl.isSampler(sampler);
    827            assertMsgOptions(isSampler, 'Got invalid boolean value', false, true);
    828 
    829            gl.deleteSampler(sampler);
    830            isSampler = gl.isSampler(sampler);
    831            assertMsgOptions(!isSampler, 'Got invalid boolean value', false, true);
    832 
    833            this.expectError (gl.NO_ERROR);
    834        }));
    835 
    836        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_sync', 'Invalid gl.isSync() usage', gl, function() {
    837            /** @type{WebGLSync} */ var sync;
    838            /** @type{boolean} */ var isSync;
    839 
    840            bufferedLogToConsole('A name returned by gl.fenceSync is the name of a sync object.');
    841            isSync = gl.isSync(sync);
    842            assertMsgOptions(!isSync, 'Got invalid boolean value', false, true);
    843 
    844            sync = gl.fenceSync (gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
    845            isSync = gl.isSync(sync);
    846            assertMsgOptions(isSync, 'Got invalid boolean value', false, true);
    847 
    848            gl.deleteSync (sync);
    849            isSync = gl.isSync(sync);
    850            assertMsgOptions(!isSync, 'Got invalid boolean value', false, true);
    851 
    852            this.expectError (gl.NO_ERROR);
    853        }));
    854 
    855        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_transform_feedback', 'Invalid gl.isTransformFeedback() usage', gl, function() {
    856            /** @type{WebGLTransformFeedback} */ var tf;
    857            /** @type{boolean} */ var isTF;
    858 
    859            bufferedLogToConsole('A name returned by glGenTransformFeedbacks, but not yet bound using glBindTransformFeedback, is not the name of a transform feedback object.');
    860            isTF = gl.isTransformFeedback(tf);
    861            assertMsgOptions(!isTF, 'Got invalid boolean value', false, true);
    862 
    863            tf = gl.createTransformFeedback();
    864            isTF = gl.isTransformFeedback(tf);
    865            assertMsgOptions(!isTF, 'Got invalid boolean value', false, true);
    866 
    867            gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tf);
    868            isTF = gl.isTransformFeedback(tf);
    869            assertMsgOptions(isTF, 'Got invalid boolean value', false, true);
    870 
    871            gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, null);
    872            gl.deleteTransformFeedback (tf);
    873            isTF = gl.isTransformFeedback(tf);
    874            assertMsgOptions(!isTF, 'Got invalid boolean value', false, true);
    875 
    876            this.expectError (gl.NO_ERROR);
    877        }));
    878 
    879        testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_vertex_array', 'Invalid gl.isVertexArray() usage', gl, function() {
    880            /** @type{WebGLVertexArrayObject} */ var vao;
    881            /** @type{boolean} */ var isVao;
    882 
    883            bufferedLogToConsole('A name returned by glGenVertexArrays, but not yet bound using glBindVertexArray, is not the name of a vertex array object.');
    884            isVao = gl.isVertexArray(vao);
    885            assertMsgOptions(!isVao, 'Got invalid boolean value', false, true);
    886 
    887            vao = gl.createVertexArray();
    888            isVao = gl.isVertexArray(vao);
    889            assertMsgOptions(!isVao, 'Got invalid boolean value', false, true);
    890 
    891            gl.bindVertexArray (vao);
    892            isVao = gl.isVertexArray(vao);
    893            assertMsgOptions(isVao, 'Got invalid boolean value', false, true);
    894 
    895            gl.bindVertexArray (null);
    896            gl.deleteVertexArray (vao);
    897            isVao = gl.isVertexArray(vao);
    898            assertMsgOptions(!isVao, 'Got invalid boolean value', false, true);
    899 
    900            this.expectError (gl.NO_ERROR);
    901        }));
    902    };
    903 
    904    /**
    905    * @param {WebGL2RenderingContext} gl
    906    */
    907    es3fNegativeStateApiTests.run = function(gl) {
    908        var testName = 'state';
    909        var testDescription = 'Negative GL State API Cases';
    910        var state = tcuTestCase.runner;
    911 
    912        state.testName = testName;
    913        state.testCases = tcuTestCase.newTest(testName, testDescription, null);
    914 
    915        //Set up name and description of this test series.
    916        setCurrentTestName(testName);
    917        description(testDescription);
    918        try {
    919            es3fNegativeStateApiTests.init(gl);
    920            tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
    921        } catch (err) {
    922            bufferedLogToConsole(err);
    923            tcuTestCase.runner.terminate();
    924        }
    925    };
    926 
    927 });