Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 1 addition & 17 deletions bot/exts/info/codeblock/_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,23 +148,7 @@ def get_instructions(content: str) -> str | None:
instructions = _get_no_ticks_message(content)
else:
log.trace("Searching results for a code block with invalid ticks.")
bad_ticks = [block for block in blocks if block.tick != _parsing.BACKTICK]
block = None
if bad_ticks:
block = next(
(
bad_tick
for bad_tick in bad_ticks
if any(
block
for block in blocks
if block != bad_tick
and bad_tick.content != block.content
and bad_tick.content not in block.content
)
),
None,
)
block = next((block for block in blocks if block.tick != _parsing.BACKTICK), None)

if block:
log.trace("A code block exists but has invalid ticks.")
Expand Down
6 changes: 1 addition & 5 deletions bot/exts/info/codeblock/_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
from collections.abc import Sequence
from typing import NamedTuple

import regex

from bot import constants
from bot.log import get_logger
from bot.utils import has_lines
Expand Down Expand Up @@ -47,8 +45,6 @@
""",
re.DOTALL | re.VERBOSE
)
# copy of _RE_CODE_BLOCK. Done like this for highlighting reasons (regex.compile doesn't properly highlight)
_REGEX_CODE_BLOCK = regex.compile(_RE_CODE_BLOCK.pattern, regex.DOTALL | regex.VERBOSE)

_RE_LANGUAGE = re.compile(
fr"""
Expand Down Expand Up @@ -91,7 +87,7 @@ def find_faulty_code_blocks(message: str) -> Sequence[CodeBlock] | None:
log.trace("Finding all code blocks in a message.")

code_blocks = []
for match in _REGEX_CODE_BLOCK.finditer(message, overlapped=True):
for match in _RE_CODE_BLOCK.finditer(message):
# Used to ensure non-matched groups have an empty string as the default value.
groups = match.groupdict("")
language = groups["lang"].strip() # Strip the whitespace cause it's included in the group.
Expand Down
93 changes: 93 additions & 0 deletions tests/bot/exts/info/codeblock/test_instructions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import unittest
from textwrap import dedent

from bot.exts.info.codeblock import _instructions as instructions, _parsing as parsing


class ProvideBadTicksInstructionsTest(unittest.TestCase):
def __assert_is_instructions_for_message_bad_ticks_one(self, message: str) -> None:
code_blocks = parsing.find_faulty_code_blocks(message)
self.assertIsNotNone(code_blocks)

# Type narrowing
if code_blocks is None:
return

code_block = next((block for block in code_blocks if block.tick != parsing.BACKTICK), None)
self.assertIsNotNone(code_block)

# Type narrowing
if code_block is None:
return

expected_instructions_text = instructions._get_bad_ticks_message(code_block)
self.assertIsInstance(expected_instructions_text, str)

# Type narrowing
if not isinstance(expected_instructions_text, str):
return

instructions_text = instructions.get_instructions(message)
self.assertIsInstance(instructions_text, str)

# Type narrowing
if not isinstance(instructions_text, str):
return

self.assertEqual(instructions_text, expected_instructions_text)

def test_should_provide_when_no_lang_spec_and_bad_ticks_are_used(self) -> None:
message = dedent("""
'''
\"\"\"Docstring\"\"\"
numbs = [1, 2, 3]

for numb in numbs:
print(numb)
'''
""").strip()
self.__assert_is_instructions_for_message_bad_ticks_one(message)

def test_should_provide_when_correct_lang_spec_and_bad_ticks_are_used(self) -> None:
message = dedent("""
'''py
\"\"\"Docstring\"\"\"
numbs = [1, 2, 3]

for numb in numbs:
print(numb)
'''
""").strip()
self.__assert_is_instructions_for_message_bad_ticks_one(message)

def test_should_provide_when_wrong_lang_spec_and_bad_ticks_are_used(self) -> None:
message = dedent("""
'''c
\"\"\"Docstring\"\"\"
numbs = [1, 2, 3]

for numb in numbs:
print(numb)
'''
""").strip()
self.__assert_is_instructions_for_message_bad_ticks_one(message)

def test_should_provide_bad_ticks_are_used_in_two_identical_codeblocks(self) -> None:
message = dedent("""
'''
\"\"\"Docstring\"\"\"
numbs = [1, 2, 3]

for numb in numbs:
print(numb)
'''

'''
\"\"\"Docstring\"\"\"
numbs = [1, 2, 3]

for numb in numbs:
print(numb)
'''
""").strip()
self.__assert_is_instructions_for_message_bad_ticks_one(message)
2 changes: 1 addition & 1 deletion tests/bot/exts/info/codeblock/test_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def test_should_recognize_contained_codeblock(self):
faulty_code_blocks = parsing.find_faulty_code_blocks(message)
self.assertIsNone(faulty_code_blocks)

@unittest.expectedFailure
def test_should_recognize_contained_codeblock_even_if_that_breaks_formatting(self):
message = """```
```py
Expand Down Expand Up @@ -67,7 +68,6 @@ def test_should_not_recognize_quoting_single_quotes(self):
self.assertIsNotNone(faulty_code_blocks)
self.assertEqual(len(faulty_code_blocks), 0)


def test_should_not_recognize_normal_double_quotes(self):
"""normal double quotes refer to double quotes that appear normally in text to quote something"""
message = """ "I am doing a long quote.
Expand Down