2023-07-15 15:27:31 -07:00
|
|
|
# These tests are auto-generated with test data from:
|
|
|
|
|
# https://github.com/exercism/problem-specifications/tree/main/exercises/zipper/canonical-data.json
|
2023-07-21 16:54:40 -07:00
|
|
|
# File last updated on 2023-07-19
|
2023-07-15 15:27:31 -07:00
|
|
|
|
2017-10-21 11:46:02 -05:00
|
|
|
import unittest
|
|
|
|
|
|
2021-01-31 16:49:12 -05:00
|
|
|
from zipper import (
|
|
|
|
|
Zipper,
|
|
|
|
|
)
|
2017-10-21 11:46:02 -05:00
|
|
|
|
2020-02-20 18:43:59 +00:00
|
|
|
|
2018-02-20 05:09:33 +08:00
|
|
|
class ZipperTest(unittest.TestCase):
|
2020-02-20 18:43:59 +00:00
|
|
|
def test_data_is_retained(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
2017-10-21 11:46:02 -05:00
|
|
|
}
|
|
|
|
|
|
2020-02-20 18:43:59 +00:00
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
2017-10-21 11:46:02 -05:00
|
|
|
|
2020-02-20 18:43:59 +00:00
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.to_tree()
|
|
|
|
|
self.assertEqual(result, expected)
|
2017-10-21 11:46:02 -05:00
|
|
|
|
2020-02-20 18:43:59 +00:00
|
|
|
def test_left_right_and_value(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
2017-10-21 11:46:02 -05:00
|
|
|
|
2020-02-20 18:43:59 +00:00
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().right().value()
|
|
|
|
|
self.assertEqual(result, 3)
|
2017-10-21 11:46:02 -05:00
|
|
|
|
|
|
|
|
def test_dead_end(self):
|
2020-02-20 18:43:59 +00:00
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().left()
|
|
|
|
|
self.assertIsNone(result)
|
2017-10-21 11:46:02 -05:00
|
|
|
|
|
|
|
|
def test_tree_from_deep_focus(self):
|
2020-02-20 18:43:59 +00:00
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().right().to_tree()
|
|
|
|
|
self.assertEqual(result, expected)
|
|
|
|
|
|
|
|
|
|
def test_traversing_up_from_top(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.up()
|
|
|
|
|
self.assertIsNone(result)
|
|
|
|
|
|
|
|
|
|
def test_left_right_and_up(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().up().right().up().left().right().value()
|
|
|
|
|
self.assertEqual(result, 3)
|
2017-10-21 11:46:02 -05:00
|
|
|
|
2022-02-09 18:35:20 -08:00
|
|
|
def test_test_ability_to_descend_multiple_levels_and_return(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().right().up().up().value()
|
|
|
|
|
self.assertEqual(result, 1)
|
|
|
|
|
|
2017-10-21 11:46:02 -05:00
|
|
|
def test_set_value(self):
|
2020-02-20 18:43:59 +00:00
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 5,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().set_value(5).to_tree()
|
|
|
|
|
self.assertEqual(result, expected)
|
|
|
|
|
|
|
|
|
|
def test_set_value_after_traversing_up(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 5,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().right().up().set_value(5).to_tree()
|
|
|
|
|
self.assertEqual(result, expected)
|
|
|
|
|
|
|
|
|
|
def test_set_left_with_leaf(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": {"value": 5, "left": None, "right": None},
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = (
|
|
|
|
|
zipper.left().set_left({"value": 5, "left": None, "right": None}).to_tree()
|
|
|
|
|
)
|
|
|
|
|
self.assertEqual(result, expected)
|
|
|
|
|
|
|
|
|
|
def test_set_right_with_null(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {"value": 2, "left": None, "right": None},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().set_right(None).to_tree()
|
|
|
|
|
self.assertEqual(result, expected)
|
|
|
|
|
|
|
|
|
|
def test_set_right_with_subtree(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {
|
|
|
|
|
"value": 6,
|
|
|
|
|
"left": {"value": 7, "left": None, "right": None},
|
|
|
|
|
"right": {"value": 8, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.set_right(
|
|
|
|
|
{
|
|
|
|
|
"value": 6,
|
|
|
|
|
"left": {"value": 7, "left": None, "right": None},
|
|
|
|
|
"right": {"value": 8, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
).to_tree()
|
|
|
|
|
self.assertEqual(result, expected)
|
|
|
|
|
|
|
|
|
|
def test_set_value_on_deep_focus(self):
|
|
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 5, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipper = Zipper.from_tree(initial)
|
|
|
|
|
result = zipper.left().right().set_value(5).to_tree()
|
|
|
|
|
self.assertEqual(result, expected)
|
2017-10-21 11:46:02 -05:00
|
|
|
|
|
|
|
|
def test_different_paths_to_same_zipper(self):
|
2020-02-20 18:43:59 +00:00
|
|
|
initial = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
result = Zipper.from_tree(initial).left().up().right().to_tree()
|
|
|
|
|
|
|
|
|
|
final = {
|
|
|
|
|
"value": 1,
|
|
|
|
|
"left": {
|
|
|
|
|
"value": 2,
|
|
|
|
|
"left": None,
|
|
|
|
|
"right": {"value": 3, "left": None, "right": None},
|
|
|
|
|
},
|
|
|
|
|
"right": {"value": 4, "left": None, "right": None},
|
|
|
|
|
}
|
|
|
|
|
expected = Zipper.from_tree(final).right().to_tree()
|
|
|
|
|
|
|
|
|
|
self.assertEqual(result, expected)
|