mirror of
https://github.com/vuejs/vue.git
synced 2024-11-21 20:28:54 +00:00
wip: shallowReactive/shallowReadonly
This commit is contained in:
parent
a5ad708ccf
commit
f29ad1def5
@ -81,7 +81,7 @@ export function computed<T>(
|
||||
} as any
|
||||
|
||||
def(ref, RefFlag, true)
|
||||
def(ref, ReactiveFlags.IS_READONLY, true)
|
||||
def(ref, ReactiveFlags.IS_READONLY, onlyGetter)
|
||||
|
||||
return ref
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { observe, Observer } from 'core/observer'
|
||||
import { def, isPrimitive, warn, toRawType } from 'core/util'
|
||||
import { def, isArray, isPrimitive, warn, toRawType } from 'core/util'
|
||||
import type { Ref, UnwrapRefSimple, RawSymbol } from './ref'
|
||||
|
||||
export const enum ReactiveFlags {
|
||||
@ -22,20 +22,7 @@ export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRefSimple<T>
|
||||
|
||||
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
|
||||
export function reactive(target: object) {
|
||||
// if trying to observe a readonly proxy, return the readonly version.
|
||||
if (!isReadonly(target)) {
|
||||
const ob = observe(target)
|
||||
if (__DEV__ && !ob) {
|
||||
if (target == null || isPrimitive(target)) {
|
||||
warn(`value cannot be made reactive: ${String(target)}`)
|
||||
}
|
||||
if (isCollectionType(target)) {
|
||||
warn(
|
||||
`Vue 2 does not support reactive collection types such as Map or Set.`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
makeReactive(target, false)
|
||||
return target
|
||||
}
|
||||
|
||||
@ -51,10 +38,49 @@ export type ShallowReactive<T> = T & { [ShallowReactiveMarker]?: true }
|
||||
export function shallowReactive<T extends object>(
|
||||
target: T
|
||||
): ShallowReactive<T> {
|
||||
// TODO
|
||||
makeReactive(target, true)
|
||||
def(target, ReactiveFlags.IS_SHALLOW, true)
|
||||
return target
|
||||
}
|
||||
|
||||
function makeReactive(target: any, shallow: boolean) {
|
||||
// if trying to observe a readonly proxy, return the readonly version.
|
||||
if (!isReadonly(target)) {
|
||||
if (__DEV__) {
|
||||
if (isArray(target)) {
|
||||
warn(
|
||||
`Avoid using Array as root value for ${
|
||||
shallow ? `shallowReactive()` : `reactive()`
|
||||
} as it cannot be tracked in watch() or watchEffect(). Use ${
|
||||
shallow ? `shallowRef()` : `ref()`
|
||||
} instead. This is a Vue-2-only limitation.`
|
||||
)
|
||||
}
|
||||
const existingOb = target && target.__ob__
|
||||
if (existingOb && existingOb.shallow !== shallow) {
|
||||
warn(
|
||||
`Target is already a ${
|
||||
existingOb.shallow ? `` : `non-`
|
||||
}shallow reactive object, and cannot be converted to ${
|
||||
shallow ? `` : `non-`
|
||||
}shallow.`
|
||||
)
|
||||
}
|
||||
}
|
||||
const ob = observe(target, shallow)
|
||||
if (__DEV__ && !ob) {
|
||||
if (target == null || isPrimitive(target)) {
|
||||
warn(`value cannot be made reactive: ${String(target)}`)
|
||||
}
|
||||
if (isCollectionType(target)) {
|
||||
warn(
|
||||
`Vue 2 does not support reactive collection types such as Map or Set.`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function isReactive(value: unknown): boolean {
|
||||
if (isReadonly(value)) {
|
||||
return isReactive((value as Target)[ReactiveFlags.RAW])
|
||||
|
@ -33,10 +33,15 @@ export type DeepReadonly<T> = T extends Builtin
|
||||
: Readonly<T>
|
||||
|
||||
const rawToReadonlyFlag = `__v_rawToReadonly`
|
||||
const rawToShallowReadonlyFlag = `__v_rawToShallowReadonly`
|
||||
|
||||
export function readonly<T extends object>(
|
||||
target: T
|
||||
): DeepReadonly<UnwrapNestedRefs<T>> {
|
||||
return createReadonly(target, false)
|
||||
}
|
||||
|
||||
function createReadonly(target: any, shallow: boolean) {
|
||||
if (!isPlainObject(target)) {
|
||||
if (__DEV__) {
|
||||
if (isArray(target)) {
|
||||
@ -58,13 +63,14 @@ export function readonly<T extends object>(
|
||||
}
|
||||
|
||||
// already has a readonly proxy
|
||||
const existingProxy = target[rawToReadonlyFlag]
|
||||
const existingFlag = shallow ? rawToShallowReadonlyFlag : rawToReadonlyFlag
|
||||
const existingProxy = target[existingFlag]
|
||||
if (existingProxy) {
|
||||
return existingProxy
|
||||
}
|
||||
|
||||
const proxy = {}
|
||||
def(target, rawToReadonlyFlag, proxy)
|
||||
def(target, existingFlag, proxy)
|
||||
|
||||
def(proxy, ReactiveFlags.IS_READONLY, true)
|
||||
def(proxy, ReactiveFlags.RAW, target)
|
||||
@ -72,25 +78,30 @@ export function readonly<T extends object>(
|
||||
if (isRef(target)) {
|
||||
def(proxy, RefFlag, true)
|
||||
}
|
||||
if (isShallow(target)) {
|
||||
if (shallow || isShallow(target)) {
|
||||
def(proxy, ReactiveFlags.IS_SHALLOW, true)
|
||||
}
|
||||
|
||||
const keys = Object.keys(target)
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
defineReadonlyProperty(proxy, target, keys[i])
|
||||
defineReadonlyProperty(proxy, target, keys[i], shallow)
|
||||
}
|
||||
|
||||
return proxy as any
|
||||
}
|
||||
|
||||
function defineReadonlyProperty(proxy: any, target: any, key: string) {
|
||||
function defineReadonlyProperty(
|
||||
proxy: any,
|
||||
target: any,
|
||||
key: string,
|
||||
shallow: boolean
|
||||
) {
|
||||
Object.defineProperty(proxy, key, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get() {
|
||||
const val = target[key]
|
||||
return isPlainObject(val) ? readonly(val) : val
|
||||
return shallow || !isPlainObject(val) ? val : readonly(val)
|
||||
},
|
||||
set() {
|
||||
__DEV__ &&
|
||||
@ -106,5 +117,5 @@ function defineReadonlyProperty(proxy: any, target: any, key: string) {
|
||||
* This is used for creating the props proxy object for stateful components.
|
||||
*/
|
||||
export function shallowReadonly<T extends object>(target: T): Readonly<T> {
|
||||
return target as any
|
||||
return createReadonly(target, true)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ export function initState(vm: Component) {
|
||||
if (opts.data) {
|
||||
initData(vm)
|
||||
} else {
|
||||
observe((vm._data = {}), true /* asRootData */)
|
||||
observe((vm._data = {}))!.vmCount++
|
||||
}
|
||||
if (opts.computed) initComputed(vm, opts.computed)
|
||||
if (opts.watch && opts.watch !== nativeWatch) {
|
||||
@ -148,7 +148,7 @@ function initData(vm: Component) {
|
||||
}
|
||||
}
|
||||
// observe data
|
||||
observe(data, true /* asRootData */)
|
||||
observe(data)!.vmCount++
|
||||
}
|
||||
|
||||
export function getData(data: Function, vm: Component): any {
|
||||
|
@ -36,12 +36,11 @@ export function toggleObserving(value: boolean) {
|
||||
* collect dependencies and dispatch updates.
|
||||
*/
|
||||
export class Observer {
|
||||
value: any
|
||||
dep: Dep
|
||||
vmCount: number // number of vms that have this object as root $data
|
||||
|
||||
constructor(value: any) {
|
||||
this.value = value
|
||||
constructor(public value: any, public shallow = false) {
|
||||
// this.value = value
|
||||
this.dep = new Dep()
|
||||
this.vmCount = 0
|
||||
def(value, '__ob__', this)
|
||||
@ -51,9 +50,11 @@ export class Observer {
|
||||
} else {
|
||||
copyAugment(value, arrayMethods, arrayKeys)
|
||||
}
|
||||
this.observeArray(value)
|
||||
if (!shallow) {
|
||||
this.observeArray(value)
|
||||
}
|
||||
} else {
|
||||
this.walk(value)
|
||||
this.walk(value, shallow)
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,10 +63,11 @@ export class Observer {
|
||||
* getter/setters. This method should only be called when
|
||||
* value type is Object.
|
||||
*/
|
||||
walk(obj: object) {
|
||||
walk(obj: object, shallow: boolean) {
|
||||
const keys = Object.keys(obj)
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
defineReactive(obj, keys[i])
|
||||
const key = keys[i]
|
||||
defineReactive(obj, key, obj[key], undefined, shallow)
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +110,7 @@ function copyAugment(target: Object, src: Object, keys: Array<string>) {
|
||||
* returns the new observer if successfully observed,
|
||||
* or the existing observer if the value already has one.
|
||||
*/
|
||||
export function observe(value: any, asRootData?: boolean): Observer | void {
|
||||
export function observe(value: any, shallow?: boolean): Observer | void {
|
||||
if (!isObject(value) || isRef(value) || value instanceof VNode) {
|
||||
return
|
||||
}
|
||||
@ -122,10 +124,7 @@ export function observe(value: any, asRootData?: boolean): Observer | void {
|
||||
Object.isExtensible(value) &&
|
||||
!value.__v_skip
|
||||
) {
|
||||
ob = new Observer(value)
|
||||
}
|
||||
if (asRootData && ob) {
|
||||
ob.vmCount++
|
||||
ob = new Observer(value, shallow)
|
||||
}
|
||||
return ob
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ describe('reactivity/ref', () => {
|
||||
})
|
||||
|
||||
test('toRefs reactive array', () => {
|
||||
const arr = reactive(['a', 'b', 'c'])
|
||||
const { arr } = reactive({ arr: ['a', 'b', 'c'] })
|
||||
const refs = toRefs(arr)
|
||||
|
||||
expect(Array.isArray(refs)).toBe(true)
|
||||
|
@ -0,0 +1,169 @@
|
||||
import {
|
||||
isReactive,
|
||||
isShallow,
|
||||
reactive,
|
||||
shallowReactive,
|
||||
shallowReadonly
|
||||
} from 'vca/index'
|
||||
|
||||
describe('shallowReactive', () => {
|
||||
test('should not make non-reactive properties reactive', () => {
|
||||
const props = shallowReactive({ n: { foo: 1 } })
|
||||
expect(isReactive(props.n)).toBe(false)
|
||||
})
|
||||
|
||||
test('should keep reactive properties reactive', () => {
|
||||
const props: any = shallowReactive({ n: reactive({ foo: 1 }) })
|
||||
props.n = reactive({ foo: 2 })
|
||||
expect(isReactive(props.n)).toBe(true)
|
||||
})
|
||||
|
||||
test('isShallow', () => {
|
||||
expect(isShallow(shallowReactive({}))).toBe(true)
|
||||
expect(isShallow(shallowReadonly({}))).toBe(true)
|
||||
})
|
||||
|
||||
// #5271
|
||||
test('should respect shallow reactive nested inside reactive on reset', () => {
|
||||
const r = reactive({ foo: shallowReactive({ bar: {} }) })
|
||||
expect(isShallow(r.foo)).toBe(true)
|
||||
expect(isReactive(r.foo.bar)).toBe(false)
|
||||
|
||||
r.foo = shallowReactive({ bar: {} })
|
||||
expect(isShallow(r.foo)).toBe(true)
|
||||
expect(isReactive(r.foo.bar)).toBe(false)
|
||||
})
|
||||
|
||||
// @discrepancy no shallow/non-shallow versions from the same source -
|
||||
// cannot support this without real proxies
|
||||
// #2843
|
||||
// test('should allow shallow and normal reactive for same target', () => {
|
||||
// const original = { foo: {} }
|
||||
// const shallowProxy = shallowReactive(original)
|
||||
// const reactiveProxy = reactive(original)
|
||||
// expect(shallowProxy).not.toBe(reactiveProxy)
|
||||
// expect(isReactive(shallowProxy.foo)).toBe(false)
|
||||
// expect(isReactive(reactiveProxy.foo)).toBe(true)
|
||||
// })
|
||||
|
||||
// test('should respect shallow/deep versions of same target on access', () => {
|
||||
// const original = {}
|
||||
// const shallow = shallowReactive(original)
|
||||
// const deep = reactive(original)
|
||||
// const r = reactive({ shallow, deep })
|
||||
// expect(r.shallow).toBe(shallow)
|
||||
// expect(r.deep).toBe(deep)
|
||||
// })
|
||||
|
||||
// @discrepancy Vue 2 does not support collections
|
||||
// describe('collections', () => {
|
||||
// test('should be reactive', () => {
|
||||
// const shallowSet = shallowReactive(new Set())
|
||||
// const a = {}
|
||||
// let size
|
||||
|
||||
// effect(() => {
|
||||
// size = shallowSet.size
|
||||
// })
|
||||
|
||||
// expect(size).toBe(0)
|
||||
|
||||
// shallowSet.add(a)
|
||||
// expect(size).toBe(1)
|
||||
|
||||
// shallowSet.delete(a)
|
||||
// expect(size).toBe(0)
|
||||
// })
|
||||
|
||||
// test('should not observe when iterating', () => {
|
||||
// const shallowSet = shallowReactive(new Set())
|
||||
// const a = {}
|
||||
// shallowSet.add(a)
|
||||
|
||||
// const spreadA = [...shallowSet][0]
|
||||
// expect(isReactive(spreadA)).toBe(false)
|
||||
// })
|
||||
|
||||
// test('should not get reactive entry', () => {
|
||||
// const shallowMap = shallowReactive(new Map())
|
||||
// const a = {}
|
||||
// const key = 'a'
|
||||
|
||||
// shallowMap.set(key, a)
|
||||
|
||||
// expect(isReactive(shallowMap.get(key))).toBe(false)
|
||||
// })
|
||||
|
||||
// test('should not get reactive on foreach', () => {
|
||||
// const shallowSet = shallowReactive(new Set())
|
||||
// const a = {}
|
||||
// shallowSet.add(a)
|
||||
|
||||
// shallowSet.forEach(x => expect(isReactive(x)).toBe(false))
|
||||
// })
|
||||
|
||||
// // #1210
|
||||
// test('onTrack on called on objectSpread', () => {
|
||||
// const onTrackFn = vi.fn()
|
||||
// const shallowSet = shallowReactive(new Set())
|
||||
// let a
|
||||
// effect(
|
||||
// () => {
|
||||
// a = Array.from(shallowSet)
|
||||
// },
|
||||
// {
|
||||
// onTrack: onTrackFn
|
||||
// }
|
||||
// )
|
||||
|
||||
// expect(a).toMatchObject([])
|
||||
// expect(onTrackFn).toHaveBeenCalled()
|
||||
// })
|
||||
// })
|
||||
|
||||
// @discrepancy Vue 2 does not track array without access
|
||||
// describe('array', () => {
|
||||
// test('should be reactive', () => {
|
||||
// const shallowArray = shallowReactive<unknown[]>([])
|
||||
// const a = {}
|
||||
// let size
|
||||
|
||||
// effect(() => {
|
||||
// size = shallowArray.length
|
||||
// })
|
||||
|
||||
// expect(size).toBe(0)
|
||||
|
||||
// shallowArray.push(a)
|
||||
// expect(size).toBe(1)
|
||||
|
||||
// shallowArray.pop()
|
||||
// expect(size).toBe(0)
|
||||
// })
|
||||
// test('should not observe when iterating', () => {
|
||||
// const shallowArray = shallowReactive<object[]>([])
|
||||
// const a = {}
|
||||
// shallowArray.push(a)
|
||||
|
||||
// const spreadA = [...shallowArray][0]
|
||||
// expect(isReactive(spreadA)).toBe(false)
|
||||
// })
|
||||
|
||||
// test('onTrack on called on objectSpread', () => {
|
||||
// const onTrackFn = vi.fn()
|
||||
// const shallowArray = shallowReactive([])
|
||||
// let a
|
||||
// effect(
|
||||
// () => {
|
||||
// a = Array.from(shallowArray)
|
||||
// },
|
||||
// {
|
||||
// onTrack: onTrackFn
|
||||
// }
|
||||
// )
|
||||
|
||||
// expect(a).toMatchObject([])
|
||||
// expect(onTrackFn).toHaveBeenCalled()
|
||||
// })
|
||||
// })
|
||||
})
|
@ -0,0 +1,206 @@
|
||||
import { isReactive, shallowReadonly, readonly, isReadonly } from 'vca/index'
|
||||
|
||||
describe('reactivity/shallowReadonly', () => {
|
||||
test('should be readonly', () => {
|
||||
expect(isReadonly(shallowReadonly({}))).toBe(true)
|
||||
})
|
||||
|
||||
test('should not make non-reactive properties reactive', () => {
|
||||
const props = shallowReadonly({ n: { foo: 1 } })
|
||||
expect(isReactive(props.n)).toBe(false)
|
||||
})
|
||||
|
||||
test('should make root level properties readonly', () => {
|
||||
const props = shallowReadonly({ n: 1 })
|
||||
// @ts-expect-error
|
||||
props.n = 2
|
||||
expect(props.n).toBe(1)
|
||||
expect(
|
||||
`Set operation on key "n" failed: target is readonly.`
|
||||
).toHaveBeenWarned()
|
||||
})
|
||||
|
||||
// to retain 2.x behavior.
|
||||
test('should NOT make nested properties readonly', () => {
|
||||
const props = shallowReadonly({ n: { foo: 1 } })
|
||||
|
||||
props.n.foo = 2
|
||||
expect(props.n.foo).toBe(2)
|
||||
expect(
|
||||
`Set operation on key "foo" failed: target is readonly.`
|
||||
).not.toHaveBeenWarned()
|
||||
})
|
||||
|
||||
// #2843
|
||||
test('should differentiate from normal readonly calls', () => {
|
||||
const original = { foo: {} }
|
||||
const shallowProxy = shallowReadonly(original)
|
||||
const reactiveProxy = readonly(original)
|
||||
expect(shallowProxy).not.toBe(reactiveProxy)
|
||||
expect(isReadonly(shallowProxy.foo)).toBe(false)
|
||||
expect(isReadonly(reactiveProxy.foo)).toBe(true)
|
||||
})
|
||||
|
||||
// @discrepancy does not support collections
|
||||
// describe('collection/Map', () => {
|
||||
// ;[Map, WeakMap].forEach(Collection => {
|
||||
// test('should make the map/weak-map readonly', () => {
|
||||
// const key = {}
|
||||
// const val = { foo: 1 }
|
||||
// const original = new Collection([[key, val]])
|
||||
// const sroMap = shallowReadonly(original)
|
||||
// expect(isReadonly(sroMap)).toBe(true)
|
||||
// expect(isReactive(sroMap)).toBe(false)
|
||||
// expect(sroMap.get(key)).toBe(val)
|
||||
|
||||
// sroMap.set(key, {} as any)
|
||||
// expect(
|
||||
// `Set operation on key "[object Object]" failed: target is readonly.`
|
||||
// ).toHaveBeenWarned()
|
||||
// })
|
||||
|
||||
// test('should not make nested values readonly', () => {
|
||||
// const key = {}
|
||||
// const val = { foo: 1 }
|
||||
// const original = new Collection([[key, val]])
|
||||
// const sroMap = shallowReadonly(original)
|
||||
// expect(isReadonly(sroMap.get(key))).toBe(false)
|
||||
// expect(isReactive(sroMap.get(key))).toBe(false)
|
||||
|
||||
// sroMap.get(key)!.foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
// })
|
||||
// })
|
||||
|
||||
// test('should not make the value generated by the iterable method readonly', () => {
|
||||
// const key = {}
|
||||
// const val = { foo: 1 }
|
||||
// const original = new Map([[key, val]])
|
||||
// const sroMap = shallowReadonly(original)
|
||||
|
||||
// const values1 = [...sroMap.values()]
|
||||
// const values2 = [...sroMap.entries()]
|
||||
|
||||
// expect(isReadonly(values1[0])).toBe(false)
|
||||
// expect(isReactive(values1[0])).toBe(false)
|
||||
// expect(values1[0]).toBe(val)
|
||||
|
||||
// values1[0].foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
|
||||
// expect(isReadonly(values2[0][1])).toBe(false)
|
||||
// expect(isReactive(values2[0][1])).toBe(false)
|
||||
// expect(values2[0][1]).toBe(val)
|
||||
|
||||
// values2[0][1].foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
// })
|
||||
|
||||
// test('should not make the value generated by the forEach method readonly', () => {
|
||||
// const val = { foo: 1 }
|
||||
// const original = new Map([['key', val]])
|
||||
// const sroMap = shallowReadonly(original)
|
||||
|
||||
// sroMap.forEach(val => {
|
||||
// expect(isReadonly(val)).toBe(false)
|
||||
// expect(isReactive(val)).toBe(false)
|
||||
// expect(val).toBe(val)
|
||||
|
||||
// val.foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
|
||||
// describe('collection/Set', () => {
|
||||
// test('should make the set/weak-set readonly', () => {
|
||||
// ;[Set, WeakSet].forEach(Collection => {
|
||||
// const obj = { foo: 1 }
|
||||
// const original = new Collection([obj])
|
||||
// const sroSet = shallowReadonly(original)
|
||||
// expect(isReadonly(sroSet)).toBe(true)
|
||||
// expect(isReactive(sroSet)).toBe(false)
|
||||
// expect(sroSet.has(obj)).toBe(true)
|
||||
|
||||
// sroSet.add({} as any)
|
||||
// expect(
|
||||
// `Add operation on key "[object Object]" failed: target is readonly.`
|
||||
// ).toHaveBeenWarned()
|
||||
// })
|
||||
// })
|
||||
|
||||
// test('should not make nested values readonly', () => {
|
||||
// const obj = { foo: 1 }
|
||||
// const original = new Set([obj])
|
||||
// const sroSet = shallowReadonly(original)
|
||||
|
||||
// const values = [...sroSet.values()]
|
||||
|
||||
// expect(values[0]).toBe(obj)
|
||||
// expect(isReadonly(values[0])).toBe(false)
|
||||
// expect(isReactive(values[0])).toBe(false)
|
||||
|
||||
// sroSet.add({} as any)
|
||||
// expect(
|
||||
// `Add operation on key "[object Object]" failed: target is readonly.`
|
||||
// ).toHaveBeenWarned()
|
||||
|
||||
// values[0].foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
// })
|
||||
|
||||
// test('should not make the value generated by the iterable method readonly', () => {
|
||||
// const val = { foo: 1 }
|
||||
// const original = new Set([val])
|
||||
// const sroSet = shallowReadonly(original)
|
||||
|
||||
// const values1 = [...sroSet.values()]
|
||||
// const values2 = [...sroSet.entries()]
|
||||
|
||||
// expect(isReadonly(values1[0])).toBe(false)
|
||||
// expect(isReactive(values1[0])).toBe(false)
|
||||
// expect(values1[0]).toBe(val)
|
||||
|
||||
// values1[0].foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
|
||||
// expect(isReadonly(values2[0][1])).toBe(false)
|
||||
// expect(isReactive(values2[0][1])).toBe(false)
|
||||
// expect(values2[0][1]).toBe(val)
|
||||
|
||||
// values2[0][1].foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
// })
|
||||
|
||||
// test('should not make the value generated by the forEach method readonly', () => {
|
||||
// const val = { foo: 1 }
|
||||
// const original = new Set([val])
|
||||
// const sroSet = shallowReadonly(original)
|
||||
|
||||
// sroSet.forEach(val => {
|
||||
// expect(isReadonly(val)).toBe(false)
|
||||
// expect(isReactive(val)).toBe(false)
|
||||
// expect(val).toBe(val)
|
||||
|
||||
// val.foo = 2
|
||||
// expect(
|
||||
// `Set operation on key "foo" failed: target is readonly.`
|
||||
// ).not.toHaveBeenWarned()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
})
|
Loading…
Reference in New Issue
Block a user