| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import { ref, effect, reactive, isRef, toRefs, Ref } from '../src/index'
- import { computed } from '@vue/runtime-dom'
- describe('reactivity/ref', () => {
- it('should hold a value', () => {
- const a = ref(1)
- expect(a.value).toBe(1)
- a.value = 2
- expect(a.value).toBe(2)
- })
- it('should be reactive', () => {
- const a = ref(1)
- let dummy
- effect(() => {
- dummy = a.value
- })
- expect(dummy).toBe(1)
- a.value = 2
- expect(dummy).toBe(2)
- })
- it('should make nested properties reactive', () => {
- const a = ref({
- count: 1
- })
- let dummy
- effect(() => {
- dummy = a.value.count
- })
- expect(dummy).toBe(1)
- a.value.count = 2
- expect(dummy).toBe(2)
- })
- it('should work like a normal property when nested in a reactive object', () => {
- const a = ref(1)
- const obj = reactive({
- a,
- b: {
- c: a,
- d: [a]
- }
- })
- let dummy1: number
- let dummy2: number
- let dummy3: number
- effect(() => {
- dummy1 = obj.a
- dummy2 = obj.b.c
- dummy3 = obj.b.d[0]
- })
- const assertDummiesEqualTo = (val: number) =>
- [dummy1, dummy2, dummy3].forEach(dummy => expect(dummy).toBe(val))
- assertDummiesEqualTo(1)
- a.value++
- assertDummiesEqualTo(2)
- obj.a++
- assertDummiesEqualTo(3)
- obj.b.c++
- assertDummiesEqualTo(4)
- obj.b.d[0]++
- assertDummiesEqualTo(5)
- })
- it('should unwrap nested ref in types', () => {
- const a = ref(0)
- const b = ref(a)
- expect(typeof (b.value + 1)).toBe('number')
- })
- it('should unwrap nested values in types', () => {
- const a = {
- b: ref(0)
- }
- const c = ref(a)
- expect(typeof (c.value.b + 1)).toBe('number')
- })
- it('should properly unwrap ref types nested inside arrays', () => {
- const arr = ref([1, ref(1)]).value
- // should unwrap to number[]
- arr[0]++
- arr[1]++
- const arr2 = ref([1, new Map<string, any>(), ref('1')]).value
- const value = arr2[0]
- if (typeof value === 'string') {
- value + 'foo'
- } else if (typeof value === 'number') {
- value + 1
- } else {
- // should narrow down to Map type
- // and not contain any Ref type
- value.has('foo')
- }
- })
- it('should keep tuple types', () => {
- const tuple: [number, string, { a: number }, () => number, Ref<number>] = [
- 0,
- '1',
- { a: 1 },
- () => 0,
- ref(0)
- ]
- const tupleRef = ref(tuple)
- tupleRef.value[0]++
- expect(tupleRef.value[0]).toBe(1)
- tupleRef.value[1] += '1'
- expect(tupleRef.value[1]).toBe('11')
- tupleRef.value[2].a++
- expect(tupleRef.value[2].a).toBe(2)
- expect(tupleRef.value[3]()).toBe(0)
- tupleRef.value[4]++
- expect(tupleRef.value[4]).toBe(1)
- })
- test('isRef', () => {
- expect(isRef(ref(1))).toBe(true)
- expect(isRef(computed(() => 1))).toBe(true)
- expect(isRef(0)).toBe(false)
- expect(isRef(1)).toBe(false)
- // an object that looks like a ref isn't necessarily a ref
- expect(isRef({ value: 0 })).toBe(false)
- })
- test('toRefs', () => {
- const a = reactive({
- x: 1,
- y: 2
- })
- const { x, y } = toRefs(a)
- expect(isRef(x)).toBe(true)
- expect(isRef(y)).toBe(true)
- expect(x.value).toBe(1)
- expect(y.value).toBe(2)
- // source -> proxy
- a.x = 2
- a.y = 3
- expect(x.value).toBe(2)
- expect(y.value).toBe(3)
- // proxy -> source
- x.value = 3
- y.value = 4
- expect(a.x).toBe(3)
- expect(a.y).toBe(4)
- // reactivity
- let dummyX, dummyY
- effect(() => {
- dummyX = x.value
- dummyY = y.value
- })
- expect(dummyX).toBe(x.value)
- expect(dummyY).toBe(y.value)
- // mutating source should trigger effect using the proxy refs
- a.x = 4
- a.y = 5
- expect(dummyX).toBe(4)
- expect(dummyY).toBe(5)
- })
- })
|