pdfjs.test.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import fs from 'node:fs'
  2. import Path from 'node:path'
  3. import { beforeAll, expect, describe, it } from 'vitest'
  4. import XrefParser from '../../../app/js/XrefParser.js'
  5. import { NoXrefTableError } from '../../../app/js/Errors.js'
  6. const PATH_EXAMPLES = 'test/acceptance/fixtures/examples/'
  7. const PATH_SNAPSHOTS = 'test/unit/js/snapshots/pdfjs/'
  8. const EXAMPLES = fs.readdirSync(PATH_EXAMPLES)
  9. const { parseXrefTable } = XrefParser
  10. function snapshotPath(example) {
  11. return Path.join(PATH_SNAPSHOTS, example, 'XrefTable.json')
  12. }
  13. function pdfPath(example) {
  14. return Path.join(PATH_EXAMPLES, example, 'output.pdf')
  15. }
  16. async function loadContext(example) {
  17. const size = (await fs.promises.stat(pdfPath(example))).size
  18. let blob
  19. try {
  20. blob = await fs.promises.readFile(snapshotPath(example))
  21. } catch (e) {
  22. if (e.code !== 'ENOENT') {
  23. throw e
  24. }
  25. }
  26. const snapshot = blob ? JSON.parse(blob) : null
  27. return {
  28. size,
  29. snapshot,
  30. }
  31. }
  32. async function backFillSnapshot(example, size) {
  33. const table = await parseXrefTable(pdfPath(example), size, () => {})
  34. await fs.promises.mkdir(Path.dirname(snapshotPath(example)), {
  35. recursive: true,
  36. })
  37. await fs.promises.writeFile(
  38. snapshotPath(example),
  39. JSON.stringify(table, null, 2)
  40. )
  41. return table
  42. }
  43. describe('pdfjs', function () {
  44. describe('when the pdf is an empty file', function () {
  45. it('should yield no entries', async function () {
  46. const path = 'does/not/matter.pdf'
  47. let table
  48. try {
  49. table = await parseXrefTable(path, 0)
  50. } catch (e) {
  51. expect(e).to.be.an.instanceof(NoXrefTableError)
  52. }
  53. expect(table).to.not.exist
  54. })
  55. })
  56. for (const example of EXAMPLES) {
  57. describe(example, function () {
  58. let size, snapshot
  59. beforeAll(async function () {
  60. // load snapshot
  61. const ctx = await loadContext(example)
  62. size = ctx.size
  63. snapshot = ctx.snapshot
  64. })
  65. beforeAll(async function () {
  66. // back fill new snapshot
  67. if (snapshot === null) {
  68. console.error('back filling snapshot for', example)
  69. snapshot = await backFillSnapshot(example, size)
  70. }
  71. })
  72. it('should produce the expected xRef table', async function () {
  73. const table = await parseXrefTable(pdfPath(example), size, () => {})
  74. // compare the essential parts of the xref table only
  75. expect(table.xRefEntries[0]).to.include({ offset: 0 })
  76. expect(table.xRefEntries.slice(1)).to.deep.equal(
  77. snapshot.xRefEntries
  78. .slice(1)
  79. .filter(xref => xref.uncompressed) // we only use the uncompressed fields
  80. .map(xref => {
  81. return { offset: xref.offset, uncompressed: xref.uncompressed } // ignore unused gen field
  82. })
  83. )
  84. })
  85. })
  86. }
  87. })