diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-02-10 15:16:14 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-02-10 15:16:14 -0800 |
commit | ed896c9c00edc7c7bdd4c4cfaca057509c3cd628 (patch) | |
tree | a4721bedbe82d57cff7f6a94dbd2ed8e5b8425dc /tests | |
parent | 8eb52e34be029cd7f276871c830b02fdf53ed00c (diff) | |
parent | b5cf147e6ce7a8d3277342d87beec76290a578bf (diff) |
Merge pull request #2099 from waywardmonkeys/upstream-from-imvu
Upstream from imvu
Diffstat (limited to 'tests')
-rw-r--r-- | tests/embind/embind.test.js | 72 | ||||
-rw-r--r-- | tests/embind/embind_test.cpp | 61 |
2 files changed, 122 insertions, 11 deletions
diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js index da81a81e..5ca972be 100644 --- a/tests/embind/embind.test.js +++ b/tests/embind/embind.test.js @@ -55,7 +55,7 @@ module({ }); }); }); - + } BaseFixture.extend("access to base class members", function() { @@ -609,7 +609,7 @@ module({ assert.equal("0", cm.unsigned_int_to_string(0)); assert.equal("0", cm.long_to_string(0)); assert.equal("0", cm.unsigned_long_to_string(0)); - + // all types should have positive values. assert.equal("5", cm.char_to_string(5)); assert.equal("5", cm.signed_char_to_string(5)); @@ -650,7 +650,7 @@ module({ assert.equal("-32768", cm.short_to_string(-32768)); assert.equal("-2147483648", cm.int_to_string(-2147483648)); assert.equal("-2147483648", cm.long_to_string(-2147483648)); - + // passing out of range values should fail. assert.throws(TypeError, function() { cm.char_to_string(-129); }); assert.throws(TypeError, function() { cm.char_to_string(128); }); @@ -733,7 +733,7 @@ module({ test("overloading of derived class member functions", function() { var foo = new cm.MultipleOverloadsDerived(); - + // NOTE: In C++, default lookup rules will hide overloads from base class if derived class creates them. // In JS, we make the base class overloads implicitly available. In C++, they would need to be explicitly // invoked, like foo.MultipleOverloads::Func(10); @@ -748,7 +748,7 @@ module({ assert.equal(foo.WhichFuncCalled(), 4); foo.delete(); }); - + test("overloading of class static functions", function() { assert.equal(cm.MultipleOverloads.StaticFunc(10), 1); assert.equal(cm.MultipleOverloads.WhichStaticFuncCalled(), 1); @@ -1441,7 +1441,7 @@ module({ test("repr includes enum value", function() { assert.equal('<#Enum_ONE {}>', IMVU.repr(cm.Enum.ONE)); assert.equal('<#Enum_TWO {}>', IMVU.repr(cm.Enum.TWO)); - }); + }); } test("instanceof", function() { @@ -1591,7 +1591,7 @@ module({ test("returning a new shared pointer from interfaces implemented in JS code does not leak", function() { var impl = cm.AbstractClass.implement({ returnsSharedPtr: function() { - return cm.embind_test_return_smart_derived_ptr(); + return cm.embind_test_return_smart_derived_ptr().deleteLater(); } }); cm.callReturnsSharedPtrMethod(impl); @@ -1644,7 +1644,7 @@ module({ }); if (typeof INVOKED_FROM_EMSCRIPTEN_TEST_RUNNER === "undefined") { // TODO: Enable this to work in Emscripten runner as well! - + BaseFixture.extend("unbound types", function() { function assertMessage(fn, message) { var e = assert.throws(cm.UnboundTypeError, fn); @@ -1689,7 +1689,7 @@ module({ }, 'Cannot construct HasConstructorUsingUnboundArgumentAndUnboundBase due to unbound types: 18SecondUnboundClass'); }); - + test('class function with unbound argument', function() { var x = new cm.BoundClass; assertMessage( @@ -1719,12 +1719,12 @@ module({ }, 'Cannot access BoundClass.property due to unbound types: 12UnboundClass'); x.delete(); }); - + // todo: tuple elements // todo: tuple element accessors // todo: struct fields }); - + } BaseFixture.extend("noncopyable", function() { @@ -1743,6 +1743,10 @@ module({ BaseFixture.extend("constants", function() { assert.equal(10, cm.INT_CONSTANT); + + assert.equal(1, cm.STATIC_CONST_INTEGER_VALUE_1); + assert.equal(1000, cm.STATIC_CONST_INTEGER_VALUE_1000); + assert.equal("some string", cm.STRING_CONSTANT); assert.deepEqual([1, 2, 3, 4], cm.VALUE_ARRAY_CONSTANT); assert.deepEqual({x:1,y:2,z:3,w:4}, cm.VALUE_OBJECT_CONSTANT); @@ -1888,6 +1892,52 @@ module({ sh.delete(); }); }); + + BaseFixture.extend("val::as from pointer to value", function() { + test("calling as on pointer with value makes a copy", function() { + var sh1 = new cm.StringHolder("Hello world"); + var sh2 = cm.return_StringHolder_copy(sh1); + assert.equal("Hello world", sh1.get()); + assert.equal("Hello world", sh2.get()); + assert.false(sh1.isAliasOf(sh2)); + sh2.delete(); + sh1.delete(); + }); + + test("calling function that returns a StringHolder", function() { + var sh1 = new cm.StringHolder("Hello world"); + var sh2 = cm.call_StringHolder_func(function() { + return sh1; + }); + assert.equal("Hello world", sh1.get()); + assert.equal("Hello world", sh2.get()); + assert.false(sh1.isAliasOf(sh2)); + sh2.delete(); + sh1.delete(); + }); + }); + + BaseFixture.extend("mixin", function() { + test("can call mixin method", function() { + var a = new cm.DerivedWithMixin(); + assert.instanceof(a, cm.Base); + assert.equal(10, a.get10()); + a.delete(); + }); + }); + + test("returning a cached new shared pointer from interfaces implemented in JS code does not leak", function() { + var derived = cm.embind_test_return_smart_derived_ptr(); + var impl = cm.AbstractClass.implement({ + returnsSharedPtr: function() { + return derived; + } + }); + cm.callReturnsSharedPtrMethod(impl); + impl.delete(); + derived.delete(); + // Let the memory leak test superfixture check that no leaks occurred. + }); }); /* global run_all_tests */ diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index d6b27bce..4efc4bd8 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -1283,6 +1283,7 @@ std::shared_ptr<HeldBySmartPtr> takesHeldBySmartPtrSharedPtr(std::shared_ptr<Hel namespace emscripten { template<typename T> struct smart_ptr_trait<CustomSmartPtr<T>> { + typedef CustomSmartPtr<T> pointer_type; typedef T element_type; static sharing_policy get_sharing_policy() { @@ -1297,6 +1298,10 @@ namespace emscripten { ++ptr->refcount; // implement an adopt API? return CustomSmartPtr<T>(ptr); } + + static pointer_type* construct_null() { + return new pointer_type; + } }; } @@ -2210,8 +2215,20 @@ EMSCRIPTEN_BINDINGS(read_only_properties) { ; } +struct StaticConstIntStruct { + static const int STATIC_CONST_INTEGER_VALUE_1; + static const int STATIC_CONST_INTEGER_VALUE_1000; +}; + +const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1 = 1; +const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000 = 1000; + EMSCRIPTEN_BINDINGS(constants) { constant("INT_CONSTANT", 10); + + constant("STATIC_CONST_INTEGER_VALUE_1", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1); + constant("STATIC_CONST_INTEGER_VALUE_1000", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000); + constant("STRING_CONSTANT", std::string("some string")); TupleVector tv(1, 2, 3, 4); @@ -2243,3 +2260,47 @@ void clear_StringHolder(StringHolder& sh) { EMSCRIPTEN_BINDINGS(references) { function("clear_StringHolder", &clear_StringHolder); } + +StringHolder return_StringHolder_copy(val func) { + return func.as<StringHolder>(); +} + +StringHolder call_StringHolder_func(val func) { + return func().as<StringHolder>(); +} + +EMSCRIPTEN_BINDINGS(return_values) { + function("return_StringHolder_copy", &return_StringHolder_copy); + function("call_StringHolder_func", &call_StringHolder_func); +} + + +struct Mixin { + int get10() const { + return 10; + } +}; + +template<typename ClassBinding> +const ClassBinding& registerMixin(const ClassBinding& binding) { + // need a wrapper for implicit conversion from DerivedWithMixin to Mixin + struct Local { + static int get10(const typename ClassBinding::class_type& self) { + return self.get10(); + } + }; + + return binding + .function("get10", &Local::get10) + ; +} + +class DerivedWithMixin : public Base, public Mixin { +}; + +EMSCRIPTEN_BINDINGS(mixins) { + registerMixin( + class_<DerivedWithMixin, base<Base>>("DerivedWithMixin") + .constructor<>() + ); +} |