From 8879cde471839beb2f72ab5a7ca9d6593127a03a Mon Sep 17 00:00:00 2001
From: Mike Pennisi <mike@mikepennisi.com>
Date: Thu, 6 Aug 2015 14:50:09 -0400
Subject: [PATCH] Add tests for well-known Symbol: @@search

---
 .../Symbol.search/coerce-string-err.js        | 26 +++++++++
 .../prototype/Symbol.search/coerce-string.js  | 20 +++++++
 .../Symbol.search/cstm-exec-return-index.js   | 32 +++++++++++
 .../Symbol.search/cstm-exec-return-invalid.js | 56 +++++++++++++++++++
 .../Symbol.search/failure-return-val.js       | 13 +++++
 .../Symbol.search/get-lastindex-err.js        | 22 ++++++++
 .../RegExp/prototype/Symbol.search/length.js  | 27 +++++++++
 .../prototype/Symbol.search/match-err.js      | 25 +++++++++
 .../RegExp/prototype/Symbol.search/name.js    | 24 ++++++++
 .../prototype/Symbol.search/prop-desc.js      | 19 +++++++
 .../Symbol.search/set-lastindex-init-err.js   | 52 +++++++++++++++++
 .../Symbol.search/set-lastindex-init.js       | 28 ++++++++++
 .../set-lastindex-restore-err.js              | 49 ++++++++++++++++
 .../Symbol.search/set-lastindex-restore.js    | 30 ++++++++++
 .../Symbol.search/success-get-index-err.js    | 27 +++++++++
 .../Symbol.search/success-return-val.js       | 15 +++++
 .../Symbol.search/this-val-non-obj.js         | 39 +++++++++++++
 .../prototype/search/cstm-search-get-err.js   | 24 ++++++++
 .../search/cstm-search-invocation.js          | 34 +++++++++++
 .../invoke-builtin-search-searcher-undef.js   | 51 +++++++++++++++++
 .../prototype/search/invoke-builtin-search.js | 41 ++++++++++++++
 test/built-ins/Symbol/search/prop-desc.js     | 17 ++++++
 22 files changed, 671 insertions(+)
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/coerce-string-err.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/coerce-string.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-index.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-invalid.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/failure-return-val.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/get-lastindex-err.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/length.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/match-err.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/name.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/prop-desc.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init-err.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore-err.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/success-get-index-err.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/success-return-val.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.search/this-val-non-obj.js
 create mode 100644 test/built-ins/String/prototype/search/cstm-search-get-err.js
 create mode 100644 test/built-ins/String/prototype/search/cstm-search-invocation.js
 create mode 100644 test/built-ins/String/prototype/search/invoke-builtin-search-searcher-undef.js
 create mode 100644 test/built-ins/String/prototype/search/invoke-builtin-search.js
 create mode 100644 test/built-ins/Symbol/search/prop-desc.js

