"""Unit tests for the H5P semantics parser."""

from __future__ import annotations

import pytest

from byteb4rb1e.sphinxcontrib.h5p.utils.pkg.semantics import parse
from byteb4rb1e.sphinxcontrib.h5p.utils.pkg.semantics.classify import (
    field_name_to_option,
    machine_name_to_directive,
)


# -------------------------------------------------------------------
# Naming helpers
# -------------------------------------------------------------------

class TestMachineNameToDirective:

    def test_true_false(self) -> None:
        assert machine_name_to_directive("H5P.TrueFalse") == \
            "h5p-true-false"

    def test_multi_choice(self) -> None:
        assert machine_name_to_directive("H5P.MultiChoice") == \
            "h5p-multi-choice"

    def test_question_set(self) -> None:
        assert machine_name_to_directive("H5P.QuestionSet") == \
            "h5p-question-set"

    def test_drag_question(self) -> None:
        assert machine_name_to_directive("H5P.DragQuestion") == \
            "h5p-drag-question"

    def test_multi_media_choice(self) -> None:
        assert machine_name_to_directive("H5P.MultiMediaChoice") == \
            "h5p-multi-media-choice"


class TestFieldNameToOption:

    def test_enable_retry(self) -> None:
        assert field_name_to_option("enableRetry") == "enable-retry"

    def test_confirm_check_dialog(self) -> None:
        assert field_name_to_option("confirmCheckDialog") == \
            "confirm-check-dialog"

    def test_single_word(self) -> None:
        assert field_name_to_option("correct") == "correct"

    def test_show_intro_page(self) -> None:
        assert field_name_to_option("showIntroPage") == \
            "show-intro-page"

    def test_background_image_alt_text(self) -> None:
        assert field_name_to_option("backgroundImageAltText") == \
            "background-image-alt-text"


# -------------------------------------------------------------------
# Fixtures: actual semantics.json content
# -------------------------------------------------------------------

TRUE_FALSE_SEMANTICS = [
    {
        "name": "media",
        "type": "group",
        "label": "Media",
        "importance": "medium",
        "fields": [
            {
                "name": "type",
                "type": "library",
                "label": "Type",
                "importance": "medium",
                "options": [
                    "H5P.Image 1.1",
                    "H5P.Video 1.6",
                    "H5P.Audio 1.5",
                ],
                "optional": True,
            },
            {
                "name": "disableImageZooming",
                "type": "boolean",
                "label": "Disable image zooming",
                "importance": "low",
                "default": False,
                "optional": True,
            },
        ],
    },
    {
        "name": "question",
        "type": "text",
        "widget": "html",
        "label": "Question",
        "importance": "high",
        "enterMode": "p",
        "tags": ["strong", "em", "sub", "sup", "h2", "h3", "pre", "code"],
    },
    {
        "name": "correct",
        "type": "select",
        "widget": "radioGroup",
        "alignment": "horizontal",
        "label": "Correct answer",
        "importance": "high",
        "options": [
            {"value": "true", "label": "True"},
            {"value": "false", "label": "False"},
        ],
        "default": "true",
    },
    {
        "name": "l10n",
        "type": "group",
        "common": True,
        "label": "User interface translations for True/False Questions",
        "importance": "low",
        "fields": [
            {"name": "trueText", "type": "text", "label": "Label for true button",
             "importance": "low", "default": "True"},
            {"name": "falseText", "type": "text", "label": "Label for false button",
             "importance": "low", "default": "False"},
        ],
    },
    {
        "name": "behaviour",
        "type": "group",
        "label": "Behavioural settings",
        "importance": "low",
        "fields": [
            {"name": "enableRetry", "type": "boolean",
             "label": "Enable \"Retry\" button",
             "importance": "low", "default": True},
            {"name": "enableSolutionsButton", "type": "boolean",
             "label": "Enable \"Show Solution\" button",
             "importance": "low", "default": True},
            {"name": "enableCheckButton", "type": "boolean",
             "label": "Enable \"Check\" button",
             "importance": "low", "default": True, "optional": True},
            {"name": "confirmCheckDialog", "type": "boolean",
             "label": "Show confirmation dialog on \"Check\"",
             "importance": "low", "default": False},
            {"name": "confirmRetryDialog", "type": "boolean",
             "label": "Show confirmation dialog on \"Retry\"",
             "importance": "low", "default": False},
            {"name": "autoCheck", "type": "boolean",
             "label": "Automatically check answer",
             "importance": "low", "default": False},
            {"name": "feedbackOnCorrect", "type": "text",
             "label": "Feedback on correct answer",
             "importance": "low", "optional": True, "maxLength": 2048},
            {"name": "feedbackOnWrong", "type": "text",
             "label": "Feedback on wrong answer",
             "importance": "low", "optional": True, "maxLength": 2048},
        ],
    },
    {
        "name": "confirmCheck",
        "type": "group",
        "common": True,
        "label": "Check confirmation dialog",
        "importance": "low",
        "fields": [
            {"name": "header", "type": "text", "label": "Header text",
             "importance": "low", "default": "Finish ?"},
        ],
    },
    {
        "name": "confirmRetry",
        "type": "group",
        "common": True,
        "label": "Retry confirmation dialog",
        "importance": "low",
        "fields": [
            {"name": "header", "type": "text", "label": "Header text",
             "importance": "low", "default": "Retry ?"},
        ],
    },
]


