ExampleDocumentTests.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /* eslint-disable
  2. camelcase,
  3. no-path-concat,
  4. no-return-assign,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS101: Remove unnecessary use of Array.from
  12. * DS102: Remove unnecessary code created because of implicit returns
  13. * DS103: Rewrite code to no longer use __guard__
  14. * DS207: Consider shorter variations of null checks
  15. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  16. */
  17. const Client = require('./helpers/Client')
  18. const request = require('request')
  19. const fs = require('fs')
  20. const fsExtra = require('fs-extra')
  21. const ChildProcess = require('child_process')
  22. const ClsiApp = require('./helpers/ClsiApp')
  23. const logger = require('logger-sharelatex')
  24. const Path = require('path')
  25. const fixturePath = path => {
  26. if (path.slice(0, 3) === 'tmp') {
  27. return '/tmp/clsi_acceptance_tests' + path.slice(3)
  28. }
  29. return Path.normalize(__dirname + '/../fixtures/' + path)
  30. }
  31. const process = require('process')
  32. console.log(
  33. process.pid,
  34. process.ppid,
  35. process.getuid(),
  36. process.getgroups(),
  37. 'PID'
  38. )
  39. const MOCHA_LATEX_TIMEOUT = 60 * 1000
  40. const convertToPng = function (pdfPath, pngPath, callback) {
  41. if (callback == null) {
  42. callback = function () {}
  43. }
  44. const command = `convert ${fixturePath(pdfPath)} ${fixturePath(pngPath)}`
  45. console.log('COMMAND')
  46. console.log(command)
  47. const convert = ChildProcess.exec(command)
  48. const stdout = ''
  49. convert.stdout.on('data', chunk => console.log('STDOUT', chunk.toString()))
  50. convert.stderr.on('data', chunk => console.log('STDERR', chunk.toString()))
  51. return convert.on('exit', () => callback())
  52. }
  53. const compare = function (originalPath, generatedPath, callback) {
  54. if (callback == null) {
  55. callback = function () {}
  56. }
  57. const diff_file = `${fixturePath(generatedPath)}-diff.png`
  58. const proc = ChildProcess.exec(
  59. `compare -metric mae ${fixturePath(originalPath)} ${fixturePath(
  60. generatedPath
  61. )} ${diff_file}`
  62. )
  63. let stderr = ''
  64. proc.stderr.on('data', chunk => (stderr += chunk))
  65. return proc.on('exit', () => {
  66. if (stderr.trim() === '0 (0)') {
  67. // remove output diff if test matches expected image
  68. fs.unlink(diff_file, err => {
  69. if (err) {
  70. throw err
  71. }
  72. })
  73. return callback(null, true)
  74. } else {
  75. console.log('compare result', stderr)
  76. return callback(null, false)
  77. }
  78. })
  79. }
  80. const checkPdfInfo = function (pdfPath, callback) {
  81. if (callback == null) {
  82. callback = function () {}
  83. }
  84. const proc = ChildProcess.exec(`pdfinfo ${fixturePath(pdfPath)}`)
  85. let stdout = ''
  86. proc.stdout.on('data', chunk => (stdout += chunk))
  87. proc.stderr.on('data', chunk => console.log('STDERR', chunk.toString()))
  88. return proc.on('exit', () => {
  89. if (stdout.match(/Optimized:\s+yes/)) {
  90. return callback(null, true)
  91. } else {
  92. return callback(null, false)
  93. }
  94. })
  95. }
  96. const compareMultiplePages = function (project_id, callback) {
  97. if (callback == null) {
  98. callback = function () {}
  99. }
  100. function compareNext(page_no, callback) {
  101. const path = `tmp/${project_id}-source-${page_no}.png`
  102. return fs.stat(fixturePath(path), (error, stat) => {
  103. if (error != null) {
  104. return callback()
  105. } else {
  106. return compare(
  107. `tmp/${project_id}-source-${page_no}.png`,
  108. `tmp/${project_id}-generated-${page_no}.png`,
  109. (error, same) => {
  110. if (error != null) {
  111. throw error
  112. }
  113. same.should.equal(true)
  114. return compareNext(page_no + 1, callback)
  115. }
  116. )
  117. }
  118. })
  119. }
  120. return compareNext(0, callback)
  121. }
  122. const comparePdf = function (project_id, example_dir, callback) {
  123. if (callback == null) {
  124. callback = function () {}
  125. }
  126. console.log('CONVERT')
  127. console.log(`tmp/${project_id}.pdf`, `tmp/${project_id}-generated.png`)
  128. return convertToPng(
  129. `tmp/${project_id}.pdf`,
  130. `tmp/${project_id}-generated.png`,
  131. error => {
  132. if (error != null) {
  133. throw error
  134. }
  135. return convertToPng(
  136. `examples/${example_dir}/output.pdf`,
  137. `tmp/${project_id}-source.png`,
  138. error => {
  139. if (error != null) {
  140. throw error
  141. }
  142. return fs.stat(
  143. fixturePath(`tmp/${project_id}-source-0.png`),
  144. (error, stat) => {
  145. if (error != null) {
  146. return compare(
  147. `tmp/${project_id}-source.png`,
  148. `tmp/${project_id}-generated.png`,
  149. (error, same) => {
  150. if (error != null) {
  151. throw error
  152. }
  153. same.should.equal(true)
  154. return callback()
  155. }
  156. )
  157. } else {
  158. return compareMultiplePages(project_id, error => {
  159. if (error != null) {
  160. throw error
  161. }
  162. return callback()
  163. })
  164. }
  165. }
  166. )
  167. }
  168. )
  169. }
  170. )
  171. }
  172. const downloadAndComparePdf = function (
  173. project_id,
  174. example_dir,
  175. url,
  176. callback
  177. ) {
  178. if (callback == null) {
  179. callback = function () {}
  180. }
  181. const writeStream = fs.createWriteStream(fixturePath(`tmp/${project_id}.pdf`))
  182. request.get(url).pipe(writeStream)
  183. console.log('writing file out', fixturePath(`tmp/${project_id}.pdf`))
  184. return writeStream.on('close', () => {
  185. return checkPdfInfo(`tmp/${project_id}.pdf`, (error, optimised) => {
  186. if (error != null) {
  187. throw error
  188. }
  189. optimised.should.equal(true)
  190. return comparePdf(project_id, example_dir, callback)
  191. })
  192. })
  193. }
  194. Client.runServer(4242, fixturePath('examples'))
  195. describe('Example Documents', function () {
  196. before(function (done) {
  197. ClsiApp.ensureRunning(done)
  198. })
  199. before(function (done) {
  200. fsExtra.remove(fixturePath('tmp'), done)
  201. })
  202. before(function (done) {
  203. fs.mkdir(fixturePath('tmp'), done)
  204. })
  205. after(function (done) {
  206. fsExtra.remove(fixturePath('tmp'), done)
  207. })
  208. return Array.from(fs.readdirSync(fixturePath('examples'))).map(example_dir =>
  209. (example_dir =>
  210. describe(example_dir, function () {
  211. before(function () {
  212. return (this.project_id = Client.randomId() + '_' + example_dir)
  213. })
  214. it('should generate the correct pdf', function (done) {
  215. this.timeout(MOCHA_LATEX_TIMEOUT)
  216. return Client.compileDirectory(
  217. this.project_id,
  218. fixturePath('examples'),
  219. example_dir,
  220. 4242,
  221. (error, res, body) => {
  222. if (
  223. error ||
  224. __guard__(
  225. body != null ? body.compile : undefined,
  226. x => x.status
  227. ) === 'failure'
  228. ) {
  229. console.log('DEBUG: error', error, 'body', JSON.stringify(body))
  230. return done(new Error('Compile failed'))
  231. }
  232. const pdf = Client.getOutputFile(body, 'pdf')
  233. return downloadAndComparePdf(
  234. this.project_id,
  235. example_dir,
  236. pdf.url,
  237. done
  238. )
  239. }
  240. )
  241. })
  242. return it('should generate the correct pdf on the second run as well', function (done) {
  243. this.timeout(MOCHA_LATEX_TIMEOUT)
  244. return Client.compileDirectory(
  245. this.project_id,
  246. fixturePath('examples'),
  247. example_dir,
  248. 4242,
  249. (error, res, body) => {
  250. if (
  251. error ||
  252. __guard__(
  253. body != null ? body.compile : undefined,
  254. x => x.status
  255. ) === 'failure'
  256. ) {
  257. console.log('DEBUG: error', error, 'body', JSON.stringify(body))
  258. return done(new Error('Compile failed'))
  259. }
  260. const pdf = Client.getOutputFile(body, 'pdf')
  261. return downloadAndComparePdf(
  262. this.project_id,
  263. example_dir,
  264. pdf.url,
  265. done
  266. )
  267. }
  268. )
  269. })
  270. }))(example_dir)
  271. )
  272. })
  273. function __guard__(value, transform) {
  274. return typeof value !== 'undefined' && value !== null
  275. ? transform(value)
  276. : undefined
  277. }