From 8b25d05072504863f4c12a1ec4be242f476f2d76 Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Sat, 18 Sep 2021 16:09:41 +0200 Subject: [PATCH] Add a mostly hidden test.default that provides test Our type definition uses ESM syntax; when using CJS with VSCode, the auto-completion assumes the root is accessed through `require('ava').default`. Placate VSCode by adding a mostly hidden default property on the root. This is available through both CJS and ESM imports. We use a proxy so that we don't end up with root.default.default.default chains. Fixes #2539. --- lib/create-chain.js | 23 +++++++++++++++++++++++ test/cjs-default/fixtures/package.json | 7 +++++++ test/cjs-default/fixtures/test.cjs | 19 +++++++++++++++++++ test/cjs-default/test.js | 7 +++++++ 4 files changed, 56 insertions(+) create mode 100644 test/cjs-default/fixtures/package.json create mode 100644 test/cjs-default/fixtures/test.cjs create mode 100644 test/cjs-default/test.js diff --git a/lib/create-chain.js b/lib/create-chain.js index 7f283ad45..525fa96d1 100644 --- a/lib/create-chain.js +++ b/lib/create-chain.js @@ -101,5 +101,28 @@ export default function createChain(fn, defaults, meta) { root.meta = meta; + // Our type definition uses ESM syntax; when using CJS with VSCode, the + // auto-completion assumes the root is accessed through `require('ava').default`. + // Placate VSCode by adding a mostly hidden default property on the root. + // This is available through both CJS and ESM imports. We use a proxy so that + // we don't end up with root.default.default.default chains. + Object.defineProperty(root, 'default', { + configurable: false, + enumerable: false, + writable: false, + value: new Proxy(root, { + apply(target, thisArg, argumentsList) { + target.apply(thisArg, argumentsList); + }, + get(target, prop) { + if (prop === 'default') { + throw new TypeError('Cannot access default.default'); + } + + return target[prop]; + }, + }), + }); + return root; } diff --git a/test/cjs-default/fixtures/package.json b/test/cjs-default/fixtures/package.json new file mode 100644 index 000000000..82a861884 --- /dev/null +++ b/test/cjs-default/fixtures/package.json @@ -0,0 +1,7 @@ +{ + "ava": { + "files": [ + "*.cjs" + ] + } +} diff --git a/test/cjs-default/fixtures/test.cjs b/test/cjs-default/fixtures/test.cjs new file mode 100644 index 000000000..9cbaaecc3 --- /dev/null +++ b/test/cjs-default/fixtures/test.cjs @@ -0,0 +1,19 @@ +const test = require('ava'); + +test.default('callable', t => { // eslint-disable-line ava/no-unknown-modifiers + t.pass(); +}); + +test('no recursion', t => { + t.throws(() => test.default.default, { + name: 'TypeError', + }); +}); + +test('not enumerable', t => { + t.false(Object.keys(test).includes('default')); +}); + +test('main export equals the ESM export', async t => { + t.is(test, (await import('ava')).default); // eslint-disable-line node/no-unsupported-features/es-syntax +}); diff --git a/test/cjs-default/test.js b/test/cjs-default/test.js new file mode 100644 index 000000000..24c9fec5b --- /dev/null +++ b/test/cjs-default/test.js @@ -0,0 +1,7 @@ +import test from '@ava/test'; + +import {fixture} from '../helpers/exec.js'; + +test('ok', async t => { + await t.notThrowsAsync(fixture()); +});