Initial open source commit
This commit is contained in:
46
test/acceptance/coffee/BrokenLatexFileTests.coffee
Normal file
46
test/acceptance/coffee/BrokenLatexFileTests.coffee
Normal file
@@ -0,0 +1,46 @@
|
||||
Client = require "./helpers/Client"
|
||||
request = require "request"
|
||||
require("chai").should()
|
||||
|
||||
describe "Broken LaTeX file", ->
|
||||
before ->
|
||||
@broken_request =
|
||||
resources: [
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{articl % :(
|
||||
\\begin{documen % :(
|
||||
Broken
|
||||
\\end{documen % :(
|
||||
'''
|
||||
]
|
||||
@correct_request =
|
||||
resources: [
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\begin{document}
|
||||
Hello world
|
||||
\\end{document}
|
||||
'''
|
||||
]
|
||||
|
||||
describe "on first run", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
Client.compile @project_id, @broken_request, (@error, @res, @body) => done()
|
||||
|
||||
it "should return a failure status", ->
|
||||
@body.compile.status.should.equal "failure"
|
||||
|
||||
describe "on second run", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
Client.compile @project_id, @correct_request, () =>
|
||||
Client.compile @project_id, @broken_request, (@error, @res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return a failure status", ->
|
||||
@body.compile.status.should.equal "failure"
|
||||
|
||||
|
||||
34
test/acceptance/coffee/DeleteOldFilesTest.coffee
Normal file
34
test/acceptance/coffee/DeleteOldFilesTest.coffee
Normal file
@@ -0,0 +1,34 @@
|
||||
Client = require "./helpers/Client"
|
||||
request = require "request"
|
||||
require("chai").should()
|
||||
|
||||
describe "Deleting Old Files", ->
|
||||
before ->
|
||||
@request =
|
||||
resources: [
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\begin{document}
|
||||
Hello world
|
||||
\\end{document}
|
||||
'''
|
||||
]
|
||||
|
||||
describe "on first run", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
Client.compile @project_id, @request, (@error, @res, @body) => done()
|
||||
|
||||
it "should return a success status", ->
|
||||
@body.compile.status.should.equal "success"
|
||||
|
||||
describe "after file has been deleted", ->
|
||||
before (done) ->
|
||||
@request.resources = []
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
done()
|
||||
|
||||
it "should return a failure status", ->
|
||||
@body.compile.status.should.equal "failure"
|
||||
|
||||
79
test/acceptance/coffee/ExampleDocumentTests.coffee
Normal file
79
test/acceptance/coffee/ExampleDocumentTests.coffee
Normal file
@@ -0,0 +1,79 @@
|
||||
Client = require "./helpers/Client"
|
||||
request = require "request"
|
||||
require("chai").should()
|
||||
fs = require "fs"
|
||||
ChildProcess = require "child_process"
|
||||
|
||||
fixturePath = (path) -> __dirname + "/../fixtures/" + path
|
||||
|
||||
convertToPng = (pdfPath, pngPath, callback = (error) ->) ->
|
||||
convert = ChildProcess.exec "convert #{fixturePath(pdfPath)} #{fixturePath(pngPath)}"
|
||||
convert.on "exit", () ->
|
||||
callback()
|
||||
|
||||
compare = (originalPath, generatedPath, callback = (error, same) ->) ->
|
||||
proc = ChildProcess.exec "compare -metric mae #{fixturePath(originalPath)} #{fixturePath(generatedPath)} #{fixturePath("tmp/diff.png")}"
|
||||
stderr = ""
|
||||
proc.stderr.on "data", (chunk) -> stderr += chunk
|
||||
proc.on "exit", () ->
|
||||
if stderr.trim() == "0 (0)"
|
||||
callback null, true
|
||||
else
|
||||
console.log stderr
|
||||
callback null, false
|
||||
|
||||
compareMultiplePages = (project_id, callback = (error) ->) ->
|
||||
compareNext = (page_no, callback) ->
|
||||
path = "tmp/#{project_id}-source-#{page_no}.png"
|
||||
fs.stat fixturePath(path), (error, stat) ->
|
||||
if error?
|
||||
callback()
|
||||
else
|
||||
compare "tmp/#{project_id}-source-#{page_no}.png", "tmp/#{project_id}-generated-#{page_no}.png", (error, same) =>
|
||||
throw error if error?
|
||||
same.should.equal true
|
||||
compareNext page_no + 1, callback
|
||||
compareNext 0, callback
|
||||
|
||||
downloadAndComparePdf = (project_id, example_dir, url, callback = (error) ->) ->
|
||||
writeStream = fs.createWriteStream(fixturePath("tmp/#{project_id}.pdf"))
|
||||
request.get(url).pipe(writeStream)
|
||||
writeStream.on "close", () =>
|
||||
convertToPng "tmp/#{project_id}.pdf", "tmp/#{project_id}-generated.png", (error) =>
|
||||
throw error if error?
|
||||
convertToPng "examples/#{example_dir}/output.pdf", "tmp/#{project_id}-source.png", (error) =>
|
||||
throw error if error?
|
||||
fs.stat fixturePath("tmp/#{project_id}-source-0.png"), (error, stat) =>
|
||||
if error?
|
||||
compare "tmp/#{project_id}-source.png", "tmp/#{project_id}-generated.png", (error, same) =>
|
||||
throw error if error?
|
||||
same.should.equal true
|
||||
callback()
|
||||
else
|
||||
compareMultiplePages project_id, (error) ->
|
||||
throw error if error?
|
||||
callback()
|
||||
|
||||
Client.runServer(4242, fixturePath("examples"))
|
||||
|
||||
describe "Example Documents", ->
|
||||
before (done) ->
|
||||
ChildProcess.exec("rm test/acceptance/fixtures/tmp/*").on "exit", () -> done()
|
||||
|
||||
for example_dir in fs.readdirSync fixturePath("examples")
|
||||
do (example_dir) ->
|
||||
describe example_dir, ->
|
||||
before ->
|
||||
@project_id = Client.randomId()
|
||||
|
||||
it "should generate the correct pdf", (done) ->
|
||||
Client.compileDirectory @project_id, fixturePath("examples"), example_dir, 4242, (error, res, body) =>
|
||||
pdf = Client.getOutputFile body, "pdf"
|
||||
downloadAndComparePdf(@project_id, example_dir, pdf.url, done)
|
||||
|
||||
it "should generate the correct pdf on the second run as well", (done) ->
|
||||
Client.compileDirectory @project_id, fixturePath("examples"), example_dir, 4242, (error, res, body) =>
|
||||
pdf = Client.getOutputFile body, "pdf"
|
||||
downloadAndComparePdf(@project_id, example_dir, pdf.url, done)
|
||||
|
||||
|
||||
39
test/acceptance/coffee/SimpleLatexFileTests.coffee
Normal file
39
test/acceptance/coffee/SimpleLatexFileTests.coffee
Normal file
@@ -0,0 +1,39 @@
|
||||
Client = require "./helpers/Client"
|
||||
request = require "request"
|
||||
require("chai").should()
|
||||
|
||||
describe "Simple LaTeX file", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
@request =
|
||||
resources: [
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\begin{document}
|
||||
Hello world
|
||||
\\end{document}
|
||||
'''
|
||||
]
|
||||
Client.compile @project_id, @request, (@error, @res, @body) => done()
|
||||
|
||||
it "should return the PDF", ->
|
||||
pdf = Client.getOutputFile(@body, "pdf")
|
||||
pdf.type.should.equal "pdf"
|
||||
|
||||
it "should return the log", ->
|
||||
log = Client.getOutputFile(@body, "log")
|
||||
log.type.should.equal "log"
|
||||
|
||||
it "should provide the pdf for download", (done) ->
|
||||
pdf = Client.getOutputFile(@body, "pdf")
|
||||
request.get pdf.url, (error, res, body) ->
|
||||
res.statusCode.should.equal 200
|
||||
done()
|
||||
|
||||
it "should provide the log for download", (done) ->
|
||||
log = Client.getOutputFile(@body, "pdf")
|
||||
request.get log.url, (error, res, body) ->
|
||||
res.statusCode.should.equal 200
|
||||
done()
|
||||
|
||||
27
test/acceptance/coffee/TimeoutTests.coffee
Normal file
27
test/acceptance/coffee/TimeoutTests.coffee
Normal file
@@ -0,0 +1,27 @@
|
||||
Client = require "./helpers/Client"
|
||||
request = require "request"
|
||||
require("chai").should()
|
||||
|
||||
describe "Timed out compile", ->
|
||||
before (done) ->
|
||||
@request =
|
||||
options:
|
||||
timeout: 0.01 #seconds
|
||||
resources: [
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\begin{document}
|
||||
Hello world
|
||||
\\end{document}
|
||||
'''
|
||||
]
|
||||
@project_id = Client.randomId()
|
||||
Client.compile @project_id, @request, (@error, @res, @body) => done()
|
||||
|
||||
it "should return a timeout error", ->
|
||||
@body.compile.error.should.equal "container timed out"
|
||||
|
||||
it "should return a failure status", ->
|
||||
@body.compile.status.should.equal "failure"
|
||||
|
||||
220
test/acceptance/coffee/UrlCachingTests.coffee
Normal file
220
test/acceptance/coffee/UrlCachingTests.coffee
Normal file
@@ -0,0 +1,220 @@
|
||||
Client = require "./helpers/Client"
|
||||
request = require "request"
|
||||
require("chai").should()
|
||||
sinon = require "sinon"
|
||||
|
||||
host = "localhost"
|
||||
|
||||
Server =
|
||||
run: () ->
|
||||
express = require "express"
|
||||
app = express()
|
||||
|
||||
staticServer = express.static __dirname + "/../fixtures/"
|
||||
app.get "/:random_id/*", (req, res, next) =>
|
||||
@getFile(req.url)
|
||||
req.url = "/" + req.params[0]
|
||||
staticServer(req, res, next)
|
||||
|
||||
app.listen 31415, host
|
||||
|
||||
getFile: () ->
|
||||
|
||||
randomId: () ->
|
||||
Math.random().toString(16).slice(2)
|
||||
|
||||
Server.run()
|
||||
|
||||
describe "Url Caching", ->
|
||||
describe "Downloading an image for the first time", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
@file = "#{Server.randomId()}/lion.png"
|
||||
@request =
|
||||
resources: [{
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\usepackage{graphicx}
|
||||
\\begin{document}
|
||||
\\includegraphics{lion.png}
|
||||
\\end{document}
|
||||
'''
|
||||
}, {
|
||||
path: "lion.png"
|
||||
url: "http://#{host}:31415/#{@file}"
|
||||
}]
|
||||
|
||||
sinon.spy Server, "getFile"
|
||||
Client.compile @project_id, @request, (@error, @res, @body) => done()
|
||||
|
||||
afterEach ->
|
||||
Server.getFile.restore()
|
||||
|
||||
it "should download the image", ->
|
||||
Server.getFile
|
||||
.calledWith("/" + @file)
|
||||
.should.equal true
|
||||
|
||||
describe "When an image is in the cache and the last modified date is unchanged", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
@file = "#{Server.randomId()}/lion.png"
|
||||
@request =
|
||||
resources: [{
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\usepackage{graphicx}
|
||||
\\begin{document}
|
||||
\\includegraphics{lion.png}
|
||||
\\end{document}
|
||||
'''
|
||||
}, @image_resource = {
|
||||
path: "lion.png"
|
||||
url: "http://#{host}:31415/#{@file}"
|
||||
modified: Date.now()
|
||||
}]
|
||||
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
sinon.spy Server, "getFile"
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
done()
|
||||
|
||||
after ->
|
||||
Server.getFile.restore()
|
||||
|
||||
it "should not download the image again", ->
|
||||
Server.getFile.called.should.equal false
|
||||
|
||||
describe "When an image is in the cache and the last modified date is advanced", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
@file = "#{Server.randomId()}/lion.png"
|
||||
@request =
|
||||
resources: [{
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\usepackage{graphicx}
|
||||
\\begin{document}
|
||||
\\includegraphics{lion.png}
|
||||
\\end{document}
|
||||
'''
|
||||
}, @image_resource = {
|
||||
path: "lion.png"
|
||||
url: "http://#{host}:31415/#{@file}"
|
||||
modified: @last_modified = Date.now()
|
||||
}]
|
||||
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
sinon.spy Server, "getFile"
|
||||
@image_resource.modified = new Date(@last_modified + 3000)
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
done()
|
||||
|
||||
afterEach ->
|
||||
Server.getFile.restore()
|
||||
|
||||
it "should download the image again", ->
|
||||
Server.getFile.called.should.equal true
|
||||
|
||||
describe "When an image is in the cache and the last modified date is further in the past", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
@file = "#{Server.randomId()}/lion.png"
|
||||
@request =
|
||||
resources: [{
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\usepackage{graphicx}
|
||||
\\begin{document}
|
||||
\\includegraphics{lion.png}
|
||||
\\end{document}
|
||||
'''
|
||||
}, @image_resource = {
|
||||
path: "lion.png"
|
||||
url: "http://#{host}:31415/#{@file}"
|
||||
modified: @last_modified = Date.now()
|
||||
}]
|
||||
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
sinon.spy Server, "getFile"
|
||||
@image_resource.modified = new Date(@last_modified - 3000)
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
done()
|
||||
|
||||
afterEach ->
|
||||
Server.getFile.restore()
|
||||
|
||||
it "should not download the image again", ->
|
||||
Server.getFile.called.should.equal false
|
||||
|
||||
describe "When an image is in the cache and the last modified date is not specified", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
@file = "#{Server.randomId()}/lion.png"
|
||||
@request =
|
||||
resources: [{
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\usepackage{graphicx}
|
||||
\\begin{document}
|
||||
\\includegraphics{lion.png}
|
||||
\\end{document}
|
||||
'''
|
||||
}, @image_resource = {
|
||||
path: "lion.png"
|
||||
url: "http://#{host}:31415/#{@file}"
|
||||
modified: @last_modified = Date.now()
|
||||
}]
|
||||
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
sinon.spy Server, "getFile"
|
||||
delete @image_resource.modified
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
done()
|
||||
|
||||
afterEach ->
|
||||
Server.getFile.restore()
|
||||
|
||||
it "should download the image again", ->
|
||||
Server.getFile.called.should.equal true
|
||||
|
||||
describe "After clearing the cache", ->
|
||||
before (done) ->
|
||||
@project_id = Client.randomId()
|
||||
@file = "#{Server.randomId()}/lion.png"
|
||||
@request =
|
||||
resources: [{
|
||||
path: "main.tex"
|
||||
content: '''
|
||||
\\documentclass{article}
|
||||
\\usepackage{graphicx}
|
||||
\\begin{document}
|
||||
\\includegraphics{lion.png}
|
||||
\\end{document}
|
||||
'''
|
||||
}, @image_resource = {
|
||||
path: "lion.png"
|
||||
url: "http://#{host}:31415/#{@file}"
|
||||
modified: @last_modified = Date.now()
|
||||
}]
|
||||
|
||||
Client.compile @project_id, @request, (error) =>
|
||||
throw error if error?
|
||||
Client.clearCache @project_id, (error, res, body) =>
|
||||
throw error if error?
|
||||
sinon.spy Server, "getFile"
|
||||
Client.compile @project_id, @request, (@error, @res, @body) =>
|
||||
done()
|
||||
|
||||
afterEach ->
|
||||
Server.getFile.restore()
|
||||
|
||||
it "should download the image again", ->
|
||||
Server.getFile.called.should.equal true
|
||||
|
||||
|
||||
69
test/acceptance/coffee/helpers/Client.coffee
Normal file
69
test/acceptance/coffee/helpers/Client.coffee
Normal file
@@ -0,0 +1,69 @@
|
||||
request = require "request"
|
||||
fs = require "fs"
|
||||
Settings = require "../../../../app/js/Settings"
|
||||
|
||||
host = "localhost"
|
||||
|
||||
module.exports = Client =
|
||||
host: Settings.externalUrl
|
||||
|
||||
randomId: () ->
|
||||
Math.random().toString(16).slice(2)
|
||||
|
||||
compile: (project_id, data, callback = (error, res, body) ->) ->
|
||||
request.post {
|
||||
url: "#{@host}/project/#{project_id}/compile"
|
||||
json:
|
||||
compile: data
|
||||
}, callback
|
||||
|
||||
clearCache: (project_id, callback = (error, res, body) ->) ->
|
||||
request.del "#{@host}/project/#{project_id}", callback
|
||||
|
||||
getOutputFile: (response, type) ->
|
||||
for file in response.compile.outputFiles
|
||||
if file.type == type
|
||||
return file
|
||||
return null
|
||||
|
||||
runServer: (port, directory) ->
|
||||
express = require("express")
|
||||
app = express()
|
||||
app.use express.static(directory)
|
||||
app.listen(port, host)
|
||||
|
||||
compileDirectory: (project_id, baseDirectory, directory, serverPort, callback = (error, res, body) ->) ->
|
||||
resources = []
|
||||
entities = fs.readdirSync("#{baseDirectory}/#{directory}")
|
||||
rootResourcePath = "main.tex"
|
||||
while (entities.length > 0)
|
||||
entity = entities.pop()
|
||||
stat = fs.statSync("#{baseDirectory}/#{directory}/#{entity}")
|
||||
if stat.isDirectory()
|
||||
entities = entities.concat fs.readdirSync("#{baseDirectory}/#{directory}/#{entity}").map (subEntity) ->
|
||||
if subEntity == "main.tex"
|
||||
rootResourcePath = "#{entity}/#{subEntity}"
|
||||
return "#{entity}/#{subEntity}"
|
||||
else if stat.isFile() and entity != "output.pdf"
|
||||
extension = entity.split(".").pop()
|
||||
if ["tex", "bib", "cls", "sty", "pdf_tex", "Rtex"].indexOf(extension) > -1
|
||||
resources.push
|
||||
path: entity
|
||||
content: fs.readFileSync("#{baseDirectory}/#{directory}/#{entity}").toString()
|
||||
else if ["eps", "ttf", "png", "jpg", "pdf", "jpeg"].indexOf(extension) > -1
|
||||
resources.push
|
||||
path: entity
|
||||
url: "http://#{host}:#{serverPort}/#{directory}/#{entity}"
|
||||
modified: stat.mtime
|
||||
|
||||
fs.readFile "#{baseDirectory}/#{directory}/options.json", (error, body) =>
|
||||
req =
|
||||
resources: resources
|
||||
rootResourcePath: rootResourcePath
|
||||
|
||||
if !error?
|
||||
body = JSON.parse body
|
||||
req.options = body
|
||||
|
||||
@compile project_id, req, callback
|
||||
|
||||
Reference in New Issue
Block a user