pdf-license-bundle.client.spec.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { spawnSync } from 'node:child_process'
  2. import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs'
  3. import { tmpdir } from 'node:os'
  4. import { dirname, join, resolve } from 'node:path'
  5. import { createRequire } from 'node:module'
  6. import { describe, expect, it } from 'vitest'
  7. const packageRoot = resolve(import.meta.dirname, '..')
  8. const bundlePath = join(packageRoot, 'lib/client.js')
  9. const require = createRequire(import.meta.url)
  10. const licenseNames = [
  11. 'LICENSE',
  12. 'cmaps/LICENSE',
  13. 'standard_fonts/LICENSE_FOXIT',
  14. 'standard_fonts/LICENSE_LIBERATION',
  15. 'wasm/LICENSE_JBIG2',
  16. 'wasm/LICENSE_OPENJPEG',
  17. 'wasm/LICENSE_PDFJS_JBIG2',
  18. 'wasm/LICENSE_PDFJS_OPENJPEG',
  19. 'wasm/LICENSE_PDFJS_QCMS',
  20. 'wasm/LICENSE_QCMS',
  21. ] as const
  22. function run(command: string, args: string[], cwd: string, timeout: number): string {
  23. const result = spawnSync(command, args, { cwd, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024, timeout })
  24. expect(result.error).toBeUndefined()
  25. expect(result.signal, result.stderr).toBeNull()
  26. expect(result.status, result.stderr).toBe(0)
  27. return result.stdout
  28. }
  29. function runPnpm(args: string[], cwd: string, timeout: number): string {
  30. const entrypoint = process.env.npm_execpath
  31. if (entrypoint === undefined || entrypoint === '') {
  32. if (process.platform === 'win32') throw new Error('npm_execpath is required to run pnpm on Windows')
  33. return run('pnpm', args, cwd, timeout)
  34. }
  35. return /\.[cm]?js$/iu.test(entrypoint)
  36. ? run(process.execPath, [entrypoint, ...args], cwd, timeout)
  37. : run(entrypoint, args, cwd, timeout)
  38. }
  39. describe('published PDF.js licenses', () => {
  40. it.skipIf(!existsSync(bundlePath))('keeps every bundled license in the packed client artifact', ({ task }) => {
  41. const output = mkdtempSync(join(tmpdir(), 'dsh-document-preview-pack-'))
  42. try {
  43. const packed = JSON.parse(runPnpm([
  44. 'pack', '--json', '--pack-destination', output,
  45. ], packageRoot, task.timeout)) as { filename: string; files: { path: string }[] }
  46. expect(packed.files.map(file => file.path)).toContain('lib/client.js')
  47. expect(packed.files.some(file => file.path.endsWith('pdfjs-NOTICES.txt'))).toBe(false)
  48. const client = run('tar', ['-xOf', resolve(packageRoot, packed.filename), 'package/lib/client.js'], packageRoot, task.timeout)
  49. expect(client).toContain('//! Bundled PDF.js license notices')
  50. const pdfRoot = dirname(require.resolve('pdfjs-dist/package.json'))
  51. for (const name of licenseNames) {
  52. const source = readFileSync(join(pdfRoot, name), 'utf8').trimEnd()
  53. const commented = [`// ${name}`, '// ', ...source.split('\n').map(line => `// ${line}`)].join('\n')
  54. expect(client, `${name} must be visible in package/lib/client.js`).toContain(commented)
  55. }
  56. } finally {
  57. rmSync(output, { recursive: true, force: true })
  58. }
  59. })
  60. })