From 91b6c482fbef1369410129a59f2afa44f9004961 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 10 Dec 2024 12:50:55 -0800 Subject: [PATCH] Split up tests, add a few more --- pip/tests/test_qsharp.py | 127 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 10 deletions(-) diff --git a/pip/tests/test_qsharp.py b/pip/tests/test_qsharp.py index 2c025bfe5f..86caac8ceb 100644 --- a/pip/tests/test_qsharp.py +++ b/pip/tests/test_qsharp.py @@ -3,6 +3,7 @@ import pytest import qsharp +import qsharp.env import qsharp.utils from contextlib import redirect_stdout import io @@ -380,10 +381,10 @@ def test_target_profile_from_str_match_enum_values() -> None: def test_callables_exposed_into_env() -> None: qsharp.init() qsharp.eval("function Four() : Int { 4 }") - assert qsharp.env.Four() == 4 + assert qsharp.env.Four() == 4, "callable should be available" qsharp.eval("function Add(a : Int, b : Int) : Int { a + b }") - assert qsharp.env.Four() == 4 - assert qsharp.env.Add(2, 3) == 5 + assert qsharp.env.Four() == 4, "first callable should still be available" + assert qsharp.env.Add(2, 3) == 5, "second callable should be available" # After init, the callables should be cleared and no longer available qsharp.init() with pytest.raises(AttributeError): @@ -394,15 +395,21 @@ def test_callable_exposed_into_env_complex_types() -> None: qsharp.eval( "function Complicated(a : Int, b : (Double, BigInt)) : ((Double, BigInt), Int) { (b, a) }" ) - assert qsharp.env.Complicated(2, (3.0, 4000000000000000000)) == ( - (3.0, 4000000000000000000), + assert qsharp.env.Complicated(2, (3.0, 4000000000000000000000)) == ( + (3.0, 4000000000000000000000), 2, - ) + ), "callables that take complex types should marshall them correctly" + + +def test_callable_exposed_into_env_with_array() -> None: + qsharp.init() qsharp.eval("function Smallest(a : Int[]) : Int { Std.Math.Min(a)}") - assert qsharp.env.Smallest([1, 2, 3, 0, 4, 5]) == 0 + assert ( + qsharp.env.Smallest([1, 2, 3, 0, 4, 5]) == 0 + ), "callable that takes array should work" -def test_callable_exposed_into_env_fails_incorrect_types() -> None: +def test_callable_with_int_exposed_into_env_fails_incorrect_types() -> None: qsharp.init() qsharp.eval("function Identity(a : Int) : Int { a }") assert qsharp.env.Identity(4) == 4 @@ -410,6 +417,91 @@ def test_callable_exposed_into_env_fails_incorrect_types() -> None: qsharp.env.Identity("4") with pytest.raises(TypeError): qsharp.env.Identity(4.0) + with pytest.raises(OverflowError): + qsharp.env.Identity(4000000000000000000000) + with pytest.raises(TypeError): + qsharp.env.Identity([4]) + + +def test_callable_with_double_exposed_into_env_fails_incorrect_types() -> None: + qsharp.init() + qsharp.eval("function Identity(a : Double) : Double { a }") + assert qsharp.env.Identity(4.0) == 4.0 + assert qsharp.env.Identity(4) == 4.0 + with pytest.raises(TypeError): + qsharp.env.Identity("4") + with pytest.raises(TypeError): + qsharp.env.Identity([4]) + + +def test_callable_with_bigint_exposed_into_env_fails_incorrect_types() -> None: + qsharp.init() + qsharp.eval("function Identity(a : BigInt) : BigInt { a }") + assert qsharp.env.Identity(4000000000000000000000) == 4000000000000000000000 + with pytest.raises(TypeError): + qsharp.env.Identity("4") + with pytest.raises(TypeError): + qsharp.env.Identity(4.0) + + +def test_callable_with_string_exposed_into_env_fails_incorrect_types() -> None: + qsharp.init() + qsharp.eval("function Identity(a : String) : String { a }") + assert qsharp.env.Identity("4") == "4" + with pytest.raises(TypeError): + qsharp.env.Identity(4) + with pytest.raises(TypeError): + qsharp.env.Identity(4.0) + with pytest.raises(TypeError): + qsharp.env.Identity([4]) + + +def test_callable_with_bool_exposed_into_env_fails_incorrect_types() -> None: + qsharp.init() + qsharp.eval("function Identity(a : Bool) : Bool { a }") + assert qsharp.env.Identity(True) == True + with pytest.raises(TypeError): + qsharp.env.Identity("4") + with pytest.raises(TypeError): + qsharp.env.Identity(4) + with pytest.raises(TypeError): + qsharp.env.Identity(4.0) + with pytest.raises(TypeError): + qsharp.env.Identity([4]) + + +def test_callable_with_array_exposed_into_env_fails_incorrect_types() -> None: + qsharp.init() + qsharp.eval("function Identity(a : Int[]) : Int[] { a }") + assert qsharp.env.Identity([4, 5, 6]) == [4, 5, 6] + assert qsharp.env.Identity([]) == [] + assert qsharp.env.Identity((4, 5, 6)) == [4, 5, 6] + with pytest.raises(TypeError): + qsharp.env.Identity(4) + with pytest.raises(TypeError): + qsharp.env.Identity("4") + with pytest.raises(TypeError): + qsharp.env.Identity(4.0) + with pytest.raises(TypeError): + qsharp.env.Identity([1, 2, 3.0]) + + +def test_callable_with_tuple_exposed_into_env_fails_incorrect_types() -> None: + qsharp.init() + qsharp.eval("function Identity(a : (Int, Double)) : (Int, Double) { a }") + assert qsharp.env.Identity((4, 5.0)) == (4, 5.0) + assert qsharp.env.Identity((4, 5)) == (4, 5.0) + assert qsharp.env.Identity([4, 5.0]) == (4, 5.0) + with pytest.raises(qsharp.QSharpError): + qsharp.env.Identity((4, 5, 6)) + with pytest.raises(TypeError): + qsharp.env.Identity(4) + with pytest.raises(TypeError): + qsharp.env.Identity("4") + with pytest.raises(TypeError): + qsharp.env.Identity(4.0) + with pytest.raises(TypeError): + qsharp.env.Identity([4.0, 5]) def test_callables_in_namespaces_exposed_into_env_submodules_and_removed_on_reinit() -> ( @@ -419,8 +511,7 @@ def test_callables_in_namespaces_exposed_into_env_submodules_and_removed_on_rein # callables should be created with their namespaces qsharp.eval("namespace Test { function Four() : Int { 4 } }") qsharp.eval("function Identity(a : Int) : Int { a }") - assert qsharp.env.Test.Four() == 4 - # should be able to import callables + # should be able to import callables from env and namespace submodule from qsharp.env import Identity from qsharp.env.Test import Four @@ -440,17 +531,33 @@ def test_callables_with_unsupported_types_raise_errors_on_call() -> None: qsharp.eval("function Unsupported(a : Int, q : Qubit) : Unit { }") with pytest.raises(qsharp.QSharpError, match="unsupported input type: `Qubit`"): qsharp.env.Unsupported() + + +def test_callables_with_unsupported_types_in_tuples_raise_errors_on_call() -> None: + qsharp.init() qsharp.eval("function Unsupported(q : (Int, Qubit)[]) : Unit { }") with pytest.raises(qsharp.QSharpError, match="unsupported input type: `Qubit`"): qsharp.env.Unsupported() + + +def test_callables_with_unsupported_return_types_raise_errors_on_call() -> None: + qsharp.init() qsharp.eval('function Unsupported() : Qubit { fail "won\'t be called" }') with pytest.raises(qsharp.QSharpError, match="unsupported output type: `Qubit`"): qsharp.env.Unsupported() + + +def test_callables_with_unsupported_udt_types_raise_errors_on_call() -> None: + qsharp.init() qsharp.eval("function Unsupported(a : Std.Math.Complex) : Unit { }") with pytest.raises( qsharp.QSharpError, match='unsupported input type: `UDT<"Complex":' ): qsharp.env.Unsupported() + + +def test_callable_with_unsupported_udt_return_types_raise_errors_on_call() -> None: + qsharp.init() qsharp.eval('function Unsupported() : Std.Math.Complex { fail "won\'t be called" }') with pytest.raises( qsharp.QSharpError, match='unsupported output type: `UDT<"Complex":'