From 3b44daedf67f7b2800a9b7c7c4d45a35584c679d Mon Sep 17 00:00:00 2001 From: Dean Moldovan Date: Thu, 18 Aug 2016 16:55:26 +0200 Subject: [PATCH] Rewrite eval tests to allow for simple asserts Most of the test code is left in C++ since this is the intended use case for the eval functions. --- tests/test_eval.cpp | 132 +++++++++++++++++----------------------- tests/test_eval.py | 33 +++++----- tests/test_eval_call.py | 2 +- 3 files changed, 71 insertions(+), 96 deletions(-) diff --git a/tests/test_eval.cpp b/tests/test_eval.cpp index 21098ac75..6b16e7c7b 100644 --- a/tests/test_eval.cpp +++ b/tests/test_eval.cpp @@ -11,92 +11,70 @@ #include #include "pybind11_tests.h" -void example_eval() { - py::module main_module = py::module::import("__main__"); - py::object main_namespace = main_module.attr("__dict__"); +void init_ex_eval(py::module & m) { + auto global = py::dict(py::module::import("__main__").attr("__dict__")); - bool ok = false; + m.def("test_eval_statements", [global]() { + auto local = py::dict(); + local["call_test"] = py::cpp_function([&]() -> int { + return 42; + }); - main_module.def("call_test", [&]() -> int { - ok = true; - return 42; + auto result = py::eval( + "print('Hello World!');\n" + "x = call_test();", + global, local + ); + auto x = local["x"].cast(); + + return result == py::none() && x == 42; }); - cout << "eval_statements test" << endl; + m.def("test_eval", [global]() { + auto local = py::dict(); + local["x"] = py::int_(42); + auto x = py::eval("x", global, local); + return x.cast() == 42; + }); - auto result = py::eval( - "print('Hello World!');\n" - "x = call_test();", main_namespace); + m.def("test_eval_single_statement", []() { + auto local = py::dict(); + local["call_test"] = py::cpp_function([&]() -> int { + return 42; + }); - if (ok && result == py::none()) - cout << "eval_statements passed" << endl; - else - cout << "eval_statements failed" << endl; + auto result = py::eval("x = call_test()", py::dict(), local); + auto x = local["x"].cast(); + return result == py::none() && x == 42; + }); - cout << "eval test" << endl; + m.def("test_eval_file", [global](py::str filename) { + auto local = py::dict(); + local["y"] = py::int_(43); - py::object val = py::eval("x", main_namespace); + int val_out; + local["call_test2"] = py::cpp_function([&](int value) { val_out = value; }); - if (val.cast() == 42) - cout << "eval passed" << endl; - else - cout << "eval failed" << endl; + auto result = py::eval_file(filename, global, local); + return val_out == 43 && result == py::none(); + }); - ok = false; - cout << "eval_single_statement test" << endl; + m.def("test_eval_failure", []() { + try { + py::eval("nonsense code ..."); + } catch (py::error_already_set &) { + PyErr_Clear(); + return true; + } + return false; + }); - py::eval( - "y = call_test();", main_namespace); - - if (ok) - cout << "eval_single_statement passed" << endl; - else - cout << "eval_single_statement failed" << endl; - - cout << "eval_file test" << endl; - - int val_out; - main_module.def("call_test2", [&](int value) {val_out = value;}); - - try { - result = py::eval_file("test_eval_call.py", main_namespace); - } catch (...) { - result = py::eval_file("tests/test_eval_call.py", main_namespace); - } - - if (val_out == 42 && result == py::none()) - cout << "eval_file passed" << endl; - else - cout << "eval_file failed" << endl; - - ok = false; - cout << "eval failure test" << endl; - try { - py::eval("nonsense code ..."); - } catch (py::error_already_set &) { - PyErr_Clear(); - ok = true; - } - - if (ok) - cout << "eval failure test passed" << endl; - else - cout << "eval failure test failed" << endl; - - ok = false; - cout << "eval_file failure test" << endl; - try { - py::eval_file("nonexisting file"); - } catch (std::exception &) { - ok = true; - } - - if (ok) - cout << "eval_file failure test passed" << endl; - else - cout << "eval_file failure test failed" << endl; -} - -void init_ex_eval(py::module & m) { - m.def("example_eval", &example_eval); + m.def("test_eval_file_failure", []() { + try { + py::eval_file("non-existing file"); + } catch (std::exception &) { + return true; + } + return false; + }); } diff --git a/tests/test_eval.py b/tests/test_eval.py index 2d7611c80..8715dbadb 100644 --- a/tests/test_eval.py +++ b/tests/test_eval.py @@ -1,22 +1,19 @@ +import os -def test_eval(capture): - from pybind11_tests import example_eval +def test_evals(capture): + from pybind11_tests import (test_eval_statements, test_eval, test_eval_single_statement, + test_eval_file, test_eval_failure, test_eval_file_failure) with capture: - example_eval() - assert capture == """ - eval_statements test - Hello World! - eval_statements passed - eval test - eval passed - eval_single_statement test - eval_single_statement passed - eval_file test - eval_file passed - eval failure test - eval failure test passed - eval_file failure test - eval_file failure test passed - """ + assert test_eval_statements() + assert capture == "Hello World!" + + assert test_eval() + assert test_eval_single_statement() + + filename = os.path.join(os.path.dirname(__file__), "test_eval_call.py") + assert test_eval_file(filename) + + assert test_eval_failure() + assert test_eval_file_failure() diff --git a/tests/test_eval_call.py b/tests/test_eval_call.py index b8a7603e9..a3349e281 100644 --- a/tests/test_eval_call.py +++ b/tests/test_eval_call.py @@ -1,4 +1,4 @@ # This file is called from 'test_eval.py' -if 'call_test2' in globals(): +if 'call_test2' in locals(): call_test2(y)