-
-
Save anba/d6bf0db9951d0cc8cb02 to your computer and use it in GitHub Desktop.
Unicode RegExp library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2012-2015 André Bargull | |
* Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. | |
* | |
* <https://github.com/anba/es6draft> | |
*/ | |
(function(global) { | |
"use strict"; | |
const { | |
Object, Function, Proxy, Reflect, Set, String, Symbol, SyntaxError | |
} = global; | |
const { | |
getOwnPropertyDescriptor: Reflect_getOwnPropertyDescriptor, | |
getPrototypeOf: Reflect_getPrototypeOf, | |
ownKeys: Reflect_ownKeys, | |
} = Reflect; | |
const { | |
create: Object_create, | |
getOwnPropertyDescriptor: Object_getOwnPropertyDescriptor, | |
is: Object_is, | |
} = Object; | |
const { | |
hasOwnProperty: Object_prototype_hasOwnProperty, | |
toString: Object_prototype_toString, | |
} = Object.prototype; | |
const { | |
toString: Function_prototype_toString, | |
} = Function.prototype; | |
const { | |
includes: String_prototype_includes, | |
} = String.prototype; | |
const { | |
add: Set_prototype_add, | |
delete: Set_prototype_delete, | |
forEach: Set_prototype_forEach, | |
} = Set.prototype; | |
const Set_prototype_size = Reflect_getOwnPropertyDescriptor(Set.prototype, "size").get; | |
const ThrowTypeError = Reflect_getOwnPropertyDescriptor(Function.prototype, "caller").get; | |
const $CallFunction = Function.prototype.call.bind(Function.prototype.call); | |
function IsCallable(o) { | |
try { | |
(new Proxy(o, {apply: () => {}}))(); | |
return true; | |
} catch (e) { | |
return false; | |
} | |
} | |
function IsConstructor(o) { | |
try { | |
new (new Proxy(o, {construct: () => ({})})); | |
return true; | |
} catch (e) { | |
return false; | |
} | |
} | |
function IsPrimitive(v) { | |
switch (typeof v) { | |
case "undefined": | |
case "boolean": | |
case "number": | |
case "string": | |
case "symbol": | |
return true; | |
case "object": | |
return v === null; | |
default: | |
return false; | |
} | |
} | |
function PropertyKeyToString(propertyKey) { | |
return String(propertyKey); | |
} | |
function IsDataPropertyDescriptor(desc) { | |
return $CallFunction(Object_prototype_hasOwnProperty, desc, "value"); | |
} | |
class PropertyKeySet extends null { | |
constructor(keys) { | |
var obj = Object_create(new.target.prototype); | |
obj._set = new Set(); | |
for (let i = 0, len = keys.length; i < len; ++i) { | |
obj.add(keys[i]); | |
} | |
return obj; | |
} | |
add(value) { | |
return $CallFunction(Set_prototype_add, this._set, value); | |
} | |
delete(value) { | |
return $CallFunction(Set_prototype_delete, this._set, value); | |
} | |
forEach(callback) { | |
return $CallFunction(Set_prototype_forEach, this._set, callback); | |
} | |
get size() { | |
return $CallFunction(Set_prototype_size, this._set); | |
} | |
toString() { | |
let s = ""; | |
let n = this.size; | |
this.forEach(value => { | |
s += PropertyKeyToString(value); | |
if (--n) { | |
s += ", "; | |
} | |
}); | |
return `[${s}]`; | |
} | |
} | |
function safeToString(v) { | |
switch (typeof v) { | |
case "undefined": | |
case "boolean": | |
case "string": | |
case "symbol": | |
return String(v); | |
case "number": | |
return v !== 0 ? String(v) : Object_is(v, +0) ? "+0" : "-0"; | |
case "object": | |
if (v === null) { | |
return String(v); | |
} | |
case "function": | |
default: | |
try { | |
return String(v); | |
} catch (e) { | |
try { | |
return $CallFunction(Object_prototype_toString, v); | |
} catch (e) { | |
return "???"; | |
} | |
} | |
} | |
} | |
function formatString(callSite, ...substitutions) { | |
let cooked = Object(callSite); | |
let literalSegments = cooked.length >>> 0; | |
if (literalSegments === 0) { | |
return ""; | |
} | |
let r = ""; | |
for (let nextIndex = 0;; ++nextIndex) { | |
r += cooked[nextIndex]; | |
if (nextIndex + 1 === literalSegments) { | |
return r; | |
} | |
r += safeToString(substitutions[nextIndex]); | |
} | |
} | |
function label(s) { | |
return s !== "" ? s + ": " : ""; | |
} | |
class AssertionError extends Error { | |
get name() { | |
return "AssertionError"; | |
} | |
} | |
function fail(format = "", ...args) { | |
let message = typeof format === "string" ? format : formatString(format, ...args); | |
throw new AssertionError(message); | |
} | |
function assertSame(expected, actual, message = "") { | |
if (!Object_is(expected, actual)) { | |
fail `${label(message)}Expected «${expected}», but got «${actual}»`; | |
} | |
} | |
function assertNotSame(expected, actual, message = "") { | |
if (Object_is(expected, actual)) { | |
fail `${label(message)}Expected not «${expected}»`; | |
} | |
} | |
function assertThrows(expected, f, message = "") { | |
try { | |
f(); | |
} catch (e) { | |
if (e instanceof expected) { | |
return; | |
} | |
if (e instanceof AssertionError) { | |
throw e; | |
} | |
fail `${label(message)}Expected error «${expected.name}», but got «${e}»`; | |
} | |
fail `${label(message)}Expected error «${expected.name}»`; | |
} | |
function assertSyntaxError(code, message = "") { | |
return assertThrows(SyntaxError, () => Function(code), message); | |
} | |
function assertTrue(actual, message = "") { | |
return assertSame(true, actual, message); | |
} | |
function assertFalse(actual, message = "") { | |
return assertSame(false, actual, message); | |
} | |
function assertUndefined(actual, message = "") { | |
return assertSame(void 0, actual, message); | |
} | |
function assertNotUndefined(actual, message = "") { | |
return assertNotSame(void 0, actual, message); | |
} | |
function assertNull(actual, message = "") { | |
return assertSame(null, actual, message); | |
} | |
function assertNotNull(actual, message = "") { | |
return assertNotSame(null, actual, message); | |
} | |
function assertInstanceOf(constructor, value, message = `Is an instance of ${constructor.name}`) { | |
return assertTrue(value instanceof constructor, message); | |
} | |
function assertCallable(o, message = "Is a [[Callable]] object") { | |
return assertTrue(IsCallable(o), message); | |
} | |
function assertNotCallable(o, message = "Is not a [[Callable]] object") { | |
return assertFalse(IsCallable(o), message); | |
} | |
function assertConstructor(o, message = "Is a [[Constructor]] object") { | |
return assertTrue(IsConstructor(o), message); | |
} | |
function assertNotConstructor(o, message = "Is not a [[Constructor]] object") { | |
return assertFalse(IsConstructor(o), message); | |
} | |
function assertDataProperty(objectOrValue, propertyKey, {value, writable, enumerable, configurable}) { | |
let desc = Object_getOwnPropertyDescriptor(objectOrValue, propertyKey); | |
assertNotUndefined(desc, `${PropertyKeyToString(propertyKey)} not found`); | |
assertTrue(IsDataPropertyDescriptor(desc), `${PropertyKeyToString(propertyKey)}.[[Value]] present`); | |
assertSame(value, desc.value, `${PropertyKeyToString(propertyKey)}.[[Value]]`); | |
assertSame(writable, desc.writable, `${PropertyKeyToString(propertyKey)}.[[Writable]]`); | |
assertSame(enumerable, desc.enumerable, `${PropertyKeyToString(propertyKey)}.[[Enumerable]]`); | |
assertSame(configurable, desc.configurable, `${PropertyKeyToString(propertyKey)}.[[Configurable]]`); | |
} | |
// Internal: Similar to assertDataProperty, except assertEquals is used for "value" | |
function assertDataPropertyEquals(objectOrValue, propertyKey, {value, writable, enumerable, configurable}) { | |
let desc = Object_getOwnPropertyDescriptor(objectOrValue, propertyKey); | |
assertNotUndefined(desc, `${PropertyKeyToString(propertyKey)} not found`); | |
assertTrue(IsDataPropertyDescriptor(desc), `${PropertyKeyToString(propertyKey)}.[[Value]] present`); | |
assertEquals(value, desc.value, `${PropertyKeyToString(propertyKey)}.[[Value]]`); | |
assertSame(writable, desc.writable, `${PropertyKeyToString(propertyKey)}.[[Writable]]`); | |
assertSame(enumerable, desc.enumerable, `${PropertyKeyToString(propertyKey)}.[[Enumerable]]`); | |
assertSame(configurable, desc.configurable, `${PropertyKeyToString(propertyKey)}.[[Configurable]]`); | |
} | |
function assertAccessorProperty(objectOrValue, propertyKey, {get, set, enumerable, configurable}) { | |
let desc = Object_getOwnPropertyDescriptor(objectOrValue, propertyKey); | |
assertNotUndefined(desc, `${PropertyKeyToString(propertyKey)} not found`); | |
assertFalse(IsDataPropertyDescriptor(desc), `${PropertyKeyToString(propertyKey)}.[[Value]] present`); | |
assertSame(get, desc.get, `${PropertyKeyToString(propertyKey)}.[[Get]]`); | |
assertSame(set, desc.set, `${PropertyKeyToString(propertyKey)}.[[Set]]`); | |
assertSame(enumerable, desc.enumerable, `${PropertyKeyToString(propertyKey)}.[[Enumerable]]`); | |
assertSame(configurable, desc.configurable, `${PropertyKeyToString(propertyKey)}.[[Configurable]]`); | |
} | |
function assertBuiltinFunction(fun, name, arity) { | |
assertSame("function", typeof fun); | |
assertCallable(fun); | |
assertNotConstructor(fun); | |
assertSame(Function.prototype, Reflect_getPrototypeOf(fun), `${name}.[[Prototype]]`); | |
assertDataProperty(fun, "length", {value: arity, writable: false, enumerable: false, configurable: true}); | |
if (name !== void 0) { | |
assertDataProperty(fun, "name", {value: name, writable: false, enumerable: false, configurable: true}); | |
} else { | |
// anonymous function | |
assertUndefined(Reflect_getOwnPropertyDescriptor(fun, "name")); | |
} | |
assertUndefined(Reflect_getOwnPropertyDescriptor(fun, "arguments")); | |
assertUndefined(Reflect_getOwnPropertyDescriptor(fun, "caller")); | |
} | |
function assertNativeFunction(fun, name, arity) { | |
assertBuiltinFunction(fun, name, arity); | |
let source = $CallFunction(Function_prototype_toString, fun); | |
assertTrue($CallFunction(String_prototype_includes, source, "native code")); | |
} | |
function assertBuiltinConstructor(fun, name, arity) { | |
assertSame("function", typeof fun); | |
assertCallable(fun); | |
assertConstructor(fun); | |
assertSame(Function.prototype, Reflect_getPrototypeOf(fun), `${name}.[[Prototype]]`); | |
assertDataProperty(fun, "length", {value: arity, writable: false, enumerable: false, configurable: true}); | |
assertDataProperty(fun, "name", {value: name, writable: false, enumerable: false, configurable: true}); | |
assertUndefined(Reflect_getOwnPropertyDescriptor(fun, "arguments")); | |
assertUndefined(Reflect_getOwnPropertyDescriptor(fun, "caller")); | |
} | |
function assertBuiltinPrototype(o, proto = Object.prototype) { | |
if (o === Function.prototype) { | |
assertSame("function", typeof o); | |
assertCallable(o); | |
} else { | |
assertSame("object", typeof o); | |
assertNotCallable(o); | |
} | |
assertNotConstructor(o); | |
assertSame(proto, Reflect_getPrototypeOf(o), `[[Prototype]]`); | |
} | |
function assertEquals(expected, actual, message = "") { | |
if (IsPrimitive(expected)) { | |
return assertSame(expected, actual, message); | |
} | |
assertNotNull(actual, message); | |
assertSame(typeof expected, typeof actual, message); | |
if (Object_is(expected, actual)) { | |
return; | |
} | |
let expectedOwnKeys = Reflect_ownKeys(expected); | |
let actualOwnKeys = Reflect_ownKeys(actual); | |
let actualOwnKeysSet = new PropertyKeySet(actualOwnKeys); | |
for (let i = 0, len = expectedOwnKeys.length; i < len; ++i) { | |
let propertyKey = expectedOwnKeys[i]; | |
let actualHas = actualOwnKeysSet.delete(propertyKey); | |
assertTrue(actualHas, `${PropertyKeyToString(propertyKey)} not present`); | |
let expectedDesc = Reflect_getOwnPropertyDescriptor(expected, propertyKey); | |
assertNotUndefined(expectedDesc, `${PropertyKeyToString(propertyKey)} not found`); | |
if (IsDataPropertyDescriptor(expectedDesc)) { | |
assertDataPropertyEquals(actual, propertyKey, expectedDesc); | |
} else { | |
assertAccessorProperty(actual, propertyKey, expectedDesc); | |
} | |
} | |
assertSame(0, actualOwnKeysSet.size, actualOwnKeysSet); | |
return assertEquals(Reflect_getPrototypeOf(expected), Reflect_getPrototypeOf(actual)); | |
} | |
global.Assert = { | |
AssertionError, | |
fail, | |
assertSame, | |
assertNotSame, | |
assertThrows, | |
assertSyntaxError, | |
assertTrue, | |
assertFalse, | |
assertUndefined, | |
assertNotUndefined, | |
assertNull, | |
assertNotNull, | |
assertInstanceOf, | |
assertCallable, | |
assertNotCallable, | |
assertConstructor, | |
assertNotConstructor, | |
assertDataProperty, | |
assertAccessorProperty, | |
assertBuiltinFunction, | |
assertNativeFunction, | |
assertBuiltinConstructor, | |
assertBuiltinPrototype, | |
assertEquals, | |
}; | |
})(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
loadRelativeToScript("./assert.js"); | |
loadRelativeToScript("./range.js"); | |
loadRelativeToScript("./transformers.js"); | |
loadRelativeToScript("./unicode_case_folding.js"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2012-2015 André Bargull | |
* Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. | |
* | |
* <https://github.com/anba/es6draft> | |
*/ | |
function range(start, end, increment = 1) { | |
const { assertTrue } = Assert; | |
assertTrue(typeof start == 'number' || typeof start == 'string' && start.length == 1); | |
assertTrue(typeof end == 'number' || typeof end == 'string' && start.length == 1); | |
assertTrue(typeof increment == 'number'); | |
start = typeof start == 'string' ? start.codePointAt(0) : +start; | |
end = typeof end == 'string' ? end.codePointAt(0) : +end; | |
assertTrue(start <= end); | |
assertTrue(increment > 0); | |
class Range { | |
constructor(start, end, increment) { | |
Object.assign(this, {start, end, increment}); | |
this.string = String.fromCodePoint(...this); | |
} | |
toString() { | |
return this.string; | |
} | |
startR() { | |
return new Range(this.start, this.start, 1); | |
} | |
endR() { | |
return new Range(this.end, this.end, 1); | |
} | |
[Symbol.iterator]() { | |
return new class RangeIterator { | |
constructor(range) { | |
Object.assign(this, {range, value: range.start}); | |
} | |
next() { | |
let value = this.value; | |
if (value <= this.range.end) { | |
this.value += this.range.increment; | |
return {done: false, value}; | |
} | |
return {done: true, value}; | |
} | |
}(this); | |
} | |
} | |
return new Range(start, end, increment); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2012-2015 André Bargull | |
* Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. | |
* | |
* <https://github.com/anba/es6draft> | |
*/ | |
const Transformers = (() => { | |
function toStr(number, radix, pad) { | |
let s = number.toString(radix); | |
return "0".repeat(pad - s.length) + s; | |
} | |
function rangeLength(range) { | |
return ~~((range.end - range.start) / range.increment) + 1; | |
} | |
function identity(range) { | |
return String(range); | |
} | |
function toCharClass(pattern, range) { | |
return `[${pattern}]{${rangeLength(range)}}`; | |
} | |
function toNegatedCharClass(pattern, range) { | |
return `[^${pattern}]{${rangeLength(range)}}`; | |
} | |
function toCharClassRange(t, range) { | |
return `[${t(range.startR())}-${t(range.endR())}]{${rangeLength(range)}}`; | |
} | |
function toNegatedCharClassRange(t, range) { | |
return `[^${t(range.startR())}-${t(range.endR())}]{${rangeLength(range)}}`; | |
} | |
function toIdentityEscape(range) { | |
let result = ""; | |
for (let cp of String(range)) { | |
if ((cp >= '0' && cp <= '9') || (cp >= 'A' && cp <= 'Z') || (cp >= 'a' && cp <= 'z')) { | |
result += cp; | |
} else { | |
result += `\\${cp}`; | |
} | |
} | |
return result; | |
} | |
function toOctalEscape(range) { | |
let result = ""; | |
for (let cp of range) { | |
result += `\\${toStr(cp, 8, 3)}`; | |
} | |
return result; | |
} | |
function toHexEscape(range) { | |
let result = ""; | |
for (let cp of range) { | |
result += `\\x${toStr(cp, 16, 2)}`; | |
} | |
return result; | |
} | |
function toUnicodeEscape(range) { | |
let result = ""; | |
for (let cp of range) { | |
result += `\\u${toStr(cp, 16, 4)}`; | |
} | |
return result; | |
} | |
function toExtendedUnicodeEscape(range) { | |
let result = ""; | |
for (let cp of range) { | |
result += `\\u{${cp.toString(16)}}`; | |
} | |
return result; | |
} | |
const combine = (f, g) => (...args) => f(g(...args), ...args); | |
const combine2 = (f, g) => (...args) => f(g, ...args); | |
return { | |
identity, toIdentityEscape, toOctalEscape, toHexEscape, toUnicodeEscape, toExtendedUnicodeEscape, | |
charClass: { | |
identity: combine(toCharClass, identity), | |
toIdentityEscape: combine(toCharClass, toIdentityEscape), | |
toOctalEscape: combine(toCharClass, toOctalEscape), | |
toHexEscape: combine(toCharClass, toHexEscape), | |
toUnicodeEscape: combine(toCharClass, toUnicodeEscape), | |
toExtendedUnicodeEscape: combine(toCharClass, toExtendedUnicodeEscape), | |
negated: { | |
identity: combine(toNegatedCharClass, identity), | |
toIdentityEscape: combine(toNegatedCharClass, toIdentityEscape), | |
toOctalEscape: combine(toNegatedCharClass, toOctalEscape), | |
toHexEscape: combine(toNegatedCharClass, toHexEscape), | |
toUnicodeEscape: combine(toNegatedCharClass, toUnicodeEscape), | |
toExtendedUnicodeEscape: combine(toNegatedCharClass, toExtendedUnicodeEscape), | |
}, | |
}, | |
charClassRange: { | |
identity: combine2(toCharClassRange, identity), | |
toIdentityEscape: combine2(toCharClassRange, toIdentityEscape), | |
toOctalEscape: combine2(toCharClassRange, toOctalEscape), | |
toHexEscape: combine2(toCharClassRange, toHexEscape), | |
toUnicodeEscape: combine2(toCharClassRange, toUnicodeEscape), | |
toExtendedUnicodeEscape: combine2(toCharClassRange, toExtendedUnicodeEscape), | |
negated: { | |
identity: combine2(toNegatedCharClassRange, identity), | |
toIdentityEscape: combine2(toNegatedCharClassRange, toIdentityEscape), | |
toOctalEscape: combine2(toNegatedCharClassRange, toOctalEscape), | |
toHexEscape: combine2(toNegatedCharClassRange, toHexEscape), | |
toUnicodeEscape: combine2(toNegatedCharClassRange, toUnicodeEscape), | |
toExtendedUnicodeEscape: combine2(toNegatedCharClassRange, toExtendedUnicodeEscape), | |
}, | |
}, | |
}; | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2012-2015 André Bargull | |
* Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. | |
* | |
* <https://github.com/anba/es6draft> | |
*/ | |
function UnicodeCaseFolding(test, {latin, basic, supplementary}) { | |
test(range('A', 'Z'), range('a', 'z'), latin); | |
// Generated from CaseFolding-6.3.0.txt | |
test(range(0x41, 0x49, 1), range(0x61, 0x69, 1), latin); | |
test(range(0x4a, 0x5a, 1), range(0x6a, 0x7a, 1), latin); | |
test(range(0xb5, 0xb5, 1), range(0x3bc, 0x3bc, 1), basic); | |
test(range(0xc0, 0xd6, 1), range(0xe0, 0xf6, 1), latin); | |
test(range(0xd8, 0xde, 1), range(0xf8, 0xfe, 1), latin); | |
test(range(0x100, 0x12e, 2), range(0x101, 0x12f, 2), basic); | |
test(range(0x132, 0x136, 2), range(0x133, 0x137, 2), basic); | |
test(range(0x139, 0x147, 2), range(0x13a, 0x148, 2), basic); | |
test(range(0x14a, 0x176, 2), range(0x14b, 0x177, 2), basic); | |
test(range(0x178, 0x178, 1), range(0xff, 0xff, 1), basic); | |
test(range(0x179, 0x17d, 2), range(0x17a, 0x17e, 2), basic); | |
test(range(0x17f, 0x17f, 1), range(0x73, 0x73, 1), basic, {unicode: true}); | |
test(range(0x181, 0x181, 1), range(0x253, 0x253, 1), basic); | |
test(range(0x182, 0x184, 2), range(0x183, 0x185, 2), basic); | |
test(range(0x186, 0x186, 1), range(0x254, 0x254, 1), basic); | |
test(range(0x187, 0x187, 1), range(0x188, 0x188, 1), basic); | |
test(range(0x189, 0x18a, 1), range(0x256, 0x257, 1), basic); | |
test(range(0x18b, 0x18b, 1), range(0x18c, 0x18c, 1), basic); | |
test(range(0x18e, 0x18e, 1), range(0x1dd, 0x1dd, 1), basic); | |
test(range(0x18f, 0x18f, 1), range(0x259, 0x259, 1), basic); | |
test(range(0x190, 0x190, 1), range(0x25b, 0x25b, 1), basic); | |
test(range(0x191, 0x191, 1), range(0x192, 0x192, 1), basic); | |
test(range(0x193, 0x193, 1), range(0x260, 0x260, 1), basic); | |
test(range(0x194, 0x194, 1), range(0x263, 0x263, 1), basic); | |
test(range(0x196, 0x196, 1), range(0x269, 0x269, 1), basic); | |
test(range(0x197, 0x197, 1), range(0x268, 0x268, 1), basic); | |
test(range(0x198, 0x198, 1), range(0x199, 0x199, 1), basic); | |
test(range(0x19c, 0x19c, 1), range(0x26f, 0x26f, 1), basic); | |
test(range(0x19d, 0x19d, 1), range(0x272, 0x272, 1), basic); | |
test(range(0x19f, 0x19f, 1), range(0x275, 0x275, 1), basic); | |
test(range(0x1a0, 0x1a4, 2), range(0x1a1, 0x1a5, 2), basic); | |
test(range(0x1a6, 0x1a6, 1), range(0x280, 0x280, 1), basic); | |
test(range(0x1a7, 0x1a7, 1), range(0x1a8, 0x1a8, 1), basic); | |
test(range(0x1a9, 0x1a9, 1), range(0x283, 0x283, 1), basic); | |
test(range(0x1ac, 0x1ac, 1), range(0x1ad, 0x1ad, 1), basic); | |
test(range(0x1ae, 0x1ae, 1), range(0x288, 0x288, 1), basic); | |
test(range(0x1af, 0x1af, 1), range(0x1b0, 0x1b0, 1), basic); | |
test(range(0x1b1, 0x1b2, 1), range(0x28a, 0x28b, 1), basic); | |
test(range(0x1b3, 0x1b5, 2), range(0x1b4, 0x1b6, 2), basic); | |
test(range(0x1b7, 0x1b7, 1), range(0x292, 0x292, 1), basic); | |
test(range(0x1b8, 0x1bc, 4), range(0x1b9, 0x1bd, 4), basic); | |
test(range(0x1c4, 0x1c4, 1), range(0x1c6, 0x1c6, 1), basic); | |
test(range(0x1c5, 0x1c5, 1), range(0x1c6, 0x1c6, 1), basic); | |
test(range(0x1c7, 0x1c7, 1), range(0x1c9, 0x1c9, 1), basic); | |
test(range(0x1c8, 0x1c8, 1), range(0x1c9, 0x1c9, 1), basic); | |
test(range(0x1ca, 0x1ca, 1), range(0x1cc, 0x1cc, 1), basic); | |
test(range(0x1cb, 0x1db, 2), range(0x1cc, 0x1dc, 2), basic); | |
test(range(0x1de, 0x1ee, 2), range(0x1df, 0x1ef, 2), basic); | |
test(range(0x1f1, 0x1f1, 1), range(0x1f3, 0x1f3, 1), basic); | |
test(range(0x1f2, 0x1f4, 2), range(0x1f3, 0x1f5, 2), basic); | |
test(range(0x1f6, 0x1f6, 1), range(0x195, 0x195, 1), basic); | |
test(range(0x1f7, 0x1f7, 1), range(0x1bf, 0x1bf, 1), basic); | |
test(range(0x1f8, 0x21e, 2), range(0x1f9, 0x21f, 2), basic); | |
test(range(0x220, 0x220, 1), range(0x19e, 0x19e, 1), basic); | |
test(range(0x222, 0x232, 2), range(0x223, 0x233, 2), basic); | |
test(range(0x23a, 0x23a, 1), range(0x2c65, 0x2c65, 1), basic); | |
test(range(0x23b, 0x23b, 1), range(0x23c, 0x23c, 1), basic); | |
test(range(0x23d, 0x23d, 1), range(0x19a, 0x19a, 1), basic); | |
test(range(0x23e, 0x23e, 1), range(0x2c66, 0x2c66, 1), basic); | |
test(range(0x241, 0x241, 1), range(0x242, 0x242, 1), basic); | |
test(range(0x243, 0x243, 1), range(0x180, 0x180, 1), basic); | |
test(range(0x244, 0x244, 1), range(0x289, 0x289, 1), basic); | |
test(range(0x245, 0x245, 1), range(0x28c, 0x28c, 1), basic); | |
test(range(0x246, 0x24e, 2), range(0x247, 0x24f, 2), basic); | |
test(range(0x345, 0x345, 1), range(0x3b9, 0x3b9, 1), basic); | |
test(range(0x370, 0x372, 2), range(0x371, 0x373, 2), basic); | |
test(range(0x376, 0x376, 1), range(0x377, 0x377, 1), basic); | |
test(range(0x386, 0x386, 1), range(0x3ac, 0x3ac, 1), basic); | |
test(range(0x388, 0x38a, 1), range(0x3ad, 0x3af, 1), basic); | |
test(range(0x38c, 0x38c, 1), range(0x3cc, 0x3cc, 1), basic); | |
test(range(0x38e, 0x38f, 1), range(0x3cd, 0x3ce, 1), basic); | |
test(range(0x391, 0x3a1, 1), range(0x3b1, 0x3c1, 1), basic); | |
test(range(0x3a3, 0x3ab, 1), range(0x3c3, 0x3cb, 1), basic); | |
test(range(0x3c2, 0x3c2, 1), range(0x3c3, 0x3c3, 1), basic); | |
test(range(0x3cf, 0x3cf, 1), range(0x3d7, 0x3d7, 1), basic); | |
test(range(0x3d0, 0x3d0, 1), range(0x3b2, 0x3b2, 1), basic); | |
test(range(0x3d1, 0x3d1, 1), range(0x3b8, 0x3b8, 1), basic); | |
test(range(0x3d5, 0x3d5, 1), range(0x3c6, 0x3c6, 1), basic); | |
test(range(0x3d6, 0x3d6, 1), range(0x3c0, 0x3c0, 1), basic); | |
test(range(0x3d8, 0x3ee, 2), range(0x3d9, 0x3ef, 2), basic); | |
test(range(0x3f0, 0x3f0, 1), range(0x3ba, 0x3ba, 1), basic); | |
test(range(0x3f1, 0x3f1, 1), range(0x3c1, 0x3c1, 1), basic); | |
test(range(0x3f4, 0x3f4, 1), range(0x3b8, 0x3b8, 1), basic, {unicode: true}); | |
test(range(0x3f5, 0x3f5, 1), range(0x3b5, 0x3b5, 1), basic); | |
test(range(0x3f7, 0x3f7, 1), range(0x3f8, 0x3f8, 1), basic); | |
test(range(0x3f9, 0x3f9, 1), range(0x3f2, 0x3f2, 1), basic); | |
test(range(0x3fa, 0x3fa, 1), range(0x3fb, 0x3fb, 1), basic); | |
test(range(0x3fd, 0x3ff, 1), range(0x37b, 0x37d, 1), basic); | |
test(range(0x400, 0x40f, 1), range(0x450, 0x45f, 1), basic); | |
test(range(0x410, 0x42f, 1), range(0x430, 0x44f, 1), basic); | |
test(range(0x460, 0x480, 2), range(0x461, 0x481, 2), basic); | |
test(range(0x48a, 0x4be, 2), range(0x48b, 0x4bf, 2), basic); | |
test(range(0x4c0, 0x4c0, 1), range(0x4cf, 0x4cf, 1), basic); | |
test(range(0x4c1, 0x4cd, 2), range(0x4c2, 0x4ce, 2), basic); | |
test(range(0x4d0, 0x526, 2), range(0x4d1, 0x527, 2), basic); | |
test(range(0x531, 0x556, 1), range(0x561, 0x586, 1), basic); | |
test(range(0x10a0, 0x10c5, 1), range(0x2d00, 0x2d25, 1), basic); | |
test(range(0x10c7, 0x10cd, 6), range(0x2d27, 0x2d2d, 6), basic); | |
test(range(0x1e00, 0x1e94, 2), range(0x1e01, 0x1e95, 2), basic); | |
test(range(0x1e9b, 0x1e9b, 1), range(0x1e61, 0x1e61, 1), basic); | |
test(range(0x1e9e, 0x1e9e, 1), range(0xdf, 0xdf, 1), basic, {unicode: true}); | |
test(range(0x1ea0, 0x1efe, 2), range(0x1ea1, 0x1eff, 2), basic); | |
test(range(0x1f08, 0x1f0f, 1), range(0x1f00, 0x1f07, 1), basic); | |
test(range(0x1f18, 0x1f1d, 1), range(0x1f10, 0x1f15, 1), basic); | |
test(range(0x1f28, 0x1f2f, 1), range(0x1f20, 0x1f27, 1), basic); | |
test(range(0x1f38, 0x1f3f, 1), range(0x1f30, 0x1f37, 1), basic); | |
test(range(0x1f48, 0x1f4d, 1), range(0x1f40, 0x1f45, 1), basic); | |
test(range(0x1f59, 0x1f5f, 2), range(0x1f51, 0x1f57, 2), basic); | |
test(range(0x1f68, 0x1f6f, 1), range(0x1f60, 0x1f67, 1), basic); | |
test(range(0x1f88, 0x1f88, 1), range(0x1f80, 0x1f80, 1), basic); | |
test(range(0x1f89, 0x1f89, 1), range(0x1f81, 0x1f81, 1), basic); | |
test(range(0x1f8a, 0x1f8a, 1), range(0x1f82, 0x1f82, 1), basic); | |
test(range(0x1f8b, 0x1f8b, 1), range(0x1f83, 0x1f83, 1), basic); | |
test(range(0x1f8c, 0x1f8c, 1), range(0x1f84, 0x1f84, 1), basic); | |
test(range(0x1f8d, 0x1f8d, 1), range(0x1f85, 0x1f85, 1), basic); | |
test(range(0x1f8e, 0x1f8e, 1), range(0x1f86, 0x1f86, 1), basic); | |
test(range(0x1f8f, 0x1f8f, 1), range(0x1f87, 0x1f87, 1), basic); | |
test(range(0x1f98, 0x1f98, 1), range(0x1f90, 0x1f90, 1), basic); | |
test(range(0x1f99, 0x1f99, 1), range(0x1f91, 0x1f91, 1), basic); | |
test(range(0x1f9a, 0x1f9a, 1), range(0x1f92, 0x1f92, 1), basic); | |
test(range(0x1f9b, 0x1f9b, 1), range(0x1f93, 0x1f93, 1), basic); | |
test(range(0x1f9c, 0x1f9c, 1), range(0x1f94, 0x1f94, 1), basic); | |
test(range(0x1f9d, 0x1f9d, 1), range(0x1f95, 0x1f95, 1), basic); | |
test(range(0x1f9e, 0x1f9e, 1), range(0x1f96, 0x1f96, 1), basic); | |
test(range(0x1f9f, 0x1f9f, 1), range(0x1f97, 0x1f97, 1), basic); | |
test(range(0x1fa8, 0x1fa8, 1), range(0x1fa0, 0x1fa0, 1), basic); | |
test(range(0x1fa9, 0x1fa9, 1), range(0x1fa1, 0x1fa1, 1), basic); | |
test(range(0x1faa, 0x1faa, 1), range(0x1fa2, 0x1fa2, 1), basic); | |
test(range(0x1fab, 0x1fab, 1), range(0x1fa3, 0x1fa3, 1), basic); | |
test(range(0x1fac, 0x1fac, 1), range(0x1fa4, 0x1fa4, 1), basic); | |
test(range(0x1fad, 0x1fad, 1), range(0x1fa5, 0x1fa5, 1), basic); | |
test(range(0x1fae, 0x1fae, 1), range(0x1fa6, 0x1fa6, 1), basic); | |
test(range(0x1faf, 0x1faf, 1), range(0x1fa7, 0x1fa7, 1), basic); | |
test(range(0x1fb8, 0x1fb9, 1), range(0x1fb0, 0x1fb1, 1), basic); | |
test(range(0x1fba, 0x1fbb, 1), range(0x1f70, 0x1f71, 1), basic); | |
test(range(0x1fbc, 0x1fbc, 1), range(0x1fb3, 0x1fb3, 1), basic); | |
test(range(0x1fbe, 0x1fbe, 1), range(0x3b9, 0x3b9, 1), basic); | |
test(range(0x1fc8, 0x1fcb, 1), range(0x1f72, 0x1f75, 1), basic); | |
test(range(0x1fcc, 0x1fcc, 1), range(0x1fc3, 0x1fc3, 1), basic); | |
test(range(0x1fd8, 0x1fd9, 1), range(0x1fd0, 0x1fd1, 1), basic); | |
test(range(0x1fda, 0x1fdb, 1), range(0x1f76, 0x1f77, 1), basic); | |
test(range(0x1fe8, 0x1fe9, 1), range(0x1fe0, 0x1fe1, 1), basic); | |
test(range(0x1fea, 0x1feb, 1), range(0x1f7a, 0x1f7b, 1), basic); | |
test(range(0x1fec, 0x1fec, 1), range(0x1fe5, 0x1fe5, 1), basic); | |
test(range(0x1ff8, 0x1ff9, 1), range(0x1f78, 0x1f79, 1), basic); | |
test(range(0x1ffa, 0x1ffb, 1), range(0x1f7c, 0x1f7d, 1), basic); | |
test(range(0x1ffc, 0x1ffc, 1), range(0x1ff3, 0x1ff3, 1), basic); | |
test(range(0x2126, 0x2126, 1), range(0x3c9, 0x3c9, 1), basic, {unicode: true}); | |
test(range(0x212a, 0x212a, 1), range(0x6b, 0x6b, 1), basic, {unicode: true}); | |
test(range(0x212b, 0x212b, 1), range(0xe5, 0xe5, 1), basic, {unicode: true}); | |
test(range(0x2132, 0x2132, 1), range(0x214e, 0x214e, 1), basic); | |
test(range(0x2160, 0x216f, 1), range(0x2170, 0x217f, 1), basic); | |
test(range(0x2183, 0x2183, 1), range(0x2184, 0x2184, 1), basic); | |
test(range(0x24b6, 0x24cf, 1), range(0x24d0, 0x24e9, 1), basic); | |
test(range(0x2c00, 0x2c2e, 1), range(0x2c30, 0x2c5e, 1), basic); | |
test(range(0x2c60, 0x2c60, 1), range(0x2c61, 0x2c61, 1), basic); | |
test(range(0x2c62, 0x2c62, 1), range(0x26b, 0x26b, 1), basic); | |
test(range(0x2c63, 0x2c63, 1), range(0x1d7d, 0x1d7d, 1), basic); | |
test(range(0x2c64, 0x2c64, 1), range(0x27d, 0x27d, 1), basic); | |
test(range(0x2c67, 0x2c6b, 2), range(0x2c68, 0x2c6c, 2), basic); | |
test(range(0x2c6d, 0x2c6d, 1), range(0x251, 0x251, 1), basic); | |
test(range(0x2c6e, 0x2c6e, 1), range(0x271, 0x271, 1), basic); | |
test(range(0x2c6f, 0x2c6f, 1), range(0x250, 0x250, 1), basic); | |
test(range(0x2c70, 0x2c70, 1), range(0x252, 0x252, 1), basic); | |
test(range(0x2c72, 0x2c75, 3), range(0x2c73, 0x2c76, 3), basic); | |
test(range(0x2c7e, 0x2c7f, 1), range(0x23f, 0x240, 1), basic); | |
test(range(0x2c80, 0x2ce2, 2), range(0x2c81, 0x2ce3, 2), basic); | |
test(range(0x2ceb, 0x2ced, 2), range(0x2cec, 0x2cee, 2), basic); | |
test(range(0x2cf2, 0xa640, 31054), range(0x2cf3, 0xa641, 31054), basic); | |
test(range(0xa642, 0xa66c, 2), range(0xa643, 0xa66d, 2), basic); | |
test(range(0xa680, 0xa696, 2), range(0xa681, 0xa697, 2), basic); | |
test(range(0xa722, 0xa72e, 2), range(0xa723, 0xa72f, 2), basic); | |
test(range(0xa732, 0xa76e, 2), range(0xa733, 0xa76f, 2), basic); | |
test(range(0xa779, 0xa77b, 2), range(0xa77a, 0xa77c, 2), basic); | |
test(range(0xa77d, 0xa77d, 1), range(0x1d79, 0x1d79, 1), basic); | |
test(range(0xa77e, 0xa786, 2), range(0xa77f, 0xa787, 2), basic); | |
test(range(0xa78b, 0xa78b, 1), range(0xa78c, 0xa78c, 1), basic); | |
test(range(0xa78d, 0xa78d, 1), range(0x265, 0x265, 1), basic); | |
test(range(0xa790, 0xa792, 2), range(0xa791, 0xa793, 2), basic); | |
test(range(0xa7a0, 0xa7a8, 2), range(0xa7a1, 0xa7a9, 2), basic); | |
test(range(0xa7aa, 0xa7aa, 1), range(0x266, 0x266, 1), basic); | |
test(range(0xff21, 0xff3a, 1), range(0xff41, 0xff5a, 1), basic); | |
test(range(0x10400, 0x10427, 1), range(0x10428, 0x1044f, 1), supplementary); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment