UNPKG

walt-compiler

Version:

Alternative syntax for WebAssembly text format

182 lines (164 loc) 3.81 kB
import test from 'ava'; import makeParser from '../../parser'; import { makeFragment } from '../../parser/fragment'; import semantics from '../../semantics'; import validate from '..'; const parser = makeParser([]); const stmt = makeFragment(parser); const parseAndValidate = source => validate(semantics(parser(source), [], { parser, stmt }), { lines: source.split('/n'), filename: 'spec.walt', extraSemantics: [], }); test('ast must have metadata attached', t => { const error = t.throws(() => validate({ meta: [] }, { filename: 'test' })); t.snapshot(error); }); test('typos throw', t => { const error = t.throws(() => parseAndValidate('expost const x: i32;')); t.snapshot(error, true); }); test('global exports must have value', t => { const error = t.throws(() => parseAndValidate('export const x: i32;')); t.snapshot(error); }); test('undefined types throw', t => { // Memory and Tables are fine parseAndValidate("import { memory: Memory, table: Table } from 'env';"); const error = t.throws(() => parseAndValidate("import { foo: Type } from 'env';") ); t.snapshot(error); }); test('const cannot be re-asigned', t => { const error = t.throws(() => parseAndValidate(` function test() { const x: i32 = 0; x = 1; const y: i32 = 0; y += 1; }`) ); t.snapshot(error); }); test('unterminated declaration statements', t => { const error = t.throws(() => parseAndValidate(` function test() { const x: i32 = 0 x = 2; }`) ); t.snapshot(error); }); test('unterminated assignment statements', t => { const error = t.throws(() => parseAndValidate(` function test() { let x: i32 = 0; let y: i32 = 0; x = 2 y = 3 + 3; }`) ); t.snapshot(error); }); test('undefined object properties', t => { const error = t.throws(() => parseAndValidate(` type T = { x: i32 }; function test() { const obj: T = 0; let y : i32; y = obj.y; obj = { y: 5 }; obj.y = 5; }`) ); t.snapshot(error); }); test('access on undefined objects', t => { const error = t.throws(() => parseAndValidate(` function test() { obj.y = 5; }`) ); t.snapshot(error); }); test('functions must have consistent returns', t => { const error = t.throws(() => parseAndValidate(` function i32void(): i32 { return; } function i32i64(): i32 { const x: i64 = 0; return x; } `) ); t.snapshot(error); }); test('functions must be defined', t => { const error = t.throws(() => parseAndValidate(` function test(): i32 { const ptr: Type = 0; ptr(); return notDefined(); } `) ); t.snapshot(error); }); test('constants must be initialized', t => { const error = t.throws(() => parseAndValidate(` const g: i32 = 2 + 2; function test() { const x: i32; } `) ); t.snapshot(error); }); test('untyped imports need to be compiled out via a linker/build step', t => { const error = t.throws(() => parseAndValidate(` import { foo } from './foo'; `) ); t.snapshot(error); }); test('unknown user types at global scope, error', t => { const error = t.throws(() => parseAndValidate(` let t: unknown = 0; function foo() { let k: unknown = 0; } `) ); t.snapshot(error); }); test('invalid sucbscript target', t => { const error = t.throws(() => parseAndValidate(` const memory: Memory = {initial: 1}; const table: Table = { initial: 10, element: 'anyfunc' }; type ResultFnType = (i32) => void; export function fn(a: i32, l: i32, f: ResultFnType): i32 { let v: i32 = 0; let i: i32 = 0; for(i; i < l; i+=1) v += a[i]; f(v); }`) ); t.snapshot(error); });