Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test suite for all current config loading systems #301

Merged
merged 8 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,19 @@ const config: KnipConfig = {
export default config;
```

And if you need, you can also expose an (async) function if you need, like so:

```ts
import type { KnipConfig } from 'knip';

const config = async (): Promise<KnipConfig> => ({
entry: ['src/index.ts'],
project: ['src/**/*.ts'],
});

export default config;
```

Use `--config path/to/knip.config.json` for a different path.

### Let's Go!
Expand Down
1 change: 1 addition & 0 deletions fixtures/config/js-async/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/js-async/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
3 changes: 3 additions & 0 deletions fixtures/config/js-async/knip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = async () => ({
ignore: ['dangling.js']
});
2 changes: 2 additions & 0 deletions fixtures/config/js-async/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/js-async/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-js-async"
}
1 change: 1 addition & 0 deletions fixtures/config/js-flat/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/js-flat/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
3 changes: 3 additions & 0 deletions fixtures/config/js-flat/knip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
ignore: ['dangling.js']
}
2 changes: 2 additions & 0 deletions fixtures/config/js-flat/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/js-flat/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-js-flat"
}
1 change: 1 addition & 0 deletions fixtures/config/json/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/json/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
3 changes: 3 additions & 0 deletions fixtures/config/json/knip.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore": ["dangling.js"]
}
2 changes: 2 additions & 0 deletions fixtures/config/json/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-json"
}
1 change: 1 addition & 0 deletions fixtures/config/mjs-async/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/mjs-async/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
5 changes: 5 additions & 0 deletions fixtures/config/mjs-async/knip.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = async () => ({
ignore: ['dangling.js'],
});

export default config;
2 changes: 2 additions & 0 deletions fixtures/config/mjs-async/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/mjs-async/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-mjs-async"
}
1 change: 1 addition & 0 deletions fixtures/config/mjs-flat/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/mjs-flat/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
5 changes: 5 additions & 0 deletions fixtures/config/mjs-flat/knip.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = {
ignore: ['dangling.js'],
};

export default config;
2 changes: 2 additions & 0 deletions fixtures/config/mjs-flat/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/mjs-flat/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-mjs-flat"
}
1 change: 1 addition & 0 deletions fixtures/config/package-json/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/package-json/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
2 changes: 2 additions & 0 deletions fixtures/config/package-json/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
6 changes: 6 additions & 0 deletions fixtures/config/package-json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@fixtures/config-package-json",
"knip": {
"ignore": ["dangling.js"]
}
}
1 change: 1 addition & 0 deletions fixtures/config/ts-async/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/ts-async/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
7 changes: 7 additions & 0 deletions fixtures/config/ts-async/knip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { KnipConfig } from '../../../src/index';

const config = async (): Promise<KnipConfig> => ({
ignore: ['dangling.js'],
});

export default config;
2 changes: 2 additions & 0 deletions fixtures/config/ts-async/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/ts-async/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-ts-async"
}
5 changes: 5 additions & 0 deletions fixtures/config/ts-async/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"types": ["node"]
}
}
1 change: 1 addition & 0 deletions fixtures/config/ts-flat/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/ts-flat/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
7 changes: 7 additions & 0 deletions fixtures/config/ts-flat/knip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { KnipConfig } from '../../../src/index';

const config: KnipConfig = {
ignore: ['dangling.js'],
};

export default config;
2 changes: 2 additions & 0 deletions fixtures/config/ts-flat/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/ts-flat/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-ts-flat"
}
5 changes: 5 additions & 0 deletions fixtures/config/ts-flat/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"types": ["node"]
}
}
1 change: 1 addition & 0 deletions fixtures/config/ts-function/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/ts-function/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
7 changes: 7 additions & 0 deletions fixtures/config/ts-function/knip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { KnipConfig } from '../../../src/index';

const config = (): KnipConfig => ({
ignore: ['dangling.js'],
});

export default config;
2 changes: 2 additions & 0 deletions fixtures/config/ts-function/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/ts-function/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-ts-function"
}
5 changes: 5 additions & 0 deletions fixtures/config/ts-function/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"types": ["node"]
}
}
1 change: 1 addition & 0 deletions fixtures/config/yaml/dangling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const unusedFile = true;
3 changes: 3 additions & 0 deletions fixtures/config/yaml/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as MyNamespace from './my-namespace';

export const b = MyNamespace.y;
2 changes: 2 additions & 0 deletions fixtures/config/yaml/knip.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ignore:
- 'dangling.js'
2 changes: 2 additions & 0 deletions fixtures/config/yaml/my-namespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 1;
export const y = () => x;
3 changes: 3 additions & 0 deletions fixtures/config/yaml/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/config-yaml"
}
14 changes: 13 additions & 1 deletion src/ConfigurationChief.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { getKeysByValue } from './util/object.js';
import { join, relative, toPosix } from './util/path.js';
import { normalizePluginConfig, toCamelCase } from './util/plugin.js';
import { _require } from './util/require.js';
import { unwrapFunction } from './util/unwrapFunction.js';
import { byPathDepth } from './util/workspace.js';
import type { SyncCompilers, AsyncCompilers } from './types/compilers.js';
import type {
Expand Down Expand Up @@ -150,7 +151,9 @@ export class ConfigurationChief {
throw new ConfigurationError(`Unable to find ${rawConfigArg} or package.json#knip`);
}