diff --git a/test/built-ins/RegExp/prototype/Symbol.search/coerce-string-err.js b/test/built-ins/RegExp/prototype/Symbol.search/coerce-string-err.js
new file mode 100644
index 0000000000..ace7d3dc09
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/coerce-string-err.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: Behavior when error thrown while coercing `string` argument
+info: >
+    [...]
+    3. Let S be ToString(string).
+    4. ReturnIfAbrupt(S).
+features: [Symbol.search]
+---*/
+
+var uncoercibleObj = {
+  toString: function() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  /./[Symbol.search](uncoercibleObj);
+});
+
+assert.throws(TypeError, function() {
+  /./[Symbol.search](Symbol.search);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/coerce-string.js b/test/built-ins/RegExp/prototype/Symbol.search/coerce-string.js
new file mode 100644
index 0000000000..b80750c1e0
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/coerce-string.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: String coercion of `string` argument
+info: >
+    [...]
+    3. Let S be ToString(string).
+    [...]
+features: [Symbol.search]
+---*/
+
+var obj = {
+  toString: function() {
+    return 'toString value';
+  }
+};
+
+assert.sameValue(/ring/[Symbol.search](obj), 4);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-index.js b/test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-index.js
new file mode 100644
index 0000000000..36b22964f4
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-index.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 Mike Pennisi. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: Index value returned by a custom `exec` method
+info: >
+    [...]
+    9. Let result be RegExpExec(rx, S).
+    [...]
+    14. Return Get(result, "index").
+
+    21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
+
+    [...]
+    5. If IsCallable(exec) is true, then
+       a. Let result be Call(exec, R, «S»).
+       b. ReturnIfAbrupt(result).
+       c. If Type(result) is neither Object or Null, throw a TypeError
+          exception.
+       d. Return result.
+
+features: [Symbol.search]
+---*/
+
+var fakeRe = {
+  exec: function() {
+    return { index: 86 };
+  }
+};
+
+assert.sameValue(RegExp.prototype[Symbol.search].call(fakeRe, 'abc'), 86);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-invalid.js b/test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-invalid.js
new file mode 100644
index 0000000000..70b0942c6f
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/cstm-exec-return-invalid.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2015 Mike Pennisi. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: Behavior when invalid value is returned by custom `exec` method
+info: >
+    [...]
+    9. Let result be RegExpExec(rx, S).
+    10. ReturnIfAbrupt(result).
+    [...]
+    14. Return Get(result, "index").
+
+    21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
+
+    [...]
+    5. If IsCallable(exec) is true, then
+       a. Let result be Call(exec, R, «S»).
+       b. ReturnIfAbrupt(result).
+       c. If Type(result) is neither Object or Null, throw a TypeError
+          exception.
+
+features: [Symbol, Symbol.search]
+---*/
+
+var retVal;
+var fakeRe = {
+  exec: function() {
+    return retVal;
+  }
+};
+
+retVal = undefined;
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(fakeRe, 'a');
+});
+
+retVal = 86;
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(fakeRe, 'a');
+});
+
+retVal = 'string';
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(fakeRe, 'a');
+});
+
+retVal = true;
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(fakeRe, 'a');
+});
+
+retVal = Symbol();
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(fakeRe, 'a');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/failure-return-val.js b/test/built-ins/RegExp/prototype/Symbol.search/failure-return-val.js
new file mode 100644
index 0000000000..a3664bada5
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/failure-return-val.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: Return value when no match is found
+info: >
+    [...]
+    13. If result is null, return –1.
+features: [Symbol.search]
+---*/
+
+assert.sameValue(/z/[Symbol.search]('a'), -1);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/get-lastindex-err.js b/test/built-ins/RegExp/prototype/Symbol.search/get-lastindex-err.js
new file mode 100644
index 0000000000..cc5542928e
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/get-lastindex-err.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: Behavior when error thrown while accessing `lastIndex` property
+info: >
+    [...]
+    5. Let previousLastIndex be Get(rx, "lastIndex").
+    6. ReturnIfAbrupt(previousLastIndex).
+features: [Symbol.search]
+---*/
+
+var poisonedLastIndex = {
+  get lastIndex() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  RegExp.prototype[Symbol.search].call(poisonedLastIndex);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/length.js b/test/built-ins/RegExp/prototype/Symbol.search/length.js
new file mode 100644
index 0000000000..d100b92b89
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/length.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 21.2.5.9
+description: RegExp.prototype[Symbol.search] `length` property
+info: >
+    ES6 section 17:
+
+    Every built-in Function object, including constructors, has a length
+    property whose value is an integer. Unless otherwise specified, this value
+    is equal to the largest number of named arguments shown in the subclause
+    headings for the function description, including optional parameters.
+
+    [...]
+
+    Unless otherwise specified, the length property of a built-in Function
+    object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+    [[Configurable]]: true }.
+features: [Symbol.search]
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(RegExp.prototype[Symbol.search].length, 1);
+
+verifyNotEnumerable(RegExp.prototype[Symbol.search], 'length');
+verifyNotWritable(RegExp.prototype[Symbol.search], 'length');
+verifyConfigurable(RegExp.prototype[Symbol.search], 'length');
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/match-err.js b/test/built-ins/RegExp/prototype/Symbol.search/match-err.js
new file mode 100644
index 0000000000..8d6a2a0cc3
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/match-err.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: Behavior when error thrown while executing match
+info: >
+    [...]
+    9. Let result be RegExpExec(rx, S).
+    10. ReturnIfAbrupt(result).
+features: [Symbol.search]
+---*/
+
+var fakeRe = {
+  lastIndex: 86,
+  exec: function() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  RegExp.prototype[Symbol.search].call(fakeRe);
+});
+
+assert.sameValue(fakeRe.lastIndex, 0, '`lastIndex` property is not restored');
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/name.js b/test/built-ins/RegExp/prototype/Symbol.search/name.js
new file mode 100644
index 0000000000..0a73ec9abd
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/name.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 21.2.5.9
+description: RegExp.prototype[Symbol.search] `name` property
+info: >
+    The value of the name property of this function is "[Symbol.search]".
+
+    ES6 Section 17:
+
+    [...]
+
+    Unless otherwise specified, the name property of a built-in Function
+    object, if it exists, has the attributes { [[Writable]]: false,
+    [[Enumerable]]: false, [[Configurable]]: true }.
+features: [Symbol.search]
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(RegExp.prototype[Symbol.search].name, '[Symbol.search]');
+
+verifyNotEnumerable(RegExp.prototype[Symbol.search], 'name');
+verifyNotWritable(RegExp.prototype[Symbol.search], 'name');
+verifyConfigurable(RegExp.prototype[Symbol.search], 'name');
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/prop-desc.js b/test/built-ins/RegExp/prototype/Symbol.search/prop-desc.js
new file mode 100644
index 0000000000..95bff2e481
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/prop-desc.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: RegExp.prototype[Symbol.search] property descriptor
+info: >
+    ES6 Section 17
+
+    Every other data property described in clauses 18 through 26 and in Annex
+    B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+    [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [Symbol.search]
+---*/
+
+verifyNotEnumerable(RegExp.prototype, Symbol.search);
+verifyWritable(RegExp.prototype, Symbol.search);
+verifyConfigurable(RegExp.prototype, Symbol.search);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init-err.js b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init-err.js
new file mode 100644
index 0000000000..e9c7ac5970
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init-err.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: >
+    Behavior when error thrown while initially setting `lastIndex` property
+info: >
+    [...]
+    7. Let status be Set(rx, "lastIndex", 0, true).
+    8. ReturnIfAbrupt(status).
+features: [Symbol.search]
+---*/
+
+var callCount;
+var poisonedLastIndex = {
+  get lastIndex() {
+    callCount += 1;
+  },
+  set lastIndex(_) {
+    throw new Test262Error();
+  }
+};
+var nonWritableLastIndex = {
+  get lastIndex() {
+    callCount += 1;
+  },
+  // This method defined to avoid false positives from unrelated TypeErrors
+  exec: function() {
+    return null;
+  }
+};
+
+callCount = 0;
+assert.throws(Test262Error, function() {
+  RegExp.prototype[Symbol.search].call(poisonedLastIndex);
+});
+assert.sameValue(
+  callCount,
+  1,
+  'Property value was accessed before being set ("poisoned" lastIndex)'
+);
+
+callCount = 0;
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(nonWritableLastIndex);
+});
+assert.sameValue(
+  callCount,
+  1,
+  'Property value was accessed before being set (non-writable lastIndex)'
+);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init.js b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init.js
new file mode 100644
index 0000000000..8080fcb88b
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-init.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: >
+    The `lastIndex` value is set to 0 immediately prior to match execution
+info: >
+    [...]
+    7. Let status be Set(rx, "lastIndex", 0, true).
+    8. ReturnIfAbrupt(status).
+    9. Let result be RegExpExec(rx, S).
+    [...]
+features: [Symbol.search]
+---*/
+
+var duringExec;
+var fakeRe = {
+  lastIndex: 34,
+  exec: function() {
+    duringExec = fakeRe.lastIndex;
+    return null;
+  }
+};
+
+RegExp.prototype[Symbol.search].call(fakeRe);
+
+assert.sameValue(duringExec, 0);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore-err.js b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore-err.js
new file mode 100644
index 0000000000..9a3ede8316
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore-err.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: >
+    Behavior when error thrown while restoring `lastIndex` property following
+    match execution
+info: >
+    [...]
+    11. Let status be Set(rx, "lastIndex", previousLastIndex, true).
+    12. ReturnIfAbrupt(status).
+features: [Symbol.search]
+---*/
+
+var callCount;
+var poisonedLastIndex = {
+  get lastIndex() {},
+  set lastIndex(_) {
+    if (callCount === 1) {
+      throw new Test262Error();
+    }
+  },
+  exec: function() {
+    callCount += 1;
+    return null;
+  }
+};
+var nonWritableLastIndex = {
+  exec: function() {
+    Object.defineProperty(
+      nonWritableLastIndex, 'lastIndex', { writable: false }
+    );
+    callCount += 1;
+    return null;
+  }
+};
+
+callCount = 0;
+assert.throws(Test262Error, function() {
+  RegExp.prototype[Symbol.search].call(poisonedLastIndex);
+});
+assert.sameValue(callCount, 1, 'Match executed ("poisoned" lastIndex)');
+
+callCount = 0;
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(nonWritableLastIndex);
+});
+assert.sameValue(callCount, 1, 'Match executed (non-writable lastIndex)');
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore.js b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore.js
new file mode 100644
index 0000000000..9b18b522df
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/set-lastindex-restore.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: The `lastIndex` value is restored following match execution
+info: >
+    [...]
+    11. Let status be Set(rx, "lastIndex", previousLastIndex, true).
+    [...]
+features: [Symbol.search]
+---*/
+
+var latestValue;
+var fakeRe = {
+  get lastIndex() {
+    return 86;
+  },
+  set lastIndex(_) {
+    latestValue = _;
+  },
+  exec: function() {
+    latestValue = null;
+    return null;
+  }
+};
+
+RegExp.prototype[Symbol.search].call(fakeRe);
+
+assert.sameValue(latestValue, 86);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/success-get-index-err.js b/test/built-ins/RegExp/prototype/Symbol.search/success-get-index-err.js
new file mode 100644
index 0000000000..832ad20cc4
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/success-get-index-err.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: >
+    Behavior when error thrown while accessing `index` property of match result
+info: >
+    [...]
+    14. Return Get(result, "index").
+features: [Symbol.search]
+---*/
+
+var poisonedIndex = {
+  get index() {
+    throw new Test262Error();
+  }
+};
+var fakeRe = {
+  exec: function() {
+    return poisonedIndex;
+  }
+};
+
+assert.throws(Test262Error, function() {
+  RegExp.prototype[Symbol.search].call(fakeRe);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/success-return-val.js b/test/built-ins/RegExp/prototype/Symbol.search/success-return-val.js
new file mode 100644
index 0000000000..d47283603d
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/success-return-val.js
@@ -0,0 +1,15 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.9
+description: Return value following successful match
+info: >
+    [...]
+    14. Return Get(result, "index").
+features: [Symbol.search]
+---*/
+
+assert.sameValue(/a/[Symbol.search]('abc'), 0);
+assert.sameValue(/b/[Symbol.search]('abc'), 1);
+assert.sameValue(/c/[Symbol.search]('abc'), 2);
diff --git a/test/built-ins/RegExp/prototype/Symbol.search/this-val-non-obj.js b/test/built-ins/RegExp/prototype/Symbol.search/this-val-non-obj.js
new file mode 100644
index 0000000000..65f4e83a07
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.search/this-val-non-obj.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The `this` value must be an object
+es6id: 21.2.5.9
+info: >
+    1. Let rx be the this value.
+    2. If Type(rx) is not Object, throw a TypeError exception.
+features: [Symbol.search]
+---*/
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call();
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(undefined);
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(null);
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(true);
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call('string');
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(Symbol.search);
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.search].call(86);
+});
diff --git a/test/built-ins/String/prototype/search/cstm-search-get-err.js b/test/built-ins/String/prototype/search/cstm-search-get-err.js
new file mode 100644
index 0000000000..ae416dd6d6
--- /dev/null
+++ b/test/built-ins/String/prototype/search/cstm-search-get-err.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Behavior when error is thrown accessing @@search property
+es6id: 21.1.3.15
+info: >
+    [...]
+    3. If regexp is neither undefined nor null, then
+       a. Let searcher be GetMethod(regexp, @@search).
+       b. ReturnIfAbrupt(searcher).
+features: [Symbol.search]
+---*/
+
+var poisonedSearch = {};
+Object.defineProperty(poisonedSearch, Symbol.search, {
+  get: function() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  ''.search(poisonedSearch);
+});
diff --git a/test/built-ins/String/prototype/search/cstm-search-invocation.js b/test/built-ins/String/prototype/search/cstm-search-invocation.js
new file mode 100644
index 0000000000..c46937d538
--- /dev/null
+++ b/test/built-ins/String/prototype/search/cstm-search-invocation.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Invocation of @@search property of user-supplied objects
+es6id: 21.1.3.15
+info: >
+    [...]
+    3. If regexp is neither undefined nor null, then
+       a. Let searcher be GetMethod(regexp, @@search).
+       b. ReturnIfAbrupt(searcher).
+       c. If searcher is not undefined, then
+          i. Return Call(searcher, regexp, «O»)
+features: [Symbol.search]
+---*/
+
+var regexp = {};
+var returnVal = {};
+var callCount = 0;
+var thisVal, args;
+
+regexp[Symbol.search] = function() {
+  callCount += 1;
+  thisVal = this;
+  args = arguments;
+  return returnVal;
+};
+
+assert.sameValue('O'.search(regexp), returnVal);
+assert.sameValue(callCount, 1, 'Invokes the method exactly once');
+assert.sameValue(thisVal, regexp);
+assert.notSameValue(args, undefined);
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], 'O');
diff --git a/test/built-ins/String/prototype/search/invoke-builtin-search-searcher-undef.js b/test/built-ins/String/prototype/search/invoke-builtin-search-searcher-undef.js
new file mode 100644
index 0000000000..f6c13090b4
--- /dev/null
+++ b/test/built-ins/String/prototype/search/invoke-builtin-search-searcher-undef.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 Mike Pennisi. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+    Invocation of @@search property of internally-created RegExps when `this` value has an `undefined` @@search property
+es6id: 21.1.3.15
+info: >
+    [...]
+    3. If regexp is neither undefined nor null, then
+       a. Let searcher be GetMethod(regexp, @@search).
+       b. ReturnIfAbrupt(searcher).
+       c. If searcher is not undefined , then
+          [...]
+    [...]
+    6. Let rx be RegExpCreate(regexp, undefined) (see 21.2.3.2.3).
+    7. ReturnIfAbrupt(rx).
+    8. Return Invoke(rx, @@search, «S»).
+features: [Symbol.search]
+---*/
+
+var target = new String('target');
+var originalSearch = RegExp.prototype[Symbol.search];
+var returnVal = {};
+var result, thisVal, args;
+
+target[Symbol.search] = undefined;
+
+// Fail early if the method is undefined. This test's cleanup logic would
+// otherwise install the value `undefined` to the `Symbol.search` property of
+// the built-in prototype.
+assert.notSameValue(originalSearch, undefined);
+
+RegExp.prototype[Symbol.search] = function() {
+  thisVal = this;
+  args = arguments;
+  return returnVal;
+};
+
+try {
+  result = target.search('string source');
+
+  assert(thisVal instanceof RegExp);
+  assert.sameValue(thisVal.source, 'string source');
+  assert.sameValue(thisVal.flags, '');
+  assert.sameValue(args.length, 1);
+  assert.sameValue(args[0], 'target');
+  assert.sameValue(result, returnVal);
+} finally {
+  RegExp.prototype[Symbol.search] = originalSearch;
+}
diff --git a/test/built-ins/String/prototype/search/invoke-builtin-search.js b/test/built-ins/String/prototype/search/invoke-builtin-search.js
new file mode 100644
index 0000000000..bb4c3a8a0f
--- /dev/null
+++ b/test/built-ins/String/prototype/search/invoke-builtin-search.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Invocation of @@search property of internally-created RegExps
+es6id: 21.1.3.15
+info: >
+    [...]
+    6. Let rx be RegExpCreate(regexp, undefined) (see 21.2.3.2.3).
+    7. ReturnIfAbrupt(rx).
+    8. Return Invoke(rx, @@search, «S»).
+features: [Symbol.search]
+---*/
+
+var originalSearch = RegExp.prototype[Symbol.search];
+var returnVal = {};
+var result, thisVal, args;
+
+// Fail early if the method is undefined. This test's cleanup logic would
+// otherwise install the value `undefined` to the `Symbol.search` property of
+// the built-in prototype.
+assert.notSameValue(originalSearch, undefined);
+
+RegExp.prototype[Symbol.search] = function() {
+  thisVal = this;
+  args = arguments;
+  return returnVal;
+};
+
+try {
+  result = 'target'.search('string source');
+
+  assert(thisVal instanceof RegExp);
+  assert.sameValue(thisVal.source, 'string source');
+  assert.sameValue(thisVal.flags, '');
+  assert.sameValue(args.length, 1);
+  assert.sameValue(args[0], 'target');
+  assert.sameValue(result, returnVal);
+} finally {
+  RegExp.prototype[Symbol.search] = originalSearch;
+}
diff --git a/test/built-ins/Symbol/search/prop-desc.js b/test/built-ins/Symbol/search/prop-desc.js
new file mode 100644
index 0000000000..b1dacfc2cd
--- /dev/null
+++ b/test/built-ins/Symbol/search/prop-desc.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 19.4.2.9
+description: >
+    `Symbol.search` property descriptor
+info: >
+    This property has the attributes { [[Writable]]: false, [[Enumerable]]:
+    false, [[Configurable]]: false }.
+includes: [propertyHelper.js]
+features: [Symbol.search]
+---*/
+
+assert.sameValue(typeof Symbol.search, 'symbol');
+verifyNotEnumerable(Symbol, 'search');
+verifyNotWritable(Symbol, 'search');
+verifyNotConfigurable(Symbol, 'search');
-- 
GitLab