MULTI_CHOICE_SEMANTICS = [
    {
        "name": "media",
        "type": "group",
        "label": "Media",
        "importance": "medium",
        "fields": [
            {
                "name": "type",
                "type": "library",
                "label": "Type",
                "importance": "medium",
                "options": [
                    "H5P.Image 1.1",
                    "H5P.Video 1.6",
                    "H5P.Audio 1.5",
                ],
                "optional": True,
            },
        ],
    },
    {
        "name": "question",
        "type": "text",
        "importance": "medium",
        "widget": "html",
        "label": "Question",
        "enterMode": "p",
        "tags": ["strong", "em"],
    },
    {
        "name": "answers",
        "type": "list",
        "importance": "high",
        "label": "Available options",
        "entity": "option",
        "min": 1,
        "defaultNum": 2,
        "field": {
            "name": "answer",
            "type": "group",
            "label": "Option",
            "importance": "high",
            "fields": [
                {
                    "name": "text",
                    "type": "text",
                    "importance": "medium",
                    "widget": "html",
                    "label": "Text",
                    "tags": ["strong", "em", "sub", "sup", "code"],
                },
                {
                    "name": "correct",
                    "type": "boolean",
                    "label": "Correct",
                    "importance": "low",
                },
                {
                    "name": "tipsAndFeedback",
                    "type": "group",
                    "label": "Tips and feedback",
                    "importance": "low",
                    "optional": True,
                    "fields": [
                        {
                            "name": "tip",
                            "type": "text",
                            "widget": "html",
                            "label": "Tip text",
                            "importance": "low",
                            "optional": True,
                        },
                        {
                            "name": "chosenFeedback",
                            "type": "text",
                            "widget": "html",
                            "label": "Message displayed if answer is selected",
                            "importance": "low",
                            "optional": True,
                        },
                        {
                            "name": "notChosenFeedback",
                            "type": "text",
                            "widget": "html",
                            "label": "Message displayed if answer is not selected",
                            "importance": "low",
                            "optional": True,
                        },
                    ],
                },
            ],
        },
    },
    {
        "name": "overallFeedback",
        "type": "group",
        "label": "Overall Feedback",
        "importance": "low",
        "expanded": True,
        "fields": [
            {
                "name": "overallFeedback",
                "type": "list",
                "widgets": [{"name": "RangeList", "label": "Default"}],
                "importance": "high",
                "label": "Define custom feedback for any score range",
                "entity": "range",
                "min": 1,
                "optional": True,
                "field": {
                    "name": "overallFeedback",
                    "type": "group",
                    "importance": "low",
                    "fields": [
                        {"name": "from", "type": "number", "label": "Score Range",
                         "min": 0, "max": 100, "default": 0},
                        {"name": "to", "type": "number",
                         "min": 0, "max": 100, "default": 100},
                        {"name": "feedback", "type": "text",
                         "label": "Feedback for defined score range",
                         "importance": "low", "optional": True},
                    ],
                },
            },
        ],
    },
    {
        "name": "UI",
        "type": "group",
        "label": "User interface translations for multichoice",
        "importance": "low",
        "common": True,
        "fields": [
            {"name": "checkAnswerButton", "type": "text",
             "label": "Check answer button label",
             "importance": "low", "default": "Check"},
        ],
    },
    {
        "name": "behaviour",
        "type": "group",
        "label": "Behavioural settings",
        "importance": "low",
        "optional": True,
        "fields": [
            {"name": "enableRetry", "type": "boolean",
             "label": "Enable \"Retry\" button",
             "importance": "low", "default": True, "optional": True},
            {"name": "enableSolutionsButton", "type": "boolean",
             "label": "Enable \"Show Solution\" button",
             "importance": "low", "default": True, "optional": True},
            {"name": "enableCheckButton", "type": "boolean",
             "label": "Enable \"Check\" button",
             "importance": "low", "default": True, "optional": True},
            {
                "name": "type",
                "type": "select",
                "label": "Question Type",
                "importance": "low",
                "default": "auto",
                "options": [
                    {"value": "auto", "label": "Automatic"},
                    {"value": "multi", "label": "Multiple Choice (Checkboxes)"},
                    {"value": "single", "label": "Single Choice (Radio Buttons)"},
                ],
            },
            {"name": "singlePoint", "type": "boolean",
             "label": "Give one point for the whole task",
             "importance": "low", "default": False},
            {"name": "randomAnswers", "type": "boolean",
             "label": "Randomize answers",
             "importance": "low", "default": True},
            {"name": "showSolutionsRequiresInput", "type": "boolean",
             "label": "Require answer before the solution can be viewed",
             "importance": "low", "default": True, "optional": True},
            {"name": "confirmCheckDialog", "type": "boolean",
             "label": "Show confirmation dialog on \"Check\"",
             "importance": "low", "default": False},
            {"name": "confirmRetryDialog", "type": "boolean",
             "label": "Show confirmation dialog on \"Retry\"",
             "importance": "low", "default": False},
            {"name": "autoCheck", "type": "boolean",
             "label": "Automatically check answers",
             "importance": "low", "default": False},
            {"name": "passPercentage", "type": "number",
             "label": "Pass percentage",
             "min": 0, "max": 100, "step": 1, "default": 100},
            {"name": "showScorePoints", "type": "boolean",
             "label": "Show score points",
             "importance": "low", "default": True},
        ],
    },
    {
        "name": "confirmCheck",
        "type": "group",
        "common": True,
        "label": "Check confirmation dialog",
        "importance": "low",
        "fields": [
            {"name": "header", "type": "text", "label": "Header text",
             "importance": "low", "default": "Finish ?"},
        ],
    },
    {
        "name": "confirmRetry",
        "type": "group",
        "common": True,
        "label": "Retry confirmation dialog",
        "importance": "low",
        "fields": [
            {"name": "header", "type": "text", "label": "Header text",
             "importance": "low", "default": "Retry ?"},
        ],
    },
]


