looseEqual.spec.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import { looseEqual } from '../src'
  2. describe('utils/looseEqual', () => {
  3. test('compares booleans correctly', () => {
  4. expect(looseEqual(true, true)).toBe(true)
  5. expect(looseEqual(false, false)).toBe(true)
  6. expect(looseEqual(true, false)).toBe(false)
  7. expect(looseEqual(true, 1)).toBe(false)
  8. expect(looseEqual(false, 0)).toBe(false)
  9. })
  10. test('compares strings correctly', () => {
  11. const text = 'Lorem ipsum'
  12. const number = 1
  13. const bool = true
  14. expect(looseEqual(text, text)).toBe(true)
  15. expect(looseEqual(text, text.slice(0, -1))).toBe(false)
  16. expect(looseEqual(String(number), number)).toBe(true)
  17. expect(looseEqual(String(bool), bool)).toBe(true)
  18. })
  19. test('compares numbers correctly', () => {
  20. const number = 100
  21. const decimal = 2.5
  22. const multiplier = 1.0000001
  23. expect(looseEqual(number, number)).toBe(true)
  24. expect(looseEqual(number, number - 1)).toBe(false)
  25. expect(looseEqual(decimal, decimal)).toBe(true)
  26. expect(looseEqual(decimal, decimal * multiplier)).toBe(false)
  27. expect(looseEqual(number, number * multiplier)).toBe(false)
  28. expect(looseEqual(multiplier, multiplier)).toBe(true)
  29. })
  30. test('compares dates correctly', () => {
  31. const date1 = new Date(2019, 1, 2, 3, 4, 5, 6)
  32. const date2 = new Date(2019, 1, 2, 3, 4, 5, 6)
  33. const date3 = new Date(2019, 1, 2, 3, 4, 5, 7)
  34. const date4 = new Date(2219, 1, 2, 3, 4, 5, 6)
  35. // Identical date object references
  36. expect(looseEqual(date1, date1)).toBe(true)
  37. // Different date references with identical values
  38. expect(looseEqual(date1, date2)).toBe(true)
  39. // Dates with slightly different time (ms)
  40. expect(looseEqual(date1, date3)).toBe(false)
  41. // Dates with different year
  42. expect(looseEqual(date1, date4)).toBe(false)
  43. })
  44. test('compares files correctly', () => {
  45. const date1 = new Date(2019, 1, 2, 3, 4, 5, 6)
  46. const date2 = new Date(2019, 1, 2, 3, 4, 5, 7)
  47. const file1 = new File([''], 'filename.txt', {
  48. type: 'text/plain',
  49. lastModified: date1.getTime()
  50. })
  51. const file2 = new File([''], 'filename.txt', {
  52. type: 'text/plain',
  53. lastModified: date1.getTime()
  54. })
  55. const file3 = new File([''], 'filename.txt', {
  56. type: 'text/plain',
  57. lastModified: date2.getTime()
  58. })
  59. const file4 = new File([''], 'filename.csv', {
  60. type: 'text/csv',
  61. lastModified: date1.getTime()
  62. })
  63. const file5 = new File(['abcdef'], 'filename.txt', {
  64. type: 'text/plain',
  65. lastModified: date1.getTime()
  66. })
  67. const file6 = new File(['12345'], 'filename.txt', {
  68. type: 'text/plain',
  69. lastModified: date1.getTime()
  70. })
  71. // Identical file object references
  72. expect(looseEqual(file1, file1)).toBe(true)
  73. // Different file references with identical values
  74. expect(looseEqual(file1, file2)).toBe(true)
  75. // Files with slightly different dates
  76. expect(looseEqual(file1, file3)).toBe(false)
  77. // Two different file types
  78. expect(looseEqual(file1, file4)).toBe(false)
  79. // Two files with same name, modified date, but different content
  80. expect(looseEqual(file5, file6)).toBe(false)
  81. })
  82. test('compares arrays correctly', () => {
  83. const arr1 = [1, 2, 3, 4]
  84. const arr2 = [1, 2, 3, '4']
  85. const arr3 = [1, 2, 3, 4, 5]
  86. const arr4 = [1, 2, 3, 4, { a: 5 }]
  87. // Identical array references
  88. expect(looseEqual(arr1, arr1)).toBe(true)
  89. // Different array references with identical values
  90. expect(looseEqual(arr1, arr1.slice())).toBe(true)
  91. expect(looseEqual(arr4, arr4.slice())).toBe(true)
  92. // Array with one value different (loose)
  93. expect(looseEqual(arr1, arr2)).toBe(true)
  94. // Array with one value different
  95. expect(looseEqual(arr3, arr4)).toBe(false)
  96. // Arrays with different lengths
  97. expect(looseEqual(arr1, arr3)).toBe(false)
  98. // Arrays with values in different order
  99. expect(looseEqual(arr1, arr1.slice().reverse())).toBe(false)
  100. })
  101. test('compares RegExp correctly', () => {
  102. const rx1 = /^foo$/
  103. const rx2 = /^foo$/
  104. const rx3 = /^bar$/
  105. const rx4 = /^bar$/i
  106. // Identical regex references
  107. expect(looseEqual(rx1, rx1)).toBe(true)
  108. // Different regex references with identical values
  109. expect(looseEqual(rx1, rx2)).toBe(true)
  110. // Different regex
  111. expect(looseEqual(rx1, rx3)).toBe(false)
  112. // Same regex with different options
  113. expect(looseEqual(rx3, rx4)).toBe(false)
  114. })
  115. test('compares objects correctly', () => {
  116. const obj1 = { foo: 'bar' }
  117. const obj2 = { foo: 'bar1' }
  118. const obj3 = { a: 1, b: 2, c: 3 }
  119. const obj4 = { b: 2, c: 3, a: 1 }
  120. const obj5 = { ...obj4, z: 999 }
  121. const nestedObj1 = { ...obj1, bar: [{ ...obj1 }, { ...obj1 }] }
  122. const nestedObj2 = { ...obj1, bar: [{ ...obj1 }, { ...obj2 }] }
  123. // Identical object references
  124. expect(looseEqual(obj1, obj1)).toBe(true)
  125. // Two objects with identical keys/values
  126. expect(looseEqual(obj1, { ...obj1 })).toBe(true)
  127. // Different key values
  128. expect(looseEqual(obj1, obj2)).toBe(false)
  129. // Keys in different orders
  130. expect(looseEqual(obj3, obj4)).toBe(true)
  131. // One object has additional key
  132. expect(looseEqual(obj4, obj5)).toBe(false)
  133. // Identical object references with nested array
  134. expect(looseEqual(nestedObj1, nestedObj1)).toBe(true)
  135. // Identical object definitions with nested array
  136. expect(looseEqual(nestedObj1, { ...nestedObj1 })).toBe(true)
  137. // Object definitions with nested array (which has different order)
  138. expect(looseEqual(nestedObj1, nestedObj2)).toBe(false)
  139. })
  140. test('compares different types correctly', () => {
  141. const obj1 = {}
  142. const obj2 = { a: 1 }
  143. const obj3 = { 0: 0, 1: 1, 2: 2 }
  144. const arr1: any[] = []
  145. const arr2 = [1]
  146. const arr3 = [0, 1, 2]
  147. const date1 = new Date(2019, 1, 2, 3, 4, 5, 6)
  148. const file1 = new File([''], 'filename.txt', {
  149. type: 'text/plain',
  150. lastModified: date1.getTime()
  151. })
  152. expect(looseEqual(123, '123')).toBe(true)
  153. expect(looseEqual(123, new Date(123))).toBe(false)
  154. expect(looseEqual(`123`, new Date(123))).toBe(false)
  155. expect(looseEqual([1, 2, 3], '1,2,3')).toBe(false)
  156. expect(looseEqual(obj1, arr1)).toBe(false)
  157. expect(looseEqual(obj2, arr2)).toBe(false)
  158. expect(looseEqual(obj1, '[object Object]')).toBe(false)
  159. expect(looseEqual(arr1, '[object Array]')).toBe(false)
  160. expect(looseEqual(obj1, date1)).toBe(false)
  161. expect(looseEqual(obj2, date1)).toBe(false)
  162. expect(looseEqual(arr1, date1)).toBe(false)
  163. expect(looseEqual(arr2, date1)).toBe(false)
  164. expect(looseEqual(obj2, file1)).toBe(false)
  165. expect(looseEqual(arr2, file1)).toBe(false)
  166. expect(looseEqual(date1, file1)).toBe(false)
  167. // Special case where an object's keys are the same as keys (indexes) of an array
  168. expect(looseEqual(obj3, arr3)).toBe(false)
  169. })
  170. test('compares null and undefined values correctly', () => {
  171. expect(looseEqual(null, null)).toBe(true)
  172. expect(looseEqual(undefined, undefined)).toBe(true)
  173. expect(looseEqual(void 0, undefined)).toBe(true)
  174. expect(looseEqual(null, undefined)).toBe(false)
  175. expect(looseEqual(null, void 0)).toBe(false)
  176. expect(looseEqual(null, '')).toBe(false)
  177. expect(looseEqual(null, false)).toBe(false)
  178. expect(looseEqual(undefined, false)).toBe(false)
  179. })
  180. test('compares sparse arrays correctly', () => {
  181. // The following arrays all have a length of 3
  182. // But the first two are "sparse"
  183. const arr1 = []
  184. arr1[2] = true
  185. const arr2 = []
  186. arr2[2] = true
  187. const arr3 = [false, false, true]
  188. const arr4 = [undefined, undefined, true]
  189. // This one is also sparse (missing index 1)
  190. const arr5 = []
  191. arr5[0] = arr5[2] = true
  192. expect(looseEqual(arr1, arr2)).toBe(true)
  193. expect(looseEqual(arr2, arr1)).toBe(true)
  194. expect(looseEqual(arr1, arr3)).toBe(false)
  195. expect(looseEqual(arr3, arr1)).toBe(false)
  196. expect(looseEqual(arr1, arr4)).toBe(true)
  197. expect(looseEqual(arr4, arr1)).toBe(true)
  198. expect(looseEqual(arr1, arr5)).toBe(false)
  199. expect(looseEqual(arr5, arr1)).toBe(false)
  200. })
  201. })