65 lines
1.5 KiB
Nim
65 lines
1.5 KiB
Nim
|
import
|
||
|
unittest,
|
||
|
../stew/templateutils
|
||
|
|
||
|
var computations = newSeq[string]()
|
||
|
var templateParamAddresses = newSeq[pointer]()
|
||
|
|
||
|
type
|
||
|
ObjectHoldingSeq = object
|
||
|
data: seq[int]
|
||
|
|
||
|
proc accessSeq(x: var ObjectHoldingSeq): var seq[int] =
|
||
|
computations.add("accessor")
|
||
|
x.data
|
||
|
|
||
|
proc expensiveComputation(evaluationLabel: string): seq[int] =
|
||
|
computations.add evaluationLabel
|
||
|
return @[1, 2, 3]
|
||
|
|
||
|
template reject(code: untyped) =
|
||
|
static: assert(not compiles(code))
|
||
|
|
||
|
template evalManyTimes(xParam: untyped, shouldBeMutable: bool): string =
|
||
|
var res: string
|
||
|
evalTemplateParamOnce(xParam, x):
|
||
|
res = $x
|
||
|
|
||
|
when shouldBeMutable:
|
||
|
x.add 10
|
||
|
else:
|
||
|
reject:
|
||
|
x.add(10)
|
||
|
|
||
|
res.add " => "
|
||
|
res.add $x
|
||
|
|
||
|
templateParamAddresses.add(unsafeAddr x)
|
||
|
res
|
||
|
|
||
|
test "Template utils":
|
||
|
# Pass function call
|
||
|
check "@[1, 2, 3] => @[1, 2, 3]" == evalManyTimes(
|
||
|
expensiveComputation("call"), shouldBeMutable = false)
|
||
|
|
||
|
# Pass var symbol
|
||
|
var s1 = expensiveComputation("var")
|
||
|
check "@[1, 2, 3] => @[1, 2, 3, 10]" == evalManyTimes(
|
||
|
s1, shouldBeMutable = true)
|
||
|
|
||
|
# Pass let symbol:
|
||
|
let s2 = expensiveComputation("let")
|
||
|
check "@[1, 2, 3] => @[1, 2, 3]" == evalManyTimes(
|
||
|
s2, shouldBeMutable = false)
|
||
|
|
||
|
var o = ObjectHoldingSeq(data: @[1, 2, 3])
|
||
|
check "@[1, 2, 3] => @[1, 2, 3, 10]" == evalManyTimes(
|
||
|
o.accessSeq, shouldBeMutable = true)
|
||
|
|
||
|
check computations == ["call", "var", "let", "accessor"]
|
||
|
|
||
|
check:
|
||
|
templateParamAddresses[1] == addr s1
|
||
|
templateParamAddresses[2] == unsafeAddr s2
|
||
|
templateParamAddresses[3] == addr o.accessSeq
|