// 带有value的对象可响应it('should hold a value',()=>{const a =ref(1)expect(a.value).toBe(1)
a.value =2expect(a.value).toBe(2)})it('should be reactive',()=>{const a =ref(1)let dummy
let calls =0effect(()=>{
calls++
dummy = a.value
})expect(calls).toBe(1)expect(dummy).toBe(1)
a.value =2expect(calls).toBe(2)expect(dummy).toBe(2)// same value should not trigger
a.value =2expect(calls).toBe(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 =2expect(dummy).toBe(2)})
// 传递空值可响应it('should work without initial value',()=>{const a =ref()let dummy
effect(()=>{
dummy = a.value
})expect(dummy).toBe(undefined)
a.value =2expect(dummy).toBe(2)})
// ref 在 reactive 中会嵌套时解开被转换成原始值而非refit('should work like a normal property when nested in a reactive object',()=>{const a =ref(1)const obj =reactive({
a,
b:{
c: a
}})let dummy1: number
let dummy2: number
effect(()=>{
dummy1 = obj.a
dummy2 = obj.b.c
})constassertDummiesEqualTo=(val: number)=>[dummy1, dummy2].forEach(dummy=>expect(dummy).toBe(val))assertDummiesEqualTo(1)
a.value++assertDummiesEqualTo(2)
obj.a++assertDummiesEqualTo(3)
obj.b.c++assertDummiesEqualTo(4)})
//嵌套时自动解开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 NOT unwrap ref types nested inside arrays',()=>{const arr =ref([1,ref(1)]).value
;(arr[0]as number)++;(arr[1]as Ref<number>).value++const arr2 =ref([1,newMap<string, any>(),ref('1')]).value
const value = arr2[0]if(isRef(value)){
value +'foo'}elseif(typeof value ==='number'){
value +1}else{// should narrow down to Map type// and not contain any Ref type
value.has('foo')}})