# HG changeset patch # User David Demelier # Date 1503306529 -7200 # Node ID 18ec7f4fc3de7c56979b0afa6aee1e5257f42a3c # Parent beef249c796c49dd4b65aacff417f5e290256f61 Js: new style, closes #685 diff -r beef249c796c -r 18ec7f4fc3de CMakeLists.txt --- a/CMakeLists.txt Sat Jul 01 07:35:13 2017 +0200 +++ b/CMakeLists.txt Mon Aug 21 11:08:49 2017 +0200 @@ -33,6 +33,7 @@ # Doxygen target. find_package(Doxygen) +find_package(Boost REQUIRED COMPONENTS unit_test_framework) if (DOXYGEN_FOUND) configure_file( diff -r beef249c796c -r 18ec7f4fc3de cmake/CodeDefineModule.cmake --- a/cmake/CodeDefineModule.cmake Sat Jul 01 07:35:13 2017 +0200 +++ b/cmake/CodeDefineModule.cmake Mon Aug 21 11:08:49 2017 +0200 @@ -63,14 +63,24 @@ RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR} RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR} ) - target_compile_definitions(test-${MOD_NAME} PRIVATE ${MOD_FLAGS}) + target_compile_definitions( + test-${MOD_NAME} + PRIVATE + BOOST_TEST_DYN_LINK + ${MOD_FLAGS} + ) target_include_directories( test-${MOD_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${MOD_INCLUDES} ) - target_link_libraries(test-${MOD_NAME} gtest ${MOD_LIBRARIES}) + target_link_libraries( + test-${MOD_NAME} + Boost::unit_test_framework + gtest + ${MOD_LIBRARIES} + ) # Register the test. add_test( diff -r beef249c796c -r 18ec7f4fc3de modules/js/duktape.hpp --- a/modules/js/duktape.hpp Sat Jul 01 07:35:13 2017 +0200 +++ b/modules/js/duktape.hpp Mon Aug 21 11:08:49 2017 +0200 @@ -36,7 +36,6 @@ #include /** - * \class StackAssert * \brief Stack sanity checker. * * Instanciate this class where you need to manipulate the Duktape stack outside @@ -47,12 +46,12 @@ * * To use it, just declare an lvalue at the beginning of your function. */ -class StackAssert { +class dukx_stack_guard { #if !defined(NDEBUG) private: - duk_context *m_context; - unsigned m_expected; - unsigned m_begin; + duk_context* context_; + unsigned expected_; + unsigned begin_; #endif public: @@ -64,11 +63,11 @@ * \param ctx the context * \param expected the size expected relative to the already existing values */ - inline StackAssert(duk_context *ctx, unsigned expected = 0) noexcept + inline dukx_stack_guard(duk_context* ctx, unsigned expected = 0) noexcept #if !defined(NDEBUG) - : m_context(ctx) - , m_expected(expected) - , m_begin(static_cast(duk_get_top(ctx))) + : context_(ctx) + , expected_(expected) + , begin_(static_cast(duk_get_top(ctx))) #endif { #if defined(NDEBUG) @@ -82,16 +81,16 @@ * * No-op if NDEBUG is set. */ - inline ~StackAssert() noexcept + inline ~dukx_stack_guard() noexcept { #if !defined(NDEBUG) - if (static_cast(duk_get_top(m_context)) - m_begin != m_expected) { - std::fprintf(stderr, "Corrupt stack detection in StackAssert:\n"); - std::fprintf(stderr, " Size at start: %u\n", m_begin); - std::fprintf(stderr, " Size at end: %d\n", duk_get_top(m_context)); - std::fprintf(stderr, " Expected (user): %u\n", m_expected); - std::fprintf(stderr, " Expected (adjusted): %u\n", m_expected + m_begin); - std::fprintf(stderr, " Number of stale values: %u\n", duk_get_top(m_context) - m_begin - m_expected); + if (static_cast(duk_get_top(context_)) - begin_ != expected_) { + std::fprintf(stderr, "Corrupt stack detection in dukx_stack_guard:\n"); + std::fprintf(stderr, " Size at start: %u\n", begin_); + std::fprintf(stderr, " Size at end: %d\n", duk_get_top(context_)); + std::fprintf(stderr, " Expected (user): %u\n", expected_); + std::fprintf(stderr, " Expected (adjusted): %u\n", expected_ + begin_); + std::fprintf(stderr, " Number of stale values: %u\n", duk_get_top(context_) - begin_ - expected_); std::abort(); } #endif @@ -99,18 +98,81 @@ }; /** - * \class Exception - * \brief Error description. + * \brief dukx_error description. * - * This class fills the fields got in an Error object. + * This class fills the fields got in an dukx_error object. */ -class Exception : public std::exception { +class dukx_exception : public std::exception { +private: + std::string name_; + std::string message_; + std::string stack_; + std::string filename_; + int linenumber_{0}; + public: - std::string name; //!< name of error - std::string message; //!< error message - std::string stack; //!< stack if available - std::string fileName; //!< filename if applicable - int lineNumber{0}; //!< line number if applicable + inline dukx_exception(std::string name, + std::string message, + std::string stack = "", + std::string filename = "", + int linenumber = 0) noexcept + : name_(std::move(name)) + , message_(std::move(message)) + , stack_(std::move(stack)) + , filename_(std::move(filename)) + , linenumber_(linenumber) + { + } + + /** + * Get exception name (e.g. URIdukx_error). + * + * \return the exception name + */ + inline const std::string& name() const noexcept + { + return name_; + } + + /** + * Get error message. + * + * \return the error message + */ + inline const std::string& message() const noexcept + { + return message_; + } + + /** + * Get stack if available. + * + * \return the stack + */ + inline const std::string& stack() const noexcept + { + return stack_; + } + + /** + * Get filename if available. + * + * \return the filename + */ + inline const std::string& filename() const noexcept + { + return filename_; + } + + /** + * Get the line number if available. + * + * \return the line number + */ + inline int linenumber() const noexcept + { + return linenumber_; + } /** * Get the error message. This effectively returns message field. @@ -119,7 +181,7 @@ */ const char *what() const noexcept override { - return message.c_str(); + return message_.c_str(); } }; @@ -128,38 +190,35 @@ * * This class is implicitly convertible to duk_context for convenience. */ -class UniqueContext { +class dukx_unique_context { private: - using Deleter = void (*)(duk_context *); - using Handle = std::unique_ptr; + std::unique_ptr handle_; - Handle m_handle; - - UniqueContext(const UniqueContext &) = delete; - UniqueContext &operator=(const UniqueContext &) = delete; + dukx_unique_context(const dukx_unique_context&) = delete; + dukx_unique_context& operator=(const dukx_unique_context&) = delete; public: /** * Create default context. */ - inline UniqueContext() - : m_handle(duk_create_heap_default(), duk_destroy_heap) + inline dukx_unique_context() + : handle_(duk_create_heap_default(), duk_destroy_heap) { } /** * Default move constructor. */ - UniqueContext(UniqueContext &&) noexcept = default; + dukx_unique_context(dukx_unique_context&&) noexcept = default; /** * Convert the context to the native Duktape/C type. * * \return the duk_context */ - inline operator duk_context *() noexcept + inline operator duk_context*() noexcept { - return m_handle.get(); + return handle_.get(); } /** @@ -167,9 +226,9 @@ * * \return the duk_context */ - inline operator duk_context *() const noexcept + inline operator duk_context*() const noexcept { - return m_handle.get(); + return handle_.get(); } /** @@ -177,18 +236,17 @@ * * \return this */ - UniqueContext &operator=(UniqueContext &&) noexcept = delete; + dukx_unique_context& operator=(dukx_unique_context&&) noexcept = delete; }; /** - * \class Error * \brief Base ECMAScript error class. * \warning Override the function create for your own exceptions */ -class Error { +class dukx_error { private: - int m_type{DUK_ERR_ERROR}; - std::string m_message; + int type_{DUK_ERR_ERROR}; + std::string message_; protected: /** @@ -198,9 +256,9 @@ * \param type of error (e.g. DUK_ERR_ERROR) * \param message the message */ - inline Error(int type, std::string message) noexcept - : m_type(type) - , m_message(std::move(message)) + inline dukx_error(int type, std::string message) noexcept + : type_(type) + , message_(std::move(message)) { } @@ -210,8 +268,8 @@ * * \param message the message */ - inline Error(std::string message) noexcept - : m_message(std::move(message)) + inline dukx_error(std::string message) noexcept + : message_(std::move(message)) { } @@ -221,110 +279,104 @@ * \note the default implementation search for the global variables * \param ctx the context */ - virtual void raise(duk_context *ctx) const + virtual void raise(duk_context* ctx) const { - duk_error(ctx, m_type, "%s", m_message.c_str()); + duk_error(ctx, type_, "%s", message_.c_str()); } }; /** - * \class EvalError * \brief Error in eval() function. */ -class EvalError : public Error { +class dukx_eval_error : public dukx_error { public: /** - * Construct an EvalError. + * Construct an EvalError * * \param message the message */ - inline EvalError(std::string message) noexcept - : Error(DUK_ERR_EVAL_ERROR, std::move(message)) + inline dukx_eval_error(std::string message) noexcept + : dukx_error(DUK_ERR_EVAL_ERROR, std::move(message)) { } }; /** - * \class RangeError * \brief Value is out of range. */ -class RangeError : public Error { +class dukx_range_error : public dukx_error { public: /** * Construct an RangeError. * * \param message the message */ - inline RangeError(std::string message) noexcept - : Error(DUK_ERR_RANGE_ERROR, std::move(message)) + inline dukx_range_error(std::string message) noexcept + : dukx_error(DUK_ERR_RANGE_ERROR, std::move(message)) { } }; /** - * \class ReferenceError * \brief Trying to use a variable that does not exist. */ -class ReferenceError : public Error { +class dukx_reference_error : public dukx_error { public: /** * Construct an ReferenceError. * * \param message the message */ - inline ReferenceError(std::string message) noexcept - : Error(DUK_ERR_REFERENCE_ERROR, std::move(message)) + inline dukx_reference_error(std::string message) noexcept + : dukx_error(DUK_ERR_REFERENCE_ERROR, std::move(message)) { } }; /** - * \class SyntaxError * \brief Syntax error in the script. */ -class SyntaxError : public Error { +class dukx_syntax_error : public dukx_error { public: /** * Construct an SyntaxError. * * \param message the message */ - inline SyntaxError(std::string message) noexcept - : Error(DUK_ERR_SYNTAX_ERROR, std::move(message)) + inline dukx_syntax_error(std::string message) noexcept + : dukx_error(DUK_ERR_SYNTAX_ERROR, std::move(message)) { } }; /** - * \class TypeError * \brief Invalid type given. */ -class TypeError : public Error { +class dukx_type_error : public dukx_error { public: /** * Construct an TypeError. * * \param message the message */ - inline TypeError(std::string message) noexcept - : Error(DUK_ERR_TYPE_ERROR, std::move(message)) + inline dukx_type_error(std::string message) noexcept + : dukx_error(DUK_ERR_TYPE_ERROR, std::move(message)) { } }; /** - * \class URIError * \brief URI manipulation failure. */ -class URIError : public Error { +class dukx_uri_error : public dukx_error { public: /** * Construct an URIError. * * \param message the message */ - inline URIError(std::string message) noexcept - : Error(DUK_ERR_URI_ERROR, std::move(message)) + inline dukx_uri_error(std::string message) noexcept + : dukx_error(DUK_ERR_URI_ERROR, std::move(message)) { } }; @@ -338,28 +390,29 @@ * \param pop if true, also remove the exception from the stack * \return the information */ -inline Exception dukx_exception(duk_context *ctx, int index, bool pop = true) +inline dukx_exception dukx_get_exception(duk_context* ctx, int index, bool pop = true) { - Exception ex; + std::string name, message, stack, filename; + int linenumber; index = duk_normalize_index(ctx, index); duk_get_prop_string(ctx, index, "name"); - ex.name = duk_to_string(ctx, -1); + name = duk_to_string(ctx, -1); duk_get_prop_string(ctx, index, "message"); - ex.message = duk_to_string(ctx, -1); + message = duk_to_string(ctx, -1); duk_get_prop_string(ctx, index, "fileName"); - ex.fileName = duk_to_string(ctx, -1); + filename = duk_to_string(ctx, -1); duk_get_prop_string(ctx, index, "lineNumber"); - ex.lineNumber = duk_to_int(ctx, -1); + linenumber = duk_to_int(ctx, -1); duk_get_prop_string(ctx, index, "stack"); - ex.stack = duk_to_string(ctx, -1); + stack = duk_to_string(ctx, -1); duk_pop_n(ctx, 5); if (pop) duk_remove(ctx, index); - return ex; + return dukx_exception(name, message, stack, filename, linenumber); } /** @@ -367,11 +420,13 @@ * * \param ctx the context * \param ex the exception + * \return 0 for convenience */ template -void dukx_throw(duk_context *ctx, const Exception &ex) +int dukx_throw(duk_context* ctx, const Exception& ex) { ex.raise(ctx); + return 0; } /** @@ -381,10 +436,10 @@ * \param index the index * \return the string */ -inline std::string dukx_get_std_string(duk_context *ctx, int index) +inline std::string dukx_get_std_string(duk_context* ctx, int index) { duk_size_t size; - const char *text = duk_get_lstring(ctx, index, &size); + const char* text = duk_get_lstring(ctx, index, &size); return std::string(text, size); } @@ -396,10 +451,10 @@ * \param index the index * \return the string */ -inline std::string dukx_require_std_string(duk_context *ctx, int index) +inline std::string dukx_require_std_string(duk_context* ctx, int index) { duk_size_t size; - const char *text = duk_require_lstring(ctx, index, &size); + const char* text = duk_require_lstring(ctx, index, &size); return std::string(text, size); } @@ -410,96 +465,9 @@ * \param ctx the context * \param str the string */ -inline void dukx_push_std_string(duk_context *ctx, const std::string &str) +inline void dukx_push_std_string(duk_context* ctx, const std::string& str) { duk_push_lstring(ctx, str.data(), str.length()); } -/** - * Get an array. - * - * \param ctx the context - * \param index the array index - * \param get the conversion function (e.g. duk_get_int) - */ -template -auto dukx_get_array(duk_context *ctx, duk_idx_t index, Getter &&get) -{ - using T = decltype(get(ctx, 0)); - - std::vector result; - std::size_t length = duk_get_length(ctx, index); - - for (std::size_t i = 0; i < length; ++i) { - duk_get_prop_index(ctx, -1, i); - result.push_back(get(ctx, -1)); - duk_pop(ctx); - } - - return result; -} - -/** - * Push an array. - * - * \param ctx the context - * \param values the values - * \param push the function to push values - */ -template -void dukx_push_array(duk_context *ctx, const std::vector &values, Pusher &&push) -{ - duk_push_array(ctx); - - int i = 0; - for (auto x : values) { - push(ctx, x); - duk_put_prop_index(ctx, -2, i++); - } -} - -/** - * Get an object. - * - * \param ctx the context - * \param index the object index - * \param get the conversion function (e.g. duk_get_int) - */ -template -auto dukx_get_object(duk_context *ctx, duk_idx_t index, Getter &&get) -{ - using T = decltype(get(ctx, 0)); - - std::unordered_map result; - - duk_enum(ctx, index, 0); - - while (duk_next(ctx, -1, true)) { - result.emplace(dukx_get_std_string(ctx, -2), get(ctx, -1)); - duk_pop_2(ctx); - } - - duk_pop(ctx); - - return result; -} - -/** - * Push an object. - * - * \param ctx the context - * \param values the values - * \param push the function to push values - */ -template -void dukx_push_object(duk_context *ctx, const std::unordered_map &values, Pusher &&push) -{ - duk_push_object(ctx); - - for (const auto &pair : values) { - push(ctx, pair.second); - duk_put_prop_string(ctx, -2, pair.first.c_str()); - } -} - #endif // !DUKTAPE_HPP diff -r beef249c796c -r 18ec7f4fc3de modules/js/test/main.cpp --- a/modules/js/test/main.cpp Sat Jul 01 07:35:13 2017 +0200 +++ b/modules/js/test/main.cpp Mon Aug 21 11:08:49 2017 +0200 @@ -1,5 +1,5 @@ /* - * TestJsUnicode.cpp -- test irccd JS functions + * main.cpp -- test Duktape extras * * Copyright (c) 2016 David Demelier * @@ -16,277 +16,176 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#define BOOST_TEST_MODULE "Duktape" +#include #include -TEST(Push, array) -{ - UniqueContext ctx; - - std::vector v{1, 2, 3}; - - dukx_push_array(ctx, v, duk_push_int); - ASSERT_EQ(v, dukx_get_array(ctx, -1, duk_get_int)); -} - -TEST(Push, object) -{ - UniqueContext ctx; - - std::unordered_map o{ - { "file", "foo.txt" }, - { "password", "test" } - }; - - dukx_push_object(ctx, o, dukx_push_std_string); - ASSERT_EQ(o, dukx_get_object(ctx, -1, dukx_get_std_string)); -} - -#if 0 - -TEST(Basics, enumerate) -{ - duk::UniqueContext context; - - ASSERT_EQ(0, duk::top(context)); - duk::push(context, duk::Object{}); - duk::putProperty(context, -1, "x", 123); - duk::putProperty(context, -1, "y", 456); - ASSERT_EQ(1, duk::top(context)); - duk::enumerate(context, -1, 0, true, [] (duk::Context *ctx) { - ASSERT_EQ(DUK_TYPE_STRING, duk::type(ctx, -2)); - ASSERT_EQ(DUK_TYPE_NUMBER, duk::type(ctx, -1)); - - if (duk::get(ctx, -2) == "x") - ASSERT_EQ(123, duk::get(ctx, -1)); - if (duk::get(ctx, -2) == "y") - ASSERT_EQ(456, duk::get(ctx, -1)); - }); - ASSERT_EQ(1, duk::top(context)); -} - -/* - * Exception handling. - * ------------------------------------------------------------------ - */ - -TEST(Exception, raise) -{ - duk::UniqueContext context; - - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, DUK_ERR_ERROR, "error thrown"); - - return 0; - }}); - duk::evalString(context, - "try {" - " f();" - "} catch (ex) {" - " name = ex.name;" - " message = ex.message;" - " received = true;" - "}" - ); - - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("Error", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); -} - /* * Standard exceptions. * -------------------------------------------------------- */ -TEST(StandardExceptions, error) +BOOST_AUTO_TEST_SUITE(standard_exceptions) + +BOOST_AUTO_TEST_CASE(error) { - duk::UniqueContext context; - - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, duk::Error("error thrown")); + dukx_unique_context ctx; - return 0; - }}); - duk::evalString(context, - "try {" - " f();" - "} catch (ex) {" - " name = ex.name;" - " message = ex.message;" - " received = true;" - " correct = (ex instanceof Error);" - "}" - ); - - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("Error", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); - ASSERT_TRUE(duk::getGlobal(context, "correct")); -} - -TEST(StandardExceptions, evalError) -{ - duk::UniqueContext context; - - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, duk::EvalError("error thrown")); - - return 0; - }}); - duk::evalString(context, + duk_push_c_function(ctx, [] (duk_context* ctx) -> duk_idx_t { + return dukx_throw(ctx, dukx_error("error thrown")); + }, 0); + duk_put_global_string(ctx, "f"); + duk_peval_string(ctx, "try {" " f();" "} catch (ex) {" " name = ex.name;" " message = ex.message;" - " received = true;" - " correct = (ex instanceof EvalError);" + " instance = (ex instanceof Error);" "}" ); - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("EvalError", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); - ASSERT_TRUE(duk::getGlobal(context, "correct")); + duk_get_global_string(ctx, "name"); + BOOST_REQUIRE_EQUAL("Error", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "message"); + BOOST_REQUIRE_EQUAL("error thrown", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "instance"); + BOOST_REQUIRE(duk_get_boolean(ctx, -1)); } -TEST(StandardExceptions, rangeError) +BOOST_AUTO_TEST_CASE(eval_error) { - duk::UniqueContext context; + dukx_unique_context ctx; - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, duk::RangeError("error thrown")); - - return 0; - }}); - duk::evalString(context, + duk_push_c_function(ctx, [] (duk_context* ctx) -> duk_idx_t { + return dukx_throw(ctx, dukx_eval_error("error thrown")); + }, 0); + duk_put_global_string(ctx, "f"); + duk_peval_string(ctx, "try {" " f();" "} catch (ex) {" " name = ex.name;" " message = ex.message;" - " received = true;" - " correct = (ex instanceof RangeError);" + " instance = (ex instanceof EvalError);" "}" ); - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("RangeError", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); - ASSERT_TRUE(duk::getGlobal(context, "correct")); + duk_get_global_string(ctx, "name"); + BOOST_REQUIRE_EQUAL("EvalError", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "message"); + BOOST_REQUIRE_EQUAL("error thrown", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "instance"); + BOOST_REQUIRE(duk_get_boolean(ctx, -1)); } -TEST(StandardExceptions, referenceError) +BOOST_AUTO_TEST_CASE(range_error) { - duk::UniqueContext context; + dukx_unique_context ctx; - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, duk::ReferenceError("error thrown")); - - return 0; - }}); - duk::evalString(context, + duk_push_c_function(ctx, [] (duk_context* ctx) -> duk_idx_t { + return dukx_throw(ctx, dukx_range_error("error thrown")); + }, 0); + duk_put_global_string(ctx, "f"); + duk_peval_string(ctx, "try {" " f();" "} catch (ex) {" " name = ex.name;" " message = ex.message;" - " received = true;" - " correct = (ex instanceof ReferenceError);" + " instance = (ex instanceof RangeError);" "}" ); - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("ReferenceError", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); - ASSERT_TRUE(duk::getGlobal(context, "correct")); + duk_get_global_string(ctx, "name"); + BOOST_REQUIRE_EQUAL("RangeError", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "message"); + BOOST_REQUIRE_EQUAL("error thrown", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "instance"); + BOOST_REQUIRE(duk_get_boolean(ctx, -1)); } -TEST(StandardExceptions, syntaxError) +BOOST_AUTO_TEST_CASE(reference_error) { - duk::UniqueContext context; + dukx_unique_context ctx; - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, duk::SyntaxError("error thrown")); - - return 0; - }}); - duk::evalString(context, + duk_push_c_function(ctx, [] (duk_context* ctx) -> duk_idx_t { + return dukx_throw(ctx, dukx_reference_error("error thrown")); + }, 0); + duk_put_global_string(ctx, "f"); + duk_peval_string(ctx, "try {" " f();" "} catch (ex) {" " name = ex.name;" " message = ex.message;" - " received = true;" - " correct = (ex instanceof SyntaxError);" + " instance = (ex instanceof ReferenceError);" "}" ); - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("SyntaxError", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); - ASSERT_TRUE(duk::getGlobal(context, "correct")); + duk_get_global_string(ctx, "name"); + BOOST_REQUIRE_EQUAL("ReferenceError", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "message"); + BOOST_REQUIRE_EQUAL("error thrown", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "instance"); + BOOST_REQUIRE(duk_get_boolean(ctx, -1)); } -TEST(StandardExceptions, typeError) +BOOST_AUTO_TEST_CASE(syntax_error) { - duk::UniqueContext context; + dukx_unique_context ctx; - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, duk::TypeError("error thrown")); - - return 0; - }}); - duk::evalString(context, + duk_push_c_function(ctx, [] (duk_context* ctx) -> duk_idx_t { + return dukx_throw(ctx, dukx_syntax_error("error thrown")); + }, 0); + duk_put_global_string(ctx, "f"); + duk_peval_string(ctx, "try {" " f();" "} catch (ex) {" " name = ex.name;" " message = ex.message;" - " received = true;" - " correct = (ex instanceof TypeError);" + " instance = (ex instanceof SyntaxError);" "}" ); - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("TypeError", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); - ASSERT_TRUE(duk::getGlobal(context, "correct")); + duk_get_global_string(ctx, "name"); + BOOST_REQUIRE_EQUAL("SyntaxError", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "message"); + BOOST_REQUIRE_EQUAL("error thrown", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "instance"); + BOOST_REQUIRE(duk_get_boolean(ctx, -1)); } -TEST(StandardExceptions, uriError) +BOOST_AUTO_TEST_CASE(type_error) { - duk::UniqueContext context; + dukx_unique_context ctx; - duk::putGlobal(context, "f", duk::Function{[] (duk::Context *ctx) -> duk_idx_t { - duk::raise(ctx, duk::URIError("error thrown")); - - return 0; - }}); - duk::evalString(context, + duk_push_c_function(ctx, [] (duk_context* ctx) -> duk_idx_t { + return dukx_throw(ctx, dukx_type_error("error thrown")); + }, 0); + duk_put_global_string(ctx, "f"); + duk_peval_string(ctx, "try {" " f();" "} catch (ex) {" " name = ex.name;" " message = ex.message;" - " received = true;" - " correct = (ex instanceof URIError);" + " instance = (ex instanceof TypeError);" "}" ); - ASSERT_TRUE(duk::getGlobal(context, "received")); - ASSERT_EQ("URIError", duk::getGlobal(context, "name")); - ASSERT_EQ("error thrown", duk::getGlobal(context, "message")); - ASSERT_TRUE(duk::getGlobal(context, "correct")); + duk_get_global_string(ctx, "name"); + BOOST_REQUIRE_EQUAL("TypeError", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "message"); + BOOST_REQUIRE_EQUAL("error thrown", dukx_get_std_string(ctx, -1)); + duk_get_global_string(ctx, "instance"); + BOOST_REQUIRE(duk_get_boolean(ctx, -1)); } -#endif - -int main(int argc, char **argv) +BOOST_AUTO_TEST_CASE(uriError) { - testing::InitGoogleTest(&argc, argv); +} - return RUN_ALL_TESTS(); -} +BOOST_AUTO_TEST_SUITE_END()