From d3ec9d1a870ab9d0f651adf8cc5b130afb458845 Mon Sep 17 00:00:00 2001 From: Anton T Date: Sun, 28 Nov 2021 22:57:52 +0300 Subject: [PATCH 1/8] Add pytest to requirements Add conftest --- conftest.py | 0 requirements.txt | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 conftest.py diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index f045283..46566b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ Pillow==8.1.2 requests==2.25.1 + +pytest~=6.2.5 From 3d677b1aee67b087146f7e4e137ac1e3b7eba0cd Mon Sep 17 00:00:00 2001 From: Anton T Date: Sun, 28 Nov 2021 23:02:54 +0300 Subject: [PATCH 2/8] Add tests --- tests/fake_class.py | 8 +++++ tests/test_code.py | 72 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/fake_class.py create mode 100644 tests/test_code.py diff --git a/tests/fake_class.py b/tests/fake_class.py new file mode 100644 index 0000000..8e95779 --- /dev/null +++ b/tests/fake_class.py @@ -0,0 +1,8 @@ +class Money: + value: int + + def __init__(self, value: int): + self.value = value + + def __add__(self, other): + return Money(self.value + other.value) diff --git a/tests/test_code.py b/tests/test_code.py new file mode 100644 index 0000000..46d21d9 --- /dev/null +++ b/tests/test_code.py @@ -0,0 +1,72 @@ +import io + +import pytest +from PIL import Image + +import code + +from fake_class import Money + + +@pytest.mark.parametrize('class_name,expected', [ + ('class_name', False), + ('ClassName', False), + ('Classname', True) +]) +def test_is_python_class_name(class_name, expected): + assert code.is_python_class_name(class_name) == expected + + +@pytest.mark.parametrize('items,default,expected', [ + (range(0, 9), None, 8), + ([], None, 0), + ([], 3, 3), + (range(100, 102), 192, 101) +]) +def test_max_with_default(items, default, expected): + assert code.max_with_default(items, default=default) == expected + + +@pytest.mark.parametrize('obj,class_name', [ + (3, 'int'), + (object, 'type'), + (None, 'NoneType'), + (Money(5), 'fake_class.Money'), +]) +def test_get_full_class_name(obj, class_name): + assert code.get_full_class_name(obj) == class_name + + +@pytest.mark.parametrize('camel_cased_word,words', [ + ('NotYetCamel', ['not', 'yet', 'camel']), + ('realCamelCaseWords', ['real', 'camel', 'case', 'words']), +]) +def test_split_camel_case_words(camel_cased_word, words): + assert code.split_camel_case_words(camel_cased_word) == words + + +@pytest.mark.parametrize('word,expected', [ + ('not_camel_cased_word', False), + ('camelCase', True), + ('NotCamelCase', True), + ('', False) +]) +def test_split_camel_case_words_without_capital_letters(word, expected): + assert code.is_camel_case_word(word) == expected + + +@pytest.mark.parametrize('log,commands', [ + (['log_entity1'], []), + ([], ['CMD1']), + ([], []) +]) +def test_if_logs_has_any_of_commands_with_epmty_lists(log, commands): + assert not code.if_logs_has_any_of_commands(log, commands) + + +def get_image(): + img = Image.new('RGB', (100,100), color='white') + buf = io.BytesIO() + img.save(buf, format='JPEG') + return buf.read() + From 55924ce4a3aa32cb6eeaa69f6a25f1b7435119bd Mon Sep 17 00:00:00 2001 From: Anton T Date: Sun, 28 Nov 2021 23:08:33 +0300 Subject: [PATCH 3/8] Style --- tests/test_code.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_code.py b/tests/test_code.py index 46d21d9..90383d4 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -65,8 +65,7 @@ def test_if_logs_has_any_of_commands_with_epmty_lists(log, commands): def get_image(): - img = Image.new('RGB', (100,100), color='white') + img = Image.new('RGB', (100, 100), color='white') buf = io.BytesIO() img.save(buf, format='JPEG') return buf.read() - From 1d2a99b00857c5dd11bc203d62973cc30c95d8b3 Mon Sep 17 00:00:00 2001 From: Anton T Date: Mon, 29 Nov 2021 22:55:53 +0300 Subject: [PATCH 4/8] Add tests --- tests/__init__.py | 0 tests/test_code.py | 37 +++++++++++++++++++++++++------------ tests/test_code_ast.py | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_code_ast.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_code.py b/tests/test_code.py index 90383d4..65006e8 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -1,11 +1,9 @@ -import io +import datetime import pytest -from PIL import Image import code - -from fake_class import Money +from tests.fake_class import Money @pytest.mark.parametrize('class_name,expected', [ @@ -31,7 +29,7 @@ def test_max_with_default(items, default, expected): (3, 'int'), (object, 'type'), (None, 'NoneType'), - (Money(5), 'fake_class.Money'), + (Money(5), 'tests.fake_class.Money'), ]) def test_get_full_class_name(obj, class_name): assert code.get_full_class_name(obj) == class_name @@ -58,14 +56,29 @@ def test_split_camel_case_words_without_capital_letters(word, expected): @pytest.mark.parametrize('log,commands', [ (['log_entity1'], []), ([], ['CMD1']), - ([], []) + ([], []), + (['CMD12'], ['CMD1']), ]) -def test_if_logs_has_any_of_commands_with_epmty_lists(log, commands): +def test_if_logs_has_any_of_commands_negative(log, commands): assert not code.if_logs_has_any_of_commands(log, commands) -def get_image(): - img = Image.new('RGB', (100, 100), color='white') - buf = io.BytesIO() - img.save(buf, format='JPEG') - return buf.read() +@pytest.mark.parametrize('log,commands', [ + (['', 'CMD1'], ['CMD1']), + (['Log1', 'CREATE_USER email pass'], ['CREATE_USER']), + (['request DELETE /users/email', '2021-02-22T15:02:01 DELETE_USER {email: EMAIL}'], ['DELETE_USER']), +]) +def test_if_logs_has_any_of_commands(log, commands): + assert code.if_logs_has_any_of_commands(log, commands) + + +now = datetime.datetime.utcnow() + + +@pytest.mark.parametrize('iso_datetime_str,expected', [ + (now.isoformat(), now), + (f'{now.isoformat()}Z', now), + ('NotRealyISODate', None) +]) +def test_parse_iso_datetime(iso_datetime_str, expected): + assert code.parse_iso_datetime(iso_datetime_str) == expected diff --git a/tests/test_code_ast.py b/tests/test_code_ast.py new file mode 100644 index 0000000..8293ff6 --- /dev/null +++ b/tests/test_code_ast.py @@ -0,0 +1,18 @@ +import ast +import code + + +func = ''' +def func_with_strings(): + s1 = "A" + s2 = "B" + if s2 == f"C": + return ",".join(s1) + else: + return s1 +''' + + +def test_extract_all_constants_from_ast(): + ast_tree = ast.parse(func) + assert set(code.extract_all_constants_from_ast(ast_tree)) == {'A', 'B', 'C', ','} From adb846f36ccb1c2625fca278ec2b62871633001e Mon Sep 17 00:00:00 2001 From: Anton T Date: Wed, 1 Dec 2021 23:46:19 +0300 Subject: [PATCH 5/8] Add tests --- tests/test_code.py | 32 ++++++++++++++++++++++++++++---- tests/test_code_ast.py | 29 ++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/tests/test_code.py b/tests/test_code.py index 65006e8..3b2b6af 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize('class_name,expected', [ ('class_name', False), ('ClassName', False), - ('Classname', True) + ('Classname', True), ]) def test_is_python_class_name(class_name, expected): assert code.is_python_class_name(class_name) == expected @@ -19,7 +19,7 @@ def test_is_python_class_name(class_name, expected): (range(0, 9), None, 8), ([], None, 0), ([], 3, 3), - (range(100, 102), 192, 101) + (range(100, 102), 192, 101), ]) def test_max_with_default(items, default, expected): assert code.max_with_default(items, default=default) == expected @@ -47,7 +47,7 @@ def test_split_camel_case_words(camel_cased_word, words): ('not_camel_cased_word', False), ('camelCase', True), ('NotCamelCase', True), - ('', False) + ('', False), ]) def test_split_camel_case_words_without_capital_letters(word, expected): assert code.is_camel_case_word(word) == expected @@ -78,7 +78,31 @@ def test_if_logs_has_any_of_commands(log, commands): @pytest.mark.parametrize('iso_datetime_str,expected', [ (now.isoformat(), now), (f'{now.isoformat()}Z', now), - ('NotRealyISODate', None) + ('NotRealyISODate', None), ]) def test_parse_iso_datetime(iso_datetime_str, expected): assert code.parse_iso_datetime(iso_datetime_str) == expected + + +@pytest.mark.parametrize('iterable,chunk_size', [ + (list(range(0, 9)), 2), +]) +def test_chunks(iterable, chunk_size): + source = [] + [source.extend(chunk) for chunk in list(code.chunks(iterable, chunk_size))] + assert source == iterable + + +@pytest.mark.parametrize('nested,flatted', [ + ([[12, 2, 3], [4]], [12, 2, 3, 4]), + ([[]], []), +]) +def test_flat(nested, flatted): + assert code.flat(nested) == flatted + + +@pytest.mark.parametrize('path,exclude', [ + ('/fword/some/path', ['not', 'fword']), +]) +def test_is_path_in_exclude_list(path, exclude): + assert code.is_path_in_exclude_list(path, exclude) diff --git a/tests/test_code_ast.py b/tests/test_code_ast.py index 8293ff6..113b139 100644 --- a/tests/test_code_ast.py +++ b/tests/test_code_ast.py @@ -1,8 +1,12 @@ import ast + +import pytest + import code -func = ''' +def test_extract_all_constants_from_ast(): + func = """ def func_with_strings(): s1 = "A" s2 = "B" @@ -10,9 +14,24 @@ def func_with_strings(): return ",".join(s1) else: return s1 -''' - - -def test_extract_all_constants_from_ast(): + """ ast_tree = ast.parse(func) assert set(code.extract_all_constants_from_ast(ast_tree)) == {'A', 'B', 'C', ','} + + +@pytest.mark.xfail +def test_rec(): + fibonacci = """ +def fibonacci(n): + if n == 1: + return 1 + elif n == 2: + return 1 + else: + return f(n-1) + f(n-2) +fibonacci(5) + """ + ast_tree = ast.parse(fibonacci) + for node in ast.walk(ast_tree): + if type(node) == ast.FunctionDef: + assert code.has_recursive_calls(node) From 715d23a5c9c87667b76109b1db1143b183f97f32 Mon Sep 17 00:00:00 2001 From: Anton T Date: Sat, 4 Dec 2021 11:31:45 +0300 Subject: [PATCH 6/8] Add test for get_image_height_in_pixels --- tests/test_code.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_code.py b/tests/test_code.py index 3b2b6af..8432498 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -106,3 +106,11 @@ def test_flat(nested, flatted): ]) def test_is_path_in_exclude_list(path, exclude): assert code.is_path_in_exclude_list(path, exclude) + +@pytest.mark.parametrize('url,expected', [ + ('//notrealurl.com/img.jpg', None), + ('asdfjads', None), + ('https://docs.pytest.org/en/6.2.x/_static/pytest1.png', 143) +]) +def test_get_image_height_in_pixels(url, expected): + assert code.get_image_height_in_pixels(url) == expected From a8e675df5ec449fd6c6f412c3c6f29db73cb8a8d Mon Sep 17 00:00:00 2001 From: Anton T Date: Sat, 4 Dec 2021 11:36:36 +0300 Subject: [PATCH 7/8] Fix test for has_recursive_calls --- tests/test_code_ast.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_code_ast.py b/tests/test_code_ast.py index 113b139..d58ca6c 100644 --- a/tests/test_code_ast.py +++ b/tests/test_code_ast.py @@ -19,7 +19,6 @@ def func_with_strings(): assert set(code.extract_all_constants_from_ast(ast_tree)) == {'A', 'B', 'C', ','} -@pytest.mark.xfail def test_rec(): fibonacci = """ def fibonacci(n): @@ -28,7 +27,7 @@ def fibonacci(n): elif n == 2: return 1 else: - return f(n-1) + f(n-2) + return fibonacci(n-1) + fibonacci(n-2) fibonacci(5) """ ast_tree = ast.parse(fibonacci) From 4e35b55240e7c7e53656bd49712e12812d7e58ce Mon Sep 17 00:00:00 2001 From: Anton T Date: Sat, 4 Dec 2021 11:40:22 +0300 Subject: [PATCH 8/8] Style fixes --- tests/test_code.py | 3 ++- tests/test_code_ast.py | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_code.py b/tests/test_code.py index 8432498..368d05c 100644 --- a/tests/test_code.py +++ b/tests/test_code.py @@ -107,10 +107,11 @@ def test_flat(nested, flatted): def test_is_path_in_exclude_list(path, exclude): assert code.is_path_in_exclude_list(path, exclude) + @pytest.mark.parametrize('url,expected', [ ('//notrealurl.com/img.jpg', None), ('asdfjads', None), - ('https://docs.pytest.org/en/6.2.x/_static/pytest1.png', 143) + ('https://docs.pytest.org/en/6.2.x/_static/pytest1.png', 143), ]) def test_get_image_height_in_pixels(url, expected): assert code.get_image_height_in_pixels(url) == expected diff --git a/tests/test_code_ast.py b/tests/test_code_ast.py index d58ca6c..fa6358f 100644 --- a/tests/test_code_ast.py +++ b/tests/test_code_ast.py @@ -1,7 +1,5 @@ import ast -import pytest - import code