QUESTION_SET_SEMANTICS = [
    {
        "name": "introPage",
        "type": "group",
        "label": "Quiz introduction",
        "importance": "medium",
        "fields": [
            {"name": "showIntroPage", "type": "boolean",
             "label": "Display introduction", "importance": "low"},
            {"name": "title", "type": "text", "label": "Title",
             "importance": "high", "optional": True,
             "tags": ["sub", "sup", "strong", "em", "code"]},
            {"name": "introduction", "type": "text", "widget": "html",
             "label": "Introduction text", "importance": "medium",
             "optional": True, "enterMode": "p",
             "tags": ["sub", "sup", "strong", "em", "p", "code"]},
            {"name": "startButtonText", "type": "text",
             "label": "Start button text", "importance": "low",
             "optional": True, "default": "Start Quiz"},
            {"name": "backgroundImage", "type": "image",
             "label": "Cover image", "importance": "low", "optional": True},
            {"name": "backgroundImageAltText", "type": "text",
             "label": "Alternative text", "importance": "low",
             "optional": True},
        ],
    },
    {
        "name": "progressType",
        "type": "select",
        "label": "Progress indicator",
        "importance": "low",
        "options": [
            {"value": "textual", "label": "Textual"},
            {"value": "dots", "label": "Dots"},
        ],
        "default": "dots",
    },
    {
        "name": "passPercentage",
        "type": "number",
        "label": "Pass percentage",
        "importance": "low",
        "min": 0,
        "max": 100,
        "step": 1,
        "default": 50,
    },
    {
        "name": "questions",
        "label": "Questions",
        "importance": "high",
        "type": "list",
        "min": 1,
        "entity": "question",
        "field": {
            "name": "question",
            "type": "library",
            "label": "Question type",
            "importance": "high",
            "options": [
                "H5P.MultiChoice 1.16",
                "H5P.DragQuestion 1.15",
                "H5P.Blanks 1.14",
                "H5P.MarkTheWords 1.11",
                "H5P.DragText 1.10",
                "H5P.TrueFalse 1.8",
                "H5P.Essay 1.5",
                "H5P.MultiMediaChoice 0.3",
            ],
        },
    },
    {
        "name": "texts",
        "type": "group",
        "label": "Interface texts in quiz",
        "importance": "low",
        "common": True,
        "fields": [
            {"name": "prevButton", "type": "text",
             "label": "Back button", "importance": "low",
             "default": "Previous question"},
        ],
    },
    {
        "name": "disableBackwardsNavigation",
        "type": "boolean",
        "label": "Disable backwards navigation",
        "importance": "low",
        "optional": True,
        "default": False,
    },
    {
        "name": "randomQuestions",
        "type": "boolean",
        "label": "Randomize questions",
        "importance": "low",
        "default": False,
    },
    {
        "name": "poolSize",
        "type": "number",
        "min": 1,
        "label": "Number of questions to be shown:",
        "importance": "low",
        "optional": True,
    },
    {
        "name": "endGame",
        "type": "group",
        "label": "Quiz finished",
        "importance": "medium",
        "fields": [
            {"name": "showResultPage", "type": "boolean",
             "label": "Display results", "importance": "low",
             "default": True},
            {"name": "showSolutionButton", "type": "boolean",
             "label": "Display solution button", "default": True},
            {"name": "showRetryButton", "type": "boolean",
             "label": "Display retry button", "default": True},
            {"name": "noResultMessage", "type": "text",
             "label": "No results message", "importance": "low",
             "default": "Finished", "optional": True},
            {"name": "message", "type": "text",
             "label": "Results heading", "importance": "low",
             "default": "Results",
             "tags": ["strong", "em", "code"]},
            {"name": "scoreBarLabel", "type": "text",
             "label": "Score announcer", "importance": "low",
             "default": "You got @finals out of @totals points"},
            {
                "name": "overallFeedback",
                "type": "group",
                "label": "Overall Feedback",
                "importance": "low",
                "expanded": True,
                "fields": [
                    {
                        "name": "overallFeedback",
                        "type": "list",
                        "widgets": [{"name": "RangeList", "label": "Default"}],
                        "importance": "high",
                        "label": "Define custom feedback",
                        "entity": "range",
                        "min": 1,
                        "optional": True,
                        "field": {
                            "name": "overallFeedback",
                            "type": "group",
                            "importance": "low",
                            "fields": [
                                {"name": "from", "type": "number",
                                 "label": "Score Range",
                                 "min": 0, "max": 100, "default": 0},
                                {"name": "to", "type": "number",
                                 "min": 0, "max": 100, "default": 100},
                                {"name": "feedback", "type": "text",
                                 "label": "Feedback for defined score range",
                                 "importance": "low", "optional": True},
                            ],
                        },
                    },
                ],
            },
            {
                "name": "oldFeedback",
                "type": "group",
                "label": "Old Feedback",
                "importance": "low",
                "deprecated": True,
                "fields": [
                    {"name": "successGreeting", "type": "text",
                     "label": "Quiz passed greeting",
                     "importance": "low", "optional": True},
                ],
            },
            {"name": "solutionButtonText", "type": "text",
             "label": "Solution button label", "importance": "low",
             "default": "Show solution"},
            {"name": "retryButtonText", "type": "text",
             "label": "Retry button label", "importance": "low",
             "default": "Retry"},
            {"name": "finishButtonText", "type": "text",
             "label": "Finish button text", "importance": "low",
             "default": "Finish"},
            {"name": "submitButtonText", "type": "text",
             "label": "Submit button text", "importance": "low",
             "default": "Submit"},
            {"name": "showAnimations", "type": "boolean",
             "label": "Display video before quiz results",
             "importance": "low"},
            {"name": "skippable", "type": "boolean",
             "label": "Enable skip video button", "importance": "low"},
            {"name": "skipButtonText", "type": "text",
             "label": "Skip video button label", "importance": "low",
             "default": "Skip video"},
            {"name": "successVideo", "type": "video",
             "label": "Passed video", "importance": "low", "optional": True},
            {"name": "failVideo", "type": "video",
             "label": "Fail video", "importance": "low", "optional": True},
        ],
    },
    {
        "name": "override",
        "type": "group",
        "label": "Behavioural settings",
        "importance": "low",
        "optional": True,
        "fields": [
            {"name": "checkButton", "type": "boolean",
             "label": "Show \"Check\" buttons",
             "importance": "low", "optional": True, "default": True},
            {
                "name": "showSolutionButton",
                "type": "select",
                "label": "Override \"Show Solution\" button",
                "importance": "low",
                "optional": True,
                "options": [
                    {"value": "on", "label": "Enabled"},
                    {"value": "off", "label": "Disabled"},
                ],
            },
            {
                "name": "retryButton",
                "type": "select",
                "label": "Override \"Retry\" button",
                "importance": "low",
                "optional": True,
                "options": [
                    {"value": "on", "label": "Enabled"},
                    {"value": "off", "label": "Disabled"},
                ],
            },
            {"name": "backgroundImage", "type": "image",
             "label": "Background image", "importance": "low",
             "optional": True},
        ],
    },
]


