diff --git a/has-arrow-function-support/README.md b/has-arrow-function-support/README.md new file mode 100644 index 00000000..e3f2e506 --- /dev/null +++ b/has-arrow-function-support/README.md @@ -0,0 +1,125 @@ + + +# Arrow Function Support + +> Detect native [`arrow function`][arrow-function] support. + +
+ +## Usage + +```javascript +var hasArrowFunctionSupport = require( '@stdlib/assert/has-arrow-function-support' ); +``` + +#### hasArrowFunctionSupport() + +Detects if a runtime environment supports ES2015 [`arrow functions`][arrow-function]` such as `( a, b ) => a + b`, `x => x`, or `( x ) => { return x*x; }`. + +```javascript +var bool = hasArrowFunctionSupport(); +// returns +``` + +
+ + + +
+ +## Notes + +- The implementation uses code evaluation, which may be problematic in browser contexts enforcing a strict [content security policy][mdn-csp] (CSP). + +
+ + + +
+ +## Examples + + + +```javascript +var hasArrowFunctionSupport = require( '@stdlib/assert/has-arrow-function-support' ); + +var bool = hasArrowFunctionSupport(); +if ( bool ) { + console.log( 'Environment has native arrow function support.' ); +} else { + console.log( 'Environment lacks native arrow function support.' ); +} +``` + +
+ + + +* * * + +
+ +## CLI + +
+ +### Usage + +```text +Usage: has-arrow-function-support [options] + +Options: + + -h, --help Print this message. + -V, --version Print the package version. +``` + +
+ + + +
+ +### Examples + +```bash +$ has-arrow-function-support + +``` + +
+ + + +
+ + + + + + diff --git a/has-arrow-function-support/benchmark/benchmark.js b/has-arrow-function-support/benchmark/benchmark.js new file mode 100644 index 00000000..078604e5 --- /dev/null +++ b/has-arrow-function-support/benchmark/benchmark.js @@ -0,0 +1,50 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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 bench = require( '@stdlib/bench' ); +var isBoolean = require( './../../is-boolean' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var hasArrowFunctionSupport = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var bool; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + // Note: the following *could* be optimized away via loop-invariant code motion. If so, the entire loop will disappear. + bool = hasArrowFunctionSupport(); + if ( !isBoolean( bool ) ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( isBoolean( bool ) ) { + b.pass( 'benchmark finished' ); + } else { + b.fail( 'should return a boolean' ); + } + b.end(); +}); diff --git a/has-arrow-function-support/bin/cli b/has-arrow-function-support/bin/cli new file mode 100755 index 00000000..f92ab0b6 --- /dev/null +++ b/has-arrow-function-support/bin/cli @@ -0,0 +1,60 @@ +#!/usr/bin/env node + +/** +* @license Apache-2.0 +* +* Copyright (c) 2 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 readFileSync = require( '@stdlib/fs/read-file' ).sync; +var CLI = require( '@stdlib/cli/ctor' ); +var detect = require( './../lib' ); + + +// MAIN // + +/** +* Main execution sequence. +* +* @private +*/ +function main() { + var flags; + var cli; + + // Create a command-line interface: + cli = new CLI({ + 'pkg': require( './../package.json' ), + 'options': require( './../etc/cli_opts.json' ), + 'help': readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), { + 'encoding': 'utf8' + }) + }); + + // Get any provided command-line options: + flags = cli.flags(); + if ( flags.help || flags.version ) { + return; + } + + console.log( detect() ); // eslint-disable-line no-console +} + +main(); diff --git a/has-arrow-function-support/docs/repl.txt b/has-arrow-function-support/docs/repl.txt new file mode 100644 index 00000000..47cc8de6 --- /dev/null +++ b/has-arrow-function-support/docs/repl.txt @@ -0,0 +1,17 @@ + +{{alias}}() + Tests whether an environment supports native arrow functions. + + Returns + ------- + bool: boolean + Boolean indicating if an environment support arrow functions. + + Examples + -------- + > var bool = {{alias}}() + + + See Also + -------- + diff --git a/has-arrow-function-support/docs/types/index.d.ts b/has-arrow-function-support/docs/types/index.d.ts new file mode 100644 index 00000000..a70ce9f9 --- /dev/null +++ b/has-arrow-function-support/docs/types/index.d.ts @@ -0,0 +1,35 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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: 2.0 + +/** +* Tests for native arrow function support. +* +* @returns boolean indicating if an environment has native arrow function support +* +* @example +* var bool = hasArrowFunctionSupport(); +* // returns +*/ +declare function hasArrowFunctionSupport(): boolean; + + +// EXPORTS // + +export = hasArrowFunctionSupport; diff --git a/has-arrow-function-support/docs/types/test.ts b/has-arrow-function-support/docs/types/test.ts new file mode 100644 index 00000000..44f4b6ef --- /dev/null +++ b/has-arrow-function-support/docs/types/test.ts @@ -0,0 +1,33 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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 hasArrowFunctionSupport = require( './index' ); + + +// TESTS // + +// The function returns a boolean... +{ + hasArrowFunctionSupport(); // $ExpectType boolean +} + +// The compiler throws an error if the function is provided arguments... +{ + hasArrowFunctionSupport( true ); // $ExpectError + hasArrowFunctionSupport( [], 123 ); // $ExpectError +} diff --git a/has-arrow-function-support/docs/usage.txt b/has-arrow-function-support/docs/usage.txt new file mode 100644 index 00000000..1be9f117 --- /dev/null +++ b/has-arrow-function-support/docs/usage.txt @@ -0,0 +1,7 @@ + +Usage: has-arrow-function-support [options] + +Options: + + -h, --help Print this message. + -V, --version Print the package version. diff --git a/has-arrow-function-support/etc/cli_opts.json b/has-arrow-function-support/etc/cli_opts.json new file mode 100644 index 00000000..f245a17e --- /dev/null +++ b/has-arrow-function-support/etc/cli_opts.json @@ -0,0 +1,14 @@ +{ + "boolean": [ + "help", + "version" + ], + "alias": { + "help": [ + "h" + ], + "version": [ + "V" + ] + } +} diff --git a/has-arrow-function-support/examples/index.js b/has-arrow-function-support/examples/index.js new file mode 100644 index 00000000..a4ab2fc0 --- /dev/null +++ b/has-arrow-function-support/examples/index.js @@ -0,0 +1,28 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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 hasArrowFunctionSupport = require( './../lib' ); + +var bool = hasArrowFunctionSupport(); +if ( bool ) { + console.log( 'Environment has native arrow function support.' ); +} else { + console.log( 'Environment lacks native arrow function support.' ); +} diff --git a/has-arrow-function-support/lib/index.js b/has-arrow-function-support/lib/index.js new file mode 100644 index 00000000..6b3a0222 --- /dev/null +++ b/has-arrow-function-support/lib/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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'; + +/** +* Test for native arrow function support. +* +* @module @stdlib/assert/has-arrow-function-support +* +* @example +* var hasArrowFunctionSupport = require( '@stdlib/assert/has-arrow-function-support' ); +* +* var bool = hasArrowFunctionSupport(); +* // returns +*/ + +// MODULES // + +var hasArrowFunctionSupport = require( './main.js' ); + + +// EXPORTS // + +module.exports = hasArrowFunctionSupport; diff --git a/has-arrow-function-support/lib/main.js b/has-arrow-function-support/lib/main.js new file mode 100644 index 00000000..9113a47c --- /dev/null +++ b/has-arrow-function-support/lib/main.js @@ -0,0 +1,51 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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 evil = require( '@stdlib/utils/eval' ); + + +// MAIN // + +/** +* Tests for native arrow function support. +* +* @returns {boolean} boolean indicating if an environment has native arrow function support +* +* @example +* var bool = hasArrowFunctionSupport(); +* // returns +*/ +function hasArrowFunctionSupport() { + var bool; + try { + evil( '"use strict"; (() => {})' ); + bool = true; + } catch ( err ) { // eslint-disable-line no-unused-vars + bool = false; + } + return bool; +} + + +// EXPORTS // + +module.exports = hasArrowFunctionSupport; diff --git a/has-arrow-function-support/package.json b/has-arrow-function-support/package.json new file mode 100644 index 00000000..5fac5446 --- /dev/null +++ b/has-arrow-function-support/package.json @@ -0,0 +1,78 @@ +{ + "name": "@stdlib/assert/has-arrow-function-support", + "version": "0.0.0", + "description": "Detect native arrow function support.", + "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": { + "has-arrow-function-support": "./bin/cli" + }, + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "bin": "./bin", + "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", + "stdutils", + "stdutil", + "utilities", + "utility", + "utils", + "util", + "detect", + "feature", + "arrow", + "arrow function", + "yield", + "es2015", + "es6", + "support", + "has", + "hasarrowfunction", + "hasarrowfunctions", + "native", + "issupported", + "cli" + ] +} diff --git a/has-arrow-function-support/test/test.cli.js b/has-arrow-function-support/test/test.cli.js new file mode 100644 index 00000000..2377fff1 --- /dev/null +++ b/has-arrow-function-support/test/test.cli.js @@ -0,0 +1,163 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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 exec = require( 'child_process' ).exec; +var tape = require( 'tape' ); +var IS_BROWSER = require( './../../is-browser' ); +var IS_WINDOWS = require( './../../is-windows' ); +var EXEC_PATH = require( '@stdlib/process/exec-path' ); +var readFileSync = require( '@stdlib/fs/read-file' ).sync; + + +// VARIABLES // + +var fpath = resolve( __dirname, '..', 'bin', 'cli' ); +var opts = { + 'skip': IS_BROWSER || IS_WINDOWS +}; + + +// FIXTURES // + +var PKG_VERSION = require( './../package.json' ).version; + + +// TESTS // + +tape( 'command-line interface', function test( t ) { + t.ok( true, __filename ); + t.end(); +}); + +tape( 'when invoked with a `--help` flag, the command-line interface prints the help text to `stderr`', opts, function test( t ) { + var expected; + var cmd; + + expected = readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), { + 'encoding': 'utf8' + }); + cmd = [ + EXEC_PATH, + fpath, + '--help' + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + if ( error ) { + t.fail( error.message ); + } else { + t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' ); + t.strictEqual( stderr.toString(), expected+'\n', 'expected value' ); + } + t.end(); + } +}); + +tape( 'when invoked with a `-h` flag, the command-line interface prints the help text to `stderr`', opts, function test( t ) { + var expected; + var cmd; + + expected = readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), { + 'encoding': 'utf8' + }); + cmd = [ + EXEC_PATH, + fpath, + '-h' + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + if ( error ) { + t.fail( error.message ); + } else { + t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' ); + t.strictEqual( stderr.toString(), expected+'\n', 'expected value' ); + } + t.end(); + } +}); + +tape( 'when invoked with a `--version` flag, the command-line interface prints the version to `stderr`', opts, function test( t ) { + var cmd = [ + EXEC_PATH, + fpath, + '--version' + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + if ( error ) { + t.fail( error.message ); + } else { + t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' ); + t.strictEqual( stderr.toString(), PKG_VERSION+'\n', 'expected value' ); + } + t.end(); + } +}); + +tape( 'when invoked with a `-V` flag, the command-line interface prints the version to `stderr`', opts, function test( t ) { + var cmd = [ + EXEC_PATH, + fpath, + '-V' + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + if ( error ) { + t.fail( error.message ); + } else { + t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' ); + t.strictEqual( stderr.toString(), PKG_VERSION+'\n', 'expected value' ); + } + t.end(); + } +}); + +tape( 'the command-line interface prints either `true` or `false` to `stdout` indicating whether an environment provides native `() => {}` support', opts, function test( t ) { + var cmd = [ + EXEC_PATH, + fpath + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + var str; + if ( error ) { + t.fail( error.message ); + } else { + str = stdout.toString(); + t.strictEqual( str === 'true\n' || str === 'false\n', true, 'prints either `true` or `false` to `stdout`' ); + t.strictEqual( stderr.toString(), '', 'does not print to `stderr`' ); + } + t.end(); + } +}); diff --git a/has-arrow-function-support/test/test.js b/has-arrow-function-support/test/test.js new file mode 100644 index 00000000..83fa2bbf --- /dev/null +++ b/has-arrow-function-support/test/test.js @@ -0,0 +1,65 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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 proxyquire = require( 'proxyquire' ); +var detect = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof detect, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'feature detection result is a boolean', function test( t ) { + t.strictEqual( typeof detect(), 'boolean', 'detection result is a boolean' ); + t.end(); +}); + +tape( 'if `() => {}` is supported, detection result is `true`', function test( t ) { + var detect = proxyquire( './../lib/main.js', { + '@stdlib/utils/eval': stub + }); + + t.ok( detect(), 'detection result is `true`' ); + t.end(); + + function stub() { + return 'beep'; + } +}); + +tape( 'if `() => {}` is not supported, detection result is `false`', function test( t ) { + var detect = proxyquire( './../lib/main.js', { + '@stdlib/utils/eval': stub + }); + + t.notOk( detect(), 'detection result is `false`' ); + t.end(); + + function stub() { + throw new Error( 'boop' ); + } +}); diff --git a/is-arrow-function/README.md b/is-arrow-function/README.md new file mode 100644 index 00000000..ed10995f --- /dev/null +++ b/is-arrow-function/README.md @@ -0,0 +1,105 @@ + + +# isArrowFunction + +> Test if a value is an [`arrow function`][mdn-arrow-function]. + +
+ +## Usage + +```javascript +var isArrowFunction = require( '@stdlib/assert/is-arrow-function' ); +``` + +#### isArrowFunction( value ) + +Tests if a `value` is a an [`arrow function`][mdn-arrow-function] such as `( a, b ) => a + b`, `x => x`, or `( x ) => { return x*x; }`. + + + +```javascript +var beep = () => { + console.log( 'beep' ); +}; + +var bool = isArrowFunction( beep ); +// returns true + +function boop() { + console.log( 'boop' ); +} + +bool = isArrowFunction( boop ); +// returns false +``` + +
+ + + +
+ +## Examples + + + + + +```javascript +var isArrowFunction = require( '@stdlib/assert/is-arrow-function' ); + +var bool = isArrowFunction( () => {} ); +// returns true + +bool = isArrowFunction( function foo() {} ); +// returns false + +bool = isArrowFunction( 'beep' ); +// returns false + +bool = isArrowFunction( 5 ); +// returns false + +bool = isArrowFunction( true ); +// returns false + +bool = isArrowFunction( null ); +// returns false + +bool = isArrowFunction( [] ); +// returns false + +bool = isArrowFunction( {} ); +// returns false +``` + +
+ + + + + + diff --git a/is-arrow-function/benchmark/benchmark.js b/is-arrow-function/benchmark/benchmark.js new file mode 100644 index 00000000..4aa6887e --- /dev/null +++ b/is-arrow-function/benchmark/benchmark.js @@ -0,0 +1,78 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* eslint-disable no-empty-function */ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var evil = require( '@stdlib/utils/eval' ); +var hasArrowFunctionSupport = require( './../../has-arrow-function-support' ); +var isBoolean = require( './../../is-boolean' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var isArrowFunction = require( './../lib' ); + + +// FUNCTIONS // + +function createArrowFunction() { + return evil( '( () => {} )' ); +} + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var bool; + var i; + + values = [ + '5', + 5, + NaN, + true, + false, + null, + void 0, + [], + {}, + new Date(), + function noop() {} + ]; + if ( hasArrowFunctionSupport() ) { + values.push( createArrowFunction() ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + bool = isArrowFunction( values[ i%values.length ] ); + if ( !isBoolean( bool ) ) { + b.fail( 'should return a boolean' ); + } + } + b.toc(); + if ( isBoolean( bool ) ) { + b.pass( 'benchmark finished' ); + } else { + b.fail( 'should return a boolean' ); + } + b.end(); +}); diff --git a/is-arrow-function/docs/repl.txt b/is-arrow-function/docs/repl.txt new file mode 100644 index 00000000..df1d8c0d --- /dev/null +++ b/is-arrow-function/docs/repl.txt @@ -0,0 +1,25 @@ + +{{alias}}( value ) + Tests if a value is an arrow function. + + Parameters + ---------- + value: any + Value to test. + + Returns + ------- + bool: boolean + Boolean indicating whether value is an arrow function. + + Examples + -------- + > function beep() {}; + > var bool = {{alias}}( beep ) + false + > bool = {{alias}}( {} ) + false + + See Also + -------- + diff --git a/is-arrow-function/docs/types/index.d.ts b/is-arrow-function/docs/types/index.d.ts new file mode 100644 index 00000000..f5787421 --- /dev/null +++ b/is-arrow-function/docs/types/index.d.ts @@ -0,0 +1,45 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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: 2.0 + +/** +* Tests if a value is an arrow function. +* +* @param value - value to test +* @returns boolean indicating whether value is an arrow function +* +* @example +* var arrow = () => {}; +* var bool = isArrowFunction( arrow ); +* // returns true +* +* @example +* function beep() { +* return 'beep'; +* } + +* var bool = isArrowFunction( beep ); +* // returns false +*/ +declare function isArrowFunction( value: any ): boolean; + + +// EXPORTS // + +export = isArrowFunction; diff --git a/is-arrow-function/docs/types/test.ts b/is-arrow-function/docs/types/test.ts new file mode 100644 index 00000000..468f813a --- /dev/null +++ b/is-arrow-function/docs/types/test.ts @@ -0,0 +1,34 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2021 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 isArrowFunction = require( './index' ); + + +// TESTS // + +// The function returns a boolean... +{ + isArrowFunction( ( x: number ) => x ); // $ExpectType boolean + isArrowFunction( [] ); // $ExpectType boolean +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + isArrowFunction(); // $ExpectError + isArrowFunction( ( x: number ) => x, 123 ); // $ExpectError +} diff --git a/is-arrow-function/examples/index.js b/is-arrow-function/examples/index.js new file mode 100644 index 00000000..ef6959c6 --- /dev/null +++ b/is-arrow-function/examples/index.js @@ -0,0 +1,55 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* eslint-disable no-empty-function, no-restricted-syntax */ + +'use strict'; + +var hasArrowFunctionSupport = require( './../../has-arrow-function-support' ); +var evil = require( '@stdlib/utils/eval' ); +var isArrowFunction = require( './../lib' ); + +function createArrowFunction() { + return evil( '( () => {} )' ); +} + +if ( hasArrowFunctionSupport() ) { + console.log( isArrowFunction( createArrowFunction() ) ); + // => true +} + +console.log( isArrowFunction( function foo() {} ) ); +// => false + +console.log( isArrowFunction( 'beep' ) ); +// => false + +console.log( isArrowFunction( 5 ) ); +// => false + +console.log( isArrowFunction( true ) ); +// => false + +console.log( isArrowFunction( null ) ); +// => false + +console.log( isArrowFunction( [] ) ); +// => false + +console.log( isArrowFunction( {} ) ); +// => false diff --git a/is-arrow-function/lib/index.js b/is-arrow-function/lib/index.js new file mode 100644 index 00000000..7543a4f0 --- /dev/null +++ b/is-arrow-function/lib/index.js @@ -0,0 +1,49 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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'; + +/** +* Test if a value is an arrow function. +* +* @module @stdlib/assert/is-arrow-function +* +* @example +* var isArrowFunction = require( '@stdlib/assert/is-arrow-function' ); +* +* var beep = () => 'beep'; +* +* var bool = isArrowFunction( beep ); +* // returns true + +* function boop() { +* return 'boop'; +* } +* +* bool = isArrowFunction( boop ); +* // returns false +*/ + +// MODULES // + +var isArrowFunction = require( './main.js' ); + + +// EXPORTS // + +module.exports = isArrowFunction; diff --git a/is-arrow-function/lib/main.js b/is-arrow-function/lib/main.js new file mode 100644 index 00000000..1d2cec09 --- /dev/null +++ b/is-arrow-function/lib/main.js @@ -0,0 +1,67 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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 isFunction = require( './../../is-function' ); + + +// VARIABLES // + +var RE_ARROW_FUNCTION = /^(?:\([^)]*\) *|[^=]*)=>/; + +// Using `Function#toString` bypasses a value's own `toString` method to provide an extra, but not security proof, precaution to prevent a provided function from impersonating an arrow function: +var fcn2str = Function.prototype.toString; + + +// MAIN // + +/** +* Tests whether a value is an arrow function. +* +* @param {*} value - value to test +* @returns {boolean} boolean indicating whether a value is an arrow function +* +* @example +* var arrow = () => {}; +* var bool = isArrowFunction( arrow ); +* // returns true +* +* @example +* function beep() { +* return 'beep'; +* } + +* var bool = isArrowFunction( beep ); +* // returns false +*/ +function isArrowFunction( value ) { + var str; + if ( !isFunction( value ) ) { + return false; + } + str = fcn2str.call( value ); + return RE_ARROW_FUNCTION.test( str ); +} + + +// EXPORTS // + +module.exports = isArrowFunction; diff --git a/is-arrow-function/package.json b/is-arrow-function/package.json new file mode 100644 index 00000000..0dd0b7ed --- /dev/null +++ b/is-arrow-function/package.json @@ -0,0 +1,71 @@ +{ + "name": "@stdlib/assert/is-arrow-function", + "version": "0.0.0", + "description": "Test if a value is an arrow function.", + "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" + } + ], + "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", + "stdassert", + "assertion", + "assert", + "utilities", + "utility", + "utils", + "util", + "function", + "is", + "isfunction", + "arrow", + "arrowfunction", + "type", + "check", + "valid", + "validate", + "test" + ] +} diff --git a/is-arrow-function/test/es2015-arrow-function/index.js b/is-arrow-function/test/es2015-arrow-function/index.js new file mode 100644 index 00000000..77623b1d --- /dev/null +++ b/is-arrow-function/test/es2015-arrow-function/index.js @@ -0,0 +1,34 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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'; + +/* eslint-disable */ + +// MODULES // + +var tape = require( 'tape' ); +var isArrowFunction = require( './../../lib' ); + + +// TESTS // + +tape( 'the function returns `true` if provided an arrow function', function test( t ) { + t.equal( isArrowFunction( () => {} ), true, 'returns true' ); + t.end(); +}); diff --git a/is-arrow-function/test/test.js b/is-arrow-function/test/test.js new file mode 100644 index 00000000..eda8d407 --- /dev/null +++ b/is-arrow-function/test/test.js @@ -0,0 +1,96 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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 arrowFunctionSupport = require( './../../has-arrow-function-support' ); +var isArrowFunction = require( './../lib' ); + + +// VARIABLES // + +var hasArrowFunctions = arrowFunctionSupport(); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof isArrowFunction, 'function', 'main export is a function' ); + t.end(); +}); + +// Run arrow function tests if environment supports `() => {}`... + +if ( hasArrowFunctions ) { + require( './es2015-arrow-function' ); // eslint-disable-line stdlib/no-unassigned-require +} + +tape( 'the function returns `false` if provided a function trying to impersonate an arrow function', function test( t ) { + function pretend() {} + pretend.toString = function toString() { + return '() => {}'; + }; + t.strictEqual( isArrowFunction( pretend ), false, 'returns false' ); + t.end(); +}); + +tape( 'the function returns `false` if provided a function which is not an arrow function', function test( t ) { + // eslint-disable-next-line func-style, func-names + var beep = function () { + return 'boop'; + }; + t.strictEqual( isArrowFunction( beep ), false, 'returns false' ); + + beep = function beep() { + return 'boop'; + }; + t.strictEqual( isArrowFunction( beep ), false, 'returns false' ); + + function baz() { + return 'boop'; + } + t.strictEqual( isArrowFunction( baz ), false, 'returns false' ); + + t.end(); +}); + +tape( 'the function returns `false` if not provided a function', function test( t ) { + var values; + var i; + + values = [ + '5', + 5, + NaN, + void 0, + true, + false, + null, + [], + {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.strictEqual( isArrowFunction( values[i] ), false, 'returns false when provided '+values[i] ); + } + t.end(); +}); diff --git a/is-class/benchmark/benchmark.js b/is-class/benchmark/benchmark.js index a21d47ff..78db5d8d 100644 --- a/is-class/benchmark/benchmark.js +++ b/is-class/benchmark/benchmark.js @@ -22,10 +22,19 @@ var bench = require( '@stdlib/bench' ); var isBoolean = require( './../../is-boolean' ).isPrimitive; +var evil = require( '@stdlib/utils/eval' ); +var hasClassSupport = require( './../../has-class-support' ); var pkg = require( './../package.json' ).name; var isClass = require( './../lib' ); +// FUNCTIONS // + +function createClass() { + return evil( '(class Person {})' ); +} + + // MAIN // bench( pkg, function benchmark( b ) { @@ -34,7 +43,6 @@ bench( pkg, function benchmark( b ) { var i; values = [ - class Person {}, // eslint-disable-line no-restricted-syntax function Person() {}, // eslint-disable-line no-empty-function '5', 5, @@ -44,6 +52,9 @@ bench( pkg, function benchmark( b ) { null, void 0 ]; + if ( hasClassSupport() ) { + values.push( createClass() ); + } b.tic(); for ( i = 0; i < b.iterations; i++ ) { diff --git a/is-class/examples/index.js b/is-class/examples/index.js index d6360cfc..cb1a8d78 100644 --- a/is-class/examples/index.js +++ b/is-class/examples/index.js @@ -20,11 +20,21 @@ 'use strict'; +var hasClassSupport = require( './../../has-class-support' ); +var evil = require( '@stdlib/utils/eval' ); var isClass = require( './../lib' ); -var bool = isClass( class Person {} ); -console.log( bool ); -// => true +function createClass() { + return evil( '(class Person {})' ); +} + +var bool; + +if ( hasClassSupport() ) { + bool = isClass( createClass() ); + console.log( bool ); + // => true +} bool = isClass( function Person() {} ); console.log( bool ); diff --git a/is-class/test/es2015-class/index.js b/is-class/test/es2015-class/index.js new file mode 100644 index 00000000..65c64d85 --- /dev/null +++ b/is-class/test/es2015-class/index.js @@ -0,0 +1,37 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2021 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. +*/ + +/* eslint-disable no-restricted-syntax, max-classes-per-file */ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var isClass = require( './../../lib' ); + + +// TESTS // + +tape( 'the function returns `true` if provided an ES2015 class', function test( t ) { + var Rectangle = class {}; + t.strictEqual( isClass( Rectangle ), true, 'returns true' ); + + t.strictEqual( isClass( class Person {} ), true, 'returns true' ); + t.end(); +}); diff --git a/is-class/test/test.js b/is-class/test/test.js index 6f95364c..f5434856 100644 --- a/is-class/test/test.js +++ b/is-class/test/test.js @@ -21,9 +21,15 @@ // MODULES // var tape = require( 'tape' ); +var detectClassSupport = require( './../../has-class-support' ); var isClass = require( './../lib' ); +// VARIABLES // + +var hasClassSupport = detectClassSupport(); + + // TESTS // tape( 'main export is a function', function test( t ) { @@ -32,12 +38,7 @@ tape( 'main export is a function', function test( t ) { t.end(); }); -tape( 'the function returns `true` if provided is a class', function test( t ) { - t.strictEqual( isClass( class Person {} ), true, 'returns true' ); // eslint-disable-line no-restricted-syntax - t.end(); -}); - -tape( 'the function returns `false` if not provided an ES6 class', function test( t ) { +tape( 'the function returns `false` if not provided an ES2015 class', function test( t ) { var values; var i; @@ -59,3 +60,9 @@ tape( 'the function returns `false` if not provided an ES6 class', function test } t.end(); }); + +// Run positive tests if environment supports class... + +if ( hasClassSupport ) { + require( './es2015-class' ); // eslint-disable-line stdlib/no-unassigned-require +} diff --git a/lib/index.js b/lib/index.js index 6f1617f6..1a54cd94 100644 --- a/lib/index.js +++ b/lib/index.js @@ -81,6 +81,15 @@ setReadOnly( ns, 'deepHasProp', require( './../deep-has-property' ) ); */ setReadOnly( ns, 'hasArrayBufferSupport', require( './../has-arraybuffer-support' ) ); +/** +* @name hasArrowFunctionSupport +* @memberof ns +* @readonly +* @type {Function} +* @see {@link module:@stdlib/assert/has-arrow-function-support} +*/ +setReadOnly( ns, 'hasArrowFunctionSupport', require( './../has-arrow-function-support' ) ); + /** * @name hasAsyncAwaitSupport * @memberof ns @@ -531,6 +540,15 @@ setReadOnly( ns, 'isArrayBuffer', require( './../is-arraybuffer' ) ); */ setReadOnly( ns, 'isArrayBufferView', require( './../is-arraybuffer-view' ) ); +/** +* @name isArrowFunction +* @memberof ns +* @readonly +* @type {Function} +* @see {@link module:@stdlib/assert/is-arrow-function} +*/ +setReadOnly( ns, 'isArrowFunction', require( './../is-arrow-function' ) ); + /** * @name isASCII * @memberof ns