diff --git a/katas/es6/language/proxy/api.js b/katas/es6/language/proxy/api.js new file mode 100644 index 00000000..defb1c5a --- /dev/null +++ b/katas/es6/language/proxy/api.js @@ -0,0 +1,53 @@ +// 49: Proxy - apis +// To do: make all tests pass, leave the assert lines unchanged! + +describe('handler can have different traps', function() { + + it('"apply" is a trap for a function call', function() { + var value = ""; + + let doSomething = function(arg) { + value = "Yeah! I'm safe!"; + }; + + let doSomethingProxy = new Proxy(doSomething, { + apply(target, thisArg, argumentsList) { + value = "Oh gosh, it's a trap!"; + } + }); + + doSomethingProxy(); + assert.equal(value, "Oh gosh, it's a trap!"); + }); + + it('"construct" is a trap for the "new" operator', function() { + var value = ""; + + let DoSomething = function(arg) { + value = "Yeah! I'm safe!"; + }; + + let DoSomethingProxy = new Proxy(DoSomething, { + construct(target, argumentsList) { + value = "Oh gosh, they got me!"; + return target; + } + }); + + var instance = new DoSomethingProxy(); + assert.equal(value, "Oh gosh, they got me!"); + }); + + it('"defineProperty" is a trap for Object.defineProperty()', function() {}); + it('"deleteProperty" is a trap for the "delete" operator', function() {}); + it('"enumerate" is a trap for for...in statements', function() {}); + it('"get" is a trap for getting a property value', function() {}); + it('"getOwnPropertyDescriptor" is a trap for Object.getOwnPropertyDescriptor()', function() {}); + it('"getPrototypeOf" is a trap for the [[GetPrototypeOf]] internal method', function() {}); + it('"has" is a trap for the in operator', function() {}); + it('"isExtensible" is a trap for Object.isExtensible()', function() {}); + it('"ownKeys" is a trap for Object.getOwnPropertyNames()', function() {}); + it('"preventExtensions" is a trap for Object.preventExtensions()', function() {}); + it('"set" is a trap for setting a property value', function() {}); + it('"setPrototypeOf" is a trap for Object.setPrototypeOf()', function() {}); +}); \ No newline at end of file diff --git a/katas/es6/language/proxy/basics.js b/katas/es6/language/proxy/basics.js new file mode 100644 index 00000000..b613f02f --- /dev/null +++ b/katas/es6/language/proxy/basics.js @@ -0,0 +1,46 @@ +// 49: Proxy - basics +// To do: make all tests pass, leave the assert lines unchanged! + +describe('proxies bring intercession to JavaScript', function() { + + it('is made of handler, traps and target', function() { + let target = {}; + let handler = { + // get is a trap + get(target, propKey, receiver) { + return 123; + } + }; + let proxy = new Proxy(target, handler); + + assert.equal(proxy.foo, 123); + }); + + it('can intercept operation on objects such as get and set', function() { + let target = {}; + let handler = { + get(target, propKey, receiver) { + if (propKey === 'foo') { + return 123; + } + return target[propKey]; + }, + set(target, propKey, value) { + if (propKey === 'age') { + if (!Number.isInteger(value)) { + throw new TypeError('The age is not an integer'); + } + } + + target[propKey] = value; + return true; + } + }; + + let proxy = new Proxy(target, handler); + + proxy.age = 26; + assert.equal(proxy.age, 26); + assert.equal(proxy.foo, 123); + }); +}); \ No newline at end of file diff --git a/katas/es6/language/proxy/behaviour.js b/katas/es6/language/proxy/behaviour.js new file mode 100644 index 00000000..de5afbca --- /dev/null +++ b/katas/es6/language/proxy/behaviour.js @@ -0,0 +1,91 @@ +// 49: Proxy - behaviour +// To do: make all tests pass, leave the assert lines unchanged! + +describe('handler has traps', function() { + + describe('traps are the operations defined on the handler object', function() { + it('is called when the handler implements it', function() { + let target = { + foo: 987 + }; + + let handler = { + get(target, propKey, receiver) { + return 123; + } + }; + + let proxy = new Proxy(target, handler); + + assert.equal(proxy.foo, 123); + }); + + it('is not called when the handler does not implement it but target works as a fallback', function() { + let target = { + foo: 987 + }; + + let handler = { + has(target, propKey, receiver) { + return true; + } + }; + + let proxy = new Proxy(target, handler); + + assert.equal(proxy.foo, 987); + }); + }); +}); + +describe('target object is the aimed object to be intercepted', function() { + + it ('target property is not called when a trap intercepts its opertion', function() { + var counter = (function() { + var that = {}; + that.value = 0; + + that.increments = function() { + that.value = that.value + 1; + } + + return that; + })(); + + let handler = { + apply(target, propKey, receiver) { + return 999; + } + }; + + let proxyIncrement = new Proxy(counter.increments, handler); + + assert.equal(proxyIncrement(), 999); + assert.equal(counter.value, 0); + }); + + it ('must be done manually', function() { + var counter = (function() { + var that = {}; + that.value = 0; + + that.increments = function() { + that.value = that.value + 1; + } + + return that; + })(); + + let handler = { + apply(target, propKey, receiver) { + target(); + return 999; + } + }; + + let proxyIncrement = new Proxy(counter.increments, handler); + + assert.equal(proxyIncrement(), 999); + assert.equal(counter.value, 1); + }); +}); \ No newline at end of file