Skip to content

Commit

Permalink
feat(type): support enum in pathResolver/resolvePath
Browse files Browse the repository at this point in the history
  • Loading branch information
marcj committed Aug 12, 2024
1 parent 9af344f commit 78d7df0
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 8 deletions.
30 changes: 30 additions & 0 deletions packages/type/src/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,34 @@ function pathResolverCode(type: Type, compilerContext: CompilerContext, jitStack
${pathResolverCode(type.type, compilerContext, jitStack)}
}
`;
} else if (type.kind === ReflectionKind.tupleMember) {
return `
if (!path) return ${compilerContext.reserveVariable('type', type)};
${pathResolverCode(type.type, compilerContext, jitStack)};
`;
} else if (type.kind === ReflectionKind.tuple) {
const cases: string[] = [];
for (let i = 0; i < type.types.length; i++) {
cases.push(`
case "${i}": {
${pathResolverCode(type.types[i], compilerContext, jitStack)}
}
`);
}

return `
{
const dotIndex = path.indexOf('.');
const segment = dotIndex === -1 ? path : path.substr(0, dotIndex);
path = dotIndex === -1 ? '' : path.substr(dotIndex + 1);
switch (segment) {
${cases.join('\n')}
default: {
return undefined;
}
}
}
`;
} else if (type.kind === ReflectionKind.class && type.classType === Set) {
} else if (type.kind === ReflectionKind.class && type.classType === Map) {
} else if (type.kind === ReflectionKind.union) {
Expand Down Expand Up @@ -72,6 +100,8 @@ export function pathResolver<T>(type?: ReceiveType<T>, jitStack: JitStack = new
const pathName = dotIndex === -1 ? path : path.substr(0, dotIndex);
path = dotIndex === -1 ? '' : path.substr(dotIndex + 1);
if (!pathName) return ${compilerContext.reserveVariable('type', type)};
switch(pathName) {
${lines.join('\n')}
default: {
Expand Down
16 changes: 16 additions & 0 deletions packages/type/tests/path.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ test('pathResolver deep array object', () => {
expect(resolver('b.0.0.c')).toMatchObject({ kind: ReflectionKind.propertySignature, type: { kind: ReflectionKind.boolean } });
});

test('pathResolver deep array object', () => {
type t = { a: [string, number, [boolean, string, { b: number }]?] };

const resolver = pathResolver<t>();

expect(resolver('a')).toMatchObject({ kind: ReflectionKind.propertySignature, type: { kind: ReflectionKind.tuple } });

expect(resolver('a.0')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.string } });
expect(resolver('a.1')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.number } });

expect(resolver('a.2.0')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.boolean } });
expect(resolver('a.2.1')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.string } });
expect(resolver('a.2.2')).toMatchObject({ kind: ReflectionKind.tupleMember, type: { kind: ReflectionKind.objectLiteral } });
expect(resolver('a.2.2.b')).toMatchObject({ kind: ReflectionKind.propertySignature });
});

test('pathResolver deep class', () => {
interface Config {
name: string;
Expand Down
54 changes: 46 additions & 8 deletions packages/type/tests/typeguard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import { expect, test } from '@jest/globals';
import { float, float32, int8, integer, PrimaryKey, Reference } from '../src/reflection/type.js';
import { is } from '../src/typeguard.js';
import { Serializer } from '../src/serializer.js';
import { cast } from '../src/serializer-facade.js';
import { isReferenceInstance } from '../src/reference.js';

test('primitive string', () => {
expect(is<string>('a')).toEqual(true);
Expand Down Expand Up @@ -198,10 +201,10 @@ test('array any', () => {
expect(is<any[]>(true)).toEqual(false);
expect(is<any[]>({})).toEqual(false);

expect(is<any[]>({length:1})).toEqual(false);
expect(is<any[]>({length:0})).toEqual(false);
expect(is<any[]>({length:null})).toEqual(false);
expect(is<any[]>({length:undefined})).toEqual(false);
expect(is<any[]>({ length: 1 })).toEqual(false);
expect(is<any[]>({ length: 0 })).toEqual(false);
expect(is<any[]>({ length: null })).toEqual(false);
expect(is<any[]>({ length: undefined })).toEqual(false);
});

test('union', () => {
Expand Down Expand Up @@ -397,15 +400,50 @@ test('class with literal and default', () => {
readConcernLevel: 'local' = 'local';
}

expect(is<ConnectionOptions>({readConcernLevel: 'local'})).toBe(true);
expect(is<ConnectionOptions>({readConcernLevel: 'local2'})).toBe(false);
expect(is<ConnectionOptions>({ readConcernLevel: 'local' })).toBe(true);
expect(is<ConnectionOptions>({ readConcernLevel: 'local2' })).toBe(false);
});

test('union literal', () => {
class ConnectionOptions {
readConcernLevel: 'local' | 'majority' | 'linearizable' | 'available' = 'majority';
}

expect(is<ConnectionOptions>({readConcernLevel: 'majority'})).toBe(true);
expect(is<ConnectionOptions>({readConcernLevel: 'majority2'})).toBe(false);
expect(is<ConnectionOptions>({ readConcernLevel: 'majority' })).toBe(true);
expect(is<ConnectionOptions>({ readConcernLevel: 'majority2' })).toBe(false);
});

test('union classes with generic', () => {
class Group {
id: number & PrimaryKey = 0;
second: string = '';
}

class User {
id: number = 0;
groups: (Group & Reference)[] = [];
}

const serializer = new Serializer();

const newGroup = cast<Group>({ id: 1, second: 'a' });

const a = cast<User>({
id: 1,
groups: [newGroup],
}, undefined, serializer);

expect(a.groups[0]).toBeInstanceOf(Group);
expect(isReferenceInstance(a.groups[0])).toBe(false);

const b = cast<User>({
id: 1,
groups: [1],
}, undefined, serializer);

expect(b.groups[0]).toBeInstanceOf(Group);
expect(isReferenceInstance(b.groups[0])).toBe(true);
if (isReferenceInstance(b.groups[0])) {
//do something with this instance and fully load it
}
});

0 comments on commit 78d7df0

Please sign in to comment.