# -------------------------------------------------------------------
# Helpers
# -------------------------------------------------------------------

def _option_names(ir):
    """Return a set of RST option names from a DirectiveIR or child IR."""
    return {opt.name for opt in ir.options}


def _find_option(options, name):
    """Find an option by its RST name."""
    for opt in options:
        if opt.name == name:
            return opt
    return None


# -------------------------------------------------------------------
# H5P.TrueFalse
# -------------------------------------------------------------------

class TestTrueFalse:
    """Parser tests against H5P.TrueFalse semantics."""

    @pytest.fixture
    def ir(self):
        return parse("H5P.TrueFalse", "H5P.TrueFalse 1.8",
                      TRUE_FALSE_SEMANTICS)

    def test_directive_name(self, ir) -> None:
        assert ir.directive_name == "h5p-true-false"

    def test_machine_name(self, ir) -> None:
        assert ir.machine_name == "H5P.TrueFalse"

    def test_library(self, ir) -> None:
        assert ir.library == "H5P.TrueFalse 1.8"

    def test_body_is_question(self, ir) -> None:
        assert ir.body is not None
        assert ir.body.field_name == "question"
        assert ir.body.field_type == "text"

    def test_correct_is_option(self, ir) -> None:
        opt = _find_option(ir.options, "correct")
        assert opt is not None
        assert opt.field_type == "select"
        assert opt.choices == (("true", "True"), ("false", "False"))
        assert opt.default == "true"

    def test_l10n_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "true-text" not in names
        assert "false-text" not in names

    def test_confirm_check_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "header" not in names

    def test_media_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "disable-image-zooming" not in names

    def test_behaviour_flattened(self, ir) -> None:
        names = _option_names(ir)
        assert "enable-retry" in names
        assert "enable-solutions-button" in names
        assert "enable-check-button" in names
        assert "confirm-check-dialog" in names
        assert "confirm-retry-dialog" in names
        assert "auto-check" in names

    def test_behaviour_enable_retry_default(self, ir) -> None:
        opt = _find_option(ir.options, "enable-retry")
        assert opt is not None
        assert opt.default is True
        assert opt.field_type == "boolean"

    def test_behaviour_feedback_on_correct(self, ir) -> None:
        opt = _find_option(ir.options, "feedback-on-correct")
        assert opt is not None
        assert opt.field_type == "text"
        assert opt.required is False

    def test_no_structural_children(self, ir) -> None:
        assert ir.structural_children == ()

    def test_no_library_children(self, ir) -> None:
        assert ir.library_children == ()