this.rawConfig = this.resolvedConfigFilePath ? await _load(this.resolvedConfigFilePath) : manifest.knip;
this.rawConfig = this.resolvedConfigFilePath
? await this.loadResolvedConfigurationFile(this.resolvedConfigFilePath)
: manifest.knip;

// Have to partition compiler functions before Zod touches them
const parsedConfig = this.rawConfig ? ConfigurationValidator.parse(partitionCompilers(this.rawConfig)) : {};
Expand All @@ -159,6 +162,15 @@ export class ConfigurationChief {
await this.setWorkspaces();
}

private async loadResolvedConfigurationFile(configPath: string) {
const loadedValue = await _load(configPath);
try {
return await unwrapFunction(loadedValue);
} catch (e) {
throw new ConfigurationError(`Error running the function from ${configPath}`);
}
}

public getCompilers(): [SyncCompilers, AsyncCompilers] {
return [this.config.syncCompilers, this.config.asyncCompilers];
}
Expand Down
13 changes: 13 additions & 0 deletions src/util/unwrapFunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { debugLogObject } from './debug.js';

export const unwrapFunction = async (possibleFunction: unknown) => {
if (typeof possibleFunction === 'function') {
try {
return await possibleFunction();
} catch (error) {
debugLogObject('*', 'Error executing function:', error);
throw error;
}
}
return possibleFunction;
};
11 changes: 2 additions & 9 deletions test/cli-preprocessor.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import assert from 'node:assert/strict';
import { execSync } from 'node:child_process';
import test from 'node:test';
import { resolve } from '../src/util/path.js';
import { execFactory } from './helpers/execKnip.js';

const cwd = resolve('fixtures/cli-preprocessor');

const exec = (command: string) => {
try {
const output = execSync(command.replace(/^knip/, 'node ../../dist/cli.js'), { cwd });
return output.toString().trim();
} catch {
console.error(`Error during execution of command: ${command}`);
}
};
const exec = execFactory(cwd);

test('knip --preprocessor ./index.js', () => {
assert.equal(exec('knip --preprocessor ./index.js'), 'hi from js preprocessor');
Expand Down
7 changes: 2 additions & 5 deletions test/cli-reporter.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import assert from 'node:assert/strict';
import { execSync } from 'node:child_process';
import test from 'node:test';
import { resolve } from '../src/util/path.js';
import { execFactory } from './helpers/execKnip.js';

const cwd = resolve('fixtures/cli-reporter');

const exec = (command: string) => {
const output = execSync(command.replace(/^knip/, 'node ../../dist/cli.js'), { cwd });
return output.toString().trim();
};
const exec = execFactory(cwd);

test('knip --reporter ./index.js', () => {
assert.equal(exec('knip --reporter ./index.js'), 'hi from js reporter');
Expand Down
7 changes: 2 additions & 5 deletions test/cli.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import assert from 'node:assert/strict';
import { execSync } from 'node:child_process';
import test from 'node:test';
import { helpText } from '../src/util/cli-arguments.js';
import { resolve } from '../src/util/path.js';
import { version } from '../src/version.js';
import { execFactory } from './helpers/execKnip.js';

const cwd = resolve('fixtures/cli');

const exec = (command: string) => {
const output = execSync(command.replace(/^knip/, 'node ../../dist/cli.js'), { cwd });
return output.toString().trim();
};
const exec = execFactory(cwd);

test('knip --version', () => {
assert.equal(exec('knip --version'), version);
Expand Down
12 changes: 12 additions & 0 deletions test/config/js-async.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { resolve } from '../../src/util/path.js';
import { execFactory } from '../helpers/execKnip.js';

const cwd = resolve('fixtures/config/js-async');

const exec = execFactory(cwd);

test('Support loading js async function for configuration', async () => {
assert.equal(exec('knip'), '');
});
12 changes: 12 additions & 0 deletions test/config/js-flat.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { resolve } from '../../src/util/path.js';
import { execFactory } from '../helpers/execKnip.js';

const cwd = resolve('fixtures/config/js-flat');

const exec = execFactory(cwd);

test('Support loading js object files for configuration', async () => {
assert.equal(exec('knip'), '');
});
12 changes: 12 additions & 0 deletions test/config/json.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { resolve } from '../../src/util/path.js';
import { execFactory } from '../helpers/execKnip.js';

const cwd = resolve('fixtures/config/json');

const exec = execFactory(cwd);

test('Support loading json files for configuration', async () => {
assert.equal(exec('knip'), '');
});
12 changes: 12 additions & 0 deletions test/config/mjs-async.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { resolve } from '../../src/util/path.js';
import { execFactory } from '../helpers/execKnip.js';

const cwd = resolve('fixtures/config/mjs-async');

const exec = execFactory(cwd);

test('Support loading mjs async function files for configuration', async () => {
assert.equal(exec('knip -c knip.mjs'), '');
});
12 changes: 12 additions & 0 deletions test/config/mjs-flat.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { resolve } from '../../src/util/path.js';
import { execFactory } from '../helpers/execKnip.js';

const cwd = resolve('fixtures/config/mjs-flat');

const exec = execFactory(cwd);

test('Support loading mjs object files for configuration', async () => {
assert.equal(exec('knip -c knip.mjs'), '');
});