Created
September 6, 2017 07:12
-
-
Save rattrayalex/2ec894c546f98627bcfc78b35e4426be to your computer and use it in GitHub Desktop.
Example Match Polyfill with "tests"
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
if (!Symbol.matches) { | |
const DEFINE_PROPERTY = "defineProperty"; | |
// define Symbol.matches | |
Object[DEFINE_PROPERTY](Symbol, "matches", { | |
configurable: false, | |
writable: false, | |
value: Symbol("matches"), | |
}); | |
function defineMatch(O, fn) { | |
Object[DEFINE_PROPERTY](O, Symbol.matches, { | |
writable: false, | |
configurable: false, | |
enumerable: false, | |
value: fn | |
}); | |
} | |
// Classes | |
defineMatch(Function.prototype, function (x) { | |
return x instanceof this; | |
}); | |
// Primitive Classes | |
defineMatch(Number, function (x) { | |
return typeof x === "number"; | |
}); | |
defineMatch(String, function (x) { | |
return typeof x === "string"; | |
}); | |
defineMatch(Boolean, function (x) { | |
return typeof x === "boolean"; | |
}); | |
// Objects & Arrays (very unsure of this) | |
defineMatch(Object.prototype, function (x) { | |
return _.isMatch(x, this); | |
}); | |
// RegExp | |
defineMatch(RegExp.prototype, function (x) { | |
return this.test(x); | |
}); | |
// Sets | |
defineMatch(Set.prototype, function (x) { | |
return this.has(x); | |
}); | |
// Math.Range(min, max) – (very unsure of this) | |
Object[DEFINE_PROPERTY](Math, "Range", { | |
configurable: false, | |
writable: false, | |
value: function Range(min, max) { | |
if (!(this instanceof Range)) { | |
return new Range(min, max); | |
} | |
this.min = min == null ? -Infinity : min; | |
this.max = max == null ? Infinity : max; | |
}, | |
}); | |
defineMatch(Math.Range.prototype, function (x) { | |
// TODO: allow Range/Range comparisons, return true on overlap(?) | |
return typeof x === "number" && this.min <= x && this.max >= x; | |
}); | |
} | |
function isMatch(pattern, x) { | |
return Boolean( | |
x != null && Symbol.matches in pattern | |
? pattern[Symbol.matches](x) | |
: x === pattern | |
); | |
} | |
class Foo {} | |
class FooChild extends Foo {} | |
class FooSibling {} | |
class Bar { | |
static [Symbol.matches](x) { | |
return x === "bar" | |
} | |
} | |
function OldSchoolCool() {} | |
console.log([ | |
[isMatch(Array, []), true], | |
[isMatch(Array, [4, 5]), true], | |
[isMatch(Array, { 0: 1, length: 1 }), false], | |
[isMatch(Number, 1), true], | |
[isMatch(Number, "1"), false], | |
[isMatch(String, "hi"), true], | |
[isMatch(String, 1), false], | |
[isMatch(Boolean, true), true], | |
[isMatch(Boolean, false), true], | |
[isMatch(Boolean, null), false], | |
[isMatch(Boolean, ""), false], | |
[isMatch(Boolean, 0), false], | |
[isMatch(Boolean, 1), false], | |
[isMatch(Foo, new Foo()), true], | |
[isMatch(Foo, new FooChild()), true], | |
[isMatch(FooChild, new FooChild()), true], | |
[isMatch(FooChild, new Foo()), false], | |
[isMatch(Foo, new FooSibling()), false], | |
[isMatch(Foo, Foo), false], | |
[isMatch(Foo, FooChild), false], | |
[isMatch(Foo, {}), false], | |
[isMatch(OldSchoolCool, new OldSchoolCool()), true], | |
[isMatch(OldSchoolCool, OldSchoolCool()), false], | |
[isMatch(OldSchoolCool, OldSchoolCool), false], | |
[isMatch(Bar, "bar"), true], | |
[isMatch(Bar, new Bar()), false], | |
[isMatch(Bar, Bar), false], | |
[isMatch(/f(o+)/, "fo"), true], | |
[isMatch(/f(o+)/, "foooo"), true], | |
[isMatch(/f(o+)/, "f"), false], | |
[isMatch(/f(o+)/, null), false], | |
[isMatch(new Set(["hi", "there"]), "hi"), true], | |
[isMatch(new Set(["hi", "there"]), "there"), true], | |
[isMatch(new Set(["hi", "there"]), "bye"), false], | |
[isMatch(new Set(["hi", "there"]), 0), false], | |
[isMatch(new Set(["hi", "there"]), "0"), false], | |
[isMatch(new Set(["hi", "there"]), new Set()), false], | |
[isMatch(Math.Range(0, 1), 1), true], | |
[isMatch(Math.Range(0, 1), 2), false], | |
[isMatch(new Math.Range(0, 1), 1), true], | |
[isMatch(new Math.Range(0, 1), 0), true], | |
[isMatch(new Math.Range(-10, 10), 2), true], | |
[isMatch(new Math.Range(null, 10), 2), true], | |
[isMatch(new Math.Range(null, 10), 12), false], | |
[isMatch(new Math.Range(-10, null), 2), true], | |
[isMatch(new Math.Range(-10, null), -12), false], | |
].map(x => x.toString())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment