const types = [ "Int8", "Int16", "Int32", "Uint8", "Uint16", "Uint32", "Float32", "Float64", ]; function convert(type, value) { let num = Number(value); switch (type) { case "Int8": return ((num | 0) << 24) >> 24; case "Int16": return ((num | 0) << 16) >> 16; case "Int32": return (num | 0); case "Uint8": return (num >>> 0) & 0xff; case "Uint16": return (num >>> 0) & 0xffff; case "Uint32": return (num >>> 0); case "Uint8Clamped": { if (Number.isNaN(num)) { return 0; } let clamped = Math.max(0, Math.min(num, 255)); let f = Math.floor(clamped); if (clamped < f + 0.5) { return f; } if (clamped > f + 0.5) { return f + 1; } return f + (f & 1); } case "Float32": return Math.fround(num); case "Float64": return num; } throw new Error(); } function runTest(type, initial, values) { let expected = values.map(v => convert(type, v)); assertEq( expected.some(e => Object.is(e, initial)), false, "initial must be different from the expected values" ); // Create a fresh function to ensure ICs are specific to a single DataView function. let test = Function("initial, values, expected", ` let ab = new ArrayBuffer(16); let dv = new DataView(ab); for (let i = 0; i < 200; ++i) { dv.set${type}(0, initial); dv.set${type}(0, values[i % values.length]); assertEq(dv.get${type}(0), expected[i % expected.length]); } `); test(initial, values, expected); } const tests = [ // |null| is coerced to zero. { initial: 1, values: [null], }, // |undefined| is coerced to zero or NaN. { initial: 1, values: [undefined], }, // |false| is coerced to zero and |true| is coerced to one. { initial: 2, values: [false, true], }, // Strings without a fractional part. { initial: 42, values: [ "0", "1", "10", "111", "128", "256", "0x7fffffff", "0xffffffff", ], }, // Strings without a fractional part, but a leading minus sign. { initial: 42, values: [ "-0", "-1", "-10", "-111", "-128", "-256", "-2147483647", "-4294967295", ], }, // Strings with a fractional number part. { initial: 42, values: [ "0.1", "1.2", "10.8", "111.9", "-0.1", "-1.2", "-10.8", "-111.9", ], }, // Special values and strings not parseable as a number. { initial: 42, values: ["Infinity", "-Infinity", "NaN", "foobar"], }, ]; for (let type of types) { for (let {initial, values} of tests) { runTest(type, initial, values); } }