1/*
2    tests/test_eval.cpp -- Usage of eval() and eval_file()
3
4    Copyright (c) 2016 Klemens D. Morgenstern
5
6    All rights reserved. Use of this source code is governed by a
7    BSD-style license that can be found in the LICENSE file.
8*/
9
10
11#include <pybind11/eval.h>
12#include "pybind11_tests.h"
13
14TEST_SUBMODULE(eval_, m) {
15    // test_evals
16
17    auto global = py::dict(py::module::import("__main__").attr("__dict__"));
18
19    m.def("test_eval_statements", [global]() {
20        auto local = py::dict();
21        local["call_test"] = py::cpp_function([&]() -> int {
22            return 42;
23        });
24
25        // Regular string literal
26        py::exec(
27            "message = 'Hello World!'\n"
28            "x = call_test()",
29            global, local
30        );
31
32        // Multi-line raw string literal
33        py::exec(R"(
34            if x == 42:
35                print(message)
36            else:
37                raise RuntimeError
38            )", global, local
39        );
40        auto x = local["x"].cast<int>();
41
42        return x == 42;
43    });
44
45    m.def("test_eval", [global]() {
46        auto local = py::dict();
47        local["x"] = py::int_(42);
48        auto x = py::eval("x", global, local);
49        return x.cast<int>() == 42;
50    });
51
52    m.def("test_eval_single_statement", []() {
53        auto local = py::dict();
54        local["call_test"] = py::cpp_function([&]() -> int {
55            return 42;
56        });
57
58        auto result = py::eval<py::eval_single_statement>("x = call_test()", py::dict(), local);
59        auto x = local["x"].cast<int>();
60        return result.is_none() && x == 42;
61    });
62
63    m.def("test_eval_file", [global](py::str filename) {
64        auto local = py::dict();
65        local["y"] = py::int_(43);
66
67        int val_out;
68        local["call_test2"] = py::cpp_function([&](int value) { val_out = value; });
69
70        auto result = py::eval_file(filename, global, local);
71        return val_out == 43 && result.is_none();
72    });
73
74    m.def("test_eval_failure", []() {
75        try {
76            py::eval("nonsense code ...");
77        } catch (py::error_already_set &) {
78            return true;
79        }
80        return false;
81    });
82
83    m.def("test_eval_file_failure", []() {
84        try {
85            py::eval_file("non-existing file");
86        } catch (std::exception &) {
87            return true;
88        }
89        return false;
90    });
91}
92