Skip to content

Commit

Permalink
support execute & parse options in inferred types
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasAribart committed May 22, 2021
1 parent db7cabb commit f8675ca
Show file tree
Hide file tree
Showing 7 changed files with 595 additions and 200 deletions.
4 changes: 1 addition & 3 deletions src/__tests__/entity.delete.unit.test.ts
Expand Up @@ -45,7 +45,6 @@ describe('delete', () => {
})

it('deletes the key from inputs (async)', async () => {
// @ts-expect-error 💥 TODO: Fix return type
const { TableName, Key } = await TestEntity.delete({ email: 'test-pk', sort: 'test-sk' })
expect(TableName).toBe('test-table')
expect(Key).toEqual({ pk: 'test-pk', sk: 'test-sk' })
Expand All @@ -63,7 +62,6 @@ describe('delete', () => {
})

it('filters out extra data (async)', async () => {
// @ts-expect-error 💥 TODO: Fix return type
let { TableName, Key } = await TestEntity.delete({
email: 'test-pk',
sort: 'test-sk',
Expand All @@ -82,7 +80,7 @@ describe('delete', () => {
})

it('coerces key values to correct types (async)', async () => {
// @ts-expect-error 💥 TODO: Fix return type + Support coerce keyword
// @ts-expect-error 💥 TODO: Support coerce keyword
let { TableName, Key } = await TestEntity.delete({ email: 1, sort: true })
expect(TableName).toBe('test-table')
expect(Key).toEqual({ pk: '1', sk: 'true' })
Expand Down
4 changes: 1 addition & 3 deletions src/__tests__/entity.get.unit.test.ts
Expand Up @@ -45,7 +45,6 @@ describe('get', () => {
})

it('gets the key from inputs (async)', async () => {
// @ts-expect-error 💥 TODO: Correct interface ?
const { TableName, Key } = await TestEntity.get({ email: 'test-pk', sort: 'test-sk' })
expect(TableName).toBe('test-table')
expect(Key).toEqual({ pk: 'test-pk', sk: 'test-sk' })
Expand All @@ -63,7 +62,6 @@ describe('get', () => {
})

it('filters out extra data (async)', async () => {
// @ts-expect-error 💥 TODO: Correct interface ?
let { TableName, Key } = await TestEntity.get({
email: 'test-pk',
sort: 'test-sk',
Expand All @@ -82,7 +80,7 @@ describe('get', () => {
})

it('coerces key values to correct types (async)', async () => {
// @ts-expect-error 💥 TODO: Correct interface ? + Support coerce keyword
// @ts-expect-error 💥 TODO: Support coerce keyword
let { TableName, Key } = await TestEntity.get({ email: 1, sort: true })
expect(TableName).toBe('test-table')
expect(Key).toEqual({ pk: '1', sk: 'true' })
Expand Down
24 changes: 24 additions & 0 deletions src/__tests__/entity.utils.unit.test.ts
@@ -0,0 +1,24 @@
import { shouldExecute, shouldParse } from '../classes/Entity'

describe('Entity - utils', () => {
it('should execute', () => {
expect(shouldExecute(true, true)).toBe(true)
expect(shouldExecute(true, false)).toBe(true)
expect(shouldExecute(undefined, true)).toBe(true)
})
it('should not execute', () => {
expect(shouldExecute(false, false)).toBe(false)
expect(shouldExecute(undefined, false)).toBe(false)
expect(shouldExecute(false, true)).toBe(false)
})
it('should parse', () => {
expect(shouldParse(true, true)).toBe(true)
expect(shouldParse(true, false)).toBe(true)
expect(shouldParse(undefined, true)).toBe(true)
})
it('should not parse', () => {
expect(shouldParse(false, false)).toBe(false)
expect(shouldParse(undefined, false)).toBe(false)
expect(shouldParse(false, true)).toBe(false)
})
})
255 changes: 255 additions & 0 deletions src/__tests__/type-infering.unit.test.ts
@@ -1,4 +1,5 @@
import { DynamoDB } from 'aws-sdk'
import { DocumentClient as DocumentClientType } from 'aws-sdk/clients/dynamodb'
import MockDate from 'mockdate'
import { A, C, F, O } from 'ts-toolbelt'

Expand Down Expand Up @@ -160,6 +161,28 @@ describe('Entity', () => {
table: tableWithoutSK
} as const)

const entNoExecute = new Entity({
name: entityName,
autoExecute: false,
attributes: {
pk: { type: 'string', partitionKey: true, hidden: true },
pkMap1: ['pk', 0],
pkMap2: ['pk', 1]
},
table: tableWithoutSK
} as const)

const entNoParse = new Entity({
name: entityName,
autoParse: false,
attributes: {
pk: { type: 'string', partitionKey: true, hidden: true },
pkMap1: ['pk', 0],
pkMap2: ['pk', 1]
},
table: tableWithoutSK
} as const)

type ExpectedItem = {
created: string
modified: string
Expand All @@ -179,6 +202,60 @@ describe('Entity', () => {
testGetItem
})

it('no auto-execution', () => {
const item = { pk }
const getPromise = () => entNoExecute.get(item)
type GetParams = C.PromiseOf<F.Return<typeof getPromise>>
type TestGetParams = A.Equals<GetParams, DocumentClientType.GetItemInput>
const testGetParams: TestGetParams = 1
testGetParams
})

it('force execution', () => {
const item = { pk }
const getPromise = () => entNoExecute.get(item, { execute: true })
type GetItem = C.PromiseOf<F.Return<typeof getPromise>>['Item']
type TestGetItem = A.Equals<GetItem, ExpectedItem | undefined>
const testGetItem: TestGetItem = 1
testGetItem
})

it('force no execution', () => {
const item = { pk }
const getPromise = () => ent.get(item, { execute: false })
type GetParams = C.PromiseOf<F.Return<typeof getPromise>>
type TestGetParams = A.Equals<GetParams, DocumentClientType.GetItemInput>
const testGetParams: TestGetParams = 1
testGetParams
})

it('no auto-parsing', () => {
const item = { pk }
const getPromise = () => entNoParse.get(item)
type GetRawResponse = C.PromiseOf<F.Return<typeof getPromise>>
type TestGetRawResponse = A.Equals<GetRawResponse, DocumentClientType.GetItemOutput>
const testGetRawResponse: TestGetRawResponse = 1
testGetRawResponse
})

it('force parsing', () => {
const item = { pk }
const getPromise = () => entNoParse.get(item, { parse: true })
type GetItem = C.PromiseOf<F.Return<typeof getPromise>>['Item']
type TestGetItem = A.Equals<GetItem, ExpectedItem | undefined>
const testGetItem: TestGetItem = 1
testGetItem
})

it('force no parsing', () => {
const item = { pk }
const getPromise = () => ent.get(item, { parse: false })
type GetRawResponse = C.PromiseOf<F.Return<typeof getPromise>>
type TestGetRawResponse = A.Equals<GetRawResponse, DocumentClientType.GetItemOutput>
const testGetRawResponse: TestGetRawResponse = 1
testGetRawResponse
})

it('throws when primary key is incomplete', () => {
// @ts-expect-error
expect(() => ent.getParams({})).toThrow()
Expand Down Expand Up @@ -216,6 +293,68 @@ describe('Entity', () => {
testDeleteItem2
})

it('no auto-execution', () => {
const item = { pk }
const deletePromise = () => entNoExecute.delete(item)
type DeleteParams = C.PromiseOf<F.Return<typeof deletePromise>>
type TestDeleteParams = A.Equals<DeleteParams, DocumentClientType.DeleteItemInput>
const testDeleteParams: TestDeleteParams = 1
testDeleteParams
})

it('force execution', () => {
const item = { pk }
const deletePromise = () =>
entNoExecute.delete(item, { execute: true, returnValues: 'ALL_OLD' })
type DeleteItem = C.PromiseOf<F.Return<typeof deletePromise>>['Attributes']
type TestDeleteItem = A.Equals<DeleteItem, ExpectedItem | undefined>
const testDeleteItem: TestDeleteItem = 1
testDeleteItem
})

it('force no execution', () => {
const item = { pk }
const deletePromise = () => ent.delete(item, { execute: false })
type DeleteParams = C.PromiseOf<F.Return<typeof deletePromise>>
type TestDeleteParams = A.Equals<DeleteParams, DocumentClientType.DeleteItemInput>
const testDeleteParams: TestDeleteParams = 1
testDeleteParams
})

it('no auto-parsing', () => {
const item = { pk }
const deletePromise = () => entNoParse.delete(item)
type DeleteRawResponse = C.PromiseOf<F.Return<typeof deletePromise>>
type TestDeleteRawResponse = A.Equals<
DeleteRawResponse,
DocumentClientType.DeleteItemOutput
>
const testDeleteRawResponse: TestDeleteRawResponse = 1
testDeleteRawResponse
})

it('force parsing', () => {
const item = { pk }
const deletePromise = () =>
entNoParse.delete(item, { parse: true, returnValues: 'ALL_OLD' })
type DeleteItem = C.PromiseOf<F.Return<typeof deletePromise>>['Attributes']
type TestDeleteItem = A.Equals<DeleteItem, ExpectedItem | undefined>
const testDeleteItem: TestDeleteItem = 1
testDeleteItem
})

it('force no parsing', () => {
const item = { pk }
const deletePromise = () => ent.update(item, { parse: false })
type DeleteRawResponse = C.PromiseOf<F.Return<typeof deletePromise>>
type TestDeleteRawResponse = A.Equals<
DeleteRawResponse,
DocumentClientType.DeleteItemOutput
>
const testDeleteRawResponse: TestDeleteRawResponse = 1
testDeleteRawResponse
})

it('throws when primary key is incomplete', () => {
// @ts-expect-error
expect(() => ent.deleteParams({})).toThrow()
Expand Down Expand Up @@ -260,6 +399,60 @@ describe('Entity', () => {
testPutItem2
})

it('no auto-execution', () => {
const item = { pk }
const putPromise = () => entNoExecute.put(item)
type PutParams = C.PromiseOf<F.Return<typeof putPromise>>
type TestPutParams = A.Equals<PutParams, DocumentClientType.PutItemInput>
const testPutParams: TestPutParams = 1
testPutParams
})

it('force execution', () => {
const item = { pk }
const putPromise = () => entNoExecute.put(item, { execute: true, returnValues: 'ALL_OLD' })
type PutItem = C.PromiseOf<F.Return<typeof putPromise>>['Attributes']
type TestPutItem = A.Equals<PutItem, ExpectedItem | undefined>
const testPutItem: TestPutItem = 1
testPutItem
})

it('force no execution', () => {
const item = { pk }
const putPromise = () => ent.put(item, { execute: false, returnValues: 'ALL_OLD' })
type PutParams = C.PromiseOf<F.Return<typeof putPromise>>
type TestPutParams = A.Equals<PutParams, DocumentClientType.PutItemInput>
const testPutParams: TestPutParams = 1
testPutParams
})

it('no auto-parsing', () => {
const item = { pk }
const putPromise = () => entNoParse.put(item)
type PutRawResponse = C.PromiseOf<F.Return<typeof putPromise>>
type TestPutRawResponse = A.Equals<PutRawResponse, DocumentClientType.PutItemOutput>
const testPutRawResponse: TestPutRawResponse = 1
testPutRawResponse
})

it('force parsing', () => {
const item = { pk }
const putPromise = () => entNoParse.put(item, { parse: true, returnValues: 'ALL_OLD' })
type PutItem = C.PromiseOf<F.Return<typeof putPromise>>['Attributes']
type TestPutItem = A.Equals<PutItem, ExpectedItem | undefined>
const testPutItem: TestPutItem = 1
testPutItem
})

it('force no parsing', () => {
const item = { pk }
const putPromise = () => ent.put(item, { parse: false })
type PutRawResponse = C.PromiseOf<F.Return<typeof putPromise>>
type TestPutRawResponse = A.Equals<PutRawResponse, DocumentClientType.PutItemOutput>
const testPutRawResponse: TestPutRawResponse = 1
testPutRawResponse
})

it('throws when primary key is incomplete', () => {
// @ts-expect-error
expect(() => ent.putParams({})).toThrow()
Expand Down Expand Up @@ -301,6 +494,68 @@ describe('Entity', () => {
testUpdateItem2
})

it('no auto-execution', () => {
const item = { pk }
const updatePromise = () => entNoExecute.update(item)
type UpdateParams = C.PromiseOf<F.Return<typeof updatePromise>>
type TestUpdateParams = A.Equals<UpdateParams, DocumentClientType.UpdateItemInput>
const testUpdateParams: TestUpdateParams = 1
testUpdateParams
})

it('force execution', () => {
const item = { pk }
const updatePromise = () =>
entNoExecute.update(item, { execute: true, returnValues: 'ALL_NEW' })
type UpdateItem = C.PromiseOf<F.Return<typeof updatePromise>>['Attributes']
type TestUpdateItem = A.Equals<UpdateItem, ExpectedItem | undefined>
const testUpdateItem: TestUpdateItem = 1
testUpdateItem
})

it('force no execution', () => {
const item = { pk }
const updatePromise = () => ent.update(item, { execute: false })
type UpdateParams = C.PromiseOf<F.Return<typeof updatePromise>>
type TestUpdateParams = A.Equals<UpdateParams, DocumentClientType.UpdateItemInput>
const testUpdateParams: TestUpdateParams = 1
testUpdateParams
})

it('no auto-parsing', () => {
const item = { pk }
const updatePromise = () => entNoParse.update(item)
type UpdateRawResponse = C.PromiseOf<F.Return<typeof updatePromise>>
type TestUpdateRawResponse = A.Equals<
UpdateRawResponse,
DocumentClientType.UpdateItemOutput
>
const testUpdateRawResponse: TestUpdateRawResponse = 1
testUpdateRawResponse
})

it('force parsing', () => {
const item = { pk }
const updatePromise = () =>
entNoParse.update(item, { parse: true, returnValues: 'ALL_NEW' })
type UpdateItem = C.PromiseOf<F.Return<typeof updatePromise>>['Attributes']
type TestUpdateItem = A.Equals<UpdateItem, ExpectedItem | undefined>
const testUpdateItem: TestUpdateItem = 1
testUpdateItem
})

it('force no parsing', () => {
const item = { pk }
const updatePromise = () => ent.update(item, { parse: false })
type UpdateRawResponse = C.PromiseOf<F.Return<typeof updatePromise>>
type TestUpdateRawResponse = A.Equals<
UpdateRawResponse,
DocumentClientType.UpdateItemOutput
>
const testUpdateRawResponse: TestUpdateRawResponse = 1
testUpdateRawResponse
})

it('throws when primary key is incomplete', () => {
// @ts-expect-error
expect(() => ent.updateParams({})).toThrow()
Expand Down

0 comments on commit f8675ca

Please sign in to comment.