From 7d14f099e52e63d786808e19dd65b931b57e14fc Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Tue, 8 Aug 2023 17:23:30 -0500 Subject: [PATCH 01/14] feat: refactor remove-last API with base string packages --- .../base/remove-first-code-point/package.json | 2 +- .../package.json | 2 +- .../string/base/remove-first/package.json | 2 +- .../base/remove-last-code-point/README.md | 95 ++++++ .../benchmark/benchmark.js | 56 ++++ .../base/remove-last-code-point/docs/repl.txt | 29 ++ .../docs/types/index.d.ts | 53 ++++ .../remove-last-code-point/docs/types/test.ts | 57 ++++ .../remove-last-code-point/examples/index.js | 33 ++ .../base/remove-last-code-point/lib/index.js | 43 +++ .../base/remove-last-code-point/lib/main.js | 94 ++++++ .../base/remove-last-code-point/package.json | 67 +++++ .../base/remove-last-code-point/test/test.js | 96 ++++++ .../remove-last-grapheme-cluster/README.md | 104 +++++++ .../benchmark/benchmark.js | 56 ++++ .../docs/repl.txt | 30 ++ .../docs/types/index.d.ts | 57 ++++ .../docs/types/test.ts | 57 ++++ .../examples/index.js | 36 +++ .../remove-last-grapheme-cluster/lib/index.js | 46 +++ .../remove-last-grapheme-cluster/lib/main.js | 75 +++++ .../remove-last-grapheme-cluster/package.json | 68 +++++ .../remove-last-grapheme-cluster/test/test.js | 111 +++++++ .../@stdlib/string/base/remove-last/README.md | 92 ++++++ .../base/remove-last/benchmark/benchmark.js | 56 ++++ .../string/base/remove-last/docs/repl.txt | 29 ++ .../base/remove-last/docs/types/index.d.ts | 53 ++++ .../base/remove-last/docs/types/test.ts | 57 ++++ .../string/base/remove-last/examples/index.js | 30 ++ .../string/base/remove-last/lib/index.js | 43 +++ .../string/base/remove-last/lib/main.js | 53 ++++ .../string/base/remove-last/package.json | 67 +++++ .../string/base/remove-last/test/test.js | 78 +++++ .../@stdlib/string/remove-last/README.md | 29 +- .../string/remove-last/benchmark/benchmark.js | 90 ++++++ .../@stdlib/string/remove-last/bin/cli | 29 +- .../@stdlib/string/remove-last/docs/repl.txt | 21 +- .../string/remove-last/docs/types/index.d.ts | 63 ++++ .../string/remove-last/docs/types/test.ts | 60 +++- .../@stdlib/string/remove-last/docs/usage.txt | 1 + .../string/remove-last/etc/cli_opts.json | 3 +- .../@stdlib/string/remove-last/lib/main.js | 67 ++++- .../string/remove-last/test/test.cli.js | 62 ++++ .../@stdlib/string/remove-last/test/test.js | 284 ++++++++++++++++-- 44 files changed, 2470 insertions(+), 66 deletions(-) create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/README.md create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/benchmark/benchmark.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/index.d.ts create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/test.ts create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/examples/index.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/index.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/package.json create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/README.md create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/benchmark/benchmark.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/index.d.ts create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/test.ts create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/examples/index.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/index.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/package.json create mode 100644 lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/README.md create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/benchmark/benchmark.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/docs/types/index.d.ts create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/docs/types/test.ts create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/examples/index.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/lib/index.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/lib/main.js create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/package.json create mode 100644 lib/node_modules/@stdlib/string/base/remove-last/test/test.js diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/package.json b/lib/node_modules/@stdlib/string/base/remove-first-code-point/package.json index c5e2628fb194..bd5f53e9b1c0 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/package.json +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/package.json @@ -1,5 +1,5 @@ { - "name": "@stdlib/string/base/first-code-point", + "name": "@stdlib/string/base/remove-first-code-point", "version": "0.0.0", "description": "Remove the first Unicode code point of a string.", "license": "Apache-2.0", diff --git a/lib/node_modules/@stdlib/string/base/remove-first-grapheme-cluster/package.json b/lib/node_modules/@stdlib/string/base/remove-first-grapheme-cluster/package.json index e0178441b7b9..c9b278e7e0c7 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-grapheme-cluster/package.json +++ b/lib/node_modules/@stdlib/string/base/remove-first-grapheme-cluster/package.json @@ -1,5 +1,5 @@ { - "name": "@stdlib/string/base/first-grapheme-cluster", + "name": "@stdlib/string/base/remove-first-grapheme-cluster", "version": "0.0.0", "description": "Remove the first grapheme cluster (i.e., user-perceived character) of a string.", "license": "Apache-2.0", diff --git a/lib/node_modules/@stdlib/string/base/remove-first/package.json b/lib/node_modules/@stdlib/string/base/remove-first/package.json index 9d5f7f258f3b..e183299014ee 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first/package.json +++ b/lib/node_modules/@stdlib/string/base/remove-first/package.json @@ -1,5 +1,5 @@ { - "name": "@stdlib/string/base/first", + "name": "@stdlib/string/base/remove-first", "version": "0.0.0", "description": "Remove the first UTF-16 code unit of a string.", "license": "Apache-2.0", diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/README.md b/lib/node_modules/@stdlib/string/base/remove-last-code-point/README.md new file mode 100644 index 000000000000..e1afa61780dd --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/README.md @@ -0,0 +1,95 @@ + + +# removeLastCodePoint + +> Remove the last `n` Unicode code points of a string. + +
+ +## Usage + +```javascript +var removeLastCodePoint = require( '@stdlib/string/base/remove-last-code-point' ); +``` + +#### removeLastCodePoint( str, n ) + +Removes the last `n` Unicode code points of a string. + +```javascript +var out = removeLastCodePoint( 'last man standing', 1 ); +// returns 'last man standin' + +out = removeLastCodePoint( 'Hidden Treasures', 1 ); +// returns 'Hidden Treasure' + +out = removeLastCodePoint( 'foo bar', 5 ); +// returns 'fo' + +out = removeLastCodePoint( 'foo bar', 10 ); +// returns '' +``` + +
+ + + +
+ +## Examples + + + +```javascript +var removeLastCodePoint = require( '@stdlib/string/base/remove-last-code-point' ); + +var str = removeLastCodePoint( 'presidential election', 1 ); +// returns 'presidential electio' + +str = removeLastCodePoint( 'JavaScript', 1 ); +// returns 'JavaScrip' + +str = removeLastCodePoint( 'The Last of the Mohicans', 5 ); +// returns 'The Last of the Moh' + +str = removeLastCodePoint( 'अनुच्छेद', 1 ); +// returns 'अनुच्छे' +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/benchmark/benchmark.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/benchmark/benchmark.js new file mode 100644 index 000000000000..1f34ea036fab --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/benchmark/benchmark.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var removeLast = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var i; + + values = [ + 'beep boop', + 'foo bar', + 'xyz abc', + '🐶🐮🐷🐰🐸' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = removeLast( values[ i%values.length ], 1 ); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/repl.txt b/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/repl.txt new file mode 100644 index 000000000000..a08ea5521cba --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/repl.txt @@ -0,0 +1,29 @@ + +{{alias}}( str, n ) + Removes the last `n` Unicode code points of a string. + + Parameters + ---------- + str: string + Input string. + + n: integer + Number of Unicode code points to remove. + + Returns + ------- + out: string + Output string. + + Examples + -------- + > var out = {{alias}}( 'beep', 1 ) + 'bee' + > out = {{alias}}( 'Boop', 1 ) + 'Boo' + > out = {{alias}}( 'foo bar', 5 ) + 'fo' + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/index.d.ts b/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/index.d.ts new file mode 100644 index 000000000000..8a1c90be35e9 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/index.d.ts @@ -0,0 +1,53 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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 + +/** +* Removes the last `n` Unicode code points of a string. +* +* @param str - input string +* @param n - number of code points to remove +* @returns output string +* +* @example +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* @example +* var out = removeLast( 'presidential election', 1 ); +* // returns 'presidential electio' +* +* @example +* var out = removeLast( 'JavaScript', 1 ); +* // returns 'JavaScrip' +* +* @example +* var out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure' +* +* @example +* var out = removeLast( 'foo bar', 5 ); +* // returns 'fo' +*/ +declare function removeLast( str: string, n: number ): string; + + +// EXPORTS // + +export = removeLast; diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/test.ts b/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/test.ts new file mode 100644 index 000000000000..fd426d2386eb --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/docs/types/test.ts @@ -0,0 +1,57 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLast = require( './index' ); + + +// TESTS // + +// The function returns a string... +{ + removeLast( 'abc', 1 ); // $ExpectType string +} + +// The compiler throws an error if the function is provided a value other than a string... +{ + removeLast( true, 1 ); // $ExpectError + removeLast( false, 1 ); // $ExpectError + removeLast( null, 1 ); // $ExpectError + removeLast( undefined, 1 ); // $ExpectError + removeLast( 5, 1 ); // $ExpectError + removeLast( [], 1 ); // $ExpectError + removeLast( {}, 1 ); // $ExpectError + removeLast( ( x: number ): number => x, 1 ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument that is not a number... +{ + removeLast( 'abc', true ); // $ExpectError + removeLast( 'abc', false ); // $ExpectError + removeLast( 'abc', null ); // $ExpectError + removeLast( 'abc', 'abc' ); // $ExpectError + removeLast( 'abc', [] ); // $ExpectError + removeLast( 'abc', {} ); // $ExpectError + removeLast( 'abc', ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + removeLast(); // $ExpectError + removeLast( 'abc' ); // $ExpectError + removeLast( 'abc', 1, 2 ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/examples/index.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/examples/index.js new file mode 100644 index 000000000000..085633ea496b --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/examples/index.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLastCodePoint = require( './../lib' ); + +console.log( removeLastCodePoint( 'presidential election', 1 ) ); +// => 'presidential electio' + +console.log( removeLastCodePoint( 'JavaScript', 1 ) ); +// => 'JavaScrip' + +console.log( removeLastCodePoint( 'The Last of the Mohicans', 5 ) ); +// => 'The Last of the Moh' + +console.log( removeLastCodePoint( 'अनुच्छेद', 1 ) ); +// => 'अनुच्छे' diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/index.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/index.js new file mode 100644 index 000000000000..6b889032215c --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/index.js @@ -0,0 +1,43 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +/** +* Remove the last `n` Unicode code points of a string. +* +* @module @stdlib/string/base/remove-last-code-point +* +* @example +* var removeLast = require( '@stdlib/string/base/remove-last-code-point' ); +* +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure'; +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js new file mode 100644 index 000000000000..eb7518aa07bf --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js @@ -0,0 +1,94 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +// VARIABLES // + +var RE_UTF16_LOW_SURROGATE = /[\uDC00-\uDFFF]/; // TODO: replace with stdlib pkg +var RE_UTF16_HIGH_SURROGATE = /[\uD800-\uDBFF]/; // TODO: replace with stdlib pkg + + +// MAIN // + +/** +* Removes the last `n` Unicode code points of a string. +* +* @param {string} str - input string +* @param {NonNegativeInteger} n - number of Unicode code points to remove +* @returns {string} output string +* +* @example +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* @example +* var out = removeLast( 'presidential election', 1 ); +* // returns 'presidential electio' +* +* @example +* var out = removeLast( 'JavaScript', 1 ); +* // returns 'JavaScrip' +* +* @example +* var out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure' +*/ +function removeLast( str, n ) { + var len; + var ch1; + var ch2; + var cnt; + var i; + if ( n === 0 ) { + return str; + } + len = str.length; + cnt = 0; + + // Process the string one Unicode code unit at a time and count UTF-16 surrogate pairs as a single Unicode code point... + for ( i = len - 1; i >= 0; i-- ) { + ch1 = str[ i ]; + cnt += 1; + + // Check for a high UTF-16 surrogate... + if ( RE_UTF16_HIGH_SURROGATE.test( ch1 ) ) { + // Check for an unpaired surrogate at the end of the input string... + if ( i === len-1 ) { + // We found an unpaired surrogate... + break; + } + // Check whether the high surrogate is paired with a low surrogate... + ch2 = str[ i-1 ]; + if ( RE_UTF16_LOW_SURROGATE.test( ch2 ) ) { + // We found a surrogate pair: + i -= 1; // bump the index to process the next code unit + } + } + // Check whether we've found the desired number of code points... + if ( cnt === n ) { + break; + } + } + return str.substring( 0, str.length - cnt ); +} + + +// EXPORTS // + +module.exports = removeLast; diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/package.json b/lib/node_modules/@stdlib/string/base/remove-last-code-point/package.json new file mode 100644 index 000000000000..b0450658f5eb --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/string/base/remove-last-code-point", + "version": "0.0.0", + "description": "Remove the last Unicode code point of a string.", + "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", + "stdstring", + "utilities", + "utility", + "utils", + "util", + "string", + "str", + "base", + "last", + "character", + "char", + "codepoint", + "unicode" + ] +} diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js new file mode 100644 index 000000000000..9306b4396275 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js @@ -0,0 +1,96 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLast = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof removeLast, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an empty string if provided an empty string', function test( t ) { + t.strictEqual( removeLast( '', 1 ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', 2 ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', 3 ), '', 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the input string if provided zero as the second argument', function test( t ) { + t.strictEqual( removeLast( 'hello world', 0 ), 'hello world', 'returns expected value' ); + t.end(); +}); + +tape( 'the function removes the last Unicode code point of a provided string (ascii)', function test( t ) { + var out; + + out = removeLast( 'hello world', 1 ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( '!!!', 1 ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( 'Hello World', 1 ); + t.strictEqual( out, 'Hello Worl', 'returns expected value' ); + + t.end(); +}); + +tape( 'the function removes the last Unicode code point of a provided string (Unicode)', function test( t ) { + var out; + + out = removeLast( 'अनुच्छेद', 1 ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 1 ); + t.strictEqual( out, '六书/六', 'returns expected value' ); + + t.end(); +}); + +tape( 'the function supports removing the last `n` Unicode code points of a provided string', function test( t ) { + var out; + + out = removeLast( 'hello world', 1 ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( 'hello world', 7 ); + t.strictEqual( out, 'hell', 'returns expected value' ); + + out = removeLast( '!!!', 1 ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( '!!!', 2 ); + t.strictEqual( out, '!', 'returns expected value' ); + + out = removeLast( 'अनुच्छेद', 1 ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 3 ); + t.strictEqual( out, '六书', 'returns expected value' ); + + t.end(); +}); diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/README.md b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/README.md new file mode 100644 index 000000000000..18938ce087e2 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/README.md @@ -0,0 +1,104 @@ + + +# removeLastGraphemeCluster + +> Remove the last `n` grapheme clusters (i.e., user-perceived characters) of a string. + +
+ +## Usage + + + +```javascript +var removeLastGraphemeCluster = require( '@stdlib/string/base/remove-last-grapheme-cluster' ); +``` + +#### removeLastGraphemeCluster( str, n ) + +Removes the last `n` grapheme clusters (i.e., user-perceived characters) of a string. + + + +```javascript +var out = removeLastGraphemeCluster( 'last man standing', 1 ); +// returns 'last man standin' + +out = removeLastGraphemeCluster( 'Hidden Treasures', 1 ); +// returns 'Hidden Treasure' + +out = removeLastGraphemeCluster( 'foo bar', 5 ); +// returns 'fo' + +out = removeLastGraphemeCluster( 'foo bar', 10 ); +// returns '' +``` + +
+ + + +
+ +## Examples + + + + + +```javascript +var removeLastGraphemeCluster = require( '@stdlib/string/base/remove-last-grapheme-cluster' ); + +var str = removeLastGraphemeCluster( 'presidential election', 1 ); +// returns 'presidential electio' + +str = removeLastGraphemeCluster( 'JavaScript', 1 ); +// returns 'JavaScrip' + +str = removeLastGraphemeCluster( 'The Last of the Mohicans', 5 ); +// returns 'The Last of the Moh' + +str = removeLastGraphemeCluster( '🐶🐮🐷🐰🐸', 2 ); +// returns '🐶🐮🐷' + +str = removeLastGraphemeCluster( '🐶🐮🐷🐰🐸', 10 ); +// returns '' +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/benchmark/benchmark.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/benchmark/benchmark.js new file mode 100644 index 000000000000..1f34ea036fab --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/benchmark/benchmark.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var removeLast = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var i; + + values = [ + 'beep boop', + 'foo bar', + 'xyz abc', + '🐶🐮🐷🐰🐸' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = removeLast( values[ i%values.length ], 1 ); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/repl.txt b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/repl.txt new file mode 100644 index 000000000000..24ce266c721a --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/repl.txt @@ -0,0 +1,30 @@ + +{{alias}}( str, n ) + Removes the last `n` grapheme clusters (i.e., user-perceived characters) + of a string. + + Parameters + ---------- + str: string + Input string. + + n: integer + Number of grapheme clusters to remove. + + Returns + ------- + out: string + Output string. + + Examples + -------- + > var out = {{alias}}( 'beep', 1 ) + 'bee' + > out = {{alias}}( 'Boop', 1 ) + 'Boo' + > out = {{alias}}( 'foo bar', 5 ) + 'fo' + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/index.d.ts b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/index.d.ts new file mode 100644 index 000000000000..bcefff046a0b --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/index.d.ts @@ -0,0 +1,57 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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 + +/** +* Removes the last `n` grapheme clusters (i.e., user-perceived characters) of a string. +* +* @param str - input string +* @param n - number of grapheme clusters to remove +* @returns output string +* +* @example +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* @example +* var out = removeLast( 'presidential election', 1 ); +* // returns 'presidential electio' +* +* @example +* var out = removeLast( 'JavaScript', 1 ); +* // returns 'JavaScrip' +* +* @example +* var out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure' +* +* @example +* var out = removeLast( '🐶🐮🐷🐰🐸', 2 ); +* // returns '🐶🐮🐷' +* +* @example +* var out = removeLast( 'foo bar', 5 ); +* // returns 'fo' +*/ +declare function removeLast( str: string, n: number ): string; + + +// EXPORTS // + +export = removeLast; diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/test.ts b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/test.ts new file mode 100644 index 000000000000..fd426d2386eb --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/docs/types/test.ts @@ -0,0 +1,57 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLast = require( './index' ); + + +// TESTS // + +// The function returns a string... +{ + removeLast( 'abc', 1 ); // $ExpectType string +} + +// The compiler throws an error if the function is provided a value other than a string... +{ + removeLast( true, 1 ); // $ExpectError + removeLast( false, 1 ); // $ExpectError + removeLast( null, 1 ); // $ExpectError + removeLast( undefined, 1 ); // $ExpectError + removeLast( 5, 1 ); // $ExpectError + removeLast( [], 1 ); // $ExpectError + removeLast( {}, 1 ); // $ExpectError + removeLast( ( x: number ): number => x, 1 ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument that is not a number... +{ + removeLast( 'abc', true ); // $ExpectError + removeLast( 'abc', false ); // $ExpectError + removeLast( 'abc', null ); // $ExpectError + removeLast( 'abc', 'abc' ); // $ExpectError + removeLast( 'abc', [] ); // $ExpectError + removeLast( 'abc', {} ); // $ExpectError + removeLast( 'abc', ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + removeLast(); // $ExpectError + removeLast( 'abc' ); // $ExpectError + removeLast( 'abc', 1, 2 ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/examples/index.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/examples/index.js new file mode 100644 index 000000000000..eb2a0ca82cc8 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/examples/index.js @@ -0,0 +1,36 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLastGraphemeCluster = require( './../lib' ); + +console.log( removeLastGraphemeCluster( 'presidential election', 1 ) ); +// => 'presidential electio' + +console.log( removeLastGraphemeCluster( 'JavaScript', 1 ) ); +// => 'JavaScrip' + +console.log( removeLastGraphemeCluster( 'The Last of the Mohicans', 5 ) ); +// => 'The Last of the Moh' + +console.log( removeLastGraphemeCluster( '🐶🐮🐷🐰🐸', 2 ) ); +// => '🐶🐮🐷' + +console.log( removeLastGraphemeCluster( '🐶🐮🐷🐰🐸', 10 ) ); +// => '' diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/index.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/index.js new file mode 100644 index 000000000000..4d1b2cd74142 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/index.js @@ -0,0 +1,46 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +/** +* Remove the last `n` grapheme clusters (i.e., user-perceived characters) of a string. +* +* @module @stdlib/string/base/remove-last-grapheme-cluster +* +* @example +* var removeLast = require( '@stdlib/string/base/remove-last-grapheme-cluster' ); +* +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure'; +* +* out = removeLast( '🐮🐷🐸🐵', 2 ); +* // returns '🐮🐷' +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js new file mode 100644 index 000000000000..29e71ef9cf90 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js @@ -0,0 +1,75 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 prevGraphemeClusterBreak = require( '@stdlib/string/prev-grapheme-cluster-break' ); + + +// MAIN // + +/** +* Removes the last `n` grapheme clusters (i.e., user-perceived characters) of a string. +* +* @param {string} str - input string +* @param {NonNegativeInteger} n - number of grapheme clusters to remove +* @returns {string} output string +* +* @example +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* @example +* var out = removeLast( 'presidential election', 1 ); +* // returns 'presidential electio' +* +* @example +* var out = removeLast( 'JavaScript', 1 ); +* // returns 'JavaScrip' +* +* @example +* var out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure' +* +* @example +* var out = removeLast( '🐶🐮🐷🐰🐸', 2 ); +* // returns '🐶🐮🐷' +* +* @example +* var out = removeLast( 'foo bar', 5 ); +* // returns 'fo' +*/ +function removeLast( str, n ) { + var i = str.length; + while ( n > 0 ) { + i = prevGraphemeClusterBreak( str, i ); + n -= 1; + } + // Value of `i` will be -1 if and only if `str` is an empty string or `str` has only 1 extended grapheme cluster... + if ( str === '' || i === -1 ) { + return ''; + } + return str.substring( 0, i + 1 ); +} + + +// EXPORTS // + +module.exports = removeLast; diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/package.json b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/package.json new file mode 100644 index 000000000000..8d11cb71bff4 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/package.json @@ -0,0 +1,68 @@ +{ + "name": "@stdlib/string/base/remove-last-grapheme-cluster", + "version": "0.0.0", + "description": "Remove the last grapheme cluster (i.e., user-perceived character) of a string.", + "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", + "stdstring", + "utilities", + "utility", + "utils", + "util", + "string", + "str", + "base", + "last", + "character", + "char", + "grapheme", + "cluster", + "unicode" + ] +} diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js new file mode 100644 index 000000000000..42ea0a911e58 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js @@ -0,0 +1,111 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLast = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof removeLast, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an empty string if provided an empty string', function test( t ) { + t.strictEqual( removeLast( '', 1 ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', 2 ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', 3 ), '', 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the input string if provided zero as the second argument', function test( t ) { + t.strictEqual( removeLast( 'hello world', 0 ), 'hello world', 'returns expected value' ); + t.end(); +}); + +tape( 'the function removes the last grapheme cluster of a provided string (ascii)', function test( t ) { + var out; + + out = removeLast( 'hello world', 1 ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( '!!!', 1 ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( 'Hello World', 1 ); + t.strictEqual( out, 'Hello Worl', 'returns expected value' ); + + t.end(); +}); + +tape( 'the function removes the last grapheme cluster of a provided string (Unicode)', function test( t ) { + var out; + + out = removeLast( 'अनुच्छेद', 1 ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 1 ); + t.strictEqual( out, '六书/六', 'returns expected value' ); + + t.end(); +}); + +tape( 'the function removes the last grapheme cluster of a provided string (emoji)', function test( t ) { + var out; + + out = removeLast( '🌷', 1 ); + t.strictEqual( out, '', 'returns expected value' ); + + out = removeLast( '🏝️🌷', 1 ); + t.strictEqual( out, '🏝️', 'returns expected value' ); + + t.end(); +}); + +tape( 'the function supports removing the last `n` grapheme clusters of a provided string', function test( t ) { + var out; + + out = removeLast( 'hello world', 1 ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( 'hello world', 7 ); + t.strictEqual( out, 'hell', 'returns expected value' ); + + out = removeLast( '!!!', 1 ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( '!!!', 2 ); + t.strictEqual( out, '!', 'returns expected value' ); + + out = removeLast( 'अनुच्छेद', 1 ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 1 ); + t.strictEqual( out, '六书/六', 'returns expected value' ); + + out = removeLast( '🌷🌷🌷🌷🌷', 2 ); + t.strictEqual( out, '🌷🌷🌷', 'returns expected value' ); + + t.end(); +}); diff --git a/lib/node_modules/@stdlib/string/base/remove-last/README.md b/lib/node_modules/@stdlib/string/base/remove-last/README.md new file mode 100644 index 000000000000..22fef865238c --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/README.md @@ -0,0 +1,92 @@ + + +# removeLast + +> Remove the last `n` UTF-16 code units of a string. + +
+ +## Usage + +```javascript +var removeLast = require( '@stdlib/string/base/remove-last' ); +``` + +#### removeLast( str, n ) + +Removes the last `n` UTF-16 code units of a string. + +```javascript +var out = removeLast( 'last man standing', 1 ); +// returns 'last man standin' + +out = removeLast( 'Hidden Treasures', 1 ); +// returns 'Hidden Treasure' + +out = removeLast( 'foo bar', 5 ); +// returns 'fo' + +out = removeLast( 'foo bar', 10 ); +// returns '' +``` + +
+ + + +
+ +## Examples + + + +```javascript +var removeLast = require( '@stdlib/string/base/remove-last' ); + +var str = removeLast( 'presidential election', 1 ); +// returns 'presidential electio' + +str = removeLast( 'JavaScript', 1 ); +// returns 'JavaScrip' + +str = removeLast( 'The Last of the Mohicans', 5 ); +// returns 'The Last of the Moh' +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/string/base/remove-last/benchmark/benchmark.js b/lib/node_modules/@stdlib/string/base/remove-last/benchmark/benchmark.js new file mode 100644 index 000000000000..1f34ea036fab --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/benchmark/benchmark.js @@ -0,0 +1,56 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var pkg = require( './../package.json' ).name; +var removeLast = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var values; + var out; + var i; + + values = [ + 'beep boop', + 'foo bar', + 'xyz abc', + '🐶🐮🐷🐰🐸' + ]; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = removeLast( values[ i%values.length ], 1 ); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/string/base/remove-last/docs/repl.txt b/lib/node_modules/@stdlib/string/base/remove-last/docs/repl.txt new file mode 100644 index 000000000000..ef06292c21a6 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/docs/repl.txt @@ -0,0 +1,29 @@ + +{{alias}}( str, n ) + Removes the last `n` UTF-16 code units of a string. + + Parameters + ---------- + str: string + Input string. + + n: integer + Number of UTF-16 code units to remove. + + Returns + ------- + out: string + Output string. + + Examples + -------- + > var out = {{alias}}( 'beep', 1 ) + 'bee' + > out = {{alias}}( 'Boop', 1 ) + 'Boo' + > out = {{alias}}( 'foo bar', 5 ) + 'fo' + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/string/base/remove-last/docs/types/index.d.ts b/lib/node_modules/@stdlib/string/base/remove-last/docs/types/index.d.ts new file mode 100644 index 000000000000..025f444e63a2 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/docs/types/index.d.ts @@ -0,0 +1,53 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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 + +/** +* Removes the last `n` UTF-16 code units of a string. +* +* @param str - input string +* @param n - number of code units to remove +* @returns output string +* +* @example +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* @example +* var out = removeLast( 'presidential election', 1 ); +* // returns 'presidential electio' +* +* @example +* var out = removeLast( 'JavaScript', 1 ); +* // returns 'JavaScrip' +* +* @example +* var out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure' +* +* @example +* var out = removeLast( 'foo bar', 5 ); +* // returns 'fo' +*/ +declare function removeLast( str: string, n: number ): string; + + +// EXPORTS // + +export = removeLast; diff --git a/lib/node_modules/@stdlib/string/base/remove-last/docs/types/test.ts b/lib/node_modules/@stdlib/string/base/remove-last/docs/types/test.ts new file mode 100644 index 000000000000..fd426d2386eb --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/docs/types/test.ts @@ -0,0 +1,57 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLast = require( './index' ); + + +// TESTS // + +// The function returns a string... +{ + removeLast( 'abc', 1 ); // $ExpectType string +} + +// The compiler throws an error if the function is provided a value other than a string... +{ + removeLast( true, 1 ); // $ExpectError + removeLast( false, 1 ); // $ExpectError + removeLast( null, 1 ); // $ExpectError + removeLast( undefined, 1 ); // $ExpectError + removeLast( 5, 1 ); // $ExpectError + removeLast( [], 1 ); // $ExpectError + removeLast( {}, 1 ); // $ExpectError + removeLast( ( x: number ): number => x, 1 ); // $ExpectError +} + +// The compiler throws an error if the function is provided a second argument that is not a number... +{ + removeLast( 'abc', true ); // $ExpectError + removeLast( 'abc', false ); // $ExpectError + removeLast( 'abc', null ); // $ExpectError + removeLast( 'abc', 'abc' ); // $ExpectError + removeLast( 'abc', [] ); // $ExpectError + removeLast( 'abc', {} ); // $ExpectError + removeLast( 'abc', ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + removeLast(); // $ExpectError + removeLast( 'abc' ); // $ExpectError + removeLast( 'abc', 1, 2 ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/string/base/remove-last/examples/index.js b/lib/node_modules/@stdlib/string/base/remove-last/examples/index.js new file mode 100644 index 000000000000..b56142f01c5e --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/examples/index.js @@ -0,0 +1,30 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLast = require( './../lib' ); + +console.log( removeLast( 'presidential election', 1 ) ); +// => 'presidential electio' + +console.log( removeLast( 'JavaScript', 1 ) ); +// => 'JavaScrip' + +console.log( removeLast( 'The Last of the Mohicans', 5 ) ); +// => 'The Last of the Moh' diff --git a/lib/node_modules/@stdlib/string/base/remove-last/lib/index.js b/lib/node_modules/@stdlib/string/base/remove-last/lib/index.js new file mode 100644 index 000000000000..bac319ebdd50 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/lib/index.js @@ -0,0 +1,43 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +/** +* Remove the last `n` UTF-16 code units of a string. +* +* @module @stdlib/string/base/remove-last +* +* @example +* var removeLast = require( '@stdlib/string/base/remove-last' ); +* +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure'; +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/string/base/remove-last/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last/lib/main.js new file mode 100644 index 000000000000..2bf0fb1c1926 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/lib/main.js @@ -0,0 +1,53 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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'; + +// MAIN // + +/** +* Removes the last `n` UTF-16 code units of a string. +* +* @param {string} str - input string +* @param {NonNegativeInteger} n - number of UTF-16 code units to remove +* @returns {string} output string +* +* @example +* var out = removeLast( 'last man standing', 1 ); +* // returns 'last man standin' +* +* @example +* var out = removeLast( 'presidential election', 1 ); +* // returns 'presidential electio' +* +* @example +* var out = removeLast( 'JavaScript', 1 ); +* // returns 'JavaScrip' +* +* @example +* var out = removeLast( 'Hidden Treasures', 1 ); +* // returns 'Hidden Treasure' +*/ +function removeLast( str, n ) { + return str.substring( 0, str.length - n ); +} + + +// EXPORTS // + +module.exports = removeLast; diff --git a/lib/node_modules/@stdlib/string/base/remove-last/package.json b/lib/node_modules/@stdlib/string/base/remove-last/package.json new file mode 100644 index 000000000000..be0d590d3a39 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/string/base/remove-last", + "version": "0.0.0", + "description": "Remove the last UTF-16 code unit of a string.", + "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", + "stdstring", + "utilities", + "utility", + "utils", + "util", + "string", + "str", + "base", + "last", + "character", + "char", + "codeunit", + "unicode" + ] +} diff --git a/lib/node_modules/@stdlib/string/base/remove-last/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last/test/test.js new file mode 100644 index 000000000000..6621b39a55b6 --- /dev/null +++ b/lib/node_modules/@stdlib/string/base/remove-last/test/test.js @@ -0,0 +1,78 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2023 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 removeLast = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof removeLast, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an empty string if provided an empty string', function test( t ) { + t.strictEqual( removeLast( '', 1 ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', 2 ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', 3 ), '', 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the input string if provided zero as the second argument', function test( t ) { + t.strictEqual( removeLast( 'hello world', 0 ), 'hello world', 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns the string without the last UTF-16 code unit', function test( t ) { + var out; + + out = removeLast( 'hello world', 1 ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( '!!!', 1 ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( 'Hello World', 1 ); + t.strictEqual( out, 'Hello Worl', 'returns expected value' ); + + t.end(); +}); + +tape( 'the function supports removing the last `n` UTF-16 code units of a provided string', function test( t ) { + var out; + + out = removeLast( 'hello world', 1 ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( 'hello world', 7 ); + t.strictEqual( out, 'hell', 'returns expected value' ); + + out = removeLast( '!!!', 1 ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( '!!!', 2 ); + t.strictEqual( out, '!', 'returns expected value' ); + + t.end(); +}); diff --git a/lib/node_modules/@stdlib/string/remove-last/README.md b/lib/node_modules/@stdlib/string/remove-last/README.md index f02b29febc9f..92fc4488f263 100644 --- a/lib/node_modules/@stdlib/string/remove-last/README.md +++ b/lib/node_modules/@stdlib/string/remove-last/README.md @@ -30,9 +30,9 @@ limitations under the License. var removeLast = require( '@stdlib/string/remove-last' ); ``` -#### removeLast( str\[, n] ) +#### removeLast( str\[, n]\[, options] ) -Removes the last character of a `string`. +Removes the last character(s) of a `string`. ```javascript var out = removeLast( 'last man standing' ); @@ -42,7 +42,17 @@ out = removeLast( 'Hidden Treasures' ); // returns 'Hidden Treasure' ``` -If provided a second argument, the function removes the last `n` characters. +The function supports the following options: + +- **mode**: type of characters to return. Must be one of the following: + + - `'grapheme'`: grapheme clusters. Appropriate for strings containing visual characters which can span multiple Unicode code points (e.g., emoji). + - `'code_point'`: Unicode code points. Appropriate for strings containing visual characters which are comprised of more than one Unicode code unit (e.g., ideographic symbols and punctuation and mathematical alphanumerics). + - `'code_unit'`: UTF-16 code units. Appropriate for strings containing visual characters drawn from the basic multilingual plane (BMP) (e.g., common characters, such as those from the Latin, Greek, and Cyrillic alphabets). + + Default: `'grapheme'`. + +By default, the function returns the last character. To return the last `n` characters, provide a second argument specifying the number of characters to return. ```javascript var out = removeLast( 'foo bar', 4 ); @@ -56,6 +66,18 @@ out = removeLast( 'foo bar', 0 ); + + +
+ +## Notes + +- By default, the function assumes the general case in which an input string may contain an arbitrary number of grapheme clusters. This assumption comes with a performance cost. Accordingly, if an input string is known to only contain visual characters of a particular type (e.g., only alphanumeric), one can achieve better performance by specifying the appropriate `mode` option. + +
+ + +
## Examples @@ -107,6 +129,7 @@ Options: -V, --version Print the package version. --n Number of characters to remove. Default: 1. --split sep Delimiter for stdin data. Default: '/\\r?\\n/'. + --mode mode Type of character to return. Default: 'grapheme'. ```
diff --git a/lib/node_modules/@stdlib/string/remove-last/benchmark/benchmark.js b/lib/node_modules/@stdlib/string/remove-last/benchmark/benchmark.js index f994eb7b2c2a..5677c9359d3d 100644 --- a/lib/node_modules/@stdlib/string/remove-last/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/string/remove-last/benchmark/benchmark.js @@ -49,3 +49,93 @@ bench( pkg, function benchmark( b ) { b.pass( 'benchmark finished' ); b.end(); }); + +bench( pkg+':mode=grapheme', function benchmark( b ) { + var values; + var opts; + var out; + var i; + + values = [ + 'beep boop', + 'foo bar', + 'xyz abc' + ]; + opts = { + 'mode': 'grapheme' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = removeLast( values[ i%values.length ], opts ); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=code_point', function benchmark( b ) { + var values; + var opts; + var out; + var i; + + values = [ + 'beep boop', + 'foo bar', + 'xyz abc' + ]; + opts = { + 'mode': 'code_point' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = removeLast( values[ i%values.length ], opts ); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( pkg+':mode=code_unit', function benchmark( b ) { + var values; + var opts; + var out; + var i; + + values = [ + 'beep boop', + 'foo bar', + 'xyz abc' + ]; + opts = { + 'mode': 'code_unit' + }; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + out = removeLast( values[ i%values.length ], opts ); + if ( typeof out !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( !isString( out ) ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); diff --git a/lib/node_modules/@stdlib/string/remove-last/bin/cli b/lib/node_modules/@stdlib/string/remove-last/bin/cli index d4cd67052410..453eac622b1e 100644 --- a/lib/node_modules/@stdlib/string/remove-last/bin/cli +++ b/lib/node_modules/@stdlib/string/remove-last/bin/cli @@ -45,6 +45,7 @@ function main() { var split; var flags; var args; + var opts; var cli; var n; @@ -65,6 +66,13 @@ function main() { if ( flags.n ) { n = parseInt( flags.n, 10 ); } + else { + n = 1; + } + opts = {}; + if ( flags.mode ) { + opts.mode = flags.mode; + } // Get any provided command-line arguments: args = cli.args(); @@ -81,10 +89,10 @@ function main() { } return stdin( onRead ); } - if ( n ) { - console.log( removeLast( args[ 0 ], n ) ); // eslint-disable-line no-console - } else { - console.log( removeLast( args[ 0 ] ) ); // eslint-disable-line no-console + try { + console.log( removeLast( args[ 0 ], n, opts ) ); // eslint-disable-line no-console + } catch ( error ) { + return cli.error( error ); } /** @@ -107,13 +115,14 @@ function main() { if ( lines[ lines.length-1 ] === '' ) { lines.pop(); } - if ( n ) { - for ( i = 0; i < lines.length; i++ ) { - console.log( removeLast( lines[ i ], n ) ); // eslint-disable-line no-console + if ( lines.length ) { + try { + console.log( removeLast( lines[ 0 ], n, opts ) ); // eslint-disable-line no-console + } catch ( error ) { + return cli.error( error ); } - } else { - for ( i = 0; i < lines.length; i++ ) { - console.log( removeLast( lines[ i ] ) ); // eslint-disable-line no-console + for ( i = 1; i < lines.length; i++ ) { + console.log( removeLast( lines[ i ], n, opts ) ); // eslint-disable-line no-console } } } diff --git a/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt b/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt index f25ece815965..cacda95baa22 100644 --- a/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt +++ b/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt @@ -1,5 +1,5 @@ -{{alias}}( str[, n] ) +{{alias}}( str[, n][, options] ) Removes the last character(s) of a `string`. Parameters @@ -10,6 +10,25 @@ n: integer (optional) Number of characters to remove. Default: 1. + options: Object (optional) + Options. + + options.mode: string (optional) + Type of characters to return. The following modes are supported: + + - grapheme: grapheme clusters. Appropriate for strings containing visual + characters which can span multiple Unicode code points (e.g., emoji). + - code_point: Unicode code points. Appropriate for strings containing + visual characters which are comprised of more than one Unicode code + unit (e.g., ideographic symbols and punctuation and mathematical + alphanumerics). + - code_unit': UTF-16 code units. Appropriate for strings containing + visual characters drawn from the basic multilingual plane (BMP) (e.g., + common characters, such as those from the Latin, Greek, and Cyrillic + alphabets). + + Default: 'grapheme'. + Returns ------- out: string diff --git a/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts b/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts index 154929b2563a..efa3e05bd0db 100644 --- a/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts @@ -18,6 +18,69 @@ // TypeScript Version: 2.0 +// tslint:disable:unified-signatures + +/** +* Interface describing function options. +*/ +interface Options { + /** + * Specifies the type of characters to return (default: 'grapheme'). + * + * ## Notes + * + * - The following option values are supported: + * + * - `'grapheme'`: grapheme clusters. Appropriate for strings containing visual characters which can span multiple Unicode code points (e.g., emoji). + * - `'code_point'`: Unicode code points. Appropriate for strings containing visual characters which are comprised of more than one Unicode code unit (e.g., ideographic symbols and punctuation and mathematical alphanumerics). + * - `'code_unit'`: UTF-16 code units. Appropriate for strings containing visual characters drawn from the basic multilingual plane (BMP) (e.g., common characters, such as those from the Latin, Greek, and Cyrillic alphabets). + */ + mode?: 'grapheme' | 'code_point' | 'code_unit'; +} + +/** +* Removes the last character(s) of a string. +* +* @param str - input string +* @param n - number of characters to remove (default: 1) +* @param options - options +* @returns updated string +* +* @example +* var out = removeLast( 'last man standing', 1, { +* 'mode': 'code_unit' +* }); +* // returns 'last man standin' +* +* @example +* var out = removeLast( '🐶🐮🐷🐰🐸', 2, { +* 'mode': 'grapheme' +* }); +* // returns '🐶🐮🐷' +*/ +declare function removeLast( str: string, n: number, options?: Options ): string; + +/** +* Removes the last character of a string. +* +* @param str - input string +* @param options - options +* @returns updated string +* +* @example +* var out = removeLast( 'last man standing', { +* 'mode': 'code_unit' +* }); +* // returns 'last man standin' +* +* @example +* var out = removeFirst( '🐶🐮🐷🐰🐸', { +* 'mode': 'grapheme' +* }); +* // returns '🐶🐮🐷🐰' +*/ +declare function removeLast( str: string, options?: Options ): string; + /** * Removes the last character(s) of a string. * diff --git a/lib/node_modules/@stdlib/string/remove-last/docs/types/test.ts b/lib/node_modules/@stdlib/string/remove-last/docs/types/test.ts index c094600da804..486e4f76ae81 100644 --- a/lib/node_modules/@stdlib/string/remove-last/docs/types/test.ts +++ b/lib/node_modules/@stdlib/string/remove-last/docs/types/test.ts @@ -24,6 +24,9 @@ import removeLast = require( './index' ); // The function returns a string... { removeLast( 'abc' ); // $ExpectType string + removeLast( 'abc', 1 ); // $ExpectType string + removeLast( 'abc', {} ); // $ExpectType string + removeLast( 'abc', 1, {} ); // $ExpectType string } // The compiler throws an error if the function is provided a value other than a string... @@ -36,18 +39,69 @@ import removeLast = require( './index' ); removeLast( [] ); // $ExpectError removeLast( {} ); // $ExpectError removeLast( ( x: number ): number => x ); // $ExpectError + + removeLast( true, 1 ); // $ExpectError + removeLast( false, 1 ); // $ExpectError + removeLast( null, 1 ); // $ExpectError + removeLast( undefined, 1 ); // $ExpectError + removeLast( 5, 1 ); // $ExpectError + removeLast( [], 1 ); // $ExpectError + removeLast( {}, 1 ); // $ExpectError + removeLast( ( x: number ): number => x, 1 ); // $ExpectError + + removeLast( true, {} ); // $ExpectError + removeLast( false, {} ); // $ExpectError + removeLast( null, {} ); // $ExpectError + removeLast( undefined, {} ); // $ExpectError + removeLast( 5, {} ); // $ExpectError + removeLast( [], {} ); // $ExpectError + removeLast( {}, {} ); // $ExpectError + removeLast( ( x: number ): number => x, {} ); // $ExpectError + + removeLast( true, 1, {} ); // $ExpectError + removeLast( false, 1, {} ); // $ExpectError + removeLast( null, 1, {} ); // $ExpectError + removeLast( undefined, 1, {} ); // $ExpectError + removeLast( 5, 1, {} ); // $ExpectError + removeLast( [], 1, {} ); // $ExpectError + removeLast( {}, 1, {} ); // $ExpectError + removeLast( ( x: number ): number => x, 1, {} ); // $ExpectError } -// The compiler throws an error if the function is provided a second argument that is not a number... +// The compiler throws an error if the function is provided an invalid second argument... { removeLast( 'abc', true ); // $ExpectError removeLast( 'abc', false ); // $ExpectError removeLast( 'abc', null ); // $ExpectError - removeLast( 'abc', undefined ); // $ExpectError removeLast( 'abc', 'abc' ); // $ExpectError removeLast( 'abc', [] ); // $ExpectError - removeLast( 'abc', {} ); // $ExpectError removeLast( 'abc', ( x: number ): number => x ); // $ExpectError + + removeLast( 'abc', true, {} ); // $ExpectError + removeLast( 'abc', false, {} ); // $ExpectError + removeLast( 'abc', null, {} ); // $ExpectError + removeLast( 'abc', '', {} ); // $ExpectError + removeLast( 'abc', [], {} ); // $ExpectError + removeLast( 'abc', {}, {} ); // $ExpectError + removeLast( 'abc', ( x: number ): number => x, {} ); // $ExpectError +} + +// The compiler throws an error if the function is provided an invalid `mode` option... +{ + removeLast( 'abc', { 'mode': true } ); // $ExpectError + removeLast( 'abc', { 'mode': false } ); // $ExpectError + removeLast( 'abc', { 'mode': null } ); // $ExpectError + removeLast( 'abc', { 'mode': '' } ); // $ExpectError + removeLast( 'abc', { 'mode': [] } ); // $ExpectError + removeLast( 'abc', { 'mode': ( x: number ): number => x } ); // $ExpectError + + removeLast( 'abc', 1, { 'mode': true } ); // $ExpectError + removeLast( 'abc', 1, { 'mode': false } ); // $ExpectError + removeLast( 'abc', 1, { 'mode': null } ); // $ExpectError + removeLast( 'abc', 1, { 'mode': '' } ); // $ExpectError + removeLast( 'abc', 1, { 'mode': [] } ); // $ExpectError + removeLast( 'abc', 1, { 'mode': {} } ); // $ExpectError + removeLast( 'abc', 1, { 'mode': ( x: number ): number => x } ); // $ExpectError } // The compiler throws an error if the function is provided insufficient arguments... diff --git a/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt b/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt index 903c21a3e98d..0f0dc330bbc6 100644 --- a/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt +++ b/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt @@ -7,3 +7,4 @@ Options: -V, --version Print the package version. --n Number of characters to remove. Default: 1. --split sep Delimiter for stdin data. Default: '/\\r?\\n/'. + --mode mode Type of character to return. Default: 'grapheme'. diff --git a/lib/node_modules/@stdlib/string/remove-last/etc/cli_opts.json b/lib/node_modules/@stdlib/string/remove-last/etc/cli_opts.json index 5d6ecc981c2a..2ceae4582b33 100644 --- a/lib/node_modules/@stdlib/string/remove-last/etc/cli_opts.json +++ b/lib/node_modules/@stdlib/string/remove-last/etc/cli_opts.json @@ -5,7 +5,8 @@ ], "string": [ "n", - "split" + "split", + "mode" ], "alias": { "help": [ diff --git a/lib/node_modules/@stdlib/string/remove-last/lib/main.js b/lib/node_modules/@stdlib/string/remove-last/lib/main.js index 98f49b3dccfd..6ec34b7698f0 100644 --- a/lib/node_modules/@stdlib/string/remove-last/lib/main.js +++ b/lib/node_modules/@stdlib/string/remove-last/lib/main.js @@ -21,11 +21,27 @@ // MODULES // var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var isPlainObject = require( '@stdlib/assert/is-plain-object' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var contains = require( '@stdlib/array/base/assert/contains' ).factory; var isNonNegativeInteger = require( '@stdlib/assert/is-nonnegative-integer' ).isPrimitive; -var prevGraphemeClusterBreak = require( '@stdlib/string/prev-grapheme-cluster-break' ); +var removeLastCodeUnit = require( '@stdlib/string/base/remove-last' ); +var removeLastCodePoint = require( '@stdlib/string/base/remove-last-code-point' ); +var removeLastGraphemeCluster = require( '@stdlib/string/base/remove-last-grapheme-cluster' ); var format = require( '@stdlib/string/format' ); +// VARIABLES // + +var MODES = [ 'grapheme', 'code_point', 'code_unit' ]; +var FCNS = { + 'grapheme': removeLastGraphemeCluster, + 'code_point': removeLastCodePoint, + 'code_unit': removeLastCodeUnit +}; +var isMode = contains( MODES ); + + // MAIN // /** @@ -33,8 +49,11 @@ var format = require( '@stdlib/string/format' ); * * @param {string} str - input string * @param {NonNegativeInteger} [n=1] - number of character to remove +* @param {Options} [options] - options * @throws {TypeError} must provide a string primitive * @throws {TypeError} second argument must be a nonnegative integer +* @throws {TypeError} options argument must be an object +* @throws {TypeError} must provide valid options * @returns {string} updated string * * @example @@ -57,30 +76,48 @@ var format = require( '@stdlib/string/format' ); * var out = removeLast( 'leader', 2 ); * // returns 'lead' */ -function removeLast( str, n ) { - var i; +function removeLast( str ) { + var options; + var nargs; + var opts; + var n; if ( !isString( str ) ) { throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', str ) ); } - if ( str === '' ) { - return ''; - } - if ( arguments.length > 1 ) { + opts = { + 'mode': 'grapheme' + }; + nargs = arguments.length; + if ( nargs === 1 ) { + n = 1; + } else if ( nargs === 2 ) { + n = arguments[ 1 ]; + if ( isPlainObject( n ) ) { + options = n; + n = 1; + } else if ( !isNonNegativeInteger( n ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be a nonnegative integer. Value: `%s`.', n ) ); + } + } else { // nargs > 2 + n = arguments[ 1 ]; if ( !isNonNegativeInteger( n ) ) { throw new TypeError( format( 'invalid argument. Second argument must be a nonnegative integer. Value: `%s`.', n ) ); } - if ( n === 0 ) { - return str; + options = arguments[ 2 ]; + if ( !isPlainObject( options ) ) { + throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) ); } - i = str.length - 1; - while ( n > 0 ) { - i = prevGraphemeClusterBreak( str, i ); - n -= 1; + } + if ( options ) { + if ( hasOwnProp( options, 'mode' ) ) { + opts.mode = options.mode; + if ( !isMode( opts.mode ) ) { + throw new TypeError( format( 'invalid option. `%s` option must be one of the following: "%s". Value: `%s`.', 'mode', MODES.join( '", "' ), opts.mode ) ); + } } - return str.substring( 0, i + 1 ); } - return str.substring( 0, prevGraphemeClusterBreak( str, str.length-1 ) + 1 ); // eslint-disable-line max-len + return FCNS[ opts.mode ]( str, n ); } diff --git a/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js b/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js index 3ed861886210..e5596f4901d9 100644 --- a/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js +++ b/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js @@ -182,6 +182,46 @@ tape( 'the command-line interface removes the last `n` characters of a string ar } }); +tape( 'the command-line interface supports specifying the type of characters to return', opts, function test( t ) { + var cmd = [ + EXEC_PATH, + '-e', + '"process.stdin.isTTY = true; process.argv[ 2 ] = \'beep\'; process.argv[ 3 ] = \'--mode=code_point\'; require( \''+fpath+'\' );"' + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + if ( error ) { + t.fail( error.message ); + } else { + t.strictEqual( stdout.toString(), 'bee\n', 'expected value' ); + t.strictEqual( stderr.toString(), '', 'does not print to `stderr`' ); + } + t.end(); + } +}); + +tape( 'if provided an invalid option, the command-line interface prints an error and sets a non-zero exit code', opts, function test( t ) { + var cmd = [ + EXEC_PATH, + '-e', + '"process.stdin.isTTY = true; process.argv[ 2 ] = \'beep\'; process.argv[ 3 ] = \'--mode=foo\'; require( \''+fpath+'\' );"' + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + if ( error ) { + t.pass( error.message ); + t.strictEqual( error.code, 1, 'expected exit code' ); + } + t.strictEqual( stdout.toString(), '', 'does not print to `stdout`' ); + t.strictEqual( stderr.toString().length > 0, true, 'expected value' ); + t.end(); + } +}); + tape( 'the command-line interface supports use as a standard stream', opts, function test( t ) { var cmd = [ 'printf "beep\nboop"', @@ -247,6 +287,28 @@ tape( 'the command-line interface supports specifying a custom delimiter when us } }); +tape( 'the command-line interface supports specifying the type of characters to return when used as a standard stream', opts, function test( t ) { + var cmd = [ + 'printf \'foo\nbar\nbaz\'', + '|', + EXEC_PATH, + fpath, + '--mode code_point' + ]; + + exec( cmd.join( ' ' ), done ); + + function done( error, stdout, stderr ) { + if ( error ) { + t.fail( error.message ); + } else { + t.strictEqual( stdout.toString(), 'fo\nba\nba\n', 'expected value' ); + t.strictEqual( stderr.toString(), '', 'does not print to `stderr`' ); + } + t.end(); + } +}); + tape( 'the command-line interface supports specifying a custom delimiter when used as a standard stream (regexp)', opts, function test( t ) { var cmd = [ 'printf \'foo\tbar\tbaz\'', diff --git a/lib/node_modules/@stdlib/string/remove-last/test/test.js b/lib/node_modules/@stdlib/string/remove-last/test/test.js index c6c79eb9550a..0a52959e51e3 100644 --- a/lib/node_modules/@stdlib/string/remove-last/test/test.js +++ b/lib/node_modules/@stdlib/string/remove-last/test/test.js @@ -59,6 +59,33 @@ tape( 'the function throws an error if not provided a string', function test( t } }); +tape( 'the function throws an error if not provided a string (options)', function test( t ) { + var values; + var i; + + values = [ + 5, + null, + true, + void 0, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + removeLast( value, {} ); + }; + } +}); + tape( 'the function throws an error if provided a second argument which is not a nonnegative integer', function test( t ) { var values; var i; @@ -71,7 +98,6 @@ tape( 'the function throws an error if provided a second argument which is not a void 0, NaN, [], - {}, function noop() {} ]; @@ -87,8 +113,124 @@ tape( 'the function throws an error if provided a second argument which is not a } }); +tape( 'the function throws an error if provided a second argument which is not a nonnegative integer (options)', function test( t ) { + var values; + var i; + + values = [ + 'abc', + 3.14, + null, + true, + void 0, + NaN, + [], + {}, + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + removeLast( 'beep', value, {} ); + }; + } +}); + +tape( 'the function throws an error if provided an options argument which is not an object', function test( t ) { + var values; + var i; + + values = [ + 'abc', + 3, + null, + true, + void 0, + NaN, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + removeLast( 'beep', 1, value ); + }; + } +}); + +tape( 'the function throws an error if provided a `mode` option which is not a supported mode (second argument)', function test( t ) { + var values; + var i; + + values = [ + 'abc', + 3, + null, + true, + void 0, + NaN, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + removeLast( 'beep', { + 'mode': value + }); + }; + } +}); + +tape( 'the function throws an error if provided a `mode` option which is not a supported mode (third argument)', function test( t ) { + var values; + var i; + + values = [ + 'abc', + 3, + null, + true, + void 0, + NaN, + [], + function noop() {} + ]; + + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + removeLast( 'beep', 1, { + 'mode': value + }); + }; + } +}); + tape( 'the function returns an empty string if provided an empty string', function test( t ) { t.strictEqual( removeLast( '' ), '', 'returns empty string' ); + t.strictEqual( removeLast( '', 1 ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', {} ), '', 'returns expected value' ); + t.strictEqual( removeLast( '', 1, {} ), '', 'returns expected value' ); t.end(); }); @@ -104,18 +246,6 @@ tape( 'the function removes the last character of a given string', function test out = removeLast( 'Hello World' ); t.strictEqual( out, 'Hello Worl', 'removes character' ); - t.end(); -}); - -tape( 'the function removes the last character of a given string (Unicode characters)', function test( t ) { - var out; - - out = removeLast( '😀😀😀' ); - t.strictEqual( out, '😀😀', 'removes character' ); - - out = removeLast( '🤖 Robot Army 🤖' ); - t.strictEqual( out, '🤖 Robot Army ', 'removes character' ); - out = removeLast( 'अनुच्छेद' ); t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); @@ -128,20 +258,26 @@ tape( 'the function removes the last character of a given string (Unicode charac t.end(); }); -tape( 'the function returns the original string if provided zero for the second parameter', function test( t ) { +tape( 'the function returns the original string if provided zero as the second argument', function test( t ) { var out; out = removeLast( 'hello world', 0 ); t.strictEqual( out, 'hello world', 'returns original string' ); + out = removeLast( 'hello world', 0, {} ); + t.strictEqual( out, 'hello world', 'returns expected value' ); + t.end(); }); -tape( 'the function removes the last `n` characters when supplied a second argument', function test( t ) { +tape( 'the function removes the last `n` characters of a given string (default)', function test( t ) { var out; - out = removeLast( 'hello world', 5 ); - t.strictEqual( out, 'hello ', 'removes characters' ); + out = removeLast( 'hello world', 1 ); + t.strictEqual( out, 'hello worl', 'removes last character' ); + + out = removeLast( 'hello world', 6 ); + t.strictEqual( out, 'hello', 'returns expected value' ); out = removeLast( '!!!', 1 ); t.strictEqual( out, '!!', 'removes character' ); @@ -149,35 +285,123 @@ tape( 'the function removes the last `n` characters when supplied a second argum out = removeLast( '!!!', 2 ); t.strictEqual( out, '!', 'removes character' ); + out = removeLast( 'अनुच्छेद', 1 ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 1 ); + t.strictEqual( out, '六书/六', 'returns expected value' ); + + out = removeLast( '🌷', 1 ); + t.strictEqual( out, '', 'returns expected value' ); + t.end(); }); -tape( 'the function returns an empty string if `n` is greater than or equal to the length of the string', function test( t ) { +tape( 'the function supports removing the last `n` characters of a provided string (mode=grapheme)', function test( t ) { + var opts; var out; - out = removeLast( 'hello world', 12 ); - t.strictEqual( out, '', 'returns empty string' ); + opts = { + 'mode': 'grapheme' + }; - out = removeLast( '!!!', 3 ); - t.strictEqual( out, '', 'returns empty string' ); + out = removeLast( 'hello world', 1, opts ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( 'hello world', 7, opts ); + t.strictEqual( out, 'hell', 'returns expected value' ); + + out = removeLast( '!!!', 1, opts ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( '!!!', 2, opts ); + t.strictEqual( out, '!', 'returns expected value' ); + + out = removeLast( 'अनुच्छेद', 1, opts ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 1, opts ); + t.strictEqual( out, '六书/六', 'returns expected value' ); + + out = removeLast( '🌷', 1, opts ); + t.strictEqual( out, '', 'returns expected value' ); + + out = removeLast( '👉🏿', 1, opts ); + t.strictEqual( out, '👉', 'returns expected value' ); t.end(); }); -tape( 'the function removes the last `n` characters when supplied a second argument (Unicode characters)', function test( t ) { +tape( 'the function supports removing the last `n` characters of a provided string (mode=code_point)', function test( t ) { + var opts; var out; - out = removeLast( '😀😀😀', 1 ); - t.strictEqual( out, '😀😀', 'removes character' ); + opts = { + 'mode': 'code_point' + }; - out = removeLast( '🤖 Robot Army 🤖', 2 ); - t.strictEqual( out, '🤖 Robot Army', 'removes character' ); + out = removeLast( 'hello world', 1, opts ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); - out = removeLast( '六书/六書', 1 ); + out = removeLast( 'hello world', 7, opts ); + t.strictEqual( out, 'hell', 'returns expected value' ); + + out = removeLast( '!!!', 1, opts ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( '!!!', 2, opts ); + t.strictEqual( out, '!', 'returns expected value' ); + + out = removeLast( 'अनुच्छेद', 1, opts ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 1, opts ); t.strictEqual( out, '六书/六', 'returns expected value' ); - out = removeLast( '🌷', 1 ); - t.strictEqual( out, '', 'returns expected value' ); + out = removeLast( '🌷', 1, opts ); + t.strictEqual( out, '\ud83c', 'returns expected value' ); + t.end(); +}); + +tape( 'the function supports removing the last `n` characters of a provided string (mode=code_unit)', function test( t ) { + var opts; + var out; + + opts = { + 'mode': 'code_unit' + }; + + out = removeLast( 'hello world', 1, opts ); + t.strictEqual( out, 'hello worl', 'returns expected value' ); + + out = removeLast( 'hello world', 7, opts ); + t.strictEqual( out, 'hell', 'returns expected value' ); + + out = removeLast( '!!!', 1, opts ); + t.strictEqual( out, '!!', 'returns expected value' ); + + out = removeLast( '!!!', 2, opts ); + t.strictEqual( out, '!', 'returns expected value' ); + + out = removeLast( 'अनुच्छेद', 1, opts ); + t.strictEqual( out, 'अनुच्छे', 'returns expected value' ); + + out = removeLast( '六书/六書', 1, opts ); + t.strictEqual( out, '六书/六', 'returns expected value' ); + + out = removeLast( '🌷', 1, opts ); + t.strictEqual( out, '\ud83c', 'returns expected value' ); + t.end(); +}); + +tape( 'the function returns an empty string if `n` is greater than or equal to the length of the string', function test( t ) { + var out; + + out = removeLast( 'hello world', 12 ); + t.strictEqual( out, '', 'returns empty string' ); + + out = removeLast( '!!!', 3 ); + t.strictEqual( out, '', 'returns empty string' ); t.end(); }); From b9b95be52aa7d13aa7b3cf5bd4b92b52b3faa63a Mon Sep 17 00:00:00 2001 From: Athan Date: Tue, 22 Aug 2023 16:14:15 -0700 Subject: [PATCH 02/14] Apply suggestions from code review --- .../@stdlib/string/base/remove-last/test/test.js | 2 +- lib/node_modules/@stdlib/string/remove-last/README.md | 6 +++--- lib/node_modules/@stdlib/string/remove-last/bin/cli | 3 +-- lib/node_modules/@stdlib/string/remove-last/docs/repl.txt | 2 +- .../@stdlib/string/remove-last/docs/types/index.d.ts | 2 +- lib/node_modules/@stdlib/string/remove-last/docs/usage.txt | 2 +- .../@stdlib/string/remove-last/test/test.cli.js | 4 ++-- 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-last/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last/test/test.js index 6621b39a55b6..db663cef7b17 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-last/test/test.js @@ -44,7 +44,7 @@ tape( 'the function returns the input string if provided zero as the second argu t.end(); }); -tape( 'the function returns the string without the last UTF-16 code unit', function test( t ) { +tape( 'the function returns the input string without the last UTF-16 code unit', function test( t ) { var out; out = removeLast( 'hello world', 1 ); diff --git a/lib/node_modules/@stdlib/string/remove-last/README.md b/lib/node_modules/@stdlib/string/remove-last/README.md index 92fc4488f263..7f3733ea5176 100644 --- a/lib/node_modules/@stdlib/string/remove-last/README.md +++ b/lib/node_modules/@stdlib/string/remove-last/README.md @@ -32,7 +32,7 @@ var removeLast = require( '@stdlib/string/remove-last' ); #### removeLast( str\[, n]\[, options] ) -Removes the last character(s) of a `string`. +Removes the last character(s) of an input string. ```javascript var out = removeLast( 'last man standing' ); @@ -44,7 +44,7 @@ out = removeLast( 'Hidden Treasures' ); The function supports the following options: -- **mode**: type of characters to return. Must be one of the following: +- **mode**: type of characters to remove. Must be one of the following: - `'grapheme'`: grapheme clusters. Appropriate for strings containing visual characters which can span multiple Unicode code points (e.g., emoji). - `'code_point'`: Unicode code points. Appropriate for strings containing visual characters which are comprised of more than one Unicode code unit (e.g., ideographic symbols and punctuation and mathematical alphanumerics). @@ -129,7 +129,7 @@ Options: -V, --version Print the package version. --n Number of characters to remove. Default: 1. --split sep Delimiter for stdin data. Default: '/\\r?\\n/'. - --mode mode Type of character to return. Default: 'grapheme'. + --mode mode Type of character to remove. Default: 'grapheme'. ``` diff --git a/lib/node_modules/@stdlib/string/remove-last/bin/cli b/lib/node_modules/@stdlib/string/remove-last/bin/cli index 453eac622b1e..d76e824f7c68 100644 --- a/lib/node_modules/@stdlib/string/remove-last/bin/cli +++ b/lib/node_modules/@stdlib/string/remove-last/bin/cli @@ -65,8 +65,7 @@ function main() { } if ( flags.n ) { n = parseInt( flags.n, 10 ); - } - else { + } else { n = 1; } opts = {}; diff --git a/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt b/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt index cacda95baa22..2b5002663b86 100644 --- a/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt +++ b/lib/node_modules/@stdlib/string/remove-last/docs/repl.txt @@ -14,7 +14,7 @@ Options. options.mode: string (optional) - Type of characters to return. The following modes are supported: + Type of characters to remove. The following modes are supported: - grapheme: grapheme clusters. Appropriate for strings containing visual characters which can span multiple Unicode code points (e.g., emoji). diff --git a/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts b/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts index efa3e05bd0db..2d37a6344d7c 100644 --- a/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/string/remove-last/docs/types/index.d.ts @@ -25,7 +25,7 @@ */ interface Options { /** - * Specifies the type of characters to return (default: 'grapheme'). + * Specifies the type of characters to remove (default: 'grapheme'). * * ## Notes * diff --git a/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt b/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt index 0f0dc330bbc6..bc7c94018b00 100644 --- a/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt +++ b/lib/node_modules/@stdlib/string/remove-last/docs/usage.txt @@ -7,4 +7,4 @@ Options: -V, --version Print the package version. --n Number of characters to remove. Default: 1. --split sep Delimiter for stdin data. Default: '/\\r?\\n/'. - --mode mode Type of character to return. Default: 'grapheme'. + --mode mode Type of character to remove. Default: 'grapheme'. diff --git a/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js b/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js index e5596f4901d9..bc7219b9a973 100644 --- a/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js +++ b/lib/node_modules/@stdlib/string/remove-last/test/test.cli.js @@ -182,7 +182,7 @@ tape( 'the command-line interface removes the last `n` characters of a string ar } }); -tape( 'the command-line interface supports specifying the type of characters to return', opts, function test( t ) { +tape( 'the command-line interface supports specifying the type of characters to remove', opts, function test( t ) { var cmd = [ EXEC_PATH, '-e', @@ -287,7 +287,7 @@ tape( 'the command-line interface supports specifying a custom delimiter when us } }); -tape( 'the command-line interface supports specifying the type of characters to return when used as a standard stream', opts, function test( t ) { +tape( 'the command-line interface supports specifying the type of characters to remove when used as a standard stream', opts, function test( t ) { var cmd = [ 'printf \'foo\nbar\nbaz\'', '|', From 6ed8e6d6509d16f31d272b77b51d5a2d11ba90bb Mon Sep 17 00:00:00 2001 From: Athan Date: Tue, 22 Aug 2023 16:15:25 -0700 Subject: [PATCH 03/14] test: update test description --- lib/node_modules/@stdlib/string/base/remove-last/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-last/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last/test/test.js index db663cef7b17..9bb746102c31 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-last/test/test.js @@ -44,7 +44,7 @@ tape( 'the function returns the input string if provided zero as the second argu t.end(); }); -tape( 'the function returns the input string without the last UTF-16 code unit', function test( t ) { +tape( 'the function removes the last UTF-16 code unit from a provided string', function test( t ) { var out; out = removeLast( 'hello world', 1 ); From 120d9fb18646b0ba39cb0fa3e9acc734b0332140 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:10:50 -0500 Subject: [PATCH 04/14] fix: fix bug in code point and grapheme cluster implementations --- .../base/remove-first-code-point/test/test.js | 6 +++++ .../base/remove-last-code-point/lib/main.js | 10 ++++----- .../base/remove-last-code-point/test/test.js | 6 +++++ .../remove-last-grapheme-cluster/lib/main.js | 22 ++++++++++++------- .../remove-last-grapheme-cluster/test/test.js | 3 +++ .../@stdlib/string/remove-last/lib/main.js | 2 +- .../@stdlib/string/remove-last/test/test.js | 2 +- 7 files changed, 36 insertions(+), 15 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js index 66a0cb9bc0a3..ff7b1d1bce0b 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js @@ -68,6 +68,9 @@ tape( 'the function removes the first Unicode code point of a provided string (U out = removeFirst( '六书/六書', 1 ); t.strictEqual( out, '书/六書', 'returns expected value' ); + out = removeLast( '𐒻𐓟', 1 ); + t.strictEqual( out, '𐓟', 'returns expected value' ); + t.end(); }); @@ -92,5 +95,8 @@ tape( 'the function supports removing the first `n` Unicode code points of a pro out = removeFirst( '六书/六書', 3 ); t.strictEqual( out, '六書', 'returns expected value' ); + out = removeLast( '𐒻𐓟𐓟', 2 ); + t.strictEqual( out, '𐓟', 'returns expected value' ); + t.end(); }); diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js index eb7518aa07bf..fc341870df31 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/lib/main.js @@ -66,16 +66,16 @@ function removeLast( str, n ) { ch1 = str[ i ]; cnt += 1; - // Check for a high UTF-16 surrogate... - if ( RE_UTF16_HIGH_SURROGATE.test( ch1 ) ) { + // Check for a low UTF-16 surrogate... + if ( RE_UTF16_LOW_SURROGATE.test( ch1 ) ) { // Check for an unpaired surrogate at the end of the input string... - if ( i === len-1 ) { + if ( i === 0 ) { // We found an unpaired surrogate... break; } // Check whether the high surrogate is paired with a low surrogate... ch2 = str[ i-1 ]; - if ( RE_UTF16_LOW_SURROGATE.test( ch2 ) ) { + if ( RE_UTF16_HIGH_SURROGATE.test( ch2 ) ) { // We found a surrogate pair: i -= 1; // bump the index to process the next code unit } @@ -85,7 +85,7 @@ function removeLast( str, n ) { break; } } - return str.substring( 0, str.length - cnt ); + return str.substring( 0, i ); } diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js index 9306b4396275..d9256cd8e100 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js @@ -68,6 +68,9 @@ tape( 'the function removes the last Unicode code point of a provided string (Un out = removeLast( '六书/六書', 1 ); t.strictEqual( out, '六书/六', 'returns expected value' ); + out = removeLast( '𐒻𐓟', 1 ); + t.strictEqual( out, '𐒻', 'returns expected value' ); + t.end(); }); @@ -92,5 +95,8 @@ tape( 'the function supports removing the last `n` Unicode code points of a prov out = removeLast( '六书/六書', 3 ); t.strictEqual( out, '六书', 'returns expected value' ); + out = removeLast( '𐒻𐓟𐓟', 2 ); + t.strictEqual( out, '𐒻', 'returns expected value' ); + t.end(); }); diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js index 29e71ef9cf90..62326855b16d 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js @@ -20,7 +20,7 @@ // MODULES // -var prevGraphemeClusterBreak = require( '@stdlib/string/prev-grapheme-cluster-break' ); +const nextGraphemeClusterBreak = require('@stdlib/string/next-grapheme-cluster-break'); // MAIN // @@ -57,16 +57,22 @@ var prevGraphemeClusterBreak = require( '@stdlib/string/prev-grapheme-cluster-br * // returns 'fo' */ function removeLast( str, n ) { - var i = str.length; - while ( n > 0 ) { - i = prevGraphemeClusterBreak( str, i ); - n -= 1; + var idx; + var i; + + idx = []; + i = 0; + while ( i < str.length ) { + i = nextGraphemeClusterBreak( str, i ); + if ( i === -1 ) { + break; + } + idx.push(i); } - // Value of `i` will be -1 if and only if `str` is an empty string or `str` has only 1 extended grapheme cluster... - if ( str === '' || i === -1 ) { + if ( str === '' || idx.length < n ) { return ''; } - return str.substring( 0, i + 1 ); + return str.substring( 0, idx[ idx.length - n ] ); } diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js index 42ea0a911e58..9224525c3cb7 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/test/test.js @@ -80,6 +80,9 @@ tape( 'the function removes the last grapheme cluster of a provided string (emoj out = removeLast( '🏝️🌷', 1 ); t.strictEqual( out, '🏝️', 'returns expected value' ); + out = removeLast( '👉🏿', 1 ); + t.strictEqual( out, '', 'returns expected value' ); + t.end(); }); diff --git a/lib/node_modules/@stdlib/string/remove-last/lib/main.js b/lib/node_modules/@stdlib/string/remove-last/lib/main.js index 6ec34b7698f0..14fae9593c4f 100644 --- a/lib/node_modules/@stdlib/string/remove-last/lib/main.js +++ b/lib/node_modules/@stdlib/string/remove-last/lib/main.js @@ -49,7 +49,7 @@ var isMode = contains( MODES ); * * @param {string} str - input string * @param {NonNegativeInteger} [n=1] - number of character to remove -* @param {Options} [options] - options +* @param {string} [options.mode="grapheme"] - type of "character" to return (must be either `grapheme`, `code_point`, or `code_unit`) * @throws {TypeError} must provide a string primitive * @throws {TypeError} second argument must be a nonnegative integer * @throws {TypeError} options argument must be an object diff --git a/lib/node_modules/@stdlib/string/remove-last/test/test.js b/lib/node_modules/@stdlib/string/remove-last/test/test.js index 0a52959e51e3..ef60b65ec58a 100644 --- a/lib/node_modules/@stdlib/string/remove-last/test/test.js +++ b/lib/node_modules/@stdlib/string/remove-last/test/test.js @@ -327,7 +327,7 @@ tape( 'the function supports removing the last `n` characters of a provided stri t.strictEqual( out, '', 'returns expected value' ); out = removeLast( '👉🏿', 1, opts ); - t.strictEqual( out, '👉', 'returns expected value' ); + t.strictEqual( out, '', 'returns expected value' ); t.end(); }); From 08bd1803613e7b1587e8731d5855aacded9c0740 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:12:03 -0500 Subject: [PATCH 05/14] fix: fix typo --- .../@stdlib/string/base/remove-first-code-point/test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js index ff7b1d1bce0b..a78b5e759dd0 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js @@ -68,7 +68,7 @@ tape( 'the function removes the first Unicode code point of a provided string (U out = removeFirst( '六书/六書', 1 ); t.strictEqual( out, '书/六書', 'returns expected value' ); - out = removeLast( '𐒻𐓟', 1 ); + out = removeFirst( '𐒻𐓟', 1 ); t.strictEqual( out, '𐓟', 'returns expected value' ); t.end(); @@ -95,7 +95,7 @@ tape( 'the function supports removing the first `n` Unicode code points of a pro out = removeFirst( '六书/六書', 3 ); t.strictEqual( out, '六書', 'returns expected value' ); - out = removeLast( '𐒻𐓟𐓟', 2 ); + out = removeFirst( '𐒻𐓟𐓟', 2 ); t.strictEqual( out, '𐓟', 'returns expected value' ); t.end(); From 6d959b939156f6b75de079a45f6e6e5787ec3c61 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:15:35 -0500 Subject: [PATCH 06/14] fix: fix tests --- .../string/base/remove-first-code-point/test/test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js index a78b5e759dd0..08312cf5563f 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js @@ -68,8 +68,8 @@ tape( 'the function removes the first Unicode code point of a provided string (U out = removeFirst( '六书/六書', 1 ); t.strictEqual( out, '书/六書', 'returns expected value' ); - out = removeFirst( '𐒻𐓟', 1 ); - t.strictEqual( out, '𐓟', 'returns expected value' ); + out = removeFirst( '𐓟𐒻', 1 ); + t.strictEqual( out, '𐒻', 'returns expected value' ); t.end(); }); @@ -95,8 +95,8 @@ tape( 'the function supports removing the first `n` Unicode code points of a pro out = removeFirst( '六书/六書', 3 ); t.strictEqual( out, '六書', 'returns expected value' ); - out = removeFirst( '𐒻𐓟𐓟', 2 ); - t.strictEqual( out, '𐓟', 'returns expected value' ); + out = removeFirst( '𐓟𐓟𐒻', 2 ); + t.strictEqual( out, '𐒻', 'returns expected value' ); t.end(); }); From be44b0786ef32c0f7780f141a096c2029f5a6205 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:24:14 -0500 Subject: [PATCH 07/14] fix: fix bug in remove first code point implementation --- .../string/base/remove-first-code-point/lib/main.js | 2 +- .../string/base/remove-first-code-point/test/test.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-first-code-point/lib/main.js index 175f9f540e5c..cdf29f94ca91 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/lib/main.js +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/lib/main.js @@ -85,7 +85,7 @@ function removeFirst( str, n ) { break; } } - return str.substring( cnt, str.length ); + return str.substring( i + 1, str.length ); } diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js index 08312cf5563f..2bbe04db0023 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js @@ -68,8 +68,8 @@ tape( 'the function removes the first Unicode code point of a provided string (U out = removeFirst( '六书/六書', 1 ); t.strictEqual( out, '书/六書', 'returns expected value' ); - out = removeFirst( '𐓟𐒻', 1 ); - t.strictEqual( out, '𐒻', 'returns expected value' ); + out = removeFirst( '𐒻𐓟', 1 ); + t.strictEqual( out, '𐓟', 'returns expected value' ); t.end(); }); @@ -95,8 +95,8 @@ tape( 'the function supports removing the first `n` Unicode code points of a pro out = removeFirst( '六书/六書', 3 ); t.strictEqual( out, '六書', 'returns expected value' ); - out = removeFirst( '𐓟𐓟𐒻', 2 ); - t.strictEqual( out, '𐒻', 'returns expected value' ); + out = removeFirst( '𐓟𐒻𐓟', 2 ); + t.strictEqual( out, '𐓟', 'returns expected value' ); t.end(); }); From 62980a085e2eb1a69eb0e8b91f0a7cd078918784 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:26:09 -0500 Subject: [PATCH 08/14] fix: fix failing test --- lib/node_modules/@stdlib/string/remove-last/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/string/remove-last/test/test.js b/lib/node_modules/@stdlib/string/remove-last/test/test.js index ef60b65ec58a..b036830dce78 100644 --- a/lib/node_modules/@stdlib/string/remove-last/test/test.js +++ b/lib/node_modules/@stdlib/string/remove-last/test/test.js @@ -359,7 +359,7 @@ tape( 'the function supports removing the last `n` characters of a provided stri t.strictEqual( out, '六书/六', 'returns expected value' ); out = removeLast( '🌷', 1, opts ); - t.strictEqual( out, '\ud83c', 'returns expected value' ); + t.strictEqual( out, '', 'returns expected value' ); t.end(); }); From 3b86ec3096cce204a21267d1e11144dc02a0ac48 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:33:51 -0500 Subject: [PATCH 09/14] fix: fix failing tests and linting --- .../string/base/remove-last-grapheme-cluster/lib/main.js | 2 +- lib/node_modules/@stdlib/string/remove-first/test/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js index 62326855b16d..9fdcee02f377 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js @@ -20,7 +20,7 @@ // MODULES // -const nextGraphemeClusterBreak = require('@stdlib/string/next-grapheme-cluster-break'); +var nextGraphemeClusterBreak = require('@stdlib/string/next-grapheme-cluster-break'); // MAIN // diff --git a/lib/node_modules/@stdlib/string/remove-first/test/test.js b/lib/node_modules/@stdlib/string/remove-first/test/test.js index 1bc69e1fb0a2..ebed95cf0243 100644 --- a/lib/node_modules/@stdlib/string/remove-first/test/test.js +++ b/lib/node_modules/@stdlib/string/remove-first/test/test.js @@ -359,7 +359,7 @@ tape( 'the function supports removing the first `n` characters of a provided str t.strictEqual( out, '书/六書', 'returns expected value' ); out = removeFirst( '🌷', 1, opts ); - t.strictEqual( out, '\udf37', 'returns expected value' ); + t.strictEqual( out, '', 'returns expected value' ); t.end(); }); From 7b41d50187dd727a5c8a786675394c06bb0cdabf Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:43:21 -0500 Subject: [PATCH 10/14] fix: add more tests for full coverage --- .../string/base/remove-first-code-point/test/test.js | 3 +++ .../@stdlib/string/base/remove-last-code-point/test/test.js | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js index 2bbe04db0023..bba3b52897e1 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js @@ -71,6 +71,9 @@ tape( 'the function removes the first Unicode code point of a provided string (U out = removeFirst( '𐒻𐓟', 1 ); t.strictEqual( out, '𐓟', 'returns expected value' ); + out = removeFirst( '\uDC00', 1 ); + t.strictEqual( out, '', 'returns expected value' ); + t.end(); }); diff --git a/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js index d9256cd8e100..a25545e30946 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-code-point/test/test.js @@ -71,6 +71,12 @@ tape( 'the function removes the last Unicode code point of a provided string (Un out = removeLast( '𐒻𐓟', 1 ); t.strictEqual( out, '𐒻', 'returns expected value' ); + out = removeLast( '𐒻𐓟', 1 ); + t.strictEqual( out, '𐒻', 'returns expected value' ); + + out = removeLast( '\uDC00', 1 ); + t.strictEqual( out, '', 'returns expected value' ); + t.end(); }); From 228b921b019d54232e1a80e22092650f192961f0 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Sat, 26 Aug 2023 00:52:13 -0500 Subject: [PATCH 11/14] fix: add more tests for remove first package coverage --- .../@stdlib/string/base/remove-first-code-point/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js index bba3b52897e1..a4bd6b92bc4c 100644 --- a/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js +++ b/lib/node_modules/@stdlib/string/base/remove-first-code-point/test/test.js @@ -71,7 +71,7 @@ tape( 'the function removes the first Unicode code point of a provided string (U out = removeFirst( '𐒻𐓟', 1 ); t.strictEqual( out, '𐓟', 'returns expected value' ); - out = removeFirst( '\uDC00', 1 ); + out = removeFirst( '\uD800', 1 ); t.strictEqual( out, '', 'returns expected value' ); t.end(); From 76d08ac7fd57e8eee5a2716ae757842f74bbf601 Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Mon, 4 Sep 2023 15:27:10 -0500 Subject: [PATCH 12/14] fix: update implementation to avoid using an array --- .../remove-last-grapheme-cluster/lib/main.js | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js index 9fdcee02f377..fd08f319f531 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js @@ -21,6 +21,7 @@ // MODULES // var nextGraphemeClusterBreak = require('@stdlib/string/next-grapheme-cluster-break'); +var numGraphemeClusters = require( '@stdlib/string/num-grapheme-clusters' ); // MAIN // @@ -57,22 +58,29 @@ var nextGraphemeClusterBreak = require('@stdlib/string/next-grapheme-cluster-bre * // returns 'fo' */ function removeLast( str, n ) { - var idx; + var total; + var num; var i; - idx = []; + if ( n === 0 ) { + return str; + } + + total = numGraphemeClusters( str ); + if ( str === '' || total < n ) { + return ''; + } + i = 0; - while ( i < str.length ) { + num = 0; + while ( num < total - n ) { i = nextGraphemeClusterBreak( str, i ); + num += 1; if ( i === -1 ) { break; } - idx.push(i); - } - if ( str === '' || idx.length < n ) { - return ''; } - return str.substring( 0, idx[ idx.length - n ] ); + return str.substring( 0, i ); } From 3260861a80f95da8e3e57ca63c35aef0095a783c Mon Sep 17 00:00:00 2001 From: Stephannie Jimenez Date: Mon, 4 Sep 2023 15:32:53 -0500 Subject: [PATCH 13/14] fix: fix coverage for remove-last-grapheme-cluster --- .../string/base/remove-last-grapheme-cluster/lib/main.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js index fd08f319f531..88e44cc00b1c 100644 --- a/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js +++ b/lib/node_modules/@stdlib/string/base/remove-last-grapheme-cluster/lib/main.js @@ -76,9 +76,6 @@ function removeLast( str, n ) { while ( num < total - n ) { i = nextGraphemeClusterBreak( str, i ); num += 1; - if ( i === -1 ) { - break; - } } return str.substring( 0, i ); } From c4ddd4d48e7f92f8a1c763bc90c5d14d83500261 Mon Sep 17 00:00:00 2001 From: Athan Date: Thu, 21 Sep 2023 14:30:26 -0700 Subject: [PATCH 14/14] Fix missing parameter description --- lib/node_modules/@stdlib/string/remove-last/lib/main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/node_modules/@stdlib/string/remove-last/lib/main.js b/lib/node_modules/@stdlib/string/remove-last/lib/main.js index 14fae9593c4f..88917610cc65 100644 --- a/lib/node_modules/@stdlib/string/remove-last/lib/main.js +++ b/lib/node_modules/@stdlib/string/remove-last/lib/main.js @@ -49,6 +49,7 @@ var isMode = contains( MODES ); * * @param {string} str - input string * @param {NonNegativeInteger} [n=1] - number of character to remove +* @param {Options} [options] - options * @param {string} [options.mode="grapheme"] - type of "character" to return (must be either `grapheme`, `code_point`, or `code_unit`) * @throws {TypeError} must provide a string primitive * @throws {TypeError} second argument must be a nonnegative integer