diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2c38732..1bad614 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,15 @@ on: branches: [main] jobs: + lint: + name: Lint JS + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Lint JS + run: npx --yes oxlint@latest -D perf + test: name: Unit tests runs-on: ubuntu-latest @@ -23,9 +32,9 @@ jobs: - 18 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: npm diff --git a/package-lock.json b/package-lock.json index 2e3284a..0f2252b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ }, "devDependencies": { "microbundle": "^0.15.1", + "oxlint": "^0.2.13", "uvu": "^0.5.6" } }, @@ -1809,6 +1810,110 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@oxlint/darwin-arm64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-0.2.13.tgz", + "integrity": "sha512-mocMLfP4TDIfXDE6HkzJABDiTngdrZtFL27sI8jkB9BcezexZk6/qFihrupnMeGthTUbptsc9ViOHAwAXaKwBw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/darwin-x64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-0.2.13.tgz", + "integrity": "sha512-ylq7QvWNE+RNdgFpAQFYNPvkaA1+MO3UqRTlllDBW3eCVQ0QqHq0z1ZV+TlwwGdIgW+hwP4S62uSXegqY5JXSA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/linux-arm64-gnu": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-0.2.13.tgz", + "integrity": "sha512-nW22QvaUirWlLQJ+qgQ3ufhNlql/T2Jnqq5VyCDPqUKslnPy/IwdqdC8pshED7b5gOSoeIcf2BJo6kA1p5K29w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-arm64-musl": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-0.2.13.tgz", + "integrity": "sha512-+PDSLyOAgTIUz7FTll+N8aRnFrLqPRMFrPwRNuyR64VlA6/43zH0VAuZnIMlkJcAE0qvS+5vsMQTUjZpCRkP2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-gnu": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-0.2.13.tgz", + "integrity": "sha512-Xcr20ELJ+M928abYly4MPUmzkdb47aIDWB9brEmDhRQH6YvQr04iObQg8cm39Ftu/wKOvej2JxWJtYCv6DZhXw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-musl": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-0.2.13.tgz", + "integrity": "sha512-SyR8dVaK9siHio71UiEfH36065LwDJ2waxjF7V25MG3voVWMdEDktBIcwXQEXNrQpqbCur54SGaq8X0lnFFskA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/win32-arm64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-0.2.13.tgz", + "integrity": "sha512-Eb+ZQKozJJQjzvp/p7EfV60RMrcY6BaNAXPkU53KdynlexIlMCVQMCUmxOl9nwFoXJeVEc4C9tyn1HqA10JzOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint/win32-x64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-0.2.13.tgz", + "integrity": "sha512-bup+fpJBq31qpCA/riWmPQc4osebS/62OFtgPVAThsmhwUPJ5RD49GA5fbEH3DRSq2KMjbvMEEPpM94KguveVg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@projectwallace/css-analyzer": { "version": "5.14.0", "resolved": "https://registry.npmjs.org/@projectwallace/css-analyzer/-/css-analyzer-5.14.0.tgz", @@ -4125,6 +4230,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/oxlint": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-0.2.13.tgz", + "integrity": "sha512-Ae42i+QPO3TBuC4RQMZ5nsDPfm2q3wOMld5UGkZd29mdGspqnADC1JIOO5YAHYwf4Wwlx9lj+S4piA9qUCijdw==", + "dev": true, + "bin": { + "oxlint": "bin/oxlint" + }, + "engines": { + "node": ">=14.*" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxlint/darwin-arm64": "0.2.13", + "@oxlint/darwin-x64": "0.2.13", + "@oxlint/linux-arm64-gnu": "0.2.13", + "@oxlint/linux-arm64-musl": "0.2.13", + "@oxlint/linux-x64-gnu": "0.2.13", + "@oxlint/linux-x64-musl": "0.2.13", + "@oxlint/win32-arm64": "0.2.13", + "@oxlint/win32-x64": "0.2.13" + } + }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -7154,6 +7284,62 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@oxlint/darwin-arm64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-0.2.13.tgz", + "integrity": "sha512-mocMLfP4TDIfXDE6HkzJABDiTngdrZtFL27sI8jkB9BcezexZk6/qFihrupnMeGthTUbptsc9ViOHAwAXaKwBw==", + "dev": true, + "optional": true + }, + "@oxlint/darwin-x64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-0.2.13.tgz", + "integrity": "sha512-ylq7QvWNE+RNdgFpAQFYNPvkaA1+MO3UqRTlllDBW3eCVQ0QqHq0z1ZV+TlwwGdIgW+hwP4S62uSXegqY5JXSA==", + "dev": true, + "optional": true + }, + "@oxlint/linux-arm64-gnu": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-0.2.13.tgz", + "integrity": "sha512-nW22QvaUirWlLQJ+qgQ3ufhNlql/T2Jnqq5VyCDPqUKslnPy/IwdqdC8pshED7b5gOSoeIcf2BJo6kA1p5K29w==", + "dev": true, + "optional": true + }, + "@oxlint/linux-arm64-musl": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-0.2.13.tgz", + "integrity": "sha512-+PDSLyOAgTIUz7FTll+N8aRnFrLqPRMFrPwRNuyR64VlA6/43zH0VAuZnIMlkJcAE0qvS+5vsMQTUjZpCRkP2w==", + "dev": true, + "optional": true + }, + "@oxlint/linux-x64-gnu": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-0.2.13.tgz", + "integrity": "sha512-Xcr20ELJ+M928abYly4MPUmzkdb47aIDWB9brEmDhRQH6YvQr04iObQg8cm39Ftu/wKOvej2JxWJtYCv6DZhXw==", + "dev": true, + "optional": true + }, + "@oxlint/linux-x64-musl": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-0.2.13.tgz", + "integrity": "sha512-SyR8dVaK9siHio71UiEfH36065LwDJ2waxjF7V25MG3voVWMdEDktBIcwXQEXNrQpqbCur54SGaq8X0lnFFskA==", + "dev": true, + "optional": true + }, + "@oxlint/win32-arm64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-0.2.13.tgz", + "integrity": "sha512-Eb+ZQKozJJQjzvp/p7EfV60RMrcY6BaNAXPkU53KdynlexIlMCVQMCUmxOl9nwFoXJeVEc4C9tyn1HqA10JzOQ==", + "dev": true, + "optional": true + }, + "@oxlint/win32-x64": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-0.2.13.tgz", + "integrity": "sha512-bup+fpJBq31qpCA/riWmPQc4osebS/62OFtgPVAThsmhwUPJ5RD49GA5fbEH3DRSq2KMjbvMEEPpM94KguveVg==", + "dev": true, + "optional": true + }, "@projectwallace/css-analyzer": { "version": "5.14.0", "resolved": "https://registry.npmjs.org/@projectwallace/css-analyzer/-/css-analyzer-5.14.0.tgz", @@ -8863,6 +9049,22 @@ "is-wsl": "^2.2.0" } }, + "oxlint": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-0.2.13.tgz", + "integrity": "sha512-Ae42i+QPO3TBuC4RQMZ5nsDPfm2q3wOMld5UGkZd29mdGspqnADC1JIOO5YAHYwf4Wwlx9lj+S4piA9qUCijdw==", + "dev": true, + "requires": { + "@oxlint/darwin-arm64": "0.2.13", + "@oxlint/darwin-x64": "0.2.13", + "@oxlint/linux-arm64-gnu": "0.2.13", + "@oxlint/linux-arm64-musl": "0.2.13", + "@oxlint/linux-x64-gnu": "0.2.13", + "@oxlint/linux-x64-musl": "0.2.13", + "@oxlint/win32-arm64": "0.2.13", + "@oxlint/win32-x64": "0.2.13" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", diff --git a/package.json b/package.json index 60fe154..87a129a 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "types": "./dist/index.d.ts", "scripts": { "test": "uvu", + "lint": "oxlint", "build": "microbundle" }, "dependencies": { @@ -44,6 +45,7 @@ }, "devDependencies": { "microbundle": "^0.15.1", + "oxlint": "^0.2.13", "uvu": "^0.5.6" } -} \ No newline at end of file +} diff --git a/src/complexity.test.js b/src/complexity.test.js index 4f235bc..fe31a52 100644 --- a/src/complexity.test.js +++ b/src/complexity.test.js @@ -6,13 +6,13 @@ const Complexity = suite('Complexity') Complexity('should deduct points for a lot of Selectors more complex than most common Complexity', () => { const fixture = ` - ${new Array(1000) + ${Array.from({ length: 1000 }) .fill('') .map(_ => `selector { }`) .join('') } - ${new Array(500) + ${Array.from({ length: 500 }) .fill('') .map(_ => `:where(selector) { }`) .join('') @@ -25,7 +25,7 @@ Complexity('should deduct points for a lot of Selectors more complex than most c id: 'MoreThanMostCommonSelectorComplexity', score: 5, value: 1 / 3, - actuals: (new Array(1000).fill(1)).concat(new Array(500).fill(2)), + actuals: (Array.from({ length: 1000 }).fill(1)).concat(Array.from({ length: 500 }).fill(2)), } ]) assert.is(actual.complexity.score, 95) @@ -33,13 +33,13 @@ Complexity('should deduct points for a lot of Selectors more complex than most c Complexity('should deduct points for a lot of Selectors more complex than most common Specificity', () => { const fixture = ` - ${new Array(500) + ${Array.from({ length: 500 }) .fill('') .map(_ => `selector1 { }`) .join('') } - ${new Array(200) + ${Array.from({ length: 200 }) .fill('') .map(_ => `.selector { }`) .join('') @@ -52,7 +52,7 @@ Complexity('should deduct points for a lot of Selectors more complex than most c id: 'MoreThanMostCommonSelectorSpecificity', score: 2, value: 200 / 700, - actuals: (new Array(500).fill([0, 0, 1])).concat(new Array(200).fill([0, 1, 0])), + actuals: (Array.from({ length: 500 }).fill([0, 0, 1])).concat(Array.from({ length: 200 }).fill([0, 1, 0])), } ]) assert.is(actual.complexity.score, 98) diff --git a/src/maintainability.test.js b/src/maintainability.test.js index 9bbfd7b..ab29961 100644 --- a/src/maintainability.test.js +++ b/src/maintainability.test.js @@ -11,7 +11,7 @@ Maintainability('does not deduct points for 1 SLoC', () => { }) Maintainability('deducts points for having lots of SLoC', () => { - const fixture = new Array(10_000) + const fixture = Array.from({ length: 10_000 }) .fill('') .map((_, index) => `selector-${index} { opacity: 0.${index}}`) .join('') @@ -109,7 +109,7 @@ Maintainability('deducts points for having too many Declarations in a single Rul } selector2 { - ${new Array(23) + ${Array.from({ length: 23 }) .fill('') .map(i => `z-index: ${i};`) .join('') @@ -136,13 +136,13 @@ Maintainability('deducts points for having too many Declarations in a single Rul Maintainability('deducts points for having RuleSets with more Selectors than what is most common', () => { const fixture = ` - ${new Array(1000) + ${Array.from({ length: 1000 }) .fill('') .map(index => `selector-${index} {}`) .join('') } - ${new Array(500) + ${Array.from({ length: 500 }) .fill('') .map(index => `selector-${index}a, selector-${index}-b {}`) .join('') @@ -155,7 +155,7 @@ Maintainability('deducts points for having RuleSets with more Selectors than wha id: 'MoreThanMostCommonSelectorsPerRule', score: 5, value: 1, - actuals: (new Array(1000).fill(1)).concat(new Array(500).fill(2)), + actuals: (Array.from({ length: 1000 }).fill(1)).concat(Array.from({ length: 500 }).fill(2)), }, ]) assert.is(actual.maintainability.score, 95) @@ -163,13 +163,13 @@ Maintainability('deducts points for having RuleSets with more Selectors than wha Maintainability('deducts points for having RuleSets with more Selectors than what is most common', () => { const fixture = ` - ${new Array(1000) + ${Array.from({ length: 1000 }) .fill('') .map(index => `selector-${index}a { z-index: ${index}; }`) .join('') } - ${new Array(500) + ${Array.from({ length: 500 }) .fill('') .map(index => `selector-${index}b { z-index: ${index}; content: "${index}" }`) .join('') @@ -182,7 +182,7 @@ Maintainability('deducts points for having RuleSets with more Selectors than wha id: 'MoreThanMostCommonDeclarationsPerRule', score: 5, value: 1, - actuals: (new Array(1000).fill(1)).concat(new Array(500).fill(2)), + actuals: (Array.from({ length: 1000 }).fill(1)).concat(Array.from({ length: 500 }).fill(2)), }, ]) assert.is(actual.maintainability.score, 95) diff --git a/src/performance.test.js b/src/performance.test.js index ca2d6c9..cc2d3da 100644 --- a/src/performance.test.js +++ b/src/performance.test.js @@ -140,7 +140,7 @@ Performance('does not deduct points for small stylesheets', () => { }) Performance('deducts points for large stylesheets', () => { - const fixture = new Array(10_000) + const fixture = Array.from({ length: 10_000 }) .fill('') .map((_, index) => `selector-${index} { opacity: 0.${index}}`) .join('') @@ -150,7 +150,7 @@ Performance('deducts points for large stylesheets', () => { }) Performance('deducts points for having comments', () => { - const fixture = new Array(100) + const fixture = Array.from({ length: 100 }) .fill('/* a comment to take up some space */') .map((comment, index) => `${comment} selector-${index} { opacity: 0.${index} }`) .join('') @@ -170,7 +170,7 @@ Performance('deducts points for having embedded content', () => { function generateEmbed(index) { return `data:image/svg+xml,%3Csvg%20id%3D%22Layer_${index}%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20195.6%20107.8%22%3E%3Cpath%20fill%3D%22%23B5B5B5%22%20class%3D%22st0%22%20d%3D%22M97.8%20107.8c-2.6%200-5.1-1-7.1-2.9L2.9%2017.1C-1%2013.2-1%206.8%202.9%202.9%206.8-1%2013.2-1%2017.1%202.9l80.7%2080.7%2080.7-80.7c3.9-3.9%2010.2-3.9%2014.1%200%203.9%203.9%203.9%2010.2%200%2014.1l-87.8%2087.8c-1.9%202-4.4%203-7%203z%22%2F%3E%3C%2Fsvg%3E` } - const fixture = new Array(100) + const fixture = Array.from({ length: 100 }) .fill('') .map((_, index) => ` selector-${index} { @@ -186,7 +186,7 @@ Performance('deducts points for having embedded content', () => { id: 'TooMuchEmbeddedContent', score: 20, value: 45990, - actuals: new Array(100).fill('').map((_, index) => generateEmbed(index)), + actuals: Array.from({ length: 100 }).fill('').map((_, index) => generateEmbed(index)), }, ]) })