Repository: quantumlib/Cirq

Issue:
Test cirq.testing.assert_equivalent_repr on every class with a __repr__ exposed by cirq
Comes after https://github.com/quantumlib/Cirq/pull/997 (which defines the `cirq.testing.assert_equivalent_repr` method)

Basically the goal here is, for each place you can find `def __repr__(` in the project, there should be an associated test that calls `cirq.testing.assert_equivalent_repr(a, b, c) ` on a few test values.


Discussion:
is this still a thing? i could give it a go if so.
@funston It is. Go for it!
Assign this to me

Resolving patch:
diff --git a/cirq/schedules/scheduled_operation.py b/cirq/schedules/scheduled_operation.py
--- a/cirq/schedules/scheduled_operation.py
+++ b/cirq/schedules/scheduled_operation.py
@@ -66,5 +66,5 @@ def __str__(self):
             self.operation, self.time, self.time + self.duration)
 
     def __repr__(self):
-        return 'ScheduledOperation({}, {}, {})'.format(
-            repr(self.time), repr(self.duration), repr(self.operation))
+        return 'cirq.ScheduledOperation({!r}, {!r}, {!r})'.format(
+            self.time, self.duration, self.operation)
diff --git a/cirq/sim/wave_function_simulator.py b/cirq/sim/wave_function_simulator.py
--- a/cirq/sim/wave_function_simulator.py
+++ b/cirq/sim/wave_function_simulator.py
@@ -251,8 +251,8 @@ def _qid_shape_(self):
 
     def __repr__(self):
         return (
-            'cirq.WaveFunctionSimulatorState(state_vector={!r}, qubit_map={!r})'
-                .format(self.state_vector, self.qubit_map))
+            "cirq.WaveFunctionSimulatorState(state_vector=np.{!r}, qubit_map="
+            "{!r})".format(self.state_vector, self.qubit_map))
 
     def _value_equality_values_(self):
         return (self.state_vector.tolist(), self.qubit_map)


Test patch:
diff --git a/cirq/devices/grid_qubit_test.py b/cirq/devices/grid_qubit_test.py
--- a/cirq/devices/grid_qubit_test.py
+++ b/cirq/devices/grid_qubit_test.py
@@ -47,6 +47,11 @@ def test_square():
     ]
 
 
