diff --git a/src/utils/types.ts b/src/utils/types.ts index 46004a75..4492e111 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -14,9 +14,9 @@ const TYPE_ADAPTERS = Object.freeze({ bool: 'boolean', }); -const defaultTypeShorthands: ColumnDefinitions = { +const DEFAULT_TYPE_SHORTHANDS: Readonly = Object.freeze({ id: { type: 'serial', primaryKey: true }, // convenience type for serial primary keys -}; +}); // some convenience adapters -- see above export function applyTypeAdapters(type: string): string { @@ -25,11 +25,11 @@ export function applyTypeAdapters(type: string): string { : type; } -function toType(type: string | ColumnDefinition): ColumnDefinition { +function toType(type: string | Readonly): ColumnDefinition { return typeof type === 'string' ? { type } : type; } -function removeType({ +function removeType>({ // eslint-disable-next-line @typescript-eslint/no-unused-vars type, ...rest @@ -38,11 +38,11 @@ function removeType({ } export function applyType( - type: Type, - extendingTypeShorthands: ColumnDefinitions = {} + type: Readonly, + extendingTypeShorthands: Readonly = {} ): ColumnDefinition & FunctionParamType { const typeShorthands: ColumnDefinitions = { - ...defaultTypeShorthands, + ...DEFAULT_TYPE_SHORTHANDS, ...extendingTypeShorthands, }; diff --git a/test/utils/types.spec.ts b/test/utils/types.spec.ts index 03942395..cc9c0e15 100644 --- a/test/utils/types.spec.ts +++ b/test/utils/types.spec.ts @@ -1,26 +1,58 @@ import { describe, expect, it } from 'vitest'; import type { ColumnDefinitions } from '../../src/operations/tablesTypes'; -import { applyType } from '../../src/utils'; +import { applyType, applyTypeAdapters } from '../../src/utils'; describe('utils', () => { + describe('applyTypeAdapters', () => { + it.each([ + ['int', 'integer'], + ['string', 'text'], + ['float', 'real'], + ['double', 'double precision'], + ['datetime', 'timestamp'], + ['bool', 'boolean'], + ])('should map %s to %s', (type, mappedType) => { + const actual = applyTypeAdapters(type); + + expect(actual).toBeTypeOf('string'); + expect(actual).toBe(mappedType); + }); + + it('should map custom value', () => { + const actual = applyTypeAdapters('custom'); + + expect(actual).toBeTypeOf('string'); + expect(actual).toBe('custom'); + }); + }); + describe('applyType', () => { it('should convert string', () => { const type = 'type'; - expect(applyType(type)).toEqual({ type }); + const actual = applyType(type); + + expect(actual).toBeTypeOf('object'); + expect(actual).toStrictEqual({ type }); }); it('should apply id shorthand', () => { - expect(applyType('id')).toEqual({ type: 'serial', primaryKey: true }); + const actual = applyType('id'); + + expect(actual).toBeTypeOf('object'); + expect(actual).toStrictEqual({ type: 'serial', primaryKey: true }); }); it('should apply shorthand', () => { const shorthandName = 'type'; const shorthandDefinition = { type: 'integer', defaultValue: 1 }; - expect( - applyType(shorthandName, { [shorthandName]: shorthandDefinition }) - ).toEqual(shorthandDefinition); + const actual = applyType(shorthandName, { + [shorthandName]: shorthandDefinition, + }); + + expect(actual).toBeTypeOf('object'); + expect(actual).toStrictEqual(shorthandDefinition); }); it('should apply recursive shorthand', () => { @@ -29,7 +61,10 @@ describe('utils', () => { user: { type: 'ref', references: 'users' }, }; - expect(applyType('user', shorthands)).toEqual({ + const actual = applyType('user', shorthands); + + expect(actual).toBeTypeOf('object'); + expect(actual).toStrictEqual({ type: 'integer', onDelete: 'CASCADE', references: 'users', @@ -42,7 +77,9 @@ describe('utils', () => { user: { type: 'ref', references: 'users' }, }; - expect(() => applyType('user', shorthands)).toThrow(); + expect(() => applyType('user', shorthands)).toThrow( + new Error('Shorthands contain cyclic dependency: user, ref, user') + ); }); }); });