test/e2e/compilation.spec.ts
import retry from 'bluebird-retry'
import chai, { assert, expect } from 'chai'
import chaiAsPromised from 'chai-as-promised'
import forEach from 'mocha-each'
import { InputOptions, OutputOptions } from 'rollup'
import sinon from 'sinon'
import sinonChai from 'sinon-chai'
import preprocessor, { PreprocessorOptions } from '../../src'
import { createFixtureFile, FixtureFile } from '../fixtures'
import { chaiSnapshot } from '../helpers/match-snapshot'
chai.use(sinonChai)
chai.use(chaiAsPromised)
chai.use(chaiSnapshot)
describe('compilation - e2e', function () {
let file: FixtureFile
beforeEach(async function () {
await FixtureFile.reset()
})
afterEach(function () {
file.close()
})
describe('test preprocessor output', function () {
it('correctly preprocesses the file', async function () {
file = await createFixtureFileAndRunPreprocessor()
await expect(file.getOutputFileContent()).to.eventually.matchSnapshot
})
it('correctly preprocesses the file using input options', async function () {
file = createFixtureFile({ name: 'success_spec.ts' })
const inputOptions: InputOptions = {
plugins: [
require('rollup-plugin-typescript2')({
tsconfigOverride: {
compilerOptions: {
module: 'esnext',
},
},
}),
],
}
await runPreprocessor(file, { inputOptions })
await expect(file.getOutputFileContent()).to.eventually.matchSnapshot
})
it('correctly preprocesses using output options', async function () {
file = createFixtureFile({ name: 'success_spec.js' })
const outputOptions: OutputOptions = {
format: 'umd',
}
await runPreprocessor(file, { outputOptions })
await expect(file.getOutputFileContent()).to.eventually.matchSnapshot
})
forEach([
['syntax error'],
['console.log("valid modification")'],
])
.it('correctly reprocesses the file after a modification (%s)', async (modification) => {
file = await createFixtureFileAndRunPreprocessor({ shouldWatch: true })
await file.writeOnInputFile(modification)
await listenForRerunEvent(file)
await expect(file.getOutputFileContent()).to.eventually.matchSnapshot
})
it('support watching the same file multiple times parallelly', async function () {
file = createFixtureFile({ shouldWatch: true })
const [firstOutput, secondOutput] = await Promise.all([
runPreprocessor(file),
runPreprocessor(file),
])
expect(firstOutput).to.be.equal(secondOutput)
})
it('support watching the same file multiple times sequencialy', async function () {
file = createFixtureFile({ shouldWatch: true })
await runPreprocessor(file)
const firstOutput = await file.getOutputFileContent()
await runPreprocessor(file)
const secondOutput = await file.getOutputFileContent()
expect(firstOutput).to.be.equal(secondOutput)
})
forEach([
'error_due_importing_nonexistent_file_spec.js',
'error_due_invalid_syntax_spec.js',
])
.it('has less verbose error message (%s)', async (name) => {
file = createFixtureFile({ name })
await expect(runPreprocessor(file))
.to.eventually.be.rejected
.and.to.matchSnapshot
})
forEach([
true,
false,
])
.it('throws on invalid file (%s)', async (shouldWatch) => {
await expect(runPreprocessor(new FixtureFile('', shouldWatch), {}))
.to.eventually.be.rejected
.and.to.matchSnapshot
})
})
describe('test event emission', function () {
forEach([
'this is a syntax error',
'console.log("this is a valid modification")',
])
.it('triggers rerun after a modification (%s)', async () => {
file = await createFixtureFileAndRunPreprocessor({ shouldWatch: true })
await file.writeOnInputFile('console.log()')
await listenForRerunEvent(file)
})
it('does not trigger rerun on initial build', async function () {
file = await createFixtureFileAndRunPreprocessor({ shouldWatch: true })
expect(file.emit).not.to.be.calledWith('rerun')
})
it('does not trigger rerun on errored initial build', async function () {
file = createFixtureFile({ name: 'error_due_invalid_syntax_spec.js', shouldWatch: true })
spyOnEmitMethod(file)
try {
await runPreprocessor(file)
assert.fail()
} catch {
expect(file.emit).not.to.be.calledWith('rerun')
}
})
it('triggers rerun on subsequent builds, even after a errored initial build', async function () {
file = createFixtureFile({ name: 'error_due_invalid_syntax_spec.js', shouldWatch: true })
spyOnEmitMethod(file)
try {
await runPreprocessor(file)
assert.fail()
} catch {
await file.writeOnInputFile('console.log()')
await listenForRerunEvent(file)
}
})
})
})
async function createFixtureFileAndRunPreprocessor (createFileOpts?: Parameters<typeof createFixtureFile>[0], preprocessorOpts?: PreprocessorOptions): Promise<FixtureFile> {
const file = createFixtureFile(createFileOpts)
spyOnEmitMethod(file)
await runPreprocessor(file, preprocessorOpts)
return file
}
async function runPreprocessor (file: FixtureFile, options?: PreprocessorOptions): Promise<string> {
const result = await preprocessor(options)(file)
// MAC OS bug
if (file.shouldWatch) {
await new Promise<void>((resolve) => setTimeout(resolve, 100))
}
return result
}
function spyOnEmitMethod (file: FixtureFile) {
return sinon.spy(file, 'emit')
}
function listenForRerunEvent (file: FixtureFile) {
return retry(() => expect(file.emit).calledWith('rerun'), { max_tries: 20 })
}