+def test_repr():
+    a = cirq.GridQubit(0, 1)
+    cirq.testing.assert_equivalent_repr(a)
+
+
 def test_rec():
     assert cirq.GridQubit.rect(
         1, 2, top=5, left=6) == [cirq.GridQubit(5, 6),
diff --git a/cirq/ops/fourier_transform_test.py b/cirq/ops/fourier_transform_test.py
--- a/cirq/ops/fourier_transform_test.py
+++ b/cirq/ops/fourier_transform_test.py
@@ -47,6 +47,16 @@ def test_str():
     assert str(cirq.PhaseGradientGate(num_qubits=2, exponent=1)) == 'Grad[2]'
 
 
+def test_phase_gradient_gate_repr():
+    a = cirq.PhaseGradientGate(num_qubits=2, exponent=0.5)
+    cirq.testing.assert_equivalent_repr(a)
+
+
+def test_quantum_fourier_transform_gate_repr():
+    b = cirq.QuantumFourierTransformGate(num_qubits=2, without_reverse=False)
+    cirq.testing.assert_equivalent_repr(b)
+
+
 def test_pow():
     a = cirq.PhaseGradientGate(num_qubits=2, exponent=0.5)
     assert a**0.5 == cirq.PhaseGradientGate(num_qubits=2, exponent=0.25)
diff --git a/cirq/ops/fsim_gate_test.py b/cirq/ops/fsim_gate_test.py
--- a/cirq/ops/fsim_gate_test.py
+++ b/cirq/ops/fsim_gate_test.py
@@ -236,6 +236,11 @@ def test_fsim_iswap_cphase(theta, phi):
     assert np.allclose(cirq.unitary(iswap_cphase), cirq.unitary(fsim))
 
 
+def test_repr():
+    f = cirq.FSimGate(sympy.Symbol('a'), sympy.Symbol('b'))
+    cirq.testing.assert_equivalent_repr(f)
+
+
 def test_fsim_json_dict():
     assert cirq.FSimGate(theta=0.123, phi=0.456)._json_dict_() == {
         'cirq_type': 'FSimGate',
diff --git a/cirq/ops/global_phase_op_test.py b/cirq/ops/global_phase_op_test.py
--- a/cirq/ops/global_phase_op_test.py
+++ b/cirq/ops/global_phase_op_test.py
@@ -44,6 +44,11 @@ def test_str():
     assert str(cirq.GlobalPhaseOperation(1j)) == '1j'
 
 
+def test_repr():
+    op = cirq.GlobalPhaseOperation(1j)
+    cirq.testing.assert_equivalent_repr(op)
+
+
 def test_diagram():
     a, b = cirq.LineQubit.range(2)
     x, y = cirq.LineQubit.range(10, 12)
diff --git a/cirq/ops/matrix_gates_test.py b/cirq/ops/matrix_gates_test.py
--- a/cirq/ops/matrix_gates_test.py
+++ b/cirq/ops/matrix_gates_test.py
@@ -232,3 +232,15 @@ def test_two_qubit_consistent():
     u = cirq.testing.random_unitary(4)
     g = cirq.TwoQubitMatrixGate(u)
     cirq.testing.assert_implements_consistent_protocols(g)
+
+
+def test_two_qubit_matrix_gate():
+    u = cirq.testing.random_unitary(4)
+    g = cirq.TwoQubitMatrixGate(u)
+    cirq.testing.assert_equivalent_repr(g)
+
+
+def test_single_qubit_matrix_gate():
+    u = cirq.testing.random_unitary(2)
+    g = cirq.SingleQubitMatrixGate(u)
+    cirq.testing.assert_equivalent_repr(g)
diff --git a/cirq/ops/moment_test.py b/cirq/ops/moment_test.py
--- a/cirq/ops/moment_test.py
+++ b/cirq/ops/moment_test.py
@@ -227,6 +227,13 @@ def test_bool():
     assert Moment([cirq.X(a)])
 
 
+def test_repr():
+    a = cirq.NamedQubit('a')
+    b = cirq.NamedQubit('b')
+    original = Moment([cirq.CZ(a, b)])
+    cirq.testing.assert_equivalent_repr(original)
+
+
 def test_json_dict():
     a = cirq.NamedQubit('a')
     b = cirq.NamedQubit('b')
diff --git a/cirq/ops/pauli_interaction_gate_test.py b/cirq/ops/pauli_interaction_gate_test.py
--- a/cirq/ops/pauli_interaction_gate_test.py
+++ b/cirq/ops/pauli_interaction_gate_test.py
@@ -81,6 +81,11 @@ def test_exponent():
         ]))
 
 
+def test_repr():
+    cnot = cirq.PauliInteractionGate(cirq.Z, False, cirq.X, False)
+    cirq.testing.assert_equivalent_repr(cnot)
+
+
 def test_decomposes_despite_symbol():
     q0, q1 = cirq.NamedQubit('q0'), cirq.NamedQubit('q1')
     gate = cirq.PauliInteractionGate(cirq.Z, False, cirq.X, False,
diff --git a/cirq/ops/phased_iswap_gate_test.py b/cirq/ops/phased_iswap_gate_test.py
--- a/cirq/ops/phased_iswap_gate_test.py
+++ b/cirq/ops/phased_iswap_gate_test.py
@@ -37,6 +37,13 @@ def test_phased_iswap_equality():
                                     exponent=0.4) == cirq.ISWAP**0.4)
 
 
+def test_repr():
+    p = -0.25
+    t = 0.75
+    gate = cirq.PhasedISwapPowGate(phase_exponent=p, exponent=t)
+    cirq.testing.assert_equivalent_repr(gate)
+
+
 def test_phased_iswap_unitary():
     p = 0.3
     t = 0.4
