Useful methods for file-related functions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.4 KiB

  1. import * as fc from 'fast-check'
  2. import File from './File'
  3. jest.mock('./isBrowser', function IsBrowser() {
  4. return () => false
  5. })
  6. it('should exist', () => {
  7. expect(File).toBeDefined()
  8. })
  9. it('should be a callable', () => {
  10. expect(typeof File).toBe('function')
  11. })
  12. describe('instances', () => {
  13. it('should contain a name', () => {
  14. fc.assert(
  15. fc.property(
  16. fc.string().filter(s => /^[a-zA-Z0-9._-]+$/.test(s)),
  17. fileName => {
  18. const file = new File([], fileName, { type: 'application/octet-stream' })
  19. expect(file).toHaveProperty('name', fileName)
  20. }
  21. )
  22. )
  23. })
  24. it('should contain a last modified timestamp', () => {
  25. fc.assert(
  26. fc.property(
  27. fc.tuple(
  28. fc.string().filter(s => /^[a-zA-Z0-9._-]+$/.test(s)),
  29. fc.nat()
  30. ),
  31. ([fileName, lastModified]) => {
  32. const file = new File([], fileName, { type: 'application/octet-stream', lastModified })
  33. expect(file).toHaveProperty('lastModified', lastModified)
  34. }
  35. )
  36. )
  37. })
  38. it('should contain a type', () => {
  39. fc.assert(
  40. fc.property(
  41. fc.tuple(
  42. fc.oneof(
  43. fc.constant('application'),
  44. fc.constant('font'),
  45. fc.constant('audio'),
  46. fc.constant('model'),
  47. fc.constant('video'),
  48. fc.constant('text')
  49. ),
  50. fc.string().filter(s => /^[a-zA-Z0-9._-]+$/.test(s))
  51. ),
  52. mimeTypeFragments => {
  53. const file = new File([], 'foo', { type: mimeTypeFragments.join('/') })
  54. expect(file).toHaveProperty('type', mimeTypeFragments.join('/').toLowerCase())
  55. }
  56. )
  57. )
  58. })
  59. })
  60. describe('on cases for last modified date', () => {
  61. // We put lastModified as `any` because native DOM types classify
  62. // `lastModified` as number only under FilePropertyBag (but browser
  63. // accepts both Date and number objects equally.
  64. it('should be 0 given invalid date objects', () => {
  65. fc.assert(
  66. fc.property(
  67. fc.anything().filter(
  68. s =>
  69. // `new Date(Number.MAX_SAFE_INTEGER)` returns Invalid Date, but
  70. // is ok with File instances on browsers. Weird. This is why we
  71. // exclude numbers that will generate invalid dates (we already
  72. // covered numbers previously anyway).
  73. typeof s !== 'number' && isNaN(new Date(s as Date).getTime())
  74. ),
  75. v => {
  76. const lastModified = new Date(v as Date)
  77. const file = new File([], 'foo', { type: 'application/octet-stream', lastModified: lastModified as any })
  78. expect(file.lastModified).toBe(0)
  79. }
  80. )
  81. )
  82. })
  83. it('should be 0 given NaN', () => {
  84. const file = new File([], 'foo', { type: 'application/octet-stream', lastModified: NaN })
  85. expect(file.lastModified).toBe(0)
  86. })
  87. it('should be 0 given generic object values', () => {
  88. fc.assert(
  89. fc.property(fc.object(), o => {
  90. const file = new File([], 'foo', { type: 'application/octet-stream', lastModified: o as any })
  91. expect(file.lastModified).toBe(0)
  92. })
  93. )
  94. })
  95. it('should be a corresponding integer timestamp given valid date objects', () => {
  96. fc.assert(
  97. fc.property(fc.date(), lastModified => {
  98. const file = new File([], 'foo', { type: 'application/octet-stream', lastModified: lastModified as any })
  99. expect(file.lastModified).toBe(lastModified.getTime())
  100. })
  101. )
  102. })
  103. })