예제 #1
0
    def __initialize_logging(
            self, args: argparse.Namespace) -> Optional[logging.FileHandler]:

        self.__show_stack_trace = args.show_stack_trace
        if not self.__show_stack_trace:
            self.__show_stack_trace = self.__properties.get_boolean_property(
                "log.stack-trace")

        effective_log_file = (self.__properties.get_string_property("log.file")
                              if args.log_file is None else args.log_file)
        new_handler = None
        if effective_log_file:
            new_handler = logging.FileHandler(effective_log_file)
            logging.getLogger().addHandler(new_handler)
        else:
            temp_log_level = (logging.DEBUG
                              if self.__show_stack_trace else logging.CRITICAL)
            logging.basicConfig(stream=sys.stdout, level=temp_log_level)

        effective_log_level = args.log_level or None
        if effective_log_level is None:
            effective_log_level = self.__properties.get_string_property(
                "log.level", valid_value_fn=PyMarkdownLint.log_level_type)
        if effective_log_level is None:
            effective_log_level = self.default_log_level

        log_level_to_enact = PyMarkdownLint.available_log_maps[
            effective_log_level]

        logging.getLogger().setLevel(log_level_to_enact)
        ParserLogger.sync_on_next_call()
        return new_handler
예제 #2
0
def test_markdown_logger_inactive():
    """
    Since calls to it are commented out most of the time,
    test the debug_with_visible_whitespace function manually.
    """
    configuration_file_name = None
    new_handler = None
    root_logger = None
    file_as_lines = None
    try:
        configuration_file_name = write_temporary_configuration("")
        new_handler = logging.FileHandler(configuration_file_name)

        root_logger = logging.getLogger()
        root_logger.setLevel(logging.WARNING)
        root_logger.addHandler(new_handler)

        assert POGGER.is_enabled_for(logging.WARNING)
        new_logger = ParserLogger(logging.getLogger(__name__))
        new_logger.debug("simple logging")
    finally:
        if root_logger and new_handler:
            root_logger.removeHandler(new_handler)
            new_handler.close()
        with open(configuration_file_name, encoding="utf-8") as file_to_parse:
            file_as_lines = file_to_parse.readlines()
        if configuration_file_name and os.path.exists(configuration_file_name):
            os.remove(configuration_file_name)

    assert not file_as_lines
예제 #3
0
def act_and_assert(
    source_markdown,
    expected_gfm,
    expected_tokens,
    show_debug=False,
    config_map=None,
    disable_consistency_checks=False,
):
    """
    Act and assert on the expected behavior of parsing the source_markdown.
    """

    # Arrange
    logging.getLogger().setLevel(logging.DEBUG if show_debug else logging.WARNING)
    ParserLogger.sync_on_next_call()

    tokenizer = TokenizedMarkdown()
    test_properties = ApplicationProperties()
    if config_map:
        test_properties.load_from_dict(config_map)
    extension_manager = ExtensionManager()
    extension_manager.initialize(None, test_properties)
    extension_manager.apply_configuration()
    tokenizer.apply_configuration(test_properties, extension_manager)
    transformer = TransformToGfm()

    # Act
    actual_tokens = tokenizer.transform(source_markdown, show_debug=show_debug)
    actual_gfm = transformer.transform(actual_tokens)

    # Assert
    assert_if_lists_different(expected_tokens, actual_tokens)
    assert_if_strings_different(expected_gfm, actual_gfm)
    if not disable_consistency_checks:
        assert_token_consistency(source_markdown, actual_tokens)
예제 #4
0
def test_markdown_logger_arg_list_not_out_of_sync_with_debug():
    """
    Since calls to it are commented out most of the time,
    test the debug_with_visible_whitespace function manually.
    """
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.DEBUG)
    assert POGGER.is_enabled_for(logging.DEBUG)
    new_logger = ParserLogger(logging.getLogger(__name__))
    new_logger.debug_with_visible_whitespace("one sub $ and one in list",
                                             " 1 ")
예제 #5
0
def test_markdown_with_dash_dash_log_level_info_with_file():
    # sourcery skip: extract-method
    """
    Test to make sure we get the right effect if the `--log-level` flag
    is set for info with the results going to a file.
    """

    # Arrange
    temp_file = None
    with tempfile.NamedTemporaryFile(delete=False) as temp_file:
        log_file_name = temp_file.name

    try:
        scanner = MarkdownScanner()
        supplied_arguments = [
            "--log-level",
            "INFO",
            "--log-file",
            log_file_name,
            "scan",
            "test/resources/rules/md047/end_with_blank_line.md",
        ]

        expected_return_code = 0
        expected_output = ""
        expected_error = ""

        # Act
        ParserLogger.sync_on_next_call()
        execute_results = scanner.invoke_main(arguments=supplied_arguments)

        # Assert
        execute_results.assert_results(expected_output, expected_error,
                                       expected_return_code)

        with open(log_file_name, encoding="utf-8") as file:
            file_data = file.read().replace("\n", "")

        # Info messages
        assert "Number of files found: " in file_data, f">{file_data}<"
        assert ("Determining files to scan for path " +
                "'test/resources/rules/md047/end_with_blank_line.md'."
                in file_data)

        # Debug messages
        assert (
            "Provided path 'test/resources/rules/md047/end_with_blank_line.md' "
            + "is a valid file. Adding." not in file_data)
    finally:
        if os.path.exists(log_file_name):
            os.remove(log_file_name)