diff --git a/cirq/schedules/scheduled_operation_test.py b/cirq/schedules/scheduled_operation_test.py
--- a/cirq/schedules/scheduled_operation_test.py
+++ b/cirq/schedules/scheduled_operation_test.py
@@ -37,6 +37,13 @@ def test_init_timedelta():
     assert r.operation == cirq.H(cirq.NamedQubit('a'))
 
 
+def test_repr():
+    a = ScheduledOperation(time=Timestamp(picos=5),
+                           duration=timedelta(microseconds=7),
+                           operation=cirq.H(cirq.NamedQubit('a')))
+    cirq.testing.assert_equivalent_repr(a)
+
+
 def test_eq():
     q0 = cirq.NamedQubit('q0')
 
diff --git a/cirq/sim/wave_function_simulator_test.py b/cirq/sim/wave_function_simulator_test.py
--- a/cirq/sim/wave_function_simulator_test.py
+++ b/cirq/sim/wave_function_simulator_test.py
@@ -25,12 +25,18 @@ def test_wave_function_trial_result_repr():
         measurements={'m': np.array([[1]])},
         final_simulator_state=final_simulator_state)
     assert repr(trial_result) == (
-               "cirq.WaveFunctionTrialResult("
-               "params=cirq.ParamResolver({'s': 1}), "
-               "measurements={'m': array([[1]])}, "
-               "final_simulator_state=cirq.WaveFunctionSimulatorState("
-                   "state_vector=array([0, 1]), "
-                   "qubit_map={cirq.NamedQubit('a'): 0}))")
+        "cirq.WaveFunctionTrialResult("
+        "params=cirq.ParamResolver({'s': 1}), "
+        "measurements={'m': array([[1]])}, "
+        "final_simulator_state=cirq.WaveFunctionSimulatorState("
+        "state_vector=np.array([0, 1]), "
+        "qubit_map={cirq.NamedQubit('a'): 0}))")
+
+
+def test_wave_function_simulator_state_repr():
+    final_simulator_state = cirq.WaveFunctionSimulatorState(
+        qubit_map={cirq.NamedQubit('a'): 0}, state_vector=np.array([0, 1]))
+    cirq.testing.assert_equivalent_repr(final_simulator_state)
 
 
 def test_wave_function_trial_result_equality():
diff --git a/cirq/value/duration_test.py b/cirq/value/duration_test.py
--- a/cirq/value/duration_test.py
+++ b/cirq/value/duration_test.py
@@ -53,6 +53,15 @@ def test_total_nanoseconds():
     assert Duration(nanos=5).total_nanos() == 5
 
 
+def test_repr():
+    a = Duration(picos=1000, nanos=1000)
+    cirq.testing.assert_equivalent_repr(a)
+    b = Duration(picos=5000)
+    cirq.testing.assert_equivalent_repr(b)
+    c = Duration(nanos=1.0)
+    cirq.testing.assert_equivalent_repr(c)
+
+
 def test_eq():
     eq = cirq.testing.EqualsTester()
     eq.add_equality_group(Duration(), Duration(picos=0), Duration(nanos=0.0))
diff --git a/cirq/value/timestamp_test.py b/cirq/value/timestamp_test.py
--- a/cirq/value/timestamp_test.py
+++ b/cirq/value/timestamp_test.py
@@ -32,6 +32,15 @@ def test_init():
     assert isinstance(Timestamp(nanos=1.0).raw_picos(), float)
 
 
+def test_repr():
+    a = Timestamp(picos=1000, nanos=1000)
+    cirq.testing.assert_equivalent_repr(a)
+    b = Timestamp(nanos=5.0)
+    cirq.testing.assert_equivalent_repr(b)
+    c = Timestamp(picos=-100)
+    cirq.testing.assert_equivalent_repr(c)
+
+
 def test_eq():
     eq = cirq.testing.EqualsTester()
     eq.add_equality_group(Timestamp(),