diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..e960818 --- /dev/null +++ b/test/index.js @@ -0,0 +1,16 @@ +'use strict'; + +var values = require('../'); +var test = require('tape'); + +test('as a function', function (t) { + t.test('bad array/this value', function (st) { + st.throws(function () { values(undefined); }, TypeError, 'undefined is not an object'); + st.throws(function () { values(null); }, TypeError, 'null is not an object'); + st.end(); + }); + + require('./tests')(values, t); + + t.end(); +}); diff --git a/test/shimmed.js b/test/shimmed.js new file mode 100644 index 0000000..7981d7a --- /dev/null +++ b/test/shimmed.js @@ -0,0 +1,34 @@ +'use strict'; + +var values = require('../'); +values.shim(); + +var test = require('tape'); +var defineProperties = require('define-properties'); +var isEnumerable = Object.prototype.propertyIsEnumerable; +var functionsHaveNames = function f() {}.name === 'f'; + +test('shimmed', function (t) { + t.equal(Object.values.length, 1, 'Object.values has a length of 1'); + t.test('Function name', { skip: !functionsHaveNames }, function (st) { + st.equal(Object.values.name, 'values', 'Object.values has name "values"'); + st.end(); + }); + + t.test('enumerability', { skip: !defineProperties.supportsDescriptors }, function (et) { + et.equal(false, isEnumerable.call(Object, 'values'), 'Object.values is not enumerable'); + et.end(); + }); + + var supportsStrictMode = (function () { return typeof this === 'undefined'; }()); + + t.test('bad object value', { skip: !supportsStrictMode }, function (st) { + st.throws(function () { return Object.values(undefined); }, TypeError, 'undefined is not an object'); + st.throws(function () { return Object.values(null); }, TypeError, 'null is not an object'); + st.end(); + }); + + require('./tests')(Object.values, t); + + t.end(); +}); diff --git a/test/tests.js b/test/tests.js new file mode 100644 index 0000000..5a678dd --- /dev/null +++ b/test/tests.js @@ -0,0 +1,56 @@ +'use strict'; + +var keys = require('object-keys'); +var map = require('array-map'); + +var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol'; + +module.exports = function (values, t) { + var a = {}; + var b = {}; + var c = {}; + var obj = { a: a, b: b, c: c }; + + t.deepEqual(values(obj), [a, b, c], 'basic support'); + t.deepEqual(values({ a: a, b: a, c: c }), [a, a, c], 'duplicate values are included'); + + t.test('values are in the same order as keys', function (st) { + var object = { a: a, b: b }; + object[0] = 3; + object.c = c; + object[1] = 4; + delete object[0]; + var objKeys = keys(object); + var objValues = map(objKeys, function (key) { + return object[key]; + }); + st.deepEqual(values(object), objValues, 'values match key order'); + st.end(); + }); + + t.test('non-enumerable properties are omitted', { skip: !Object.defineProperty }, function (st) { + var object = { a: a, b: b }; + Object.defineProperty(object, 'c', { enumerable: false, value: c }); + st.deepEqual(values(object), [a, b], 'non-enumerable property‘s value is omitted'); + st.end(); + }); + + t.test('inherited properties are omitted', function (st) { + var F = function G() {}; + F.prototype.a = a; + var f = new F(); + f.b = b; + st.deepEqual(values(f), [b], 'only own properties are included'); + st.end(); + }); + + t.test('Symbols are omitted', { skip: !hasSymbols }, function (st) { + var object = { a: a, b: b, c: c }; + var enumSym = Symbol('enum'); + var nonEnumSym = Symbol('non enum'); + object[enumSym] = enumSym; + Object.defineProperty(object, nonEnumSym, { enumerable: false, value: nonEnumSym }); + st.deepEqual(values(object), [a, b, c], 'symbols are omitted'); + st.end(); + }); +};