|
1 | 1 | const Utils = require('../lib/Utils'); |
2 | 2 | const { createSanitizedError, createSanitizedHttpError } = require("../lib/Error") |
| 3 | +const vm = require('vm'); |
3 | 4 |
|
4 | 5 | describe('Utils', () => { |
5 | 6 | describe('encodeForUrl', () => { |
@@ -287,4 +288,156 @@ describe('Utils', () => { |
287 | 288 | expect(error.message).toBe('Detailed error message'); |
288 | 289 | }); |
289 | 290 | }); |
| 291 | + |
| 292 | + describe('isDate', () => { |
| 293 | + it('should return true for a Date', () => { |
| 294 | + expect(Utils.isDate(new Date())).toBe(true); |
| 295 | + }); |
| 296 | + it('should return true for a cross-realm Date', () => { |
| 297 | + const crossRealmDate = vm.runInNewContext('new Date()'); |
| 298 | + expect(crossRealmDate instanceof Date).toBe(false); |
| 299 | + expect(Utils.isDate(crossRealmDate)).toBe(true); |
| 300 | + }); |
| 301 | + it('should return false for non-Date values', () => { |
| 302 | + expect(Utils.isDate(null)).toBe(false); |
| 303 | + expect(Utils.isDate(undefined)).toBe(false); |
| 304 | + expect(Utils.isDate('2021-01-01')).toBe(false); |
| 305 | + expect(Utils.isDate(123)).toBe(false); |
| 306 | + expect(Utils.isDate({})).toBe(false); |
| 307 | + }); |
| 308 | + }); |
| 309 | + |
| 310 | + describe('isRegExp', () => { |
| 311 | + it('should return true for a RegExp', () => { |
| 312 | + expect(Utils.isRegExp(/test/)).toBe(true); |
| 313 | + expect(Utils.isRegExp(new RegExp('test'))).toBe(true); |
| 314 | + }); |
| 315 | + it('should return true for a cross-realm RegExp', () => { |
| 316 | + const crossRealmRegExp = vm.runInNewContext('/test/'); |
| 317 | + expect(crossRealmRegExp instanceof RegExp).toBe(false); |
| 318 | + expect(Utils.isRegExp(crossRealmRegExp)).toBe(true); |
| 319 | + }); |
| 320 | + it('should return false for non-RegExp values', () => { |
| 321 | + expect(Utils.isRegExp(null)).toBe(false); |
| 322 | + expect(Utils.isRegExp(undefined)).toBe(false); |
| 323 | + expect(Utils.isRegExp('/test/')).toBe(false); |
| 324 | + expect(Utils.isRegExp({})).toBe(false); |
| 325 | + }); |
| 326 | + }); |
| 327 | + |
| 328 | + describe('isMap', () => { |
| 329 | + it('should return true for a Map', () => { |
| 330 | + expect(Utils.isMap(new Map())).toBe(true); |
| 331 | + }); |
| 332 | + it('should return true for a cross-realm Map', () => { |
| 333 | + const crossRealmMap = vm.runInNewContext('new Map()'); |
| 334 | + expect(crossRealmMap instanceof Map).toBe(false); |
| 335 | + expect(Utils.isMap(crossRealmMap)).toBe(true); |
| 336 | + }); |
| 337 | + it('should return false for non-Map values', () => { |
| 338 | + expect(Utils.isMap(null)).toBe(false); |
| 339 | + expect(Utils.isMap(undefined)).toBe(false); |
| 340 | + expect(Utils.isMap({})).toBe(false); |
| 341 | + expect(Utils.isMap(new Set())).toBe(false); |
| 342 | + }); |
| 343 | + }); |
| 344 | + |
| 345 | + describe('isSet', () => { |
| 346 | + it('should return true for a Set', () => { |
| 347 | + expect(Utils.isSet(new Set())).toBe(true); |
| 348 | + }); |
| 349 | + it('should return true for a cross-realm Set', () => { |
| 350 | + const crossRealmSet = vm.runInNewContext('new Set()'); |
| 351 | + expect(crossRealmSet instanceof Set).toBe(false); |
| 352 | + expect(Utils.isSet(crossRealmSet)).toBe(true); |
| 353 | + }); |
| 354 | + it('should return false for non-Set values', () => { |
| 355 | + expect(Utils.isSet(null)).toBe(false); |
| 356 | + expect(Utils.isSet(undefined)).toBe(false); |
| 357 | + expect(Utils.isSet({})).toBe(false); |
| 358 | + expect(Utils.isSet(new Map())).toBe(false); |
| 359 | + }); |
| 360 | + }); |
| 361 | + |
| 362 | + describe('isNativeError', () => { |
| 363 | + it('should return true for an Error', () => { |
| 364 | + expect(Utils.isNativeError(new Error('test'))).toBe(true); |
| 365 | + }); |
| 366 | + it('should return true for Error subclasses', () => { |
| 367 | + expect(Utils.isNativeError(new TypeError('test'))).toBe(true); |
| 368 | + expect(Utils.isNativeError(new RangeError('test'))).toBe(true); |
| 369 | + }); |
| 370 | + it('should return true for a cross-realm Error', () => { |
| 371 | + const crossRealmError = vm.runInNewContext('new Error("test")'); |
| 372 | + expect(crossRealmError instanceof Error).toBe(false); |
| 373 | + expect(Utils.isNativeError(crossRealmError)).toBe(true); |
| 374 | + }); |
| 375 | + it('should return false for non-Error values', () => { |
| 376 | + expect(Utils.isNativeError(null)).toBe(false); |
| 377 | + expect(Utils.isNativeError(undefined)).toBe(false); |
| 378 | + expect(Utils.isNativeError({ message: 'fake' })).toBe(false); |
| 379 | + expect(Utils.isNativeError('error')).toBe(false); |
| 380 | + }); |
| 381 | + }); |
| 382 | + |
| 383 | + describe('isPromise', () => { |
| 384 | + it('should return true for a Promise', () => { |
| 385 | + expect(Utils.isPromise(Promise.resolve())).toBe(true); |
| 386 | + }); |
| 387 | + it('should return true for a cross-realm Promise', () => { |
| 388 | + const crossRealmPromise = vm.runInNewContext('Promise.resolve()'); |
| 389 | + expect(crossRealmPromise instanceof Promise).toBe(false); |
| 390 | + expect(Utils.isPromise(crossRealmPromise)).toBe(true); |
| 391 | + }); |
| 392 | + it('should return true for a thenable', () => { |
| 393 | + expect(Utils.isPromise({ then: () => {} })).toBe(true); |
| 394 | + }); |
| 395 | + it('should return false for non-Promise values', () => { |
| 396 | + expect(Utils.isPromise(null)).toBe(false); |
| 397 | + expect(Utils.isPromise(undefined)).toBe(false); |
| 398 | + expect(Utils.isPromise({})).toBe(false); |
| 399 | + expect(Utils.isPromise(42)).toBe(false); |
| 400 | + }); |
| 401 | + it('should return false for plain objects when Object.prototype.then is polluted', () => { |
| 402 | + Object.prototype.then = () => {}; |
| 403 | + try { |
| 404 | + expect(Utils.isPromise({})).toBe(false); |
| 405 | + expect(Utils.isPromise({ a: 1 })).toBe(false); |
| 406 | + } finally { |
| 407 | + delete Object.prototype.then; |
| 408 | + } |
| 409 | + }); |
| 410 | + it('should return true for real thenables even when Object.prototype.then is polluted', () => { |
| 411 | + Object.prototype.then = () => {}; |
| 412 | + try { |
| 413 | + expect(Utils.isPromise({ then: () => {} })).toBe(true); |
| 414 | + expect(Utils.isPromise(Promise.resolve())).toBe(true); |
| 415 | + } finally { |
| 416 | + delete Object.prototype.then; |
| 417 | + } |
| 418 | + }); |
| 419 | + }); |
| 420 | + |
| 421 | + describe('isObject', () => { |
| 422 | + it('should return true for plain objects', () => { |
| 423 | + expect(Utils.isObject({})).toBe(true); |
| 424 | + expect(Utils.isObject({ a: 1 })).toBe(true); |
| 425 | + }); |
| 426 | + it('should return true for a cross-realm object', () => { |
| 427 | + const crossRealmObj = vm.runInNewContext('({ a: 1 })'); |
| 428 | + expect(crossRealmObj instanceof Object).toBe(false); |
| 429 | + expect(Utils.isObject(crossRealmObj)).toBe(true); |
| 430 | + }); |
| 431 | + it('should return true for arrays and other objects', () => { |
| 432 | + expect(Utils.isObject([])).toBe(true); |
| 433 | + expect(Utils.isObject(new Date())).toBe(true); |
| 434 | + }); |
| 435 | + it('should return false for non-object values', () => { |
| 436 | + expect(Utils.isObject(null)).toBe(false); |
| 437 | + expect(Utils.isObject(undefined)).toBe(false); |
| 438 | + expect(Utils.isObject(42)).toBe(false); |
| 439 | + expect(Utils.isObject('string')).toBe(false); |
| 440 | + expect(Utils.isObject(true)).toBe(false); |
| 441 | + }); |
| 442 | + }); |
290 | 443 | }); |
0 commit comments