Last active
December 17, 2016 20:12
-
-
Save HDv2b/965a42cb93b714f7d00b784f77542638 to your computer and use it in GitHub Desktop.
Using Proxy and Reflect (ES6) to restrict insertion of objects into an Array - with test
This file contains hidden or 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
"use strict"; | |
class Fruit { | |
constructor(name){ | |
this._name = name; | |
} | |
set name(name){ | |
this._name = name; | |
} | |
get name(){ | |
return this._name; | |
} | |
} | |
class Vegetable { | |
constructor(name){ | |
this.name(name); | |
} | |
set name(name){ | |
this._name = name; | |
} | |
get name(){ | |
return this._name; | |
} | |
} | |
// a proxy for our array | |
var fruitbowl = new Proxy([], { | |
deleteProperty: function(target, property) { | |
return true; | |
}, | |
set: function(target, property, value, receiver) { | |
//console.log("Setting "+property+" to ",value); | |
if(property == "length"){ | |
target.length = value; | |
return true; | |
} else { | |
if(value instanceof Fruit){ | |
target[property] = value; | |
return true; | |
} else { | |
return false; | |
throw TypeError("Expected Fruit, got "+typeof(value)+" ("+value+")"); | |
} | |
} | |
} | |
}); | |
Reflect.defineProperty(fruitbowl, 'splice', { | |
configurable: true, | |
enumerable: false, | |
value: function(start, deleteCount, ...items) { | |
if (items.every(item => item instanceof Fruit)) { | |
return Reflect.apply(Array.prototype.splice, this, [start, deleteCount, ...items]); | |
} else { | |
throw new Error('All elements must be Fruit objects'); | |
} | |
} | |
}); | |
console.log("\n\n=== Putting fruit into the bowl... ===\n\n"); | |
try{ | |
fruitbowl.push(new Vegetable("potato")); | |
} catch (e){ | |
console.log("Shoudln't allow vegetables: PASSED"); | |
} | |
console.log("Fruitbowl should still be empty: " + (fruitbowl.length == 0 ? "PASSED" : "FAILED")); | |
fruitbowl.push(new Fruit("apple")); | |
console.log("Should allow fruit: " + (fruitbowl.length == 1 ? "PASSED" : "FAILED")); | |
fruitbowl[0] = new Fruit("orange"); | |
console.log("Should replace item specified as long as it's a Fruit: " + (fruitbowl.length == 1 && fruitbowl[0].name == "orange" ? "PASSED" : "FAILED")); | |
try { | |
fruitbowl[0] = "Bananas!!1one"; | |
} catch(e) { | |
} | |
console.log("Should not replace with a string: " + (fruitbowl.length == 1 && fruitbowl[0].name == "orange" ? "PASSED" : "FAILED")); | |
fruitbowl.push(new Fruit("banana"), new Fruit("pear")); | |
console.log("Should have 3 items [orange, banana, pear]: " + (fruitbowl.length == 3 ? "PASSED" : "FAILED"), fruitbowl); | |
console.log("\n\n === Cropping the bowl... ===\n\n"); | |
fruitbowl.length = 2; | |
console.log("Should have 2 items [orange,banana]: " + (fruitbowl.length == 2 ? "PASSED" : "FAILED")); | |
console.log("Should error at item 2: " + (!fruitbowl[2] ? "PASSED" : "FAILED"), fruitbowl); | |
console.log("\n\n === Splicing the bowl... ===\n\n"); | |
try{ | |
fruitbowl.splice(0,0,"pineapples!!1one"); | |
console.log(fruitbowl.length); | |
} catch (e){ | |
console.log("Shouldn't have inserted string: PASSED"); | |
} | |
console.log("Should still only have 2 fruit: " + (fruitbowl.length == 2 ? "PASSED" : "FAILED ("+fruitbowl.length+")")); | |
fruitbowl.splice(0,0,new Fruit("pineapple")); | |
console.log("Should now have 3 fruit: " + (fruitbowl.length == 3 ? "PASSED" : "FAILED")); | |
console.log("Should first fruit should be pineapple: " + (fruitbowl[0].name == "pineapple" ? "PASSED" : "FAILED")); | |
fruitbowl.splice(1,1); | |
console.log("Should now have 2 fruit: " + (fruitbowl.length == 2 ? "PASSED" : "FAILED")); | |
console.log("Should first fruit should be pineapple: " + (fruitbowl[0].name == "pineapple" ? "PASSED" : "FAILED")); | |
console.log("Should second fruit should be banana: " + (fruitbowl[1].name == "banana" ? "PASSED" : "FAILED")); | |
console.log("Should third fruit should be non-exostant: " + (typeof(fruitbowl[2] )== "undefined" ? "PASSED" : "FAILED")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment