shim-diff.spec.ts 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * Differential check of the worker's crypto/url/util shims against Node.
  3. */
  4. import { expect, test } from 'vitest'
  5. import { createHash as nodeCreateHash } from 'node:crypto'
  6. import { fileURLToPath as nodeFileURLToPath, pathToFileURL as nodePathToFileURL } from 'node:url'
  7. import { isDeepStrictEqual as nodeIsDeepStrictEqual, promisify as nodePromisify } from 'node:util'
  8. import * as shimCrypto from '@deepseek-ai/dsh-experimental-webworker-runtime/src/node/builtin_modules/implemented/crypto.ts'
  9. import * as shimUrl from '@deepseek-ai/dsh-experimental-webworker-runtime/src/node/builtin_modules/implemented/url.ts'
  10. import * as shimUtil from '@deepseek-ai/dsh-experimental-webworker-runtime/src/node/builtin_modules/implemented/util.ts'
  11. const compare = (label: string, actual: unknown, expected: unknown): void => {
  12. const [shimmed, node] = [JSON.stringify(actual), JSON.stringify(expected)]
  13. test(label, () => { expect(shimmed).toBe(node) })
  14. }
  15. const INPUTS = ['', 'a', 'hello world', '中文字符串', '�ÿ', 'x'.repeat(100_000)]
  16. for (const algorithm of ['sha1', 'sha256', 'sha512']) {
  17. for (const input of INPUTS) {
  18. compare(
  19. `${algorithm}(${input.slice(0, 12)}… len ${String(input.length)})`,
  20. shimCrypto.createHash(algorithm).update(input).digest('hex'),
  21. nodeCreateHash(algorithm).update(input).digest('hex'),
  22. )
  23. }
  24. // Chained updates must equal the concatenated input.
  25. compare(
  26. `${algorithm} chained update`,
  27. shimCrypto.createHash(algorithm).update('ab').update('cd').digest('hex'),
  28. nodeCreateHash(algorithm).update('abcd').digest('hex'),
  29. )
  30. compare(
  31. `${algorithm} base64`,
  32. shimCrypto.createHash(algorithm).update('abc').digest('base64'),
  33. nodeCreateHash(algorithm).update('abc').digest('base64'),
  34. )
  35. compare(
  36. `${algorithm} bytes`,
  37. [...shimCrypto.createHash(algorithm).update(new Uint8Array([1, 2, 3])).digest()],
  38. [...nodeCreateHash(algorithm).update(new Uint8Array([1, 2, 3])).digest()],
  39. )
  40. }
  41. const PATHS = [
  42. '/dsh/config/cordis.yml', '/a b/c', '/中文/x.md', '/a%b', '/dsh/node_modules/@scope/pkg/lib/index.js',
  43. ]
  44. for (const path of PATHS) {
  45. compare(`pathToFileURL(${path})`, shimUrl.pathToFileURL(path).href, nodePathToFileURL(path).href)
  46. compare(
  47. `fileURLToPath(pathToFileURL(${path}))`,
  48. shimUrl.fileURLToPath(shimUrl.pathToFileURL(path)),
  49. nodeFileURLToPath(nodePathToFileURL(path)),
  50. )
  51. }
  52. const PAIRS: [unknown, unknown][] = [
  53. [1, 1], [1, '1'], [{ a: 1 }, { a: 1 }], [{ a: 1 }, { a: 2 }], [{ a: 1 }, { a: 1, b: undefined }],
  54. [[1, 2], [1, 2]], [[1, 2], [2, 1]], [null, undefined], [{ a: { b: [1, { c: 2 }] } }, { a: { b: [1, { c: 2 }] } }],
  55. ]
  56. for (const [left, right] of PAIRS) {
  57. compare(
  58. `isDeepStrictEqual(${JSON.stringify(left)}, ${JSON.stringify(right)})`,
  59. shimUtil.isDeepStrictEqual(left, right),
  60. nodeIsDeepStrictEqual(left, right),
  61. )
  62. }
  63. const callbackStyle = (value: number, callback: (error: unknown, result?: number) => void): void => {
  64. if (value < 0) callback(new Error('negative'))
  65. else callback(null, value * 2)
  66. }
  67. const shimPromised = shimUtil.promisify(callbackStyle)
  68. const nodePromised = nodePromisify(callbackStyle)
  69. compare('promisify success', await shimPromised(21), await nodePromised(21))
  70. const shimError = await shimPromised(-1).then(() => undefined, (error: unknown) => (error as Error).message)
  71. const nodeError = await nodePromised(-1).then(() => undefined, (error: unknown) => (error as Error).message)
  72. compare('promisify rejection', shimError, nodeError)