diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/README.md b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/README.md new file mode 100644 index 00000000000..b191db9770f --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/README.md @@ -0,0 +1,225 @@ + + +# resolveParentPathsBy + +> Resolve paths from a set of paths according to a predicate function by walking parent directories. + +
+ +## Usage + +```javascript +var resolveParentPathsBy = require( '@stdlib/fs/resolve-parent-paths-by' ); +``` + + + +#### resolveParentPathsBy( paths\[, options], predicate, clbk ) + +Asynchronously resolves paths from a set of paths according to a `predicate` function by walking parent directories. + +```javascript +resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], predicate, onPath ); + +function predicate( path, next ) { + var bool = ( /\/test\//.test( path ) === false ); + next( null, bool ); +} + +function onPath( error, paths ) { + if ( error ) { + throw error; + } + console.log( paths ); + // e.g., => [...] +} +``` + +The function accepts the following `options`: + +- **dir**: base directory from which to begin walking. May be either an absolute path or a path relative to the current working directory. + +- **mode**: mode of operation. The following modes are supported: + + - `first`: return the first resolved path. + - `some`: return one or more paths resolved within the first directory level containing a match. + - `all`: return all resolved paths within the first directory level containing matches for all provided paths. + - `each`: independently return the first resolved path for each path at any directory level. + + Default: `'all'`. + +By default, the function begins walking from the current working directory. To specify an alternative directory, set the `dir` option. + +```javascript +var opts = { + 'dir': __dirname +}; +resolveParentPathsBy( [ 'package.json' ], opts, predicate, onPath ); + +function predicate( path, next ) { + var bool = ( /\/test\//.test( path ) === false ); + next( null, bool ); +} + +function onPath( error, paths ) { + if ( error ) { + throw error; + } + console.log( paths ); + // e.g., => [...] +} +``` + +When invoked, the `predicate` function is provided two arguments: + +- `path`: a resolved path. +- `next`: a callback which should be called once the `predicate` function has finished processing a resolved path. + +If a `predicate` function calls the `next` callback with a `truthy` second argument, the function proceeds to next function and returns the resolved path. + +If unable to resolve a path, the function returns `null` as the path result. + +By default, the function requires that a directory contains matches for all provided paths before returning results. To specify an alternative operation mode, set the `mode` option. + +```javascript +var opts = { + 'dir': __dirname, + 'mode': 'first' +}; +resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], opts, predicate, onPaths ); + +function predicate( path, next ) { + var bool = ( /\/test\//.test( path ) === false ); + next( null, bool ); +} + +function onPaths( error, paths ) { + if ( error ) { + throw error; + } + console.log( paths ); + // => [...] +} +``` + +#### resolveParentPathsBy.sync( path\[, options], predicate ) + +Synchronously resolves paths from a set of paths according to a `predicate` function by walking parent directories. + +```javascript +function predicate( path ) { + return ( /\/test\//.test( path ) === false ); +} + +var path = resolveParentPathsBy.sync( [ 'package.json', 'README.md' ], predicate ); +// e.g., returns [...] +``` + +
+ + + +
+ +## Notes + +- In `some` mode, the return order of asynchronously resolved paths is not guaranteed. +- This implementation is **not** similar in functionality to core [`path.resolve`][node-core-path-resolve]. The latter performs string manipulation to generate a full path. This implementation walks parent directories to perform a **search**, thereby touching the file system. Accordingly, this implementation resolves a _real_ absolute file path and is intended for use when a target's location in a parent directory is unknown relative to a child directory; e.g., when wanting to find a package root from deep within a package directory. + +
+ + + +
+ +## Examples + + + + + +```javascript +var resolveParentPathsBy = require( '@stdlib/fs/resolve-parent-paths-by' ); + +var opts = { + 'dir': __dirname +}; + +/* Sync */ + +function predicateSync( path ) { + return true; +} + +var out = resolveParentPathsBy.sync( [ 'package.json', 'README.md' ], opts, predicateSync ); +// returns [...] + +out = resolveParentPathsBy.sync( [ 'non_existent_basename/package.json' ], opts, predicateSync ); +// => [] + +opts.mode = 'first'; +out = resolveParentPathsBy.sync( [ 'non_existent_basename/package.json', 'package.json' ], opts, predicateSync ); +// => returns [...] + +/* Async */ + +function predicateAsync( path, next ) { + setTimeout( onTimeout, 0 ); + + function onTimeout() { + next( null, true ); + } +} + +function onPath( error, paths ) { + if ( error ) { + throw error; + } + console.log( paths ); +} + +resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicateAsync, onPath ); +resolveParentPathsBy( [ './../non_existent_path/package.json' ], predicateAsync, onPath ); +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/benchmark/benchmark.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/benchmark/benchmark.js new file mode 100644 index 00000000000..83b1e33d63f --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/benchmark/benchmark.js @@ -0,0 +1,349 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var basename = require( 'path' ).basename; +var bench = require( '@stdlib/bench' ); +var pkg = require( './../package.json' ).name; +var resolveParentPathsBy = require( './../lib' ); + + +// MAIN // + +bench( pkg+':mode=first', function benchmark( b ) { + var PATHS; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'beep-boop!!!hello world!?!', 'package.json' ], + [ 'package.json', 'README.md' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'first' + }; + + i = 0; + b.tic(); + + return next(); + + function next() { + i += 1; + if ( i <= b.iterations ) { + return resolveParentPathsBy(PATHS[ i % 3 ], opts, predicate, done); + } + b.toc(); + b.pass( 'benchmark finished' ); + b.end(); + } + + function predicate( path, next ) { + next( null, true ); + } + + function done( error, paths ) { + if ( error ) { + b.fail( error.message ); + } + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + next(); + } +}); + +bench( pkg+':mode=some', function benchmark( b ) { + var PATHS; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'beep-boop!!!hello world!?!', 'package.json' ], + [ 'package.json', 'README.md' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'some' + }; + + i = 0; + b.tic(); + + return next(); + + function next() { + i += 1; + if ( i <= b.iterations ) { + return resolveParentPathsBy(PATHS[ i % 3 ], opts, predicate, done); + } + b.toc(); + b.pass( 'benchmark finished' ); + b.end(); + } + + function predicate( path, next ) { + next( null, true ); + } + + function done( error, paths ) { + if ( error ) { + b.fail( error.message ); + } + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + next(); + } +}); + +bench( pkg+':mode=all', function benchmark( b ) { + var PATHS; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'package.json', 'README.md' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'all' + }; + + i = 0; + b.tic(); + + return next(); + + function next() { + i += 1; + if ( i <= b.iterations ) { + return resolveParentPathsBy(PATHS[ i % 2 ], opts, predicate, done); + } + b.toc(); + b.pass( 'benchmark finished' ); + b.end(); + } + + function predicate( path, next ) { + next( null, true ); + } + + function done( error, paths ) { + if ( error ) { + b.fail( error.message ); + } + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + next(); + } +}); + +bench( pkg+':mode=each', function benchmark( b ) { + var PATHS; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'beep-boop!!!hello world!?!', 'package.json' ], + [ basename( __dirname ), 'README.md' ], + [ 'README.md', 'package.json' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'each' + }; + + i = 0; + b.tic(); + + return next(); + + function next() { + i += 1; + if ( i <= b.iterations ) { + return resolveParentPathsBy(PATHS[ i % 4 ], opts, predicate, done); + } + b.toc(); + b.pass( 'benchmark finished' ); + b.end(); + } + + function predicate( path, next ) { + next( null, true ); + } + + function done( error, paths ) { + if ( error ) { + b.fail( error.message ); + } + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + next(); + } +}); + +bench( pkg+':sync:mode=first', function benchmark( b ) { + var PATHS; + var paths; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'beep-boop!!!hello world!?!', 'package.json' ], + [ 'package.json', 'README.md' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'first' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + paths = resolveParentPathsBy.sync( PATHS[ i % 3 ], opts, predicate ); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + } + b.toc(); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function predicate() { + return true; + } +}); + +bench( pkg+':sync:mode=some', function benchmark( b ) { + var PATHS; + var paths; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'beep-boop!!!hello world!?!', 'package.json' ], + [ 'package.json', 'README.md' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'some' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + paths = resolveParentPathsBy.sync( PATHS[ i % 3 ], opts, predicate ); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + } + b.toc(); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function predicate() { + return true; + } +}); + +bench( pkg+':sync:mode=all', function benchmark( b ) { + var PATHS; + var paths; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'package.json', 'README.md' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'all' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + paths = resolveParentPathsBy.sync( PATHS[ i % 2 ], opts, predicate ); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + } + b.toc(); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function predicate() { + return true; + } +}); + +bench( pkg+':sync:mode=each', function benchmark( b ) { + var PATHS; + var paths; + var opts; + var i; + + PATHS = [ + [ 'package.json' ], + [ 'beep-boop!!!hello world!?!', 'package.json' ], + [ basename( __dirname ), 'README.md' ], + [ 'README.md', 'package.json' ] + ]; + opts = { + 'dir': __dirname, + 'mode': 'each' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + paths = resolveParentPathsBy.sync( PATHS[ i % 4 ], opts, predicate ); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + } + b.toc(); + if ( paths.length === 0 ) { + b.fail( 'should return a path' ); + } + b.pass( 'benchmark finished' ); + b.end(); + + function predicate() { + return true; + } +}); diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/repl.txt b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/repl.txt new file mode 100644 index 00000000000..d5282063c6d --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/repl.txt @@ -0,0 +1,142 @@ + +{{alias}}( paths[, options], predicate, clbk ) + Asynchronously resolves paths from a set of paths according to a + predicate function by walking parent directories. + + When invoked, the predicate function is provided two arguments: + + - `path`: resolved paths + - `next`: a callback to be invoked after processing a resolved path + + The `next` callback takes two arguments: + + - `error`: error argument + - `result`: test result + + If a provided predicate function calls the `next` callback with a truthy + `error` argument, the function suspends execution and immediately calls + the `done` callback for subsequent `error` handling. + + The function immediately returns upon encountering a non-falsy `result` + value and calls the `done` callback with `null` as the first argument and + the array of resolved paths as the second argument. + + If unable to resolve paths, the function returns empty array as the path + result. + + Execution is *not* guaranteed to be asynchronous. To guarantee asynchrony, + wrap the `done` callback in a function which either executes at the end of + the current stack (e.g., `nextTick`) or during a subsequent turn of the + event loop (e.g., `setImmediate`, `setTimeout`). + + Parameters + ---------- + paths: Array + Paths to resolve. + + options: Object (optional) + Options. + + options.dir: string (optional) + Base directory from which to search. Default: current working + directory. + + options.mode: string (optional) + Mode of operation. The following modes are supported: + + - first: return the first resolved path. + - some: return one or more paths resolved within the first + directory level containing a match. + - all: return all resolved paths within the first directory level + containing matches for all provided paths. + - each: independently return the first resolved path for each path + at any directory level. + + Default: 'all'. + + predicate: Function + The test function to invoke for each resolved path. + + clbk: Function + Callback to invoke after resolving a path. + + Examples + -------- + > function predicate( path, next ) { + ... setTimeout( onTimeout, path ); + ... function onTimeout() { + ... console.log( path ); + ... next( null, false ); + ... } + ... }; + > function onPaths( error, paths ) { + ... if ( error ) { + ... console.error( error.message ); + ... } else { + ... console.log( paths ); + ... } + ... }; + > {{alias}}( + ... [ 'package.json', 'package-lock.json' ], + ... predicate, + ... onPaths + ... ); + + +{{alias}}.sync( paths[, options], predicate ) + Synchronously resolves paths from a set of paths according to a predicate + function by walking parent directories. + + The predicate function is provided one argument: + + - `path`: a resolved path + + The function immediately returns upon encountering a truthy return value. + + If unable to resolve paths, the function returns a empty array as the + path result. + + Parameters + ---------- + paths: Array + Paths to resolve. + + options: Object (optional) + Options. + + options.dir: string (optional) + Base directory from which to search. Default: current working + directory. + + options.mode: string (optional) + Mode of operation. The following modes are supported: + + - first: return the first resolved path. + - some: return one or more paths resolved within the first directory + level containing a match. + - all: return all resolved paths within the first directory level + containing matches for all provided paths. + - each: independently return the first resolved path for each path at + any directory level. + + Default: 'all'. + + predicate: Function + The test function to invoke for each resolved path. + + Returns + ------- + out: Array + Resolved paths. + + Examples + -------- + > function predicate() { return false; }; + > var out = {{alias}}.sync( + ... [ 'package.json', 'package-lock.json' ], + ... predicate + ... ); + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/types/index.d.ts b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/types/index.d.ts new file mode 100644 index 00000000000..900b593e456 --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/types/index.d.ts @@ -0,0 +1,237 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// TypeScript Version: 4.1 + +/** +* Interface defining function options. +*/ +interface Options { + /** + * Base directory from which to search (default: current working directory). + */ + dir?: string; + + /** + * Mode of operation. + * + * ## Notes + * + * - The following modes are supported: + * + * - **first**: return the first resolved path. + * - **some**: return one or more paths resolved within the first directory level containing a match. + * - **all**: return all resolved paths within the first directory level containing matches for all provided paths. + * - **each**: independently return the first resolved path for each path at any directory level. + * + * Default: `'all'`. + * + * - In `'some'` mode, the return order of resolved paths is not guaranteed. + */ + mode?: 'first' | 'some' | 'all' | 'each'; +} + +/** +* Callback function. +*/ +type Nullary = () => void; + +/** +* Callback function. +* +* @param error - encountered error or null +*/ +type Unary = ( error: Error | null ) => void; + +/** +* Callback function. +* +* @param error - encountered error or null +* @param result - test result +*/ +type Binary = ( error: Error | null, result: boolean ) => void; + +/** +* Callback function. +* +* @param error - encountered error or null +* @param result - test result +*/ +type NextCallback = Nullary | Unary | Binary; + +/** +* Checks whether a resolved path passes a test. +* +* @param path - resolved path +* @returns test result +*/ +type SyncPredicate = ( path: string ) => boolean; + +/** +* Checks whether a resolved path passes a test. +* +* @param path - resolved path +* @param next - callback which should be called once the `predicate` function has finished processing a resolved path +*/ +type AsyncPredicate = ( path: string, next: NextCallback ) => void; + +/** +* Callback invoked after resolving paths according to a predicate function. +* +* @param error - error object +* @param path - resolved path +*/ +type DoneCallback = ( err: Error | null, paths: Array ) => void; + +/** +* Interface for resolving paths from a set of paths according to a predicate function by walking parent directories. +*/ +interface resolveParentPathsBy { + /** + * Asynchronously resolves paths from a set of paths according to a predicate function by walking parent directories. + * + * @param paths - path to resolve + * @param options - function options + * @param options.dir - base directory + * @param options.mode - mode of operation + * @param predicate - predicate function + * @param clbk - callback to invoke after resolving paths + * @throws must provide valid options + * + * @example + * resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], { 'dir': __dirname, 'mode': 'some' }, predicate, onPaths ); + * + * function predicate( path, next ) { + * next( null, true ); + * } + * + * function onPaths( error, paths ) { + * if ( error ) { + * throw error; + * } + * console.log( paths ); + * } + */ + ( paths: Array, options: Options, predicate: AsyncPredicate, clbk: DoneCallback ): void; + + /** + * Asynchronously resolves paths from a set of paths according to a predicate function by walking parent directories. + * + * @param paths - path to resolve + * @param predicate - predicate function + * @param clbk - callback to invoke after resolving paths + * + * @example + * resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], predicate, onPaths ); + * + * function predicate( path, next ) { + * next( null, true ); + * } + * + * function onPaths( error, paths ) { + * if ( error ) { + * throw error; + * } + * console.log( paths ); + * } + */ + ( paths: Array, predicate: AsyncPredicate, clbk: DoneCallback ): void; + + /** + * Synchronously resolves paths from a set of paths according to a predicate function by walking parent directories. + * + * ## Notes + * + * - If unable to resolve a path, the function returns an empty array as the path result. + * + * @param paths - paths to resolve + * @param options - function options + * @param options.dir - base directory + * @param options.mode - mode of operation + * @param predicate - predicate function + * @throws must provide valid options + * @returns resolved paths + * + * @example + * function predicate() { + * return true; + * } + * + * var paths = resolveParentPathsBy.sync( [ 'package.json', 'package-lock.json' ], { 'dir': __dirname, 'mode': 'some' }, predicate ); + * // e.g., returns [ '...', '...' ] + */ + sync( paths: Array, options: Options, predicate: SyncPredicate ): Array; + + /** + * Synchronously resolves paths from a set of paths according to a predicate function by walking parent directories. + * + * ## Notes + * + * - If unable to resolve a path, the function returns an empty array as the path result. + * + * @param paths - paths to resolve + * @param predicate - predicate function + * @throws must provide valid options + * @returns resolved paths + * + * @example + * function predicate() { + * return true; + * } + * + * var paths = resolveParentPathsBy.sync( [ 'package.json', 'package-lock.json' ], predicate ); + * // e.g., returns [ '...', '...' ] + */ + sync( paths: Array, predicate: SyncPredicate ): Array; +} + +/** +* Asynchronously resolves paths from a set of paths according to a predicate function by walking parent directories. +* +* @param paths - paths to resolve +* @param options - function options +* @param options.dir - base directory +* @param options.mode - mode of operation +* @param predicate - predicate function +* @param clbk - callback to invoke after resolving paths +* @throws must provide valid options +* +* @example +* resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], predicate, onPaths ); +* +* function predicate( path, next ) { +* next( null, true ); +* } +* +* function onPaths( error, paths ) { +* if ( error ) { +* throw error; +* } +* console.log( paths ); +* } +* +* @example +* var paths = resolveParentPathsBy.sync( [ 'package.json', 'package-lock.json' ], predicate ); +* // e.g., returns [ '...', '...' ] +*/ +declare var resolveParentPathsBy: resolveParentPathsBy; + + +// EXPORTS // + +export = resolveParentPathsBy; diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/types/test.ts b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/types/test.ts new file mode 100644 index 00000000000..9a410208483 --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/docs/types/test.ts @@ -0,0 +1,266 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import resolveParentPathsBy = require( './index' ); + +/** +* Callback to invoke after processing a path. +* +* @param error - error object or null +* @param result - test result +*/ +type Callback = ( error: Error | null, result: boolean ) => void; + +/** +* Checks whether a path passes a test. +* +* @param path - resolved path +* @param next - callback +*/ +function predicate( path: string, next: Callback ): void { + next( null, ( path === path ) ); +} + +/** +* Checks whether a path passes a test. +* +* @param path - resolved path +*/ +function predicateSync( path: string ): boolean { + return ( path === path ); +} + +/** +* Callback function. +* +* @param error - error object +* @param path - resolved path +*/ +function done( error: Error | null, paths: Array ): void { + if ( error || paths === null ) { + throw error; + } +} + + +// TESTS // + +// The function does not have a return value... +{ + resolveParentPathsBy( [ 'package.json' ], predicate, done ); // $ExpectType void + resolveParentPathsBy( [ 'package.json' ], {}, predicate, done ); // $ExpectType void +} + +// The compiler throws an error if the function is provided a first argument which is not an array of strings... +{ + resolveParentPathsBy( 123, predicate, done ); // $ExpectError + resolveParentPathsBy( false, predicate, done ); // $ExpectError + resolveParentPathsBy( true, predicate, done ); // $ExpectError + resolveParentPathsBy( null, predicate, done ); // $ExpectError + resolveParentPathsBy( undefined, predicate, done ); // $ExpectError + resolveParentPathsBy( {}, predicate, done ); // $ExpectError + resolveParentPathsBy( ( x: number ): number => x, predicate, done ); // $ExpectError + resolveParentPathsBy( 'beep', predicate, done ); // $ExpectError + resolveParentPathsBy( [ 1, 2 ], predicate, done ); // $ExpectError + + resolveParentPathsBy( 123, {}, predicate, done ); // $ExpectError + resolveParentPathsBy( false, {}, predicate, done ); // $ExpectError + resolveParentPathsBy( true, {}, predicate, done ); // $ExpectError + resolveParentPathsBy( null, {}, predicate, done ); // $ExpectError + resolveParentPathsBy( undefined, {}, predicate, done ); // $ExpectError + resolveParentPathsBy( {}, {}, predicate, done ); // $ExpectError + resolveParentPathsBy( ( x: number ): number => x, {}, predicate, done ); // $ExpectError + resolveParentPathsBy( 'beep', {}, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 1, 2 ], {}, predicate, done ); // $ExpectError +} + +// The compiler throws an error if the function is provided a predicate function argument which is not a function with the expected signature... +{ + resolveParentPathsBy( [ '/var/log/' ], 1, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], false, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], true, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], null, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], undefined, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], [], done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], ( x: number ): number => x, done ); // $ExpectError + + resolveParentPathsBy( [ '/var/log/' ], {}, 1, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, false, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, true, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, null, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, undefined, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, [], done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, {}, done ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, ( x: number ): number => x, done ); // $ExpectError +} + +// The compiler throws an error if the function is provided a callback argument which is not a function with the expected signature... +{ + resolveParentPathsBy( [ '/var/log/' ], predicate, 1 ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], predicate, false ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], predicate, true ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], predicate, null ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], predicate, undefined ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], predicate, [] ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], predicate, {} ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], predicate, ( x: number ): number => x ); // $ExpectError + + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, 1 ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, false ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, true ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, null ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, undefined ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, [] ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, {} ); // $ExpectError + resolveParentPathsBy( [ '/var/log/' ], {}, predicate, ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an options argument which is not an object... +{ + resolveParentPathsBy( [ 'package.json' ], '5', predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], 5, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], true, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], false, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], null, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], undefined, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], [], predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], ( x: number ): number => x, predicate, done ); // $ExpectError +} + +// The compiler throws an error if the function is provided an `dir` option which is not a string... +{ + resolveParentPathsBy( [ 'package.json' ], { 'dir': 123 }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'dir': true }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'dir': false }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'dir': null }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'dir': [] }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'dir': {} }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'dir': ( x: number ): number => x }, predicate, done ); // $ExpectError +} + +// The compiler throws an error if the function is provided an `mode` option which is not a recognized string... +{ + resolveParentPathsBy( [ 'package.json' ], { 'mode': 'beep' }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'mode': 123 }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'mode': true }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'mode': false }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'mode': null }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'mode': [] }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'mode': {} }, predicate, done ); // $ExpectError + resolveParentPathsBy( [ 'package.json' ], { 'mode': ( x: number ): number => x }, predicate, done ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + resolveParentPathsBy(); // $ExpectError + resolveParentPathsBy( [ 'C:\\foo\\bar\\baz' ] ); // $ExpectError + resolveParentPathsBy( [ 'C:\\foo\\bar\\baz' ], {} ); // $ExpectError + resolveParentPathsBy( [ 'C:\\foo\\bar\\baz' ], predicate ); // $ExpectError + resolveParentPathsBy( [ 'C:\\foo\\bar\\baz' ], {}, predicate ); // $ExpectError + resolveParentPathsBy( [ 'C:\\foo\\bar\\baz' ], {}, predicate, done, {} ); // $ExpectError +} + +// Attached to main export is a `sync` method which returns an array... +{ + resolveParentPathsBy.sync( [ 'package.json' ], predicateSync ); // $ExpectType (string | null)[] + resolveParentPathsBy.sync( [ 'package.json' ], {}, predicateSync ); // $ExpectType (string | null)[] +} + +// The compiler throws an error if the `sync` method is provided a first argument which is not an array of strings... +{ + resolveParentPathsBy.sync( 123, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( false, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( true, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( null, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( undefined, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( ( x: number ): number => x, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( 'beep', predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 1, 2 ], predicateSync ); // $ExpectError + + resolveParentPathsBy.sync( 123, {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( false, {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( true, {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( null, {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( undefined, {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( {}, {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( ( x: number ): number => x, {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( 'beep', {}, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 1, 2 ], {}, predicateSync ); // $ExpectError +} + +// The compiler throws an error if the `sync` method is provided a predicate function argument which is not a function with the expected signature... +{ + resolveParentPathsBy.sync( [ 'package.json' ], 123 ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], false ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], true ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], null ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], undefined ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], [] ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {} ); // $ExpectError + + resolveParentPathsBy.sync( [ 'package.json' ], {}, 123 ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, false ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, true ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, null ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, undefined ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, [] ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, {} ); // $ExpectError +} + +// The compiler throws an error if the `sync` method is provided an options argument which is not an object... +{ + resolveParentPathsBy.sync( [ 'package.json' ], '5', predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], 5, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], true, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], false, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], null, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], [], predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], ( x: number ): number => x, predicateSync ); // $ExpectError +} + +// The compiler throws an error if the `sync` method is provided an `dir` option which is not a string... +{ + resolveParentPathsBy.sync( [ 'package.json' ], { 'dir': 123 }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'dir': true }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'dir': false }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'dir': null }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'dir': [] }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'dir': {} }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'dir': ( x: number ): number => x }, predicateSync ); // $ExpectError +} + +// The compiler throws an error if the `sync` method is provided an `mode` option which is not a recognized string... +{ + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': 'beep' }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': 123 }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': true }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': false }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': null }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': [] }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': {} }, predicateSync ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], { 'mode': ( x: number ): number => x }, predicateSync ); // $ExpectError +} + +// The compiler throws an error if the `sync` method is provided an unsupported number of arguments... +{ + resolveParentPathsBy.sync(); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, {} ); // $ExpectError + resolveParentPathsBy.sync( [ 'package.json' ], {}, predicateSync, {} ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/examples/index.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/examples/index.js new file mode 100644 index 00000000000..7b9d1d91527 --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/examples/index.js @@ -0,0 +1,64 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var resolveParentPathsBy = require( './../lib' ); + +var opts = { + 'dir': __dirname +}; + +/* Sync */ + +function predicateSync( path ) { + return path === path; +} + +var out = resolveParentPathsBy.sync( [ 'package.json', 'README.md' ], opts, predicateSync ); +console.log( out ); +// => [ '...', '...' ] + +out = resolveParentPathsBy.sync( [ 'non_existent_basename', 'package.json' ], opts, predicateSync ); +console.log( out ); +// => [] + +opts.mode = 'first'; +out = resolveParentPathsBy.sync( [ 'non_existent_basename', 'package.json' ], opts, predicateSync ); +console.log( out ); +// => [ '...' ] + +/* Async */ + +function predicateAsync( path, next ) { + setTimeout( onTimeout, 0 ); + + function onTimeout() { + next( null, true ); + } +} + +function onPaths( error, paths ) { + if ( error ) { + throw error; + } + console.log( paths ); +} + +resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicateAsync, onPaths ); +resolveParentPathsBy( [ './../non_existent_path' ], predicateAsync, onPaths ); diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/index.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/index.js new file mode 100644 index 00000000000..b6602814e2a --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/index.js @@ -0,0 +1,69 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Resolve paths from a set of paths according to a predicate function by walking parent directories. +* +* @module @stdlib/fs/resolve-parent-paths-by +* +* @example +* var resolveParentPathsBy = require( '@stdlib/fs/resolve-parent-paths-by' ); +* +* resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], predicate, onPaths ); +* +* function predicate( path, next ) { +* next( null, true ); +* } +* +* function onPaths( error, paths ) { +* if ( error ) { +* throw error; +* } +* console.log( paths ); +* } +* +* @example +* var resolveParentPathsBy = require( '@stdlib/fs/resolve-parent-paths-by' ); +* +* function predicate() { +* return true; +* } +* +* var paths = resolveParentPathsBy.sync( [ 'package.json', 'package-lock.json' ], predicate ); +* // e.g., returns [ '...', '...' ] +*/ + +// MODULES // + +var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var main = require( './main.js' ); +var sync = require( './sync.js' ); + + +// MAIN // + +setReadOnly( main, 'sync', sync ); + + +// EXPORTS // + +module.exports = main; + +// exports: { "sync": "main.sync" } diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/main.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/main.js new file mode 100644 index 00000000000..14ca8ccb0ae --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/main.js @@ -0,0 +1,507 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var isArrayLikeObject = require( '@stdlib/assert/is-array-like-object' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var cwd = require( '@stdlib/process/cwd' ); +var exists = require( '@stdlib/fs/exists' ); +var filled = require( '@stdlib/array/base/filled' ); +var format = require( '@stdlib/string/format' ); +var validate = require( './validate.js' ); + + +// VARIABLES // + +var MODES = { + 'first': first, + 'some': some, + 'all': all, + 'each': each +}; + + +// FUNCTIONS // + +/** +* Asynchronously resolves the first path match from a set of paths according to a predicate function by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @param {Callback} done - callback to invoke after resolving paths +* @returns {void} +*/ +function first( paths, dir, test, done ) { + var child; + var spath; + var idx; + var out; + + out = []; + + // Start at a base directory and continue moving up through each parent directory... + spath = resolve( dir, paths[ 0 ] ); + + idx = 1; // index of next path + exists( spath, onExists ); + + /** + * Callback invoked after checking for path existence. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onExists( error, bool ) { // eslint-disable-line node/handle-callback-err + if ( bool ) { + return test( spath, onTest ); + } + next(); + } + + /** + * Resolves the next candidate path. + * + * @private + * @returns {void} + */ + function next() { + if ( idx === paths.length ) { + // Resolve a parent directory: + child = dir; + dir = resolve( dir, '..' ); + + if ( child === dir ) { + return done( null, out ); + } + idx = 0; + } + spath = resolve( dir, paths[ idx ] ); + idx += 1; + exists( spath, onExists ); + } + + /** + * Callback invoked after testing a resolved path. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onTest( error, bool ) { + if ( error ) { + return done( error ); + } + if ( bool ) { + out.push(spath); + return done( null, out ); + } + next(); + } +} + +/** +* Asynchronously resolves one or more paths from a set of paths at a directory level according to a predicate function by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @param {Callback} done - callback to invoke after resolving paths +* @returns {void} +*/ +function some( paths, dir, test, done ) { + var child; + var spath; + var FLG; + var out; + + FLG = 0; // initialize flag to track if we are done traversing a directory level + out = []; + + // Start at a base directory and continue moving up through each parent directory... + return next( dir ); + + /** + * Resolves paths within a directory. + * + * @private + * @param {string} dir - directory to search + */ + function next( dir ) { + var i; + for ( i = 0; i < paths.length; i++ ) { + spath = resolve( dir, paths[ i ] ); + exists( spath, getCallback( spath ) ); + } + } + + /** + * Returns a callback to be invoked upon checking for path existence. + * + * @private + * @param {string} spath - resolved path + * @returns {Callback} callback + */ + function getCallback( spath ) { + return onExists; + + /** + * Callback invoked after testing a resolved path. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onTest( error, bool ) { + if ( error ) { + return done( error ); + } + if ( bool ) { + out.push(spath); + } + } + + /** + * Callback invoked after checking for path existence. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onExists( error, bool ) { // eslint-disable-line node/handle-callback-err + if ( bool ) { + test( spath, onTest ); + } + FLG += 1; + if ( FLG === paths.length ) { + // Check if we have resolved any paths... + if ( out.length > 0 ) { + return done( null, out ); + } + // Resolve a parent directory: + child = dir; + dir = resolve( dir, '..' ); + + // Reset flag: + FLG = 0; + + // If we have already reached root, we cannot resolve any higher directories... + if ( child === dir ) { + return done( null, out ); + } + // Resolve paths at next directory level: + return next( dir ); + } + } + } +} + +/** +* Asynchronously resolves all paths from a set of paths at a directory level according to a predicate function by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @param {Callback} done - callback to invoke after resolving paths +* @returns {void} +*/ +function all( paths, dir, test, done ) { + var count; + var child; + var spath; + var FLG; + var out; + + count = 0; // initialize counter to track if we are done resolving all paths + FLG = 0; // initialize flag to track if we are done traversing a directory level + out = filled( null, paths.length ); + + // Start at a base directory and continue moving up through each parent directory... + return next( dir ); + + /** + * Resolves paths within a directory. + * + * @private + * @param {string} dir - directory to search + */ + function next( dir ) { + var i; + for ( i = 0; i < paths.length; i++ ) { + spath = resolve( dir, paths[ i ] ); + exists( spath, getCallback( i, spath ) ); + } + } + + /** + * Returns a callback to be invoked upon checking for path existence. + * + * @private + * @param {NonNegativeInteger} idx - index + * @param {string} spath - resolved path + * @returns {Callback} callback + */ + function getCallback( idx, spath ) { + return onExists; + + /** + * Callback invoked after testing a resolved path. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onTest( error, bool ) { + if ( error ) { + return done( error ); + } + if ( bool ) { + out[ idx ] = spath; + } + } + + /** + * Callback invoked after checking for path existence. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onExists( error, bool ) { // eslint-disable-line node/handle-callback-err + if ( bool ) { + test( spath, onTest ); + count += 1; + } + FLG += 1; + if ( FLG === paths.length ) { + // Check if we have resolved any path... + if ( count === paths.length ) { + return done( null, out ); + } + // Resolve a parent directory: + child = dir; + dir = resolve( dir, '..' ); + + // Reset flag and buffers: + FLG = 0; + out = []; + count = 0; + + // If we have already reached root, we cannot resolve any higher directories... + if ( child === dir ) { + return done( null, out ); + } + // Resolve paths at next directory level: + return next( dir ); + } + } + } +} + +/** +* Asynchronously resolves each path from a set of paths according to a predicate function by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @param {Callback} done - callback to invoke after resolving paths +* @returns {void} +*/ +function each( paths, dir, test, done ) { + var count; + var child; + var spath; + var out; + var i; + + count = 0; // initialize counter to track if we are done resolving all paths + out = filled( null, paths.length ); + + // Start at a base directory and continue moving up through each parent directory... + for ( i = 0; i < paths.length; i++ ) { + spath = resolve( dir, paths[ i ] ); + exists( spath, getCallback( i, spath, dir ) ); + } + + /** + * Determines whether all paths have been resolved. + * + * @private + * @returns {void} + */ + function next() { + count += 1; + if ( count === paths.length ) { + return done( null, out ); + } + } + + /** + * Returns a callback to be invoked upon checking for path existence. + * + * @private + * @param {NonNegativeInteger} idx - index + * @param {string} spath - resolved path + * @param {string} dir - base directory + * @returns {Callback} callback + */ + function getCallback( idx, spath, dir ) { + return onExists; + + /** + * Callback invoked after testing a resolved path. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onTest( error, bool ) { + if ( error ) { + return done( error ); + } + if ( bool ) { + out[ idx ] = spath; + } + } + + /** + * Callback invoked after checking for path existence. + * + * @private + * @param {(Error|null)} error - error object + * @param {boolean} bool - boolean indicating if a path exists + * @returns {void} + */ + function onExists( error, bool ) { // eslint-disable-line node/handle-callback-err + if ( bool ) { + test( spath, onTest ); + return next(); + } + // Resolve a parent directory: + child = dir; + dir = resolve( dir, '..' ); + + // If we have already reached root, we cannot resolve any higher directories... + if ( child === dir ) { + out[ idx ] = null; + return next(); + } + // Resolve path at next directory level: + spath = resolve( dir, paths[ idx ] ); + exists( spath, getCallback( idx, spath, dir ) ); + } + } +} + + +// MAIN // + +/** +* Asynchronously resolves paths from a set of paths according to a predicate function by walking parent directories. +* +* @param {Array} paths - paths to resolve +* @param {Options} [options] - function options +* @param {string} [options.dir] - base directory +* @param {string} [options.mode] - mode of operation +* @param {Function} predicate - callback which tests whether a resolved path passes a test +* @param {Callback} clbk - callback to invoke after resolving paths +* @throws {TypeError} first argument must be an array of strings +* @throws {TypeError} callback argument must be a function +* @throws {TypeError} options argument must be an object +* @throws {TypeError} must provide valid options +* @returns {void} +* +* @example +* resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], predicate, onPaths ); +* +* function predicate( path, next ) { +* next( null, true ); +* } +* +* function onPaths( error, paths ) { +* if ( error ) { +* throw error; +* } +* console.log( paths ); +* } +*/ +function resolveParentPathsBy( paths, options, predicate, clbk ) { + var opts; + var done; + var mode; + var test; + var dir; + var fcn; + var err; + + if ( !isStringArray( paths ) ) { + if ( isArrayLikeObject( paths ) && paths.length === 0 ) { + return []; + } + throw new TypeError( format( 'invalid argument. First argument must be an array of strings. Value: `%s`.', paths ) ); + } + opts = {}; + if ( arguments.length > 3 ) { + err = validate( opts, options ); + if ( err ) { + throw err; + } + test = predicate; + done = clbk; + } else { + test = options; + done = predicate; + } + if ( !isFunction( test ) ) { + throw new TypeError( format( 'invalid argument. Callback argument must be a function. Value: `%s`.', done ) ); + } + if ( !isFunction( done ) ) { + throw new TypeError( format( 'invalid argument. Callback argument must be a function. Value: `%s`.', done ) ); + } + if ( opts.dir ) { + dir = resolve( cwd(), opts.dir ); + } else { + dir = cwd(); + } + mode = opts.mode || 'all'; + + fcn = MODES[ mode ]; + fcn( paths, dir, test, done ); +} + + +// EXPORTS // + +module.exports = resolveParentPathsBy; diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/sync.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/sync.js new file mode 100644 index 00000000000..ea013bc7d0a --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/sync.js @@ -0,0 +1,250 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var isArrayLikeObject = require( '@stdlib/assert/is-array-like-object' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var cwd = require( '@stdlib/process/cwd' ); +var exists = require( '@stdlib/fs/exists' ).sync; +var filled = require( '@stdlib/array/base/filled' ); +var format = require( '@stdlib/string/format' ); +var validate = require( './validate.js' ); + + +// VARIABLES // + +var MODES = { + 'first': first, + 'some': some, + 'all': all, + 'each': each +}; + + +// FUNCTIONS // + +/** +* Synchronously resolves the first path match from a set of paths according to a predicate function by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @returns {Array} resolved paths +*/ +function first( paths, dir, test ) { + var child; + var spath; + var out; + var i; + + // Start at a base directory and continue moving up through each parent directory... + out = []; + while ( child !== dir ) { + for ( i = 0; i < paths.length; i++ ) { + spath = resolve( dir, paths[ i ] ); + if ( exists( spath ) && test( spath ) ) { + out.push( spath ); + return out; + } + } + child = dir; + dir = resolve( dir, '..' ); + } + return out; +} + +/** +* Synchronously resolves one or more paths from a set of paths according to a predicate function at a directory level by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @returns {Array} resolved paths +*/ +function some( paths, dir, test ) { + var child; + var spath; + var out; + var i; + + // Start at a base directory and continue moving up through each parent directory... + out = []; + while ( child !== dir ) { + for ( i = 0; i < paths.length; i++ ) { + spath = resolve( dir, paths[ i ] ); + if ( exists( spath ) && test( spath ) ) { + out.push( spath ); + } + } + if ( out.length > 0 ) { + return out; + } + child = dir; + dir = resolve( dir, '..' ); + } + return out; +} + +/** +* Synchronously resolves all paths from a set of paths at a directory level according to a predicate function by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @returns {Array} resolved paths +*/ +function all( paths, dir, test ) { + var child; + var spath; + var out; + var i; + + // Start at a base directory and continue moving up through each parent directory... + out = []; + while ( child !== dir ) { + for ( i = 0; i < paths.length; i++ ) { + spath = resolve( dir, paths[ i ] ); + if ( exists( spath ) && test( spath ) ) { + out.push( spath ); + } + } + if ( out.length === paths.length ) { + return out; + } + out = []; + child = dir; + dir = resolve( dir, '..' ); + } + return out; +} + +/** +* Synchronously resolves each path from a set of paths according to a predicate function by walking parent directories. +* +* @private +* @param {Array} paths - paths to resolve +* @param {string} dir - base directory +* @param {Function} test - callback which tests whether a resolved path passes a test +* @returns {Array} resolved paths +*/ +function each( paths, dir, test ) { + var count; + var child; + var spath; + var out; + var i; + + count = 0; + out = filled( null, paths.length ); + + // Start at a base directory and continue moving up through each parent directory... + while ( child !== dir ) { + for ( i = 0; i < paths.length; i++ ) { + if ( out[ i ] !== null ) { + continue; + } + spath = resolve( dir, paths[ i ] ); + if ( exists( spath ) && test( spath ) ) { + out[ i ] = spath; + count += 1; + } + } + if ( count === paths.length ) { + break; + } + child = dir; + dir = resolve( dir, '..' ); + } + return out; +} + + +// MAIN // + +/** +* Synchronously resolves paths from a set of paths according to a predicate function by walking parent directories. +* +* @param {Array} paths - paths to resolve +* @param {Options} [options] - function options +* @param {string} [options.dir] - base directory +* @param {string} [options.mode='all'] - mode of operation +* @param {Function} predicate - callback which tests whether a resolved path passes a test +* @throws {TypeError} first argument must be an array of strings +* @throws {TypeError} options argument must be an object +* @throws {TypeError} must provide valid options +* @throws {TypeError} last argument must be a function +* @returns {Array} resolved paths +* +* @example +* function predicate() { +* return true; +* } +* +* var paths = resolveParentPathsBy( [ 'package.json', 'package-lock.json' ], predicate ); +* // e.g., returns [ '...', '...' ] +*/ +function resolveParentPathsBy( paths, options, predicate ) { + var opts; + var mode; + var test; + var dir; + var fcn; + var err; + + if ( !isStringArray( paths ) ) { + if ( isArrayLikeObject( paths ) && paths.length === 0 ) { + return []; + } + throw new TypeError( format( 'invalid argument. First argument must be an array of strings. Value: `%s`.', paths ) ); + } + opts = {}; + if ( arguments.length > 2 ) { + err = validate( opts, options ); + if ( err ) { + throw err; + } + test = predicate; + } else { + test = options; + } + if ( !isFunction( test ) ) { + throw new TypeError( format( 'invalid argument. Last argument must be a function. Value: `%s`.', test ) ); + } + if ( opts.dir ) { + dir = resolve( cwd(), opts.dir ); + } else { + dir = cwd(); + } + mode = opts.mode || 'all'; + + fcn = MODES[ mode ]; + return fcn( paths, dir, test ); +} + + +// EXPORTS // + +module.exports = resolveParentPathsBy; diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/validate.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/validate.js new file mode 100644 index 00000000000..36ecdb9c131 --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/lib/validate.js @@ -0,0 +1,81 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isObject = require( '@stdlib/assert/is-plain-object' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var format = require( '@stdlib/string/format' ); +var contains = require( '@stdlib/array/base/assert/contains' ).factory; + + +// VARIABLES // + +var isMode = contains( [ 'first', 'some', 'all', 'each' ] ); + + +// MAIN // + +/** +* Validates function options. +* +* @private +* @param {Object} opts - destination object +* @param {Options} options - function options +* @param {string} [options.dir] - base directory +* @param {string} [options.mode] - operation mode +* @returns {(Error|null)} error object or null +* +* @example +* var opts = {}; +* var options = { +* 'dir': '/foo/bar/baz', +* 'mode': 'some' +* }; +* +* var err = validate( opts, options ); +* if ( err ) { +* throw err; +* } +*/ +function validate( opts, options ) { + if ( !isObject( options ) ) { + return new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) ); + } + if ( hasOwnProp( options, 'dir' ) ) { + opts.dir = options.dir; + if ( !isString( opts.dir ) ) { + return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'dir', opts.dir ) ); + } + } + if ( hasOwnProp( options, 'mode' ) ) { + opts.mode = options.mode; + if ( !isMode( opts.mode ) ) { + return new TypeError( format( 'invalid option. `%s` option must be a valid mode. Option: `%s`.', 'mode', opts.mode ) ); + } + } + return null; +} + + +// EXPORTS // + +module.exports = validate; diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/package.json b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/package.json new file mode 100644 index 00000000000..772208c0d06 --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/package.json @@ -0,0 +1,79 @@ +{ + "name": "@stdlib/fs/resolve-parent-paths-by", + "version": "0.0.0", + "description": "Resolve paths from a set of paths according to a predicate function by walking parent directories.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "bin": { + "resolve-parent-paths-by": "./bin/cli" + }, + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdfs", + "fs", + "resolve", + "parent", + "path", + "async", + "sync", + "file", + "directory", + "dir", + "find", + "up", + "findup", + "find-up", + "upsearch", + "search", + "lookup", + "look-up", + "locate", + "walk", + "filesystem", + "predicate" + ] +} diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.js new file mode 100644 index 00000000000..e771107a72a --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.js @@ -0,0 +1,38 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var resolveParentPathsBy = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof resolveParentPathsBy, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'attached to the main export is a function to resolve parent paths synchronously', function test( t ) { + t.equal( typeof resolveParentPathsBy.sync, 'function', 'has `sync` method' ); + t.end(); +}); diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.main.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.main.js new file mode 100644 index 00000000000..a775215c94e --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.main.js @@ -0,0 +1,743 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var basename = require( 'path' ).basename; +var tape = require( 'tape' ); +var IS_BROWSER = require( '@stdlib/assert/is-browser' ); +var noop = require( '@stdlib/utils/noop' ); +var cwd = require( '@stdlib/process/cwd' ); +var contains = require( '@stdlib/assert/contains' ); +var resolveParentPathsBy = require( './../lib/main.js' ); + + +// VARIABLES // + +// Don't run tests in the browser...for now... +var opts = { + 'skip': IS_BROWSER +}; + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof resolveParentPathsBy, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if provided a `paths` argument which is not an array of strings', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + null, + void 0, + true, + {}, + function noop() {}, + 'beep', + [ 1, 2 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( value, predicate, noop ); + }; + } +}); + +tape( 'the function throws an error if provided a `paths` argument which is not an array of strings (options)', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + null, + void 0, + true, + {}, + function noop() {}, + 'beep', + [ 1, 2 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( value, {}, predicate, noop ); + }; + } +}); + +tape( 'the function throws an error if provided a callback argument which is not a function', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], predicate, value ); + }; + } +}); + +tape( 'the function throws an error if provided a callback argument which is not a function (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], {}, predicate, value ); + }; + } +}); + +tape( 'the function throws an error if provided a last argument which is not a function', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], predicate, value ); + }; + } +}); + +tape( 'the function throws an error if provided a last argument which is not a function (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], {}, predicate, value ); + }; + } +}); + +tape( 'the function throws an error if provided a predicate function argument which is not a function', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], value, noop ); + }; + } +}); + +tape( 'the function throws an error if provided a predicate function argument which is not a function (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], {}, value, noop ); + }; + } +}); + +tape( 'the function throws an error if provided an options argument which is not an object', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], value, predicate, noop ); + }; + } +}); + +tape( 'the function throws an error if provided an invalid option', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + null, + void 0, + true, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate( path, next ) { + next( null, true ); + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], { + 'dir': value + }, predicate, noop ); + }; + } +}); + +tape( 'the function resolves paths from a set of paths by walking parent directories', opts, function test( t ) { + var expected; + var base; + var dir; + + dir = cwd(); + base = basename( dir ); + + expected = dir; + resolveParentPathsBy( [ base ], predicate, onPaths ); + + function onPaths( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], expected, 'returns expected value' ); + t.end(); + } + + function predicate( path, next ) { + next( null, true ); + } +}); + +tape( 'the function resolves a path from a set of paths by walking parent directories (dir option)', opts, function test( t ) { + var expected; + var opts; + + opts = { + 'dir': __dirname + }; + expected = resolve( __dirname, '..', 'package.json' ); + + resolveParentPathsBy( [ 'package.json' ], opts, predicate, onPaths ); + + function onPaths( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], expected, 'returns expected value' ); + t.end(); + } + + function predicate( path, next ) { + next( null, true ); + } +}); + +tape( 'the function resolves the first path match from a set of paths by walking parent directories (mode=first)', opts, function test( t ) { + var opts; + var dir; + var FLG; + + FLG = 0; + opts = { + 'dir': __dirname, + 'mode': 'first' + }; + dir = resolve( __dirname, '..', 'package.json' ); + + resolveParentPathsBy( [ 'package.json' ], opts, predicate, onPaths ); + resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate, onPaths ); + resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicate, onPaths ); + + function onPaths( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], dir, 'returns expected value' ); + + FLG += 1; + if ( FLG === 3 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, true ); + } +}); + +tape( 'the function resolves one or more paths from a set of paths at a directory level by walking parent directories (mode=some)', opts, function test( t ) { + var opts; + var FLG; + var v1; + var v2; + + FLG = 0; + opts = { + 'dir': __dirname, + 'mode': 'some' + }; + v1 = resolve( __dirname, '..', 'package.json' ); + v2 = resolve( __dirname, '..', 'README.md' ); + + resolveParentPathsBy( [ 'package.json' ], opts, predicate, onPaths1 ); + resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate, onPaths1 ); + resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicate, onPaths2 ); + + function onPaths1( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + + FLG += 1; + if ( FLG === 3 ) { + t.end(); + } + } + + function onPaths2( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( contains( actual, v1 ), true, 'returns expected value' ); + t.strictEqual( contains( actual, v2 ), true, 'returns expected value' ); + + FLG += 1; + if ( FLG === 3 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, true ); + } +}); + +tape( 'the function resolves all paths from a set of paths at a directory level by walking parent directories (mode=all)', opts, function test( t ) { + var opts; + var FLG; + var v1; + var v2; + + FLG = 0; + opts = { + 'dir': __dirname, + 'mode': 'all' + }; + v1 = resolve( __dirname, '..', 'package.json' ); + v2 = resolve( __dirname, '..', 'README.md' ); + + resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate, onPathsNegative ); + resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicate, onPathsPositive ); + + function onPathsNegative( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns expected value' ); + + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function onPathsPositive( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + t.strictEqual( actual[ 1 ], v2, 'returns expected value' ); + + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, true ); + } +}); + +tape( 'the function resolves each path from a set of paths by walking parent directories (mode=each)', opts, function test( t ) { + var opts; + var FLG; + var v1; + var v2; + + FLG = 0; + opts = { + 'dir': __dirname, + 'mode': 'each' + }; + v1 = resolve( __dirname, '..', 'package.json' ); + v2 = resolve( __dirname, '..', '..', 'resolve-parent-paths' ); + + resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate, onPathsNegative ); + resolveParentPathsBy( [ 'package.json', 'resolve-parent-paths' ], opts, predicate, onPathsPositive ); + + function onPathsNegative( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( actual[ 0 ], null, 'returns expected value' ); + t.strictEqual( actual[ 1 ], v1, 'returns expected value' ); + + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function onPathsPositive( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + t.strictEqual( actual[ 1 ], v2, 'returns expected value' ); + + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, true ); + } +}); + +tape( 'the function returns an empty array if unable to resolve a parent path (mode=first)', opts, function test( t ) { + var opts; + var FLG; + + FLG = 0; + opts = { + 'mode': 'first' + }; + resolveParentPathsBy( [], opts, predicate, onPaths1 ); + resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate, onPaths2 ); + + t.end(); + + function onPaths1( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns empty array' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function onPaths2( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns empty array' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, false ); + } +}); + +tape( 'the function returns an empty array if unable to resolve a parent path (mode=some)', opts, function test( t ) { + var opts; + var FLG; + + FLG = 0; + opts = { + 'mode': 'some' + }; + resolveParentPathsBy( [], opts, predicate, onPaths1 ); + resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate, onPaths2 ); + t.end(); + + function onPaths1( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns empty array' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function onPaths2( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns empty array' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, false ); + } +}); + +tape( 'the function returns an empty array if unable to resolve a parent path (mode=all)', opts, function test( t ) { + var opts; + var FLG; + + FLG = 0; + opts = { + 'mode': 'all' + }; + resolveParentPathsBy( [], opts, predicate, onPaths1 ); + resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate, onPaths2 ); + t.end(); + + function onPaths1( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns empty array' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function onPaths2( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns empty array' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, false ); + } +}); + +tape( 'the function returns an array of `null` values if unable to resolve a parent path (mode=each)', opts, function test( t ) { + var opts; + var FLG; + + FLG = 0; + opts = { + 'mode': 'each' + }; + resolveParentPathsBy( [], opts, predicate, onPaths1 ); + resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate, onPaths2 ); + t.end(); + + function onPaths1( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 0, 'returns expected array' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function onPaths2( error, actual ) { + if ( error ) { + t.ok( false, error.message ); + } + t.strictEqual( actual.length, 1, 'returns expected array' ); + t.strictEqual( actual[ 0 ], null, 'returns expected value' ); + FLG += 1; + if ( FLG === 2 ) { + t.end(); + } + } + + function predicate( path, next ) { + next( null, false ); + } +}); diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.sync.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.sync.js new file mode 100644 index 00000000000..65467ce04d4 --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.sync.js @@ -0,0 +1,484 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var basename = require( 'path' ).basename; +var tape = require( 'tape' ); +var IS_BROWSER = require( '@stdlib/assert/is-browser' ); +var cwd = require( '@stdlib/process/cwd' ); +var isArray = require( '@stdlib/assert/is-array' ); +var resolveParentPathsBy = require( './../lib/sync.js' ); + + +// VARIABLES // + +// Don't run tests in the browser...for now... +var opts = { + 'skip': IS_BROWSER +}; + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof resolveParentPathsBy, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function throws an error if provided a `paths` argument which is not an array of strings', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + null, + void 0, + true, + {}, + function noop() {}, + 'beep', + [ 1, 2 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate() { + return true; + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( value, predicate ); + }; + } +}); + +tape( 'the function throws an error if provided a `paths` argument which is not an array of strings (options)', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + null, + void 0, + true, + {}, + function noop() {}, + 'beep', + [ 1, 2 ] + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate() { + return true; + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( value, {}, predicate ); + }; + } +}); + +tape( 'the function throws an error if provided an options argument which is not an object', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate() { + return true; + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], value, predicate ); + }; + } +}); + +tape( 'the function throws an error if provided an invalid option', function test( t ) { + var values; + var i; + + values = [ + 5, + NaN, + null, + void 0, + true, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function predicate() { + return true; + } + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'beep' ], { + 'dir': value + }, predicate); + }; + } +}); + +tape( 'the function throws an error if provided a last argument which is not a function', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'package.json' ], value ); + }; + } +}); + +tape( 'the function throws an error if provided a last argument which is not a function (options)', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + null, + void 0, + true, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws a type error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + resolveParentPathsBy( [ 'package.json' ], {}, value ); + }; + } +}); + +tape( 'the function resolves paths from a set of paths by walking parent directories', opts, function test( t ) { + var expected; + var actual; + var base; + var dir; + + dir = cwd(); + base = basename( dir ); + + expected = dir; + actual = resolveParentPathsBy( [ base ], predicate ); + + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], expected, 'returns expected value' ); + t.end(); + + function predicate() { + return true; + } +}); + +tape( 'the function resolves paths from a set of paths by walking parent directories (dir option)', opts, function test( t ) { + var expected; + var actual; + var opts; + + expected = resolve( __dirname, '..', 'package.json' ); + + opts = { + 'dir': __dirname + }; + actual = resolveParentPathsBy( [ 'package.json' ], opts, predicate ); + + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], expected, 'returns expected value' ); + t.end(); + + function predicate() { + return true; + } +}); + +tape( 'the function resolves the first path match from a set of paths by walking parent directories (mode=first)', opts, function test( t ) { + var expected; + var actual; + var opts; + + expected = resolve( __dirname, '..', 'package.json' ); + + opts = { + 'dir': __dirname, + 'mode': 'first' + }; + + actual = resolveParentPathsBy( [ 'package.json' ], opts, predicate ); + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], expected, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate ); + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], expected, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicate ); + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], expected, 'returns expected value' ); + + t.end(); + + function predicate() { + return true; + } +}); + +tape( 'the function resolves one or more paths from a set of paths at a directory level by walking parent directories (mode=some)', opts, function test( t ) { + var actual; + var opts; + var v1; + var v2; + + opts = { + 'dir': __dirname, + 'mode': 'some' + }; + v1 = resolve( __dirname, '..', 'package.json' ); + v2 = resolve( __dirname, '..', 'README.md' ); + + actual = resolveParentPathsBy( [ 'package.json' ], opts, predicate ); + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate ); + t.strictEqual( actual.length, 1, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicate ); + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + t.strictEqual( actual[ 1 ], v2, 'returns expected value' ); + + t.end(); + + function predicate() { + return true; + } +}); + +tape( 'the function resolves all paths from a set of paths at a directory level by walking parent directories (mode=all)', opts, function test( t ) { + var actual; + var opts; + var v1; + var v2; + + opts = { + 'dir': __dirname, + 'mode': 'all' + }; + v1 = resolve( __dirname, '..', 'package.json' ); + v2 = resolve( __dirname, '..', 'README.md' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'package.json', 'README.md' ], opts, predicate ); + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + t.strictEqual( actual[ 1 ], v2, 'returns expected value' ); + + t.end(); + + function predicate() { + return true; + } +}); + +tape( 'the function resolves each path from a set of paths by walking parent directories (mode=each)', opts, function test( t ) { + var actual; + var opts; + var v1; + var v2; + + opts = { + 'dir': __dirname, + 'mode': 'each' + }; + v1 = resolve( __dirname, '..', 'package.json' ); + v2 = resolve( __dirname, '..', '..', 'resolve-parent-paths-by' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!helloWorld!?!', 'package.json' ], opts, predicate ); + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( actual[ 0 ], null, 'returns expected value' ); + t.strictEqual( actual[ 1 ], v1, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'package.json', 'resolve-parent-paths-by' ], opts, predicate ); + t.strictEqual( actual.length, 2, 'returns expected value' ); + t.strictEqual( actual[ 0 ], v1, 'returns expected value' ); + t.strictEqual( actual[ 1 ], v2, 'returns expected value' ); + + t.end(); + + function predicate() { + return true; + } +}); + +tape( 'the function returns an empty array if unable to resolve a parent path (mode=first)', opts, function test( t ) { + var actual; + var opts; + + opts = { + 'mode': 'first' + }; + + actual = resolveParentPathsBy( [], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + t.end(); + + function predicate() { + return false; + } +}); + +tape( 'the function returns an empty array if unable to resolve a parent path (mode=some)', opts, function test( t ) { + var actual; + var opts; + + opts = { + 'mode': 'some' + }; + + actual = resolveParentPathsBy( [], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + t.end(); + + function predicate() { + return false; + } +}); + +tape( 'the function returns an empty array if unable to resolve a parent path (mode=all)', opts, function test( t ) { + var actual; + var opts; + + opts = { + 'mode': 'all' + }; + + actual = resolveParentPathsBy( [], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + t.end(); + + function predicate() { + return false; + } +}); + +tape( 'the function returns an array of `null` values if unable to resolve a parent path (mode=each)', opts, function test( t ) { + var actual; + var opts; + + opts = { + 'mode': 'each' + }; + + actual = resolveParentPathsBy( [], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual.length, 0, 'returns expected value' ); + + actual = resolveParentPathsBy( [ 'beep-boop!!!hello world!?!' ], opts, predicate ); + t.strictEqual( isArray( actual ), true, 'returns expected value' ); + t.strictEqual( actual[ 0 ], null, 'returns expected value' ); + + t.end(); + + function predicate() { + return false; + } +}); diff --git a/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.validate.js b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.validate.js new file mode 100644 index 00000000000..fbb6a8425a2 --- /dev/null +++ b/lib/node_modules/@stdlib/fs/resolve-parent-paths-by/test/test.validate.js @@ -0,0 +1,151 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var validate = require( './../lib/validate.js' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof validate, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'if provided an `options` argument which is not an `object`, the function returns a type error', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + '5', + 5, + NaN, + true, + null, + void 0, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = {}; + err = validate( opts, values[i] ); + t.equal( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'if provided a `dir` option which is not a string, the function returns a type error', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + 5, + NaN, + true, + null, + void 0, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = {}; + err = validate( opts, { + 'dir': values[i] + }); + t.equal( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'if provided a `mode` option which is not a valid mode, the function returns a type error', function test( t ) { + var values; + var opts; + var err; + var i; + + values = [ + 5, + NaN, + true, + null, + void 0, + [], + {}, + function noop() {}, + 'beep' + ]; + + for ( i = 0; i < values.length; i++ ) { + opts = {}; + err = validate( opts, { + 'mode': values[i] + }); + t.equal( err instanceof TypeError, true, 'returns a type error when provided '+values[i] ); + } + t.end(); +}); + +tape( 'the function returns `null` if all options are valid', function test( t ) { + var opts; + var obj; + var err; + + opts = { + 'dir': './beep/boop', + 'mode': 'first' + }; + obj = {}; + err = validate( obj, opts ); + + t.equal( err, null, 'returns expected value' ); + t.equal( obj.dir, opts.dir, 'returns expected value' ); + t.equal( obj.mode, opts.mode, 'returns expected value' ); + + t.end(); +}); + +tape( 'the function ignores unsupported/unrecognized options', function test( t ) { + var opts; + var obj; + var err; + + opts = { + 'beep': 'boop', + 'a': 'b', + 'c': [ 1, 2, 3 ] + }; + obj = {}; + err = validate( obj, opts ); + + t.equal( err, null, 'returns expected value' ); + t.deepEqual( obj, {}, 'returns expected value' ); + + t.end(); +});