# -------------------------------------------------------------------
# H5P.MultiChoice
# -------------------------------------------------------------------

class TestMultiChoice:
    """Parser tests against H5P.MultiChoice semantics."""

    @pytest.fixture
    def ir(self):
        return parse("H5P.MultiChoice", "H5P.MultiChoice 1.16",
                      MULTI_CHOICE_SEMANTICS)

    def test_directive_name(self, ir) -> None:
        assert ir.directive_name == "h5p-multi-choice"

    def test_body_is_question(self, ir) -> None:
        assert ir.body is not None
        assert ir.body.field_name == "question"
        assert ir.body.field_type == "text"

    def test_structural_child_answers(self, ir) -> None:
        assert len(ir.structural_children) == 1
        child = ir.structural_children[0]
        assert child.directive_name == "h5p-multi-choice-option"
        assert child.entity == "option"
        assert child.min_count == 1

    def test_structural_child_body(self, ir) -> None:
        child = ir.structural_children[0]
        assert child.body is not None
        assert child.body.field_name == "text"
        assert child.body.field_type == "text"

    def test_structural_child_correct_option(self, ir) -> None:
        child = ir.structural_children[0]
        opt = _find_option(child.options, "correct")
        assert opt is not None
        assert opt.field_type == "boolean"

    def test_structural_child_tips_skipped(self, ir) -> None:
        child = ir.structural_children[0]
        child_names = {o.name for o in child.options}
        assert "tips-and-feedback-tip" not in child_names
        assert "tip" not in child_names

    def test_overall_feedback_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "overall-feedback" not in names

    def test_ui_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "check-answer-button" not in names

    def test_behaviour_flattened(self, ir) -> None:
        names = _option_names(ir)
        assert "enable-retry" in names
        assert "type" in names
        assert "random-answers" in names

    def test_behaviour_type_select(self, ir) -> None:
        opt = _find_option(ir.options, "type")
        assert opt is not None
        assert opt.field_type == "select"
        assert opt.default == "auto"
        assert len(opt.choices) == 3

    def test_no_library_children(self, ir) -> None:
        assert ir.library_children == ()


