Skip to content

Commit 0d89d8b

Browse files
authored
Test: support multiple assignments for @testset let (#50151)
Nested `ContextTestset` is supported, so we can stack it when there are multiple assignments in a given `let` block. ```julia julia> @testset let logi = log(im), op = !iszero @test imag(logi) == π/2 @test op(real(logi)) end Test Failed at none:3 Expression: !(iszero(real(logi))) Context: logi = 0.0 + 1.5707963267948966im op = !iszero ERROR: There was an error during testing ```
1 parent f007c01 commit 0d89d8b

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

stdlib/Test/src/Test.jl

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,11 +1351,11 @@ function _check_testset(testsettype, testsetname)
13511351
end
13521352

13531353
"""
1354-
@testset [CustomTestSet] [option=val ...] ["description"] begin ... end
1355-
@testset [CustomTestSet] [option=val ...] ["description \$v"] for v in (...) ... end
1356-
@testset [CustomTestSet] [option=val ...] ["description \$v, \$w"] for v in (...), w in (...) ... end
1357-
@testset [CustomTestSet] [option=val ...] ["description"] foo()
1358-
@testset let v = (...) ... end
1354+
@testset [CustomTestSet] [options...] ["description"] begin test_ex end
1355+
@testset [CustomTestSet] [options...] ["description \$v"] for v in itr test_ex end
1356+
@testset [CustomTestSet] [options...] ["description \$v, \$w"] for v in itrv, w in itrw test_ex end
1357+
@testset [CustomTestSet] [options...] ["description"] test_func()
1358+
@testset let v = v, w = w; test_ex; end
13591359
13601360
# With begin/end or function call
13611361
@@ -1380,7 +1380,7 @@ accepts three boolean options:
13801380
This can also be set globally via the env var `JULIA_TEST_FAILFAST`.
13811381
13821382
!!! compat "Julia 1.8"
1383-
`@testset foo()` requires at least Julia 1.8.
1383+
`@testset test_func()` requires at least Julia 1.8.
13841384
13851385
!!! compat "Julia 1.9"
13861386
`failfast` requires at least Julia 1.9.
@@ -1436,6 +1436,9 @@ parent test set (with the context object appended to any failing tests.)
14361436
!!! compat "Julia 1.9"
14371437
`@testset let` requires at least Julia 1.9.
14381438
1439+
!!! compat "Julia 1.10"
1440+
Multiple `let` assignements are supported since Julia 1.10.
1441+
14391442
## Examples
14401443
```jldoctest
14411444
julia> @testset let logi = log(im)
@@ -1446,6 +1449,17 @@ Test Failed at none:3
14461449
Expression: !(iszero(real(logi)))
14471450
Context: logi = 0.0 + 1.5707963267948966im
14481451
1452+
ERROR: There was an error during testing
1453+
1454+
julia> @testset let logi = log(im), op = !iszero
1455+
@test imag(logi) == π/2
1456+
@test op(real(logi))
1457+
end
1458+
Test Failed at none:3
1459+
Expression: op(real(logi))
1460+
Context: logi = 0.0 + 1.5707963267948966im
1461+
op = !iszero
1462+
14491463
ERROR: There was an error during testing
14501464
```
14511465
"""
@@ -1477,30 +1491,46 @@ trigger_test_failure_break(@nospecialize(err)) =
14771491
"""
14781492
Generate the code for an `@testset` with a `let` argument.
14791493
"""
1480-
function testset_context(args, tests, source)
1494+
function testset_context(args, ex, source)
14811495
desc, testsettype, options = parse_testset_args(args[1:end-1])
14821496
if desc !== nothing || testsettype !== nothing
14831497
# Reserve this syntax if we ever want to allow this, but for now,
14841498
# just do the transparent context test set.
14851499
error("@testset with a `let` argument cannot be customized")
14861500
end
14871501

1488-
assgn = tests.args[1]
1489-
if !isa(assgn, Expr) || assgn.head !== :(=)
1490-
error("`@testset let` must have exactly one assignment")
1502+
let_ex = ex.args[1]
1503+
1504+
if Meta.isexpr(let_ex, :(=))
1505+
contexts = Any[let_ex.args[1]]
1506+
elseif Meta.isexpr(let_ex, :block)
1507+
contexts = Any[]
1508+
for assign_ex in let_ex.args
1509+
if Meta.isexpr(assign_ex, :(=))
1510+
push!(contexts, assign_ex.args[1])
1511+
else
1512+
error("Malformed `let` expression is given")
1513+
end
1514+
end
1515+
else
1516+
error("Malformed `let` expression is given")
14911517
end
1492-
assignee = assgn.args[1]
1518+
reverse!(contexts)
1519+
1520+
test_ex = ex.args[2]
14931521

1494-
tests.args[2] = quote
1495-
$push_testset($(ContextTestSet)($(QuoteNode(assignee)), $assignee; $options...))
1522+
ex.args[2] = quote
1523+
$(map(contexts) do context
1524+
:($push_testset($(ContextTestSet)($(QuoteNode(context)), $context; $options...)))
1525+
end...)
14961526
try
1497-
$(tests.args[2])
1527+
$(test_ex)
14981528
finally
1499-
$pop_testset()
1529+
$(map(_->:($pop_testset()), contexts)...)
15001530
end
15011531
end
15021532

1503-
return esc(tests)
1533+
return esc(ex)
15041534
end
15051535

15061536
"""

0 commit comments

Comments
 (0)