2021-05-11 22:47:14 +01:00
describe ( "errors" , ( ) => {
test ( "invalid pattern" , ( ) => {
expect ( ( ) => {
RegExp ( "[" ) ;
2025-10-31 11:50:48 -04:00
} ) . toThrowWithMessage ( SyntaxError , "RegExp compile error: Error during parsing of regular expression:" ) ;
2021-05-11 22:47:14 +01:00
} ) ;
test ( "invalid flag" , ( ) => {
expect ( ( ) => {
RegExp ( "" , "x" ) ;
} ) . toThrowWithMessage ( SyntaxError , "Invalid RegExp flag 'x'" ) ;
} ) ;
test ( "repeated flag" , ( ) => {
expect ( ( ) => {
RegExp ( "" , "gg" ) ;
} ) . toThrowWithMessage ( SyntaxError , "Repeated RegExp flag 'g'" ) ;
} ) ;
} ) ;
2020-11-27 22:42:41 +00:00
test ( "basic functionality" , ( ) => {
2020-11-27 23:42:58 +00:00
expect ( RegExp ( ) . toString ( ) ) . toBe ( "/(?:)/" ) ;
expect ( RegExp ( undefined ) . toString ( ) ) . toBe ( "/(?:)/" ) ;
2020-11-27 22:42:41 +00:00
expect ( RegExp ( "foo" ) . toString ( ) ) . toBe ( "/foo/" ) ;
expect ( RegExp ( "foo" , undefined ) . toString ( ) ) . toBe ( "/foo/" ) ;
expect ( RegExp ( "foo" , "g" ) . toString ( ) ) . toBe ( "/foo/g" ) ;
2020-11-27 23:42:58 +00:00
expect ( RegExp ( undefined , "g" ) . toString ( ) ) . toBe ( "/(?:)/g" ) ;
2020-11-27 22:42:41 +00:00
} ) ;
2021-07-08 13:36:09 -04:00
test ( "regexp object as pattern parameter" , ( ) => {
expect ( RegExp ( /foo/ ) . toString ( ) ) . toBe ( "/foo/" ) ;
expect ( RegExp ( /foo/g ) . toString ( ) ) . toBe ( "/foo/g" ) ;
expect ( RegExp ( /foo/g , "" ) . toString ( ) ) . toBe ( "/foo/" ) ;
expect ( RegExp ( /foo/g , "y" ) . toString ( ) ) . toBe ( "/foo/y" ) ;
var regex _like _object _without _flags = {
source : "foo" ,
[ Symbol . match ] : function ( ) { } ,
} ;
expect ( RegExp ( regex _like _object _without _flags ) . toString ( ) ) . toBe ( "/foo/" ) ;
expect ( RegExp ( regex _like _object _without _flags , "y" ) . toString ( ) ) . toBe ( "/foo/y" ) ;
var regex _like _object _with _flags = {
source : "foo" ,
flags : "g" ,
[ Symbol . match ] : function ( ) { } ,
} ;
expect ( RegExp ( regex _like _object _with _flags ) . toString ( ) ) . toBe ( "/foo/g" ) ;
expect ( RegExp ( regex _like _object _with _flags , "" ) . toString ( ) ) . toBe ( "/foo/" ) ;
expect ( RegExp ( regex _like _object _with _flags , "y" ) . toString ( ) ) . toBe ( "/foo/y" ) ;
} ) ;
2021-07-29 10:34:37 -04:00
test ( "regexp literals are re-useable" , ( ) => {
for ( var i = 0 ; i < 2 ; ++ i ) {
const re = /test/ ;
expect ( re . test ( "te" ) ) . toBeFalse ( ) ;
expect ( re . test ( "test" ) ) . toBeTrue ( ) ;
}
} ) ;
2023-09-16 16:03:54 +03:30
test ( "Incorrectly escaped code units not converted to invalid patterns" , ( ) => {
const re = /[\⪾-\⫀]/ ;
expect ( re . test ( "⫀" ) ) . toBeTrue ( ) ;
expect ( re . test ( "\\u2abe" ) ) . toBeFalse ( ) ; // ⫀ is \u2abe
} ) ;
2025-02-14 14:55:36 +00:00
test ( "regexp that always matches stops matching if it's past the end of the string instead of infinitely looping" , ( ) => {
const re = new RegExp ( "[\u200E]*" , "gu" ) ;
expect ( "whf" . match ( re ) ) . toEqual ( [ "" , "" , "" , "" ] ) ;
expect ( re . lastIndex ) . toBe ( 0 ) ;
} ) ;
2025-02-28 12:29:44 +01:00
test ( "v flag should enable unicode mode" , ( ) => {
const re = new RegExp ( "a\\u{10FFFF}" , "v" ) ;
expect ( re . test ( "a\u{10FFFF}" ) ) . toBe ( true ) ;
} ) ;
2025-04-05 01:38:32 +13:00
test ( "parsing a large bytestring shouldn't crash" , ( ) => {
RegExp ( new Uint8Array ( 0x40000 ) ) ;
} ) ;
2025-07-21 14:58:39 +02:00
test ( "Unicode non-ASCII matching" , ( ) => {
const cases = [
{ pattern : /é/u , match : "é" , expected : [ "é" ] } ,
{ pattern : /é/ , match : "é" , expected : [ "é" ] } ,
{ pattern : /\u{61}/u , match : "a" , expected : [ "a" ] } ,
{ pattern : /\u{61}/ , match : "a" , expected : null } ,
{ pattern : /😄/u , match : "😄" , expected : [ "😄" ] } ,
{ pattern : /😄/u , match : "\ud83d" , expected : null } ,
{ pattern : /😄/ , match : "\ud83d" , expected : null } ,
] ;
for ( const test of cases ) {
const result = test . match . match ( test . pattern ) ;
expect ( result ) . toEqual ( test . expected ) ;
}
} ) ;
2025-07-24 00:16:08 +02:00
// Test from https://github.com/tc39/test262/blob/main/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-property-of-strings-escape.js
test ( "Unicode properties of strings" , ( ) => {
const regexes = [
/ \ p { B a s i c _ E m o j i } / v ,
/ \ p { E m o j i _ K e y c a p _ S e q u e n c e } / v ,
/ \ p { R G I _ E m o j i _ M o d i f i e r _ S e q u e n c e } / v ,
/ \ p { R G I _ E m o j i _ F l a g _ S e q u e n c e } / v ,
/ \ p { R G I _ E m o j i _ T a g _ S e q u e n c e } / v ,
/ \ p { R G I _ E m o j i _ Z W J _ S e q u e n c e } / v ,
/ \ p { R G I _ E m o j i } / v ,
] ;
for ( const re of regexes ) {
expect ( ( ) => {
re . test ( "test" ) ;
} ) . not . toThrow ( ) ;
}
2025-10-31 11:50:48 -04:00
const matchStrings = [ "0" , "1" , "2" , "3" , "4" , "5" , "8" , "A" , "B" , "D" , "E" , "F" , "a" , "b" , "c" , "d" , "e" , "f" ] ;
2025-07-24 00:16:08 +02:00
const nonMatchStrings = [
"6\uFE0F\u20E3" ,
"7\uFE0F\u20E3" ,
"9\uFE0F\u20E3" ,
"\u2603" ,
"\u{1D306}" ,
"\u{1F1E7}\u{1F1EA}" ,
] ;
const re = / ^ [ \ p { A S C I I _ H e x _ D i g i t } - - \ p { E m o j i _ K e y c a p _ S e q u e n c e } ] + $ / v ;
for ( const str of matchStrings ) {
expect ( re . test ( str ) ) . toBeTrue ( ) ;
}
for ( const str of nonMatchStrings ) {
expect ( re . test ( str ) ) . toBeFalse ( ) ;
}
} ) ;
2025-10-22 13:40:15 +02:00
test ( "Unicode matching with u and v flags" , ( ) => {
const text = "𠮷a𠮷b𠮷" ;
const complexText = "a\u{20BB7}b\u{10FFFF}c" ;
const cases = [
{ pattern : /𠮷/ , match : text , expected : [ "𠮷" ] } ,
{ pattern : /𠮷/u , match : text , expected : [ "𠮷" ] } ,
{ pattern : / 𠮷 / v , m a t c h : t e x t , e x p e c t e d : [ " 𠮷 " ] } ,
{ pattern : /\p{Script=Han}/u , match : text , expected : [ "𠮷" ] } ,
{ pattern : / \ p { S c r i p t = H a n } / v , m a t c h : t e x t , e x p e c t e d : [ " 𠮷 " ] } ,
{ pattern : /./u , match : text , expected : [ "𠮷" ] } ,
{ pattern : / . / v , m a t c h : t e x t , e x p e c t e d : [ " 𠮷 " ] } ,
{ pattern : /\p{ASCII}/u , match : text , expected : [ "a" ] } ,
{ pattern : / \ p { A S C I I } / v , m a t c h : t e x t , e x p e c t e d : [ " a " ] } ,
{ pattern : /x/u , match : text , expected : null } ,
{ pattern : / x / v , m a t c h : t e x t , e x p e c t e d : n u l l } ,
{ pattern : /\p{Script=Han}(.)/gu , match : text , expected : [ "𠮷a" , "𠮷b" ] } ,
{ pattern : / \ p { S c r i p t = H a n } ( . ) / g v , m a t c h : t e x t , e x p e c t e d : [ " 𠮷 a " , " 𠮷 b " ] } ,
{ pattern : /\P{ASCII}/u , match : complexText , expected : [ "\u{20BB7}" ] } ,
{ pattern : / \ P { A S C I I } / v , m a t c h : c o m p l e x T e x t , e x p e c t e d : [ " \ u { 2 0 B B 7 } " ] } ,
{ pattern : /\P{ASCII}/gu , match : complexText , expected : [ "\u{20BB7}" , "\u{10FFFF}" ] } ,
{ pattern : / \ P { A S C I I } / g v , m a t c h : c o m p l e x T e x t , e x p e c t e d : [ " \ u { 2 0 B B 7 } " , " \ u { 1 0 F F F F } " ] } ,
{ pattern : /./gu , match : text , expected : [ "𠮷" , "a" , "𠮷" , "b" , "𠮷" ] } ,
{ pattern : / . / g v , m a t c h : t e x t , e x p e c t e d : [ " 𠮷 " , " a " , " 𠮷 " , " b " , " 𠮷 " ] } ,
{ pattern : /(?:)/gu , match : text , expected : [ "" , "" , "" , "" , "" , "" ] } ,
{ pattern : / ( ? : ) / g v , m a t c h : t e x t , e x p e c t e d : [ " " , " " , " " , " " , " " , " " ] } ,
] ;
for ( const test of cases ) {
const result = test . match . match ( test . pattern ) ;
expect ( result ) . toEqual ( test . expected ) ;
}
} ) ;