|
1 | 1 | #!/usr/bin/env node |
2 | | -'use strict'; |
3 | | - |
4 | | -const path = require('node:path'); |
5 | | -const process = require('node:process'); |
6 | | -const Listr = require('listr'); |
7 | | -const tempy = require('tempy'); |
8 | | -const execa = require('execa'); |
9 | | -const del = require('del'); |
10 | | -const chalk = require('chalk'); |
| 2 | +import process from 'node:process'; |
| 3 | +import path from 'node:path'; |
| 4 | +import fs from 'node:fs/promises'; |
| 5 | +import os from 'node:os'; |
| 6 | +import {execa} from 'execa'; |
| 7 | +import chalk from 'chalk'; |
11 | 8 |
|
12 | 9 | const packages = new Map([ |
13 | 10 | ['chalk', 'https://github.com/chalk/chalk'], |
@@ -45,144 +42,100 @@ const packages = new Map([ |
45 | 42 | ['got', 'https://github.com/sindresorhus/got'], |
46 | 43 | ]); |
47 | 44 |
|
48 | | -const cwd = path.join(__dirname, 'eslint-config-ava-tester'); |
| 45 | +const configDirectory = path.join(import.meta.dirname, 'eslint-config-ava-tester'); |
49 | 46 |
|
50 | | -const enrichErrors = (packageName, cliArguments, f) => async (...arguments_) => { |
51 | | - try { |
52 | | - return await f(...arguments_); |
53 | | - } catch (error) { |
54 | | - error.packageName = packageName; |
55 | | - error.cliArgs = cliArguments; |
56 | | - throw error; |
57 | | - } |
58 | | -}; |
59 | | - |
60 | | -const makeEslintTask = (packageName, destination, extraArguments = []) => { |
61 | | - const arguments_ = [ |
| 47 | +const runEslint = async (packageName, destination, extraArguments = []) => { |
| 48 | + const cliArguments = [ |
62 | 49 | 'eslint', |
63 | 50 | '--config', |
64 | | - path.join(cwd, 'index.js'), |
65 | | - '--no-eslintrc', |
66 | | - '--ext', |
67 | | - '.js,.ts', |
| 51 | + path.join(configDirectory, 'eslint.config.js'), |
| 52 | + '--no-config-lookup', |
68 | 53 | destination, |
69 | 54 | '--format', |
70 | 55 | 'json', |
71 | 56 | ...extraArguments, |
72 | 57 | ]; |
73 | 58 |
|
74 | | - return enrichErrors(packageName, arguments_, async () => { |
75 | | - let stdout; |
76 | | - let processError; |
77 | | - try { |
78 | | - ({stdout} = await execa('npx', arguments_, {cwd, localDir: __dirname})); |
79 | | - } catch (error) { |
80 | | - ({stdout} = error); |
81 | | - processError = error; |
| 59 | + let stdout; |
| 60 | + try { |
| 61 | + ({stdout} = await execa('npx', cliArguments, {cwd: configDirectory})); |
| 62 | + } catch (error) { |
| 63 | + ({stdout} = error); |
| 64 | + |
| 65 | + if (!stdout) { |
| 66 | + throw error; |
| 67 | + } |
| 68 | + } |
| 69 | + |
| 70 | + let files; |
| 71 | + try { |
| 72 | + files = JSON.parse(stdout); |
| 73 | + } catch (error) { |
| 74 | + console.error('Error while parsing eslint output:', error); |
| 75 | + throw error; |
| 76 | + } |
82 | 77 |
|
83 | | - if (!stdout) { |
| 78 | + for (const file of files) { |
| 79 | + for (const message of file.messages) { |
| 80 | + if (message.fatal) { |
| 81 | + const error = new Error(message.message); |
| 82 | + error.eslintFile = file; |
| 83 | + error.eslintMessage = message; |
84 | 84 | throw error; |
85 | 85 | } |
86 | 86 | } |
| 87 | + } |
| 88 | +}; |
87 | 89 |
|
88 | | - let files; |
89 | | - try { |
90 | | - files = JSON.parse(stdout); |
91 | | - } catch (error) { |
92 | | - console.error('Error while parsing eslint output:', error); |
| 90 | +const testPackage = async (name, url) => { |
| 91 | + const destination = await fs.mkdtemp(path.join(os.tmpdir(), `eslint-ava-${name}-`)); |
93 | 92 |
|
94 | | - if (processError) { |
95 | | - throw processError; |
96 | | - } |
| 93 | + try { |
| 94 | + console.log(`${chalk.cyan(name)}: Cloning...`); |
| 95 | + await execa('git', ['clone', url, '--single-branch', destination]); |
97 | 96 |
|
98 | | - throw error; |
99 | | - } |
| 97 | + console.log(`${chalk.cyan(name)}: Running eslint...`); |
| 98 | + await runEslint(name, destination); |
100 | 99 |
|
101 | | - for (const file of files) { |
102 | | - for (const message of file.messages) { |
103 | | - if (message.fatal) { |
104 | | - const error = new Error(message.message); |
105 | | - error.eslintFile = file; |
106 | | - error.eslintMessage = message; |
107 | | - throw error; |
108 | | - } |
109 | | - } |
110 | | - } |
111 | | - }); |
112 | | -}; |
| 100 | + console.log(`${chalk.cyan(name)}: Running eslint --fix...`); |
| 101 | + await runEslint(name, destination, ['--fix-dry-run']); |
113 | 102 |
|
114 | | -const execute = name => { |
115 | | - const destination = tempy.directory(); |
116 | | - |
117 | | - return new Listr([ |
118 | | - { |
119 | | - title: 'Cloning', |
120 | | - task: () => execa('git', ['clone', packages.get(name), '--single-branch', destination]), |
121 | | - }, |
122 | | - { |
123 | | - title: 'Running eslint', |
124 | | - task: makeEslintTask(name, destination), |
125 | | - }, |
126 | | - { |
127 | | - title: 'Running eslint --fix', |
128 | | - task: makeEslintTask(name, destination, ['--fix-dry-run']), |
129 | | - }, |
130 | | - { |
131 | | - title: 'Clean up', |
132 | | - task: () => del(destination, {force: true}), |
133 | | - }, |
134 | | - ].map(({title, task}) => ({ |
135 | | - title: `${name} / ${title}`, |
136 | | - task, |
137 | | - })), { |
138 | | - exitOnError: false, |
139 | | - }); |
| 103 | + console.log(`${chalk.green(name)}: Passed`); |
| 104 | + } catch (error) { |
| 105 | + error.packageName = name; |
| 106 | + throw error; |
| 107 | + } finally { |
| 108 | + await fs.rm(destination, {recursive: true, force: true}); |
| 109 | + } |
140 | 110 | }; |
141 | 111 |
|
142 | | -const list = new Listr([ |
143 | | - { |
144 | | - title: 'Setup', |
145 | | - task: () => execa('npm', ['install', '../../..', 'eslint', 'babel-eslint', 'typescript', '@typescript-eslint/parser'], {cwd}), |
146 | | - }, |
147 | | - { |
148 | | - title: 'Integration tests', |
149 | | - task() { |
150 | | - const tests = new Listr({concurrent: true}); |
151 | | - |
152 | | - for (const [name] of packages) { |
153 | | - tests.add([ |
154 | | - { |
155 | | - title: name, |
156 | | - task: () => execute(name), |
157 | | - }, |
158 | | - ]); |
159 | | - } |
| 112 | +// Setup |
| 113 | +console.log('Installing dependencies...'); |
| 114 | +await execa('npm', ['install'], {cwd: configDirectory}); |
| 115 | + |
| 116 | +// Run integration tests concurrently |
| 117 | +console.log('Running integration tests...'); |
| 118 | +const results = await Promise.allSettled( |
| 119 | + [...packages].map(([name, url]) => testPackage(name, url)), |
| 120 | +); |
| 121 | + |
| 122 | +// Report failures |
| 123 | +const failures = results.filter(result => result.status === 'rejected'); |
| 124 | +if (failures.length > 0) { |
| 125 | + for (const {reason} of failures) { |
| 126 | + console.error('\n', chalk.red.bold.underline(reason.packageName)); |
| 127 | + console.error(reason.message); |
| 128 | + |
| 129 | + if (reason.stderr) { |
| 130 | + console.error(chalk.gray(reason.stderr)); |
| 131 | + } |
160 | 132 |
|
161 | | - return tests; |
162 | | - }, |
163 | | - }, |
164 | | -], { |
165 | | - renderer: process.env.INTEGRATION ? 'verbose' : 'default', |
166 | | -}); |
167 | | - |
168 | | -list.run() |
169 | | - .catch(error => { |
170 | | - if (error.errors) { |
171 | | - for (const error2 of error.errors) { |
172 | | - console.error('\n', chalk.red.bold.underline(error2.packageName), chalk.gray('(' + error2.cliArgs.join(' ') + ')')); |
173 | | - console.error(error2.message); |
174 | | - |
175 | | - if (error2.stderr) { |
176 | | - console.error(chalk.gray(error2.stderr)); |
177 | | - } |
178 | | - |
179 | | - if (error2.eslintMessage) { |
180 | | - console.error(chalk.gray(error2.eslintFile.filePath), chalk.gray(JSON.stringify(error2.eslintMessage, null, 2))); |
181 | | - } |
182 | | - } |
183 | | - } else { |
184 | | - console.error(error); |
| 133 | + if (reason.eslintMessage) { |
| 134 | + console.error(chalk.gray(reason.eslintFile.filePath), chalk.gray(JSON.stringify(reason.eslintMessage, undefined, 2))); |
185 | 135 | } |
| 136 | + } |
| 137 | + |
| 138 | + process.exit(1); |
| 139 | +} |
186 | 140 |
|
187 | | - process.exit(1); |
188 | | - }); |
| 141 | +console.log(chalk.green('\nAll integration tests passed!')); |
0 commit comments