diff --git a/types/adone/adone.d.ts b/types/adone/adone.d.ts index f968bfa342..a4f102752c 100644 --- a/types/adone/adone.d.ts +++ b/types/adone/adone.d.ts @@ -73,5 +73,13 @@ export { std }; export * from "./glosses/common"; export * from "./glosses/math"; export * from "./glosses/utils"; +export * from "./glosses/assertion"; +export * from "./glosses/promise"; +export * from "./glosses/shani"; + +import "./glosses/shani-global"; + +export const assert: adone.assertion.I.AssertFunction; +export const expect: adone.assertion.I.ExpectFunction; export as namespace adone; diff --git a/types/adone/glosses/assertion.d.ts b/types/adone/glosses/assertion.d.ts new file mode 100644 index 0000000000..4e8bfc593a --- /dev/null +++ b/types/adone/glosses/assertion.d.ts @@ -0,0 +1,1074 @@ +import adone from "adone"; + +/** + * assertion functions + */ +export namespace assertion { + namespace I { + interface assertion { + AssertionError: AssertionError; + config: Config; + use: UseFunction; + loadMockInterface: LoadInterfaceFunction; + loadExpectInterface: LoadInterfaceFunction; + loadAssertInterface: LoadInterfaceFunction; + assert: AssertFunction; + expect: ExpectFunction; + } + + interface Config { + /** + * Include stack in Assertion error message + */ + includeStack: boolean; + /** + * Include `showDiff` flag in the thrown errors + */ + showDiff: boolean; + /** + * Length threshold for actual and expected values in assertion errors + */ + truncateThreshold: number; + /** + * use Proxy to throw an error when a non-existent property is read + */ + useProxy: boolean; + /** + * properties that should be ignored instead of throwing an error if they do not exist on the assertion + */ + proxyExcludedKeys: string[]; + } + + type PossibleTypes = adone.util.I.PossibleTypes | "array"; + + type UseFunction = (fn: () => void) => assertion; + + type LoadInterfaceFunction = () => assertion; + + interface AssertFunction { + /** + * Asserts that value is truthy + */ + (value: any, message?: string): void; + /** + * Throws an AssertionError, like node.js + */ + fail(actual?: any, expected?: any, message?: string, operator?: any): void; + /** + * Asserts that value is truthy + */ + isOk(value: any, message?: string): void; + /** + * Asserts that value is truthy + */ + ok(value: any, message?: string): void; + /** + * Asserts that value is falsy + */ + isNotOk(value: any, message?: string): void; + /** + * Asserts that value is falsy + */ + notOk(value: any, message?: string): void; + /** + * Asserts non-strict equality + */ + equal(actual: any, expected: any, message?: string): void; + /** + * Asserts non-strict inequality + */ + notEqual(actual: any, expected: any, message?: string): void; + /** + * Asserts strict equality + */ + strictEqual(actual: any, expected: any, message?: string): void; + /** + * Asserts strict inequality + */ + notStrictEqual(actual: any, expected: any, message?: string): void; + /** + * Asserts that actual is deeply equal to expected + */ + deepEqual(actual: any, expected: any, message?: string): void; + /** + * Asserts that actual is deeply equal to expected + */ + deepStrictEqual(actual: any, expected: any, message?: string): void; + /** + * Asserts that actual and expected have the same length and the same members (===) + */ + equalArrays(actual: any[], expected: any[], message?: string): void; + /** + * Asserts that actual is not deeply equal to expected + */ + notDeepEqual(actual: any, expected: any, message?: string): void; + /** + * Asserts that value > above + */ + isAbove(value: any, above: any, message?: string): void; + /** + * Asserts that value >= atLeast + */ + isAtLeast(value: any, atLeast: any, message?: string): void; + /** + * Asserts that value < below + */ + isBelow(value: any, below: any, message?: string): void; + /** + * Asserts that value <= atMost + */ + isAtMost(value: any, atMost: any, message?: string): void; + /** + * Asserts that value is true + */ + isTrue(value: any, message?: string): void; + /** + * Asserts that value is not true + */ + isNotTrue(value: any, message?: string): void; + /** + * Asserts that value is false + */ + isFalse(value: any, message?: string): void; + /** + * Asserts that value is not false + */ + isNotFalse(value: any, message?: string): void; + /** + * Asserts that value is null + */ + isNull(value: any, message?: string): void; + /** + * Asserts that valus is not null + */ + isNotNull(value: any, message?: string): void; + /** + * Asserts that value is NaN + */ + isNaN(value: any, message?: string): void; + /** + * Asserts that value is not NaN + */ + isNotNaN(value: any, message?: string): void; + /** + * Asserts that value is neither null nor undefined + */ + exists(value: any, message?: string): void; + /** + * Asserts that value is either null or undefined + */ + notExists(value: any, message?: string): void; + /** + * Asserts that value is undefined + */ + isUndefined(value: any, message?: string): void; + /** + * Asserts that value is not undefined + */ + isDefined(value: any, message?: string): void; + /** + * Asserts that value is a function + */ + isFunction(value: any, message?: string): void; + /** + * Asserts that value is not a function + */ + isNotFunction(value: any, message?: string): void; + /** + * Asserts that value is an object of type Object + */ + isObject(value: any, message?: string): void; + /** + * Asserts that value is not an object of type Object + */ + isNotObject(value: any, message?: string): void; + /** + * Asserts that value is an array + */ + isArray(value: any, message?: string): void; + /** + * Asserts that value is not an array + */ + isNotArray(value: any, message?: string): void; + /** + * Asserts that value is a string + */ + isString(value: any, message?: string): void; + /** + * Asserts that value is not a string + */ + isNotString(value: any, message?: string): void; + /** + * Asserts that value is a number + */ + isNumber(value: any, message?: string): void; + /** + * Asserts that value is not a number + */ + isNotNumber(value: any, message?: string): void; + /** + * Asserts that value is a finite number + */ + isFinite(value: any, message?: string): void; + /** + * Asserts that value is a boolean + */ + isBoolean(value: any, message?: string): void; + /** + * Asserts that value is not a boolean + */ + isNotBoolean(value: any, message?: string): void; + /** + * Asserts that value's type is `type` + */ + typeOf(value: any, type: I.PossibleTypes, message?: string): void; + typeOf(value: any, type: string, message?: string): void; + /** + * Assert that value's type is not `type` + */ + notTypeOf(value: any, type: I.PossibleTypes, message?: string): void; + notTypeOf(value: any, type: string, message?: string): void; + /** + * Asserts that value is an instance of constructor + */ + instanceOf(value: any, constructor: object, message?: string): void; + /** + * Asserts that value is not an instance of constructor + */ + notInstanceOf(value: any, constructor: object, message?: string): void; + /** + * Asserts that expected includes inc + */ + include(expected: T[], inc: T, message?: string): void; + include(expected: string, inc: string, message?: string): void; + /** + * Asserts that expected does not include inc + */ + notInclude(expected: T[], inc: T, message?: string): void; + notInclude(expected: string, inc: string, message?: string): void; + /** + * Asserts that expected includes inc + */ + deepInclude(expected: T[], inc: T, message?: string): void; + deepInclude(expected: string, inc: string, message?: string): void; + /** + * Asserts that expected does not include inc + */ + notDeepInclude(expected: T[], inc: T, message?: string): void; + notDeepInclude(expected: string, inc: string, message?: string): void; + /** + * Asserts that expected includes inc + */ + nestedInclude(expected: object, inc: object, message?: string): void; + /** + * Asserts that expected does not include inc + */ + notNestedInclude(expected: object, inc: object, message?: string): void; + /** + * Assert that expected includes inc + */ + deepNestedInclude(expected: object, inc: object, message?: string): void; + /** + * Assert that expected includes inc + */ + notDeepNestedInclude(expected: object, inc: object, message?: string): void; + /** + * Assert that expected includes inc + */ + ownInclude(expected: object, inc: object, message?: string): void; + /** + * Assert that expected does not include inc + */ + notOwnInclude(expected: object, inc: object, message?: string): void; + /** + * Assert that expected includes inc + */ + deepOwnInclude(expected: object, inc: object, message?: string): void; + /** + * Assert that expected does not include inc + */ + notDeepOwnInclude(expected: object, inc: object, message?: string): void; + /** + * Asserts that expected matches the regular expression regExp + */ + match(expected: any, regExp: RegExp, message?: string): void; + /** + * Asserts that expected does not match the regular expression regExp + */ + notMatch(expected: any, regExp: RegExp, message?: string): void; + /** + * Asserts that object has a property named `property` + */ + property(object: object, property: string, message?: string): void; + /** + * Asserts that object does not have a property named `property` + */ + notProperty(object: object, property: string, message?: string): void; + /** + * Asserts that object has a property named `property` with value `value` (===) + */ + propertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object does not have a property named `property` with value `value` (===) + */ + notPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object has a property named `property` with a value `value` + */ + deepPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object does not have a property named `property` with value `value` + */ + notDeepPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object has an owned property named `property` + */ + ownProperty(object: object, property: string, message?: string): void; + /** + * Asserts that object does not have an owned property named `property` + */ + notOwnProperty(object: object, property: string, message?: string): void; + /** + * Asserts that object has an owned property named `property` with value `value`(===) + */ + ownPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object does not have an owned property named `property` with value `value`(===) + */ + notOwnPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object has an owned property named `property` with value `value` + */ + deepOwnPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object does not have an owned property named `property` with value `value`(===) + */ + notDeepOwnPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object has a property named `property` + */ + nestedProperty(object: object, property: string, message?: string): void; + /** + * Asserts that object does not have a property named `property` + */ + notNestedProperty(object: object, property: string, message?: string): void; + /** + * Asserts that object has a property named `property` with value `value`(===) + */ + nestedPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object does not have a property named `property` with value `value`(===) + */ + notNestedPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object has a property named `property` with value `value` + */ + deepNestedPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that object does not have a property named `property` with value `value` + */ + notDeepNestedPropertyVal(object: object, property: string, value: any, message?: string): void; + /** + * Asserts that expected has a length property with value `length` + */ + lengthOf(expected: any, length: number, message?: string): void; + /** + * Asserts that object has at least one key from `keys` + */ + hasAnyKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object has all and only all of the keys provided + */ + hasAllKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object has all the keys provided but maybe more + */ + containsAllKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object does not have any provided key + */ + doesNotHaveAnyKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object does not have all the keys provided + */ + doesNotHaveAllKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object has at least one of the keys provided + */ + hasAnyDeepKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object has all and only all of the keys provided + */ + hasAllDeepKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object has all the keys provided but maybe more + */ + containsAllDeepKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object does not have any provided key + */ + doesNotHaveAnyDeepKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that object does not have all the keys provided + */ + doesNotHaveAllDeepKeys(object: object, keys: string | string[] | object, message?: string): void; + /** + * Asserts that a function or an async functions throws an error + */ + throws(fn: () => void, errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): any; + throws(fn: () => Promise, errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): Promise; + /** + * Asserts that a function or an async functions throws an error + */ + throw(fn: () => void, errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): any; + throw(fn: () => Promise, errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): Promise; + /** + * Asserts that a function or an async function does not throw an error + */ + doesNotThrow(fn: () => Promise, errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): Promise; + doesNotThrow(fn: () => void, errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): any; + /** + * Compares two values using operator + */ + operator(value: any, operator: string, val2: any, message?: string): void; + /** + * Asserts that actual is expected +/- delta + */ + closeTo(actual: number, expected: number, delta: number, message?: string): void; + /** + * Asserts that actual is expect +/- delta + */ + approximately(actual: number, expected: number, delta: number, message?: string): void; + /** + * Asserts that arrays have the same members in any order (===) + */ + sameMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that arrays do not have the same members in any order (===) + */ + notSameMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that arrays have the same members in any order + */ + sameDeepMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that arrays do not have the same members in any order + */ + notSameDeepMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that arrays have the same members in the same order (===) + */ + sameOrderedMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that arrays do not have the same members in the same order (===) + */ + notSameOrderedMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that arrays have the same members in the same order + */ + sameDeepOrderedMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that arrays do not have the same members in the same order + */ + notSameDeepOrderedMembers(set1: any[], set2: any[], message?: string): void; + /** + * Asserts that subset is included in superset in any order (===) + */ + includeMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that subset is not included in superset in any order (===) + */ + notIncludeMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that subset is included in superset in any order + */ + includeDeepMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that subset is not included in superset in any order + */ + notIncludeDeepMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that subset is included in superset in the same order (===) + */ + includeOrderedMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that subset is not included in superset in the same order (===) + */ + notIncludeOrderedMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that subset is included in superset in the same order + */ + includeDeepOrderedMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that subset is not included in superset in the same order + */ + notIncludeDeepOrderedMembers(superset: any[], subset: any[], message?: string): void; + /** + * Asserts that list includes inList + */ + oneOf(inList: any, list: any[], message?: string): void; + /** + * Asserts that a function changes the value of a property + */ + changes(fn: () => void, object: object, property: string, message?: string): void; + /** + * Asserts that a function changes the value of a property by delta + */ + changesBy(fn: () => void, object: object, property: string, delta: number, message?: string): void; + /** + * Asserts that a function does not changes the value of a property + */ + doesNotChange(fn: () => void, object: object, property: string, message?: string): void; + /** + * Asserts that a function does not change the value of a property or of a function’s return value by delta + */ + changesButNotBy(fn: () => void, object: object, property: string, delta: number, message?: string): void; + /** + * Asserts that a function increases a numeric object property + */ + increases(fn: () => void, object: object, property: string, message?: string): void; + /** + * Asserts that a function increases a numeric object property or a function’s return value by delta + */ + increasesBy(fn: () => void, object: object, property: string, delta: number, message?: string): void; + /** + * Asserts that a function does not increase a numeric object property + */ + doesNotIncrease(fn: () => void, object: object, property: string, message?: string): void; + /** + * Asserts that a function does not increase a numeric object property or function’s return value by delta + */ + increasesButNotBy(fn: () => void, object: object, property: string, delta: number, message?: string): void; + /** + * Asserts that a function decreases the value of a property + */ + decreases(fn: () => void, object: object, property: string, message?: string): void; + /** + * Asserts that a function decreases the value of a property by delta + */ + decreasesBy(fn: () => void, object: object, property: string, delta: number, message?: string): void; + /** + * Asserts that a function does not decrease the value of a property + */ + doesNotDecrease(fn: () => void, object: object, property: string, message?: string): void; + /** + * Asserts that a function does not decrease the value of a property or a function's return value by delta + */ + doesNotDecreaseBy(fn: () => void, object: object, property: string, delta: number, message?: string): void; + /** + * Asserts that a function does not decreases a numeric object property or a function’s return value by delta + */ + decreasesButNotBy(fn: () => void, object: object, property: string, delta: number, message?: string): void; + /** + * Throws an error if value is truthy + */ + ifError(value: any): void; + /** + * Asserts that object is extensible + */ + isExtensible(object: object, message?: string): void; + /** + * Asserts that object is extensible + */ + extensible(object: object, message?: string): void; + /** + * Asserts that object is not extensible + */ + isNotExtensible(object: object, message?: string): void; + /** + * Asserts that object is not extensible + */ + notExtensible(object: object, message?: string): void; + /** + * Asserts that object is sealed + */ + isSealed(object: object, message?: string): void; + /** + * Asserts that object is sealed + */ + sealed(object: object, message?: string): void; + /** + * Asserts that object is not sealed + */ + isNotSealed(object: object, message?: string): void; + /** + * Asserts that object is not sealed + */ + notSealed(object: object, message?: string): void; + /** + * Asserts that object is frozen + */ + isFrozen(object: object, message?: string): void; + /** + * Asserts that object is frozen + */ + frozen(object: object, message?: string): void; + /** + * Asserts that object is not frozen + */ + isNotFrozen(object: object, message?: string): void; + /** + * Asserts that object is not frozen + */ + notFrozen(object: object, message?: string): void; + /** + * Asserts that value is empty + */ + isEmpty(value: any, message?: string): void; + /** + * Asserts that value is empty + */ + empty(value: any, message?: string): void; + /** + * Asserts that value is not empty + */ + isNotEmpty(value: any, message?: string): void; + /** + * Asserts that value is not empty + */ + notEmpty(value: any, message?: string): void; + } + + interface ExpectFunction { + (value: adone.shani.util.I.Spy, message?: string): MockAssertions; + (value: any, message?: string): Assertion; + fail(actual: any, expected: any, message?: string, operator?: any): void; + } + + interface LanguageChains { + to: this; + be: this; + been: this; + is: this; + that: this; + which: this; + and: this; + has: this; + have: this; + with: this; + at: this; + of: this; + same: this; + but: this; + does: this; + } + + interface Assertion extends LanguageChains { + /** + * Negates all following assertion in the chain + */ + not: this; + /** + * Causes following assertions to use deep equality + */ + deep: this; + /** + * Enables dot- and bracket-notation in following property and include assertions + */ + nested: this; + /** + * Causes following property and incude assertions to ignore inherited properties + */ + own: this; + /** + * Causes following members assertions to require that members be in the same order + */ + ordered: this; + /** + * Causes following keys assertions to only require that the target have at least one of the given keys + */ + any: this; + /** + * Causes following keys assertions to require that the target have all of the given keys + */ + all: this; + /** + * Asserts that the target's type is `type` + */ + a(type: I.PossibleTypes, message?: string): this; + a(type: string, message?: string): this; + /** + * Asserts that the target's type is `type` + */ + an(type: I.PossibleTypes, message?: string): this; + an(type: string, message?: string): this; + /** + * Asserts that the target includes the given value + */ + include(value: any, message?: string): this; + /** + * Asserts that the target includes the given value + */ + includes(value: any, message?: string): this; + /** + * Asserts that the target contains the given value + */ + contain(value: any, message?: string): this; + /** + * Asserts that the target contains the given value + */ + contains(value: any, message?: string): this; + /** + * Asserts that the target is non-strictly equal to true + */ + ok: this; + /** + * Asserts that the target is true + */ + true: this; + /** + * Asserts that the target is false + */ + false: this; + /** + * Asserts that the target is null + */ + null: this; + /** + * Asserts that the target is undefined + */ + undefined: this; + /** + * Asserts that the target is NaN + */ + NaN: this; + /** + * Asserts that the target is neither null nor undefined + */ + exist: this; + /** + * Asserts that the target is empty + */ + empty: this; + /** + * Asserts that the target is an arguments object + */ + arguments: this; + /** + * Asserts that the target is an arguments object + */ + Arguments: this; + /** + * Asserts that the target is strictly equal to value(===) + */ + equal(value: any, message?: string): this; + /** + * Asserts that the target is strictly equal to value(===) + */ + equals(value: any, message?: string): this; + /** + * Asserts that the target is strictly equal to value(===) + */ + eq(value: any, message?: string): this; + /** + * Asserts that the target is deeply equal to object + */ + eql(object: any, message?: string): this; + /** + * Asserts that the target is deeply equal to object + */ + eqls(object: any, message?: string): this; + /** + * Asserts that the target has the same length length and elements as array in the same order + */ + eqlArray(array: any[], message?: string): this; + /** + * Asserts that target > n + */ + above(n: number, message?: string): this; + /** + * Asserts that target > n + */ + gt(n: number, message?: string): this; + /** + * Asserts that target > n + */ + greaterThan(n: number, message?: string): this; + /** + * Asserts that target >= n + */ + least(n: number, message?: string): this; + /** + * Asserts that target >= n + */ + gte(n: number, message?: string): this; + /** + * Asserts that target < n + */ + below(n: number, message?: string): this; + /** + * Asserts that target < n + */ + lt(n: number, message?: string): this; + /** + * Asserts that target < n + */ + lessThan(n: number, message?: string): this; + /** + * Asserts that target <= n + */ + most(n: number, message?: string): this; + /** + * Asserts that target <= n + */ + lte(n: number, message?: string): this; + /** + * Asserts that start <= target <= end + */ + within(start: number, end: number, message?: string): this; + /** + * Asserts that the target is an instance of constructor + */ + instanceof(constructor: object, message?: string): this; + /** + * Asserts that the target is an instance of constructor + */ + instanceOf(constructor: object, message?: string): this; + /** + * Asserts that the target has a property name `name` with value `value` + */ + property(name: string, value?: any, message?: string): this; + /** + * Asserts that the target has its own property name `name` with value `value` + */ + ownProperty(name: string, value?: any, message?: string): this; + /** + * Asserts that the target has its own property name `name` with value `value` + */ + haveOwnProperty(name: string, value?: any, message?: string): this; + /** + * Asserts that the target has its own property descriptor with name `name` and value `value` + */ + ownPropertyDescriptor(name: string, descriptor?: object, message?: string): this; + /** + * Asserts that the target has its own property descriptor with name `name` and value `value` + */ + haveOwnPropertyDescriptor(name: string, descriptor?: object, message?: string): this; + /** + * Asserts that the target's property length equal to n + */ + length(n: number, message?: string): this; + /** + * Asserts that the target's property length equal to n + */ + lengthOf(n: number, message?: string): this; + /** + * Asserts that the target matches the regular expression regExp + */ + match(regExp: RegExp, message?: string): this; + /** + * Asserts that the target matches the regular expression regExp + */ + matches(regExp: RegExp, message?: string): this; + /** + * Asserts that the target contains str as a substring + */ + string(str: string, message?: string): this; + /** + * Assert that the target has the given keys + */ + key(key: string | string[] | object): this; + key(...keys: string[]): this; + /** + * Assert that the target has the given keys + */ + keys(key: string | string[] | object): this; + keys(...keys: string[]): this; + /** + * Assert that the target throws an error + */ + throw(errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): this; + /** + * Assert that the target throws an error + */ + throws(errorLike?: object, errMsgMatcher?: string | RegExp, message?: string): this; + /** + * Assert that the target throws an error + */ + Throw(errorLike?: Error, errMsgMatcher?: string | RegExp): this; + /** + * Assert that the target has a method with name `method`. For functions checks the prototype + */ + respondTo(method: string, message?: string): this; + /** + * Assert that the target has a method with name `method`. For functions checks the prototype + */ + respondsTo(method: string, message?: string): this; + /** + * Makes respondsTo behave like the target is not a function + */ + itself: this; + /** + * Asserts that matches returns a truthy value with the target as the first argument + */ + satisfy(matcher: () => boolean, message?: string): this; + /** + * Asserts that matches returns a truthy value with the target as the first argument + */ + satisfies(matcher: () => boolean, message?: string): this; + /** + * Asserts that the target is expected +/- delta + */ + closeTo(expected: number, delta: number, message?: string): this; + /** + * Asserts that the target is expected +/- delta + */ + approximately(expected: number, delta: number, message?: string): this; + /** + * Asserts that the target array has the same members as the given + */ + members(set: any[], message?: string): this; + /** + * Asserts that the target is the member of list + */ + oneOf(list: any[], message?: string): this; + /** + * Asserts that fn returns a different value after the target's invokation than before + */ + change(fn: () => any, message?: string): this; + /** + * Asserts that the target's invokation changes subject's property + */ + change(subject: object, property: string, message?: string): this; + /** + * Asserts that fn returns a different value after the target's invokation than before + */ + changes(fn: () => any, message?: string): this; + /** + * Asserts that the target's invokation changes subject's property + */ + changes(subject: object, property: string, message?: string): this; + /** + * Asserts that fn returns a greater number after the target's invokation than before + */ + increase(fn: () => number, message?: string): this; + /** + * Asserts that the target's invokation increases subject's property + */ + increase(subject: object, property?: string, message?: string): this; + /** + * Asserts that fn returns a greater number after the target's invokation than before + */ + increases(fn: () => number, message?: string): this; + /** + * Asserts that the target's invokation increases subject's property + */ + increases(subject: object, property?: string, message?: string): this; + /** + * Asserts that fn returns a lesser number after the target's invokation than before + */ + decrease(fn: () => number, message?: string): this; + /** + * Asserts that the target's invokation decreases subject's property + */ + decrease(subject: object, property?: string, message?: string): this; + /** + * Asserts that fn returns a lesser number after the target's invokation than before + */ + decreases(fn: () => number, message?: string): this; + /** + * Asserts that the target's invokation decreases subject's property + */ + decreases(subject: object, property?: string, message?: string): this; + /** + * Asserts that the value was decreased/increased by delta + */ + by(delta: number, message?: string): this; + /** + * Asserts that the target is extensible + */ + extensible: this; + /** + * Asserts that the target is sealed + */ + sealed: this; + /** + * Asserts that the target is frozen + */ + frozen: this; + /** + * Asserts that the target is a finite number + */ + finite: this; + } + + interface MockAssertions extends Assertion { + /** + * Asserts that the spy has been called + */ + called: this; + /** + * Asserts that the spy has been called n times + */ + callCount(n: number): this; + /** + * Asserts that the spy has been called once + */ + calledOnce: this; + /** + * Asserts that the spy has been called twice + */ + calledTwice: this; + /** + * Asserts that the spy has been been called with `new` + */ + calledThrice: this; + /** + * Asserts that the spy has been called before anotherSpy + */ + calledBefore(anotherSpy: adone.shani.util.I.Spy): this; + /** + * Asserts that the spy has been called after anotherSpy + */ + calledAfter(anotherSpy: adone.shani.util.I.Spy): this; + /** + * Asserts that the spy has been called immediately before anotherSpy + */ + calledImmediatelyBefore(anotherSpy: adone.shani.util.I.Spy): this; + /** + * Asserts that the spy has been called immediately after anotherSpy + */ + calledImmediatelyAfter(anotherSpy: adone.shani.util.I.Spy): this; + /** + * Asserts that the spy has been called with context as this value + */ + calledOn(context: object): this; + /** + * Asserts that the spy has been called with the given arguments + */ + calledWith(...args: any[]): this; + /** + * Asserts that the spy has been called exactly with the given arguments + */ + calledWithExactly(...args: any[]): this; + /** + * Asserts that the spy has been called with matching arguments + */ + calledWithMatch(...args: any[]): this; + /** + * Asserts that the spy returned value + */ + returned(value: any): this; + /** + * Asserts that the spy threw error + */ + thrown(error: any): this; + /** + * Asserts that the spy threw error + */ + threw(error: any): this; + } + } + + class AssertionError extends adone.x.Exception { + constructor(message?: string, props?: object, ssf?: object) + } + + const config: I.Config; + const use: I.UseFunction; + const loadMockInterface: I.LoadInterfaceFunction; + const loadExpectInterface: I.LoadInterfaceFunction; + const loadAssertInterface: I.LoadInterfaceFunction; + const assert: I.AssertFunction; + const expect: I.ExpectFunction; +} diff --git a/types/adone/glosses/common.d.ts b/types/adone/glosses/common.d.ts index f424598c02..57025ea054 100644 --- a/types/adone/glosses/common.d.ts +++ b/types/adone/glosses/common.d.ts @@ -1,3 +1,6 @@ +/** + * predicates + */ export namespace is { function _null(obj: any): boolean; export { _null as null }; diff --git a/types/adone/glosses/math.d.ts b/types/adone/glosses/math.d.ts index d16b2a8c04..076bdd105f 100644 --- a/types/adone/glosses/math.d.ts +++ b/types/adone/glosses/math.d.ts @@ -1,3 +1,6 @@ +/** + * math related things + */ export namespace math { namespace I { interface LowHighBits { diff --git a/types/adone/glosses/promise.d.ts b/types/adone/glosses/promise.d.ts new file mode 100644 index 0000000000..a5267c69a3 --- /dev/null +++ b/types/adone/glosses/promise.d.ts @@ -0,0 +1,114 @@ +/** + * promise helpers + */ +export namespace promise { + namespace I { + interface Deferred { + /** + * Resolves the promise + */ + resolve(value?: T): void; + + /** + * Rejects the promise + */ + reject(value?: any): void; + + promise: Promise; + } + } + + /** + * Creates a promise and returns an interface to control the state + */ + export function defer(): I.Deferred; + + /** + * Creates a promise that will be resolved after given milliseconds + * + * @param ms delay in milliseconds + * @param value resolving value + */ + export function delay(ms: number, value?: T): Promise; + + /** + * Creates a promise that will be rejected after given milliseconds if the given promise is not fulfilled + * + * @param ms timeout in milliseconds + */ + export function timeout(promise: Promise, ms: number): Promise; + + /** + * Converts a promise to node.js style callback + */ + export function nodeify(promise: Promise, callback: (err?: any, value?: T) => void): Promise; + + namespace I { + interface PromisifyOptions { + /** + * Context to bind to new function + */ + context?: object; + } + } + + /** + * Converts a callback function to a promise-based function + */ + export function promisify(fn: (callback: (err?: any, result?: R) => void) => void, options?: I.PromisifyOptions): () => Promise; + export function promisify(fn: (a: T, callback: (err?: any, result?: R) => void) => void, options?: I.PromisifyOptions): (a: T) => Promise; + export function promisify(fn: (a: T, callback: (err?: any) => void) => void, options?: I.PromisifyOptions): (a: T) => Promise; + export function promisify(fn: (a: T1, b: T2, callback: (err?: any, result?: R) => void) => void, options?: I.PromisifyOptions): (a: T1, b: T2) => Promise; + export function promisify(fn: (a: T1, b: T2, callback: (err?: any) => void) => void, options?: I.PromisifyOptions): (a: T1, b: T2) => Promise; + export function promisify(fn: (a: T1, b: T2, c: T3, callback: (err?: any, result?: R) => void) => void, options?: I.PromisifyOptions): (a: T1, b: T2, c: T3) => Promise; + export function promisify(fn: (a: T1, b: T2, c: T3, callback: (err?: any) => void) => void, options?: I.PromisifyOptions): (a: T1, b: T2, c: T3) => Promise; + export function promisify( + fn: (a: T1, b: T2, c: T3, d: T4, callback: (err?: any, result?: R) => void) => void, + options?: I.PromisifyOptions + ): (a: T1, b: T2, c: T3, d: T4) => Promise; + export function promisify( + fn: (a: T1, b: T2, c: T3, d: T4, callback: (err?: any) => void) => void, + options?: I.PromisifyOptions + ): (a: T1, b: T2, c: T3, d: T4) => Promise; + export function promisify( + fn: (a: T1, b: T2, c: T3, d: T4, e: T5, callback: (err?: any, result?: R) => void) => void, + options?: I.PromisifyOptions + ): (a: T1, b: T2, c: T3, d: T4, e: T5) => Promise; + export function promisify( + fn: (a: T1, b: T2, c: T3, d: T4, callback: (err?: any) => void) => void, + options?: I.PromisifyOptions + ): (a: T1, b: T2, c: T3, d: T4, e: T5) => Promise; + export function promisify(fn: (...args: any[]) => void, options?: I.PromisifyOptions): (...args: any[]) => Promise; + + namespace I { + interface PromisifyAllOptions { + /** + * Suffix to use for keys + */ + suffix?: string; + + /** + * Function to filter keys + */ + + filter?(key: string): boolean; + /** + * Context to bind to new functions + */ + context?: object; + } + } + + /** + * Promisifies entire object + */ + export function promisifyAll(source: object, options?: I.PromisifyAllOptions): object; + + /** + * Executes a function after promise fulfillment + * + * @returns the original promise + */ + function _finally(promise: Promise, onFinally?: (...args: any[]) => void): Promise; + export { _finally as finally }; +} diff --git a/types/adone/glosses/shani-global.d.ts b/types/adone/glosses/shani-global.d.ts new file mode 100644 index 0000000000..8cb7bf1827 --- /dev/null +++ b/types/adone/glosses/shani-global.d.ts @@ -0,0 +1,79 @@ +/** + * Defines a tests block + */ +declare const describe: adone.shani.I.DescribeFunction; + +/** + * Defines a tests block + */ +declare const context: adone.shani.I.DescribeFunction; + +/** + * Defines a test + */ +declare const it: adone.shani.I.TestFunction; + +/** + * Defines a test + */ +declare const specify: adone.shani.I.TestFunction; + +/** + * Defines a hook that will be called only once before the block's tests + */ +declare const before: adone.shani.I.HookFunction; + +/** + * Defines a hook that will be called only once after the block's tests + */ +declare const after: adone.shani.I.HookFunction; + +/** + * Defines a hook that will be called before each test + */ +declare const beforeEach: adone.shani.I.HookFunction; + +/** + * Defines a hook that will be called after each test + */ +declare const afterEach: adone.shani.I.HookFunction; + +/** + * assertion functions + */ +declare const assert: adone.assertion.I.AssertFunction; + +/** + * bdd-style assertion functons + */ +declare const expect: adone.assertion.I.ExpectFunction; + +/** + * tools for installing controllable timer functions + */ +declare const fakeClock: adone.util.I.fakeClock.FakeClock; + +/** + * defines a spy function + */ +declare const spy: typeof adone.shani.util.spy; + +/** + * defines a stub function + */ +declare const stub: typeof adone.shani.util.stub; + +/** + * defines a mock function + */ +declare const mock: typeof adone.shani.util.mock; + +/** + * defines a matcher for spies/stubs/mocks + */ +declare const match: typeof adone.shani.util.match; + +/** + * assertion tool for http server responses + */ +declare const request: typeof adone.shani.util.request; diff --git a/types/adone/glosses/shani.d.ts b/types/adone/glosses/shani.d.ts new file mode 100644 index 0000000000..48fefe5028 --- /dev/null +++ b/types/adone/glosses/shani.d.ts @@ -0,0 +1,1655 @@ +/** + * testing framework + */ +export namespace shani { + namespace I { + interface EngineOptions { + /** + * Default timeout for tests and block + */ + defaultTimeout?: number; + + /** + * Default timeout for hooks + */ + defaultHookTimeout?: number; + + /** + * Options that transplirer uses when loads tests from files + */ + transpilerOptions?: object; // TODO: possible options to adone.js.compiler + + /** + * Forca calling gc function after each processed file + */ + callGc?: boolean; + } + + interface DescribeOptions { + /** + * Specify that this block must be skipped + */ + skip?: boolean | (() => void); + + /** + * Specify the timeout for this block + */ + timeout?: number | (() => void); + } + + interface DescribeRuntimeContext { + /** + * Skip this block + */ + skip(): void; + + /** + * Specify timeout for this block + */ + timeout(ms: number): void; + + [key: string]: any; + } + + type DescribeCallback = (this: DescribeRuntimeContext) => void; + + interface DescribeFunction { + (description: string, callback: DescribeCallback): void; + (description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, description: string, callback: DescribeCallback): void; + (a: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, c: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, g: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, g: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, g: string, h: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, g: string, h: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, g: string, h: string, i: string, description: string, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, g: string, h: string, i: string, description: string, options: DescribeOptions, callback: DescribeCallback): void; + (a: string, b: string, c: string, d: string, e: string, f: string, g: string, h: string, i: string, j: string, description: string, callback: DescribeCallback): void; + ( + a: string, b: string, c: string, + d: string, e: string, f: string, + g: string, h: string, i: string, + j: string, description: string, options: DescribeOptions, + callback: DescribeCallback + ): void; + (a: string, ...args: Array): void; + + /** + * Mark this block as inclusive + */ + only: DescribeFunction; + + /** + * Mark this block as exclusive + */ + skip: DescribeFunction; + } + + interface TestOptions { + /** + * Specify that this test must be skipped + */ + skip?: boolean | (() => void); + + /** + * Specify timeout for this test + */ + timeout?: number | (() => void); + + /** + * Add before hook for this test + */ + before?: HookCallback | [string, HookCallback]; + + /** + * Add after hook for this test + */ + after?: HookCallback | [string, HookCallback]; + } + + interface TestRuntimeContext { + /** + * Skip this test + */ + skip(): void; + + /** + * Specify timeout for this test + */ + timeout(ms: number): void; + + [key: string]: any; + } + + type TestCallback = (this: TestRuntimeContext, done: (err?: any) => void) => void; + + interface TestFunction { + (description: string, callback: TestCallback): void; + (description: string, options: TestOptions, callback: TestCallback): void; + /** + * Mark this test as inclusive + */ + only: TestFunction; + + /** + * Mark this test as exclusive + */ + skip: TestFunction; + } + + interface HookRuntimeContext { + /** + * Specify timeout for this hook + */ + timeout(ms: number): void; + + [key: string]: any; + } + + type HookCallback = (this: HookRuntimeContext, done: (err?: any) => void) => void; + + interface HookFunction { + (callback: HookCallback): void; + (description: string, callback: HookCallback): void; + } + + type StartHookEvent = "start before hook" | "start after hook" + | "start before each hook" | "start after each hook" + | "start before test hook" | "start after test hook"; + + type EndHookEvent = "end before hook" | "end after hook" + | "end before each hook" | "end after each hook" + | "end before test hook" | "end after test hook"; + + interface Emitter extends adone.EventEmitter { + on(event: "enter block", listener: ({ block }: { block: Block }) => void): this; + on(event: "exit block", listener: ({ block }: { block: Block }) => void): this; + on(event: "start test", listener: ({ block, test }: { block: Block, test: Test }) => void): this; + on(event: "end test", listener: ({ block, test, meta }: { block: Block, test: Test, meta: ExecutionResult }) => void): this; + on(event: "skip test", listener: ({ block, test, runtime }: { block: Block, test: Test, runtime: boolean }) => void): this; + on(event: StartHookEvent, listener: ({ block, test, hook }: { block: Block, test: Test, hook: Hook }) => void): this; + on(event: EndHookEvent, listener: ({ block, test, hook, meta }: { block: Block, test: Test, hook: Hook, meta: ExecutionResult }) => void): this; + on(event: "error", listener: (err: any) => void): this; + on(event: "done", listener: () => void): this; + + /** + * Stops testing + */ + stop(): void; + } + + interface ExecutionResult { + /** + * Resulting error + */ + err: any; + + /** + * Elapsed time in milliseconds + */ + elapsed: number; + } + + class Hook { + desctiption: string; + + constructor(description: string, callback: HookCallback, runtimeContext: object); + + /** + * Check if this hook has been run + */ + fired(): boolean; + + /** + * Check if this hook failed + */ + failed(): boolean; + + /** + * The cause of the fail + */ + cause(): any; + + /** + * Returns the timeout of the hook + */ + timeout(): number; + + /** + * Seta a timeout for this hook + */ + timeout(ms: number): this; + + /** + * Executes the hook + */ + run(): Promise; + } + + class Test { + description: string; + + constructor(description: string, callback: TestCallback, block: Block, runtimeContext: object, options: TestOptions); + + /** + * Handles params from options + */ + prepare(): Promise; + + /** + * Checks if this test is exclusive (has skip flag) + */ + isExclusive(): boolean; + + /** + * Checks if this test is exclusive (has only flag) + */ + isInclusive(): boolean; + + /** + * Skips this test + */ + skip(): this; + + /** + * Marks this test as inclusive + */ + only(): this; + + /** + * Returns the timeout of the test + */ + timeout(): number | null; + + /** + * Sets a timeout for this test + */ + timeout(ms: number): this; + + /** + * Returns a string of names from the root to this test + */ + chain(): string; + + /** + * Executes the test + */ + run(): Promise; + } + + class Block { + name: string; + hooks: { + before: Hook[]; + beforeEach: Hook[]; + afterEach: Hook[]; + after: Hook[]; + }; + children: Array; + + constructor(name: string, parent: Block, options: DescribeOptions); + + /** + * Handles params from options + */ + prepare(): Promise; + + /** + * Adds a new child into this block + */ + addChild(child: Block | Test): void; + + /** + * Before hooks iterator + */ + beforeHooks(): IterableIterator; + + /** + * After hooks iterator + */ + afterHooks(): IterableIterator; + + /** + * Before each hooks iterator + */ + beforeEachHooks(): IterableIterator; + + /** + * After each hooks iterator + */ + afterEachHooks(): IterableIterator; + + /** + * Checks if this block is exclusive (has skip flag) + */ + isExclusive(): boolean; + + /** + * Checks if this block is inclusive (has only flag) + */ + isInclusive(): boolean; + + /** + * Checks if this block has an inclusive node + */ + hasInclusive(): boolean; + + /** + * Skips this block + */ + skip(): this; + + /** + * Marks this block as inclusive + */ + only(): this; + + /** + * Returns the timeout of the block + */ + timeout(): number | null; + + /** + * Sets a timeout for this block + */ + timeout(ms: number): this; + + /** + * Returns the block's level, the length of parent blocks chain + */ + level(): number; + + /** + * Sets the block's level + */ + level(level: number): this; + + /** + * Returns a string of names from the root to this block + */ + chain(): string; + + /** + * Returns a chain of blocks from the root to this block + */ + blockChain(): Block[]; + } + + interface Context { + /** + * Defines a tests block + */ + describe: DescribeFunction; + + /** + * Defines a tests block + */ + context: DescribeFunction; + + /** + * Defines a test + */ + it: TestFunction; + + /** + * Defines a test + */ + specify: TestFunction; + + /** + * Defines a hook that will be called only once before the block's tests + */ + before: HookFunction; + + /** + * Defines a hook that will be called only once after the block's tests + */ + after: HookFunction; + + /** + * Defines a hook that will be called before each test + */ + beforeEach: HookFunction; + + /** + * Defines a hook that will be called after each test + */ + afterEach: HookFunction; + + /** + * Root node + */ + root: Block; + + /** + * Starts testing + */ + start(): Emitter; + } + } + + /** + * Represents a testing engine + */ + export class Engine { + constructor(options?: I.EngineOptions); + + /** + * Includes given files as test files + */ + include(...paths: string[]): void; + + /** + * Excludes given paths from testing + */ + exclude(...paths: string[]): void; + + /** + * Returns a testing context + */ + context(): I.Context; + + /** + * Starts testing + */ + start(): I.Emitter; + } + + namespace util { + namespace I { + // based on https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/sinon + + interface SpyCallApi { + /** + * The call's this value + */ + thisValue: any; + + /** + * The call's arguments + */ + args: any[]; + + /** + * Exception throws if any + */ + exception: any; + + /** + * Return value + */ + returnValue: any; + + /** + * Whether the spy was called on obj (this value) + */ + calledOn(obj: any): boolean; + + /** + * Whether the arguments were args (and possibly others) + */ + calledWith(...args: any[]): boolean; + + /** + * Whether the arguments were exactly args (no others) + */ + calledWithExactly(...args: any[]): boolean; + + /** + * Whether the call received matching args (and possibly others) + */ + calledWithMatch(...args: any[]): boolean; + + /** + * Whether the call did not receive args + */ + notCalledWith(...args: any[]): boolean; + + /** + * Whether the call did not receive matching args + */ + notCalledWithMatch(...args: any[]): boolean; + + /** + * Whether the call returned the given value + */ + returned(value: any): boolean; + + /** + * Whether the call threw an exception + */ + threw(): boolean; + + /** + * Whether the call threw an exception of provided type + */ + threw(type: string): boolean; + + /** + * Whether the call threw obj + */ + threw(obj: any): boolean; + + /** + * Calls the argument at the given index + */ + callArg(pos: number): void; + + /** + * Calls the argument at the given index on the given context + */ + callArgOn(pos: number, obj: any): void; + + /** + * Calls the argument at the given index with arguments + */ + callArgWith(pos: number, ...args: any[]): void; + + /** + * Calls the argument at the given index on the given context and with the given arguments + */ + callArgOnWith(pos: number, obj: any, ...args: any[]): void; + + /** + * Calls a callback from the arguments with the given arguments + */ + yield(...args: any[]): void; + + /** + * Calls a callback from the arguments with the given arguments on the given context + */ + yieldOn(obj: any, ...args: any[]): void; + + /** + * Calls with the given arguments a callback that is a property of the call's argument with the given name + */ + yieldTo(property: string, ...args: any[]): void; + + /** + * Calls on the given context with the given arguments a callback that + * is a property of the call's argument with the given name + */ + yieldToOn(property: string, obj: any, ...args: any[]): void; + } + + interface SpyCall extends SpyCallApi { + /** + * Whether the call was called before the given call + */ + calledBefore(call: SpyCall): boolean; + + /** + * Whether the call was called after the given call + */ + calledAfter(call: SpyCall): boolean; + + /** + * Whether the call was called using the new operator + */ + calledWithNew(call: SpyCall): boolean; + } + + interface Spy extends SpyCallApi { + /** + * The number of recorded calls + */ + callCount: number; + + /** + * Whether the spy was called + */ + called: boolean; + + /** + * Whether the spy was not called + */ + notCalled: boolean; + + /** + * Whether the spy was called once + */ + calledOnce: boolean; + + /** + * Whether the spy was called twice + */ + calledTwice: boolean; + + /** + * Whether the spy was called thrice + */ + calledThrice: boolean; + + /** + * The first call + */ + firstCall: SpyCall; + + /** + * The second call + */ + secondCall: SpyCall; + + /** + * The third call + */ + thirdCall: SpyCall; + + /** + * The last call + */ + lastCall: SpyCall; + + /** + * Array of the calls contexts + */ + thisValues: any[]; + + /** + * Array of the calls arguments + */ + args: any[][]; + + /** + * Array of the calls exceptions + */ + exceptions: any[]; + + /** + * Array of the calls return values + */ + returnValues: any[]; + + (...args: any[]): any; + /** + * Whether the spy was called before another spy + */ + calledBefore(anotherSpy: Spy): boolean; + + /** + * Whether the spy was called after another spy + */ + calledAfter(anotherSpy: Spy): boolean; + + /** + * Whether the spy was called before another spy and no spies occured between them + */ + calledImmediatelyBefore(anotherSpy: Spy): boolean; + + /** + * Whether the spy was called after another spy and no spies occured between them + */ + calledImmediatelyAfter(anotherSpy: Spy): boolean; + + /** + * Whether the spy was called using the new operator + */ + calledWithNew(): boolean; + + /** + * Creates a spy that record calls only with the given arguments + */ + withArgs(...args: any[]): Spy; + + /** + * Whether the spy was called on the given context (this value) + */ + alwaysCalledOn(obj: any): boolean; + + /** + * Whether the spy was called with the given arguments (and possibly others) + */ + alwaysCalledWith(...args: any[]): boolean; + + /** + * Whether the spy was called exactly with the given arguments (no others) + */ + alwaysCalledWithExactly(...args: any[]): boolean; + + /** + * Whether the spy was called with the matching arguments (and possibly others) + */ + alwaysCalledWithMatch(...args: any[]): boolean; + + /** + * Whether the spy was never called with the given arguments + */ + neverCalledWith(...args: any[]): boolean; + + /** + * Whether the spy was neven called with the matching arguments + */ + neverCalledWithMatch(...args: any[]): boolean; + + /** + * Whether the spy always threw exceptions + */ + alwaysThrew(): boolean; + + /** + * Whether the spy always threw exceptions of the given types + */ + alwaysThrew(type: string): boolean; + + /** + * Whether the spy always threw the given object + */ + alwaysThrew(obj: any): boolean; + + /** + * Whether the spy always returned the given object + */ + alwaysReturned(obj: any): boolean; + + /** + * Invokes the callbacks passed in the arguments with the given arguments + */ + invokeCallback(...args: any[]): void; + + /** + * Returns the call with the given index + */ + getCall(n: number): SpyCall; + + /** + * Returns all the calls + */ + getCalls(): SpyCall[]; + + /** + * Resets the state of the spy + */ + reset(): void; + + /** + * Returns the passed format string with the given replacements + */ + printf(format: string, ...args: any[]): string; + + /** + * Replaces the spy with the original method if the spy replaced an original method + */ + restore(): void; + } + + interface Stub extends Spy { + /** + * Resets the stub's behavior to the default behavior + */ + resetBehavior(): void; + + /** + * Resets the stub's history + */ + resetHistory(): void; + + /** + * Causes the stub to return promises using the given promise library + */ + usingPromise(promiseLibrary: any): Stub; + + /** + * Makes the stub return the given object + */ + returns(obj: any): Stub; + + /** + * Causes the stub to return the argument at the given index + */ + returnsArg(index: number): Stub; + + /** + * Causes the stub to return its this value + */ + returnsThis(): Stub; + + /** + * Causes the stub to return a promise that resolves to the given value + */ + resolves(value?: any): Stub; + + /* + * Causes the stub to throw an exception of the given type + */ + throws(type?: string): Stub; + + /** + * Causes the stub to throw the given object + */ + throws(obj: any): Stub; + + /** + * Causes the stub to throw the argument at the given index + */ + throwsArg(index: number): Stub; + + /* + * Causes the stub to throw an exception of the given type + */ + throwsException(type?: string): Stub; + + /** + * Causes the stub to throw the argument at the given index + */ + throwsException(obj: any): Stub; + + /** + * Causes the stub to reject + */ + rejects(): Stub; + + /** + * Causes the stub to reject with the given type + */ + rejects(errorType: string): Stub; + + /** + * Causes the stub to reject with the given value + */ + rejects(value: any): Stub; + + /** + * Causes the stub to call the argument at the provided index as a callback function + */ + callsArg(index: number): Stub; + + /** + * Causes the original method wrapped into the stub to be called when none of the conditional stubs are matched + */ + callThrough(): Stub; + + /** + * Causes the stub to call the argument at the provided index as a callback function on the given context + */ + callsArgOn(index: number, context: any): Stub; + + /** + * Causes the stub to call the argument at the provided index as a callback function with the given arguments + */ + callsArgWith(index: number, ...args: any[]): Stub; + + /** + * Causes the stub to call the argument at the provided index as a callback function on the given context with the given arguments + */ + callsArgOnWith(index: number, context: any, ...args: any[]): Stub; + + /** + * Causes the stub to asynchronously call the argument at the provided index as a callback function + */ + callsArgAsync(index: number): Stub; + + /** + * Causes the stub to asynchronously call the argument at the provided index as a callback function on the given context + */ + callsArgOnAsync(index: number, context: any): Stub; + + /** + * Causes the stub to asynchronously call the argument at the provided index as a callback function on the given context with the given arguments + */ + callsArgWithAsync(index: number, ...args: any[]): Stub; + + /** + * Causes the stub to asynchronously call the argument at the provided index as a callback function on the given context with the given arguments + */ + callsArgOnWithAsync(index: number, context: any, ...args: any[]): Stub; + + /** + * Makes the stub call the provided fake function + */ + callsFake(func: (...args: any[]) => void): Stub; + + /** + * Replaces a new getter with this stub + */ + get(func: () => any): Stub; + + /** + * Replaces a new getter with this stub + */ + set(func: (v: any) => void): Stub; + + /** + * Defines the behavior of the stub on the call with the given index + */ + onCall(n: number): Stub; + + /** + * Defines the behavior of the stub on the first call + */ + onFirstCall(): Stub; + + /** + * Defines the behavior of the stub on the second call + */ + onSecondCall(): Stub; + + /** + * Defines the behavior of the stub on the third call + */ + onThirdCall(): Stub; + + /** + * Defines a new value for this stub + */ + value(val: any): Stub; + + /** + * Causes the stub to call the first callback it receives with the provided arguments + */ + yields(...args: any[]): Stub; + + /** + * Causes the stub to call the first callback it receives with the provided arguments on the given context + */ + yieldsOn(context: any, ...args: any[]): Stub; + + /** + * Causes the stub to call the last callback it receives with the provided arguments + */ + yieldsRight(...args: any[]): Stub; + + /** + * Causes the stub to invoke a callback passed as a property of an object to the spy + */ + yieldsTo(property: string, ...args: any[]): Stub; + + /** + * Causes the stub to invoke a callback passed as a property of an object to the spy on the given context + */ + yieldsToOn(property: string, context: any, ...args: any[]): Stub; + + /** + * Causes the stub to asynchronously call the first callback it receives with the provided arguments + */ + yieldsAsync(...args: any[]): Stub; + + /** + * Causes the stub to asynchronously call the first callback it receives with the provided arguments on the given context + */ + yieldsOnAsync(context: any, ...args: any[]): Stub; + + /** + * Causes the stub to asynchronously invoke a callback passed as a property of an object to the spy + */ + yieldsToAsync(property: string, ...args: any[]): Stub; + + /** + * Causes the stub to asynchronously invoke a callback passed as a property of an object to the spy on the given context + */ + yieldsToOnAsync(property: string, context: any, ...args: any[]): Stub; + + /** + * Stubs the method only for the provided arguments + */ + withArgs(...args: any[]): Stub; + } + + interface Expectation extends Stub { + /** + * Specifies the minimum amount of calls expected + */ + atLeast(n: number): Expectation; + + /** + * Specifies the maximum amount of calls expected + */ + atMost(n: number): Expectation; + + /** + * Expects the method to never be called + */ + never(): Expectation; + + /** + * Expects the method to be called exactly once + */ + once(): Expectation; + + /** + * Expects the method to be called exactly twice + */ + twice(): Expectation; + + /** + * Expects the method to be called exactly thrice + */ + thrice(): Expectation; + + /** + * Expects the method to be called exactly n times + */ + exactly(n: number): Expectation; + + /** + * Expects the method to be called with the provided arguments and possibly others + */ + withArgs(...args: any[]): Expectation; + + /** + * Expects the method to be called with the provided arguments and no others + */ + withExactArgs(...args: any[]): Expectation; + + /** + * Expects the method to be called with obj as this + */ + on(obj: any): Expectation; + + /** + * Verifies the expectation and throws an exception if it’s not met + */ + verify(): Expectation; + + /** + * Restores all mocked methods + */ + restore(): void; + } + + interface ExpectationStatic { + /** + * Creates a new expectation + */ + create(methodName?: string): Expectation; + } + + interface Mock { + /** + * Overrides obj.method with a mock function and returns it + */ + expects(method: string): Expectation; + + /** + * Restores all mocked methods + */ + restore(): void; + + /** + * Verifies all expectations on the mock + */ + verify(): void; + } + + interface ExposeOptions { + /** + * prefix to give assertions + */ + prefix?: string; + + /** + * Whether to copy the fail and failException properties + */ + includeFail?: boolean; + } + + interface Assert { + /** + * Default error type thrown by .fail + */ + failException: string; + + /** + * Every assertion fails by calling this method + */ + fail(message?: string): void; + + /** + * Called every time assertion passes + */ + pass(assertion: any): void; + + /** + * Passes if spy was never called + */ + notCalled(spy: Spy): void; + + /** + * Passes if spy was called at least once + */ + called(spy: Spy): void; + + /** + * Passes if spy was called once and only once + */ + calledOnce(spy: Spy): void; + + /** + * Passes if spy was called exactly twice + */ + calledTwice(spy: Spy): void; + + /** + * Passes if spy was called exactly three times + */ + calledThrice(spy: Spy): void; + + /** + * Passes if spy was called exactly count times + */ + callCount(spy: Spy, count: number): void; + + /** + * Passes if provided spies were called in the specified order + */ + callOrder(...spies: Spy[]): void; + + /** + * Passes if spy was ever called with obj as its this value + */ + calledOn(spy: Spy, obj: any): void; + + /** + * Passes if spy was always called with obj as its this value + */ + alwaysCalledOn(spy: Spy, obj: any): void; + + /** + * Passes if spy was called with the provided arguments + */ + calledWith(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy was always called with the provided arguments + */ + alwaysCalledWith(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy was never called with the provided arguments + */ + neverCalledWith(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy was called with the provided arguments and no others + */ + calledWithExactly(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy was always called with the provided arguments and no others + */ + alwaysCalledWithExactly(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy was called with matching arguments. + */ + calledWithMatch(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy was always called with matching arguments + */ + alwaysCalledWithMatch(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy was never called with matching arguments + */ + neverCalledWithMatch(spy: Spy, ...args: any[]): void; + + /** + * Passes if spy threw + */ + threw(spy: Spy): void; + + /** + * Passes if spy threw the given exception type + */ + threw(spy: Spy, exception: string): void; + + /** + * Passes if spy threw the given object + */ + threw(spy: Spy, exception: any): void; + + /** + * Passes if always spy threw + */ + alwaysThrew(spy: Spy): void; + + /** + * Passes if spy always threw the given exception type + */ + alwaysThrew(spy: Spy, exception: string): void; + + /** + * Passes if spy always threw the given object + */ + alwaysThrew(spy: Spy, exception: any): void; + + /** + * Exposes assertions into another object, to better integrate with the test framework + */ + expose(obj: any, options?: ExposeOptions): void; + } + + interface Matcher { + /** + * Logical and + */ + and(expr: Matcher): Matcher; + + /** + * Logical or + */ + or(expr: Matcher): Matcher; + } + + interface ArrayMatcher extends Matcher { + /** + * Requires an Array to be deep equal another one. + */ + deepEquals(expected: any[]): Matcher; + + /** + * Requires an Array to start with the same values as another one. + */ + startsWith(expected: any[]): Matcher; + + /** + * Requires an Array to end with the same values as another one. + */ + endsWith(expected: any[]): Matcher; + + /** + * Requires an Array to contain each one of the values the given array has. + */ + contains(expected: any[]): Matcher; + } + + interface MapMatcher extends Matcher { + /** + * Requires a Map to be deep equal another one. + */ + deepEquals(expected: Map): Matcher; + + /** + * Requires a Map to contain each one of the items the given map has. + */ + contains(expected: Map): Matcher; + } + + interface SetMatcher extends Matcher { + /** + * Requires a Set to be deep equal another one. + */ + deepEquals(expected: Set): Matcher; + + /** + * Requires a Set to contain each one of the items the given set has. + */ + contains(expected: Set): Matcher; + } + + interface Match { + /** + * Requires the value to be == to the given number + */ + (value: number): Matcher; + + /** + * Requires the value to be a string and have the expectation as a substring + */ + (value: string): Matcher; + + /** + * Requires the value to be a string and match the given regular expression + */ + (expr: RegExp): Matcher; + + /** + * Requires the value to be not null or undefined and have at least the same properties as expectation + */ + (obj: any): Matcher; + + /** + * Specify a custom matcher + */ + (callback: (value: any) => boolean, message?: string): Matcher; + + /** + * Matches anything + */ + any: Matcher; + + /** + * Requires the value to be defined + */ + defined: Matcher; + + /** + * Requires the value to be truthy + */ + truthy: Matcher; + + /** + * Requires the value to be falsy + */ + falsy: Matcher; + + /** + * Requires the value to be a boolean + */ + bool: Matcher; + + /** + * Requires the value to be a number + */ + number: Matcher; + + /** + * Requires the value to be a string + */ + string: Matcher; + + /** + * Requires the value to be an object + */ + object: Matcher; + + /** + * Requires the value to be a function + */ + func: Matcher; + + /** + * Requires the value to be a map. + */ + map: MapMatcher; + + /** + * Requires the value to be a set. + */ + set: SetMatcher; + + /** + * Requires the value to be an array. + */ + array: ArrayMatcher; + + /** + * Requires the value to be a regular expression + */ + regexp: Matcher; + + /** + * Requires the value to be a date object + */ + date: Matcher; + + /** + * Requires the value to be a symbol + */ + symbol: Matcher; + + /** + * Requires the value to strictly equal obj + */ + same(obj: any): Matcher; + + /** + * Requires the value to be of the given type + */ + typeOf(type: adone.util.I.PossibleTypes): Matcher; + typeOf(type: string): Matcher; + + /** + * Requires the value to be an instance of the given type + */ + instanceOf(type: any): Matcher; + + /** + * Requires the value to define the given property + */ + has(property: string, expect?: any): Matcher; + + /** + * Requires the value to define the given property by itself + */ + hasOwn(property: string, expect?: any): Matcher; + } + + interface SandboxConfig { + /** + * An object to add properties to + */ + injectInto?: any; + + /** + * What properties to inject + */ + properties?: string[]; + } + + interface Sandbox { + /** + * A convenience reference for assert + */ + assert: Assert; + + /** + * Works exactly like spy, only also adds the returned spy to the internal collection of fakes + */ + spy: typeof spy; + + /** + * Works exactly like stub, only also adds the returned spy to the internal collection of fakes + */ + stub: typeof stub; + + /** + * Works exactly like mock, only also adds the returned spy to the internal collection of fakes + */ + mock: typeof mock; + + /** + * Restores all fakes created through sandbox + */ + restore(): void; + + /** + * Resets the internal state of all fakes created through sandbox + */ + reset(): void; + + /** + * Resets the history of all stubs created through the sandbox + */ + resetHistory(): void; + + /** + * Resets the behaviour of all stubs created through the sandbox + */ + resetBehavior(): void; + + /** + * Causes all stubs created from the sandbox to return promises using a specific promise library + */ + usingPromise(promiseLibrary: any): Sandbox; + + /** + * Verifies all mocks created through the sandbox + */ + verify(): void; + + /** + * Verifies all mocks and restores all fakes created through the sandbox + */ + verifyAndRestore(): void; + } + + interface SandboxStatic { + /** + * Creates a sandbox object with spies, stubs, and mocks + */ + create(config?: SandboxConfig): Sandbox; + } + } + + /** + * Return a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls + */ + function spy(func?: (...args: any[]) => void): I.Spy; + function spy(object: T, method: keyof T): I.Spy; + + /** + * Creates a function (spy) with pre-programmed behavior + */ + function stub(obj?: any): I.Stub; + function stub(obj: T, method: keyof T): I.Stub; + + const expectation: I.ExpectationStatic; + + /** + * Creates a fake method (like spy) with pre-programmed behavior (like stub) + */ + function mock(): I.Expectation; + function mock(obj: any): I.Mock; + + /** + * Assertions for spies/stubs + */ + export const assert: I.Assert; + + /** + * Creates a matcher function + */ + export const match: I.Match; + + /** + * Removes the need to keep track of every fake created + */ + export const sandbox: I.SandboxStatic; + + namespace I { + interface Response extends adone.std.http.IncomingMessage { + body: Buffer; + } + + interface ExpectBodyOptions { + decompress?: boolean; + } + + interface AttachOptions { + type?: string; + filename?: string; + } + + interface Request extends Promise { + /** + * Sets the request method to GET + */ + get(path: string): this; + + /** + * Sets the request method to HEAD + */ + head(path: string): this; + + /** + * Sets the request method to POST + */ + post(path: string): this; + + /** + * Attaches an attachment + */ + attach(name: string, contents: string | Buffer, options?: AttachOptions): this; + + /** + * Attaches an attachment like a field + */ + field(name: string, value: string): this; + + /** + * Sets the request body + */ + send(value: string): this; + + /** + * Sets the request method to OPTIONS + */ + options(path: string): this; + + /** + * Sets the request method to PUT + */ + put(path: string): this; + + /** + * Sets a header value + */ + setHeader(key: string, value: string): this; + + /** + * Sets the basic auth header + */ + auth(username: string, password: string): this; + + /** + * Executes a function with the response and asserts it returns true + */ + expect(fn: (response: Response) => boolean | Promise): this; + + /** + * Asserts the response status + */ + expectStatus(code: number, message?: string): this; + + /** + * Asserts the respose status message + */ + expectStatusMessage(value: string): this; + + /** + * Asserts the response body + */ + expectBody(body: RegExp | string | Buffer, options?: ExpectBodyOptions): this; + + /** + * Asserts the response json body + */ + expectBody(body: object, options?: ExpectBodyOptions): this; + + /** + * Asserts that the response body is empty + */ + expectEmptyBody(): this; + + /** + * Asserts that the response has a header with the given key and value + */ + expectHeader(key: string, value: string | RegExp): this; + + /** + * Asserts that the response has a header with the given name + */ + expectHeaderExists(key: string): this; + + /** + * Asserts that the response does not have a header with the given name + */ + expectNoHeader(key: string): this; + } + } + + /** + * Assertion tool for http server responses + */ + function request(server: any): I.Request; // TODO: sever must be adone.net.http.server.Server or standard node.js server + + namespace FS { + // TODO: after fs + } + + namespace nock { + // TODO: after revision + } + } +} diff --git a/types/adone/glosses/utils.d.ts b/types/adone/glosses/utils.d.ts index 629b9a08bd..8f90ae180b 100644 --- a/types/adone/glosses/utils.d.ts +++ b/types/adone/glosses/utils.d.ts @@ -1,3 +1,6 @@ +/** + * various utility functions + */ export namespace util { function arrify(val: T[]): T[]; function arrify(val: T): [T]; @@ -184,6 +187,14 @@ export namespace util { } function jsesc(argument: any, options?: I.JSEscOptions): string; + namespace I { + type PossibleTypes = "object" | "class" | "null" | "global" | "Array" | "RegExp" | "Date" + | "Promise" | "Set" | "Map" | "WeakSet" | "DataView" | "Map Iterator" | "Set Iterator" + | "Array Iterator" | "String Iterator" | "Object" | "function" | "boolean" | "number" + | "undefined" | "string" | "symbol"; + } + + function typeOf(obj: any): I.PossibleTypes; function typeOf(obj: any): string; namespace memcpy { @@ -394,7 +405,7 @@ export namespace util { interface FakeClock { timers: Timers; createClock(now?: number, loopLimit?: number): Clock; - install(now: number | Date | InstallOptions): InstalledClock; + install(now?: number | Date | InstallOptions): InstalledClock; } } diff --git a/types/adone/test/glosses/assertion.ts b/types/adone/test/glosses/assertion.ts new file mode 100644 index 0000000000..4d07c78182 --- /dev/null +++ b/types/adone/test/glosses/assertion.ts @@ -0,0 +1,653 @@ +namespace assertionTests { + const { assertion } = adone; + + namespace assertionInterface { + namespace exception { + const a: adone.x.Exception = new assertion.AssertionError(); + const b: adone.x.Exception = new assertion.AssertionError("hello"); + const c: adone.x.Exception = new assertion.AssertionError("hello", { actual: 2, expected: 3 }, () => {}); + } + + namespace config { + assertion.config.includeStack = true; + assertion.config.proxyExcludedKeys = ["a"]; + assertion.config.showDiff = false; + assertion.config.truncateThreshold = 20; + assertion.config.useProxy = false; + } + + namespace loadInterfaces { + assertion.loadAssertInterface().config.includeStack = true; + assertion.loadExpectInterface().config.includeStack = true; + assertion.loadMockInterface().config.includeStack = true; + } + + namespace use { + assertion.use(() => {}).use(() => {}).config.includeStack = true; + } + } + + const { assert } = assertion; + + namespace assertTests { + assert(1); + assert(1, "hello"); + assert.fail(); + assert.fail(1); + assert.fail(1, 2); + assert.fail(1, 2, "hello"); + assert.fail(1, 2, "hello", "<"); + + assert.isOk(1); + assert.isOk(1, "hello"); + + assert.isNotOk(1); + assert.isNotOk(1, "hello"); + + assert.equal(1, 2); + assert.equal(1, 2, "hello"); + + assert.notEqual(1, 2); + assert.notEqual(1, 2, "hello"); + + assert.strictEqual(1, 2); + assert.strictEqual(1, 2, "hello"); + + assert.notStrictEqual(1, 2); + assert.notStrictEqual(1, 2, "hello"); + + assert.deepEqual(1, 2); + assert.deepEqual(1, 2, "hello"); + + assert.deepStrictEqual(1, 2); + assert.deepStrictEqual(1, 2, "hello"); + + assert.equalArrays([1, 2, 3], [4, 5, 6]); + assert.equalArrays([1, 2, 3], [4, 5, 6], "hello"); + + assert.notDeepEqual(1, 2); + assert.notDeepEqual(1, 2, "hello"); + + assert.isAbove(1, 2); + assert.isAbove(1, 2, "hello"); + + assert.isAtLeast(1, 2); + assert.isAtLeast(1, 2, "hello"); + + assert.isBelow(1, 2); + assert.isBelow(1, 2, "hello"); + + assert.isAtMost(1, 2); + assert.isAtMost(1, 2, "hello"); + + assert.isTrue(1); + assert.isTrue(1, "hello"); + + assert.isNotTrue(1); + assert.isNotTrue(1, "hello"); + + assert.isFalse(1); + assert.isFalse(1, "hello"); + + assert.isNotFalse(1); + assert.isNotFalse(1, "hello"); + + assert.isNull(1); + assert.isNull(1, "hello"); + + assert.isNaN(1); + assert.isNaN(1, "hello"); + + assert.isNotNaN(1); + assert.isNotNaN(1, "hello"); + + assert.exists(1); + assert.exists(1, "hello"); + + assert.notExists(1); + assert.notExists(1, "hello"); + + assert.isUndefined(1); + assert.isUndefined(1, "hello"); + + assert.isDefined(1); + assert.isDefined(1, "hello"); + + assert.isFunction(1); + assert.isFunction(1, "hello"); + + assert.isNotFunction(1); + assert.isNotFunction(1, "hello"); + + assert.isObject(1); + assert.isObject(1, "hello"); + + assert.isNotObject(1); + assert.isNotObject(1, "hello"); + + assert.isArray(1); + assert.isArray(1, "hello"); + + assert.isNotArray(1); + assert.isNotArray(1, "hello"); + + assert.isString(1, "hello"); + + assert.isNotString(1); + assert.isNotString(1, "hello"); + + assert.isNumber(1); + assert.isNumber(1, "hello"); + + assert.isNotNumber(1); + assert.isNotNumber(1, "hello"); + + assert.isFinite(1); + assert.isFinite(1, "hello"); + + assert.isBoolean(1); + assert.isBoolean(1, "hello"); + + assert.isNotBoolean(1); + assert.isNotBoolean(1, "hello"); + + assert.typeOf(1, "string"); + assert.typeOf(1, "number", "hello"); + + assert.notTypeOf(1, "string"); + assert.notTypeOf(1, "number", "hello"); + + assert.instanceOf(1, Date); + class A {} + assert.instanceOf("4", A, "hello"); + + assert.notInstanceOf(1, Date); + assert.notInstanceOf(Date, A, "hello"); + + assert.include([1, 2, 3], 4); + assert.include([1, 2, 3], 4, "hello"); + assert.include("string", "string"); + assert.include("string", "string", "string"); + + assert.notInclude([1, 2, 3], 4); + assert.notInclude([1, 2, 3], 4, "hello"); + assert.notInclude("string", "string"); + assert.notInclude("string", "string", "string"); + + assert.deepInclude([1, 2, 3], 4); + assert.deepInclude([1, 2, 3], 4, "hello"); + assert.deepInclude("string", "string"); + assert.deepInclude("string", "string", "string"); + + assert.notDeepInclude([1, 2, 3], 4); + assert.notDeepInclude([1, 2, 3], 4, "hello"); + assert.notDeepInclude("string", "string"); + assert.notDeepInclude("string", "string", "string"); + + assert.nestedInclude({ a: 1 }, {}); + assert.nestedInclude({ a: 1 }, {}, "hello"); + + assert.notNestedInclude({ a: 1 }, {}); + assert.notNestedInclude({ a: 1 }, {}, "hello"); + + assert.deepNestedInclude({ a: 1 }, {}); + assert.deepNestedInclude({ a: 1 }, {}, "hello"); + + assert.notDeepNestedInclude({ a: 1 }, {}); + assert.notDeepNestedInclude({ a: 1 }, {}, "hello"); + + assert.ownInclude({ a: 1 }, {}); + assert.ownInclude({ a: 1 }, {}, "hello"); + + assert.notOwnInclude({ a: 1 }, {}); + assert.notOwnInclude({ a: 1 }, {}, "hello"); + + assert.deepOwnInclude({ a: 1 }, {}); + assert.deepOwnInclude({ a: 1 }, {}, "hello"); + + assert.notDeepOwnInclude({ a: 1 }, {}); + assert.notDeepOwnInclude({ a: 1 }, {}, "hello"); + + assert.match("1", /\d+/); + assert.match("1", /\d+/, "hello"); + + assert.notMatch("1", /\d+/); + assert.notMatch("1", /\d+/, "hello"); + + assert.property({ a: 1 }, "a"); + assert.property({ a: 1 }, "a", "hello"); + + assert.notProperty({ a: 1 }, "a"); + assert.notProperty({ a: 1 }, "a", "hello"); + + assert.propertyVal({ a: 1 }, "a", 1); + assert.propertyVal({ a: 1 }, "a", 1, "hello"); + + assert.notPropertyVal({ a: 1 }, "a", 1); + assert.notPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.deepPropertyVal({ a: 1 }, "a", 1); + assert.deepPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.notDeepPropertyVal({ a: 1 }, "a", 1); + assert.notDeepPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.ownProperty({ a: 1 }, "a"); + assert.ownProperty({ a: 1 }, "a", "hello"); + + assert.notOwnProperty({ a: 1 }, "a"); + assert.notOwnProperty({ a: 1 }, "a", "hello"); + + assert.ownPropertyVal({ a: 1 }, "a", 1); + assert.ownPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.deepOwnPropertyVal({ a: 1 }, "a", 1); + assert.deepOwnPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.notDeepOwnPropertyVal({ a: 1 }, "a", 1); + assert.notDeepOwnPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.nestedProperty({ a: 1 }, "a"); + assert.nestedProperty({ a: 1 }, "a", "hello"); + + assert.notNestedProperty({ a: 1 }, "a"); + assert.notNestedProperty({ a: 1 }, "a", "hello"); + + assert.nestedPropertyVal({ a: 1 }, "a", 1); + assert.nestedPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.notNestedPropertyVal({ a: 1 }, "a", 1); + assert.notNestedPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.deepNestedPropertyVal({ a: 1 }, "a", 1); + assert.deepNestedPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.notDeepNestedPropertyVal({ a: 1 }, "a", 1); + assert.notDeepNestedPropertyVal({ a: 1 }, "a", 1, "hello"); + + assert.lengthOf([1, 2, 3], 3); + assert.lengthOf([1, 2, 3], 3, "hello"); + + assert.hasAnyKeys({ a: 1 }, "a"); + assert.hasAnyKeys({ a: 1 }, ["a"]); + assert.hasAnyKeys({ a: 1 }, ["a"], "hello"); + + assert.hasAnyKeys({ a: 1 }, { a: 1 }); + assert.hasAnyKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.hasAllKeys({ a: 1 }, "a"); + assert.hasAllKeys({ a: 1 }, ["a"]); + assert.hasAllKeys({ a: 1 }, ["a"], "hello"); + + assert.hasAllKeys({ a: 1 }, { a: 1 }); + assert.hasAllKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.containsAllKeys({ a: 1 }, "a"); + assert.containsAllKeys({ a: 1 }, ["a"]); + assert.containsAllKeys({ a: 1 }, ["a"], "hello"); + + assert.containsAllKeys({ a: 1 }, { a: 1 }); + assert.containsAllKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.doesNotHaveAnyKeys({ a: 1 }, "a"); + assert.doesNotHaveAnyKeys({ a: 1 }, ["a"]); + assert.doesNotHaveAnyKeys({ a: 1 }, ["a"], "hello"); + + assert.doesNotHaveAnyKeys({ a: 1 }, { a: 1 }); + assert.doesNotHaveAnyKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.doesNotHaveAllDeepKeys({ a: 1 }, "a"); + assert.doesNotHaveAllDeepKeys({ a: 1 }, ["a"]); + assert.doesNotHaveAllDeepKeys({ a: 1 }, ["a"], "hello"); + + assert.doesNotHaveAllDeepKeys({ a: 1 }, { a: 1 }); + assert.doesNotHaveAllDeepKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.hasAnyDeepKeys({ a: 1 }, "a"); + assert.hasAnyDeepKeys({ a: 1 }, ["a"]); + assert.hasAnyDeepKeys({ a: 1 }, ["a"], "hello"); + + assert.hasAnyDeepKeys({ a: 1 }, { a: 1 }); + assert.hasAnyDeepKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.hasAllDeepKeys({ a: 1 }, "a"); + assert.hasAllDeepKeys({ a: 1 }, ["a"]); + assert.hasAllDeepKeys({ a: 1 }, ["a"], "hello"); + + assert.hasAllDeepKeys({ a: 1 }, { a: 1 }); + assert.hasAllDeepKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.containsAllDeepKeys({ a: 1 }, "a"); + assert.containsAllDeepKeys({ a: 1 }, ["a"]); + assert.containsAllDeepKeys({ a: 1 }, ["a"], "hello"); + + assert.containsAllDeepKeys({ a: 1 }, { a: 1 }); + assert.containsAllDeepKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.doesNotHaveAnyDeepKeys({ a: 1 }, "a"); + assert.doesNotHaveAnyDeepKeys({ a: 1 }, ["a"]); + assert.doesNotHaveAnyDeepKeys({ a: 1 }, ["a"], "hello"); + + assert.doesNotHaveAnyDeepKeys({ a: 1 }, { a: 1 }); + assert.doesNotHaveAnyDeepKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.doesNotHaveAllDeepKeys({ a: 1 }, "a"); + assert.doesNotHaveAllDeepKeys({ a: 1 }, ["a"]); + assert.doesNotHaveAllDeepKeys({ a: 1 }, ["a"], "hello"); + + assert.doesNotHaveAllDeepKeys({ a: 1 }, { a: 1 }); + assert.doesNotHaveAllDeepKeys({ a: 1 }, { a: 1 }, "hello"); + + assert.throws(() => {}); + assert.throws(() => {}, Error); + assert.throws(() => {}, Error, /\d+/); + assert.throws(() => {}, Error, "string"); + assert.throws(() => {}, Error, "string", "hello"); + + assert.throws(async () => {}).then(() => 42); + assert.throws(async () => {}, Error).then(() => 42); + assert.throws(async () => {}, Error, /\d+/).then(() => 42); + assert.throws(async () => {}, Error, "string").then(() => 42); + assert.throws(async () => {}, Error, "string", "hello").then(() => 42); + + assert.doesNotThrow(() => {}); + assert.doesNotThrow(() => {}, Error); + assert.doesNotThrow(() => {}, Error, /\d+/); + assert.doesNotThrow(() => {}, Error, "string"); + assert.doesNotThrow(() => {}, Error, "string", "hello"); + + assert.doesNotThrow(async () => {}).then(() => 42); + assert.doesNotThrow(async () => {}, Error).then(() => 42); + assert.doesNotThrow(async () => {}, Error, /\d+/).then(() => 42); + assert.doesNotThrow(async () => {}, Error, "string").then(() => 42); + assert.doesNotThrow(async () => {}, Error, "string", "hello").then(() => 42); + + assert.operator(1, "<", 2); + assert.operator(1, "<", 2, "hello"); + + assert.closeTo(1, 2, 1); + assert.closeTo(1, 2, 1, "hello"); + + assert.approximately(1, 2, 2); + assert.approximately(1, 2, 2, "hello"); + + assert.sameMembers([1, 2, 3], [4, 5, 6]); + assert.sameMembers([1, 2, 3], [4, 5, 6], "hello"); + + assert.notSameMembers([1, 2, 3], [4, 5, 6]); + assert.notSameMembers([1, 2, 3], [4, 5, 6], "hello"); + + assert.sameDeepMembers([1, 2, 3], [4, 5, 6]); + assert.sameDeepMembers([1, 2, 3], [4, 5, 6], "hello"); + + assert.notSameDeepMembers([1, 2, 3], [4, 5, 6]); + assert.notSameDeepMembers([1, 2, 3], [4, 5, 6], "hello"); + + assert.sameOrderedMembers([1, 2, 3], [4, 5, 6]); + assert.sameOrderedMembers([1, 2, 3], [4, 5, 6], "hello"); + + assert.notSameOrderedMembers([1, 2, 3], [4, 5, 6]); + assert.notSameOrderedMembers([1, 2, 3], [4, 5, 6], "hello"); + + assert.includeMembers([1, 2, 3], [3]); + assert.includeMembers([1, 2, 3], [3], "hello"); + + assert.notIncludeMembers([1, 2, 3], [3]); + assert.notIncludeMembers([1, 2, 3], [3], "hello"); + + assert.includeDeepMembers([1, 2, 3], [3]); + assert.includeDeepMembers([1, 2, 3], [3], "hello"); + + assert.notIncludeDeepMembers([1, 2, 3], [3]); + assert.notIncludeDeepMembers([1, 2, 3], [3], "hello"); + + assert.includeOrderedMembers([1, 2, 3], [3]); + assert.includeOrderedMembers([1, 2, 3], [3], "hello"); + + assert.notIncludeOrderedMembers([1, 2, 3], [3]); + assert.notIncludeOrderedMembers([1, 2, 3], [3], "hello"); + + assert.includeDeepOrderedMembers([1, 2, 3], [3]); + assert.includeDeepOrderedMembers([1, 2, 3], [3], "hello"); + + assert.notIncludeDeepOrderedMembers([1, 2, 3], [3]); + assert.notIncludeDeepOrderedMembers([1, 2, 3], [3], "hello"); + + assert.oneOf(1, [1, 2, 3]); + assert.oneOf(1, [1, 2, 3], "hello"); + + assert.changes(() => {}, {}, "a"); + assert.changes(() => {}, {}, "a", "hello"); + + assert.changesBy(() => {}, {}, "a", 2); + assert.changesBy(() => {}, {}, "a", 2, "hello"); + + assert.doesNotChange(() => {}, {}, "a"); + assert.doesNotChange(() => {}, {}, "a", "hello"); + + assert.changesButNotBy(() => {}, {}, "a", 20); + assert.changesButNotBy(() => {}, {}, "a", 20, "hello"); + + assert.increases(() => {}, {}, "a"); + assert.increases(() => {}, {}, "a", "hello"); + + assert.increasesBy(() => {}, {}, "a", 20); + assert.increasesBy(() => {}, {}, "a", 20, "hello"); + + assert.doesNotIncrease(() => {}, {}, "a"); + assert.doesNotIncrease(() => {}, {}, "a", "hello"); + + assert.increasesButNotBy(() => {}, {}, "a", 20); + assert.increasesButNotBy(() => {}, {}, "a", 20, "hello"); + + assert.decreases(() => {}, {}, "a"); + assert.decreases(() => {}, {}, "a", "hello"); + + assert.decreasesBy(() => {}, {}, "a", 20); + assert.decreasesBy(() => {}, {}, "a", 20, "hello"); + + assert.doesNotDecrease(() => {}, {}, "a"); + assert.doesNotDecrease(() => {}, {}, "a", "hello"); + + assert.doesNotDecreaseBy(() => {}, {}, "a", 20); + assert.doesNotDecreaseBy(() => {}, {}, "a", 20, "hello"); + + assert.decreasesButNotBy(() => {}, {}, "a", 20); + assert.decreasesButNotBy(() => {}, {}, "a", 20, "hello"); + + assert.ifError(1); + + assert.isExtensible({}); + assert.isExtensible({}, "hello"); + + assert.isNotExtensible({}); + assert.isNotExtensible({}, "hello"); + + assert.isSealed({}); + assert.isSealed({}, "hello"); + + assert.isNotSealed({}); + assert.isNotSealed({}, "hello"); + + assert.isFrozen({}); + assert.isFrozen({}, "hello"); + + assert.isNotFrozen({}); + assert.isNotFrozen({}, "hello"); + + assert.isEmpty({}); + assert.isEmpty({}, "hello"); + } + + const { expect } = assertion; + + namespace expectTests { + expect(1); + expect(1, "hello"); + expect.fail(1, 2); + expect.fail(1, 2, "hello"); + expect.fail(1, 2, "hello", "+"); + expect(1).to.be.been.is.and.has.have.with.that.which.at.of.same.but.does.not.deep.nested.own.ordered.any.all.a("number"); + expect(1).to.be.a("number", "hello").and; + expect(1).to.be.an("array").and; + expect(1).to.be.an("array", "hello").and; + expect(1).to.include(1).and; + expect(1).to.include(1, "hello").and; + expect(1).but.includes(2).and; + expect(1).but.includes(2, "hello").and; + expect(1).to.contain(2).and; + expect(1).to.contain(2, "hello").and; + expect(1).but.contains(2).and; + expect(1).but.contains(2, "hello").and; + expect(1).to.ok.not.ok; + expect(1).to.be.true.but.false; + expect(1).to.be.false.but.true; + expect(1).to.be.null.and.null; + expect(1).to.be.undefined.and.true; + expect(1).to.be.NaN.and.null; + expect(1).to.exist.and.be.null; + expect(1).to.be.empty.and.true; + expect(1).to.be.arguments.and.a("number"); + expect(1).to.be.Arguments.and.false; + expect(1).to.be.equal(2).and; + expect(1).to.be.equal(2, "hello").and; + expect(1).but.equals(2).and; + expect(1).but.equals(2, "hello").and; + expect(1).to.eq(2).and; + expect(1).to.eq(2, "hello").and; + expect(1).but.eqls(2).and; + expect(1).but.eqls(2, "hello").and; + expect(1).to.eqlArray([1, 2, 3]).and; + expect(1).to.eqlArray([1, 2, 3], "hello").and; + expect(1).to.be.above(2).and; + expect(1).to.be.above(2, "hello").and; + expect(1).to.be.gt(2).and; + expect(1).to.be.gt(2, "hello").and; + expect(1).to.be.greaterThan(2).and; + expect(1).to.be.greaterThan(2, "hello").and; + expect(1).to.be.at.least(10).and; + expect(1).to.be.at.least(10, "hello").and; + expect(1).to.be.gte(10).and; + expect(1).to.be.gte(10, "hello").and; + expect(1).to.be.below(100).and; + expect(1).to.be.below(100, "hello").and; + expect(1).to.be.lt(10).and; + expect(1).to.be.lt(10, "hello").and; + expect(1).to.be.lessThan(10, "hello").and; + expect(1).to.be.at.most(10).and; + expect(1).to.be.at.most(10, "hello").and; + expect(1).to.be.lte(10).and; + expect(1).to.be.lte(10, "hello").and; + expect(1).to.be.within(1, 10).and; + expect(1).to.be.within(1, 10, "hello").and; + expect(1).to.be.instanceof(Number).and; + expect(1).to.be.instanceof(Number, "hello").and; + expect(1).to.be.instanceOf(Number).and; + expect(1).to.be.instanceOf(Number, "hello").and; + expect(1).to.have.property("a").and; + expect(1).to.have.property("a", 1).and; + expect(1).to.have.property("a", 1, "hello").and; + expect(1).to.have.ownProperty("a").and; + expect(1).to.have.ownProperty("a", 1).and; + expect(1).to.have.ownProperty("a", 1, "hello").and; + expect(1).to.haveOwnProperty("a").and; + expect(1).to.haveOwnProperty("a", 1).and; + expect(1).to.haveOwnProperty("a", 1, "hello").and; + expect(1).to.have.ownPropertyDescriptor("a").and; + expect(1).to.have.ownPropertyDescriptor("a", {}).and; + expect(1).to.have.ownPropertyDescriptor("a", {}, "hello").and; + expect(1).to.haveOwnPropertyDescriptor("a").and; + expect(1).to.haveOwnPropertyDescriptor("a", {}).and; + expect(1).to.haveOwnPropertyDescriptor("a", {}, "hello").and; + expect("a").to.have.length(1).and; + expect("a").to.have.length(1, "hello").and; + expect("a").to.have.lengthOf(1).and; + expect("a").to.have.lengthOf(1, "hello").and; + expect(1).to.match(/\d+/).and; + expect(1).to.match(/\d+/, "hello").and; + expect(1).to.have.string("1230").and; + expect(1).to.have.string("1230", "hello").and; + expect(1).to.have.key("a").and; + expect(1).to.have.key("a", "b").and; + expect(1).to.have.key(["a", "b"]).and; + expect(1).to.have.key({ a: 1, b: 2 }).and; + expect(1).to.have.keys("a").and; + expect(1).to.have.keys("a", "b").and; + expect(1).to.have.keys(["a", "b"]).and; + expect(1).to.have.keys({ a: 1, b: 2 }).and; + expect(() => {}).to.throw().and; + expect(() => {}).to.throw(Error).and; + expect(() => {}).to.throw(Error, "string").and; + expect(() => {}).to.throw(Error, "string", "hello").and; + expect(() => {}).to.throw(Error, /\d+/).and; + expect(() => {}).to.throw(Error, /\d+/, "hello").and; + expect(() => {}).but.throws().and; + expect(() => {}).but.throws(Error).and; + expect(() => {}).but.throws(Error, "string").and; + expect(() => {}).but.throws(Error, "string", "hello").and; + expect(() => {}).but.throws(Error, /\d+/).and; + expect(() => {}).but.throws(Error, /\d+/, "hello").and; + expect(1).to.respondTo("a").and; + expect(1).to.respondTo("a", "hello").and; + expect(1).to.respondsTo("a").and; + expect(1).to.respondsTo("a", "hello").and; + expect(1).itself.to.respondsTo("a").and; + expect(1).to.satisfy(() => true).and; + expect(1).to.satisfy(() => true, "hello").and; + expect(1).but.satisfies(() => true).and; + expect(1).but.satisfies(() => true, "hello").and; + expect(1).to.be.closeTo(2, 1).and; + expect(1).to.be.closeTo(2, 1, "hello").and; + expect(1).to.be.approximately(1, 2).and; + expect(1).to.be.approximately(1, 2, "hello").and; + expect(1).to.have.members([1, 2, 3]).and; + expect(1).to.have.members([1, 2, 3], "hello").and; + expect(1).to.be.oneOf([1, 2, 3]).and; + expect(1).to.be.oneOf([1, 2, 3], "hello").and; + expect(() => {}).to.change(() => {}).and; + expect(() => {}).to.change({}, "a").and; + expect(() => {}).to.change({}, "a", "hello").and; + expect(() => {}).but.changes(() => {}).and; + expect(() => {}).but.changes({}, "a").and; + expect(() => {}).but.changes({}, "a", "hello").and; + expect(() => {}).to.increase({}).and; + expect(() => {}).to.increase({}, "a").and; + expect(() => {}).to.increase({}, "a", "hello").and; + expect(() => {}).but.increases({}).and; + expect(() => {}).but.increases({}, "a").and; + expect(() => {}).but.increases({}, "a", "hello").and; + expect(() => {}).to.decrease({}).and; + expect(() => {}).to.decrease({}, "a").and; + expect(() => {}).to.decrease({}, "a", "hello").and; + expect(() => {}).but.decreases({}).and; + expect(() => {}).but.decreases({}, "a").and; + expect(() => {}).but.decreases({}, "a", "hello").and; + expect(() => {}).to.decreases({}).by(2).and; + expect(() => {}).to.decreases({}).by(2, "hello").and; + expect({}).to.be.extensible.and; + expect({}).to.be.sealed.and; + expect({}).to.be.frozen.and; + expect({}).to.be.finite.and; + + namespace mockTests { + const s1 = adone.shani.util.spy(); + const s2 = adone.shani.util.spy(); + + expect(s1).to.have.been.called; + expect(s1).to.have.been.calledOnce; + expect(s1).to.have.been.calledTwice; + expect(s1).to.have.been.calledThrice; + expect(s1).to.have.callCount(100); + expect(s1).to.have.been.calledBefore(s2); + expect(s1).to.have.been.calledAfter(s2); + expect(s1).to.have.been.calledImmediatelyAfter(s2); + expect(s1).to.have.been.calledImmediatelyBefore(s2); + expect(s1).to.have.been.calledOn({}); + expect(s1).to.have.been.calledOn({}); + expect(s1).to.have.been.calledWith(1, 2, 3); + expect(s1).to.have.been.calledWithExactly(1, 2, 3); + expect(s1).to.have.returned(1); + expect(s1).to.have.thrown({}); + } + } +} diff --git a/types/adone/test/glosses/promise.ts b/types/adone/test/glosses/promise.ts new file mode 100644 index 0000000000..c16d1a4852 --- /dev/null +++ b/types/adone/test/glosses/promise.ts @@ -0,0 +1,97 @@ +namespace promiseTests { + const { promise } = adone; + + namespace defer { + const a = promise.defer(); + a.promise.then((x) => 2); + a.resolve(2); + a.reject(3); + const b = promise.defer(); + b.resolve("3"); + b.reject(2); + b.promise.then((x: string) => x); + } + + namespace delay { + const a: Promise = promise.delay(10); + const b: Promise = promise.delay(10, 2); + promise.delay(20, "3").then((x: string) => x); + } + + namespace timeout { + promise.timeout(Promise.resolve(2), 100).then((x: number) => x); + } + + namespace nodeify { + promise.nodeify(Promise.resolve(2), (err: any, value: number) => value).then((x: number) => x); + promise.nodeify(Promise.resolve(2), () => 42).then((x: number) => x); + } + + namespace promisify { + type Callback = (err?: any, result?: T) => void; + namespace noargs { + const f = (cb: Callback) => { + cb(null, 32); + }; + promise.promisify(f)().then((x: number) => { }); + } + namespace nargs1 { + const f = (a: number, cb: Callback) => { + cb(null, 32); + }; + promise.promisify(f)(1).then((x: number) => { }); + } + + namespace nargs2 { + const f = (a: number, b: string, cb: Callback) => { + cb(null, 32); + }; + promise.promisify(f)(1, "1").then((x: number) => { }); + } + + namespace nargs3 { + const f = (a: number, b: string, c: number, cb: Callback) => { + cb(null, 32); + }; + promise.promisify(f)(1, "1", 1).then((x: number) => { }); + } + + namespace nargs4 { + const f = (a: number, b: string, c: number, d: string, cb: Callback) => { + cb(null, 32); + }; + promise.promisify(f)(1, "1", 1, "1").then((x: number) => { }); + } + + namespace nargs5 { + const f = (a: number, b: string, c: number, d: string, e: number, cb: Callback) => { + cb(null, 32); + }; + promise.promisify(f)(1, "1", 1, "1", 1).then((x: number) => { }); + } + + namespace moreargs { + const f = (a: number, b: string, c: number, d: string, e: number, f: string, cb: Callback) => { + cb(null, 32); + }; + promise.promisify(f)(1, 2, 3).then((x) => x); + } + + namespace options { + promise.promisify((cb: Callback) => cb(null, 42), {}); + promise.promisify((cb: Callback) => cb(null, 42), { context: {} }); + } + } + + namespace promisifyAll { + const a: object = promise.promisifyAll({}); + promise.promisifyAll({}, {}); + promise.promisifyAll({}, { context: {} }); + promise.promisifyAll({}, { filter: () => true }); + promise.promisifyAll({}, { suffix: "Async" }); + } + + namespace _finally { + promise.finally(Promise.resolve(2), () => 2).then((x: number) => {}); + } +} diff --git a/types/adone/test/glosses/shani-global.ts b/types/adone/test/glosses/shani-global.ts new file mode 100644 index 0000000000..b59dce4b6a --- /dev/null +++ b/types/adone/test/glosses/shani-global.ts @@ -0,0 +1,163 @@ +namespace shaniGlobalTests { + namespace describeTests { + describe("hello", () => {}); + + describe("hello", function () { + this.skip(); + this.timeout(10); + this.a; + }); + + describe("1", "2", "3", "4", "45", function () { + this.skip(); + this.timeout(10); + this.a; + }); + + describe("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", function () { + this.skip(); + this.timeout(10); + this.a; + }); + + context("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", function () { + this.skip(); + this.timeout(10); + this.a; + }); + } + + namespace itTests { + it("should be here", () => {}); + + it("should be here", function () { + this.timeout(100); + this.skip(); + this.a; + }); + + it("should be here", function (done: () => void) { + this.timeout(1000); + done(); + this.a; + }); + + it("hello", {}, () => {}); + + it("hello", { + skip: true + }, () => {}); + + it("hello", { + skip: () => true + }, () => {}); + + it("hello", { + timeout: () => 1202 + }, () => {}); + + it("hello", { + timeout: 1010 + }, () => {}); + + it("hello", { + before() {} + }, () => {}); + + it("hello", { + before: ["hello", () => {}] + }, () => {}); + + it("hello", { + after() {} + }, () => {}); + + it("hello", { + after: ["hello", () => {}] + }, () => {}); + + specify("hello", { + after: ["hello", () => {}] + }, () => {}); + } + + namespace beforeTests { + before(function() { + this.timeout(100); + this.a; + }); + + before("description", function () { + this.timeout(100); + this.a; + }); + + before("description", function (done) { + this.timeout(100); + done(); + this.a; + }); + } + + namespace afterTests { + after(function () { + this.timeout(10); + this.a; + }); + + after("description", function () { + this.timeout(10); + this.a; + }); + + after("description", function (done) { + this.timeout(10); + this.a; + }); + } + + namespace beforeEachTests { + beforeEach(function () { + this.timeout(100); + this.a; + }); + + beforeEach("hello", function () { + this.timeout(100); + this.a; + }); + + beforeEach("hello", function (done) { + this.timeout(100); + done(); + this.a; + }); + } + + namespace afterEachTests { + afterEach(function () { + this.timeout(100); + this.a; + }); + + afterEach("asd", function () { + this.timeout(100); + this.a; + }); + + afterEach("asd", function (done) { + this.timeout(100); + done(); + this.a; + }); + } + + expect(1).to.be.a("number"); + assert.equal(1, 1); + fakeClock.install().tick(100); + stub()(1, 2, 3); + expect(spy()).to.have.been.calledOnce; + match(2).and(match(2)); + mock().alwaysCalledOn({}); + request({}).expectBody(""); +} diff --git a/types/adone/test/glosses/shani.ts b/types/adone/test/glosses/shani.ts new file mode 100644 index 0000000000..1c09ef3837 --- /dev/null +++ b/types/adone/test/glosses/shani.ts @@ -0,0 +1,544 @@ +namespace shaniTests { + const { shani } = adone; + + namespace engineOptionsTests { + new shani.Engine(); + new shani.Engine({}); + new shani.Engine({ callGc: true }); + new shani.Engine({ defaultTimeout: 1000 }); + new shani.Engine({ defaultHookTimeout: 1000 }); + new shani.Engine({ transpilerOptions: {} }); + } + + namespace contextTests { + const e = new adone.shani.Engine(); + const c = e.context(); + + namespace describeTests { + c.describe("hello", () => {}); + + c.describe("hello", function () { + this.skip(); + this.timeout(10); + this.a; + }); + + c.describe("1", "2", "3", "4", "45", function () { + this.skip(); + this.timeout(10); + this.a; + }); + + c.describe("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", function () { + this.skip(); + this.timeout(10); + this.a; + }); + + c.context("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", function () { + this.skip(); + this.timeout(10); + this.a; + }); + } + + namespace itTests { + c.it("should be here", () => {}); + + c.it("should be here", function () { + this.timeout(100); + this.skip(); + this.a; + }); + + c.it("should be here", function (done) { + this.timeout(100); + this.skip(); + done(); + this.a; + }); + + c.it("hello", {}, () => { }); + + c.it("hello", { + skip: true + }, () => { }); + + c.it("hello", { + skip: () => true + }, () => { }); + + c.it("hello", { + timeout: () => 1202 + }, () => { }); + + c.it("hello", { + timeout: 1010 + }, () => { }); + + c.it("hello", { + before() { } + }, () => { }); + + c.it("hello", { + before: ["hello", () => { }] + }, () => { }); + + c.it("hello", { + after() { } + }, () => { }); + + c.it("hello", { + after: ["hello", () => { }] + }, () => { }); + + c.specify("hello", { + after: ["hello", () => { }] + }, () => { }); + } + + namespace beforeTests { + c.before(function () { + this.timeout(100); + this.a; + }); + + c.before("description", function () { + this.timeout(100); + this.a; + }); + + c.before("description", function (done) { + this.timeout(100); + done(); + this.a; + }); + } + + namespace afterTests { + c.after(function () { + this.timeout(10); + this.a; + }); + + c.after("description", function () { + this.timeout(10); + this.a; + }); + + c.after("description", function (done) { + this.timeout(10); + done(); + this.a; + }); + } + + namespace beforeEachTests { + c.beforeEach(function () { + this.timeout(100); + this.a; + }); + + c.beforeEach("hello", function () { + this.timeout(100); + this.a; + }); + + c.beforeEach("hello", function (done) { + this.timeout(100); + done(); + this.a; + }); + } + + namespace afterEachTests { + c.afterEach(function () { + this.timeout(100); + this.a; + }); + + c.afterEach("asd", function () { + this.timeout(100); + this.a; + }); + + c.afterEach("asd", function (done) { + this.timeout(100); + done(); + this.a; + }); + } + + namespace rootTests { + const { root } = c; + root.children[0]; + root.prepare().then((x) => { }); + root.addChild(root); + const check = (hook: adone.shani.I.Hook) => { + hook.run().then((x) => x); + hook.cause(); + hook.failed() === true; + hook.timeout() + 2; + hook.timeout(10).timeout(10).timeout() + 2; + }; + for (const hook of root.beforeHooks()) { + check(hook); + } + for (const hook of root.afterHooks()) { + check(hook); + } + for (const hook of root.beforeEachHooks()) { + check(hook); + } + for (const hook of root.afterEachHooks()) { + check(hook); + } + root.isInclusive() === true; + root.isExclusive() === false; + root.hasInclusive() === true; + root.skip().only().skip(); + const a: number | null = root.timeout(); + root.timeout(100).timeout(100); + root.level() + 2; + root.level(2).level() + 2; + root.chain().toLowerCase(); + root.blockChain()[0].blockChain()[0].addChild(root); + } + + namespace eventEmitterTests { + const a = c.start(); + a.on("enter block", ({ block }) => { + block.addChild(block); + }).on("exit block", ({ block }) => { + block.addChild(block); + }).on("start test", ({ block, test }) => { + block.addChild(test); + test.chain(); + }).on("end test", ({ block, test, meta }) => { + block.addChild(test); + test.chain(); + meta.err; + meta.elapsed + 2; + }).on("start before hook", ({ block, hook }) => { + block.addChild(block); + hook.desctiption; + }).on("end before hook", ({ block, hook, meta }) => { + block.addChild(block); + hook.desctiption; + meta.err; + meta.elapsed; + }).on("start after hook", ({ block, hook }) => { + block.addChild(block); + hook.desctiption; + }).on("end after hook", ({ block, hook, meta }) => { + block.addChild(block); + hook.desctiption; + meta.err; + meta.elapsed; + }).on("start before each hook", ({ block, hook }) => { + block.addChild(block); + hook.desctiption; + }).on("end before each hook", ({ block, hook, meta }) => { + block.addChild(block); + hook.desctiption; + meta.err; + meta.elapsed; + }).on("start after each hook", ({ block, hook }) => { + block.addChild(block); + hook.desctiption; + }).on("end after each hook", ({ block, hook, meta }) => { + block.addChild(block); + hook.desctiption; + meta.err; + meta.elapsed; + }).on("start before test hook", ({ block, hook }) => { + block.addChild(block); + hook.desctiption; + }).on("end before test hook", ({ block, hook, meta }) => { + block.addChild(block); + hook.desctiption; + meta.err; + meta.elapsed; + }).on("start after test hook", ({ block, hook }) => { + block.addChild(block); + hook.desctiption; + }).on("end after test hook", ({ block, hook, meta }) => { + block.addChild(block); + hook.desctiption; + meta.err; + meta.elapsed; + }).on("error", (err) => {}).on("done", () => {}).stop(); + } + } + + namespace utilTests { + const { util } = shani; + + namespace spyCallTests { + const call = util.spy().firstCall; + call.calledBefore(call) === true; + call.calledAfter(call) === true; + call.calledWithNew(call) === true; + call.thisValue; + call.args[0]; + call.exception; + call.returnValue; + call.calledOn({}) === true; + call.calledWith(1, 2, 3) === true; + call.calledWithExactly(1, 2, 3) === true; + call.calledWithMatch(1, 2, 3) === true; + call.notCalledWith(1, 2, 3) === true; + call.notCalledWithMatch(1, 2, 3) === true; + call.returned(1) === true; + call.threw() === true; + call.threw("12") === true; + call.threw({}) === true; + call.callArg(1); + call.callArgOn(1, {}); + call.callArgWith(1, 1, 2, 3); + call.callArgOnWith(1, {}, 1, 2, 3); + call.yield(1, 2, 3); + call.yieldOn({}, 1, 2, 3); + call.yieldToOn("a", {}, 1, 2, 3); + } + + namespace spyTests { + util.spy().alwaysCalledOn({}); + util.spy(() => { }).alwaysCalledOn({}); + const a: number = util.spy().callCount; + const s = util.spy(); + s.called === true; + s.notCalled === true; + s.calledOnce === true; + s.calledTwice === true; + s.calledThrice === true; + s.firstCall.args; + s.secondCall.args; + s.thirdCall.args; + s.lastCall.args; + s.thisValues[0]; + s.args[0][0]; + s.exceptions[0]; + s.returnValues[0]; + s(1, 2, 3); + s.calledBefore(s); + s.calledAfter(s); + s.calledImmediatelyAfter(s); + s.calledImmediatelyBefore(s); + s.calledWithNew() === true; + s.withArgs(1, 2, 3).firstCall.args; + s.alwaysCalledOn({}) === true; + s.alwaysCalledWith(1, 2, 3) === true; + s.alwaysCalledWithExactly(1, 2, 3) === true; + s.alwaysCalledWithMatch(1, 2, 3) === true; + s.neverCalledWith(1, 2, 3) === true; + s.neverCalledWithMatch(1, 2, 3) === true; + s.alwaysThrew() === true; + s.alwaysThrew("a") === true; + s.alwaysThrew({}) === true; + s.alwaysReturned({}) === true; + s.invokeCallback(1, 2, 3); + s.getCall(0).args; + s.getCalls()[0].args; + s.reset(); + s.printf("%s", "1").toLowerCase(); + s.restore(); + } + + namespace stubTests { + util.stub({}); + class A { + a() {} + } + util.stub(new A(), "a").resetHistory(); + const s = util.stub(); + s.resetBehavior(); + s.resetHistory(); + s.usingPromise({}).alwaysCalledOn(2); + s.returns({}).resetBehavior(); + s.returnsArg(1).resetBehavior(); + s.returnsThis().resetBehavior(); + s.resolves().resetBehavior(); + s.resolves(1).resetBehavior(); + s.throws().resetBehavior(); + s.throws("1").resetBehavior(); + s.throwsArg(1).resetBehavior(); + s.throwsException().resetBehavior(); + s.throwsException("1").resetBehavior(); + s.throwsException({}).resetBehavior(); + s.rejects().resetBehavior(); + s.rejects("string").resetBehavior(); + s.rejects(1).resetBehavior(); + s.callsArg(1).resetBehavior(); + s.callThrough().resetBehavior(); + s.callsArgOn(1, {}).resetBehavior(); + s.callsArgOnWith(1, {}, 123).resetBehavior(); + s.callsArgAsync(1).resetBehavior(); + s.callsArgOnAsync(1, {}).resetBehavior(); + s.callsArgOnWithAsync(1, {}, 1, 2, 3).resetBehavior(); + s.callsFake(() => { }).resetBehavior(); + s.get(() => { }).resetBehavior(); + s.set((v) => 1).resetBehavior(); + s.onCall(1).resetBehavior(); + s.onFirstCall().resetBehavior(); + s.onSecondCall().resetBehavior(); + s.onThirdCall().resetBehavior(); + s.value(1).resetBehavior(); + s.yields(1, 2, 3).resetBehavior(); + s.yieldsOn({}, 1, 2).resetBehavior(); + s.yieldsRight(1, 2, 3).resetBehavior(); + s.yieldsTo("a", 1, 2, 3).resetBehavior(); + s.yieldsToOn("a", {}, 1, 2, 3).resetBehavior(); + s.yieldsAsync(1, 2, 3).resetBehavior(); + s.yieldsOnAsync({}, 1, 2, 3).resetBehavior(); + s.yieldsToAsync("a", 1, 2, 3).resetBehavior(); + s.yieldsToOnAsync("1", {}, 1, 2, 3).resetBehavior(); + s.withArgs(1, 2, 3).resetBehavior(); + } + + namespace expectationTests { + util.expectation.create(""); + const e = util.expectation.create(); + e.atLeast(1).never(); + e.atMost(2).never(); + e.never().never(); + e.once().never(); + e.twice().never(); + e.thrice().never(); + e.exactly(1).never(); + e.withArgs(1, 2, 3).never(); + e.withExactArgs(1, 2, 3).never(); + e.on({}).never(); + e.verify().never(); + e.restore(); + } + + namespace mockTests { + util.mock().never(); + util.mock({}).expects("").restore(); + util.mock({}).verify(); + } + + namespace assertTests { + util.assert.failException; + util.assert.fail(); + util.assert.fail("1"); + util.assert.pass(1); + const s = util.spy(); + util.assert.notCalled(s); + util.assert.called(s); + util.assert.calledOnce(s); + util.assert.calledTwice(s); + util.assert.calledThrice(s); + util.assert.callCount(s, 10); + util.assert.callOrder(s, s, s, s); + util.assert.calledOn(s, {}); + util.assert.calledOn(s, {}); + util.assert.alwaysCalledOn(s, {}); + util.assert.calledWith(s, {}); + util.assert.neverCalledWith(s, {}); + util.assert.calledWithExactly(s, {}); + util.assert.alwaysCalledWithExactly(s, {}); + util.assert.calledWithMatch(s, {}); + util.assert.alwaysCalledWithMatch(s, {}); + util.assert.neverCalledWithMatch(s, {}); + util.assert.threw(s); + util.assert.threw(s, "a"); + util.assert.threw(s, {}); + util.assert.alwaysThrew(s); + util.assert.alwaysThrew(s, ""); + util.assert.alwaysThrew(s, {}); + util.assert.expose({}); + util.assert.expose({}, { includeFail: true }); + util.assert.expose({}, { prefix: "a" }); + } + + namespace matchTests { + util.match(1).and(util.match(1)); + util.match("1").and(util.match(1)); + util.match(/1/).and(util.match(1)); + util.match({}).and(util.match(1)); + util.match((v: any) => true).and(util.match(1)); + util.match((v: any) => true, "a").and(util.match(1)); + util.match.any.and; + util.match.defined.and; + util.match.truthy.and; + util.match.falsy.and; + util.match.bool.and; + util.match.number.and; + util.match.string.and; + util.match.object.and; + util.match.func.and; + util.match.map.contains(new Map()); + util.match.map.deepEquals(new Map()); + util.match.set.contains(new Set()); + util.match.array.contains([]); + util.match.array.deepEquals([]); + util.match.array.endsWith([]); + util.match.array.startsWith([]); + util.match.regexp.and; + util.match.date.and; + util.match.symbol.and; + util.match.same({}).and; + util.match.typeOf("string").and; + util.match.instanceOf({}).and; + util.match.has("a").and; + util.match.has("a", {}).and; + util.match.hasOwn("a").and; + util.match.hasOwn("a", {}).and; + } + + namespace sandboxTests { + util.sandbox.create(); + util.sandbox.create({}); + util.sandbox.create({ injectInto: {} }); + util.sandbox.create({ properties: ["a"] }); + const s = util.sandbox.create(); + s.assert.alwaysCalledOn(s.spy(), {}); + s.spy().args; + s.stub().args; + s.mock().args; + s.restore(); + s.reset(); + s.resetHistory(); + s.resetBehavior(); + s.usingPromise({}).reset(); + s.verify(); + s.verifyAndRestore(); + } + } + + namespace requestTests { + const r = request({}); + r.get("/").head("/").post("/").put("/").options("/"); + r.attach("fname", "hello"); + r.attach("fname", "hello", {}); + r.attach("fname", "hello", { type: "application/javascript" }); + r.attach("fname", "hello", { filename: "a.js" }); + r.field("a", "basd"); + r.send("asd"); + r.setHeader("Cookie", "key=value"); + r.auth("user", "pass"); + r.expect(() => true); + r.expect(async () => true); + r.expect((response) => { + assert.equal(response.statusCode, 200); + return response.body.length === 0; + }); + r.expectStatus(200); + r.expectStatusMessage("OK"); + r.expectBody("body"); + r.expectBody(Buffer.from("body")); + r.expectBody(/body/); + r.expectBody({ a: 1 }); + r.expectBody("body", {}); + r.expectBody("body", { decompress: true }); + r.expectEmptyBody(); + r.expectHeader("Cookie", "key=value"); + r.expectHeaderExists("Cookie"); + r.then((x: adone.shani.util.I.Response) => { + x.statusCode === 200; + x.body.fill(0); + }); + } +} diff --git a/types/adone/test/glosses/utils.ts b/types/adone/test/glosses/utils.ts index c0f119cb6e..9372fb4b30 100644 --- a/types/adone/test/glosses/utils.ts +++ b/types/adone/test/glosses/utils.ts @@ -580,6 +580,7 @@ namespace utilTests { } namespace install { + util.fakeClock.install(); util.fakeClock.install(100); util.fakeClock.install(new Date()); util.fakeClock.install({}); diff --git a/types/adone/test/index.ts b/types/adone/test/index.ts index 7cc5034602..a6cd5093f3 100644 --- a/types/adone/test/index.ts +++ b/types/adone/test/index.ts @@ -66,4 +66,6 @@ namespace AdoneRootTests { { const a: Buffer | string = adone.loadAsset("asset"); } { const a: object = adone.require("path"); } { const a: object = adone.package; } + { const a: typeof adone.assertion.assert = adone.assert; } + { const a: typeof adone.assertion.expect = adone.expect; } } diff --git a/types/adone/tsconfig.json b/types/adone/tsconfig.json index 6fe0c82586..ad90d2b5d7 100644 --- a/types/adone/tsconfig.json +++ b/types/adone/tsconfig.json @@ -23,12 +23,20 @@ "glosses/math.d.ts", "glosses/std.d.ts", "glosses/utils.d.ts", + "glosses/assertion.d.ts", + "glosses/promise.d.ts", + "glosses/shani.d.ts", + "glosses/shani-global.d.ts", "adone-tests.ts", "test/index.ts", "test/index-import.ts", "test/glosses/common.ts", "test/glosses/math.ts", "test/glosses/std.ts", - "test/glosses/utils.ts" + "test/glosses/utils.ts", + "test/glosses/assertion.ts", + "test/glosses/promise.ts", + "test/glosses/shani.ts", + "test/glosses/shani-global.ts" ] } diff --git a/types/adone/tslint.json b/types/adone/tslint.json index 5f7dd6afd7..0a3d7850f9 100644 --- a/types/adone/tslint.json +++ b/types/adone/tslint.json @@ -3,6 +3,8 @@ "rules": { "no-namespace": false, "strict-export-declare-modifiers": false, - "no-single-declare-module": false + "no-single-declare-module": false, + "unified-signatures": false, + "space-before-function-paren": false } } \ No newline at end of file