Mercurial > code
view C++/tests/Js/main.cpp @ 398:94bfe7ba9a13
Js:
- Rename some functions
- Cleanup a lot
- Add more documentation
- Add specialization of getProperty and getGlobal to void to push on the
stack
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 30 Sep 2015 19:59:12 +0200 |
parents | 6b2db5425836 |
children | 73517fd307dd |
line wrap: on
line source
/* * TestJsUnicode.cpp -- test irccd JS functions * * Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <gtest/gtest.h> #include <Js.h> using namespace js; /* -------------------------------------------------------- * Push & get * -------------------------------------------------------- */ TEST(PushAndGet, boolean) { Context context; context.push(true); ASSERT_TRUE(context.get<bool>(-1)); context.push(false); ASSERT_FALSE(context.get<bool>(-1)); } TEST(PushAndGet, integer) { Context context; context.push(123); ASSERT_EQ(123, context.get<int>(-1)); context.push(456); ASSERT_EQ(456, context.get<int>(-1)); } TEST(PushAndGet, number) { Context context; context.push(10.5); ASSERT_EQ(10.5, context.get<double>(-1)); context.push(50.1); ASSERT_EQ(50.1, context.get<double>(-1)); } TEST(PushAndGet, string) { Context context; context.push("hello world!"); ASSERT_EQ("hello world!", context.get<std::string>(-1)); } /* -------------------------------------------------------- * Basics * -------------------------------------------------------- */ TEST(Basics, global) { Context context; // boolean context.setGlobal("valueBoolean", true); ASSERT_TRUE(context.getGlobal<bool>("valueBoolean")); // integer context.setGlobal("valueInteger", 123); ASSERT_EQ(123, context.getGlobal<int>("valueInteger")); } TEST(Basics, top) { Context context; int current = context.top(); context.push(true); ASSERT_EQ(current + 1, context.top()); } TEST(Basics, pop1) { Context context; int current = context.top(); context.push(true); context.pop(); ASSERT_EQ(current, context.top()); } TEST(Basics, pop2) { Context context; int current = context.top(); context.push(true); context.push(true); context.pop(2); ASSERT_EQ(current, context.top()); } TEST(Basics, putProperty) { Context context; context.push(Object{}); context.putProperty(-1, "x", 123); ASSERT_EQ(123, context.getProperty<int>(-1, "x")); } TEST(Basics, enumerate) { Context context; context.push(Object{}); context.putProperty(-1, "x", 123); context.putProperty(-1, "y", 456); context.enumerate(-1, 0, true, [] (Context &ctx) { ASSERT_EQ(DUK_TYPE_STRING, ctx.type(-2)); ASSERT_EQ(DUK_TYPE_NUMBER, ctx.type(-1)); if (ctx.get<std::string>(-2) == "x") ASSERT_EQ(123, ctx.get<int>(-1)); if (ctx.get<std::string>(-2) == "y") ASSERT_EQ(456, ctx.get<int>(-1)); }); } TEST(Basics, call) { Context context; context.push(Function{[] (Context &ctx) -> int { ctx.setGlobal("x", 123); return 0; }}); context.call(); ASSERT_EQ(123, context.getGlobal<int>("x")); } /* ------------------------------------------------------------------ * Eval * ------------------------------------------------------------------ */ TEST(Eval, simple) { Context context; context.eval(Script{"x = 123;"}); ASSERT_EQ(123, context.getGlobal<int>("x")); } TEST(Eval, function) { Context context; context.eval(Script{"function f() { x = 123; }; f();"}); ASSERT_EQ(123, context.getGlobal<int>("x")); } TEST(Eval, cfunction) { Context context; context.setGlobal("f", Function{[] (Context &ctx) -> int { ctx.setGlobal("x", 123); return 0; }}); context.eval(Script{"f()"}); ASSERT_EQ(123, context.getGlobal<int>("x")); } /* ------------------------------------------------------------------ * Protected eval * ------------------------------------------------------------------ */ TEST(Peval, success) { Context context; try { context.peval(Script{"x = 1"}); } catch (const ErrorInfo &info) { FAIL() << "error unexpected: " << info.what(); } } TEST(Peval, failure) { Context context; try { context.peval(Script{"doesnotexists()"}); FAIL() << "expected exception"; } catch (const std::exception &) { } } /* ------------------------------------------------------------------ * Exception handling * ------------------------------------------------------------------ */ TEST(Exception, error) { Context context; context.setGlobal("f", Function{[] (ContextPtr pctx) -> duk_idx_t { Context ctx{pctx}; ctx.raise(Error{"error thrown"}); return 0; }}); context.eval(Script{ "try {" " f();" "} catch (ex) {" " name = ex.name;" " message = ex.message;" " received = true;" "}" }); ASSERT_TRUE(context.getGlobal<bool>("received")); ASSERT_EQ("Error", context.getGlobal<std::string>("name")); ASSERT_EQ("error thrown", context.getGlobal<std::string>("message")); } /* -------------------------------------------------------- * TypeInfo with shared * -------------------------------------------------------- */ class Player { public: bool m_updated{false}; }; template <> class TypeInfo<std::shared_ptr<Player>> : public TypeInfoShared<Player> { public: static void prototype(Context &ctx) { /* Create a temporary for the test */ ctx.push(Object{}); /* "update" method */ ctx.putProperty(-1, "update", Function{[] (ContextPtr pctx) -> duk_ret_t { Context{pctx}.self<std::shared_ptr<Player>>()->m_updated = true; return 0; }}); } }; TEST(Shared, simple) { Context ctx; std::shared_ptr<Player> p{new Player}; ctx.push(p); std::shared_ptr<Player> p2 = ctx.get<std::shared_ptr<Player>>(-1); p2->m_updated = true; ASSERT_TRUE(p->m_updated); } TEST(Shared, self) { Context ctx; std::shared_ptr<Player> p{new Player}; try { ctx.setGlobal("player", p); ctx.peval(Script{"player.update();"}); ASSERT_TRUE(p->m_updated); } catch (const std::exception &ex) { FAIL() << ex.what(); } } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }