assertron 7.1.2 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +61 -46
  3. package/package.json +62 -24
  4. package/src/assert-order/AssertOrder.spec.ts +10 -12
  5. package/src/assert-order/AssertOrder.ts +8 -8
  6. package/src/assert-order/InvalidOrder.ts +7 -12
  7. package/src/assert-order/StateMachine.ts +26 -31
  8. package/src/assert-order/index.ts +3 -1
  9. package/src/assert-order/internalInterfaces.ts +3 -3
  10. package/src/assert-order/types.ts +7 -0
  11. package/src/assertron/assertron.spec.ts +2 -4
  12. package/src/assertron/assertron.ts +13 -14
  13. package/src/assertron/falsy.spec.ts +2 -3
  14. package/src/assertron/falsy.ts +2 -6
  15. package/src/assertron/pathEqual.spec.ts +2 -3
  16. package/src/assertron/pathEqual.ts +4 -7
  17. package/src/assertron/rejects.spec.ts +7 -8
  18. package/src/assertron/rejects.ts +3 -11
  19. package/src/assertron/repeat.spec.ts +8 -10
  20. package/src/assertron/repeat.ts +4 -9
  21. package/src/assertron/resolves.spec.ts +3 -4
  22. package/src/assertron/resolves.ts +3 -13
  23. package/src/assertron/satisfies.spec.ts +57 -26
  24. package/src/assertron/satisfies.ts +23 -10
  25. package/src/assertron/throws.spec.ts +58 -39
  26. package/src/assertron/throws.ts +30 -54
  27. package/src/assertron/truthy.spec.ts +2 -3
  28. package/src/assertron/truthy.ts +2 -3
  29. package/src/errors.ts +22 -0
  30. package/src/index.ts +2 -1
  31. package/src/testUtils.ts +16 -13
  32. package/src/{errors/interfaces.ts → types.ts} +1 -1
  33. package/src/utils/index.ts +12 -0
  34. package/src/utils/isErrorConstructor.ts +5 -0
  35. package/src/utils/notEqualMessage.ts +4 -0
  36. package/src/{errors → utils}/notSatisfiedMessage.spec.ts +0 -0
  37. package/src/{errors/NotSatisfied.ts → utils/notSatisfiedMessage.ts} +1 -1
  38. package/src/utils/notThrownMessage.ts +5 -0
  39. package/src/utils/promiseMessages.ts +12 -0
  40. package/src/{errors → utils}/unexpectedErrorMessage.ts +4 -3
  41. package/dist-es2015/assert-order/AssertOrder.d.ts +0 -40
  42. package/dist-es2015/assert-order/AssertOrder.js +0 -132
  43. package/dist-es2015/assert-order/AssertOrder.js.map +0 -1
  44. package/dist-es2015/assert-order/InvalidOrder.d.ts +0 -8
  45. package/dist-es2015/assert-order/InvalidOrder.js +0 -31
  46. package/dist-es2015/assert-order/InvalidOrder.js.map +0 -1
  47. package/dist-es2015/assert-order/StateMachine.d.ts +0 -23
  48. package/dist-es2015/assert-order/StateMachine.js +0 -106
  49. package/dist-es2015/assert-order/StateMachine.js.map +0 -1
  50. package/dist-es2015/assert-order/index.d.ts +0 -2
  51. package/dist-es2015/assert-order/index.js +0 -2
  52. package/dist-es2015/assert-order/index.js.map +0 -1
  53. package/dist-es2015/assert-order/interfaces.d.ts +0 -7
  54. package/dist-es2015/assert-order/interfaces.js +0 -1
  55. package/dist-es2015/assert-order/interfaces.js.map +0 -1
  56. package/dist-es2015/assertron/assertron.d.ts +0 -20
  57. package/dist-es2015/assertron/assertron.js +0 -28
  58. package/dist-es2015/assertron/assertron.js.map +0 -1
  59. package/dist-es2015/assertron/falsy.d.ts +0 -1
  60. package/dist-es2015/assertron/falsy.js +0 -6
  61. package/dist-es2015/assertron/falsy.js.map +0 -1
  62. package/dist-es2015/assertron/index.d.ts +0 -1
  63. package/dist-es2015/assertron/index.js +0 -2
  64. package/dist-es2015/assertron/index.js.map +0 -1
  65. package/dist-es2015/assertron/pathEqual.d.ts +0 -1
  66. package/dist-es2015/assertron/pathEqual.js +0 -8
  67. package/dist-es2015/assertron/pathEqual.js.map +0 -1
  68. package/dist-es2015/assertron/rejects.d.ts +0 -1
  69. package/dist-es2015/assertron/rejects.js +0 -10
  70. package/dist-es2015/assertron/rejects.js.map +0 -1
  71. package/dist-es2015/assertron/repeat.d.ts +0 -11
  72. package/dist-es2015/assertron/repeat.js +0 -35
  73. package/dist-es2015/assertron/repeat.js.map +0 -1
  74. package/dist-es2015/assertron/resolves.d.ts +0 -1
  75. package/dist-es2015/assertron/resolves.js +0 -12
  76. package/dist-es2015/assertron/resolves.js.map +0 -1
  77. package/dist-es2015/assertron/satisfies.d.ts +0 -5
  78. package/dist-es2015/assertron/satisfies.js +0 -14
  79. package/dist-es2015/assertron/satisfies.js.map +0 -1
  80. package/dist-es2015/assertron/throws.d.ts +0 -5
  81. package/dist-es2015/assertron/throws.js +0 -55
  82. package/dist-es2015/assertron/throws.js.map +0 -1
  83. package/dist-es2015/assertron/truthy.d.ts +0 -1
  84. package/dist-es2015/assertron/truthy.js +0 -6
  85. package/dist-es2015/assertron/truthy.js.map +0 -1
  86. package/dist-es2015/errors/NotSatisfied.d.ts +0 -2
  87. package/dist-es2015/errors/NotSatisfied.js +0 -23
  88. package/dist-es2015/errors/NotSatisfied.js.map +0 -1
  89. package/dist-es2015/errors/index.d.ts +0 -7
  90. package/dist-es2015/errors/index.js +0 -7
  91. package/dist-es2015/errors/index.js.map +0 -1
  92. package/dist-es2015/errors/interfaces.d.ts +0 -2
  93. package/dist-es2015/errors/interfaces.js +0 -1
  94. package/dist-es2015/errors/interfaces.js.map +0 -1
  95. package/dist-es2015/errors/notEqualMessage.d.ts +0 -1
  96. package/dist-es2015/errors/notEqualMessage.js +0 -4
  97. package/dist-es2015/errors/notEqualMessage.js.map +0 -1
  98. package/dist-es2015/errors/notRejectedMessage.d.ts +0 -1
  99. package/dist-es2015/errors/notRejectedMessage.js +0 -4
  100. package/dist-es2015/errors/notRejectedMessage.js.map +0 -1
  101. package/dist-es2015/errors/notThrownMessage.d.ts +0 -1
  102. package/dist-es2015/errors/notThrownMessage.js +0 -4
  103. package/dist-es2015/errors/notThrownMessage.js.map +0 -1
  104. package/dist-es2015/errors/returnNotRejectedMessage.d.ts +0 -1
  105. package/dist-es2015/errors/returnNotRejectedMessage.js +0 -4
  106. package/dist-es2015/errors/returnNotRejectedMessage.js.map +0 -1
  107. package/dist-es2015/errors/unexpectedErrorMessage.d.ts +0 -2
  108. package/dist-es2015/errors/unexpectedErrorMessage.js +0 -6
  109. package/dist-es2015/errors/unexpectedErrorMessage.js.map +0 -1
  110. package/dist-es2015/errors/util.d.ts +0 -2
  111. package/dist-es2015/errors/util.js +0 -4
  112. package/dist-es2015/errors/util.js.map +0 -1
  113. package/dist-es2015/index.d.ts +0 -4
  114. package/dist-es2015/index.js +0 -5
  115. package/dist-es2015/index.js.map +0 -1
  116. package/dist-es5/assert-order/AssertOrder.d.ts +0 -40
  117. package/dist-es5/assert-order/AssertOrder.js +0 -147
  118. package/dist-es5/assert-order/AssertOrder.js.map +0 -1
  119. package/dist-es5/assert-order/InvalidOrder.d.ts +0 -8
  120. package/dist-es5/assert-order/InvalidOrder.js +0 -58
  121. package/dist-es5/assert-order/InvalidOrder.js.map +0 -1
  122. package/dist-es5/assert-order/StateMachine.d.ts +0 -23
  123. package/dist-es5/assert-order/StateMachine.js +0 -115
  124. package/dist-es5/assert-order/StateMachine.js.map +0 -1
  125. package/dist-es5/assert-order/index.d.ts +0 -2
  126. package/dist-es5/assert-order/index.js +0 -7
  127. package/dist-es5/assert-order/index.js.map +0 -1
  128. package/dist-es5/assert-order/interfaces.d.ts +0 -7
  129. package/dist-es5/assert-order/interfaces.js +0 -3
  130. package/dist-es5/assert-order/interfaces.js.map +0 -1
  131. package/dist-es5/assertron/assertron.d.ts +0 -20
  132. package/dist-es5/assertron/assertron.js +0 -33
  133. package/dist-es5/assertron/assertron.js.map +0 -1
  134. package/dist-es5/assertron/falsy.d.ts +0 -1
  135. package/dist-es5/assertron/falsy.js +0 -12
  136. package/dist-es5/assertron/falsy.js.map +0 -1
  137. package/dist-es5/assertron/index.d.ts +0 -1
  138. package/dist-es5/assertron/index.js +0 -7
  139. package/dist-es5/assertron/index.js.map +0 -1
  140. package/dist-es5/assertron/pathEqual.d.ts +0 -1
  141. package/dist-es5/assertron/pathEqual.js +0 -14
  142. package/dist-es5/assertron/pathEqual.js.map +0 -1
  143. package/dist-es5/assertron/rejects.d.ts +0 -1
  144. package/dist-es5/assertron/rejects.js +0 -16
  145. package/dist-es5/assertron/rejects.js.map +0 -1
  146. package/dist-es5/assertron/repeat.d.ts +0 -11
  147. package/dist-es5/assertron/repeat.js +0 -58
  148. package/dist-es5/assertron/repeat.js.map +0 -1
  149. package/dist-es5/assertron/resolves.d.ts +0 -1
  150. package/dist-es5/assertron/resolves.js +0 -18
  151. package/dist-es5/assertron/resolves.js.map +0 -1
  152. package/dist-es5/assertron/satisfies.d.ts +0 -5
  153. package/dist-es5/assertron/satisfies.js +0 -20
  154. package/dist-es5/assertron/satisfies.js.map +0 -1
  155. package/dist-es5/assertron/throws.d.ts +0 -5
  156. package/dist-es5/assertron/throws.js +0 -61
  157. package/dist-es5/assertron/throws.js.map +0 -1
  158. package/dist-es5/assertron/truthy.d.ts +0 -1
  159. package/dist-es5/assertron/truthy.js +0 -12
  160. package/dist-es5/assertron/truthy.js.map +0 -1
  161. package/dist-es5/errors/NotSatisfied.d.ts +0 -2
  162. package/dist-es5/errors/NotSatisfied.js +0 -26
  163. package/dist-es5/errors/NotSatisfied.js.map +0 -1
  164. package/dist-es5/errors/index.d.ts +0 -7
  165. package/dist-es5/errors/index.js +0 -12
  166. package/dist-es5/errors/index.js.map +0 -1
  167. package/dist-es5/errors/interfaces.d.ts +0 -2
  168. package/dist-es5/errors/interfaces.js +0 -3
  169. package/dist-es5/errors/interfaces.js.map +0 -1
  170. package/dist-es5/errors/notEqualMessage.d.ts +0 -1
  171. package/dist-es5/errors/notEqualMessage.js +0 -7
  172. package/dist-es5/errors/notEqualMessage.js.map +0 -1
  173. package/dist-es5/errors/notRejectedMessage.d.ts +0 -1
  174. package/dist-es5/errors/notRejectedMessage.js +0 -7
  175. package/dist-es5/errors/notRejectedMessage.js.map +0 -1
  176. package/dist-es5/errors/notThrownMessage.d.ts +0 -1
  177. package/dist-es5/errors/notThrownMessage.js +0 -7
  178. package/dist-es5/errors/notThrownMessage.js.map +0 -1
  179. package/dist-es5/errors/returnNotRejectedMessage.d.ts +0 -1
  180. package/dist-es5/errors/returnNotRejectedMessage.js +0 -7
  181. package/dist-es5/errors/returnNotRejectedMessage.js.map +0 -1
  182. package/dist-es5/errors/unexpectedErrorMessage.d.ts +0 -2
  183. package/dist-es5/errors/unexpectedErrorMessage.js +0 -9
  184. package/dist-es5/errors/unexpectedErrorMessage.js.map +0 -1
  185. package/dist-es5/errors/util.d.ts +0 -2
  186. package/dist-es5/errors/util.js +0 -7
  187. package/dist-es5/errors/util.js.map +0 -1
  188. package/dist-es5/index.d.ts +0 -4
  189. package/dist-es5/index.js +0 -10
  190. package/dist-es5/index.js.map +0 -1
  191. package/src/assert-order/interfaces.ts +0 -7
  192. package/src/errors/index.ts +0 -7
  193. package/src/errors/notEqualMessage.ts +0 -3
  194. package/src/errors/notRejectedMessage.ts +0 -3
  195. package/src/errors/notThrownMessage.ts +0 -3
  196. package/src/errors/returnNotRejectedMessage.ts +0 -3
  197. package/src/errors/util.ts +0 -5
@@ -1,20 +1,18 @@
1
- import AssertionError from 'assertion-error';
2
- import { falsy } from './falsy';
3
- import { pathEqual } from './pathEqual';
4
- import { rejects } from './rejects';
5
- import { repeat } from './repeat';
6
- import { resolves } from './resolves';
7
- import { satisfies } from './satisfies';
8
- import { throws } from './throws';
9
- import { truthy } from './truthy';
1
+ import { AssertionError } from '../errors'
2
+ import { notEqualMessage } from '../utils'
3
+ import { falsy } from './falsy'
4
+ import { pathEqual } from './pathEqual'
5
+ import { rejects } from './rejects'
6
+ import { repeat } from './repeat'
7
+ import { resolves } from './resolves'
8
+ import { satisfies } from './satisfies'
9
+ import { throws } from './throws'
10
+ import { truthy } from './truthy'
10
11
 
11
12
  export const assertron = {
12
13
  false(value: any) {
13
14
  if (value !== false)
14
- throw new AssertionError(
15
- `Expected value to equal false, but received ${value}`,
16
- { value },
17
- assertron.false)
15
+ throw new AssertionError(notEqualMessage(value, false), { ssf: assertron.false })
18
16
  },
19
17
  falsy,
20
18
  pathEqual,
@@ -24,7 +22,8 @@ export const assertron = {
24
22
  satisfies,
25
23
  throws,
26
24
  true(value: any) {
27
- if (value !== true) throw new AssertionError(`Expected value to equal true, but received ${value}`, { value }, assertron.true)
25
+ if (value !== true)
26
+ throw new AssertionError(notEqualMessage(value, true), { ssf: assertron.true })
28
27
  },
29
28
  truthy
30
29
  }
@@ -1,6 +1,5 @@
1
- import a from '..';
2
- import AssertionError from 'assertion-error'
3
- import { assertThrows, noStackTraceFor } from '../testUtils';
1
+ import a, { AssertionError } from '..'
2
+ import { assertThrows, noStackTraceFor } from '../testUtils'
4
3
 
5
4
  test('non-false statement throws', () => {
6
5
  assertThrows(() => a.falsy(true), AssertionError)
@@ -1,10 +1,6 @@
1
- import AssertionError from 'assertion-error'
1
+ import { AssertionError } from '../errors'
2
2
 
3
3
  export function falsy(value: any) {
4
4
  if (value)
5
- throw new AssertionError(
6
- `Expected value to be falsy, but received ${value}`,
7
- { value },
8
- falsy
9
- )
5
+ throw new AssertionError(`Expected value to be falsy, but received ${value}`, { ssf: falsy })
10
6
  }
@@ -1,6 +1,5 @@
1
- import AssertionError from 'assertion-error';
2
- import assertron from '..';
3
- import { assertThrows, noStackTraceFor } from '../testUtils';
1
+ import assertron, { AssertionError } from '..'
2
+ import { assertThrows, noStackTraceFor } from '../testUtils'
4
3
 
5
4
  test('path with same style passes', () => {
6
5
  assertron.pathEqual('a', 'a')
@@ -1,11 +1,8 @@
1
- import AssertionError from 'assertion-error';
2
- import { pathEqual as isPathEqual } from 'path-equal';
3
- import { notEqualMessage } from '../errors';
1
+ import { pathEqual as isPathEqual } from 'path-equal'
2
+ import { AssertionError } from '../errors'
3
+ import { notEqualMessage } from '../utils'
4
4
 
5
5
  export function pathEqual(actual: string, expected: string) {
6
6
  if (!isPathEqual(actual, expected))
7
- throw new AssertionError(
8
- notEqualMessage(actual, expected),
9
- { actual, expected },
10
- pathEqual)
7
+ throw new AssertionError(notEqualMessage(actual, expected), { ssf: pathEqual })
11
8
  }
@@ -1,7 +1,6 @@
1
- import t from 'assert';
2
- import AssertionError from 'assertion-error';
3
- import a from '..';
4
- import { assertAsyncThrows, noStackTraceFor } from '../testUtils';
1
+ import t from 'assert'
2
+ import a from '..'
3
+ import { assertAsyncThrows, noStackTraceFor } from '../testUtils'
5
4
 
6
5
  test('pass on rejected promise', async () => {
7
6
  await a.rejects(Promise.reject(1))
@@ -12,22 +11,22 @@ test('throws on resolved string promise', async () => {
12
11
  t.strictEqual(err.message, `Expected promise to reject, but it resolves with 'abc'`)
13
12
  })
14
13
 
15
- test('throws on resovled boolean promise', async () => {
14
+ test('throws on resolved boolean promise', async () => {
16
15
  const err = await a.throws(a.rejects(Promise.resolve(true)))
17
16
  t.strictEqual(err.message, `Expected promise to reject, but it resolves with true`)
18
17
  })
19
18
 
20
- test('throws on resovled object promise', async () => {
19
+ test('throws on resolved object promise', async () => {
21
20
  const err = await a.throws(a.rejects(Promise.resolve(2)))
22
21
  t.strictEqual(err.message, `Expected promise to reject, but it resolves with 2`)
23
22
  })
24
23
 
25
- test('throws on resovled object promise', async () => {
24
+ test('throws on resolved object promise', async () => {
26
25
  const err = await a.throws(a.rejects(Promise.resolve({ a: 1 })))
27
26
  t.strictEqual(err.message, `Expected promise to reject, but it resolves with { a: 1 }`)
28
27
  })
29
28
 
30
29
  test('does not contain internal stack trace', async () => {
31
- const err = await assertAsyncThrows(() => a.rejects(Promise.resolve({ a: 1 })), AssertionError)
30
+ const err = await assertAsyncThrows(() => a.rejects(Promise.resolve({ a: 1 })))
32
31
  noStackTraceFor('rejects.ts', err)
33
32
  })
@@ -1,17 +1,9 @@
1
- import { tersify } from 'tersify';
2
- import AssertionError from 'assertion-error';
1
+ import { AssertionError } from '../errors'
2
+ import { notRejectedMessage } from '../utils'
3
3
 
4
4
  export function rejects(promise: Promise<any>) {
5
5
  return promise.then(
6
- value => {
7
- throw new AssertionError(
8
- `Expected promise to reject, but it resolves with ${
9
- typeof value === 'string' ?
10
- `'${value}'` :
11
- tersify(value, { maxLength: Infinity })}`,
12
- { value },
13
- rejects)
14
- },
6
+ value => { throw new AssertionError(notRejectedMessage(value), { ssf: rejects }) },
15
7
  () => { }
16
8
  )
17
9
  }
@@ -1,5 +1,4 @@
1
- import a from '..'
2
- import { FailOnOccurance } from './repeat';
1
+ import a, { FailOnOccurrence } from '..'
3
2
 
4
3
  test('repeat function n times', () => {
5
4
  let count = 0
@@ -11,7 +10,7 @@ test('repeat function n times', () => {
11
10
  test('repeat async function n times sequentially', async () => {
12
11
  let count = 0
13
12
  let actual = ''
14
- let aa = await a.repeat(() => new Promise<string>(a => {
13
+ const aa = await a.repeat(() => new Promise<string>(a => {
15
14
  setTimeout(() => {
16
15
  ++count
17
16
  actual += String(count)
@@ -26,24 +25,23 @@ test('repeat async function n times sequentially', async () => {
26
25
  test('error is captured as inner error and indicate which call failed', () => {
27
26
  let count = 0
28
27
  const err = a.throws(() => a.repeat(() => {
29
- ++count
30
- if (count === 5) throw new Error('failed')
31
- }, 10), FailOnOccurance)
28
+ if (++count === 5) throw new Error('failed')
29
+ }, 10), FailOnOccurrence)
32
30
 
33
- expect(err.occurance).toBe(5)
31
+ expect(err.occurrence).toBe(5)
34
32
  expect(err.error.message).toBe('failed')
35
33
  })
36
34
 
37
35
  test('rejected error is captured as inner error and indicate which call failed', async () => {
38
36
  let count = 0
39
- let err = await a.throws(a.repeat(() => new Promise((a, r) => {
37
+ const err = await a.throws(a.repeat(() => new Promise<void>((a, r) => {
40
38
  setTimeout(() => {
41
39
  ++count
42
40
  if (count === 5) r(new Error('failed'))
43
41
  else a()
44
42
  }, Math.random() * 10)
45
- }), 10), FailOnOccurance)
43
+ }), 10), FailOnOccurrence)
46
44
 
47
- expect(err.occurance).toBe(5)
45
+ expect(err.occurrence).toBe(5)
48
46
  expect(err.error.message).toBe('failed')
49
47
  })
@@ -1,5 +1,5 @@
1
1
  import isPromise from 'is-promise';
2
- import AssertionError from 'assertion-error'
2
+ import { FailOnOccurrence } from '../errors';
3
3
 
4
4
  /**
5
5
  * Repeat the specified function n times and return the last result.
@@ -17,7 +17,7 @@ function repeatRecur<R>(fn: () => R | (() => Promise<R>), i: number, times: numb
17
17
  if (isPromise(result)) {
18
18
  return result.then(
19
19
  () => repeatRecur(fn, i + 1, times),
20
- (e) => { throw new FailOnOccurance(i, e) }
20
+ (e) => { throw new FailOnOccurrence(i, e, { ssf: repeat }) }
21
21
  ) as any
22
22
  }
23
23
  else {
@@ -25,13 +25,8 @@ function repeatRecur<R>(fn: () => R | (() => Promise<R>), i: number, times: numb
25
25
  }
26
26
  }
27
27
  catch (e) {
28
- if (e instanceof FailOnOccurance) throw e
29
- throw new FailOnOccurance(i, e)
28
+ if (e instanceof FailOnOccurrence) throw e
29
+ throw new FailOnOccurrence(i, e, { ssf: repeat })
30
30
  }
31
31
  }
32
32
 
33
- export class FailOnOccurance extends AssertionError {
34
- constructor(public occurance: number, public error: any) {
35
- super(`Failed on ${occurance} occurance`)
36
- }
37
- }
@@ -1,7 +1,6 @@
1
- import t from 'assert';
2
- import a from '..';
3
- import AssertionError from 'assertion-error';
4
- import { assertAsyncThrows, noStackTraceFor } from '../testUtils';
1
+ import t from 'assert'
2
+ import a, { AssertionError } from '..'
3
+ import { assertAsyncThrows, noStackTraceFor } from '../testUtils'
5
4
 
6
5
 
7
6
  test('pass on resolved promise', async () => {
@@ -1,19 +1,9 @@
1
- import { tersify } from 'tersify';
2
- import AssertionError from 'assertion-error';
1
+ import { AssertionError } from '../errors'
2
+ import { notResolvedMessage } from '../utils'
3
3
 
4
4
  export function resolves(promise: Promise<any>) {
5
5
  return promise.then(
6
6
  () => { },
7
- error => {
8
- throw new AssertionError(`Expected promise to resolve, but it rejects with ${
9
- typeof error === 'string' ?
10
- `'${error}'` :
11
- error instanceof Error ?
12
- error :
13
- tersify(error, { maxLength: Infinity })}`,
14
- { error },
15
- resolves
16
- )
17
- }
7
+ error => { throw new AssertionError(notResolvedMessage(error), { ssf: resolves }) }
18
8
  )
19
9
  }
@@ -1,20 +1,34 @@
1
- import AssertionError from 'assertion-error';
2
- import { every } from 'satisfier';
3
- import a from '..';
4
- import { assertThrows, noStackTraceFor } from '../testUtils';
5
-
6
- test('primitive types will pass', () => {
7
- a.satisfies(1, 1)
8
- a.satisfies('a', 'a')
9
- a.satisfies(true, true)
10
- })
11
-
12
- test('primitive types shows value directly in error', () => {
13
- a.throws(() => a.satisfies<number>(1, 2), e => e.message === 'Expect actual to satisfy 2, but received 1')
14
-
15
- a.throws(() => a.satisfies<boolean>(true, false), e => e.message === 'Expect actual to satisfy false, but received true')
16
-
17
- a.throws(() => a.satisfies<string>('a', 'b'), e => e.message === `Expect actual to satisfy 'b', but received 'a'`)
1
+ // import { every } from 'satisfier'
2
+ import { isType } from 'type-plus'
3
+ import a, { AssertionError } from '..'
4
+ import { assertThrows, noStackTraceFor } from '../testUtils'
5
+
6
+ describe('non-composable types', () => {
7
+ test('accept same type', () => {
8
+ a.satisfies(null, null)
9
+ a.satisfies(undefined, undefined)
10
+ a.satisfies(1, 1)
11
+ a.satisfies('a', 'a')
12
+ a.satisfies(true, true)
13
+ })
14
+
15
+ test('predicate parameter is the widen type', () => {
16
+ a.satisfies(null, (v) => isType<null>(v))
17
+ a.satisfies(undefined, (v) => isType<undefined>(v))
18
+ a.satisfies(1, (v) => isType<number>(v))
19
+ a.satisfies('a', (v) => isType<string>(v))
20
+ a.satisfies(true, (v) => isType<boolean>(v))
21
+ })
22
+
23
+ test('shows value directly in error', () => {
24
+ a.throws(() => a.satisfies(1, 2), e => e.message === 'Expect actual to satisfy 2, but received 1')
25
+ a.throws(() => a.satisfies(true, false), e => e.message === 'Expect actual to satisfy false, but received true')
26
+ a.throws(() => a.satisfies('a', 'b'), e => e.message === `Expect actual to satisfy 'b', but received 'a'`)
27
+ })
28
+
29
+ test('use regex to check against string', () => {
30
+ a.satisfies('abc', /a/)
31
+ })
18
32
  })
19
33
 
20
34
  test('empty object will pass any object', () => {
@@ -26,10 +40,10 @@ test('empty object will fail against primitive types', () => {
26
40
  a.throws(() => a.satisfies(1, {} as any), e => e.message === 'Expect actual to satisfy {}, but received 1')
27
41
  })
28
42
 
29
- test(`can use satisfier util function such as has()/every()`, () => {
30
- a.satisfies([1], every(1))
31
- a.throws(() => a.satisfies([1, 2], every(1)), e => e.message === 'Expect actual[1] to satisfy 1, but received 2')
32
- })
43
+ // test(`can use satisfier util function such as has()/every()`, () => {
44
+ // a.satisfies([1], every(1))
45
+ // a.throws(() => a.satisfies([1, 2], every(1)), e => e.message === 'Expect actual[1] to satisfy 1, but received 2')
46
+ // })
33
47
 
34
48
  test(`array entries are checked`, () => {
35
49
  a.throws(() => a.satisfies([1], [2]), e => e.message === `Expect actual[0] to satisfy 2, but received 1`)
@@ -74,12 +88,11 @@ test('function will use as predicate', () => {
74
88
  })
75
89
 
76
90
  test('predicate error should mention path', () => {
77
- a.throws(() => a.satisfies({ a: 1 }, { a: () => false }), e => e.message === `Expect a to satisfy fn() { return false }, but received 1`)
91
+ a.throws(() => a.satisfies({ a: 1 }, { a: () => false }), e => e.message === `Expect a to satisfy () => false, but received 1`)
78
92
  })
79
93
 
80
94
  test('deep predicate error should mention path', () => {
81
-
82
- a.throws(() => a.satisfies({ a: { b: 1 } }, { a: { b: b => b === 2 } }), e => e.message === `Expect a.b to satisfy fn(b) { return b === 2 }, but received 1`)
95
+ a.throws(() => a.satisfies({ a: { b: 1 } }, { a: { b: b => b === 2 } }), e => e.message === `Expect a.b to satisfy b => b === 2, but received 1`)
83
96
  })
84
97
 
85
98
  test('can check parent property', () => {
@@ -94,7 +107,7 @@ test('can check parent property', () => {
94
107
  })
95
108
 
96
109
  test('actual of type any should not have type checking error', () => {
97
- let actual: any = { a: 1 }
110
+ const actual: any = { a: 1 }
98
111
  a.satisfies(actual, { a: 1 })
99
112
  })
100
113
 
@@ -102,7 +115,7 @@ test('Work with null in array', () => {
102
115
  interface Foo {
103
116
  payload: any;
104
117
  }
105
- let action: Foo = { payload: [null, 3, 4] }
118
+ const action: Foo = { payload: [null, 3, 4] }
106
119
  a.satisfies(action, { payload: [null, 3, 4] })
107
120
  })
108
121
 
@@ -110,3 +123,21 @@ test('does not contain internal stack trace', async () => {
110
123
  const err = assertThrows(() => a.satisfies({ a: 1 }, { a: 2 }), AssertionError)
111
124
  noStackTraceFor('satisfies.ts', err)
112
125
  })
126
+
127
+ test('allow partial expectation on array entries', () => {
128
+ type U = { type: 'a', a: string } | { type: 'b', b: string }
129
+ const x: U[] = [{ type: 'a', a: 'abc' }]
130
+ a.satisfies(x, [{ type: 'a' }])
131
+ })
132
+
133
+ test('allow predicate on array', () => {
134
+ type U = { type: 'a', a: string } | { type: 'b', b: string }
135
+ const x: U[] = [{ type: 'a', a: 'abc' }]
136
+ a.satisfies(x, (v) => v[0].type == 'a')
137
+ })
138
+
139
+ test('allow predicate on array entries', () => {
140
+ type U = { type: 'a', a: string } | { type: 'b', b: string }
141
+ const x: U[] = [{ type: 'a', a: 'abc' }]
142
+ a.satisfies(x, [(v) => v.type == 'a'])
143
+ })
@@ -1,18 +1,31 @@
1
- import AssertionError from 'assertion-error';
2
- import { createSatisfier } from 'satisfier';
3
- import { notSatisfiedMessage } from '../errors';
1
+ import { createSatisfier } from 'satisfier'
2
+ import { If, IsExtend, NonComposableTypes } from 'type-plus'
3
+ import { AssertionError } from '../errors'
4
+ import { notSatisfiedMessage } from '../utils'
5
+
6
+ export type SatisfyExpectation<T> = If<
7
+ IsExtend<T, string>,
8
+ T | RegExp,
9
+ If<
10
+ IsExtend<T, NonComposableTypes>,
11
+ T,
12
+ If<IsExtend<T, Array<any>>,
13
+ T extends Array<infer E> ? Array<SatisfyExpectation<E>> : never,
14
+ {
15
+ [P in keyof T]?: T[P] extends string
16
+ ? SatisfyExpectation<T[P]> | RegExp
17
+ : SatisfyExpectation<T[P]>
18
+ }
19
+ >>
20
+ > | ((v: T) => boolean)
4
21
 
5
22
  /**
6
23
  * Check if `actual` satisfies criteria in `expected`.
7
24
  * @param expected All properties can be a value which will be compared to the same property in `actual`, RegExp, or a predicate function that will be used to check against the property.
8
25
  */
9
- export function satisfies<Actual extends any>(actual: Actual, expected: any) {
10
- const diff = createSatisfier(expected).exec(actual);
26
+ export function satisfies<Actual>(actual: Actual, expected: SatisfyExpectation<Actual>) {
27
+ const diff = createSatisfier(expected as any).exec(actual);
11
28
  if (diff) {
12
- throw new AssertionError(
13
- notSatisfiedMessage(diff),
14
- { diff },
15
- satisfies
16
- )
29
+ throw new AssertionError(notSatisfiedMessage(diff), { ssf: satisfies })
17
30
  }
18
31
  }
@@ -1,59 +1,61 @@
1
- import t from 'assert';
2
- import AssertionError from 'assertion-error';
3
- import a from '..';
4
- import { assertAsyncThrows, assertIsError, assertIsPromise, assertThrows, noStackTraceFor } from '../testUtils';
1
+ import t from 'assert'
2
+ import a, { AssertionError } from '..'
3
+ import { assertAsyncThrows, assertIsError, assertIsPromise, assertThrows, noStackTraceFor } from '../testUtils'
5
4
 
6
- test('when value is PromiseLike returns Promise', async () => {
7
- let actual = a.throws(Promise.reject(new Error()), Error)
5
+ test('when value is PromiseLike returns a promise with the rejected value', async () => {
6
+ let actual = a.throws(Promise.reject(new Error('Miku')), Error)
8
7
  assertIsPromise(actual)
8
+ t.equal((await actual).message, 'Miku')
9
9
 
10
- actual = a.throws(Promise.reject(new Error()), () => true)
10
+ actual = a.throws(Promise.reject(new Error('Ren')), () => true)
11
11
  assertIsPromise(actual)
12
+ t.equal((await actual).message, 'Ren')
12
13
 
13
- actual = a.throws(Promise.reject(new Error()))
14
+ actual = a.throws(Promise.reject(new Error('Luka')))
14
15
  assertIsPromise(actual)
16
+ t.equal((await actual).message, 'Luka')
15
17
  })
16
18
 
17
- test('when value is function returning promise, will return promise', () => {
18
- let actual = a.throws(() => Promise.reject(new Error()), Error)
19
+ test('when value is function returning a promise, will return a promise with the rejected value', async () => {
20
+ let actual = a.throws(() => Promise.reject(new Error('Miku')), Error)
19
21
  assertIsPromise(actual)
22
+ t.equal((await actual).message, 'Miku')
20
23
 
21
- actual = a.throws(() => Promise.reject(new Error()), () => true)
24
+ actual = a.throws(() => Promise.reject(new Error('Luka')), () => true)
22
25
  assertIsPromise(actual)
26
+ t.equal((await actual).message, 'Luka')
23
27
 
24
- actual = a.throws(() => Promise.reject())
28
+ actual = a.throws(() => Promise.reject('Ren'))
25
29
  assertIsPromise(actual)
30
+ t.equal((await actual), 'Ren')
26
31
  })
27
32
 
28
33
  test('when value is function returns error', () => {
29
- let actual = a.throws((() => { throw new Error() }) as () => void, Error)
34
+ let actual = a.throws((() => { throw new Error() }), Error)
30
35
  assertIsError(actual)
31
36
 
32
- actual = a.throws((() => { throw new Error() }) as () => void)
37
+ actual = a.throws((() => { throw new Error() }))
33
38
  assertIsError(actual)
34
39
  })
35
40
 
36
- test('throws InvalidUsage if input is not a function or promise', () => {
41
+ test('throws if input is not a function or promise', () => {
37
42
  assertThrows(() => a.throws(0 as any))
38
43
  assertThrows(() => a.throws(true as any))
39
44
  assertThrows(() => a.throws('...' as any))
40
45
  assertThrows(() => a.throws(/foo/ as any))
41
46
  })
42
47
 
43
- test('throws for resolved promise', async () => {
44
- const actual = await assertAsyncThrows<AssertionError<{ value: string }>>(() => a.throws(Promise.resolve('ok')), AssertionError)
45
- t.strictEqual(actual.value, 'ok')
48
+ test('throws for resolved promise', () => {
49
+ return assertAsyncThrows(() => a.throws(Promise.resolve('ok')), AssertionError)
46
50
  })
47
51
 
48
52
  test('throws error does not contain internal stack trace for resolved promise', async () => {
49
- const err = await assertAsyncThrows<AssertionError<{ value: string }>>(() => a.throws(Promise.resolve('ok')), AssertionError)
53
+ const err = await assertAsyncThrows(() => a.throws(Promise.resolve('ok')), AssertionError)
50
54
  noStackTraceFor('throws.ts', err)
51
55
  })
52
56
 
53
57
  test('passes with rejected promise', async () => {
54
- const actual = await a.throws<string>(() => new Promise((_, r) => {
55
- setImmediate(() => r('no'))
56
- }))
58
+ const actual = await a.throws<string>(() => new Promise((_, r) => setImmediate(() => r('no'))))
57
59
  t.strictEqual(actual, 'no')
58
60
  })
59
61
 
@@ -62,13 +64,14 @@ test('passes with rejected promise passing validator', () => {
62
64
  })
63
65
 
64
66
  test('throws with rejected promise failing validator', async () => {
65
- const err = await assertAsyncThrows<AssertionError<{ actual: string }>>(() => a.throws(Promise.reject('no'), err => err !== 'no'))
66
-
67
- t.strictEqual(err.actual, 'no')
67
+ await assertAsyncThrows(
68
+ () => a.throws(Promise.reject('no'), err => err !== 'no'),
69
+ AssertionError)
68
70
  })
69
71
 
70
72
  test('thrown error does not contain internal stack trace with rejected promise failing validator', async () => {
71
- const err = await assertAsyncThrows<AssertionError<{ actual: string }>>(() => a.throws(Promise.reject('no'), err => err !== 'no'))
73
+ const err = await assertAsyncThrows(() => a.throws(Promise.reject('no'), err => err !== 'no'), AssertionError)
74
+ // Error.captureStackTrace(err, a.throws)
72
75
 
73
76
  noStackTraceFor('throws.ts', err)
74
77
  })
@@ -78,26 +81,30 @@ test('passes with throwing function', () => {
78
81
  })
79
82
 
80
83
  test('throws if function does not', () => {
81
- const err = assertThrows<AssertionError<{ value: string }>>(() => a.throws(
82
- () => { return 'foo' }, AssertionError),
83
- AssertionError)
84
- t.strictEqual(err.value, 'foo')
84
+ assertThrows(
85
+ () => a.throws(() => { return 'foo' }, AssertionError),
86
+ AssertionError
87
+ )
85
88
  })
86
89
 
87
90
  test('thrown error does not contain internal stack track if function does not', () => {
88
- const err = assertThrows<AssertionError<{ value: string }>>(() => a.throws(
89
- () => { return 'foo' }, AssertionError),
90
- AssertionError)
91
+ const err = assertThrows(
92
+ () => a.throws(() => { return 'foo' }, AssertionError),
93
+ AssertionError
94
+ )
91
95
  noStackTraceFor('throws.ts', err)
92
96
  })
93
97
 
94
98
  test('throws if function returns resolved promise', async () => {
95
- const err = await assertAsyncThrows<AssertionError<{ value: string }>>(() => a.throws(() => Promise.resolve('ok')), AssertionError)
96
- t.strictEqual(err.value, 'ok')
99
+ await assertAsyncThrows(
100
+ () => a.throws(() => Promise.resolve('ok')),
101
+ AssertionError)
97
102
  })
98
103
 
99
104
  test('thrown error does not contain internal stack trace if function returns resolved promise', async () => {
100
- const err = await assertAsyncThrows<AssertionError<{ value: string }>>(() => a.throws(() => Promise.resolve('ok')), AssertionError)
105
+ const err = await assertAsyncThrows(
106
+ () => a.throws(() => Promise.resolve('ok')),
107
+ AssertionError)
101
108
  noStackTraceFor('throws.ts', err)
102
109
  })
103
110
 
@@ -112,12 +119,18 @@ test('pass if function returns rejected promise passing valdation', () => {
112
119
  })
113
120
 
114
121
  test('throws if function returns rejected promise not passing valdation', async () => {
115
- const err = await assertAsyncThrows<AssertionError<{ actual: any }>>(() => a.throws(() => Promise.reject('ok'), err => err !== 'ok'))
116
- t.strictEqual(err.actual, 'ok')
122
+ await assertAsyncThrows(
123
+ () => a.throws(() => Promise.reject('ok'), err => err !== 'ok'),
124
+ AssertionError
125
+ )
117
126
  })
118
127
 
119
128
  test('thrown error does not contain stack trace if function returns rejected promise not passing valdation', async () => {
120
- const err = await assertAsyncThrows<AssertionError<{ actual: any }>>(() => a.throws(() => Promise.reject('ok'), err => err !== 'ok'))
129
+ const err = await assertAsyncThrows(
130
+ () => a.throws(() => Promise.reject('ok'), err => err !== 'ok'),
131
+ AssertionError
132
+ )
133
+ // console.log('got err', err)
121
134
  noStackTraceFor('throws.ts', err)
122
135
  })
123
136
 
@@ -163,3 +176,9 @@ test(`a.throws(() => never) returns error of type Error`, () => {
163
176
  const err = a.throws(() => { throw new Error('failure') })
164
177
  expect(err.message).toBe('failure')
165
178
  })
179
+
180
+ test('throw if function returns an object', () => {
181
+ class Dummy { a = 1; foo() { } }
182
+ const err = assertThrows(() => a.throws(() => new Dummy()), AssertionError)
183
+ expect(err.message).toBe(`Expect function to throw, but it returned 'Dummy { a: 1 }' instead.`)
184
+ })