forked from puneetgavri/python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into drop-python2
- Loading branch information
Showing
4 changed files
with
165 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{%- import "generator_macros.j2" as macros with context -%} | ||
{{ macros.header(imports=imports, ignore=ignore) }} | ||
|
||
{%- macro test_cases_recursive(cases) -%} | ||
{% for case in cases -%} | ||
{% if "cases" in case %} | ||
# {{ case["description"] }} | ||
{{ test_cases_recursive(case["cases"]) }} | ||
{% else %} | ||
{{ test_case(case) }} | ||
{% endif -%} | ||
{% endfor -%} | ||
{% endmacro %} | ||
|
||
{% if not additional_tests -%} | ||
{%- macro additional_tests() -%} | ||
{{ test_cases_recursive(additional_cases) }} | ||
{% endmacro %} | ||
{%- endif %} | ||
|
||
class {{ exercise | camel_case }}Test(unittest.TestCase): | ||
{{ test_cases_recursive(cases) }} | ||
|
||
{% if additional_cases | length -%} | ||
# Additional tests for this track | ||
{{ additional_tests() }} | ||
{%- endif %} | ||
{{ macros.footer() }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"cases": [ | ||
{ | ||
"description": "foldr add string", | ||
"property": "foldr", | ||
"input": { | ||
"list": ["e", "x", "e", "r", "c", "i", "s", "m"], | ||
"initial": "!", | ||
"function": "(x, y) -> x + y" | ||
}, | ||
"expected": "exercism!" | ||
}, | ||
{ | ||
"description": "reverse mixed types", | ||
"property": "reverse", | ||
"input": { | ||
"list": ["xyz", 4.0, "cat", 1] | ||
}, | ||
"expected": [1, "cat", 4.0, "xyz"] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{%- import "generator_macros.j2" as macros with context -%} | ||
{% macro lambdify(function) -%} | ||
{% set function = function.replace("(", "", 1).replace(")", "", 1).replace(" ->", ":") %} | ||
{% set function = function.replace("modulo", "%") %} | ||
{% set function = function.replace("/", "//") %} | ||
lambda {{function}} | ||
{%- endmacro %} | ||
|
||
{% macro stringify(elem) -%} | ||
{% if elem is string %} | ||
"{{ elem }}" | ||
{%- else -%} | ||
{{ elem }} | ||
{%- endif -%} | ||
{%- endmacro %} | ||
|
||
{% macro test_case(case) -%} | ||
{%- set input = case["input"] -%} | ||
def test_{{ case["property"] | to_snake }}_{{ case["description"] | to_snake }}(self): | ||
self.assertEqual( | ||
{%- if case["property"] == "filter" or case["property"] == "map" -%} | ||
list_ops_ | ||
{%- endif -%} | ||
{{ case["property"] | to_snake }}( | ||
{%- if case["property"] == "append" -%} | ||
{{ input["list1"] }}, {{ input["list2"] }} | ||
{%- elif case["property"] == "concat" -%} | ||
{{ input["lists"] }} | ||
{%- elif case["property"] == "filter" or case["property"] == "map" -%} | ||
{{ lambdify(input["function"]) }}, {{ input["list"] }} | ||
{%- elif case["property"] == "length" or case["property"] == "reverse" -%} | ||
{{ input["list"] }} | ||
{%- elif case["property"] == "foldl" or case["property"] == "foldr" -%} | ||
{{ lambdify(input["function"]) }}, {{ input["list"] }}, {{ stringify(input["initial"]) }} | ||
{%- endif -%} | ||
), | ||
{{ stringify(case["expected"]) }} | ||
) | ||
{%- endmacro %} | ||
{{ macros.header(imports=["append", "concat", "foldl", "foldr", "length", "reverse", "filter as list_ops_filter", "map as list_ops_map"]) }} | ||
|
||
class {{ exercise | camel_case }}Test(unittest.TestCase): | ||
{% for casegroup in cases -%} | ||
{% for case in casegroup["cases"] -%} | ||
{{ test_case(case) }} | ||
{% endfor %} | ||
{% endfor %} | ||
{% if additional_cases | length -%} | ||
|
||
# Additional tests for this track | ||
|
||
{% for case in additional_cases -%} | ||
{{ test_case(case) }} | ||
{% endfor %} | ||
{%- endif %} | ||
|
||
|
||
{{ macros.footer() }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,99 @@ | ||
import unittest | ||
import operator | ||
|
||
import list_ops | ||
from list_ops import ( | ||
append, | ||
concat, | ||
foldl, | ||
foldr, | ||
length, | ||
reverse, | ||
filter as list_ops_filter, | ||
map as list_ops_map, | ||
) | ||
|
||
# Tests adapted from `problem-specifications//canonical-data.json` @ v2.4.1 | ||
|
||
# Tests adapted from `problem-specifications//canonical-data.json` @ v2.4.0 | ||
|
||
class ListOpsTest(unittest.TestCase): | ||
|
||
# test for append | ||
def test_append_empty_lists(self): | ||
self.assertEqual(list_ops.append([], []), []) | ||
self.assertEqual(append([], []), []) | ||
|
||
def test_append_empty_list_to_list(self): | ||
self.assertEqual(list_ops.append([], [1, 2, 3, 4]), [1, 2, 3, 4]) | ||
def test_append_list_to_empty_list(self): | ||
self.assertEqual(append([], [1, 2, 3, 4]), [1, 2, 3, 4]) | ||
|
||
def test_append_nonempty_lists(self): | ||
self.assertEqual(list_ops.append([1, 2], [2, 3, 4, 5]), | ||
[1, 2, 2, 3, 4, 5]) | ||
def test_append_non_empty_lists(self): | ||
self.assertEqual(append([1, 2], [2, 3, 4, 5]), [1, 2, 2, 3, 4, 5]) | ||
|
||
# tests for concat | ||
def test_concat_empty_list(self): | ||
self.assertEqual(list_ops.concat([]), []) | ||
self.assertEqual(concat([]), []) | ||
|
||
def test_concat_list_of_lists(self): | ||
self.assertEqual(list_ops.concat([[1, 2], [3], [], [4, 5, 6]]), | ||
[1, 2, 3, 4, 5, 6]) | ||
self.assertEqual(concat([[1, 2], [3], [], [4, 5, 6]]), [1, 2, 3, 4, 5, 6]) | ||
|
||
def test_concat_list_of_nested_lists(self): | ||
self.assertEqual( | ||
list_ops.concat([[[1], [2]], [[3]], [[]], [[4, 5, 6]]]), | ||
[[1], [2], [3], [], [4, 5, 6]]) | ||
concat([[[1], [2]], [[3]], [[]], [[4, 5, 6]]]), | ||
[[1], [2], [3], [], [4, 5, 6]], | ||
) | ||
|
||
# tests for filter | ||
def test_filter_empty_list(self): | ||
self.assertEqual(list_ops.filter(lambda x: x % 2 == 1, []), []) | ||
self.assertEqual(list_ops_filter(lambda x: x % 2 == 1, []), []) | ||
|
||
def test_filter_nonempty_list(self): | ||
self.assertEqual( | ||
list_ops.filter(lambda x: x % 2 == 1, [1, 2, 3, 4, 5]), | ||
[1, 3, 5]) | ||
def test_filter_non_empty_list(self): | ||
self.assertEqual(list_ops_filter(lambda x: x % 2 == 1, [1, 2, 3, 5]), [1, 3, 5]) | ||
|
||
# tests for length | ||
def test_length_empty_list(self): | ||
self.assertEqual(list_ops.length([]), 0) | ||
self.assertEqual(length([]), 0) | ||
|
||
def test_length_nonempty_list(self): | ||
self.assertEqual(list_ops.length([1, 2, 3, 4]), 4) | ||
def test_length_non_empty_list(self): | ||
self.assertEqual(length([1, 2, 3, 4]), 4) | ||
|
||
# tests for map | ||
def test_map_empty_list(self): | ||
self.assertEqual(list_ops.map(lambda x: x + 1, []), []) | ||
self.assertEqual(list_ops_map(lambda x: x + 1, []), []) | ||
|
||
def test_map_nonempty_list(self): | ||
self.assertEqual(list_ops.map(lambda x: x + 1, [1, 3, 5, 7]), | ||
[2, 4, 6, 8]) | ||
def test_map_non_empty_list(self): | ||
self.assertEqual(list_ops_map(lambda x: x + 1, [1, 3, 5, 7]), [2, 4, 6, 8]) | ||
|
||
# tests for foldl | ||
def test_foldl_empty_list(self): | ||
self.assertEqual(list_ops.foldl(operator.mul, [], 2), 2) | ||
self.assertEqual(foldl(lambda x, y: x * y, [], 2), 2) | ||
|
||
def test_foldl_nonempty_list_addition(self): | ||
self.assertEqual(list_ops.foldl(operator.add, [1, 2, 3, 4], 5), 15) | ||
def test_foldl_direction_independent_function_applied_to_non_empty_list(self): | ||
self.assertEqual(foldl(lambda x, y: x + y, [1, 2, 3, 4], 5), 15) | ||
|
||
def test_foldl_nonempty_list_floordiv(self): | ||
self.assertEqual(list_ops.foldl(operator.floordiv, [2, 5], 5), 0) | ||
def test_foldl_direction_dependent_function_applied_to_non_empty_list(self): | ||
self.assertEqual(foldl(lambda x, y: x // y, [2, 5], 5), 0) | ||
|
||
# tests for foldr | ||
def test_foldr_empty_list(self): | ||
self.assertEqual(list_ops.foldr(operator.mul, [], 2), 2) | ||
self.assertEqual(foldr(lambda x, y: x * y, [], 2), 2) | ||
|
||
def test_foldr_nonempty_list_addition(self): | ||
self.assertEqual(list_ops.foldr(operator.add, [1, 2, 3, 4], 5), 15) | ||
def test_foldr_direction_independent_function_applied_to_non_empty_list(self): | ||
self.assertEqual(foldr(lambda x, y: x + y, [1, 2, 3, 4], 5), 15) | ||
|
||
def test_foldr_nonempty_list_floordiv(self): | ||
self.assertEqual(list_ops.foldr(operator.floordiv, [2, 5], 5), 2) | ||
|
||
# additional test for foldr | ||
def test_foldr_add_str(self): | ||
self.assertEqual( | ||
list_ops.foldr(operator.add, | ||
["e", "x", "e", "r", "c", "i", "s", "m"], "!"), | ||
"exercism!") | ||
def test_foldr_direction_dependent_function_applied_to_non_empty_list(self): | ||
self.assertEqual(foldr(lambda x, y: x // y, [2, 5], 5), 2) | ||
|
||
# tests for reverse | ||
def test_reverse_empty_list(self): | ||
self.assertEqual(list_ops.reverse([]), []) | ||
self.assertEqual(reverse([]), []) | ||
|
||
def test_reverse_nonempty_list(self): | ||
self.assertEqual(list_ops.reverse([1, 3, 5, 7]), [7, 5, 3, 1]) | ||
def test_reverse_non_empty_list(self): | ||
self.assertEqual(reverse([1, 3, 5, 7]), [7, 5, 3, 1]) | ||
|
||
def test_reverse_list_of_lists_not_flattened(self): | ||
self.assertEqual(list_ops.reverse([[1, 2], [3], [], [4, 5, 6]]), | ||
[[4, 5, 6], [], [3], [1, 2]]) | ||
def test_reverse_list_of_lists_is_not_flattened(self): | ||
self.assertEqual( | ||
reverse([[1, 2], [3], [], [4, 5, 6]]), [[4, 5, 6], [], [3], [1, 2]] | ||
) | ||
|
||
# Additional tests for this track | ||
|
||
# additional test for reverse | ||
def test_reverse_mixed_types(self): | ||
def test_foldr_foldr_add_string(self): | ||
self.assertEqual( | ||
list_ops.reverse(["xyz", 4.0, "cat", 1]), [1, "cat", 4.0, "xyz"]) | ||
foldr(lambda x, y: x + y, ["e", "x", "e", "r", "c", "i", "s", "m"], "!"), | ||
"exercism!", | ||
) | ||
|
||
def test_reverse_reverse_mixed_types(self): | ||
self.assertEqual(reverse(["xyz", 4.0, "cat", 1]), [1, "cat", 4.0, "xyz"]) | ||
|
||
|
||
if __name__ == '__main__': | ||
if __name__ == "__main__": | ||
unittest.main() |