export const description = `Validation tests for literals`;
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { ShaderValidationTest } from '../shader_validation_test.js';
export const g = makeTestGroup(ShaderValidationTest);
g.test('bools')
.desc(`Test that valid bools are accepted.`)
.params(u => u.combine('val', ['true', 'false']).beginSubcases())
.fn(t => {
const code = `var test = ${t.params.val};`;
t.expectCompileResult(true, t.wrapInEntryPoint(code));
});
const kAbstractIntNonNegative = new Set([
'0x123',
'123',
'0',
'0x3f',
'2147483647',
]);
const kAbstractIntNegative = new Set([
'-0x123',
'-123',
'-0x3f',
'-2147483647',
'-2147483648',
]);
const kI32 = new Set([
'94i',
'2147483647i',
'-2147483647i',
'i32(-2147483648)',
]);
const kU32 = new Set([
'42u',
'0u',
'4294967295u',
]);
{
const kValidIntegers = new Set([
...kAbstractIntNonNegative,
...kAbstractIntNegative,
...kI32,
...kU32,
]);
const kInvalidIntegers = new Set([
'0123',
'2147483648i',
'-2147483649i',
'4294967295',
'4294967295i',
'4294967296u',
'-1u',
]);
g.test('abstract_int')
.desc(`Test that valid integers are accepted, and invalid integers are rejected.`)
.params(u =>
u.combine('val', new Set([...kValidIntegers, ...kInvalidIntegers])).beginSubcases()
)
.fn(t => {
const code = `var test = ${t.params.val};`;
t.expectCompileResult(kValidIntegers.has(t.params.val), t.wrapInEntryPoint(code));
});
}
{
const kValidI32 = new Set([...kAbstractIntNonNegative, ...kAbstractIntNegative, ...kI32]);
const kInvalidI32 = new Set([
...kU32,
'2147483648',
'2147483648i',
'-2147483649',
'-2147483649i',
'1.0',
'1.0f',
'1.0h',
]);
g.test('i32')
.desc(`Test that valid signed integers are accepted, and invalid signed integers are rejected.`)
.params(u => u.combine('val', new Set([...kValidI32, ...kInvalidI32])).beginSubcases())
.fn(t => {
const { val } = t.params;
const code = `var test: i32 = ${val};`;
const extensionList = val.includes('h') ? ['f16'] : [];
t.expectCompileResult(kValidI32.has(val), t.wrapInEntryPoint(code, extensionList));
});
}
{
const kValidU32 = new Set([
...kAbstractIntNonNegative,
...kU32,
'4294967295',
]);
const kInvalidU32 = new Set([
...kAbstractIntNegative,
...kI32,
'4294967296',
'4294967296u',
'-1',
'1.0',
'1.0f',
'1.0h',
]);
g.test('u32')
.desc(
`Test that valid unsigned integers are accepted, and invalid unsigned integers are rejected.`
)
.params(u => u.combine('val', new Set([...kValidU32, ...kInvalidU32])).beginSubcases())
.fn(t => {
const { val } = t.params;
const code = `var test: u32 = ${val};`;
const extensionList = val.includes('h') ? ['f16'] : [];
t.expectCompileResult(kValidU32.has(val), t.wrapInEntryPoint(code, extensionList));
});
}
const kF32 = new Set([
'0f',
'0.0f',
'12.223f',
'12.f',
'.12f',
'2.4e+4f',
'2.4e-2f',
'2.e+4f',
'1e-4f',
'0x1P+4f',
]);
const kF16 = new Set([
'0h',
'1h',
'.1h',
'1.1e2h',
'1.1E+2h',
'2.4e-2h',
'0xep2h',
'0xEp-2h',
'0x3p+2h',
'0x3.2p+2h',
]);
const kAbstractFloat = new Set([
'0.0',
'.0',
'12.',
'00012.',
'.12',
'1.2e2',
'1.2E2',
'1.2e+2',
'2.4e-2',
'.1e-2',
'0x.3',
'0X.3',
'0xa.fp+2',
'0xa.fP+2',
'0xE.fp+2',
'0X1.fp-4',
]);
{
const kValidFloats = new Set([...kF32, ...kF16, ...kAbstractFloat]);
const kInvalidFloats = new Set([
'.f',
'.e-2',
'1.e&2f',
'1.ef',
'1.e+f',
'0x.p2',
'0x1p',
'0x1p^',
'1.0e+999999999999f',
'0x1.0p+999999999999f',
'0x1.00000001pf0',
]);
const kInvalidF16s = new Set([
'1.1eh',
'1.1e!2h',
'1.1e+h',
'1.0e+999999h',
'0x1.0p+999999h',
'0xf.h',
'0x3h',
]);
g.test('abstract_float')
.desc(`Test that valid floats are accepted, and invalid floats are rejected`)
.params(u =>
u
.combine('val', new Set([...kValidFloats, ...kInvalidFloats, ...kInvalidF16s]))
.beginSubcases()
)
.fn(t => {
const code = `var test = ${t.params.val};`;
const extensionList = kF16.has(t.params.val) || kInvalidF16s.has(t.params.val) ? ['f16'] : [];
t.expectCompileResult(
kValidFloats.has(t.params.val),
t.wrapInEntryPoint(code, extensionList)
);
});
}
{
const kValidF32 = new Set([
...kF32,
...kAbstractFloat,
'1',
'-1',
]);
const kInvalidF32 = new Set([
...kF16,
'1u',
'1i',
'1h',
'.f',
'.e-2',
'1.e&2f',
'1.ef',
'1.e+f',
'0x.p2',
'0x1p',
'0x1p^',
'1.0e+999999999999f',
'0x1.0p+999999999999f',
'0x1.00000001pf0',
]);
g.test('f32')
.desc(`Test that valid floats are accepted, and invalid floats are rejected`)
.params(u => u.combine('val', new Set([...kValidF32, ...kInvalidF32])).beginSubcases())
.fn(t => {
const { val } = t.params;
const code = `var test: f32 = ${val};`;
const extensionList = kF16.has(val) ? ['f16'] : [];
t.expectCompileResult(kValidF32.has(val), t.wrapInEntryPoint(code, extensionList));
});
}
{
const kValidF16 = new Set([
...kF16,
...kAbstractFloat,
'1',
'-1',
]);
const kInvalidF16 = new Set([
...kF32,
'1i',
'1u',
'1f',
'1.1eh',
'1.1e!2h',
'1.1e+h',
'1.0e+999999h',
'0x1.0p+999999h',
]);
g.test('f16')
.desc(
`
Test that valid half floats are accepted, and invalid half floats are rejected
`
)
.params(u => u.combine('val', new Set([...kValidF16, ...kInvalidF16])).beginSubcases())
.fn(t => {
const { val } = t.params;
const code = `var test: f16 = ${val};`;
const extensionList = ['f16'];
t.expectCompileResult(kValidF16.has(val), t.wrapInEntryPoint(code, extensionList));
});
}