@plugjs/expect5 0.4.6 → 0.4.8

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 (55) hide show
  1. package/dist/cli.mjs +6 -1
  2. package/dist/cli.mjs.map +1 -1
  3. package/dist/execution/executable.mjs +6 -0
  4. package/dist/execution/executable.mjs.map +1 -1
  5. package/dist/execution/executor.mjs +6 -0
  6. package/dist/execution/executor.mjs.map +1 -1
  7. package/dist/execution/setup.mjs +6 -0
  8. package/dist/execution/setup.mjs.map +1 -1
  9. package/dist/expectation/async.cjs +14 -22
  10. package/dist/expectation/async.cjs.map +1 -1
  11. package/dist/expectation/async.d.ts +39 -13
  12. package/dist/expectation/async.mjs +20 -22
  13. package/dist/expectation/async.mjs.map +1 -1
  14. package/dist/expectation/diff.mjs +6 -0
  15. package/dist/expectation/diff.mjs.map +1 -1
  16. package/dist/expectation/expect.cjs +3 -3
  17. package/dist/expectation/expect.cjs.map +1 -1
  18. package/dist/expectation/expect.d.ts +3 -3
  19. package/dist/expectation/expect.mjs +10 -4
  20. package/dist/expectation/expect.mjs.map +1 -1
  21. package/dist/expectation/expectations.cjs +27 -44
  22. package/dist/expectation/expectations.cjs.map +1 -1
  23. package/dist/expectation/expectations.d.ts +72 -14
  24. package/dist/expectation/expectations.mjs +33 -44
  25. package/dist/expectation/expectations.mjs.map +1 -1
  26. package/dist/expectation/include.mjs +6 -0
  27. package/dist/expectation/include.mjs.map +1 -1
  28. package/dist/expectation/matchers.cjs +24 -47
  29. package/dist/expectation/matchers.cjs.map +1 -1
  30. package/dist/expectation/matchers.d.ts +136 -93
  31. package/dist/expectation/matchers.mjs +29 -46
  32. package/dist/expectation/matchers.mjs.map +1 -1
  33. package/dist/expectation/print.cjs +4 -0
  34. package/dist/expectation/print.cjs.map +1 -1
  35. package/dist/expectation/print.mjs +11 -1
  36. package/dist/expectation/print.mjs.map +1 -1
  37. package/dist/expectation/types.cjs.map +1 -1
  38. package/dist/expectation/types.d.ts +2 -2
  39. package/dist/expectation/types.mjs +6 -0
  40. package/dist/expectation/types.mjs.map +1 -1
  41. package/dist/globals.mjs +5 -0
  42. package/dist/index.mjs +6 -0
  43. package/dist/index.mjs.map +1 -1
  44. package/dist/test.cjs +17 -7
  45. package/dist/test.cjs.map +1 -1
  46. package/dist/test.mjs +25 -9
  47. package/dist/test.mjs.map +1 -1
  48. package/package.json +3 -3
  49. package/src/expectation/async.ts +69 -17
  50. package/src/expectation/expect.ts +6 -6
  51. package/src/expectation/expectations.ts +152 -27
  52. package/src/expectation/matchers.ts +207 -125
  53. package/src/expectation/print.ts +7 -1
  54. package/src/expectation/types.ts +2 -2
  55. package/src/test.ts +29 -8
@@ -8,7 +8,7 @@ import {
8
8
  type MissingValueDiff,
9
9
  type ObjectDiff,
10
10
  } from './diff'
11
- import { stringifyValue } from './types'
11
+ import { isMatcher, stringifyValue } from './types'
12
12
 
13
13
  /* ========================================================================== *
14
14
  * CONSTANT LABELS FOR PRINTING *
@@ -31,6 +31,7 @@ const _hellip = $gry('\u2026')
31
31
 
32
32
  const _error = `${_opnPar}${$gry($und('error'))}${_clsPar}`
33
33
  const _string = `${_opnPar}${$gry($und('string'))}${_clsPar}`
34
+ const _matcher = $gry('\u2026 matcher \u2026')
34
35
  const _extraProps = $gry('\u2026 extra props \u2026')
35
36
  const _diffHeader = `${$wht('Differences')} ${_opnPar}${$red('actual')}${_slash}${$grn('expected')}${_slash}${$ylw('errors')}${_clsPar}:`
36
37
 
@@ -270,6 +271,11 @@ function dumpAndContinue(
270
271
  return `${prefix}${color(stringify(value))}${suffix}`
271
272
  }
272
273
 
274
+ // matchers are a very special value...
275
+ if (isMatcher(value)) {
276
+ return `${prefix}${_matcher}${suffix}`
277
+ }
278
+
273
279
  // check for circular dependencies
274
280
  const circular = stack.indexOf(value)
275
281
  if (circular >= 0) {
@@ -1,6 +1,6 @@
1
1
  import { type Diff } from './diff'
2
2
  import { type Expectations } from './expectations'
3
- import { type Matchers } from './matchers'
3
+ import { type Matcher } from './matchers'
4
4
 
5
5
  /* ========================================================================== *
6
6
  * INTERNAL TYPES FOR EXPECTATIONS *
@@ -194,7 +194,7 @@ export function prefixType(type: TypeName): string {
194
194
 
195
195
  export const matcherMarker = Symbol.for('plugjs:expect5:types:Matcher')
196
196
 
197
- export function isMatcher(what: any): what is Matchers {
197
+ export function isMatcher(what: any): what is Matcher {
198
198
  return what && what[matcherMarker] === matcherMarker
199
199
  }
200
200
 
package/src/test.ts CHANGED
@@ -6,7 +6,7 @@ import { AssertionError } from 'node:assert'
6
6
  import { BuildFailure } from '@plugjs/plug'
7
7
  import { assert } from '@plugjs/plug/asserts'
8
8
  import { type Files } from '@plugjs/plug/files'
9
- import { $blu, $grn, $gry, $ms, $red, $wht, $ylw, ERROR, NOTICE, WARN, log, type Logger } from '@plugjs/plug/logging'
9
+ import { $blu, $grn, $gry, $ms, $red, $wht, $ylw, ERROR, NOTICE, WARN, log, type Logger, $p, githubAnnotation } from '@plugjs/plug/logging'
10
10
  import { type Context, type PipeParameters, type Plug } from '@plugjs/plug/pipe'
11
11
 
12
12
  import * as setup from './execution/setup'
@@ -15,7 +15,7 @@ import { runSuite } from './execution/executor'
15
15
  import { diff } from './expectation/diff'
16
16
  import { expect } from './expectation/expect'
17
17
  import { printDiff } from './expectation/print'
18
- import { ExpectationError, stringifyObjectType, stringifyValue } from './expectation/types'
18
+ import { ExpectationError, stringifyValue } from './expectation/types'
19
19
 
20
20
  import { type TestOptions } from './index'
21
21
 
@@ -63,7 +63,11 @@ export class Test implements Plug<void> {
63
63
 
64
64
  // Create our _root_ Suite
65
65
  const suite = new Suite(undefined, '', async () => {
66
- for (const file of files.absolutePaths()) await import(file)
66
+ let count = 0
67
+ for (const file of files.absolutePaths()) {
68
+ log.debug('Importing', $p(file), 'in suite', $gry(`(${++ count}/${files.length})`))
69
+ await import(file)
70
+ }
67
71
  })
68
72
 
69
73
  // Setup our suite counts
@@ -102,11 +106,15 @@ export class Test implements Plug<void> {
102
106
 
103
107
  execution.on('spec:skip', (spec, ms) => {
104
108
  if (suite.flag === 'only') return context.log.leave()
105
- context.log.leave(WARN, `${$ylw(_pending)} ${spec.name} ${$ms(ms)} ${$gry('[')}${$ylw('skipped')}${$gry(']')}`)
109
+ context.log.leave(WARN, `${$ylw(_pending)} ${spec.name} ${$ms(ms, $ylw('skipped'))}`)
106
110
  })
107
111
 
108
112
  execution.on('spec:pass', (spec, ms) => {
109
- context.log.leave(NOTICE, `${$grn(_success)} ${spec.name} ${$ms(ms)}`)
113
+ if (ms >= (spec.timeout * 0.75)) {
114
+ context.log.leave(WARN, `${$ylw(_success)} ${spec.name} ${$ms(ms, $ylw('slow'))}`)
115
+ } else {
116
+ context.log.leave(NOTICE, `${$grn(_success)} ${spec.name} ${$ms(ms)}`)
117
+ }
110
118
  })
111
119
 
112
120
  execution.on('spec:fail', (spec, ms, { number }) => {
@@ -174,6 +182,8 @@ function dumpError(log: Logger, error: any, genericErrorDiffs: boolean): void {
174
182
  // First and foremost, our own expectation errors
175
183
  if (error instanceof ExpectationError) {
176
184
  log.enter(ERROR, `${$gry('Expectation Error:')} ${$red(error.message)}`)
185
+ githubAnnotation({ type: 'error', title: 'Expectation Error' }, error.message)
186
+
177
187
  try {
178
188
  dumpProps(log, 17, error)
179
189
  dumpStack(log, error)
@@ -186,7 +196,10 @@ function dumpError(log: Logger, error: any, genericErrorDiffs: boolean): void {
186
196
  // Assertion errors are another kind of exception we support
187
197
  } else if (error instanceof AssertionError) {
188
198
  const [ message = 'Unknown Error', ...lines ] = error.message.split('\n')
199
+
189
200
  log.enter(ERROR, `${$gry('Assertion Error:')} ${$red(message)}`)
201
+ githubAnnotation({ type: 'error', title: 'Assertion Error' }, message)
202
+
190
203
  try {
191
204
  dumpProps(log, 15, error)
192
205
  dumpStack(log, error)
@@ -209,10 +222,16 @@ function dumpError(log: Logger, error: any, genericErrorDiffs: boolean): void {
209
222
  // Any other error also gets printed somewhat nicely
210
223
  } else if (error instanceof Error) {
211
224
  const message = error.message || 'Unknown Error'
212
- const string = stringifyObjectType(error)
225
+ const string = Object.getPrototypeOf(error)?.constructor?.name || 'Error'
226
+
213
227
  // Chai calls its own assertion errors "AssertionError"
214
- const type = string === '[AssertionError]' ? 'Assertion Error' : string
215
- log.enter(ERROR, `${$gry(type)}: ${$red(message)}`)
228
+ const type =
229
+ string === 'AssertionError' ? `${$gry('Assertion Error')}: ` :
230
+ string === 'Error' ? '' : `${$gry(string)}: `
231
+
232
+ log.enter(ERROR, `${type}${$red(message)}`)
233
+ githubAnnotation({ type: 'error', title: string }, message)
234
+
216
235
  try {
217
236
  dumpProps(log, type.length, error)
218
237
  dumpStack(log, error)
@@ -244,6 +263,8 @@ function dumpProps(log: Logger, pad: number, error: Error): void {
244
263
  'showDiff', // chai
245
264
  'stack', // error
246
265
  ].includes(k))
266
+ .filter((k) => !(error[k as keyof typeof error] === null))
267
+ .filter((k) => !(error[k as keyof typeof error] === undefined))
247
268
  .forEach((k) => {
248
269
  const value = error[k as keyof typeof error]
249
270
  if ((k === 'code') && (value === 'ERR_ASSERTION')) return