Skip to content

Commit

Permalink
Implemented Reflect global.
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorystick committed Dec 29, 2014
1 parent dbfba27 commit 6894453
Show file tree
Hide file tree
Showing 5 changed files with 296 additions and 0 deletions.
82 changes: 82 additions & 0 deletions es6-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,88 @@
// Shim incomplete iterator implementations.
addIterator(Object.getPrototypeOf((new globals.Map()).keys()));
addIterator(Object.getPrototypeOf((new globals.Set()).keys()));

// Reflect
if (!globals.Reflect) {
globals.Reflect = {

// Syntax in a functional form.
get: function (target, key, receiver) {
if (!ES.TypeIsObject(target)) {
throw new TypeError('target must be an object');
}

return target[key];
},

set: function (target, key, value, receiver) {
if (!ES.TypeIsObject(target)) {
throw new TypeError('target must be an object');
}

target[key] = value;
},

has: function (target, key) {
if (!ES.TypeIsObject(target)) {
throw new TypeError('target must be an object');
}

return key in target;
},

deleteProperty: function (target, key) {
if (!ES.TypeIsObject(target)) {
throw new TypeError('target must be an object');
}

delete target[key];
},

enumerate: function (target) {
if (!ES.TypeIsObject(target)) {
throw new TypeError('target must be an object');
}

var keys = [];

for (var key in target) {
keys.push(key);
}

return new ArrayIterator(keys, 'value');
},

// New operator in a functional form.
construct: function (constructor, args) {
if (!ES.IsCallable(constructor)) {
throw new TypeError('First argument must be callable.');
}

return ES.Construct(constructor, args);
},

// Apply method in a functional form.
apply: function (func, context, args) {
if (!ES.IsCallable(func)) {
throw new TypeError('First argument must be callable.');
}

return func.apply(context, args);
},

// Same as Object global.
defineProperty: Object.defineProperty,
getOwnPropertyDescriptor: Object.getOwnPropertyDescriptor,
getPrototypeOf: Object.getPrototypeOf,
isExtensible: Object.isExtensible,
preventExtensions: Object.preventExtensions,
setPrototypeOf: Object.setPrototypeOf,

// Different name.
ownKeys: Object.keys
};
}
}

return globals;
Expand Down
1 change: 1 addition & 0 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<script src="promise.js"></script>
<script src="regexp.js"></script>
<script src="string.js"></script>
<script src="reflect.js"></script>
<script src="worker-test.js"></script>
<script src="promise/all.js"></script>
<script src="promise/evil-promises.js"></script>
Expand Down
1 change: 1 addition & 0 deletions test/native.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<script src="promise.js"></script>
<script src="regexp.js"></script>
<script src="string.js"></script>
<script src="reflect.js"></script>
<script src="worker-test.js"></script>
<script src="promise/all.js"></script>
<script src="promise/evil-promises.js"></script>
Expand Down
211 changes: 211 additions & 0 deletions test/reflect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*global describe, it, expect, require, Reflect */

var exported = require('../');

