205 lines
5.3 KiB
Plaintext
205 lines
5.3 KiB
Plaintext
type State {
|
|
Idle
|
|
Working(value: Int)
|
|
Label(text: Text)
|
|
}
|
|
|
|
type Result {
|
|
Ready(value: Int)
|
|
error Failed(message: Text)
|
|
}
|
|
|
|
type Problem {
|
|
error Denied(code: Int)
|
|
error Missing(message: Text)
|
|
}
|
|
|
|
type Captured {
|
|
Done(value: Int)
|
|
error Rejected(problem: Problem)
|
|
}
|
|
|
|
readState(value: State.Idle) (answer: Int) pure {
|
|
answer = 0
|
|
}
|
|
readState(value: State.Working(number)) (answer: Int) pure {
|
|
answer = number
|
|
}
|
|
readState(value: State.Label(text)) (answer: Int) pure {
|
|
answer = length(text)
|
|
}
|
|
|
|
nullableState(value: null) (answer: Int) pure {
|
|
answer = -1
|
|
}
|
|
nullableState(value: State.Working(number)) (answer: Int) pure {
|
|
answer = number
|
|
}
|
|
nullableState(value: other) (answer: Int) pure {
|
|
answer = readState(value)
|
|
}
|
|
|
|
nullableText(value: other) (answer: Int) pure {
|
|
answer = length(value)
|
|
}
|
|
nullableText(value: null) (answer: Int) pure {
|
|
answer = -1
|
|
}
|
|
nullableText(value: "zero") (answer: Int) pure {
|
|
answer = 0
|
|
}
|
|
|
|
change(value: State.Label(text)) (answer: State) {
|
|
text = text + "新"
|
|
answer = State.Label(text)
|
|
}
|
|
change(value: other) (answer: State) {
|
|
answer = value
|
|
}
|
|
|
|
operation(value: Int >= 0) (answer: Int) pure {
|
|
answer = value
|
|
}
|
|
operation(value: other) (answer: Int) pure {
|
|
fail(Result.Failed("negative"))
|
|
}
|
|
|
|
propagate(value: Int) (answer: Int) pure {
|
|
answer = operation(value)
|
|
}
|
|
|
|
capture(value: Int) (answer: Result) pure {
|
|
answer = result(propagate(value))
|
|
}
|
|
|
|
recoverValue(value: Result.Ready(number)) (answer: Int) pure recover("use message length for this diagnostic probe") {
|
|
answer = number
|
|
}
|
|
recoverValue(value: Result.Failed(message)) (answer: Int) recover("use message length for this diagnostic probe") pure {
|
|
answer = length(message)
|
|
}
|
|
|
|
requireValue(value: Result.Ready(number)) (answer: Int) pure {
|
|
answer = number
|
|
}
|
|
requireValue(value: Result.Failed(message)) (answer: Int) pure {
|
|
fail(Result.Failed(message))
|
|
}
|
|
|
|
deny(value: Int) (answer: Int) {
|
|
fail(Problem.Denied(value))
|
|
}
|
|
|
|
captureDomain(value: Int) (answer: Captured) {
|
|
answer = result(deny(value))
|
|
}
|
|
|
|
problemValue(value: Problem.Denied(code)) (answer: Int) recover("inspect domain payload in the probe") {
|
|
answer = code
|
|
}
|
|
problemValue(value: Problem.Missing(message)) (answer: Int) recover("inspect domain payload in the probe") {
|
|
answer = length(message)
|
|
}
|
|
|
|
capturedValue(value: Captured.Done(number)) (answer: Int) recover("inspect wrapped result in the probe") {
|
|
answer = number
|
|
}
|
|
capturedValue(value: Captured.Rejected(problem)) (answer: Int) recover("inspect wrapped result in the probe") {
|
|
answer = problemValue(problem)
|
|
}
|
|
|
|
optionalEqual(value: Int?) (answer: Bool) pure {
|
|
answer = value == null or null == value or value == 1 or 1 == value
|
|
}
|
|
|
|
increment(value: Int) (answer: Int) pure {
|
|
answer = value + 1
|
|
}
|
|
|
|
faultEntry() (answer: Int) recover("only recover business errors in the probe") {
|
|
answer = recoverValue(result(increment(9223372036854775807)))
|
|
}
|
|
|
|
failureEntry() (answer: Int) {
|
|
answer = propagate(-1)
|
|
}
|
|
|
|
type Ack {
|
|
Done
|
|
error Stopped
|
|
}
|
|
|
|
argumentEntry() (answer: Result) {
|
|
answer = result(operation(deny(5)))
|
|
}
|
|
|
|
optionalFloat() (answer: Float?) {
|
|
answer = 1.5 + 2.5
|
|
}
|
|
|
|
optionalList() (answer: List<Int>?) {
|
|
answer = []
|
|
}
|
|
|
|
optionalLength(value: null) (answer: Int) { answer = -1 }
|
|
optionalLength(value: List<Int>) (answer: Int) { answer = length(value) }
|
|
|
|
act(ready: true) () {}
|
|
act(ready: false) () {
|
|
fail(Ack.Stopped)
|
|
}
|
|
|
|
ack(ready: Bool) (answer: Ack) {
|
|
answer = result(act(ready))
|
|
}
|
|
|
|
ackValue(value: Ack.Done) (answer: Bool) recover("represent optional probe failure as false") {
|
|
answer = true
|
|
}
|
|
ackValue(value: Ack.Stopped) (answer: Bool) recover("represent optional probe failure as false") {
|
|
answer = false
|
|
}
|
|
|
|
type PairResult {
|
|
Ready(text: Text, number: Int)
|
|
error Stopped
|
|
}
|
|
|
|
pair(ready: true) (text: Text, number: Int) {
|
|
text = "雪"
|
|
number = 42
|
|
}
|
|
pair(ready: false) (text: Text, number: Int) {
|
|
fail(PairResult.Stopped)
|
|
}
|
|
|
|
capturePair(ready: Bool) (answer: PairResult) {
|
|
answer = result(pair(ready))
|
|
}
|
|
|
|
pairValid(value: PairResult.Ready(text, number)) (answer: Bool) recover("failed optional pair probe is false") {
|
|
answer = text == "雪" and number == 42
|
|
}
|
|
pairValid(value: PairResult.Stopped) (answer: Bool) recover("failed optional pair probe is false") {
|
|
answer = false
|
|
}
|
|
|
|
optionalCapture(value: Int) (answer: Result?) {
|
|
answer = result(operation(value))
|
|
}
|
|
|
|
optionalResult(value: null) (answer: Int) {
|
|
answer = 0
|
|
}
|
|
optionalResult(value: Result) (answer: Int) {
|
|
answer = recoverValue(value)
|
|
}
|
|
|
|
verify() (answer: Bool) {
|
|
original = State.Label("雪")
|
|
changed = change(original)
|
|
base = readState(State.Idle) == 0 and readState(State.Working(42)) == 42 and readState(original) == 1 and readState(changed) == 2 and nullableState(null) == -1 and nullableState(State.Working(7)) == 7 and nullableState(State.Idle) == 0 and nullableText(null) == -1 and nullableText("zero") == 0 and nullableText("雪山") == 2
|
|
failures = recoverValue(capture(42)) == 42 and recoverValue(capture(-1)) == 8 and requireValue(capture(9)) == 9 and capturedValue(captureDomain(23)) == 23 and optionalEqual(null) and optionalEqual(1) and not optionalEqual(2)
|
|
answer = base and failures and ackValue(ack(true)) and not ackValue(ack(false)) and pairValid(capturePair(true)) and not pairValid(capturePair(false)) and optionalResult(optionalCapture(-1)) == 8 and optionalResult(null) == 0 and optionalFloat() == 4e0 and optionalLength(optionalList()) == 0
|
|
}
|