# -------------------------------------------------------------------
# H5P.QuestionSet
# -------------------------------------------------------------------

class TestQuestionSet:
    """Parser tests against H5P.QuestionSet semantics."""

    @pytest.fixture
    def ir(self):
        return parse("H5P.QuestionSet", "H5P.QuestionSet 1.20",
                      QUESTION_SET_SEMANTICS)

    def test_directive_name(self, ir) -> None:
        assert ir.directive_name == "h5p-question-set"

    def test_no_body(self, ir) -> None:
        assert ir.body is None

    def test_library_child_questions(self, ir) -> None:
        assert len(ir.library_children) == 1
        child = ir.library_children[0]
        assert child.directive_name == "h5p-question-set-question"
        assert child.entity == "question"
        assert "H5P.MultiChoice 1.16" in child.libraries
        assert "H5P.TrueFalse 1.8" in child.libraries

    def test_progress_type_option(self, ir) -> None:
        opt = _find_option(ir.options, "progress-type")
        assert opt is not None
        assert opt.field_type == "select"
        assert opt.default == "dots"
        assert opt.choices == (("textual", "Textual"), ("dots", "Dots"))

    def test_pass_percentage_option(self, ir) -> None:
        opt = _find_option(ir.options, "pass-percentage")
        assert opt is not None
        assert opt.field_type == "number"
        assert opt.default == 50

    def test_disable_backwards_navigation(self, ir) -> None:
        opt = _find_option(ir.options, "disable-backwards-navigation")
        assert opt is not None
        assert opt.field_type == "boolean"
        assert opt.required is False

    def test_random_questions(self, ir) -> None:
        opt = _find_option(ir.options, "random-questions")
        assert opt is not None
        assert opt.field_type == "boolean"
        assert opt.default is False

    def test_pool_size(self, ir) -> None:
        opt = _find_option(ir.options, "pool-size")
        assert opt is not None
        assert opt.field_type == "number"

    def test_intro_page_flattened_with_prefix(self, ir) -> None:
        names = _option_names(ir)
        assert "intro-page-show-intro-page" in names
        assert "intro-page-title" in names
        assert "intro-page-start-button-text" in names

    def test_intro_page_image_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "intro-page-background-image" not in names

    def test_texts_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "prev-button" not in names

    def test_end_game_flattened_with_prefix(self, ir) -> None:
        names = _option_names(ir)
        assert "end-game-show-result-page" in names
        assert "end-game-show-solution-button" in names
        assert "end-game-show-retry-button" in names

    def test_end_game_video_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "end-game-success-video" not in names
        assert "end-game-fail-video" not in names

    def test_end_game_overall_feedback_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "end-game-overall-feedback" not in names

    def test_end_game_old_feedback_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "end-game-success-greeting" not in names

    def test_override_skipped(self, ir) -> None:
        names = _option_names(ir)
        assert "override-check-button" not in names

    def test_no_structural_children(self, ir) -> None:
        assert ir.structural_children == ()
