---
description: 进程模块的简单测试
---

# Small Test

在完成了雏形之后，我们需要为进程模块写一些单元测试。

### 创建多个进程并运行

```typescript
it('创建多个进程并运行', () => {
    const module = new PMI()

    Game.time = 0

    let cnt = 0
    let proc0 = module.createProc([() => { cnt++; return OK; }], 'cnt++') // cnt++ 一次
    let proc1 = module.createProc([() => { cnt++; return OK; }], 'cnt++') // cnt++ 一次
    expect(proc0 != proc1).toEqual(true)
    
    module.tick()
    expect(cnt).toEqual(2)
    expect(() => module.tick()).toThrow()
    Game.time = 1

    module.createProc([() => { cnt += 3; return OK_STOP_CURRENT; }], 'cnt+=3') // cnt+=3 无数次
    
    module.tick()
    expect(cnt).toEqual(5)
    Game.time = 2
    module.tick()
    expect(cnt).toEqual(8)

    module.createProc([["START", () => {cnt += 1; return OK_STOP_NEXT;}], ["JUMP", () => true, "START"]], 'cnt+=1') // cnt += 1 无数次

    Game.time = 3
    module.tick()
    expect(cnt).toEqual(12)

    expect(() => {
        for (let i = 0; i < MAX_PROC_ID - 2 + 1; i++)
            module.createProc([() => OK], '')
    }).toThrow()
    
    Game.time = 4
    module.tick()

    let _cnt = 0
    module.createProc([
        ["0", () => { _cnt += 1; return [OK_STOP_CUSTOM, "2"] }], 
        ["1", () => { _cnt += 2; return [OK_STOP_CUSTOM, "3"] }],
        ["2", () => { _cnt += 3; return [OK_STOP_CUSTOM, "1"] }],
        ["3", () => { _cnt += 4; return OK }],
    ], "")

    Game.time++
    module.tick()
    expect(_cnt).toBe(1)

    Game.time++
    module.tick()
    expect(_cnt).toBe(4)

    Game.time++
    module.tick()
    expect(_cnt).toBe(6)

    Game.time++
    module.tick()
    expect(_cnt).toBe(10)

    module.createProc([() => [OK_STOP_CUSTOM, "not_exist"]], "")
    Game.time++
    expect(() => module.tick()).toThrow()
})
```

### 锁的创建，获得，释放与销毁

```typescript
it("锁的创建，获得，释放与销毁", () => {
    const module = new PMI()
    const lockId = module.lock.createLock()

    let cnt = 0
    Game.time = 0
    module.createProc([() => module.lock.acquireLock(lockId), () => { cnt++; return OK_STOP_NEXT; }, () => module.lock.releaseLock(lockId)], '')
    module.createProc([() => module.lock.acquireLock(lockId), () => { cnt++; return OK_STOP_NEXT; }, () => module.lock.releaseLock(lockId)], '')
    module.createProc([() => module.lock.acquireLock(lockId), () => { cnt++; return OK_STOP_NEXT; }, () => module.lock.releaseLock(lockId)], '')
    module.createProc([() => module.lock.acquireLock(lockId), () => { cnt++; return OK_STOP_NEXT; }, () => module.lock.releaseLock(lockId)], '')
    module.createProc([() => module.lock.acquireLock(lockId), () => { cnt++; return OK_STOP_NEXT; }, () => module.lock.releaseLock(lockId)], '')
    module.tick()
    expect(cnt).toBe(1)

    Game.time = 1
    module.tick()
    expect(cnt).toBe(2)

    module.lock.destroyLock(lockId)
    Game.time = 2
    module.tick()
    expect(cnt).toBe(5)
})
```

### 信号集的创建, 获得, 激活与释放

```typescript
it("信号集的创建, 获得, 激活与释放", () => {
    const module = new PMI()
    const signalLock0 = module.signal.createSignal(1)
    const signalLock1 = module.signal.createSignal(1)

    let cnt = 0
    Game.time = 0
    module.createProc([() => module.signal.Swait({signalId: signalLock0, lowerbound: 1, request: 1}, {signalId: signalLock1, lowerbound: 1, request: 1}), () => { cnt+=1; return OK_STOP_NEXT; }, () => { module.signal.Ssignal({signalId: signalLock0, request: 1}); return OK_STOP_NEXT; }, () => module.signal.Ssignal({signalId: signalLock1, request: 1})], "0,1")
    module.createProc([() => module.signal.Swait({signalId: signalLock0, lowerbound: 1, request: 1}, {signalId: signalLock1, lowerbound: 1, request: 1}), () => { cnt+=2; return OK_STOP_NEXT; }, () => { module.signal.Ssignal({signalId: signalLock0, request: 1}); return OK_STOP_NEXT; }, () => module.signal.Ssignal({signalId: signalLock1, request: 1})], "0,1")

    module.createProc([() => module.signal.Swait({signalId: signalLock0, lowerbound: 1, request: 1}), () => { cnt+=3; return OK_STOP_NEXT; }, () => module.signal.Ssignal({signalId: signalLock0, request: 1})], "0")

    module.createProc([() => module.signal.Swait({signalId: signalLock1, lowerbound: 1, request: 1}), () => { cnt+=4; return OK_STOP_NEXT; }, () => module.signal.Ssignal({signalId: signalLock1, request: 1})], "1")
    module.tick()
    expect(cnt).toBe(1)

    Game.time++
    module.tick()
    expect(cnt).toBe(4)

    Game.time++
    module.tick()
    expect(cnt).toBe(8)

    Game.time++
    module.tick()
    expect(cnt).toBe(10)

    const energySignal = module.signal.createSignal(0)
    const capacitySignal = module.signal.createSignal(300)

    let spawned0 = false
    let spawned1 = false

    module.createProc([() => module.signal.Swait({signalId: energySignal, lowerbound: 150, request: 150}), () => {spawned0 = true; return OK;}, () => module.signal.Ssignal({signalId: capacitySignal, request: 150})], "spawn 0")
    module.createProc([() => module.signal.Swait({signalId: energySignal, lowerbound: 150, request: 150}), () => {spawned1 = true; return OK;}, () => module.signal.Ssignal({signalId: capacitySignal, request: 150})], "spawn 1")

    module.createProc([["_START", () => OK], () => module.signal.Swait({signalId: capacitySignal, lowerbound: 50, request: 50}), () => module.signal.Ssignal({signalId: energySignal, request: 50}), () => OK_STOP_NEXT, ["JUMP", () => true, "_START"]], "Generate 50")

    Game.time++
    module.tick()

    Game.time++
    module.tick()
    expect(spawned0).toBe(false)
    expect(spawned1).toBe(false)

    Game.time++
    module.tick()
    expect(spawned0).toBe(true)
    expect(spawned1).toBe(false)

    Game.time++
    module.tick()

    Game.time++
    module.tick()
    expect(spawned1).toBe(false)

    Game.time++
    module.tick()
    expect(spawned1).toBe(true)
})
```
