1// Copyright 2015 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5var r1 = /abc/gi; 6assertEquals("abc", r1.source); 7assertTrue(r1.global); 8assertTrue(r1.ignoreCase); 9assertFalse(r1.multiline); 10assertFalse(r1.sticky); 11assertFalse(r1.unicode); 12 13// Internal slot of prototype is not read. 14var r2 = { __proto__: r1 }; 15assertThrows(function() { r2.source; }, TypeError); 16assertThrows(function() { r2.global; }, TypeError); 17assertThrows(function() { r2.ignoreCase; }, TypeError); 18assertThrows(function() { r2.multiline; }, TypeError); 19assertThrows(function() { r2.sticky; }, TypeError); 20assertThrows(function() { r2.unicode; }, TypeError); 21 22var r3 = /I/; 23var string = "iIiIi"; 24var expected = "iXiIi"; 25assertFalse(r3.global); 26assertFalse(r3.ignoreCase); 27assertEquals("", r3.flags); 28assertEquals(expected, string.replace(r3, "X")); 29 30var get_count = 0; 31Object.defineProperty(r3, "global", { 32 get: function() { get_count++; return true; } 33}); 34Object.defineProperty(r3, "ignoreCase", { 35 get: function() { get_count++; return true; } 36}); 37 38assertTrue(r3.global); 39assertEquals(1, get_count); 40assertTrue(r3.ignoreCase); 41assertEquals(2, get_count); 42// Overridden flag getters affects the flags getter. 43assertEquals("gi", r3.flags); 44assertEquals(4, get_count); 45// Overridden flag getters affect string.replace 46// TODO(adamk): Add more tests here once we've switched 47// to use [[OriginalFlags]] in more cases. 48assertEquals(expected, string.replace(r3, "X")); 49assertEquals(5, get_count); 50 51 52function testName(name) { 53 // Test for ES2017 RegExp web compatibility semantics 54 // https://github.com/tc39/ecma262/pull/511 55 assertEquals(name === "source" ? "(?:)" : undefined, 56 RegExp.prototype[name]); 57 assertEquals( 58 "get " + name, 59 Object.getOwnPropertyDescriptor(RegExp.prototype, name).get.name); 60} 61 62testName("global"); 63testName("ignoreCase"); 64testName("multiline"); 65testName("source"); 66testName("sticky"); 67testName("unicode"); 68 69 70RegExp.prototype.flags = 'setter should be undefined'; 71 72assertEquals('', RegExp('').flags); 73assertEquals('', /./.flags); 74assertEquals('gimuy', RegExp('', 'yugmi').flags); 75assertEquals('gimuy', /foo/yumig.flags); 76 77var descriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags'); 78assertTrue(descriptor.configurable); 79assertFalse(descriptor.enumerable); 80assertInstanceof(descriptor.get, Function); 81assertEquals(undefined, descriptor.set); 82 83function testGenericFlags(object) { 84 return descriptor.get.call(object); 85} 86 87assertEquals('', testGenericFlags({})); 88assertEquals('i', testGenericFlags({ ignoreCase: true })); 89assertEquals('uy', testGenericFlags({ global: 0, sticky: 1, unicode: 1 })); 90assertEquals('m', testGenericFlags({ __proto__: { multiline: true } })); 91assertThrows(function() { testGenericFlags(); }, TypeError); 92assertThrows(function() { testGenericFlags(undefined); }, TypeError); 93assertThrows(function() { testGenericFlags(null); }, TypeError); 94assertThrows(function() { testGenericFlags(true); }, TypeError); 95assertThrows(function() { testGenericFlags(false); }, TypeError); 96assertThrows(function() { testGenericFlags(''); }, TypeError); 97assertThrows(function() { testGenericFlags(42); }, TypeError); 98 99var counter = 0; 100var map = {}; 101var object = { 102 get global() { 103 map.g = counter++; 104 }, 105 get ignoreCase() { 106 map.i = counter++; 107 }, 108 get multiline() { 109 map.m = counter++; 110 }, 111 get unicode() { 112 map.u = counter++; 113 }, 114 get sticky() { 115 map.y = counter++; 116 } 117}; 118testGenericFlags(object); 119assertEquals({ g: 0, i: 1, m: 2, u: 3, y: 4 }, map); 120