mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
* add integration test tools * setup jest in the integrations folder * add `test:integrations` script The default `npm test` script will ignore all the tests in the `integrations` folder. * add integration tests with `webpack 5` * add integration tests with `postcss-cli` * add `npm run install:integrations` script This script will run `npm install` in every integration, and in the integrations folder itself (to setup Jest for example). * add `toIncludeCss` custom matcher * increate Jest timeout for integration tests * add integration tests with `vite` * add integration tests with `webpack 4` * add isomorphic fetch * add the ability to wait for specific stdout/stderr output * write vite tests, assert using API calls We will wait for the correct stdout/stderr output, once we know that we can request the fresh css, we will fetch it and make assertions accordingly. Port is currently hardcoded, maybe we should use a packaage to ensure that we use a free port. * add integration tests with `rollup` * add integration tests with `parcel` * run all integration tests in band * add .gitignore in integrations folder
100 lines
2.3 KiB
JavaScript
100 lines
2.3 KiB
JavaScript
let path = require('path')
|
|
let { spawn } = require('child_process')
|
|
let resolveToolRoot = require('./resolve-tool-root')
|
|
|
|
let runningProcessess = []
|
|
|
|
afterEach(() => {
|
|
runningProcessess.splice(0).forEach((runningProcess) => runningProcess.stop())
|
|
})
|
|
|
|
module.exports = function $(command, options = {}) {
|
|
let abortController = new AbortController()
|
|
let cwd = resolveToolRoot()
|
|
|
|
let args = command.split(' ')
|
|
command = args.shift()
|
|
command = path.resolve(cwd, 'node_modules', '.bin', command)
|
|
|
|
let stdoutMessages = []
|
|
let stderrMessages = []
|
|
|
|
let stdoutActors = []
|
|
let stderrActors = []
|
|
|
|
function notifyNext(actors, messages) {
|
|
if (actors.length <= 0) return
|
|
let [next] = actors
|
|
|
|
for (let [idx, message] of messages.entries()) {
|
|
if (next.predicate(message)) {
|
|
messages.splice(0, idx + 1)
|
|
let actorIdx = actors.indexOf(next)
|
|
actors.splice(actorIdx, 1)
|
|
next.resolve()
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
function notifyNextStdoutActor() {
|
|
return notifyNext(stdoutActors, stdoutMessages)
|
|
}
|
|
|
|
function notifyNextStderrActor() {
|
|
return notifyNext(stderrActors, stderrMessages)
|
|
}
|
|
|
|
let runningProcess = new Promise((resolve, reject) => {
|
|
let child = spawn(command, args, {
|
|
...options,
|
|
env: {
|
|
...process.env,
|
|
...options.env,
|
|
},
|
|
signal: abortController.signal,
|
|
cwd,
|
|
})
|
|
|
|
let stdout = ''
|
|
let stderr = ''
|
|
|
|
child.stdout.on('data', (data) => {
|
|
stdoutMessages.push(data.toString())
|
|
notifyNextStdoutActor()
|
|
stdout += data
|
|
})
|
|
|
|
child.stderr.on('data', (data) => {
|
|
stderrMessages.push(data.toString())
|
|
notifyNextStderrActor()
|
|
stderr += data
|
|
})
|
|
|
|
child.on('close', (code, signal) => {
|
|
;(signal === 'SIGTERM' ? resolve : code === 0 ? resolve : reject)({ code, stdout, stderr })
|
|
})
|
|
})
|
|
|
|
runningProcessess.push(runningProcess)
|
|
|
|
return Object.assign(runningProcess, {
|
|
stop() {
|
|
abortController.abort()
|
|
return runningProcess
|
|
},
|
|
onStdout(predicate) {
|
|
return new Promise((resolve) => {
|
|
stdoutActors.push({ predicate, resolve })
|
|
notifyNextStdoutActor()
|
|
})
|
|
},
|
|
onStderr(predicate) {
|
|
return new Promise((resolve) => {
|
|
stderrActors.push({ predicate, resolve })
|
|
notifyNextStderrActor()
|
|
})
|
|
},
|
|
})
|
|
}
|