1
|
'use strict';
|
2
|
|
3
|
var ES = require('../').ES5;
|
4
|
var test = require('tape');
|
5
|
|
6
|
var forEach = require('foreach');
|
7
|
var is = require('object-is');
|
8
|
var debug = require('object-inspect');
|
9
|
|
10
|
var v = require('./helpers/values');
|
11
|
|
12
|
require('./helpers/runManifestTest')(test, ES, 5);
|
13
|
|
14
|
test('ToPrimitive', function (t) {
|
15
|
t.test('primitives', function (st) {
|
16
|
var testPrimitive = function (primitive) {
|
17
|
st.ok(is(ES.ToPrimitive(primitive), primitive), debug(primitive) + ' is returned correctly');
|
18
|
};
|
19
|
forEach(v.primitives, testPrimitive);
|
20
|
st.end();
|
21
|
});
|
22
|
|
23
|
t.test('objects', function (st) {
|
24
|
st.equal(ES.ToPrimitive(v.coercibleObject), v.coercibleObject.valueOf(), 'coercibleObject coerces to valueOf');
|
25
|
st.equal(ES.ToPrimitive(v.coercibleObject, Number), v.coercibleObject.valueOf(), 'coercibleObject with hint Number coerces to valueOf');
|
26
|
st.equal(ES.ToPrimitive(v.coercibleObject, String), v.coercibleObject.toString(), 'coercibleObject with hint String coerces to toString');
|
27
|
st.equal(ES.ToPrimitive(v.coercibleFnObject), v.coercibleFnObject.toString(), 'coercibleFnObject coerces to toString');
|
28
|
st.equal(ES.ToPrimitive(v.toStringOnlyObject), v.toStringOnlyObject.toString(), 'toStringOnlyObject returns toString');
|
29
|
st.equal(ES.ToPrimitive(v.valueOfOnlyObject), v.valueOfOnlyObject.valueOf(), 'valueOfOnlyObject returns valueOf');
|
30
|
st.equal(ES.ToPrimitive({}), '[object Object]', '{} with no hint coerces to Object#toString');
|
31
|
st.equal(ES.ToPrimitive({}, String), '[object Object]', '{} with hint String coerces to Object#toString');
|
32
|
st.equal(ES.ToPrimitive({}, Number), '[object Object]', '{} with hint Number coerces to Object#toString');
|
33
|
st['throws'](function () { return ES.ToPrimitive(v.uncoercibleObject); }, TypeError, 'uncoercibleObject throws a TypeError');
|
34
|
st['throws'](function () { return ES.ToPrimitive(v.uncoercibleFnObject); }, TypeError, 'uncoercibleFnObject throws a TypeError');
|
35
|
st.end();
|
36
|
});
|
37
|
|
38
|
t.end();
|
39
|
});
|
40
|
|
41
|
test('ToBoolean', function (t) {
|
42
|
t.equal(false, ES.ToBoolean(undefined), 'undefined coerces to false');
|
43
|
t.equal(false, ES.ToBoolean(null), 'null coerces to false');
|
44
|
t.equal(false, ES.ToBoolean(false), 'false returns false');
|
45
|
t.equal(true, ES.ToBoolean(true), 'true returns true');
|
46
|
forEach([0, -0, NaN], function (falsyNumber) {
|
47
|
t.equal(false, ES.ToBoolean(falsyNumber), 'falsy number ' + falsyNumber + ' coerces to false');
|
48
|
});
|
49
|
forEach([Infinity, 42, 1, -Infinity], function (truthyNumber) {
|
50
|
t.equal(true, ES.ToBoolean(truthyNumber), 'truthy number ' + truthyNumber + ' coerces to true');
|
51
|
});
|
52
|
t.equal(false, ES.ToBoolean(''), 'empty string coerces to false');
|
53
|
t.equal(true, ES.ToBoolean('foo'), 'nonempty string coerces to true');
|
54
|
forEach(v.objects, function (obj) {
|
55
|
t.equal(true, ES.ToBoolean(obj), 'object coerces to true');
|
56
|
});
|
57
|
t.equal(true, ES.ToBoolean(v.uncoercibleObject), 'uncoercibleObject coerces to true');
|
58
|
t.end();
|
59
|
});
|
60
|
|
61
|
test('ToNumber', function (t) {
|
62
|
t.ok(is(NaN, ES.ToNumber(undefined)), 'undefined coerces to NaN');
|
63
|
t.ok(is(ES.ToNumber(null), 0), 'null coerces to +0');
|
64
|
t.ok(is(ES.ToNumber(false), 0), 'false coerces to +0');
|
65
|
t.equal(1, ES.ToNumber(true), 'true coerces to 1');
|
66
|
t.ok(is(NaN, ES.ToNumber(NaN)), 'NaN returns itself');
|
67
|
forEach([0, -0, 42, Infinity, -Infinity], function (num) {
|
68
|
t.equal(num, ES.ToNumber(num), num + ' returns itself');
|
69
|
});
|
70
|
forEach(['foo', '0', '4a', '2.0', 'Infinity', '-Infinity'], function (numString) {
|
71
|
t.ok(is(+numString, ES.ToNumber(numString)), '"' + numString + '" coerces to ' + Number(numString));
|
72
|
});
|
73
|
forEach(v.objects, function (object) {
|
74
|
t.ok(is(ES.ToNumber(object), ES.ToNumber(ES.ToPrimitive(object))), 'object ' + object + ' coerces to same as ToPrimitive of object does');
|
75
|
});
|
76
|
t['throws'](function () { return ES.ToNumber(v.uncoercibleObject); }, TypeError, 'uncoercibleObject throws');
|
77
|
t.end();
|
78
|
});
|
79
|
|
80
|
test('ToInteger', function (t) {
|
81
|
t.ok(is(0, ES.ToInteger(NaN)), 'NaN coerces to +0');
|
82
|
forEach([0, Infinity, 42], function (num) {
|
83
|
t.ok(is(num, ES.ToInteger(num)), num + ' returns itself');
|
84
|
t.ok(is(-num, ES.ToInteger(-num)), '-' + num + ' returns itself');
|
85
|
});
|
86
|
t.equal(3, ES.ToInteger(Math.PI), 'pi returns 3');
|
87
|
t['throws'](function () { return ES.ToInteger(v.uncoercibleObject); }, TypeError, 'uncoercibleObject throws');
|
88
|
t.end();
|
89
|
});
|
90
|
|
91
|
test('ToInt32', function (t) {
|
92
|
t.ok(is(0, ES.ToInt32(NaN)), 'NaN coerces to +0');
|
93
|
forEach([0, Infinity], function (num) {
|
94
|
t.ok(is(0, ES.ToInt32(num)), num + ' returns +0');
|
95
|
t.ok(is(0, ES.ToInt32(-num)), '-' + num + ' returns +0');
|
96
|
});
|
97
|
t['throws'](function () { return ES.ToInt32(v.uncoercibleObject); }, TypeError, 'uncoercibleObject throws');
|
98
|
t.ok(is(ES.ToInt32(0x100000000), 0), '2^32 returns +0');
|
99
|
t.ok(is(ES.ToInt32(0x100000000 - 1), -1), '2^32 - 1 returns -1');
|
100
|
t.ok(is(ES.ToInt32(0x80000000), -0x80000000), '2^31 returns -2^31');
|
101
|
t.ok(is(ES.ToInt32(0x80000000 - 1), 0x80000000 - 1), '2^31 - 1 returns 2^31 - 1');
|
102
|
forEach([0, Infinity, NaN, 0x100000000, 0x80000000, 0x10000, 0x42], function (num) {
|
103
|
t.ok(is(ES.ToInt32(num), ES.ToInt32(ES.ToUint32(num))), 'ToInt32(x) === ToInt32(ToUint32(x)) for 0x' + num.toString(16));
|
104
|
t.ok(is(ES.ToInt32(-num), ES.ToInt32(ES.ToUint32(-num))), 'ToInt32(x) === ToInt32(ToUint32(x)) for -0x' + num.toString(16));
|
105
|
});
|
106
|
t.end();
|
107
|
});
|
108
|
|
109
|
test('ToUint32', function (t) {
|
110
|
t.ok(is(0, ES.ToUint32(NaN)), 'NaN coerces to +0');
|
111
|
forEach([0, Infinity], function (num) {
|
112
|
t.ok(is(0, ES.ToUint32(num)), num + ' returns +0');
|
113
|
t.ok(is(0, ES.ToUint32(-num)), '-' + num + ' returns +0');
|
114
|
});
|
115
|
t['throws'](function () { return ES.ToUint32(v.uncoercibleObject); }, TypeError, 'uncoercibleObject throws');
|
116
|
t.ok(is(ES.ToUint32(0x100000000), 0), '2^32 returns +0');
|
117
|
t.ok(is(ES.ToUint32(0x100000000 - 1), 0x100000000 - 1), '2^32 - 1 returns 2^32 - 1');
|
118
|
t.ok(is(ES.ToUint32(0x80000000), 0x80000000), '2^31 returns 2^31');
|
119
|
t.ok(is(ES.ToUint32(0x80000000 - 1), 0x80000000 - 1), '2^31 - 1 returns 2^31 - 1');
|
120
|
forEach([0, Infinity, NaN, 0x100000000, 0x80000000, 0x10000, 0x42], function (num) {
|
121
|
t.ok(is(ES.ToUint32(num), ES.ToUint32(ES.ToInt32(num))), 'ToUint32(x) === ToUint32(ToInt32(x)) for 0x' + num.toString(16));
|
122
|
t.ok(is(ES.ToUint32(-num), ES.ToUint32(ES.ToInt32(-num))), 'ToUint32(x) === ToUint32(ToInt32(x)) for -0x' + num.toString(16));
|
123
|
});
|
124
|
t.end();
|
125
|
});
|
126
|
|
127
|
test('ToUint16', function (t) {
|
128
|
t.ok(is(0, ES.ToUint16(NaN)), 'NaN coerces to +0');
|
129
|
forEach([0, Infinity], function (num) {
|
130
|
t.ok(is(0, ES.ToUint16(num)), num + ' returns +0');
|
131
|
t.ok(is(0, ES.ToUint16(-num)), '-' + num + ' returns +0');
|
132
|
});
|
133
|
t['throws'](function () { return ES.ToUint16(v.uncoercibleObject); }, TypeError, 'uncoercibleObject throws');
|
134
|
t.ok(is(ES.ToUint16(0x100000000), 0), '2^32 returns +0');
|
135
|
t.ok(is(ES.ToUint16(0x100000000 - 1), 0x10000 - 1), '2^32 - 1 returns 2^16 - 1');
|
136
|
t.ok(is(ES.ToUint16(0x80000000), 0), '2^31 returns +0');
|
137
|
t.ok(is(ES.ToUint16(0x80000000 - 1), 0x10000 - 1), '2^31 - 1 returns 2^16 - 1');
|
138
|
t.ok(is(ES.ToUint16(0x10000), 0), '2^16 returns +0');
|
139
|
t.ok(is(ES.ToUint16(0x10000 - 1), 0x10000 - 1), '2^16 - 1 returns 2^16 - 1');
|
140
|
t.end();
|
141
|
});
|
142
|
|
143
|
test('ToString', function (t) {
|
144
|
t['throws'](function () { return ES.ToString(v.uncoercibleObject); }, TypeError, 'uncoercibleObject throws');
|
145
|
t.end();
|
146
|
});
|
147
|
|
148
|
test('ToObject', function (t) {
|
149
|
t['throws'](function () { return ES.ToObject(undefined); }, TypeError, 'undefined throws');
|
150
|
t['throws'](function () { return ES.ToObject(null); }, TypeError, 'null throws');
|
151
|
forEach(v.numbers, function (number) {
|
152
|
var obj = ES.ToObject(number);
|
153
|
t.equal(typeof obj, 'object', 'number ' + number + ' coerces to object');
|
154
|
t.equal(true, obj instanceof Number, 'object of ' + number + ' is Number object');
|
155
|
t.ok(is(obj.valueOf(), number), 'object of ' + number + ' coerces to ' + number);
|
156
|
});
|
157
|
t.end();
|
158
|
});
|
159
|
|
160
|
test('CheckObjectCoercible', function (t) {
|
161
|
t['throws'](function () { return ES.CheckObjectCoercible(undefined); }, TypeError, 'undefined throws');
|
162
|
t['throws'](function () { return ES.CheckObjectCoercible(null); }, TypeError, 'null throws');
|
163
|
var checkCoercible = function (value) {
|
164
|
t.doesNotThrow(function () { return ES.CheckObjectCoercible(value); }, debug(value) + ' does not throw');
|
165
|
};
|
166
|
forEach(v.objects.concat(v.nonNullPrimitives), checkCoercible);
|
167
|
t.end();
|
168
|
});
|
169
|
|
170
|
test('IsCallable', function (t) {
|
171
|
t.equal(true, ES.IsCallable(function () {}), 'function is callable');
|
172
|
var nonCallables = [/a/g, {}, Object.prototype, NaN].concat(v.primitives);
|
173
|
forEach(nonCallables, function (nonCallable) {
|
174
|
t.equal(false, ES.IsCallable(nonCallable), debug(nonCallable) + ' is not callable');
|
175
|
});
|
176
|
t.end();
|
177
|
});
|
178
|
|
179
|
test('SameValue', function (t) {
|
180
|
t.equal(true, ES.SameValue(NaN, NaN), 'NaN is SameValue as NaN');
|
181
|
t.equal(false, ES.SameValue(0, -0), '+0 is not SameValue as -0');
|
182
|
forEach(v.objects.concat(v.primitives), function (val) {
|
183
|
t.equal(val === val, ES.SameValue(val, val), debug(val) + ' is SameValue to itself');
|
184
|
});
|
185
|
t.end();
|
186
|
});
|
187
|
|
188
|
test('Type', function (t) {
|
189
|
t.equal(ES.Type(), 'Undefined', 'Type() is Undefined');
|
190
|
t.equal(ES.Type(undefined), 'Undefined', 'Type(undefined) is Undefined');
|
191
|
t.equal(ES.Type(null), 'Null', 'Type(null) is Null');
|
192
|
t.equal(ES.Type(true), 'Boolean', 'Type(true) is Boolean');
|
193
|
t.equal(ES.Type(false), 'Boolean', 'Type(false) is Boolean');
|
194
|
t.equal(ES.Type(0), 'Number', 'Type(0) is Number');
|
195
|
t.equal(ES.Type(NaN), 'Number', 'Type(NaN) is Number');
|
196
|
t.equal(ES.Type('abc'), 'String', 'Type("abc") is String');
|
197
|
t.equal(ES.Type(function () {}), 'Object', 'Type(function () {}) is Object');
|
198
|
t.equal(ES.Type({}), 'Object', 'Type({}) is Object');
|
199
|
t.end();
|
200
|
});
|
201
|
|
202
|
test('IsPropertyDescriptor', function (t) {
|
203
|
forEach(v.primitives, function (primitive) {
|
204
|
t.equal(ES.IsPropertyDescriptor(primitive), false, debug(primitive) + ' is not a Property Descriptor');
|
205
|
});
|
206
|
|
207
|
t.equal(ES.IsPropertyDescriptor({ invalid: true }), false, 'invalid keys not allowed on a Property Descriptor');
|
208
|
|
209
|
t.equal(ES.IsPropertyDescriptor({}), true, 'empty object is an incomplete Property Descriptor');
|
210
|
|
211
|
t.equal(ES.IsPropertyDescriptor(v.accessorDescriptor()), true, 'accessor descriptor is a Property Descriptor');
|
212
|
t.equal(ES.IsPropertyDescriptor(v.mutatorDescriptor()), true, 'mutator descriptor is a Property Descriptor');
|
213
|
t.equal(ES.IsPropertyDescriptor(v.dataDescriptor()), true, 'data descriptor is a Property Descriptor');
|
214
|
t.equal(ES.IsPropertyDescriptor(v.genericDescriptor()), true, 'generic descriptor is a Property Descriptor');
|
215
|
|
216
|
t['throws'](
|
217
|
function () { ES.IsPropertyDescriptor(v.bothDescriptor()); },
|
218
|
TypeError,
|
219
|
'a Property Descriptor can not be both a Data and an Accessor Descriptor'
|
220
|
);
|
221
|
|
222
|
t['throws'](
|
223
|
function () { ES.IsPropertyDescriptor(v.bothDescriptorWritable()); },
|
224
|
TypeError,
|
225
|
'a Property Descriptor can not be both a Data and an Accessor Descriptor'
|
226
|
);
|
227
|
|
228
|
t.end();
|
229
|
});
|
230
|
|
231
|
test('IsAccessorDescriptor', function (t) {
|
232
|
forEach(v.nonNullPrimitives.concat(null), function (primitive) {
|
233
|
t['throws'](function () { ES.IsAccessorDescriptor(primitive); }, TypeError, debug(primitive) + ' is not a Property Descriptor');
|
234
|
});
|
235
|
|
236
|
t.equal(ES.IsAccessorDescriptor(), false, 'no value is not an Accessor Descriptor');
|
237
|
t.equal(ES.IsAccessorDescriptor(undefined), false, 'undefined value is not an Accessor Descriptor');
|
238
|
|
239
|
t.equal(ES.IsAccessorDescriptor(v.accessorDescriptor()), true, 'accessor descriptor is an Accessor Descriptor');
|
240
|
t.equal(ES.IsAccessorDescriptor(v.mutatorDescriptor()), true, 'mutator descriptor is an Accessor Descriptor');
|
241
|
t.equal(ES.IsAccessorDescriptor(v.dataDescriptor()), false, 'data descriptor is not an Accessor Descriptor');
|
242
|
t.equal(ES.IsAccessorDescriptor(v.genericDescriptor()), false, 'generic descriptor is not an Accessor Descriptor');
|
243
|
|
244
|
t.end();
|
245
|
});
|
246
|
|
247
|
test('IsDataDescriptor', function (t) {
|
248
|
forEach(v.nonNullPrimitives.concat(null), function (primitive) {
|
249
|
t['throws'](function () { ES.IsDataDescriptor(primitive); }, TypeError, debug(primitive) + ' is not a Property Descriptor');
|
250
|
});
|
251
|
|
252
|
t.equal(ES.IsDataDescriptor(), false, 'no value is not a Data Descriptor');
|
253
|
t.equal(ES.IsDataDescriptor(undefined), false, 'undefined value is not a Data Descriptor');
|
254
|
|
255
|
t.equal(ES.IsDataDescriptor(v.accessorDescriptor()), false, 'accessor descriptor is not a Data Descriptor');
|
256
|
t.equal(ES.IsDataDescriptor(v.mutatorDescriptor()), false, 'mutator descriptor is not a Data Descriptor');
|
257
|
t.equal(ES.IsDataDescriptor(v.dataDescriptor()), true, 'data descriptor is a Data Descriptor');
|
258
|
t.equal(ES.IsDataDescriptor(v.genericDescriptor()), false, 'generic descriptor is not a Data Descriptor');
|
259
|
|
260
|
t.end();
|
261
|
});
|
262
|
|
263
|
test('IsGenericDescriptor', function (t) {
|
264
|
forEach(v.nonNullPrimitives.concat(null), function (primitive) {
|
265
|
t['throws'](
|
266
|
function () { ES.IsGenericDescriptor(primitive); },
|
267
|
TypeError,
|
268
|
debug(primitive) + ' is not a Property Descriptor'
|
269
|
);
|
270
|
});
|
271
|
|
272
|
t.equal(ES.IsGenericDescriptor(), false, 'no value is not a Data Descriptor');
|
273
|
t.equal(ES.IsGenericDescriptor(undefined), false, 'undefined value is not a Data Descriptor');
|
274
|
|
275
|
t.equal(ES.IsGenericDescriptor(v.accessorDescriptor()), false, 'accessor descriptor is not a generic Descriptor');
|
276
|
t.equal(ES.IsGenericDescriptor(v.mutatorDescriptor()), false, 'mutator descriptor is not a generic Descriptor');
|
277
|
t.equal(ES.IsGenericDescriptor(v.dataDescriptor()), false, 'data descriptor is not a generic Descriptor');
|
278
|
|
279
|
t.equal(ES.IsGenericDescriptor(v.genericDescriptor()), true, 'generic descriptor is a generic Descriptor');
|
280
|
|
281
|
t.end();
|
282
|
});
|
283
|
|
284
|
test('FromPropertyDescriptor', function (t) {
|
285
|
t.equal(ES.FromPropertyDescriptor(), undefined, 'no value begets undefined');
|
286
|
t.equal(ES.FromPropertyDescriptor(undefined), undefined, 'undefined value begets undefined');
|
287
|
|
288
|
forEach(v.nonNullPrimitives.concat(null), function (primitive) {
|
289
|
t['throws'](
|
290
|
function () { ES.FromPropertyDescriptor(primitive); },
|
291
|
TypeError,
|
292
|
debug(primitive) + ' is not a Property Descriptor'
|
293
|
);
|
294
|
});
|
295
|
|
296
|
var accessor = v.accessorDescriptor();
|
297
|
t.deepEqual(ES.FromPropertyDescriptor(accessor), {
|
298
|
get: accessor['[[Get]]'],
|
299
|
set: accessor['[[Set]]'],
|
300
|
enumerable: !!accessor['[[Enumerable]]'],
|
301
|
configurable: !!accessor['[[Configurable]]']
|
302
|
});
|
303
|
|
304
|
var mutator = v.mutatorDescriptor();
|
305
|
t.deepEqual(ES.FromPropertyDescriptor(mutator), {
|
306
|
get: mutator['[[Get]]'],
|
307
|
set: mutator['[[Set]]'],
|
308
|
enumerable: !!mutator['[[Enumerable]]'],
|
309
|
configurable: !!mutator['[[Configurable]]']
|
310
|
});
|
311
|
var data = v.dataDescriptor();
|
312
|
t.deepEqual(ES.FromPropertyDescriptor(data), {
|
313
|
value: data['[[Value]]'],
|
314
|
writable: data['[[Writable]]'],
|
315
|
enumerable: !!data['[[Enumerable]]'],
|
316
|
configurable: !!data['[[Configurable]]']
|
317
|
});
|
318
|
|
319
|
t['throws'](
|
320
|
function () { ES.FromPropertyDescriptor(v.genericDescriptor()); },
|
321
|
TypeError,
|
322
|
'a complete Property Descriptor is required'
|
323
|
);
|
324
|
|
325
|
t.end();
|
326
|
});
|
327
|
|
328
|
test('ToPropertyDescriptor', function (t) {
|
329
|
forEach(v.nonNullPrimitives.concat(null), function (primitive) {
|
330
|
t['throws'](
|
331
|
function () { ES.ToPropertyDescriptor(primitive); },
|
332
|
TypeError,
|
333
|
debug(primitive) + ' is not an Object'
|
334
|
);
|
335
|
});
|
336
|
|
337
|
var accessor = v.accessorDescriptor();
|
338
|
t.deepEqual(ES.ToPropertyDescriptor({
|
339
|
get: accessor['[[Get]]'],
|
340
|
enumerable: !!accessor['[[Enumerable]]'],
|
341
|
configurable: !!accessor['[[Configurable]]']
|
342
|
}), accessor);
|
343
|
|
344
|
var mutator = v.mutatorDescriptor();
|
345
|
t.deepEqual(ES.ToPropertyDescriptor({
|
346
|
set: mutator['[[Set]]'],
|
347
|
enumerable: !!mutator['[[Enumerable]]'],
|
348
|
configurable: !!mutator['[[Configurable]]']
|
349
|
}), mutator);
|
350
|
|
351
|
var data = v.descriptors.nonConfigurable(v.dataDescriptor());
|
352
|
t.deepEqual(ES.ToPropertyDescriptor({
|
353
|
value: data['[[Value]]'],
|
354
|
writable: data['[[Writable]]'],
|
355
|
configurable: !!data['[[Configurable]]']
|
356
|
}), data);
|
357
|
|
358
|
var both = v.bothDescriptor();
|
359
|
t['throws'](
|
360
|
function () {
|
361
|
ES.ToPropertyDescriptor({ get: both['[[Get]]'], value: both['[[Value]]'] });
|
362
|
},
|
363
|
TypeError,
|
364
|
'data and accessor descriptors are mutually exclusive'
|
365
|
);
|
366
|
|
367
|
t['throws'](
|
368
|
function () { ES.ToPropertyDescriptor({ get: 'not callable' }); },
|
369
|
TypeError,
|
370
|
'"get" must be undefined or callable'
|
371
|
);
|
372
|
|
373
|
t['throws'](
|
374
|
function () { ES.ToPropertyDescriptor({ set: 'not callable' }); },
|
375
|
TypeError,
|
376
|
'"set" must be undefined or callable'
|
377
|
);
|
378
|
|
379
|
t.end();
|
380
|
});
|
381
|
|
382
|
test('Abstract Equality Comparison', function (t) {
|
383
|
t.test('same types use ===', function (st) {
|
384
|
forEach(v.primitives.concat(v.objects), function (value) {
|
385
|
st.equal(ES['Abstract Equality Comparison'](value, value), value === value, debug(value) + ' is abstractly equal to itself');
|
386
|
});
|
387
|
st.end();
|
388
|
});
|
389
|
|
390
|
t.test('different types coerce', function (st) {
|
391
|
var pairs = [
|
392
|
[null, undefined],
|
393
|
[3, '3'],
|
394
|
[true, '3'],
|
395
|
[true, 3],
|
396
|
[false, 0],
|
397
|
[false, '0'],
|
398
|
[3, [3]],
|
399
|
['3', [3]],
|
400
|
[true, [1]],
|
401
|
[false, [0]],
|
402
|
[String(v.coercibleObject), v.coercibleObject],
|
403
|
[Number(String(v.coercibleObject)), v.coercibleObject],
|
404
|
[Number(v.coercibleObject), v.coercibleObject],
|
405
|
[String(Number(v.coercibleObject)), v.coercibleObject]
|
406
|
];
|
407
|
forEach(pairs, function (pair) {
|
408
|
var a = pair[0];
|
409
|
var b = pair[1];
|
410
|
// eslint-disable-next-line eqeqeq
|
411
|
st.equal(ES['Abstract Equality Comparison'](a, b), a == b, debug(a) + ' == ' + debug(b));
|
412
|
// eslint-disable-next-line eqeqeq
|
413
|
st.equal(ES['Abstract Equality Comparison'](b, a), b == a, debug(b) + ' == ' + debug(a));
|
414
|
});
|
415
|
st.end();
|
416
|
});
|
417
|
|
418
|
t.end();
|
419
|
});
|
420
|
|
421
|
test('Strict Equality Comparison', function (t) {
|
422
|
t.test('same types use ===', function (st) {
|
423
|
forEach(v.primitives.concat(v.objects), function (value) {
|
424
|
st.equal(ES['Strict Equality Comparison'](value, value), value === value, debug(value) + ' is strictly equal to itself');
|
425
|
});
|
426
|
st.end();
|
427
|
});
|
428
|
|
429
|
t.test('different types are not ===', function (st) {
|
430
|
var pairs = [
|
431
|
[null, undefined],
|
432
|
[3, '3'],
|
433
|
[true, '3'],
|
434
|
[true, 3],
|
435
|
[false, 0],
|
436
|
[false, '0'],
|
437
|
[3, [3]],
|
438
|
['3', [3]],
|
439
|
[true, [1]],
|
440
|
[false, [0]],
|
441
|
[String(v.coercibleObject), v.coercibleObject],
|
442
|
[Number(String(v.coercibleObject)), v.coercibleObject],
|
443
|
[Number(v.coercibleObject), v.coercibleObject],
|
444
|
[String(Number(v.coercibleObject)), v.coercibleObject]
|
445
|
];
|
446
|
forEach(pairs, function (pair) {
|
447
|
var a = pair[0];
|
448
|
var b = pair[1];
|
449
|
st.equal(ES['Strict Equality Comparison'](a, b), a === b, debug(a) + ' === ' + debug(b));
|
450
|
st.equal(ES['Strict Equality Comparison'](b, a), b === a, debug(b) + ' === ' + debug(a));
|
451
|
});
|
452
|
st.end();
|
453
|
});
|
454
|
|
455
|
t.end();
|
456
|
});
|
457
|
|
458
|
test('Abstract Relational Comparison', function (t) {
|
459
|
t.test('at least one operand is NaN', function (st) {
|
460
|
st.equal(ES['Abstract Relational Comparison'](NaN, {}, true), undefined, 'LeftFirst: first is NaN, returns undefined');
|
461
|
st.equal(ES['Abstract Relational Comparison']({}, NaN, true), undefined, 'LeftFirst: second is NaN, returns undefined');
|
462
|
st.equal(ES['Abstract Relational Comparison'](NaN, {}, false), undefined, '!LeftFirst: first is NaN, returns undefined');
|
463
|
st.equal(ES['Abstract Relational Comparison']({}, NaN, false), undefined, '!LeftFirst: second is NaN, returns undefined');
|
464
|
st.end();
|
465
|
});
|
466
|
|
467
|
t.equal(ES['Abstract Relational Comparison'](3, 4, true), true, 'LeftFirst: 3 is less than 4');
|
468
|
t.equal(ES['Abstract Relational Comparison'](4, 3, true), false, 'LeftFirst: 3 is not less than 4');
|
469
|
t.equal(ES['Abstract Relational Comparison'](3, 4, false), true, '!LeftFirst: 3 is less than 4');
|
470
|
t.equal(ES['Abstract Relational Comparison'](4, 3, false), false, '!LeftFirst: 3 is not less than 4');
|
471
|
|
472
|
t.equal(ES['Abstract Relational Comparison']('3', '4', true), true, 'LeftFirst: "3" is less than "4"');
|
473
|
t.equal(ES['Abstract Relational Comparison']('4', '3', true), false, 'LeftFirst: "3" is not less than "4"');
|
474
|
t.equal(ES['Abstract Relational Comparison']('3', '4', false), true, '!LeftFirst: "3" is less than "4"');
|
475
|
t.equal(ES['Abstract Relational Comparison']('4', '3', false), false, '!LeftFirst: "3" is not less than "4"');
|
476
|
|
477
|
t.equal(ES['Abstract Relational Comparison'](v.coercibleObject, 42, true), true, 'LeftFirst: coercible object is less than 42');
|
478
|
t.equal(ES['Abstract Relational Comparison'](42, v.coercibleObject, true), false, 'LeftFirst: 42 is not less than coercible object');
|
479
|
t.equal(ES['Abstract Relational Comparison'](v.coercibleObject, 42, false), true, '!LeftFirst: coercible object is less than 42');
|
480
|
t.equal(ES['Abstract Relational Comparison'](42, v.coercibleObject, false), false, '!LeftFirst: 42 is not less than coercible object');
|
481
|
|
482
|
t.equal(ES['Abstract Relational Comparison'](v.coercibleObject, '3', true), false, 'LeftFirst: coercible object is not less than "3"');
|
483
|
t.equal(ES['Abstract Relational Comparison']('3', v.coercibleObject, true), false, 'LeftFirst: "3" is not less than coercible object');
|
484
|
t.equal(ES['Abstract Relational Comparison'](v.coercibleObject, '3', false), false, '!LeftFirst: coercible object is not less than "3"');
|
485
|
t.equal(ES['Abstract Relational Comparison']('3', v.coercibleObject, false), false, '!LeftFirst: "3" is not less than coercible object');
|
486
|
|
487
|
t.end();
|
488
|
});
|
489
|
|
490
|
test('FromPropertyDescriptor', function (t) {
|
491
|
t.equal(ES.FromPropertyDescriptor(), undefined, 'no value begets undefined');
|
492
|
t.equal(ES.FromPropertyDescriptor(undefined), undefined, 'undefined value begets undefined');
|
493
|
|
494
|
forEach(v.nonUndefinedPrimitives, function (primitive) {
|
495
|
t['throws'](
|
496
|
function () { ES.FromPropertyDescriptor(primitive); },
|
497
|
TypeError,
|
498
|
debug(primitive) + ' is not a Property Descriptor'
|
499
|
);
|
500
|
});
|
501
|
|
502
|
var accessor = v.accessorDescriptor();
|
503
|
t.deepEqual(ES.FromPropertyDescriptor(accessor), {
|
504
|
get: accessor['[[Get]]'],
|
505
|
set: accessor['[[Set]]'],
|
506
|
enumerable: !!accessor['[[Enumerable]]'],
|
507
|
configurable: !!accessor['[[Configurable]]']
|
508
|
});
|
509
|
|
510
|
var mutator = v.mutatorDescriptor();
|
511
|
t.deepEqual(ES.FromPropertyDescriptor(mutator), {
|
512
|
get: mutator['[[Get]]'],
|
513
|
set: mutator['[[Set]]'],
|
514
|
enumerable: !!mutator['[[Enumerable]]'],
|
515
|
configurable: !!mutator['[[Configurable]]']
|
516
|
});
|
517
|
var data = v.dataDescriptor();
|
518
|
t.deepEqual(ES.FromPropertyDescriptor(data), {
|
519
|
value: data['[[Value]]'],
|
520
|
writable: data['[[Writable]]'],
|
521
|
enumerable: !!data['[[Enumerable]]'],
|
522
|
configurable: !!data['[[Configurable]]']
|
523
|
});
|
524
|
|
525
|
t['throws'](
|
526
|
function () { ES.FromPropertyDescriptor(v.genericDescriptor()); },
|
527
|
TypeError,
|
528
|
'a complete Property Descriptor is required'
|
529
|
);
|
530
|
|
531
|
t.end();
|
532
|
});
|
533
|
|
534
|
test('SecFromTime', function (t) {
|
535
|
var now = new Date();
|
536
|
t.equal(ES.SecFromTime(now.getTime()), now.getUTCSeconds(), 'second from Date timestamp matches getUTCSeconds');
|
537
|
t.end();
|
538
|
});
|
539
|
|
540
|
test('MinFromTime', function (t) {
|
541
|
var now = new Date();
|
542
|
t.equal(ES.MinFromTime(now.getTime()), now.getUTCMinutes(), 'minute from Date timestamp matches getUTCMinutes');
|
543
|
t.end();
|
544
|
});
|
545
|
|
546
|
test('HourFromTime', function (t) {
|
547
|
var now = new Date();
|
548
|
t.equal(ES.HourFromTime(now.getTime()), now.getUTCHours(), 'hour from Date timestamp matches getUTCHours');
|
549
|
t.end();
|
550
|
});
|
551
|
|
552
|
test('msFromTime', function (t) {
|
553
|
var now = new Date();
|
554
|
t.equal(ES.msFromTime(now.getTime()), now.getUTCMilliseconds(), 'ms from Date timestamp matches getUTCMilliseconds');
|
555
|
t.end();
|
556
|
});
|
557
|
|
558
|
var msPerSecond = 1e3;
|
559
|
var msPerMinute = 60 * msPerSecond;
|
560
|
var msPerHour = 60 * msPerMinute;
|
561
|
var msPerDay = 24 * msPerHour;
|
562
|
|
563
|
test('Day', function (t) {
|
564
|
var time = Date.UTC(2019, 8, 10, 2, 3, 4, 5);
|
565
|
var add = 2.5;
|
566
|
var later = new Date(time + (add * msPerDay));
|
567
|
|
568
|
t.equal(ES.Day(later.getTime()), ES.Day(time) + Math.floor(add), 'adding 2.5 days worth of ms, gives a Day delta of 2');
|
569
|
t.end();
|
570
|
});
|
571
|
|
572
|
test('TimeWithinDay', function (t) {
|
573
|
var time = Date.UTC(2019, 8, 10, 2, 3, 4, 5);
|
574
|
var add = 2.5;
|
575
|
var later = new Date(time + (add * msPerDay));
|
576
|
|
577
|
t.equal(ES.TimeWithinDay(later.getTime()), ES.TimeWithinDay(time) + (0.5 * msPerDay), 'adding 2.5 days worth of ms, gives a TimeWithinDay delta of +0.5');
|
578
|
t.end();
|
579
|
});
|
580
|
|
581
|
test('DayFromYear', function (t) {
|
582
|
t.equal(ES.DayFromYear(2021) - ES.DayFromYear(2020), 366, '2021 is a leap year, has 366 days');
|
583
|
t.equal(ES.DayFromYear(2020) - ES.DayFromYear(2019), 365, '2020 is not a leap year, has 365 days');
|
584
|
t.equal(ES.DayFromYear(2019) - ES.DayFromYear(2018), 365, '2019 is not a leap year, has 365 days');
|
585
|
t.equal(ES.DayFromYear(2018) - ES.DayFromYear(2017), 365, '2018 is not a leap year, has 365 days');
|
586
|
t.equal(ES.DayFromYear(2017) - ES.DayFromYear(2016), 366, '2017 is a leap year, has 366 days');
|
587
|
|
588
|
t.end();
|
589
|
});
|
590
|
|
591
|
test('TimeFromYear', function (t) {
|
592
|
for (var i = 1900; i < 2100; i += 1) {
|
593
|
t.equal(ES.TimeFromYear(i), Date.UTC(i, 0, 1), 'TimeFromYear matches a Date object’s year: ' + i);
|
594
|
}
|
595
|
t.end();
|
596
|
});
|
597
|
|
598
|
test('YearFromTime', function (t) {
|
599
|
for (var i = 1900; i < 2100; i += 1) {
|
600
|
t.equal(ES.YearFromTime(Date.UTC(i, 0, 1)), i, 'YearFromTime matches a Date object’s year on 1/1: ' + i);
|
601
|
t.equal(ES.YearFromTime(Date.UTC(i, 10, 1)), i, 'YearFromTime matches a Date object’s year on 10/1: ' + i);
|
602
|
}
|
603
|
t.end();
|
604
|
});
|
605
|
|
606
|
test('WeekDay', function (t) {
|
607
|
var now = new Date();
|
608
|
var today = now.getUTCDay();
|
609
|
for (var i = 0; i < 7; i += 1) {
|
610
|
var weekDay = ES.WeekDay(now.getTime() + (i * msPerDay));
|
611
|
t.equal(weekDay, (today + i) % 7, i + ' days after today (' + today + '), WeekDay is ' + weekDay);
|
612
|
}
|
613
|
t.end();
|
614
|
});
|
615
|
|
616
|
test('DaysInYear', function (t) {
|
617
|
t.equal(ES.DaysInYear(2021), 365, '2021 is not a leap year');
|
618
|
t.equal(ES.DaysInYear(2020), 366, '2020 is a leap year');
|
619
|
t.equal(ES.DaysInYear(2019), 365, '2019 is not a leap year');
|
620
|
t.equal(ES.DaysInYear(2018), 365, '2018 is not a leap year');
|
621
|
t.equal(ES.DaysInYear(2017), 365, '2017 is not a leap year');
|
622
|
t.equal(ES.DaysInYear(2016), 366, '2016 is a leap year');
|
623
|
|
624
|
t.end();
|
625
|
});
|
626
|
|
627
|
test('InLeapYear', function (t) {
|
628
|
t.equal(ES.InLeapYear(Date.UTC(2021, 0, 1)), 0, '2021 is not a leap year');
|
629
|
t.equal(ES.InLeapYear(Date.UTC(2020, 0, 1)), 1, '2020 is a leap year');
|
630
|
t.equal(ES.InLeapYear(Date.UTC(2019, 0, 1)), 0, '2019 is not a leap year');
|
631
|
t.equal(ES.InLeapYear(Date.UTC(2018, 0, 1)), 0, '2018 is not a leap year');
|
632
|
t.equal(ES.InLeapYear(Date.UTC(2017, 0, 1)), 0, '2017 is not a leap year');
|
633
|
t.equal(ES.InLeapYear(Date.UTC(2016, 0, 1)), 1, '2016 is a leap year');
|
634
|
|
635
|
t.end();
|
636
|
});
|
637
|
|
638
|
test('DayWithinYear', function (t) {
|
639
|
t.equal(ES.DayWithinYear(Date.UTC(2019, 0, 1)), 0, '1/1 is the 1st day');
|
640
|
t.equal(ES.DayWithinYear(Date.UTC(2019, 11, 31)), 364, '12/31 is the 365th day in a non leap year');
|
641
|
t.equal(ES.DayWithinYear(Date.UTC(2016, 11, 31)), 365, '12/31 is the 366th day in a leap year');
|
642
|
|
643
|
t.end();
|
644
|
});
|
645
|
|
646
|
test('MonthFromTime', function (t) {
|
647
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 0, 1)), 0, 'non-leap: 1/1 gives January');
|
648
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 0, 31)), 0, 'non-leap: 1/31 gives January');
|
649
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 1, 1)), 1, 'non-leap: 2/1 gives February');
|
650
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 1, 28)), 1, 'non-leap: 2/28 gives February');
|
651
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 1, 29)), 2, 'non-leap: 2/29 gives March');
|
652
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 2, 1)), 2, 'non-leap: 3/1 gives March');
|
653
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 2, 31)), 2, 'non-leap: 3/31 gives March');
|
654
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 3, 1)), 3, 'non-leap: 4/1 gives April');
|
655
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 3, 30)), 3, 'non-leap: 4/30 gives April');
|
656
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 4, 1)), 4, 'non-leap: 5/1 gives May');
|
657
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 4, 31)), 4, 'non-leap: 5/31 gives May');
|
658
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 5, 1)), 5, 'non-leap: 6/1 gives June');
|
659
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 5, 30)), 5, 'non-leap: 6/30 gives June');
|
660
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 6, 1)), 6, 'non-leap: 7/1 gives July');
|
661
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 6, 31)), 6, 'non-leap: 7/31 gives July');
|
662
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 7, 1)), 7, 'non-leap: 8/1 gives August');
|
663
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 7, 30)), 7, 'non-leap: 8/30 gives August');
|
664
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 8, 1)), 8, 'non-leap: 9/1 gives September');
|
665
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 8, 30)), 8, 'non-leap: 9/30 gives September');
|
666
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 9, 1)), 9, 'non-leap: 10/1 gives October');
|
667
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 9, 31)), 9, 'non-leap: 10/31 gives October');
|
668
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 10, 1)), 10, 'non-leap: 11/1 gives November');
|
669
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 10, 30)), 10, 'non-leap: 11/30 gives November');
|
670
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 11, 1)), 11, 'non-leap: 12/1 gives December');
|
671
|
t.equal(ES.MonthFromTime(Date.UTC(2019, 11, 31)), 11, 'non-leap: 12/31 gives December');
|
672
|
|
673
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 0, 1)), 0, 'leap: 1/1 gives January');
|
674
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 0, 31)), 0, 'leap: 1/31 gives January');
|
675
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 1, 1)), 1, 'leap: 2/1 gives February');
|
676
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 1, 28)), 1, 'leap: 2/28 gives February');
|
677
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 1, 29)), 1, 'leap: 2/29 gives February');
|
678
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 2, 1)), 2, 'leap: 3/1 gives March');
|
679
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 2, 31)), 2, 'leap: 3/31 gives March');
|
680
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 3, 1)), 3, 'leap: 4/1 gives April');
|
681
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 3, 30)), 3, 'leap: 4/30 gives April');
|
682
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 4, 1)), 4, 'leap: 5/1 gives May');
|
683
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 4, 31)), 4, 'leap: 5/31 gives May');
|
684
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 5, 1)), 5, 'leap: 6/1 gives June');
|
685
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 5, 30)), 5, 'leap: 6/30 gives June');
|
686
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 6, 1)), 6, 'leap: 7/1 gives July');
|
687
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 6, 31)), 6, 'leap: 7/31 gives July');
|
688
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 7, 1)), 7, 'leap: 8/1 gives August');
|
689
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 7, 30)), 7, 'leap: 8/30 gives August');
|
690
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 8, 1)), 8, 'leap: 9/1 gives September');
|
691
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 8, 30)), 8, 'leap: 9/30 gives September');
|
692
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 9, 1)), 9, 'leap: 10/1 gives October');
|
693
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 9, 31)), 9, 'leap: 10/31 gives October');
|
694
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 10, 1)), 10, 'leap: 11/1 gives November');
|
695
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 10, 30)), 10, 'leap: 11/30 gives November');
|
696
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 11, 1)), 11, 'leap: 12/1 gives December');
|
697
|
t.equal(ES.MonthFromTime(Date.UTC(2016, 11, 31)), 11, 'leap: 12/31 gives December');
|
698
|
t.end();
|
699
|
});
|
700
|
|
701
|
test('DateFromTime', function (t) {
|
702
|
var i;
|
703
|
for (i = 1; i <= 28; i += 1) {
|
704
|
t.equal(ES.DateFromTime(Date.UTC(2019, 1, i)), i, '2019.02.' + i + ' is date ' + i);
|
705
|
}
|
706
|
for (i = 1; i <= 29; i += 1) {
|
707
|
t.equal(ES.DateFromTime(Date.UTC(2016, 1, i)), i, '2016.02.' + i + ' is date ' + i);
|
708
|
}
|
709
|
for (i = 1; i <= 30; i += 1) {
|
710
|
t.equal(ES.DateFromTime(Date.UTC(2019, 8, i)), i, '2019.09.' + i + ' is date ' + i);
|
711
|
}
|
712
|
for (i = 1; i <= 31; i += 1) {
|
713
|
t.equal(ES.DateFromTime(Date.UTC(2019, 9, i)), i, '2019.10.' + i + ' is date ' + i);
|
714
|
}
|
715
|
t.end();
|
716
|
});
|
717
|
|
718
|
test('MakeDay', function (t) {
|
719
|
var day2015 = 16687;
|
720
|
t.equal(ES.MakeDay(2015, 8, 9), day2015, '2015.09.09 is day 16687');
|
721
|
var day2016 = day2015 + 366; // 2016 is a leap year
|
722
|
t.equal(ES.MakeDay(2016, 8, 9), day2016, '2015.09.09 is day 17053');
|
723
|
var day2017 = day2016 + 365;
|
724
|
t.equal(ES.MakeDay(2017, 8, 9), day2017, '2017.09.09 is day 17418');
|
725
|
var day2018 = day2017 + 365;
|
726
|
t.equal(ES.MakeDay(2018, 8, 9), day2018, '2018.09.09 is day 17783');
|
727
|
var day2019 = day2018 + 365;
|
728
|
t.equal(ES.MakeDay(2019, 8, 9), day2019, '2019.09.09 is day 18148');
|
729
|
t.end();
|
730
|
});
|
731
|
|
732
|
test('MakeDate', function (t) {
|
733
|
forEach(v.infinities.concat(NaN), function (nonFiniteNumber) {
|
734
|
t.ok(is(ES.MakeDate(nonFiniteNumber, 0), NaN), debug(nonFiniteNumber) + ' is not a finite `day`');
|
735
|
t.ok(is(ES.MakeDate(0, nonFiniteNumber), NaN), debug(nonFiniteNumber) + ' is not a finite `time`');
|
736
|
});
|
737
|
t.equal(ES.MakeDate(0, 0), 0, 'zero day and zero time is zero date');
|
738
|
t.equal(ES.MakeDate(0, 123), 123, 'zero day and nonzero time is a date of the "time"');
|
739
|
t.equal(ES.MakeDate(1, 0), msPerDay, 'day of 1 and zero time is a date of "ms per day"');
|
740
|
t.equal(ES.MakeDate(3, 0), 3 * msPerDay, 'day of 3 and zero time is a date of thrice "ms per day"');
|
741
|
t.equal(ES.MakeDate(1, 123), msPerDay + 123, 'day of 1 and nonzero time is a date of "ms per day" plus the "time"');
|
742
|
t.equal(ES.MakeDate(3, 123), (3 * msPerDay) + 123, 'day of 3 and nonzero time is a date of thrice "ms per day" plus the "time"');
|
743
|
|
744
|
t.end();
|
745
|
});
|
746
|
|
747
|
test('MakeTime', function (t) {
|
748
|
forEach(v.infinities.concat(NaN), function (nonFiniteNumber) {
|
749
|
t.ok(is(ES.MakeTime(nonFiniteNumber, 0, 0, 0), NaN), debug(nonFiniteNumber) + ' is not a finite `hour`');
|
750
|
t.ok(is(ES.MakeTime(0, nonFiniteNumber, 0, 0), NaN), debug(nonFiniteNumber) + ' is not a finite `min`');
|
751
|
t.ok(is(ES.MakeTime(0, 0, nonFiniteNumber, 0), NaN), debug(nonFiniteNumber) + ' is not a finite `sec`');
|
752
|
t.ok(is(ES.MakeTime(0, 0, 0, nonFiniteNumber), NaN), debug(nonFiniteNumber) + ' is not a finite `ms`');
|
753
|
});
|
754
|
|
755
|
t.equal(
|
756
|
ES.MakeTime(1.2, 2.3, 3.4, 4.5),
|
757
|
(1 * msPerHour) + (2 * msPerMinute) + (3 * msPerSecond) + 4,
|
758
|
'all numbers are converted to integer, multiplied by the right number of ms, and summed'
|
759
|
);
|
760
|
t.end();
|
761
|
});
|
762
|
|
763
|
test('TimeClip', function (t) {
|
764
|
forEach(v.infinities.concat(NaN), function (nonFiniteNumber) {
|
765
|
t.ok(is(ES.TimeClip(nonFiniteNumber), NaN), debug(nonFiniteNumber) + ' is not a finite `time`');
|
766
|
});
|
767
|
t.ok(is(ES.TimeClip(8.64e15 + 1), NaN), '8.64e15 is the largest magnitude considered "finite"');
|
768
|
t.ok(is(ES.TimeClip(-8.64e15 - 1), NaN), '-8.64e15 is the largest magnitude considered "finite"');
|
769
|
|
770
|
forEach(v.zeroes.concat([-10, 10, +new Date()]), function (time) {
|
771
|
t.looseEqual(ES.TimeClip(time), time, debug(time) + ' is a time of ' + debug(time));
|
772
|
});
|
773
|
|
774
|
t.end();
|
775
|
});
|
776
|
|
777
|
test('modulo', function (t) {
|
778
|
t.equal(3 % 2, 1, '+3 % 2 is +1');
|
779
|
t.equal(ES.modulo(3, 2), 1, '+3 mod 2 is +1');
|
780
|
|
781
|
t.equal(-3 % 2, -1, '-3 % 2 is -1');
|
782
|
t.equal(ES.modulo(-3, 2), 1, '-3 mod 2 is +1');
|
783
|
t.end();
|
784
|
});
|