ref.spec.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 ref in types', () => {
  62. const a = ref(0)
  63. const b = ref(a)
  64. expect(typeof (b.value + 1)).toBe('number')
  65. })
  66. it('should unwrap nested values in types', () => {
  67. const a = {
  68. b: ref(0)
  69. }
  70. const c = ref(a)
  71. expect(typeof (c.value.b + 1)).toBe('number')
  72. })
  73. test('isRef', () => {
  74. expect(isRef(ref(1))).toBe(true)
  75. expect(isRef(computed(() => 1))).toBe(true)
  76. expect(isRef(0)).toBe(false)
  77. expect(isRef(1)).toBe(false)
  78. // an object that looks like a ref isn't necessarily a ref
  79. expect(isRef({ value: 0 })).toBe(false)
  80. })
  81. test('toRefs', () => {
  82. const a = reactive({
  83. x: 1,
  84. y: 2
  85. })
  86. const { x, y } = toRefs(a)
  87. expect(isRef(x)).toBe(true)
  88. expect(isRef(y)).toBe(true)
  89. expect(x.value).toBe(1)
  90. expect(y.value).toBe(2)
  91. // source -> proxy
  92. a.x = 2
  93. a.y = 3
  94. expect(x.value).toBe(2)
  95. expect(y.value).toBe(3)
  96. // proxy -> source
  97. x.value = 3
  98. y.value = 4
  99. expect(a.x).toBe(3)
  100. expect(a.y).toBe(4)
  101. // reactivity
  102. let dummyX, dummyY
  103. effect(() => {
  104. dummyX = x.value
  105. dummyY = y.value
  106. })
  107. expect(dummyX).toBe(x.value)
  108. expect(dummyY).toBe(y.value)
  109. // mutating source should trigger effect using the proxy refs
  110. a.x = 4
  111. a.y = 5
  112. expect(dummyX).toBe(4)
  113. expect(dummyY).toBe(5)
  114. })
  115. })