describe('Reflect', function () {
it('is on the exported object', function () {
expect(exported.Reflect).to.equal(Reflect);
});

describe('Reflect.apply()', function () {
it('is a function', function () {
expect(typeof Reflect.apply).to.equal('function');
});

expect(Reflect.apply(Array.prototype.push, [1, 2], [3, 4, 5])).to.equal(5);
});

describe('Reflect.construct()', function () {
it('is a function', function () {
expect(typeof Reflect.construct).to.equal('function');
});

expect(Reflect.construct(function (a, b, c) {
this.qux = a + b + c;
}, ['foo', 'bar', 'baz']).qux).to.equal('foobarbaz');
});

describe('Reflect.get()', function () {
it('is a function', function () {
expect(typeof Reflect.get).to.equal('function');
});

it('throws on null and undefined', function () {
[null, undefined].forEach(function (item) {
expect(function () {
return Reflect.get(item, 'property');
}).to.throw(TypeError);
});
});
});

describe('Reflect.set()', function () {
it('is a function', function () {
expect(typeof Reflect.set).to.equal('function');
});

it('throws on null and undefined', function () {
[null, undefined].forEach(function (item) {
expect(function () {
return Reflect.set(item, 'property', 'value');
}).to.throw(TypeError);
});
});
});

describe('Reflect.has()', function () {
it('is a function', function () {
expect(typeof Reflect.has).to.equal('function');
});

it('throws on primitives', function () {
[null, undefined, 1, 'string', true].forEach(function (item) {
expect(function () {
return Reflect.has(item, 'property', 'value');
}).to.throw(TypeError);
});
});
});

describe('Reflect.deleteProperty()', function () {
it('is a function', function () {
expect(typeof Reflect.deleteProperty).to.equal('function');
});

});

describe('Reflect.getOwnPropertyDescriptor()', function () {
it('is a function', function () {
expect(typeof Reflect.getOwnPropertyDescriptor).to.equal('function');
});

});

describe('Reflect.defineProperty()', function () {
it('is a function', function () {
expect(typeof Reflect.defineProperty).to.equal('function');
});

});

describe('Reflect.getPrototypeOf()', function () {
it('is a function', function () {
expect(typeof Reflect.getPrototypeOf).to.equal('function');
});

it('is the same as Object.getPrototypeOf()', function () {
expect(Reflect.getPrototypeOf).to.equal(Object.getPrototypeOf);
});

it('can get prototypes', function () {

});
});

describe('Reflect.setPrototypeOf()', function () {
it('is a function', function () {
expect(typeof Reflect.setPrototypeOf).to.equal('function');
});

it('is the same as Object.setPrototypeOf()', function () {
expect(Reflect.setPrototypeOf).to.equal(Object.setPrototypeOf);
});

it('can set prototypes', function () {
var obj = {};
Reflect.setPrototypeOf(obj, Array.prototype);
expect(obj).to.be.an.instanceOf(Array);

expect(obj.toString).not.to.equal(undefined);
Reflect.setPrototypeOf(obj, null);
expect(obj.toString).to.equal(undefined);
});
});

describe('Reflect.isExtensible()', function () {
it('is a function', function () {
expect(typeof Reflect.isExtensible).to.equal('function');
});

it('is the same as Object.isExtensible()', function () {
expect(Reflect.isExtensible).to.equal(Object.isExtensible);
});

it('returns true for plain objects', function () {
expect(Reflect.isExtensible({})).to.equal(true);
expect(Reflect.isExtensible(Object.preventExtensions({}))).to.equal(false);
});
});

describe('Reflect.preventExtensions()', function () {
it('is a function', function () {
expect(typeof Reflect.preventExtensions).to.equal('function');
});

it('is the same as Object.preventExtensions()', function () {
expect(Reflect.preventExtensions).to.equal(Object.preventExtensions);
});

it('prevents extensions on objects', function () {
var obj = {};
Reflect.preventExtensions(obj);
expect(Object.isExtensible(obj)).to.equal(false);
});
});

describe('Reflect.enumerate()', function () {
it('is a function', function () {
expect(typeof Reflect.enumerate).to.equal('function');
});

it('only includes enumerable properties', function () {
var a = Object.create(null, {
// Non-enumerable per default.
a: { value: 1 }
});

a.b = 2;

var iter = Reflect.enumerate(a);

expect(iter.next()).to.deep.equal({
value: 'b',
done: false
});

expect(iter.next()).to.deep.equal({
value: undefined,
done: true
});
});

it('includes all enumerable properties of prototypes', function () {
var a = { prop: true };
var b = Object.create(a);

var iter = Reflect.enumerate(b);

expect(iter.next()).to.deep.equal({
value: 'prop',
done: false
});

expect(iter.next()).to.deep.equal({
value: undefined,
done: true
});
});
});

describe('Reflect.ownKeys()', function () {
it('is a function', function () {
expect(typeof Reflect.ownKeys).to.equal('function');
});

it('should return the same result as Object.keys()', function () {
var obj = { foo: 1, bar: 2};

expect(Reflect.ownKeys(obj)).to.deep.equal(Object.keys(obj));
});
});
});
1 change: 1 addition & 0 deletions testling.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<script src="test/object.js"></script>
<script src="test/promise.js"></script>
<script src="test/string.js"></script>
<script src="test/reflect.js"></script>
<script src="test/promise/all.js"></script>
<script src="test/promise/evil-promises.js"></script>
<!--
Expand Down

0 comments on commit 6894453

Please sign in to comment.