diff --git a/unit_tests/test_leafy_tree.js b/unit_tests/test_leafy_tree.js
index 2b85b323272dcc2d45d6a4db5808e5636162f5d2..b8b1e55659152b6c25a9b2fba3dc6d39bd92ca83 100644
--- a/unit_tests/test_leafy_tree.js
+++ b/unit_tests/test_leafy_tree.js
@@ -232,3 +232,108 @@ QUnit.test('assign heights to vertices in a many-element tree', (assert) => {
   assert.deepEqual(tree._root.children[1].children[1].children[0].height, 0);
   assert.deepEqual(tree._root.children[1].children[1].children[1].height, 0);
 });
+
+function summaries(vertex) {
+  return [vertex.height, ...vertex.summaryOfLeftmostLeaf, ...vertex.summary];
+}
+
+QUnit.test('Perform a single rotation to the left', (assert) => {
+  const tree = new LeafyTree(KEYED_LIGHTSWITCH_MONOID);
+  tree.set(0, FLIP);
+  tree.set(1, FLIP);
+  tree.set(2, FLIP);
+  tree.set(3, FLIP);
+  assert.deepEqual(summaries(tree._root), [2, [0, 0], FLIP, [0, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0]), [1, [0, 0], FLIP, [0, 1], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0]), [0, [0, 0], FLIP, [0, 0], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1]), [0, [1, 1], FLIP, [1, 1], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1]), [1, [2, 2], FLIP, [2, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[1].children[0]), [0, [2, 2], FLIP, [2, 2], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1]), [0, [3, 3], FLIP, [3, 3], FLIP]);
+});
+
+QUnit.test('Perform a double rotation to the left', (assert) => {
+  const tree = new LeafyTree(KEYED_LIGHTSWITCH_MONOID);
+  tree.set(0, FLIP);
+  tree.set(2, FLIP);
+  tree.set(3, FLIP);
+  tree.set(1, FLIP);
+  assert.deepEqual(summaries(tree._root), [2, [0, 0], FLIP, [0, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0]), [1, [0, 0], FLIP, [0, 1], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0]), [0, [0, 0], FLIP, [0, 0], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1]), [0, [1, 1], FLIP, [1, 1], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1]), [1, [2, 2], FLIP, [2, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[1].children[0]), [0, [2, 2], FLIP, [2, 2], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1]), [0, [3, 3], FLIP, [3, 3], FLIP]);
+});
+
+QUnit.test('Perform a single rotation to the right', (assert) => {
+  const tree = new LeafyTree(KEYED_LIGHTSWITCH_MONOID);
+  tree.set(3, FLIP);
+  tree.set(2, FLIP);
+  tree.set(1, FLIP);
+  tree.set(0, FLIP);
+  assert.deepEqual(summaries(tree._root), [2, [0, 0], FLIP, [0, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0]), [1, [0, 0], FLIP, [0, 1], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0]), [0, [0, 0], FLIP, [0, 0], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1]), [0, [1, 1], FLIP, [1, 1], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1]), [1, [2, 2], FLIP, [2, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[1].children[0]), [0, [2, 2], FLIP, [2, 2], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1]), [0, [3, 3], FLIP, [3, 3], FLIP]);
+});
+
+QUnit.test('Perform a double rotation to the right', (assert) => {
+  const tree = new LeafyTree(KEYED_LIGHTSWITCH_MONOID);
+  tree.set(3, FLIP);
+  tree.set(2, FLIP);
+  tree.set(0, FLIP);
+  tree.set(1, FLIP);
+  assert.deepEqual(summaries(tree._root), [2, [0, 0], FLIP, [0, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0]), [1, [0, 0], FLIP, [0, 1], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0]), [0, [0, 0], FLIP, [0, 0], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1]), [0, [1, 1], FLIP, [1, 1], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1]), [1, [2, 2], FLIP, [2, 3], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[1].children[0]), [0, [2, 2], FLIP, [2, 2], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1]), [0, [3, 3], FLIP, [3, 3], FLIP]);
+});
+
+QUnit.test('Perform a mix of single and double rotations', (assert) => {
+  const tree = new LeafyTree(KEYED_LIGHTSWITCH_MONOID);
+  tree.set(12, FLIP);
+  tree.set(4, FLIP);
+  tree.set(7, FLIP);
+  tree.set(1, FLIP);
+  tree.set(9, FLIP);
+  tree.set(5, FLIP);
+  tree.set(3, FLIP);
+  tree.set(0, FLIP);
+  tree.set(10, FLIP);
+  tree.set(8, FLIP);
+  tree.set(6, FLIP);
+  tree.set(2, FLIP);
+  tree.set(11, FLIP);
+  tree.delete(0);
+  assert.deepEqual(summaries(tree._root), [4, [1, 1], FLIP, [1, 12], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0]), [3, [1, 1], FLIP, [1, 7], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0]), [2, [1, 1], FLIP, [1, 4], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0].children[0]), [1, [1, 1], FLIP, [1, 2], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0].children[0].children[0]), [0, [1, 1], FLIP, [1, 1], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0].children[0].children[1]), [0, [2, 2], FLIP, [2, 2], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0].children[1]), [1, [3, 3], FLIP, [3, 4], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0].children[1].children[0]), [0, [3, 3], FLIP, [3, 3], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[0].children[1].children[1]), [0, [4, 4], FLIP, [4, 4], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1]), [2, [5, 5], FLIP, [5, 7], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1].children[0]), [0, [5, 5], FLIP, [5, 5], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1].children[1]), [1, [6, 6], FLIP, [6, 7], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1].children[1].children[0]), [0, [6, 6], FLIP, [6, 6], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[0].children[1].children[1].children[1]), [0, [7, 7], FLIP, [7, 7], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1]), [3, [8, 8], FLIP, [8, 12], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[0]), [1, [8, 8], FLIP, [8, 9], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[1].children[0].children[0]), [0, [8, 8], FLIP, [8, 8], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[0].children[1]), [0, [9, 9], FLIP, [9, 9], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1]), [2, [10, 10], FLIP, [10, 12], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1].children[0]), [0, [10, 10], FLIP, [10, 10], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1].children[1]), [1, [11, 11], FLIP, [11, 12], HOLD]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1].children[1].children[0]), [0, [11, 11], FLIP, [11, 11], FLIP]);
+  assert.deepEqual(summaries(tree._root.children[1].children[1].children[1].children[1]), [0, [12, 12], FLIP, [12, 12], FLIP]);
+});