More tests, and variant label duplicate check
This commit is contained in:
parent
52be118dc7
commit
0db223ede8
|
@ -32,13 +32,18 @@ class Checker {
|
||||||
|
|
||||||
checkDefinition(def: M.Definition, name: symbol): void {
|
checkDefinition(def: M.Definition, name: symbol): void {
|
||||||
switch (def._variant) {
|
switch (def._variant) {
|
||||||
case 'or':
|
case 'or': {
|
||||||
[def.pattern0, def.pattern1, ... def.patternN].forEach(({ variantLabel, pattern }) =>
|
const labels = new Set<string>();
|
||||||
this.checkPattern(new Set(),
|
[def.pattern0, def.pattern1, ... def.patternN].forEach(({ variantLabel, pattern }) => {
|
||||||
pattern,
|
const context = `variant ${variantLabel} of ${name.description!}`;
|
||||||
`variant ${variantLabel} of ${name.description!}`,
|
if (labels.has(variantLabel)) {
|
||||||
typeFor(_ref => ANY_TYPE, pattern)));
|
this.recordProblem(context, `duplicate variant label`);
|
||||||
|
}
|
||||||
|
labels.add(variantLabel);
|
||||||
|
this.checkPattern(new Set(), pattern, context, typeFor(_ref => ANY_TYPE, pattern));
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'and': {
|
case 'and': {
|
||||||
const ps = [def.pattern0, def.pattern1, ... def.patternN];
|
const ps = [def.pattern0, def.pattern1, ... def.patternN];
|
||||||
const scope = new Set<string>();
|
const scope = new Set<string>();
|
||||||
|
|
|
@ -59,5 +59,79 @@ describe('checker', () => {
|
||||||
expect(() => readSchema('version 1 . A = [@a string @b string @c int @a any ...].'))
|
expect(() => readSchema('version 1 . A = [@a string @b string @c int @a any ...].'))
|
||||||
.toThrow(/duplicate binding named "a" in tail of A/);
|
.toThrow(/duplicate binding named "a" in tail of A/);
|
||||||
});
|
});
|
||||||
|
describe('in records', () => {
|
||||||
|
it('complains about duplicates in recs (1)', () => {
|
||||||
|
expect(() => readSchema('version 1 . A = <a @a string @a int>.'))
|
||||||
|
.toThrow(/duplicate binding named "a" in item 1 of fields of A/);
|
||||||
|
});
|
||||||
|
it('complains about duplicates in recs (2)', () => {
|
||||||
|
expect(() => readSchema('version 1 . A = <a @a string <x @y int @a int>>.'))
|
||||||
|
.toThrow(/duplicate binding named "a" in item 1 of fields of item 1 of fields of A/);
|
||||||
|
});
|
||||||
|
it('complains about duplicates in recs (3)', () => {
|
||||||
|
expect(() => readSchema('version 1 . A = <a @a string <<rec> =x [@y int @a int]>>.'))
|
||||||
|
.toThrow(/duplicate binding named "a" in item 1 of fields of item 1 of fields of A/);
|
||||||
|
});
|
||||||
|
it('complains about duplicates in recs (4)', () => {
|
||||||
|
expect(() => readSchema('version 1 . A = <a @a string <<rec> @a =x [@y int @z int]>>.'))
|
||||||
|
.toThrow(/duplicate binding named "a" in label of item 1 of fields of A/);
|
||||||
|
});
|
||||||
|
it('complains about duplicates in recs (5)', () => {
|
||||||
|
expect(() => readSchema('version 1 . A = <a @a string <<rec> @a any [@y int @z int]>>.'))
|
||||||
|
.toThrow(/duplicate binding named "a" in label of item 1 of fields of A/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('in unions', () => {
|
||||||
|
it('is OK with non-duplicate but duplicate-seeming bindings across branches', () => {
|
||||||
|
expect(readSchema('version 1 . A = <a @a string> / <b @a string>.')).not.toBeNull();
|
||||||
|
});
|
||||||
|
it('complains about duplicates within branches', () => {
|
||||||
|
expect(() => readSchema('version 1 . A = <a @a string @a int> / <b @a string>.'))
|
||||||
|
.toThrow(/in item 1 of fields of variant a of A/);
|
||||||
|
});
|
||||||
|
it('complains about duplicate branch names', () => {
|
||||||
|
expect(() => readSchema('version 1 . A = @x <a @a string> / @x <b @a string>.'))
|
||||||
|
.toThrow(/duplicate variant label in variant x of A/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('in intersections', () => {
|
||||||
|
it('is OK with non-duplicate bindings across branches', () => {
|
||||||
|
expect(readSchema('version 1 . A = <a @a string> & <a @b string>.')).not.toBeNull();
|
||||||
|
});
|
||||||
|
it('complains about duplicates within branches', () => {
|
||||||
|
expect(() => readSchema(
|
||||||
|
`version 1 . A = <a @a string @a int> & <a @b string @c int>.`))
|
||||||
|
.toThrow(/in item 1 of fields of A/);
|
||||||
|
});
|
||||||
|
it('complains about duplicates across branches', () => {
|
||||||
|
expect(() => readSchema(
|
||||||
|
`version 1 . A = <a @a string @b int> & <a @a string @c int>.`))
|
||||||
|
.toThrow(/in item 0 of fields of A/);
|
||||||
|
});
|
||||||
|
it('complains about duplicates within named branches', () => {
|
||||||
|
expect(() => readSchema(
|
||||||
|
`version 1 .
|
||||||
|
AAA = <a @a string @a int>.
|
||||||
|
ABC = <a @b string @c int>.
|
||||||
|
A = @x AAA & @y ABC.`))
|
||||||
|
.toThrow(/in item 1 of fields of AAA/);
|
||||||
|
});
|
||||||
|
it('is OK with seeming- but non-duplicates across named branches', () => {
|
||||||
|
expect(readSchema(
|
||||||
|
`version 1 .
|
||||||
|
AAA = <a @a string @b int>.
|
||||||
|
ABC = <a @a string @c int>.
|
||||||
|
A = @x AAA & @y ABC.`))
|
||||||
|
.not.toBeNull();
|
||||||
|
});
|
||||||
|
it('complains about duplicate branch names', () => {
|
||||||
|
expect(() => readSchema(
|
||||||
|
`version 1 .
|
||||||
|
AAB = <a @a string @b int>.
|
||||||
|
ACD = <a @c string @d int>.
|
||||||
|
A = @x AAB & @x ACD.`))
|
||||||
|
.toThrow(/in A/);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue