diff --git a/frontend/Makefile b/frontend/Makefile index 66872ce72..4b2b6a8c9 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -6,9 +6,9 @@ SPHINXCONF = sphinx BUILDDIR = dist SRC_TEST_DIR = $(BUILDDIR)/test_output TEST_LAMBDA ?= 0 -TEST_LOCAL_DRIVER = PYTHONPATH="$PYTHONPATH:sphinx" python3 tests/compile_blocks.py --keep_files -B $(SRC_TEST_DIR) +TEST_LOCAL_DRIVER = PYTHONPATH="$$PYTHONPATH:sphinx" python3 tests/compile_blocks.py --keep_files -B $(SRC_TEST_DIR) TEST_OPTIONS ?= -TEST_LAMBDA_DRIVER = PYTHONPATH="$PYTHONPATH:sphinx" python3 tests/execute_rst_code_blocks.py --halt-on-failure +TEST_LAMBDA_DRIVER = PYTHONPATH="$$PYTHONPATH:sphinx" python3 tests/execute_rst_code_blocks.py --halt-on-failure ifeq ($(strip $(TEST_LAMBDA)),1) TEST_DRIVER := $(TEST_LAMBDA_DRIVER) diff --git a/frontend/python/rst_code_example_pipeline/src/rst_code_example_pipeline/blocks.py b/frontend/python/rst_code_example_pipeline/src/rst_code_example_pipeline/blocks.py index 2bdf95858..448dcea38 100644 --- a/frontend/python/rst_code_example_pipeline/src/rst_code_example_pipeline/blocks.py +++ b/frontend/python/rst_code_example_pipeline/src/rst_code_example_pipeline/blocks.py @@ -175,7 +175,12 @@ def start_config_block(i, line, indent): if cb_start != -1: process_block(i, line, indent) - else: + # Not `else`: the line that ends a block (the first one indented + # less than its body) may itself start the next one. A + # ``.. code::`` directly following a code block, with no prose + # between them, was otherwise consumed as the terminator and + # never seen as a directive, so the second block vanished. + if cb_start == -1: if line[indent:].startswith(".. code::"): start_code_block(i, line, indent) elif line[indent:].startswith(":code-config:"): diff --git a/frontend/python/rst_code_example_pipeline/tests/test_blocks.py b/frontend/python/rst_code_example_pipeline/tests/test_blocks.py index 1e38f1255..fc3fcc699 100644 --- a/frontend/python/rst_code_example_pipeline/tests/test_blocks.py +++ b/frontend/python/rst_code_example_pipeline/tests/test_blocks.py @@ -164,6 +164,56 @@ def test_active_defaults_to_true(self): # T-blocks-02: project and main_file attributes # --------------------------------------------------------------------------- +class TestConsecutiveBlocks: + """A code block directly followed by another one, with no prose line + between them: both are parsed. The line that terminates the first block + is the second block's directive, and it used to be consumed as the + terminator only, so the second block was silently dropped.""" + + RST = textwrap.dedent("""\ + Intro. + + .. code:: ada compile_button project=P.First + + procedure First is begin null; end First; + + .. code:: ada run_button project=P.Second + + procedure Second is begin null; end Second; + + Closing paragraph. + """) + + def test_both_blocks_parsed(self): + blocks = [b for b in Block.get_blocks_from_rst(RST_FILE, self.RST) + if isinstance(b, CodeBlock)] + assert [b.project for b in blocks] == ["P.First", "P.Second"] + + def test_second_block_keeps_its_own_attributes(self): + blocks = [b for b in Block.get_blocks_from_rst(RST_FILE, self.RST) + if isinstance(b, CodeBlock)] + assert blocks[1].buttons == ["run"] + assert blocks[1].text.strip() == "procedure Second is begin null; end Second;" + + def test_block_after_an_indented_block(self): + rst = textwrap.dedent("""\ + - item + + .. code:: ada compile_button project=P.Nested + + procedure Nested is begin null; end Nested; + + .. code:: ada compile_button project=P.Outer + + procedure Outer is begin null; end Outer; + + Closing paragraph. + """) + blocks = [b for b in Block.get_blocks_from_rst(RST_FILE, rst) + if isinstance(b, CodeBlock)] + assert [b.project for b in blocks] == ["P.Nested", "P.Outer"] + + class TestProjectAndMainFile: RST = minimal_rst("""\ .. code:: ada project=MyProject main=main.adb