diff --git a/packages/runtime-vapor/__tests__/for.spec.ts b/packages/runtime-vapor/__tests__/for.spec.ts
index 13d1c1407..28233cbc9 100644
--- a/packages/runtime-vapor/__tests__/for.spec.ts
+++ b/packages/runtime-vapor/__tests__/for.spec.ts
@@ -1,4 +1,9 @@
-import { createFor, renderEffect } from '../src'
+import {
+ createFor,
+ getDefaultValue,
+ getRestElement,
+ renderEffect,
+} from '../src'
import { nextTick, ref, shallowRef, triggerRef } from '@vue/runtime-dom'
import { makeRender } from './_utils'
@@ -257,6 +262,112 @@ describe('createFor', () => {
expect(host.innerHTML).toBe('')
})
+ test('de-structured value (rest element)', async () => {
+ const list = ref([
+ { name: '1', a: 1 },
+ { name: '2', a: 2 },
+ { name: '3', a: 3 },
+ ])
+ function reverse() {
+ list.value = list.value.reverse()
+ }
+
+ const { host } = define(() => {
+ const n1 = createFor(
+ () => list.value,
+ state => {
+ const span = document.createElement('li')
+ renderEffect(() => {
+ span.innerHTML = JSON.stringify(
+ getRestElement(state[0].value, ['name']),
+ )
+ // index should be undefined if source is not an object
+ expect(state[2].value).toBe(undefined)
+ })
+ return span
+ },
+ item => item.name,
+ )
+ return n1
+ }).render()
+
+ expect(host.innerHTML).toBe(
+ '
{"a":1}{"a":2}{"a":3}',
+ )
+
+ // add
+ list.value.push({ name: '4', a: 4 })
+ await nextTick()
+ expect(host.innerHTML).toBe(
+ '{"a":1}{"a":2}{"a":3}{"a":4}',
+ )
+
+ // move
+ reverse()
+ await nextTick()
+ expect(host.innerHTML).toBe(
+ '{"a":4}{"a":3}{"a":2}{"a":1}',
+ )
+
+ reverse()
+ await nextTick()
+ expect(host.innerHTML).toBe(
+ '{"a":1}{"a":2}{"a":3}{"a":4}',
+ )
+
+ // change
+ list.value[0].a = 5
+ await nextTick()
+ expect(host.innerHTML).toBe(
+ '{"a":5}{"a":2}{"a":3}{"a":4}',
+ )
+
+ // remove
+ list.value.splice(1, 1)
+ await nextTick()
+ expect(host.innerHTML).toBe(
+ '{"a":5}{"a":3}{"a":4}',
+ )
+
+ // clear
+ list.value = []
+ await nextTick()
+ expect(host.innerHTML).toBe('')
+ })
+
+ test('de-structured value (default value)', async () => {
+ const list = ref([{ name: '1' }, { name: '2' }, { name: '3' }])
+
+ const { host } = define(() => {
+ const n1 = createFor(
+ () => list.value,
+ state => {
+ const span = document.createElement('li')
+ renderEffect(() => {
+ span.innerHTML = getDefaultValue(state[0].value.x, '0')
+ // index should be undefined if source is not an object
+ expect(state[2].value).toBe(undefined)
+ })
+ return span
+ },
+ item => item.name,
+ )
+ return n1
+ }).render()
+
+ expect(host.innerHTML).toBe('000')
+
+ // change
+ list.value[0].x = 5
+ await nextTick()
+ expect(host.innerHTML).toBe('500')
+
+ // clear
+ list.value = []
+ await nextTick()
+ expect(host.innerHTML).toBe('')
+ })
+
test('shallowRef source', async () => {
const list = shallowRef([{ name: '1' }, { name: '2' }, { name: '3' }])
const setList = (update = list.value.slice()) => (list.value = update)