@@ -969,7 +969,7 @@ if get_testset_depth() != 0
969
969
end
970
970
```
971
971
"""
972
- function finish end
972
+ finish (ts :: AbstractTestSet ) = ts
973
973
974
974
"""
975
975
TestSetException
@@ -1004,7 +1004,6 @@ end
1004
1004
A simple fallback test set that throws immediately on a failure.
1005
1005
"""
1006
1006
struct FallbackTestSet <: AbstractTestSet end
1007
- fallback_testset = FallbackTestSet ()
1008
1007
1009
1008
struct FallbackTestSetException <: Exception
1010
1009
msg:: String
@@ -1021,8 +1020,6 @@ function record(ts::FallbackTestSet, t::Union{Fail, Error})
1021
1020
println (t)
1022
1021
throw (FallbackTestSetException (" There was an error during testing" ))
1023
1022
end
1024
- # We don't need to do anything as we don't record anything
1025
- finish (ts:: FallbackTestSet ) = ts
1026
1023
1027
1024
# -----------------------------------------------------------------------
1028
1025
@@ -1639,21 +1636,11 @@ function testset_context(args, ex, source)
1639
1636
else
1640
1637
error (" Malformed `let` expression is given" )
1641
1638
end
1642
- reverse! (contexts)
1643
-
1644
1639
test_ex = ex. args[2 ]
1645
-
1646
- ex. args[2 ] = quote
1647
- $ (map (contexts) do context
1648
- :($ push_testset ($ (ContextTestSet)($ (QuoteNode (context)), $ context; $ options... )))
1649
- end ... )
1650
- try
1651
- $ (test_ex)
1652
- finally
1653
- $ (map (_-> :($ pop_testset ()), contexts)... )
1654
- end
1640
+ for context in reverse (contexts)
1641
+ test_ex = :($ Test. @with_testset ($ ContextTestSet ($ (QuoteNode (context)), $ context; $ options... ), $ test_ex))
1655
1642
end
1656
-
1643
+ ex . args[ 2 ] = test_ex
1657
1644
return esc (ex)
1658
1645
end
1659
1646
@@ -1687,35 +1674,34 @@ function testset_beginend_call(args, tests, source)
1687
1674
else
1688
1675
$ (testsettype)($ desc; $ options... )
1689
1676
end
1690
- push_testset (ts)
1691
- # we reproduce the logic of guardseed, but this function
1692
- # cannot be used as it changes slightly the semantic of @testset,
1693
- # by wrapping the body in a function
1694
- local default_rng_orig = copy (default_rng ())
1695
- local tls_seed_orig = copy (Random. get_tls_seed ())
1696
- try
1697
- # default RNG is reset to its state from last `seed!()` to ease reproduce a failed test
1698
- copy! (Random. default_rng (), tls_seed_orig)
1699
- let
1700
- $ (esc (tests))
1701
- end
1702
- catch err
1703
- err isa InterruptException && rethrow ()
1704
- # something in the test block threw an error. Count that as an
1705
- # error in this test set
1706
- trigger_test_failure_break (err)
1707
- if err isa FailFastError
1708
- get_testset_depth () > 1 ? rethrow () : failfast_print ()
1709
- else
1710
- record (ts, Error (:nontest_error , Expr (:tuple ), err, Base. current_exceptions (), $ (QuoteNode (source))))
1677
+ @with_testset ts begin
1678
+ # we reproduce the logic of guardseed, but this function
1679
+ # cannot be used as it changes slightly the semantic of @testset,
1680
+ # by wrapping the body in a function
1681
+ local default_rng_orig = copy (default_rng ())
1682
+ local tls_seed_orig = copy (Random. get_tls_seed ())
1683
+ try
1684
+ # default RNG is reset to its state from last `seed!()` to ease reproduce a failed test
1685
+ copy! (Random. default_rng (), tls_seed_orig)
1686
+ let
1687
+ $ (esc (tests))
1688
+ end
1689
+ catch err
1690
+ err isa InterruptException && rethrow ()
1691
+ # something in the test block threw an error. Count that as an
1692
+ # error in this test set
1693
+ trigger_test_failure_break (err)
1694
+ if err isa FailFastError
1695
+ get_testset_depth () > 1 ? rethrow () : failfast_print ()
1696
+ else
1697
+ record (ts, Error (:nontest_error , Expr (:tuple ), err, Base. current_exceptions (), $ (QuoteNode (source))))
1698
+ end
1699
+ finally
1700
+ copy! (default_rng (), default_rng_orig)
1701
+ copy! (Random. get_tls_seed (), tls_seed_orig)
1711
1702
end
1712
- finally
1713
- copy! (default_rng (), default_rng_orig)
1714
- copy! (Random. get_tls_seed (), tls_seed_orig)
1715
- pop_testset ()
1716
- ret = finish (ts)
1717
1703
end
1718
- ret
1704
+ ts
1719
1705
end
1720
1706
# preserve outer location if possible
1721
1707
if tests isa Expr && tests. head === :block && ! isempty (tests. args) && tests. args[1 ] isa LineNumberNode
@@ -1771,52 +1757,38 @@ function testset_forloop(args, testloop, source)
1771
1757
_check_testset ($ testsettype, $ (QuoteNode (testsettype. args[1 ])))
1772
1758
# Trick to handle `break` and `continue` in the test code before
1773
1759
# they can be handled properly by `finally` lowering.
1774
- if ! first_iteration
1775
- pop_testset ()
1776
- finish_errored = true
1777
- push! (arr, finish (ts))
1778
- finish_errored = false
1779
- copy! (default_rng (), tls_seed_orig)
1780
- end
1781
1760
ts = if ($ testsettype === $ DefaultTestSet) && $ (isa (source, LineNumberNode))
1782
1761
$ (testsettype)($ desc; source= $ (QuoteNode (source. file)), $ options... )
1783
1762
else
1784
1763
$ (testsettype)($ desc; $ options... )
1785
1764
end
1786
- push_testset (ts)
1787
- first_iteration = false
1788
- try
1789
- $ (esc (tests))
1790
- catch err
1791
- err isa InterruptException && rethrow ()
1792
- # Something in the test block threw an error. Count that as an
1793
- # error in this test set
1794
- trigger_test_failure_break (err)
1795
- if ! isa (err, FailFastError)
1796
- record (ts, Error (:nontest_error , Expr (:tuple ), err, Base. current_exceptions (), $ (QuoteNode (source))))
1765
+ @with_testset ts begin
1766
+ try
1767
+ # default RNG is reset to its state from last `seed!()` to ease reproduce a failed test
1768
+ copy! (Random. default_rng (), tls_seed_orig)
1769
+ $ (esc (tests))
1770
+ catch err
1771
+ err isa InterruptException && rethrow ()
1772
+ # Something in the test block threw an error. Count that as an
1773
+ # error in this test set
1774
+ trigger_test_failure_break (err)
1775
+ if ! isa (err, FailFastError)
1776
+ record (ts, Error (:nontest_error , Expr (:tuple ), err, Base. current_exceptions (), $ (QuoteNode (source))))
1777
+ end
1778
+ finally
1779
+ copy! (default_rng (), default_rng_orig)
1780
+ copy! (Random. get_tls_seed (), tls_seed_orig)
1781
+ push! (arr, ts)
1797
1782
end
1798
1783
end
1799
1784
end
1800
1785
quote
1801
1786
local arr = Vector {Any} ()
1802
- local first_iteration = true
1803
- local ts
1804
- local finish_errored = false
1805
1787
local default_rng_orig = copy (default_rng ())
1806
1788
local tls_seed_orig = copy (Random. get_tls_seed ())
1807
- copy! (Random. default_rng (), tls_seed_orig)
1808
- try
1809
- let
1810
- $ (Expr (:for , Expr (:block , [esc (v) for v in loopvars]. .. ), blk))
1811
- end
1812
- finally
1813
- # Handle `return` in test body
1814
- if ! first_iteration && ! finish_errored
1815
- pop_testset ()
1816
- push! (arr, finish (ts))
1817
- end
1818
- copy! (default_rng (), default_rng_orig)
1819
- copy! (Random. get_tls_seed (), tls_seed_orig)
1789
+ local ts
1790
+ let
1791
+ $ (Expr (:for , Expr (:block , [esc (v) for v in loopvars]. .. ), blk))
1820
1792
end
1821
1793
arr
1822
1794
end
@@ -1855,39 +1827,27 @@ end
1855
1827
# -----------------------------------------------------------------------
1856
1828
# Various helper methods for test sets
1857
1829
1830
+ const CURRENT_TESTSET = Base. ScopedValue {AbstractTestSet} (FallbackTestSet ())
1831
+ const TESTSET_DEPTH = Base. ScopedValue {Int} (0 )
1832
+
1833
+ macro with_testset (ts, expr)
1834
+ quote
1835
+ ts = $ (esc (ts))
1836
+ $ (Expr (:tryfinally ,
1837
+ :(Base. @with (CURRENT_TESTSET => ts, TESTSET_DEPTH => get_testset_depth () + 1 , $ (esc (expr)))),
1838
+ :(finish (ts))
1839
+ ))
1840
+ end
1841
+ end
1842
+
1858
1843
"""
1859
1844
get_testset()
1860
1845
1861
1846
Retrieve the active test set from the task's local storage. If no
1862
1847
test set is active, use the fallback default test set.
1863
1848
"""
1864
1849
function get_testset ()
1865
- testsets = get (task_local_storage (), :__BASETESTNEXT__ , AbstractTestSet[])
1866
- return isempty (testsets) ? fallback_testset : testsets[end ]
1867
- end
1868
-
1869
- """
1870
- push_testset(ts::AbstractTestSet)
1871
-
1872
- Adds the test set to the `task_local_storage`.
1873
- """
1874
- function push_testset (ts:: AbstractTestSet )
1875
- testsets = get (task_local_storage (), :__BASETESTNEXT__ , AbstractTestSet[])
1876
- push! (testsets, ts)
1877
- setindex! (task_local_storage (), testsets, :__BASETESTNEXT__ )
1878
- end
1879
-
1880
- """
1881
- pop_testset()
1882
-
1883
- Pops the last test set added to the `task_local_storage`. If there are no
1884
- active test sets, returns the fallback default test set.
1885
- """
1886
- function pop_testset ()
1887
- testsets = get (task_local_storage (), :__BASETESTNEXT__ , AbstractTestSet[])
1888
- ret = isempty (testsets) ? fallback_testset : pop! (testsets)
1889
- setindex! (task_local_storage (), testsets, :__BASETESTNEXT__ )
1890
- return ret
1850
+ something (Base. ScopedValues. get (CURRENT_TESTSET))
1891
1851
end
1892
1852
1893
1853
"""
@@ -1896,10 +1856,10 @@ end
1896
1856
Return the number of active test sets, not including the default test set
1897
1857
"""
1898
1858
function get_testset_depth ()
1899
- testsets = get (task_local_storage (), :__BASETESTNEXT__ , AbstractTestSet[])
1900
- return length (testsets)
1859
+ something (Base. ScopedValues. get (TESTSET_DEPTH))
1901
1860
end
1902
1861
1862
+
1903
1863
_args_and_call (args... ; kwargs... ) = (args[1 : end - 1 ], kwargs, args[end ](args[1 : end - 1 ]. .. ; kwargs... ))
1904
1864
_materialize_broadcasted (f, args... ) = Broadcast. materialize (Broadcast. broadcasted (f, args... ))
1905
1865
0 commit comments