• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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