diff --git a/.prettierignore b/.prettierignore index d831b3e04bd..88ed0a8538c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -15,6 +15,7 @@ MOCK_DATA.json # unconventional blueprints/ vendor/ +!tests/blueprints/ # prettier is reporting syntax errors in these *.yml diff --git a/config/eslint/ignore.cjs b/config/eslint/ignore.cjs index ea7272fde81..c337eab5bb1 100644 --- a/config/eslint/ignore.cjs +++ b/config/eslint/ignore.cjs @@ -1,6 +1,7 @@ const RULES = [ // # unconventional js 'blueprints/', + '!tests/blueprints/', 'vendor', // # Declaration files diff --git a/config/eslint/mocha.cjs b/config/eslint/mocha.cjs new file mode 100644 index 00000000000..fc50ce88a28 --- /dev/null +++ b/config/eslint/mocha.cjs @@ -0,0 +1,20 @@ +const isolation = require('./isolation.cjs'); + +function defaults(config = {}) { + return { + files: config.files || ['tests/**/*-test.{js,ts}'], + plugins: ['mocha'], + extends: ['plugin:mocha/recommended'], + env: { + node: true, + }, + rules: { + // We use setup to set up beforeEach hooks, etc, which should be OK + 'mocha/no-setup-in-describe': 'off', + }, + }; +} + +module.exports = { + defaults, +}; diff --git a/config/eslint/qunit.cjs b/config/eslint/qunit.cjs index e0428b6d216..e836f0a4307 100644 --- a/config/eslint/qunit.cjs +++ b/config/eslint/qunit.cjs @@ -8,6 +8,7 @@ function defaults(config = {}) { isolation.rules({ allowedImports: ['@ember/debug', '@ember/test-helpers', 'qunit'], }), + config?.rules, {} ), }; diff --git a/config/package.json b/config/package.json index 16de6938cd3..122323d0f4c 100644 --- a/config/package.json +++ b/config/package.json @@ -11,6 +11,7 @@ "eslint": "^8.52.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-import": "^2.29.0", + "eslint-plugin-mocha": "^10.2.0", "eslint-plugin-n": "^16.2.0", "eslint-plugin-qunit": "^8.0.1", "eslint-plugin-simple-import-sort": "^10.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 15a160476c1..fe6bbdce1c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -126,6 +126,9 @@ importers: eslint-plugin-import: specifier: ^2.29.0 version: 2.29.0(@typescript-eslint/parser@6.8.0)(eslint@8.52.0) + eslint-plugin-mocha: + specifier: ^10.2.0 + version: 10.2.0(eslint@8.52.0) eslint-plugin-n: specifier: ^16.2.0 version: 16.2.0(eslint@8.52.0) @@ -2200,6 +2203,9 @@ importers: '@warp-drive/core-types': specifier: workspace:5.5.0-alpha.11 version: file:packages/core-types(@babel/core@7.23.2) + '@warp-drive/internal-config': + specifier: workspace:5.5.0-alpha.11 + version: link:../../config ember-cli: specifier: ~5.3.0 version: 5.3.0 @@ -11659,6 +11665,17 @@ packages: - supports-color dev: false + /eslint-plugin-mocha@10.2.0(eslint@8.52.0): + resolution: {integrity: sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.52.0 + eslint-utils: 3.0.0(eslint@8.52.0) + rambda: 7.5.0 + dev: false + /eslint-plugin-n@16.2.0(eslint@8.52.0): resolution: {integrity: sha512-AQER2jEyQOt1LG6JkGJCCIFotzmlcCZFur2wdKrp1JX2cNotC7Ae0BcD/4lLv3lUAArM9uNS8z/fsvXTd0L71g==} engines: {node: '>=16.0.0'} @@ -15792,6 +15809,10 @@ packages: tiny-glob: 0.2.9 patched: true + /rambda@7.5.0: + resolution: {integrity: sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==} + dev: false + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: diff --git a/tests/blueprints/.eslintrc.cjs b/tests/blueprints/.eslintrc.cjs new file mode 100644 index 00000000000..1c4b6969b8a --- /dev/null +++ b/tests/blueprints/.eslintrc.cjs @@ -0,0 +1,32 @@ +const base = require('@warp-drive/internal-config/eslint/base.cjs'); +const ignore = require('@warp-drive/internal-config/eslint/ignore.cjs'); +const imports = require('@warp-drive/internal-config/eslint/imports.cjs'); +const isolation = require('@warp-drive/internal-config/eslint/isolation.cjs'); +const mocha = require('@warp-drive/internal-config/eslint/mocha.cjs'); +const node = require('@warp-drive/internal-config/eslint/node.cjs'); +const parser = require('@warp-drive/internal-config/eslint/parser.cjs'); +const qunit = require('@warp-drive/internal-config/eslint/qunit.cjs'); + +module.exports = { + ...parser.defaults(), + + plugins: [...base.plugins(), ...imports.plugins()], + extends: [...base.extend()], + rules: Object.assign(base.rules(), imports.rules(), isolation.rules(), {}), + + ignorePatterns: ignore.ignoreRules(), + + overrides: [ + node.config(), + node.defaults(), + qunit.defaults({ + files: ['fixtures/**/*.{js,ts}'], + rules: { + // Fixing these would cause test failures + 'prefer-const': 'off', + 'simple-import-sort/imports': 'off', + }, + }), + mocha.defaults(), + ], +}; diff --git a/tests/blueprints/package.json b/tests/blueprints/package.json index b4e5c19815d..f85e77cbb48 100644 --- a/tests/blueprints/package.json +++ b/tests/blueprints/package.json @@ -11,6 +11,7 @@ "license": "MIT", "author": "", "scripts": { + "lint": "eslint . --quiet --cache --cache-strategy=content --ext .js,.ts,.mjs,.cjs --report-unused-disable-directives", "test:blueprints": "mocha tests", "_syncPnpm": "bun run sync-dependencies-meta-injected" }, @@ -89,6 +90,7 @@ "@glimmer/component": "^1.1.2", "@glimmer/tracking": "^1.1.2", "@warp-drive/core-types": "workspace:5.5.0-alpha.11", + "@warp-drive/internal-config": "workspace:5.5.0-alpha.11", "ember-cli": "~5.3.0", "ember-cli-blueprint-test-helpers": "^0.19.2", "ember-inflector": "^4.0.2", diff --git a/tests/blueprints/tests/adapter-test.js b/tests/blueprints/tests/adapter-test.js index a96393a1e63..2a3ea3944a3 100644 --- a/tests/blueprints/tests/adapter-test.js +++ b/tests/blueprints/tests/adapter-test.js @@ -28,7 +28,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter', async function () { - let args = ['adapter', 'foo']; + const args = ['adapter', 'foo']; await emberGenerateDestroy(args, (_file) => { expect(_file('app/adapters/foo.js')) @@ -40,7 +40,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter extends application adapter if it exists', async function () { - let args = ['adapter', 'foo']; + const args = ['adapter', 'foo']; await emberGenerate(['adapter', 'application']); await emberGenerateDestroy(args, (_file) => { @@ -53,7 +53,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter with --base-class', async function () { - let args = ['adapter', 'foo', '--base-class=bar']; + const args = ['adapter', 'foo', '--base-class=bar']; await emberGenerateDestroy(args, (_file) => { expect(_file('app/adapters/foo.js')) @@ -65,13 +65,13 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); xit('adapter throws when --base-class is same as name', function () { - let args = ['adapter', 'foo', '--base-class=foo']; + const args = ['adapter', 'foo', '--base-class=foo']; return expect(emberGenerate(args)).to.be.rejectedWith(SilentError, /Adapters cannot extend from themself/); }); it('adapter when is named "application"', function () { - let args = ['adapter', 'application']; + const args = ['adapter', 'application']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/adapters/application.js')) @@ -85,7 +85,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter-test', function () { - let args = ['adapter-test', 'foo']; + const args = ['adapter-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/adapters/foo-test.js')).to.equal(fixture(__dirname, 'adapter-test/rfc232.js')); @@ -118,7 +118,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter', function () { - let args = ['adapter', 'foo']; + const args = ['adapter', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/adapters/foo.js')) @@ -130,7 +130,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter extends application adapter if it exists', function () { - let args = ['adapter', 'foo']; + const args = ['adapter', 'foo']; return emberGenerate(['adapter', 'application']).then(() => emberGenerateDestroy(args, (_file) => { @@ -144,7 +144,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter with --base-class', function () { - let args = ['adapter', 'foo', '--base-class=bar']; + const args = ['adapter', 'foo', '--base-class=bar']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/adapters/foo.js')) @@ -156,7 +156,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter when is named "application"', function () { - let args = ['adapter', 'application']; + const args = ['adapter', 'application']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/adapters/application.js')) @@ -170,7 +170,7 @@ describe('Acceptance: generate and destroy adapter blueprints', function () { }); it('adapter-test', function () { - let args = ['adapter-test', 'foo']; + const args = ['adapter-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/adapters/foo-test.js')).to.equal(fixture(__dirname, 'adapter-test/rfc232.js')); diff --git a/tests/blueprints/tests/model-test.js b/tests/blueprints/tests/model-test.js index ee5d586d329..2e7e91ea0ef 100644 --- a/tests/blueprints/tests/model-test.js +++ b/tests/blueprints/tests/model-test.js @@ -26,7 +26,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model', function () { - let args = ['model', 'foo']; + const args = ['model', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/models/foo.js')) @@ -38,7 +38,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model with attrs', function () { - let args = [ + const args = [ 'model', 'foo', 'misc', @@ -69,7 +69,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model with belongsTo', function () { - let args = ['model', 'comment', 'post:belongs-to', 'author:belongs-to:user']; + const args = ['model', 'comment', 'post:belongs-to', 'author:belongs-to:user']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/models/comment.js')) @@ -85,7 +85,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model with hasMany', function () { - let args = ['model', 'post', 'comments:has-many', 'otherComments:has-many:comment']; + const args = ['model', 'post', 'comments:has-many', 'otherComments:has-many:comment']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/models/post.js')) @@ -99,7 +99,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model-test', function () { - let args = ['model-test', 'foo']; + const args = ['model-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/models/foo-test.js')).to.equal(fixture(__dirname, 'model-test/rfc232.js')); @@ -132,7 +132,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model', function () { - let args = ['model', 'foo']; + const args = ['model', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/models/foo.js')) @@ -144,7 +144,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model with attrs', function () { - let args = [ + const args = [ 'model', 'foo', 'misc', @@ -175,7 +175,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model with belongsTo', function () { - let args = ['model', 'comment', 'post:belongs-to', 'author:belongs-to:user']; + const args = ['model', 'comment', 'post:belongs-to', 'author:belongs-to:user']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/models/comment.js')) @@ -191,7 +191,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model with hasMany', function () { - let args = ['model', 'post', 'comments:has-many', 'otherComments:has-many:comment']; + const args = ['model', 'post', 'comments:has-many', 'otherComments:has-many:comment']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/models/post.js')) @@ -205,7 +205,7 @@ describe('Acceptance: generate and destroy model blueprints', function () { }); it('model-test', function () { - let args = ['model-test', 'foo']; + const args = ['model-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/models/foo-test.js')).to.equal(fixture(__dirname, 'model-test/rfc232.js')); diff --git a/tests/blueprints/tests/serializer-test.js b/tests/blueprints/tests/serializer-test.js index c39ec7a7944..d4021b9350d 100644 --- a/tests/blueprints/tests/serializer-test.js +++ b/tests/blueprints/tests/serializer-test.js @@ -27,7 +27,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer', function () { - let args = ['serializer', 'foo']; + const args = ['serializer', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/serializers/foo.js')) @@ -39,7 +39,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer extends application serializer if it exists', function () { - let args = ['serializer', 'foo']; + const args = ['serializer', 'foo']; return emberGenerate(['serializer', 'application']).then(() => emberGenerateDestroy(args, (_file) => { @@ -53,7 +53,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer with --base-class', function () { - let args = ['serializer', 'foo', '--base-class=bar']; + const args = ['serializer', 'foo', '--base-class=bar']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/serializers/foo.js')) @@ -65,13 +65,13 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); xit('serializer throws when --base-class is same as name', function () { - let args = ['serializer', 'foo', '--base-class=foo']; + const args = ['serializer', 'foo', '--base-class=foo']; return expect(emberGenerate(args)).to.be.rejectedWith(SilentError, /Serializers cannot extend from themself/); }); it('serializer when is named "application"', function () { - let args = ['serializer', 'application']; + const args = ['serializer', 'application']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/serializers/application.js')) @@ -85,7 +85,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer-test', function () { - let args = ['serializer-test', 'foo']; + const args = ['serializer-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/serializers/foo-test.js')).to.equal(fixture(__dirname, 'serializer-test/rfc232.js')); @@ -121,7 +121,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer', function () { - let args = ['serializer', 'foo']; + const args = ['serializer', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/serializers/foo.js')) @@ -133,7 +133,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer extends application serializer if it exists', function () { - let args = ['serializer', 'foo']; + const args = ['serializer', 'foo']; return emberGenerate(['serializer', 'application']).then(() => emberGenerateDestroy(args, (_file) => { @@ -147,7 +147,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer with --base-class', function () { - let args = ['serializer', 'foo', '--base-class=bar']; + const args = ['serializer', 'foo', '--base-class=bar']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/serializers/foo.js')) @@ -159,13 +159,13 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); xit('serializer throws when --base-class is same as name', function () { - let args = ['serializer', 'foo', '--base-class=foo']; + const args = ['serializer', 'foo', '--base-class=foo']; return expect(emberGenerate(args)).to.be.rejectedWith(SilentError, /Serializers cannot extend from themself/); }); it('serializer when is named "application"', function () { - let args = ['serializer', 'application']; + const args = ['serializer', 'application']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/serializers/application.js')) @@ -179,7 +179,7 @@ describe('Acceptance: generate and destroy serializer blueprints', function () { }); it('serializer-test', function () { - let args = ['serializer-test', 'foo']; + const args = ['serializer-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/serializers/foo-test.js')).to.equal(fixture(__dirname, 'serializer-test/rfc232.js')); diff --git a/tests/blueprints/tests/transform-test.js b/tests/blueprints/tests/transform-test.js index 01ed7683bff..2525c086493 100644 --- a/tests/blueprints/tests/transform-test.js +++ b/tests/blueprints/tests/transform-test.js @@ -26,7 +26,7 @@ describe('Acceptance: generate and destroy transform blueprints', function () { }); it('transform', function () { - let args = ['transform', 'foo']; + const args = ['transform', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/transforms/foo.js')) @@ -39,7 +39,7 @@ describe('Acceptance: generate and destroy transform blueprints', function () { }); it('transform-test', function () { - let args = ['transform-test', 'foo']; + const args = ['transform-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/transforms/foo-test.js')).to.equal(fixture(__dirname, 'transform-test/rfc232.js')); @@ -77,7 +77,7 @@ describe('Acceptance: generate and destroy transform blueprints', function () { }); it('transform', function () { - let args = ['transform', 'foo']; + const args = ['transform', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('app/transforms/foo.js')) @@ -90,7 +90,7 @@ describe('Acceptance: generate and destroy transform blueprints', function () { }); it('transform-test', function () { - let args = ['transform-test', 'foo']; + const args = ['transform-test', 'foo']; return emberGenerateDestroy(args, (_file) => { expect(_file('tests/unit/transforms/foo-test.js')).to.equal(fixture(__dirname, 'transform-test/rfc232.js'));