Skip to content

Commit

Permalink
chore: better type checking
Browse files Browse the repository at this point in the history
  • Loading branch information
ThisIsManta committed Jan 7, 2024
1 parent 860a522 commit d66d93f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 32 deletions.
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env node

// @ts-check

const fs = require('fs')
const path = require('path')

Expand Down Expand Up @@ -52,6 +54,8 @@ if (process.argv.includes('test')) {
* Returns the current dependent repository path which `.git` directory resides.
*
* Do not write `require('../../package.json')` which might break when using PNPM.
* @param {string} workPath
* @returns {string | null}
*/
function findRootPath(workPath) {
if (workPath === path.dirname(workPath)) {
Expand Down
86 changes: 54 additions & 32 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,89 @@
// @ts-check

const { RuleTester } = require('eslint')
const chalk = require('chalk')

/**
* @typedef {{
* valid: Array<import('eslint').RuleTester.ValidTestCase>
* invalid: Array<import('eslint').RuleTester.InvalidTestCase>
* }} TestCases
*/

/**
* @param {Record<string, import('eslint').Rule.RuleModule & { tests?: TestCases }>} rules
* @returns {void | false}
*/
module.exports = function test(rules) {
// See https://eslint.org/docs/latest/integrate/nodejs-api#ruletester
const tester = new RuleTester()

const exclusiveTestCases = []
global.only = function only(testCase) {
exclusiveTestCases.push(testCase)
return testCase
}

for (const name in rules) {
const rule = rules[name]
if (!rule.tests) {
console.log('🟡 ' + name)
for (const ruleName in rules) {
const ruleModule = rules[ruleName]
if (!ruleModule.tests || typeof ruleModule.tests !== 'object') {
console.log(' ' + ruleName)
continue
}

let skipped = false
for (const type of ['valid', 'invalid']) {
for (const test of rule.tests[type]) {
if (test === null || typeof test !== 'object' || typeof test.code !== 'string') {
continue
}

if (exclusiveTestCases.length > 0 && !exclusiveTestCases.includes(test)) {
skipped = true
continue
}

try {
tester.run(name, rule, { valid: [], invalid: [], [type]: [test] })
const validItems = ruleModule.tests.valid.map(testCase => (
{ testCase, valid: [testCase], invalid: [] }
))
const invalidItems = ruleModule.tests.invalid.map(testCase => (
{ testCase, valid: [], invalid: [testCase] }
))

for (const { testCase, valid, invalid } of [...validItems, ...invalidItems]) {
if (exclusiveTestCases.length > 0 && !exclusiveTestCases.includes(testCase)) {
skipped = true
continue
}

} catch (error) {
console.log('🔴 ' + chalk.bold(name))
try {
tester.run(ruleName, ruleModule, { valid, invalid })

console.log('')
console.log(offset(getPrettyCode(test.code), chalk.bgRed))
console.log('')
} catch (error) {
console.log('🔴 ' + chalk.bold(ruleName))

console.error(offset(error.message, chalk.red))
if (error.stack) {
console.error(offset(error.stack, chalk.red))
}
console.log('')
console.log(offset(getPrettyCode(testCase.code), chalk.bgRed))
console.log('')

return false
console.error(offset(error.message, chalk.red))
if (error.stack) {
console.error(offset(error.stack, chalk.red))
}

return false
}
}

console.log((skipped ? '🟡' : '✅') + ' ' + name)
console.log((skipped ? '🟡' : '✅') + ' ' + ruleName)
}

console.log('')
console.log(`Done testing ${Object.keys(rules).length} rule${Object.keys(rules).length === 1 ? '' : 's'}.`)
}

global.only = function only(testCase) {
exclusiveTestCases.push(testCase)
return testCase
}

/**
* @param {string} text
* @param {(line: string) => string} [decorateLine=line => line]
*/
function offset(text, decorateLine = line => line) {
return text.split('\n').map(line => ' ' + decorateLine(line)).join('\n')
}

/**
* @param {string} text
* @returns {string}
*/
function getPrettyCode(text) {
const trimmedCode = text.split('\n').filter((line, rank, list) =>
(rank === 0 || rank === list.length - 1) ? line.trim().length > 0 : true
Expand Down

0 comments on commit d66d93f

Please sign in to comment.