Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge fix branch Bug/tests/result-set-definition-error #9

Merged
merged 11 commits into from
May 24, 2023
59 changes: 52 additions & 7 deletions src/urban.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def assert_index_valid(_index: int):
raise TypeError("Index should be an integer")

if _index > 0:
PendingDeprecationWarning(
raise PendingDeprecationWarning(
"Index parameter is introduced in > 1.1.0. If you are on an eariler release this is an experimental command."
)

Expand Down Expand Up @@ -335,6 +335,42 @@ def get_statistics_from_soup(_soup: BeautifulSoup):
# print(type(x))
return;

def get_author_from_soup(_soup: BeautifulSoup) -> str:
"""Return author from soup.

:param _soup: `_soup` object as `BeautifulSoup` object.
:return: author as a string
"""

# get definition container
container = derive_definition_as_tag(_soup)

return (
container.find_next("div", class_="contributor")
.find_next("a")["href"]
.split("=")[1]
)


@deprecated("Likes and dislikes are rendered via javascript")
def get_statistics_from_soup(_soup: BeautifulSoup):
"""Return likes and dislikes (both integers) as a dictionary.

:param _soup: `_soup` object as `BeautifulSoup` object.
return: likes and dislikes (both integers) as a dictionary.
"""

# get definition container
container = derive_definition_as_tag(_soup)

x: Tag = container.find_next("div", class_="contributor").find_next_sibling(
"div"
) # pyright: ignore
print(x.find_all(name="span", recursive=True, attrs={"class": "text-xs"}))
# print(type(x))
return


# TODO get `_definition` working
def fetch_word_from_remote(_word: str) -> dict[str, str] | None:
"""Query urban dictionary for `_word`.
Expand Down Expand Up @@ -364,6 +400,9 @@ def fetch_word_from_remote(_word: str) -> dict[str, str] | None:

words_as_str = format_words_as_string_from_tag(word_meaning, hyperlinks_list)

if not isinstance(words_as_str, str) or words_as_str == "":
words_as_str = "Definition not found or not available."

# NOTE don't delete!
print(words_as_str)

Expand All @@ -372,13 +411,19 @@ def fetch_word_from_remote(_word: str) -> dict[str, str] | None:
date_posted = ""

# TODO/FIXME return date and author as well
return {"definition": "", "author": post_author, "date": date_posted}
return {"definition": words_as_str, "author": post_author, "date": date_posted}


def main():
word = join_words()

word = join_words()
# NOTE: deprecated function
# get_statistics_from_soup(get_soup_object_from_word(word))
fetch_word_from_remote(word)

# NOTE: deprecated function
# get_statistics_from_soup(get_soup_object_from_word(word))
fetch_word_from_remote(word)
print(
f"Defined by {colorama.Fore.BLUE}{get_author_from_soup(get_soup_object_from_word(word))}{colorama.Fore.RESET}"
)

print(f"Defined by {colorama.Fore.BLUE}{get_author_from_soup(get_soup_object_from_word(word))}{colorama.Fore.RESET}")
if __name__ == "__main__":
main()
75 changes: 49 additions & 26 deletions tests/test_urban.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@

from bs4 import BeautifulSoup, NavigableString, Tag

from urban import (
sys.path.insert(0, os.getcwd())

from src.urban import (
assert_index_valid,
assert_soup_and_index_valid,
derive_meaning_as_tag,
get_found_word_from_soup,
get_soup_object_from_word,
)

sys.path.insert(0, os.path.join(os.path.dirname(os.getcwd()), "src"))


class TestUrban(unittest.TestCase):
def __init__(self) -> None:
def __init__(self, methodName: str = "runTest") -> None:
self.word_index = 0
self.words = [
"YOLO",
Expand All @@ -31,18 +32,17 @@ def __init__(self) -> None:
"rickroll",
]

super().__init__()
super().__init__(methodName)

def setUp(self) -> None:
try:
self.word = self.words[self.word_index]
import random
self.word = random.choice(self.words)
print(f"[{self.words.index(self.word)}] LOOKING UP: {self.word}")
self.soup = get_soup_object_from_word(self.word)
self.word_index += 1
except IndexError:
sys.exit(0)

return super().setUp()

def test_definition_from_soup_object(self):
"""
Test definition class is present in each soup object.
Expand All @@ -67,11 +67,18 @@ def test_word_index_raises_warning(self):
Test that word index raises warning when greater than 0
"""

_soup = get_soup_object_from_word(self.word)
# NOTE This relies on there being more than 1 definition present.
with self.assertRaises(PendingDeprecationWarning):
assert_index_valid(_index=1)

def test_invalid_word_index_raises_error_from_float(self):
"""
Test invalid type in word index raises type erorr
"""

# NOTE This relies on there being more than 1 definition present.
with self.assertWarns(PendingDeprecationWarning):
assert_soup_and_index_valid(_soup, _index=1)
with self.assertRaises(TypeError):
assert_index_valid(_index=float(2.3)) # pyright: ignore

def test_word_index_raises_index_error(self):
"""
Expand All @@ -80,11 +87,8 @@ def test_word_index_raises_index_error(self):

_soup = get_soup_object_from_word(self.word)

# NOTE In order of warns / errors
with self.assertWarns(PendingDeprecationWarning) or self.assertRaises(
IndexError
):
assert_soup_and_index_valid(_soup, _index=999)
with self.assertRaises(PendingDeprecationWarning):
assert_index_valid(_index=9000000)

def test_word_type_raises_type_error(self):
"""
Expand All @@ -93,17 +97,17 @@ def test_word_type_raises_type_error(self):

_soup = get_soup_object_from_word(self.word)

assert isinstance(_soup.string, BeautifulSoup)
# assert isinstance(_soup.string, BeautifulSoup)
with self.assertRaises(TypeError):
assert_soup_and_index_valid(_soup.string, _index=0)
assert_soup_and_index_valid(_soup=False)

def test_word_none_raises_key_error(self):
def test_word_none_raises_index_error(self):
"""
Test that word raises keyerror when word is none
Test that word raises indexerror when word non-existant.
"""

with self.assertRaises(KeyError):
get_found_word_from_soup(None) # pyright: ignore
with self.assertRaises(IndexError):
get_found_word_from_soup(BeautifulSoup("test", features="lxml")) # pyright: ignore

def test_found_word_equal_to_parameter(self):
"""
Expand Down Expand Up @@ -141,6 +145,25 @@ def test_derivation_index_overload_raises_error(self):
_soup = get_soup_object_from_word(self.word)

with self.assertRaises(IndexError):
assert isinstance(
derive_meaning_as_tag(_soup, _index=999), Tag
) # pyright: ignore
assert isinstance(derive_meaning_as_tag(_soup), Tag) # pyright: ignore

def test_words_as_other_type_returns_str_error(self):
"""Test `words_as_str` returns string-based error on invalid data type output"""

def test_word_from_soup_raises_index_error(self):
"""Test that word from soup raises when a given value is missing"""

with self.assertRaises(IndexError):
_soup = get_soup_object_from_word(self.word)
word_soup = _soup.find_all_next("a")[0].select(".definintion")
word_soup_raises_key_error = word_soup[0].replace_with(
word_soup[0].get_text(strip=False)
)

assert_soup_and_index_valid(_soup)

get_found_word_from_soup(
BeautifulSoup(
word_soup_raises_key_error.get_text(strip=False), "html.parser"
)
)