1'use strict'; 2 3var define = require('../'); 4var test = require('tape'); 5var keys = require('object-keys'); 6 7var arePropertyDescriptorsSupported = function () { 8 var obj = { a: 1 }; 9 try { 10 Object.defineProperty(obj, 'x', { value: obj }); 11 return obj.x === obj; 12 } catch (e) { /* this is IE 8. */ 13 return false; 14 } 15}; 16var descriptorsSupported = !!Object.defineProperty && arePropertyDescriptorsSupported(); 17 18var hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol'; 19 20test('defineProperties', function (dt) { 21 dt.test('with descriptor support', { skip: !descriptorsSupported }, function (t) { 22 var getDescriptor = function (value) { 23 return { 24 configurable: true, 25 enumerable: false, 26 value: value, 27 writable: true 28 }; 29 }; 30 31 var obj = { 32 a: 1, 33 b: 2, 34 c: 3 35 }; 36 t.deepEqual(keys(obj), ['a', 'b', 'c'], 'all literal-set keys start enumerable'); 37 define(obj, { 38 b: 3, 39 c: 4, 40 d: 5 41 }); 42 t.deepEqual(obj, { 43 a: 1, 44 b: 2, 45 c: 3 46 }, 'existing properties were not overridden'); 47 t.deepEqual(Object.getOwnPropertyDescriptor(obj, 'd'), getDescriptor(5), 'new property "d" was added and is not enumerable'); 48 t.deepEqual(['a', 'b', 'c'], keys(obj), 'new keys are not enumerable'); 49 50 define(obj, { 51 a: 2, 52 b: 3, 53 c: 4 54 }, { 55 a: function () { return true; }, 56 b: function () { return false; } 57 }); 58 t.deepEqual(obj, { 59 b: 2, 60 c: 3 61 }, 'properties only overriden when predicate exists and returns true'); 62 t.deepEqual(Object.getOwnPropertyDescriptor(obj, 'd'), getDescriptor(5), 'existing property "d" remained and is not enumerable'); 63 t.deepEqual(Object.getOwnPropertyDescriptor(obj, 'a'), getDescriptor(2), 'existing property "a" was overridden and is not enumerable'); 64 t.deepEqual(['b', 'c'], keys(obj), 'overridden keys are not enumerable'); 65 66 t.end(); 67 }); 68 69 dt.test('without descriptor support', { skip: descriptorsSupported }, function (t) { 70 var obj = { 71 a: 1, 72 b: 2, 73 c: 3 74 }; 75 define(obj, { 76 b: 3, 77 c: 4, 78 d: 5 79 }); 80 t.deepEqual(obj, { 81 a: 1, 82 b: 2, 83 c: 3, 84 d: 5 85 }, 'existing properties were not overridden, new properties were added'); 86 87 define(obj, { 88 a: 2, 89 b: 3, 90 c: 4 91 }, { 92 a: function () { return true; }, 93 b: function () { return false; } 94 }); 95 t.deepEqual(obj, { 96 a: 2, 97 b: 2, 98 c: 3, 99 d: 5 100 }, 'properties only overriden when predicate exists and returns true'); 101 102 t.end(); 103 }); 104 105 dt.end(); 106}); 107 108test('symbols', { skip: !hasSymbols }, function (t) { 109 var sym = Symbol('foo'); 110 var obj = {}; 111 var aValue = {}; 112 var bValue = {}; 113 var properties = { a: aValue }; 114 properties[sym] = bValue; 115 116 define(obj, properties); 117 118 t.deepEqual(Object.keys(obj), [], 'object has no enumerable keys'); 119 t.deepEqual(Object.getOwnPropertyNames(obj), ['a'], 'object has non-enumerable "a" key'); 120 t.deepEqual(Object.getOwnPropertySymbols(obj), [sym], 'object has non-enumerable symbol key'); 121 t.equal(obj.a, aValue, 'string keyed value is defined'); 122 t.equal(obj[sym], bValue, 'symbol keyed value is defined'); 123 124 t.end(); 125}); 126