March 26, 2020
TestsSource
- Create an object using `Reflect`
- Override properties using Reflect
- Object vs. Reflect
- Work with a frozen object
Source Code
The source code we wrote during the event.
reflect.spec.js
import assert from 'assert';
describe('Create an object using `Reflect`', () => {
it('use Reflect.construct to create an object', () => {
const constructorFunction = function() {};
assert.equal(typeof Reflect.construct(constructorFunction, []), 'object');
});
it('has properties defined in the constructor function', () => {
const constructorFunction = function() { this.a = 1; };
const result = Reflect.construct(constructorFunction, []);
assert.equal(result.a, 1);
assert.equal(result['a'], 1);
});
it('can pass one argument to the constructor function', () => {
const constructorFunction = function(arg1) { this.a = arg1; };
const result = Reflect.construct(constructorFunction, [1]);
assert.equal(result.a, 1);
});
it('can pass two arguments to the constructor function', () => {
const constructorFunction = function(arg1, arg2) { this.args = [arg1, arg2]; };
const result = Reflect.construct(constructorFunction, [1, 2]);
assert.deepStrictEqual(result.args, [1, 2]);
});
});
describe('Override properties using Reflect', () => {
it('define a property and re-define it', () => {
const a = {x: 42};
Reflect.defineProperty(a, 'x', {value: 13});
assert.strictEqual(a.x, 13);
});
it('re-defining a method on an object is possible', () => {
const a = {method: () => 42};
Reflect.defineProperty(a, 'method', {value: () => 13})
assert.strictEqual(a.method(), 13);
});
it('make a writable property be not writable', () => {
const a = {x: 42};
Reflect.defineProperty(a, 'x', {value: 13, writable: false});
assert.throws(() => { a.x = 45; }, TypeError);
});
it('make read-only property writable', () => {
const a = {x: 13};
Reflect.defineProperty(a, 'x', {writable: false});
assert.throws(() => a.x = 45);
assert.doesNotThrow(() => Reflect.defineProperty(a, 'x', {writable: true}));
assert.doesNotThrow(() => a.x = 45);
});
it('prevent making a read-only property writable', () => {
const a = {x: 13};
Reflect.defineProperty(a, 'x', {configurable: false});
assert.doesNotThrow(() => Reflect.defineProperty(a, 'x', {writable: false}));
assert.throws(() => a.x = 42);
});
});
describe('Object vs. Reflect', () => {
it('changing configurable from false to true using Reflect returns false', () => {
const a = {x: 13};
Reflect.defineProperty(a, 'x', {configurable: false});
const result = Reflect.defineProperty(a, 'x', {configurable: true});
assert.strictEqual(result, false);
assert.strictEqual(Reflect.getOwnPropertyDescriptor(a, 'x').configurable, false);
});
it('changing configurable from false to true using Object throws with TypeError', () => {
const a = {x: 13};
Object.defineProperty(a, 'x', {configurable: false});
assert.throws(() => Object.defineProperty(a, 'x', {configurable: true}));
});
it('deleting an not-existing property using `delete` of an object does NOT throw', () => {
const obj = {};
assert.doesNotThrow(() => delete obj.y);
});
it('deleting a not-existing property returns true', () => {
assert.strictEqual(Reflect.deleteProperty({}, 'y'), true);
assert.strictEqual(Reflect.has({}, 'y'), false);
});
it('deleting an existing property of an object returns true', () => {
assert.strictEqual(Reflect.deleteProperty({y: 1}, 'y'), true);
});
});
describe('Work with a frozen object', () => {
it('with Reflect we can NOT extend a frozen object', () => {
const obj = Object.freeze({x: 1});
const result = Reflect.defineProperty(obj, 'y', {value: 1});
assert.strictEqual(result, false);
assert.strictEqual(result.y, undefined);
assert.strictEqual(Reflect.has(obj, 'y'), false);
assert.strictEqual(Reflect.has(obj, 'x'), true);
assert.strictEqual(Reflect.deleteProperty(obj, 'x'), false);
});
it('deleting an existing property using `delete` of a frozen object throws', () => {
const frozenObj = Object.freeze({y: 1});
assert.throws(() => delete frozenObj.y, TypeError);
});
it('deleting an existing property of a frozen object returns false', () => {
assert.strictEqual(Reflect.deleteProperty(Object.freeze({y: 1}), 'y'), false);
});
});