Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 2 additions & 78 deletions tests/spec/s-xregexp-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -1251,84 +1251,8 @@ describe('XRegExp.replace()', function() {
expect(function() {XRegExp.replace('test', XRegExp('(?<test>t)', 'g'), ':$<x>:');}).toThrowError(SyntaxError);
});

});

describe('explicit numbered backreferences', function() {

it('should return the numbered backreference', function() {
expect(XRegExp.replace('test', /(.)./g, '${1}')).toBe('ts');
expect(XRegExp.replace('test', /(.)./g, '$<1>')).toBe('ts');

// Backreference to a nonparticipating capturing group
expect(XRegExp.replace('test', /t|(e)/g, '${1}')).toBe('es');
expect(XRegExp.replace('test', /t|(e)/g, '$<1>')).toBe('es');
});

it('should allow leading zeros', function() {
expect(XRegExp.replace('test', /(.)./g, '${01}')).toBe('ts');
expect(XRegExp.replace('test', /(.)./g, '$<01>')).toBe('ts');

expect(XRegExp.replace('test', /(.)./g, '${001}')).toBe('ts');
expect(XRegExp.replace('test', /(.)./g, '$<001>')).toBe('ts');
});

it('should return named backreferences by number', function() {
expect(XRegExp.replace('test', XRegExp('(?<name>.).', 'g'), '${1}')).toBe('ts');
expect(XRegExp.replace('test', XRegExp('(?<name>.).', 'g'), '$<1>')).toBe('ts');
});

it('should separate numbered backreferences from following literal digits', function() {
expect(XRegExp.replace('test', new RegExp('(.).', 'g'), '${1}0')).toBe('t0s0');
expect(XRegExp.replace('test', new RegExp('(.).', 'g'), '$<1>0')).toBe('t0s0');

expect(XRegExp.replace('test', new RegExp('(.).' + '()'.repeat(9), 'g'), '${1}0')).toBe('t0s0');
expect(XRegExp.replace('test', new RegExp('(.).' + '()'.repeat(9), 'g'), '$<1>0')).toBe('t0s0');
});

it('should throw an exception for backreferences to unknown group numbers', function() {
expect(function() {XRegExp.replace('test', /t/, '${1}');}).toThrowError(SyntaxError);
expect(function() {XRegExp.replace('test', /t/, '$<1>');}).toThrowError(SyntaxError);

expect(function() {XRegExp.replace('test', /(t)/, '${2}');}).toThrowError(SyntaxError);
expect(function() {XRegExp.replace('test', /(t)/, '$<2>');}).toThrowError(SyntaxError);
});

it('should allow ${0} to refer to the entire match', function() {
expect(XRegExp.replace('test', /../g, '${0}:')).toBe('te:st:');
expect(XRegExp.replace('test', /../g, '$<0>:')).toBe('te:st:');

expect(XRegExp.replace('test', /../g, '${00}:')).toBe('te:st:');
expect(XRegExp.replace('test', /../g, '$<00>:')).toBe('te:st:');

expect(XRegExp.replace('test', /../g, '${000}:')).toBe('te:st:');
expect(XRegExp.replace('test', /../g, '$<000>:')).toBe('te:st:');
});

it('should support backreferences 100 and greater, if the browser does natively', function() {
// IE < 9 doesn't allow backreferences greater than \99 *within* a regex, but
// XRegExp still allows backreferences to groups 100+ within replacement text
try {
// Regex with 1,000 capturing groups. This fails in Firefox 4-6 (but not v3.6
// or v7+) with `InternalError: regular expression too complex`
var lottaGroups = new RegExp([
'^(a)\\1', '()'.repeat(8),
'(b)\\10', '()'.repeat(89),
'(c)', '()'.repeat(899),
'(d)$'
].join(''));

expect(XRegExp.replace('aabbcd', lottaGroups, '${0} ${01} ${001} ${0001} ${1} ${10} ${100} ${1000}')).toBe('aabbcd a a a a b c d');
expect(XRegExp.replace('aabbcd', lottaGroups, '$<0> $<01> $<001> $<0001> $<1> $<10> $<100> $<1000>')).toBe('aabbcd a a a a b c d');
expect(XRegExp.replace('aabbcd', lottaGroups, '$<0> ${01} $<001> ${0001} $<1> ${10} $<100> ${1000}')).toBe('aabbcd a a a a b c d');
// For comparison...
expect(XRegExp.replace('aabbcd', lottaGroups, '$0 $01 $001 $0001 $1 $10 $100 $1000')).toBe('aabbcd a aabbcd1 aabbcd01 a b b0 b00');
} catch (err) {
// Keep the assertion count consistent cross-browser
expect(true).toBe(true);
expect(true).toBe(true);
expect(true).toBe(true);
expect(true).toBe(true);
}
it('should not allow leading digits', function() {
expect(function() {XRegExp.replace('test', /(.)./g, '${01}');}).toThrowError(SyntaxError);
});

});
Expand Down
62 changes: 10 additions & 52 deletions tests/spec/s-xregexp.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,27 +393,24 @@ describe('XRegExp()', function() {
// Named capture *functionality* is tested by the specs for named backreference syntax,
// XRegExp.exec, XRegExp.replace, etc.

it('should allow the characters A-Z, a-z, 0-9, $, and _ to be used in capture names', function() {
it('should allow the characters A-Z, a-z, 0-9, $, _, and RegExpIdentifierName characters to be used in capture names', function() {
expect(XRegExp('(?<Az>x)').test('x')).toBe(true);
expect(XRegExp('(?<_09>x)').test('x')).toBe(true);
expect(XRegExp('(?<$>x)').test('x')).toBe(true);
expect(function() {XRegExp('(?<naïve>)');}).not.toThrow();
expect(function() {XRegExp('(?<Русский>)');}).not.toThrow();
expect(function() {XRegExp('(?<日本語>)');}).not.toThrow();
});

it('should throw an exception if characters other than A-Z, a-z, 0-9, $, and _ are used in capture names', function() {
expect(function() {XRegExp('(?<?>)');}).toThrowError(SyntaxError);
expect(function() {XRegExp('(?<.>)');}).toThrowError(SyntaxError);
expect(function() {XRegExp('(?<<>)');}).toThrowError(SyntaxError);
expect(function() {XRegExp('(?<->)');}).toThrowError(SyntaxError);
// Native named capture uses different allowed chars that XRegExp should be updated to handle
//expect(function() {XRegExp('(?<naïve>)');}).toThrowError(SyntaxError);
//expect(function() {XRegExp('(?<Русский>)');}).toThrowError(SyntaxError);
//expect(function() {XRegExp('(?<日本語>)');}).toThrowError(SyntaxError);
});

it('should allow capture names to start with digits', function() {
expect(XRegExp('(?<0a>x)').test('x')).toBe(true);
expect(XRegExp('(?<1_1>x)').test('x')).toBe(true);
expect(XRegExp('(?<234$>x)').test('x')).toBe(true);
it('should not allow capture names to start with digits', function() {
expect(function() {XRegExp('(?<0a>x)');}).toThrowError(SyntaxError);
});

it('should throw an exception if bare integers are used as capture names', function() {
Expand Down Expand Up @@ -488,6 +485,10 @@ describe('XRegExp()', function() {
expect(function() {XRegExp('\\k<`>');}).toThrowError(SyntaxError);
});

it('should not allow leading digits', function() {
expect(function() {XRegExp('(.)\\k<01>');}).toThrowError(SyntaxError);
});

it('should separate backreferences from following literal digits', function() {
expect(XRegExp('(?<$1>A1)(2)(3)(4)(5)(6)(7)(8)(9)(B10)\\k<$1>0').test('A123456789B10A10')).toBe(true);
expect(XRegExp('(?<$1>A)\\k<$1>2').test('AA2')).toBe(true);
Expand All @@ -506,49 +507,6 @@ describe('XRegExp()', function() {

});

describe('explicit numbered backreferences', function() {

it('should match the numbered backreference', function() {
expect(XRegExp('(.)\\k<1>').test('aa')).toBe(true);
expect(XRegExp('(.)\\k<1>').test('ab')).toBe(false);
expect(XRegExp('(.)\\k<1>\\k<1>').test('aaa')).toBe(true);
});

it('should allow leading zeros', function() {
expect(XRegExp('(.)\\k<01>').test('aa')).toBe(true);
expect(XRegExp('(.)\\k<001>').test('aa')).toBe(true);
});

it('should match named backreferences by number', function() {
expect(XRegExp('(?<A>.)\\k<1>').test('aa')).toBe(true);
expect(XRegExp('(?<A>.)\\k<1>').test('ab')).toBe(false);
expect(XRegExp('(?<A>.)\\k<1>\\k<1>').test('aaa')).toBe(true);
});

it('should separate numbered backreferences from following literal digits', function() {
expect(XRegExp('(A1)(2)(3)(4)(5)(6)(7)(8)(9)(B10)\\k<1>0').test('A123456789B10A10')).toBe(true);
expect(XRegExp('(A)\\k<1>2').test('AA2')).toBe(true);
});

it('should throw an exception for backreferences to unknown groups', function() {
expect(function() {XRegExp('\\k<1>');}).toThrowError(SyntaxError);
expect(function() {XRegExp('()\\k<2>');}).toThrowError(SyntaxError);
});

it('should throw an exception for backreferences to capturing groups not opened to the left', function() {
expect(function() {XRegExp('\\k<1>()');}).toThrowError(SyntaxError);
expect(function() {XRegExp('()\\k<2>()');}).toThrowError(SyntaxError);
expect(function() {XRegExp('(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)\\k<11>(11)');}).toThrowError(SyntaxError);
expect(function() {XRegExp('(\\k<1>)');}).not.toThrow();
});

it('should not allow \\k<0> to refer to the entire match', function() {
expect(function() {XRegExp('\\k<0>');}).toThrowError(SyntaxError);
expect(function() {XRegExp('\\k<00>');}).toThrowError(SyntaxError);
});

});

describe('strict error handling', function() {

it('should throw an exception for octals except \\0 not followed by 0-9', function() {
Expand Down