UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

108 lines (98 loc) 4.01 kB
import { describe, it } from 'mocha' import { assert } from 'chai' import { newTraceRecorder } from '../../src/runtime/trace' import { QuintApp } from '../../src/ir/quintIr' import { verbosity } from '../../src/verbosity' import { newRng } from '../../src/rng' import { QuintError } from '../../src/quintError' import { left } from '@sweet-monads/either' const emptyFrameError: QuintError = { code: 'QNT501', message: 'empty frame' } describe('newTraceRecorder', () => { it('one layer', () => { const rec = newTraceRecorder(verbosity.maxVerbosity, newRng()) const A: QuintApp = { id: 0n, kind: 'app', opcode: 'A', args: [] } rec.onUserOperatorCall(A) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) rec.onUserOperatorCall(A) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) const trace = rec.currentFrame assert(trace.subframes.length === 2) assert(trace.subframes[0].app === A) assert(trace.subframes[0].subframes.length === 0) assert(trace.subframes[1].app === A) assert(trace.subframes[1].subframes.length === 0) }) it('two layers', () => { const rec = newTraceRecorder(verbosity.maxVerbosity, newRng()) const A: QuintApp = { id: 0n, kind: 'app', opcode: 'A', args: [] } const B: QuintApp = { id: 0n, kind: 'app', opcode: 'B', args: [] } // (A calls (B, after that it calls A)), after that another A is called rec.onUserOperatorCall(A) rec.onUserOperatorCall(B) rec.onUserOperatorReturn(B, [], left(emptyFrameError)) rec.onUserOperatorCall(A) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) rec.onUserOperatorCall(A) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) const trace = rec.currentFrame assert(trace.subframes.length === 2) assert(trace.subframes[0].app === A) assert(trace.subframes[0].subframes.length === 2) assert(trace.subframes[0].subframes[0].app === B) assert(trace.subframes[0].subframes[1].app === A) assert(trace.subframes[1].app === A) assert(trace.subframes[1].subframes.length === 0) }) it('any {...} mixed', () => { const rec = newTraceRecorder(verbosity.maxVerbosity, newRng()) const A: QuintApp = { id: 0n, kind: 'app', opcode: 'A', args: [] } const B: QuintApp = { id: 0n, kind: 'app', opcode: 'B', args: [] } const C: QuintApp = { id: 0n, kind: 'app', opcode: 'C', args: [] } const anyEx: QuintApp = { id: 0n, kind: 'app', opcode: 'any', args: [A, B, C], } // A() rec.onUserOperatorCall(A) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) // any { rec.onAnyOptionCall(anyEx, 0) // A() rec.onUserOperatorCall(A) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) rec.onAnyOptionReturn(anyEx, 0) rec.onAnyOptionCall(anyEx, 1) // B() rec.onUserOperatorCall(B) rec.onUserOperatorReturn(B, [], left(emptyFrameError)) // C() rec.onUserOperatorCall(C) rec.onUserOperatorReturn(C, [], left(emptyFrameError)) rec.onAnyOptionReturn(anyEx, 1) rec.onAnyOptionCall(anyEx, 2) // C() rec.onUserOperatorCall(C) rec.onUserOperatorReturn(C, [], left(emptyFrameError)) rec.onAnyOptionReturn(anyEx, 2) rec.onAnyReturn(3, 1) // } // any rec.onUserOperatorCall(A) rec.onUserOperatorReturn(A, [], left(emptyFrameError)) const trace = rec.currentFrame assert(trace.subframes.length === 4) // A() is the operator before `any { ... }` assert(trace.subframes[0].app === A) assert(trace.subframes[0].subframes.length === 0) // A() and C() are from option 1 assert(trace.subframes[1].app === B) assert(trace.subframes[1].subframes.length === 0) assert(trace.subframes[2].app === C) assert(trace.subframes[2].subframes.length === 0) // A() is the operator after `any { ... }` assert(trace.subframes[3].app === A) assert(trace.subframes[3].subframes.length === 0) }) })