| |
| function shouldBe(actual, expected) { |
| if (actual !== expected) |
| throw new Error('bad value: ' + actual); |
| } |
| |
| function shouldThrow(func, expected) { |
| var error = null; |
| try { |
| func(); |
| } catch (e) { |
| error = e; |
| } |
| if (!error) |
| throw new Error('not thrown'); |
| shouldBe(String(error), expected); |
| } |
| |
| var errorKey = { |
| toString() { |
| throw new Error('out'); |
| } |
| }; |
| var string = 'Cocoa, Cappuccino, Rize, Matcha, Kilimanjaro'; |
| |
| shouldThrow(function () { |
| String.prototype.search.call(null, /Cocoa/); |
| }, "TypeError: String.prototype.search requires that |this| not be null or undefined"); |
| |
| shouldThrow(function () { |
| String.prototype.search.call(undefined, /Cocoa/); |
| }, "TypeError: String.prototype.search requires that |this| not be null or undefined"); |
| |
| shouldThrow(function () { |
| string.search(errorKey); |
| }, "Error: out"); |
| |
| shouldBe('Cocoa'.search(/Cocoa/), 0); |
| |
| shouldBe(string.search(/Rize/), 19); |
| shouldBe(string.search('Rize'), 19); |
| shouldBe(string.search(/Matcha/), 25); |
| shouldBe(string.search('Matcha'), 25); |
| |
| shouldBe(' undefined'.search(), 0); |
| shouldBe(' undefined'.search('undefined'), 4); |
| |
| shouldBe((/Cocoa/)[Symbol.search]('Cocoa'), 0); |
| |
| var primitives = [ |
| '', |
| 'string', |
| null, |
| undefined, |
| 42, |
| Symbol('Cocoa'), |
| ]; |
| |
| for (var primitive of primitives) { |
| shouldThrow(function () { |
| RegExp.prototype[Symbol.search].call(primitive) |
| }, 'TypeError: RegExp.prototype.@@search requires that |this| be an Object'); |
| } |
| |
| shouldThrow(function () { |
| /Cocoa/[Symbol.search](errorKey); |
| }, "Error: out"); |
| |
| |
| function testRegExpSearch(regexp, string, result, lastIndex) { |
| shouldBe(regexp[Symbol.search](string), result); |
| shouldBe(regexp.lastIndex, lastIndex); |
| } |
| |
| function testSearch(regexp, string, result, lastIndex) { |
| shouldBe(string.search(regexp), result); |
| shouldBe(regexp.lastIndex, lastIndex); |
| } |
| |
| function testBoth(regexp, string, result, lastIndex) { |
| testSearch(regexp, string, result, lastIndex); |
| testRegExpSearch(regexp, string, result, lastIndex); |
| } |
| |
| var cocoa = /Cocoa/; |
| cocoa.lastIndex = 20; |
| testBoth(cocoa, 'Cocoa', 0, 20); |
| testBoth(cocoa, ' Cocoa', 2, 20); |
| testBoth(cocoa, ' ', -1, 20); |
| |
| var multibyte = /ココア/; |
| multibyte.lastIndex = 20; |
| testBoth(multibyte, 'ココア', 0, 20); |
| testBoth(multibyte, ' Cocoa', -1, 20); |
| testBoth(multibyte, 'カプチーノ', -1, 20); |
| |
| function alwaysUnmatch(string) { |
| return -1; |
| } |
| |
| var regexp = new RegExp('ココア'); |
| regexp[Symbol.search] = alwaysUnmatch; |
| shouldBe(regexp[Symbol.search], alwaysUnmatch); |
| testBoth(regexp, 'ココア', -1, 0); |