예제 #6
0
    def transform(self,
                  your_text_string: str,
                  show_debug: bool = False) -> List[MarkdownToken]:
        """
        Transform a text string in a Markdown format into a Markdown token stream.
        This function should only be used as a simplified manner of accessing the
        functionality for the purposes of testing.
        """

        logging.getLogger().setLevel(
            logging.DEBUG if show_debug else logging.WARNING)
        ParserLogger.sync_on_next_call()
        self.__source_provider = InMemorySourceProvider(your_text_string)
        return self.__transform()
예제 #7
0
def test_markdown_with_dash_dash_log_level_invalid(caplog):
    """
    Test to make sure we get the right effect if the `--log-level` flag
    is set for an invalid log level.
    """

    # Arrange
    scanner = MarkdownScanner()
    supplied_arguments = [
        "--log-level",
        "invalid",
        "scan",
        "test/resources/rules/md047/end_with_blank_line.md",
    ]

    expected_return_code = 2
    expected_output = ""
    expected_error = """usage: main.py [-h] [-e ENABLE_RULES] [-d DISABLE_RULES]
               [--add-plugin ADD_PLUGIN] [--config CONFIGURATION_FILE]
               [--set SET_CONFIGURATION] [--strict-config] [--stack-trace]
               [--log-level {CRITICAL,ERROR,WARNING,INFO,DEBUG}]
               [--log-file LOG_FILE]
               {plugins,extensions,scan,version} ...
main.py: error: argument --log-level: invalid log_level_type value: 'invalid'
"""

    # Act
    ParserLogger.sync_on_next_call()
    execute_results = scanner.invoke_main(arguments=supplied_arguments)

    # Assert
    execute_results.assert_results(expected_output, expected_error,
                                   expected_return_code)

    # Info messages
    assert "Number of scanned files found: " not in caplog.text
    assert ("Determining files to scan for path " +
            "'test/resources/rules/md047/end_with_blank_line.md'."
            not in caplog.text)

    # Debug messages
    assert (
        "Provided path 'test/resources/rules/md047/end_with_blank_line.md' " +
        "is a valid Markdown file. Adding." not in caplog.text)
예제 #8
0
def test_markdown_logger_arg_list_out_of_sync():
    """
    Test to verify that if we don't have the same number of
    $ characters in the string as arguments in the list, an
    exception with be thrown.
    """

    # Arrange
    try:
        root_logger = logging.getLogger()
        root_logger.setLevel(logging.DEBUG)
        assert POGGER.is_enabled_for(logging.DEBUG)
        new_logger = ParserLogger(logging.getLogger(__name__))
        new_logger.debug("one sub $ but two in list", 1, 2)
        raise AssertionError("An exception should have been thrown by now.")
    except Exception as this_exception:
        assert (
            str(this_exception) ==
            "The number of $ substitution characters does not equal the number of arguments in the list."
        )
예제 #9
0
def test_markdown_with_dash_dash_log_level_info(caplog):
    """
    Test to make sure we get the right effect if the `--log-level` flag
    is set for info.
    """

    # Arrange
    scanner = MarkdownScanner()
    supplied_arguments = [
        "--log-level",
        "INFO",
        "scan",
        "test/resources/rules/md047/end_with_blank_line.md",
    ]

    expected_return_code = 0
    expected_output = ""
    expected_error = ""

    # Act
    ParserLogger.sync_on_next_call()
    execute_results = scanner.invoke_main(arguments=supplied_arguments)

    # Assert
    execute_results.assert_results(expected_output, expected_error,
                                   expected_return_code)

    # Info messages
    assert "Number of files found: " in caplog.text
    assert ("Determining files to scan for path " +
            "'test/resources/rules/md047/end_with_blank_line.md'."
            in caplog.text)

    # Debug messages
    assert (
        "Provided path 'test/resources/rules/md047/end_with_blank_line.md' " +
        "is a valid file. Adding." not in caplog.text)
"""
Module to provide for a container element that can be added to markdown parsing stream.
"""
import logging
from typing import Optional

from pymarkdown.markdown_token import MarkdownToken, MarkdownTokenClass
from pymarkdown.parser_helper import ParserHelper
from pymarkdown.parser_logger import ParserLogger
from pymarkdown.position_marker import PositionMarker

POGGER = ParserLogger(logging.getLogger(__name__))


# pylint: disable=too-many-arguments
class ContainerMarkdownToken(MarkdownToken):
    """
    Class to provide for a container element that can be added to markdown parsing stream.
    """

    def __init__(
        self,
        token_name: str,
        extra_data: str,
        line_number: int = 0,
        column_number: int = 0,
        position_marker: Optional[PositionMarker] = None,
    ) -> None:
        MarkdownToken.__init__(
            self,
            token_name,