Skip to content

Commit

Permalink
Drop support for the callback interface
Browse files Browse the repository at this point in the history
  • Loading branch information
mgol committed Nov 15, 2023
1 parent 28257dd commit fc04cc8
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 163 deletions.
48 changes: 14 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ $ check-dependencies --scope-list dependencies --scope-list devDependencies

### API

The exported function returns a promise which should eventually be fulfilled (never rejected).

```js
require('check-dependencies')(config, callback);
const output = await require('check-dependencies')(config);
```

where `callback` is invoked upon completion and `config` is a configuration object.
where `config` is a configuration object.

`callback` is invoked with the object containing fields:
`output` is an object containing fields:

```js
{
Expand All @@ -62,23 +64,13 @@ where `callback` is invoked upon completion and `config` is a configuration obje
}
```

The function returns a promise so passing a callback is not necessary; instead you can do:

```js
require('check-dependencies')(config).then(function (output) {
/* handle output */
});
```

The promise should never fail.

There is a synchronous alternative -- the following code:

```js
var output = require('check-dependencies').sync(config);
const output = require('check-dependencies').sync(config);
```

will assign to `output` the same object that would otherwise be passed to the `callback` in the asynchronous scenario.
will assign to `output` the same object to which the returned promise would otherwise resolve to.

The `config` object may have the following fields:

Expand Down Expand Up @@ -181,33 +173,21 @@ Default: `console.error.bind(console)`
The most basic usage:

```js
require('check-dependencies')(callback);
const output = await require('check-dependencies')();
```

This will check packages' versions and report an error to `callback` if packages' versions are mismatched.
This will check packages' versions and report an error to `output` if packages' versions are mismatched.

The following:

```js
require('check-dependencies')(
{
install: true,
verbose: true,
},
callback,
);
```

will install mismatched ones and call `callback`.

The following two examples:

```js
require('check-dependencies')(callback);
require('check-dependencies')({}, callback);
await require('check-dependencies')({
install: true,
verbose: true,
});
```

behave in the same way - `callback` is invoked upon completion; if there was an error, it's passed as a parameter to `callback`.
will install mismatched ones.

## Supported Node.js versions

Expand Down
2 changes: 1 addition & 1 deletion bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@ const Cli = {
},
};

checkDependencies(argv, Cli.reporter);
checkDependencies(argv).then(result => Cli.reporter(result));

module.exports = Cli;
41 changes: 3 additions & 38 deletions lib/check-dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,41 +23,7 @@ const findup = fileName => {
}
};

const checkDependenciesHelper = (syncOrAsync, config, callback) => {
// We treat the signature:
// checkDependencies(callback)
// as:
// checkDependencies({}, callback)

if (syncOrAsync === 'async') {
// Catch all cases where `config` is not an object - even if it's not a function
// so it's useless here, we need it to be assigned to `callback` to provide
// to the error message.
if (
typeof callback !== 'function' &&
(typeof config !== 'object' || config == null)
) {
callback = config;
config = null;
}
if (typeof callback !== 'function') {
if (callback == null) {
// In the async mode we return the promise anyway; assign callback
// to noop to keep code consistency.
callback = () => {
/* noop */
};
} else {
// If callback was simply not provided, we assume the user wanted
// to handle the returned promise. If it was passed but not a function
// we assume user error and throw.
throw new TypeError(
`The provided callback wasn't a function! Got: ${callback}`,
);
}
}
}

const checkDependenciesHelper = (syncOrAsync, config) => {
const spawnShellSupported = semver.satisfies(process.version, '>=4.8.0');
const win32 = process.platform === 'win32';
const output = { log: [], error: [] };
Expand Down Expand Up @@ -85,7 +51,6 @@ const checkDependenciesHelper = (syncOrAsync, config, callback) => {
const finish = () => {
output.status = success ? 0 : 1;
if (syncOrAsync === 'async') {
callback(output);
return Promise.resolve(output);
}
return output;
Expand Down Expand Up @@ -396,5 +361,5 @@ const checkDependenciesHelper = (syncOrAsync, config, callback) => {
});
};

module.exports = (cfg, cb) => checkDependenciesHelper('async', cfg, cb);
module.exports.sync = (cfg, cb) => checkDependenciesHelper('sync', cfg, cb);
module.exports = cfg => checkDependenciesHelper('async', cfg);
module.exports.sync = cfg => checkDependenciesHelper('sync', cfg);
91 changes: 1 addition & 90 deletions test/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@ describe('checkDependencies', () => {
const testSuite = (packageManager, checkDependenciesMode) => {
const getCheckDependencies = () =>
function checkDependenciesWrapped(...args) {
let callback;
const callback = args.pop();

if (checkDependenciesMode === 'callbacks') {
checkDependencies(...args);
}
if (checkDependenciesMode === 'promises') {
callback = args.pop();
checkDependencies(...args)
.then(output => {
callback(output);
Expand All @@ -39,7 +35,6 @@ describe('checkDependencies', () => {
});
}
if (checkDependenciesMode === 'sync') {
callback = args.pop();
callback(checkDependenciesSync(...args));
}
};
Expand Down Expand Up @@ -253,87 +248,6 @@ describe('checkDependencies', () => {
);
});

if (checkDependenciesMode === 'callback') {
it('should throw if callback is not a function', () => {
const config = {
packageDir: `${fixturePrefix}ok`,
};

const expectToThrow = fnsWithReasons => {
for (const fnWithReason of fnsWithReasons) {
assert.throws(
fnWithReason[0],
Error,
`Expected the function to throw when passed a callback: ${fnWithReason[1]}`,
);
}
};

const getFunctionWithReason = fakeCallback => [
() => checkDeps(config, fakeCallback),
fakeCallback,
];

expectToThrow([
getFunctionWithReason(undefined),
getFunctionWithReason(null),
getFunctionWithReason(42),
getFunctionWithReason('foobar'),
getFunctionWithReason({ a: 2 }),
]);
});
}

// In other than async cases we fake the callback in tests so this wouldn't work.
// But we test correctness of those modes in many other tests so that one
// is not needed.
if (checkDependenciesMode === 'callback') {
it('should not throw if only one parameter provided', () => {
assert.doesNotThrow(() => {
checkDeps({
packageDir: `${fixturePrefix}ok`,
});
}, 'Expected the function with one parameter not to throw');
});
}

if (packageManager === 'npm') {
it('should allow to provide callback as the first argument', done => {
checkDeps(output => {
assert.deepEqual(output.error, []);
assert.strictEqual(output.depsWereOk, true);
assert.strictEqual(output.status, 0);
done();
});
});

if (checkDependenciesMode === 'callback') {
it('should throw if config not present and callback is not a function', () => {
const expectToThrow = fnsWithReasons => {
for (const fnWithReason of fnsWithReasons) {
assert.throws(
fnWithReason[0],
Error,
`Expected the function to throw when passed a callback: ${fnWithReason[1]}`,
);
}
};

const getFunctionWithReason = fakeCallback => [
() => checkDeps(fakeCallback),
fakeCallback,
];

expectToThrow([
getFunctionWithReason(undefined),
getFunctionWithReason(null),
getFunctionWithReason(42),
getFunctionWithReason('foobar'),
]);
});
}
}

it('should support `log` and `error` options', done => {
const logArray = [];
const errorArray = [];
Expand Down Expand Up @@ -686,9 +600,6 @@ describe('checkDependencies', () => {
};

describe('API', () => {
describe('callbacks', () => {
testSuite('npm', 'callbacks');
});
describe('promises', () => {
testSuite('npm', 'promises');
});
Expand Down

0 comments on commit fc04cc8

Please sign in to comment.