Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfisher committed Jun 9, 2024
1 parent 17fd0b2 commit cca7e38
Show file tree
Hide file tree
Showing 16 changed files with 403 additions and 161 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export function createForm<State extends Dict=Dict>(schema: FormSchema<State>,op
// 所有计算函数的上下文均指向根
computedThis: ()=>ComputedScopeRef.Root,
// 计算函数作用域默认指向fields
computedScope: ()=>[FIELDS_STATE_KEY],
scope: ()=>[FIELDS_STATE_KEY],
// 创建计算函数时的钩子函数,可以在创建前做一些不可描述的处理
onCreateComputed(valuePath,getter,options) {
// 1. 只对validator进行处理,目的是使validate函数依赖于当前字段的值value,将使得validate函数的第一个参数总是当前字段的值
Expand Down
92 changes: 92 additions & 0 deletions packages/reactive/src/__tests__/computed.async.base.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { test,expect, describe, beforeAll } from "vitest"
import { createStore,ComputedScopeRef,computed, IStore, Dict } from ".."
import { delay } from "flex-tools/async/delay"

describe("简单异步计算",()=>{

test("异步计算原地替换创建AsyncComputed数据结构",async ()=>{
return new Promise<void>((resolve)=>{
const store = createStore({
price:2,
count:3,
total:async (scope:any)=>{
await delay(10)
return scope.price * scope.count
}
})
store.state.total
expect(store.state.total.loading).toBe(true) // 由于计算属性会马上执行一次,所以loading=true
expect(store.state.total.cancel).toBeDefined()
expect(store.state.total.error).toBeDefined()
expect(store.state.total.loading).toBeDefined()
expect(store.state.total.progress).toBeDefined()
expect(store.state.total.result).toBeUndefined()
expect(store.state.total.retry).toBeDefined()
expect(store.state.total.run).toBeDefined()
expect(store.state.total.timeout).toBeDefined()
resolve()
})
})

test("异步计算初始化时不执行",async ()=>{
return new Promise<void>(async (resolve)=>{
const store = createStore({
price:2,
count:3,
total:computed(async (scope:any)=>{
return scope.price * scope.count
},['price','count'],{
immediate:false // 不马上执行,需要等等依赖变化多端时再执行
})
})
expect(store.state.total.loading).toBe(false)
await delay(10)
resolve()
})
})
test("当异步计算属性依赖变化时自动重新计算",async ()=>{
return new Promise<void>((resolve)=>{
const results:number[] = []
const store = createStore({
price:2,
count:3,
total:computed<number>(async (scope:any)=>{
return scope.price * scope.count
},['price','count'],{
immediate:false // 不马上执行,需要等等依赖变化多端时再执行
})
})
store.setState(draft=>draft.count++)
store.setState(draft=>draft.price++)
// 当计算函数执行完成后的回调
store.on("computed",({path})=>{
results.push(store.state.total.result)

resolve()
})
})
})



test("默认this指向state",()=>{
return new Promise<void>((resolve)=>{
const store = createStore({
order:{
price:2,
count:3,
total:computed(function(this:any){
expect(this.order.price).toBe(2)
expect(this.order.count).toBe(3)
resolve()
})
}
})
store.state.order.total // 读取操作时创建计算属性
})
})



})

38 changes: 38 additions & 0 deletions packages/reactive/src/__tests__/computed.sync.base.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { test,expect, describe, beforeAll } from "vitest"
import { createStore,ComputedScopeRef,computed, IStore } from ".."



describe("基本同步计算",()=>{

test("默认同步计算",async ()=>{
const store = createStore({
price:2,
count:3,
total:computed((scope)=>{
return scope.price * scope.count
})
})
store.setState((draft)=>draft.count = 4)
expect(store.state.total).toBe(8)
})
test("默认this指向state",()=>{
return new Promise<void>((resolve)=>{
const store = createStore({
order:{
price:2,
count:3,
total:computed(function(this:any){
expect(this.order.price).toBe(2)
expect(this.order.count).toBe(3)
resolve()
})
}
})
store.state.order.total // 读取操作时创建计算属性
})
})



})
214 changes: 214 additions & 0 deletions packages/reactive/src/__tests__/computed.sync.scope.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { test,expect, describe, beforeAll } from "vitest"
import { createStore,ComputedScopeRef,computed } from ".."

describe("计算函数的Scope指向",()=>{

test("默认Scope指向Current=order",()=>{
return new Promise<void>((resolve)=>{
const store = createStore({
order:{
price:2,
count:3,
total:computed((scope)=>{
expect(scope.price).toBe(2)
expect(scope.count).toBe(3)
resolve()
})
}
})
store.state.order.total // 读取操作时创建计算属性
})

})
test("Scope指向Root",()=>{
return new Promise<void>((resolve)=>{
const store = createStore({
order:{
price:2,
count:3,
total:computed<number>((scope)=>{
expect(scope.order.price).toBe(2)
expect(scope.order.count).toBe(3)
resolve()
return scope.order.price * scope.order.count
})
}
},{
scope:()=>ComputedScopeRef.Root
})

store.state.order.total // 读取操作时创建计算属性
})
})
test("Scope指向parent",()=>{
return new Promise<void>((resolve)=>{
const store = createStore({
root:{
parent:{
order:{
price:2,
count:3,
total:computed<number>((scope)=>{
expect(scope.order.price).toBe(2)
expect(scope.order.count).toBe(3)
resolve()
return scope.order.price * scope.order.count
})
}
}
}
},{
scope:()=>ComputedScopeRef.Parent
})

store.state.root.parent.order.total // 读取操作时创建计算属性
})
})
test("Scope指向Depends",()=>{
return new Promise<void>((resolve)=>{
const store = createStore({
root:{
parent:{
order:{
price:2,
count:3,
// 当指定Depends时,同步计算通过执行计算函数不收集依赖的,所以第一次执行时,scope是空的
// 所以ComputedScopeRef.Depends在同步计算下是无效的
total:computed<number>((scope)=>{
expect(scope.length).toBe(0)
resolve()
return 0
})
}
}
}
},{
scope:()=>ComputedScopeRef.Depends
})
store.state.root.parent.order.total // 读取操作时创建计算属性
})
})
test("Scope指向字符串指定的绝对路径",()=>{
//
return new Promise<void>((resolve)=>{
const store = createStore({
root:{
parent:{
order:{
price:2,
count:3,
total:computed<number>((scope)=>{
expect(scope).toBe(1)
resolve()
return 0
})
}
},
a:1
}
},{
scope:()=>"/root/a" // 绝对路径需要以/开头
})
store.state.root.parent.order.total // 读取操作时创建计算属性
})
})

test("Scope指向字符串指定的当前对象的相对路径",()=>{
//注意: . 代表的是不是total,而是total所在的对象
return new Promise<void>((resolve)=>{
const store = createStore({
root:{
parent:{
order:{
price:2,
count:3,
total:computed<number>((scope)=>{
expect(scope).toBe(2)
resolve()
return 0
})
}
},
a:1
}
},{
scope:()=>"./price" //.代表的是order
})
store.state.root.parent.order.total // 读取操作时创建计算属性
})
})
test("Scope指向字符串指定的当前对象父对象的相对路径",()=>{
//注意: .. 代表的是不是total,而是total所在的对象
return new Promise<void>((resolve)=>{
const store = createStore({
root:{
parent:{
order:{
price:2,
count:3,
total:computed<number>((scope)=>{
expect(scope).toBe(100)
resolve()
return 0
})
},
x:100
},
a:1
}
},{
scope:()=>"../x" // ..指向parent
})
store.state.root.parent.order.total // 读取操作时创建计算属性
})
})
test("Scope指向字符串指定的多级相对父对象路径",()=>{
//注意: .. 代表的是不是total,而是total所在的对象
return new Promise<void>((resolve)=>{
const store = createStore({
root:{
parent:{
order:{
price:2,
count:3,
total:computed<number>((scope)=>{
expect(scope).toBe(1)
resolve()
return 0
})
},
x:100
},
a:1
}
},{
scope:()=>"../../a" //
})
store.state.root.parent.order.total // 读取操作时创建计算属性
})
})
test("使用字符串数组作为Scope指向的绝对路径",()=>{
//注意: .. 代表的是不是total,而是total所在的对象
return new Promise<void>((resolve)=>{
const store = createStore({
root:{
parent:{
order:{
price:2,
count:3,
total:computed<number>((scope)=>{
expect(scope).toBe(3)
resolve()
return 0
})
}
}
}
},{
scope:()=>["root","parent","order","count"]
})
store.state.root.parent.order.total // 读取操作时创建计算属性
})
})

})
Loading

0 comments on commit cca7e38

Please sign in to comment.