ref.spec.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { ref, effect, reactive, isRef, toRefs } from '../src/index'
  2. import { computed } from '@vue/runtime-dom'
  3. describe('reactivity/ref', () => {
  4. it('should hold a value', () => {
  5. const a = ref(1)
  6. expect(a.value).toBe(1)
  7. a.value = 2
  8. expect(a.value).toBe(2)
  9. })
  10. it('should be reactive', () => {
  11. const a = ref(1)
  12. let dummy
  13. effect(() => {
  14. dummy = a.value
  15. })
  16. expect(dummy).toBe(1)
  17. a.value = 2
  18. expect(dummy).toBe(2)
  19. })
  20. it('should make nested properties reactive', () => {
  21. const a = ref({
  22. count: 1
  23. })
  24. let dummy
  25. effect(() => {
  26. dummy = a.value.count
  27. })
  28. expect(dummy).toBe(1)
  29. a.value.count = 2
  30. expect(dummy).toBe(2)
  31. })
  32. it('should work like a normal property when nested in a reactive object', () => {
  33. const a = ref(1)
  34. const obj = reactive({
  35. a,
  36. b: {
  37. c: a,
  38. d: [a]
  39. }
  40. })
  41. let dummy1
  42. let dummy2
  43. let dummy3
  44. effect(() => {
  45. dummy1 = obj.a
  46. dummy2 = obj.b.c
  47. dummy3 = obj.b.d[0]
  48. })
  49. expect(dummy1).toBe(1)
  50. expect(dummy2).toBe(1)
  51. expect(dummy3).toBe(1)
  52. a.value++
  53. expect(dummy1).toBe(2)
  54. expect(dummy2).toBe(2)
  55. expect(dummy3).toBe(2)
  56. obj.a++
  57. expect(dummy1).toBe(3)
  58. expect(dummy2).toBe(3)
  59. expect(dummy3).toBe(3)
  60. })
  61. it('should unwrap nested values in types', () => {
  62. const a = {
  63. b: ref(0)
  64. }
  65. const c = ref(a)
  66. expect(typeof (c.value.b + 1)).toBe('number')
  67. })
  68. test('isRef', () => {
  69. expect(isRef(ref(1))).toBe(true)
  70. expect(isRef(computed(() => 1))).toBe(true)
  71. expect(isRef(0)).toBe(false)
  72. // an object that looks like a ref isn't necessarily a ref
  73. expect(isRef({ value: 0 })).toBe(false)
  74. })
  75. test('toRefs', () => {
  76. const a = reactive({
  77. x: 1,
  78. y: 2
  79. })
  80. const { x, y } = toRefs(a)
  81. expect(isRef(x)).toBe(true)
  82. expect(isRef(y)).toBe(true)
  83. expect(x.value).toBe(1)
  84. expect(y.value).toBe(2)
  85. // source -> proxy
  86. a.x = 2
  87. a.y = 3
  88. expect(x.value).toBe(2)
  89. expect(y.value).toBe(3)
  90. // proxy -> source
  91. x.value = 3
  92. y.value = 4
  93. expect(a.x).toBe(3)
  94. expect(a.y).toBe(4)
  95. // reactivity
  96. let dummyX, dummyY
  97. effect(() => {
  98. dummyX = x.value
  99. dummyY = y.value
  100. })
  101. expect(dummyX).toBe(x.value)
  102. expect(dummyY).toBe(y.value)
  103. // mutating source should trigger effect using the proxy refs
  104. a.x = 4
  105. a.y = 5
  106. expect(dummyX).toBe(4)
  107. expect(dummyY).toBe(5)
  108. })
  109. })