Skip to content

Commit

Permalink
fix(utils/assert): evaluate exception lazily
Browse files Browse the repository at this point in the history
...and utilize typescript 3.0 for accurate `rest parameter` typing.
  • Loading branch information
chuan6 committed Jul 31, 2018
1 parent 4078d37 commit 6a4dc7c
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"tslint": "^5.9.1",
"tslint-eslint-rules": "^5.1.0",
"tslint-loader": "^3.6.0",
"typescript": "^2.8.3",
"typescript": "^3.0.1",
"webpack": "^4.1.1",
"webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.0"
Expand Down
16 changes: 8 additions & 8 deletions src/storage/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class Database {

private findSchema = (name: string): ParsedSchema => {
const schema = this.schemas.get(name)
return assertValue(schema, Exception.NonExistentTable(name))
return assertValue(schema, Exception.NonExistentTable, name)
}

/**
Expand All @@ -60,11 +60,11 @@ export class Database {
*/
defineSchema<T>(tableName: string, schema: SchemaDef<T>) {
const advanced = !this.schemaDefs.has(tableName) && !this.connected
assert(advanced, Exception.UnmodifiableTable())
assert(advanced, Exception.UnmodifiableTable)

const hasPK = Object.keys(schema)
.some((key: string) => schema[key].primaryKey === true)
assert(hasPK, Exception.PrimaryKeyNotProvided())
assert(hasPK, Exception.PrimaryKeyNotProvided)

this.schemaDefs.set(tableName, schema)
return this
Expand Down Expand Up @@ -101,7 +101,7 @@ export class Database {
}

load(data: any) {
assert(!this.connected, Exception.DatabaseIsNotEmpty())
assert(!this.connected, Exception.DatabaseIsNotEmpty)

const load = (db: lf.Database) => {
forEach(data.tables, (entities: any[], name: string) => {
Expand Down Expand Up @@ -487,7 +487,7 @@ export class Database {
columns.set(key, def.type as RDBType)

if (def.primaryKey) {
assert(!primaryKey[0], Exception.PrimaryKeyConflict())
assert(!primaryKey[0], Exception.PrimaryKeyConflict)
primaryKey.push(key)
}

Expand Down Expand Up @@ -649,7 +649,7 @@ export class Database {

const onlyNavigator = Array.from(fieldsValue.keys())
.every(key => contains(key, navigators))
assert(!onlyNavigator, Exception.InvalidQuery())
assert(!onlyNavigator, Exception.InvalidQuery)

if (!hasKey) {
// 保证主键一定比关联字段更早的被遍历到
Expand All @@ -669,7 +669,7 @@ export class Database {
}

columns.push(...ret.columns)
assert(!rootDefinition[key], Exception.AliasConflict(key, tableName))
assert(!rootDefinition[key], Exception.AliasConflict, key, tableName)

if ((defs as ColumnDef).column) {
rootDefinition[key] = defs
Expand Down Expand Up @@ -761,7 +761,7 @@ export class Database {
const schema = this.findSchema(tableName)
const pk = schema.pk
const pkVal = compoundEntites[pk]
assert(pkVal !== undefined, Exception.PrimaryKeyNotProvided())
assert(pkVal !== undefined, Exception.PrimaryKeyNotProvided)

const [ table ] = Database.getTables(db, tableName)
const identifier = fieldIdentifier(tableName, pkVal)
Expand Down
4 changes: 2 additions & 2 deletions src/storage/modules/Mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class Mutation {
}

private toUpdater() {
const meta = assertValue(this.meta, Exception.PrimaryKeyNotProvided())
const meta = assertValue(this.meta, Exception.PrimaryKeyNotProvided)
const query = this.db.update(this.table)
query.where(this.table[meta.key].eq(meta.val))

Expand All @@ -84,7 +84,7 @@ export class Mutation {
}

private toRow() {
const meta = assertValue(this.meta, Exception.PrimaryKeyNotProvided())
const meta = assertValue(this.meta, Exception.PrimaryKeyNotProvided)
return {
table: this.table,
row: this.table.createRow({
Expand Down
4 changes: 2 additions & 2 deletions src/storage/modules/QueryToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class QueryToken<T> {
}

values(): Observable<T[]> {
assert(!this.consumed, TokenConsumed())
assert(!this.consumed, TokenConsumed)

this.consumed = true
return this.selector$.pipe(
Expand All @@ -49,7 +49,7 @@ export class QueryToken<T> {
}

changes(): Observable<T[]> {
assert(!this.consumed, TokenConsumed())
assert(!this.consumed, TokenConsumed)

this.consumed = true
return this.selector$.pipe(
Expand Down
8 changes: 4 additions & 4 deletions src/storage/modules/Selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ export class Selector <T> {
const [ minSkip ] = skipsAndLimits
const maxLimit = skipsAndLimits.reduce((acc, current) => {
const nextSkip = acc.skip! + acc.limit!
assert(current.skip === nextSkip, Exception.TokenConcatFailed(`
assert(current.skip === nextSkip, Exception.TokenConcatFailed, `
skip should be serial,
expect: ${JSON.stringify(acc, null, 2)}
actual: ${nextSkip}
`))
`)
return current
})
return new Selector(
Expand All @@ -60,7 +60,7 @@ export class Selector <T> {
refCount()
)
dist.values = () => {
assert(!dist.consumed, Exception.TokenConsumed())
assert(!dist.consumed, Exception.TokenConsumed)
dist.consumed = true
return from(metaDatas).pipe(
mergeMap(metaData => metaData.values()),
Expand Down Expand Up @@ -230,7 +230,7 @@ export class Selector <T> {
)
)
)
assert(equal, Exception.TokenConcatFailed())
assert(equal, Exception.TokenConcatFailed)

return Selector.concatFactory(this, ...selectors)
}
Expand Down
42 changes: 31 additions & 11 deletions src/utils/assert.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
import { Truthy } from './truthy'

export function assert(condition: boolean, error: Error | string): void {
truthyOrThrow(condition, error)
type FailureHandler<U extends any[]> = (...args: U) => Error

export function assert(condition: boolean, failureMsg: string): void
export function assert<U extends any[]>(
condition: boolean,
failure: FailureHandler<U>,
...failureArgs: U
): void
export function assert<U extends any[]>(
condition: boolean,
failure: FailureHandler<U> | string,
...failureArgs: U
): void {
truthyOrThrow(condition, failure, ...failureArgs)
}

export function assertValue<T>(
export function assertValue<T>(value: T, falsyValueMsg: string): Truthy<T> | never
export function assertValue<T, U extends any[]>(
value: T,
failure: FailureHandler<U>,
...failureArgs: U
): Truthy<T> | never
export function assertValue<T, U extends any[]>(
value: T,
error: Error | string
failure: FailureHandler<U> | string,
...failureArgs: U
): Truthy<T> | never {
return truthyOrThrow(value, error)
return truthyOrThrow(value, failure, ...failureArgs)
}

function truthyOrThrow<T>(x: T, error: Error | string): Truthy<T> | never {
function truthyOrThrow<T, U extends any[]>(
x: T,
failure: FailureHandler<U> | string,
...failureArgs: U
): Truthy<T> | never {
if (x) {
return x as Truthy<T>
}

if (error instanceof Error) {
throw error
} else {
throw new Error(error)
}
const error = typeof failure === 'string' ? new Error(failure) : failure(...failureArgs)
throw error
}
13 changes: 11 additions & 2 deletions test/specs/utils/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ export default describe('Utils Testcase: ', () => {
describe('Func: assert', () => {

it('should throw when assert failed [1]', () => {
const check = () => assert(false, Error('failed'))
const check = () => assert(false, (msg: string) => new Error(msg), 'failed')
expect(check).to.throw('failed')
})

Expand All @@ -391,10 +391,19 @@ export default describe('Utils Testcase: ', () => {
})

it('should not throw when assert successed', () => {
const check = () => assert(true, Error('error code path'))
const check = () => assert(true, 'error code path')
expect(check).to.not.throw()
})

it('should not execute error function when assert condition is met', () => {
let x = 0
assert(true, () => {
x++
return new Error('failed')
})
expect(x).to.equal(0)
})

})

describe('Func: hash', () => {
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7423,9 +7423,9 @@ typescript@^2.4.2, typescript@^2.6.1:
version "2.6.2"
resolved "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4"

typescript@^2.8.3:
version "2.8.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-2.8.3.tgz#5d817f9b6f31bb871835f4edf0089f21abe6c170"
typescript@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz#43738f29585d3a87575520a4b93ab6026ef11fdb"

uglify-es@^3.3.4:
version "3.3.9"
Expand Down

0 comments on commit 6a4dc7c

Please sign in to comment.