Mercurial > hg
changeset 50210:6515d9a6592d stable
run-tests: make it possible to nest conditionals
This is not that hard to implement and makes our life easier on a regular basis.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 31 Jan 2023 13:16:39 +0100 |
parents | be019ac8c1e4 |
children | f5e4248e5bce |
files | tests/run-tests.py |
diffstat | 1 files changed, 46 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/tests/run-tests.py Mon Nov 28 12:33:20 2022 +0100 +++ b/tests/run-tests.py Tue Jan 31 13:16:39 2023 +0100 @@ -1834,8 +1834,44 @@ pos = prepos = -1 - # True or False when in a true or false conditional section - skipping = None + # The current stack of conditionnal section. + # Each relevant conditionnal section can have the following value: + # - True: we should run this block + # - False: we should skip this block + # - None: The parent block is skipped, + # (no branch of this one will ever run) + condition_stack = [] + + def run_line(): + """return True if the current line should be run""" + if not condition_stack: + return True + return bool(condition_stack[-1]) + + def push_conditional_block(should_run): + """Push a new conditional context, with its initial state + + i.e. entry a #if block""" + if not run_line(): + condition_stack.append(None) + else: + condition_stack.append(should_run) + + def flip_conditional(): + """reverse the current condition state + + i.e. enter a #else + """ + assert condition_stack + if condition_stack[-1] is not None: + condition_stack[-1] = not condition_stack[-1] + + def pop_conditional(): + """exit the current skipping context + + i.e. reach the #endif""" + assert condition_stack + condition_stack.pop() # We keep track of whether or not we're in a Python block so we # can generate the surrounding doctest magic. @@ -1891,7 +1927,7 @@ after.setdefault(pos, []).append( b' !!! invalid #require\n' ) - if not skipping: + if run_line(): haveresult, message = self._hghave(lsplit[1:]) if not haveresult: script = [b'echo "%s"\nexit 80\n' % message] @@ -1901,21 +1937,19 @@ lsplit = l.split() if len(lsplit) < 2 or lsplit[0] != b'#if': after.setdefault(pos, []).append(b' !!! invalid #if\n') - if skipping is not None: - after.setdefault(pos, []).append(b' !!! nested #if\n') - skipping = not self._iftest(lsplit[1:]) + push_conditional_block(self._iftest(lsplit[1:])) after.setdefault(pos, []).append(l) elif l.startswith(b'#else'): - if skipping is None: + if not condition_stack: after.setdefault(pos, []).append(b' !!! missing #if\n') - skipping = not skipping + flip_conditional() after.setdefault(pos, []).append(l) elif l.startswith(b'#endif'): - if skipping is None: + if not condition_stack: after.setdefault(pos, []).append(b' !!! missing #if\n') - skipping = None + pop_conditional() after.setdefault(pos, []).append(l) - elif skipping: + elif not run_line(): after.setdefault(pos, []).append(l) elif l.startswith(b' >>> '): # python inlines after.setdefault(pos, []).append(l) @@ -1960,7 +1994,7 @@ if inpython: script.append(b'EOF\n') - if skipping is not None: + if condition_stack: after.setdefault(pos, []).append(b' !!! missing #endif\n') addsalt(n + 1, False) # Need to end any current per-command trace