Skip to content

Commit 18a1a48

Browse files
committed
feat: add support for BigInts
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent bc1c717 commit 18a1a48

4 files changed

Lines changed: 180 additions & 16 deletions

File tree

lib/node_modules/@stdlib/_tools/doctest/compare-values/lib/main.js

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
* limitations under the License.
1717
*/
1818

19+
/* eslint-disable stdlib/no-empty-lines-between-requires */
20+
1921
'use strict';
2022

2123
// MODULES //
@@ -86,6 +88,7 @@ var removeLast = require( '@stdlib/string/remove-last' );
8688
var replace = require( '@stdlib/string/replace' );
8789
var trim = require( '@stdlib/string/trim' );
8890
var constructorName = require( '@stdlib/utils/constructor-name' );
91+
var BigInt = require( '@stdlib/bigint/ctor' );
8992
var PINF = require( '@stdlib/constants/float64/pinf' );
9093
var NINF = require( '@stdlib/constants/float64/ninf' );
9194
var real = require( '@stdlib/complex/float64/real' );
@@ -110,6 +113,7 @@ var RE_NDARRAY = /<([^>]+)>(\[[\s\S]+\])/;
110113

111114
var RE_UNESCAPED_QUOTE = /[^\\]'/;
112115
var BOXED_TYPE_ANNOTATIONS = [
116+
'<BigInt>',
113117
'<Boolean>',
114118
'<Number>',
115119
'<String>',
@@ -119,7 +123,8 @@ var PRIMITIVE_TYPE_ANNOTATIONS = [ // eslint-disable-line id-length
119123
'<boolean>',
120124
'<number>',
121125
'<string>',
122-
'<symbol>'
126+
'<symbol>',
127+
'<bigint>'
123128
];
124129

125130
var OPTS = {
@@ -129,11 +134,25 @@ var OPTS = {
129134

130135
// FUNCTIONS //
131136

137+
/**
138+
* Formats a value for an error message.
139+
*
140+
* @private
141+
* @param {*} value - input value
142+
* @returns {*} formatted value
143+
*/
144+
function formatValue( value ) {
145+
if ( isBigInt( value ) ) {
146+
return value.toString() + 'n';
147+
}
148+
return value;
149+
}
150+
132151
/**
133152
* Checks whether a primitive value matches a return annotation.
134153
*
135154
* @private
136-
* @param {(string|boolean|number|null|void)} actual - primitive value
155+
* @param {(string|boolean|number|bigint|null|void)} actual - primitive value
137156
* @param {string} expected - return value annotation
138157
* @returns {boolean} boolean indicating whether a value matches a return annotation
139158
*/
@@ -144,6 +163,21 @@ function checkPrimitive( actual, expected ) {
144163
var b;
145164

146165
type = typeOf( actual );
166+
if ( type === 'bigint' ) {
167+
if ( typeOf( expected ) === 'bigint' ) {
168+
return actual === expected;
169+
}
170+
if ( !isString( expected ) || !endsWith( expected, 'n' ) ) {
171+
return false;
172+
}
173+
try {
174+
// BigInt() does not accept `'100n'`, but only bare integer strings `'100'`
175+
return actual === BigInt( removeLast( expected ) );
176+
} catch ( err ) { // eslint-disable-line no-unused-vars
177+
return false;
178+
}
179+
}
180+
expected = String( expected );
147181
if ( type === 'number' ) {
148182
if ( expected === 'Infinity' || expected === '+Infinity' ) {
149183
return actual === PINF;
@@ -205,6 +239,7 @@ function checkForPlaceholders( actual, expected ) {
205239
return isArray( actual );
206240
case '<ArrayBuffer>':
207241
return isArrayBuffer( actual );
242+
case '<bigint>':
208243
case '<BigInt>':
209244
return isBigInt( actual );
210245
case '<BigInt64Array>':
@@ -312,7 +347,7 @@ function compareEntries( actual, expected ) {
312347
return format( 'Expected entries [%s], but observed [%s]', expected, actual );
313348
}
314349
for ( i = 0; i < expected.length; i++ ) {
315-
if ( !checkPrimitive( actual[ i ], String( expected[ i ] ) ) ) {
350+
if ( !checkPrimitive( actual[ i ], expected[ i ] ) ) {
316351
return format( 'Expected entries [%s], but observed [%s]', expected, actual );
317352
}
318353
}
@@ -441,7 +476,6 @@ function checkArray( actual, expected ) {
441476
if ( !isPrimitive( b ) ) {
442477
return false;
443478
}
444-
b = String( b );
445479
if ( !checkPrimitive( a, b ) ) {
446480
return false;
447481
}
@@ -558,20 +592,20 @@ function compareValues( actual, expected ) {
558592
contains( BOXED_TYPE_ANNOTATIONS, expected ) &&
559593
isPrimitive( actual )
560594
) {
561-
return format( 'Expected a %s, but received an unboxed primitive: `%s`', expected, actual );
595+
return format( 'Expected a %s, but received an unboxed primitive: `%s`', expected, formatValue( actual ) );
562596
}
563597
// Case: compareValues( 5, '<number>' )
564598
if (
565599
contains( PRIMITIVE_TYPE_ANNOTATIONS, expected ) &&
566600
isBoxedPrimitive( actual )
567601
) {
568-
return format( 'Expected a %s, but received a boxed primitive: `%s`', expected, actual );
602+
return format( 'Expected a %s, but received a boxed primitive: `%s`', expected, formatValue( actual ) );
569603
}
570604
return null;
571605
}
572606
// Case: compareValues( 5, '5' )
573607
if ( isPrimitive( actual ) ) {
574-
if ( isString( actual) ) {
608+
if ( isString( actual ) ) {
575609
if (
576610
!RE_UNESCAPED_QUOTE.test( actual ) &&
577611
( !startsWith( expected, '\'' ) || !endsWith( expected, '\'' ) )
@@ -581,7 +615,7 @@ function compareValues( actual, expected ) {
581615
expected = removeFirst( removeLast( expected ) );
582616
}
583617
if ( !checkPrimitive( actual, expected ) ) {
584-
return format( 'Displayed return value is `%s`, but expected `%s` instead', expected, actual );
618+
return format( 'Displayed return value is `%s`, but expected `%s` instead', expected, formatValue( actual ) );
585619
}
586620
return null;
587621
}

lib/node_modules/@stdlib/_tools/doctest/compare-values/lib/parse.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@
2727

2828
// MODULES //
2929

30-
var isNumberArray = require( '@stdlib/assert/is-number-array' );
31-
var isfinite = require( '@stdlib/assert/is-finite' );
32-
var isString = require( '@stdlib/assert/is-string' );
30+
var isNumberArray = require( '@stdlib/assert/is-number-array' ).primitives;
31+
var isfinite = require( '@stdlib/assert/is-finite' ).isPrimitive;
32+
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
3333
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
3434
var startsWith = require( '@stdlib/string/starts-with' );
3535
var reFromString = require( '@stdlib/utils/regexp-from-string' );
36+
var BigInt = require( '@stdlib/bigint/ctor' );
3637
var NINF = require( '@stdlib/constants/float64/ninf' );
3738
var PINF = require( '@stdlib/constants/float64/pinf' );
3839
var format = require( '@stdlib/string/format' );
@@ -202,7 +203,7 @@ function word() {
202203
* Parses a type annotation.
203204
*
204205
* @private
205-
* @returns {string} type identifier wrapped in quotes
206+
* @returns {(string|*)} type identifier wrapped in quotes or a parsed value
206207
*/
207208
function type() {
208209
var ctor;
@@ -423,13 +424,16 @@ function goNext( c ) {
423424
* Parses a number value.
424425
*
425426
* @private
426-
* @returns {(number|string)} parsed number or string for rounded values
427+
* @returns {(number|string|bigint)} parsed number, string for rounded values, or BigInt
427428
*/
428429
function number() {
430+
var isBigInt;
429431
var string;
432+
var digits;
430433
var value;
431434

432435
string = '';
436+
digits = 0;
433437
if ( ch === '~' ) {
434438
string += '~';
435439
goNext( '~' );
@@ -454,15 +458,18 @@ function number() {
454458
}
455459
while ( ch >= '0' && ch <= '9' ) {
456460
string += ch;
461+
digits += 1;
457462
goNext();
458463
}
459464
if ( ch === '.' ) {
465+
isBigInt = false;
460466
string += '.';
461467
while ( goNext() && ch >= '0' && ch <= '9' ) {
462468
string += ch;
463469
}
464470
}
465471
if ( ch === 'e' || ch === 'E' ) {
472+
isBigInt = false;
466473
string += ch;
467474
goNext();
468475
if ( ch === '-' || ch === '+' ) {
@@ -471,9 +478,17 @@ function number() {
471478
}
472479
while ( ch >= '0' && ch <= '9' ) {
473480
string += ch;
481+
digits += 1;
474482
goNext();
475483
}
476484
}
485+
if ( ch === 'n' ) {
486+
if ( digits === 0 || startsWith( string, '~' ) || isBigInt === false ) {
487+
return error( 'Bad BigInt' );
488+
}
489+
goNext( 'n' );
490+
return BigInt( string );
491+
}
477492
if ( startsWith( string, '~' ) ) {
478493
return string;
479494
}

lib/node_modules/@stdlib/_tools/doctest/compare-values/test/test.js

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121
// MODULES //
2222

2323
var tape = require( 'tape' );
24+
var hasBigIntSupport = require( '@stdlib/assert/has-bigint-support' );
25+
var hasBigInt64ArraySupport = require( '@stdlib/assert/has-bigint64array-support' );
26+
var hasBigUint64ArraySupport = require( '@stdlib/assert/has-biguint64array-support' );
2427
var Number = require( '@stdlib/number/ctor' );
2528
var Boolean = require( '@stdlib/boolean/ctor' );
29+
var BigInt = require( '@stdlib/bigint/ctor' );
30+
var Object = require( '@stdlib/object/ctor' );
2631
var Float32Array = require( '@stdlib/array/float32' );
2732
var Float64Array = require( '@stdlib/array/float64' );
2833
var Complex64 = require( '@stdlib/complex/float32/ctor' );
@@ -36,6 +41,13 @@ var scalar2ndarray = require( '@stdlib/ndarray/from-scalar' );
3641
var compareValues = require( './../lib' );
3742

3843

44+
// VARIABLES //
45+
46+
var HAS_BIGINTS = hasBigIntSupport();
47+
var HAS_BIGINT64ARRAY = hasBigInt64ArraySupport();
48+
var HAS_BIGUINT64ARRAY = hasBigUint64ArraySupport();
49+
50+
3951
// FUNCTIONS //
4052

4153
function createErrorMessage( actual, expected ) {
@@ -87,6 +99,11 @@ tape( 'the function compares primitives and a corresponding matching return anno
8799
expected = '\'2.13\'';
88100
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
89101

102+
if ( HAS_BIGINTS ) {
103+
actual = BigInt( 100 );
104+
expected = '100n';
105+
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
106+
}
90107
t.end();
91108
});
92109

@@ -135,6 +152,13 @@ tape( 'the function compares primitives and a corresponding non-matching return
135152
msg = createErrorMessage( actual, expected );
136153
t.strictEqual( compareValues( actual, expected ), msg, 'returns expected message' );
137154

155+
if ( HAS_BIGINTS ) {
156+
actual = BigInt( 100 );
157+
expected = '101n';
158+
msg = 'Displayed return value is `101n`, but expected `100n` instead';
159+
t.strictEqual( compareValues( actual, expected ), msg, 'returns expected value' );
160+
}
161+
138162
t.end();
139163
});
140164

@@ -204,6 +228,12 @@ tape( 'the function compares an array and a corresponding return annotation', fu
204228
expected = '[ 2, -Infinity ]';
205229
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
206230

231+
if ( HAS_BIGINTS ) {
232+
actual = [ BigInt( 100 ), BigInt( 101 ) ];
233+
expected = '[ 100n, 101n ]';
234+
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
235+
}
236+
207237
actual = [ 0, 2, 3 ];
208238
expected = '[ 0, 2, 2 ]';
209239
msg = 'Displayed return value is `[ 0, 2, 2 ]`, but expected `[ 0, 2, 3 ]` instead';
@@ -226,6 +256,13 @@ tape( 'the function compares an array and a corresponding return annotation', fu
226256
expected = '[ ~-3.81, ~3.81 ]';
227257
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
228258

259+
if ( HAS_BIGINTS ) {
260+
actual = [ BigInt( 100 ), BigInt( 101 ) ];
261+
expected = '[ 101n, 102n ]';
262+
msg = 'Displayed return value is `[ 101n, 102n ]`, but expected `[ 100n, 101n ]` instead';
263+
t.strictEqual( compareValues( actual, expected ), msg, 'returns expected value' );
264+
}
265+
229266
actual = [ [ 3, 60 ], [ 2, 50 ] ];
230267
expected = '[ [3, 60], [2, 50] ]';
231268
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
@@ -328,6 +365,18 @@ tape( 'the function compares a typed array and a corresponding return annotation
328365
msg = 'Expected entries [true,true,true,true], but observed [true,false,true,false]';
329366
t.strictEqual( compareValues( actual, expected ), msg, 'returns expected message' );
330367

368+
if ( HAS_BIGINT64ARRAY ) {
369+
actual = new BigInt64Array( [ BigInt( 100 ), BigInt( -101 ) ] ); // eslint-disable-line stdlib/require-globals, no-undef
370+
expected = '<BigInt64Array>[ 100n, -101n ]';
371+
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
372+
}
373+
374+
if ( HAS_BIGUINT64ARRAY ) {
375+
actual = new BigUint64Array( [ BigInt( 100 ), BigInt( 101 ) ] ); // eslint-disable-line stdlib/require-globals, no-undef
376+
expected = '<BigUint64Array>[ 100n, 101n ]';
377+
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
378+
}
379+
331380
t.end();
332381
});
333382

@@ -468,6 +517,12 @@ tape( 'the function compares a value with a type equality return annotation', fu
468517
expected = '<Function>';
469518
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
470519

520+
if ( HAS_BIGINTS ) {
521+
actual = BigInt( 100 );
522+
expected = '<bigint>';
523+
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
524+
}
525+
471526
t.end();
472527
});
473528

@@ -490,8 +545,8 @@ tape( 'the function differentiates between boxed and primitive values', function
490545
msg = 'Expected a <number>, but received a boxed primitive: `2.3`';
491546
t.strictEqual( compareValues( actual, expected ), msg, 'returns expected message' );
492547

493-
actual = 2.3;
494-
expected = '<number>';
548+
actual = new Number( 2.3 );
549+
expected = '<Number>';
495550
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
496551

497552
actual = 'beep';
@@ -518,6 +573,26 @@ tape( 'the function differentiates between boxed and primitive values', function
518573
expected = '<boolean>';
519574
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
520575

576+
if ( HAS_BIGINTS ) {
577+
actual = BigInt( 100 );
578+
expected = '<bigint>';
579+
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
580+
581+
actual = BigInt( 100 );
582+
expected = '<BigInt>';
583+
msg = 'Expected a <BigInt>, but received an unboxed primitive: `100n`';
584+
t.strictEqual( compareValues( actual, expected ), msg, 'returns expected message' );
585+
586+
actual = Object( BigInt( 100 ) );
587+
expected = '<bigint>';
588+
msg = 'Expected a <bigint>, but received a boxed primitive: `100n`';
589+
t.strictEqual( compareValues( actual, expected ), msg, 'returns expected message' );
590+
591+
actual = Object( BigInt( 100 ) );
592+
expected = '<BigInt>';
593+
t.strictEqual( compareValues( actual, expected ), null, 'returns expected value' );
594+
}
595+
521596
t.end();
522597
});
523598

0 commit comments

Comments
 (0)