def test_merge_operations_merges_connected_component():
    q = cirq.LineQubit.range(3)
    c_orig = cirq.Circuit(cirq.Moment(cirq.H.on_each(*q)), cirq.CNOT(q[0], q[2]), cirq.CNOT(*q[0:2]), cirq.H(q[0]), cirq.CZ(*q[:2]), cirq.X(q[0]), cirq.Y(q[1]), cirq.CNOT(*q[0:2]), cirq.CNOT(*q[1:3]), cirq.X(q[0]), cirq.Y(q[1]), cirq.CNOT(*q[:2]), strategy=cirq.InsertStrategy.NEW)
    cirq.testing.assert_has_diagram(c_orig, '\n0: ───H───@───@───H───@───X───────@───────X───────@───\n          │   │       │           │               │\n1: ───H───┼───X───────@───────Y───X───@───────Y───X───\n          │                           │\n2: ───H───X───────────────────────────X───────────────\n')

    def merge_func(op1, op2):
        'Artificial example where a CZ will absorb any merge-able operation.'
        for op in [op1, op2]:
            if (op.gate == cirq.CZ):
                return op
        return None
    c_new = cirq.merge_operations(c_orig, merge_func)
    cirq.testing.assert_has_diagram(c_new, '\n0: ───H───@───────────@───────────────────────────@───\n          │           │                           │\n1: ───────┼───────────@───────────────@───────Y───X───\n          │                           │\n2: ───H───X───────────────────────────X───────────────')
def test_merge_operations_merges_connected_component():
    q = cirq.LineQubit.range(3)
    c_orig = cirq.Circuit(cirq.Moment(cirq.H.on_each(*q)), cirq.CNOT(q[0], q[2]), cirq.CNOT(*q[0:2]), cirq.H(q[0]), cirq.CZ(*q[:2]), cirq.X(q[0]), cirq.Y(q[1]), cirq.CNOT(*q[0:2]), cirq.CNOT(*q[1:3]), cirq.X(q[0]), cirq.Y(q[1]), cirq.CNOT(*q[:2]), strategy=cirq.InsertStrategy.NEW)
    cirq.testing.assert_has_diagram(c_orig, '\n0: ───H───@───@───H───@───X───────@───────X───────@───\n          │   │       │           │               │\n1: ───H───┼───X───────@───────Y───X───@───────Y───X───\n          │                           │\n2: ───H───X───────────────────────────X───────────────\n')

    def merge_func(op1, op2):
        'Artificial example where a CZ will absorb any merge-able operation.'
        for op in [op1, op2]:
            if (op.gate == cirq.CZ):
                return op
        return None
    c_new = cirq.merge_operations(c_orig, merge_func)
    cirq.testing.assert_has_diagram(c_new, '\n0: ───H───@───────────@───────────────────────────@───\n          │           │                           │\n1: ───────┼───────────@───────────────@───────Y───X───\n          │                           │\n2: ───H───X───────────────────────────X───────────────')