diff options
Diffstat (limited to 'dom/promise/gtest')
-rw-r--r-- | dom/promise/gtest/NativeThenHandler.cpp | 160 | ||||
-rw-r--r-- | dom/promise/gtest/ThenWithCycleCollectedArgsJS.cpp | 158 | ||||
-rw-r--r-- | dom/promise/gtest/moz.build | 14 |
3 files changed, 332 insertions, 0 deletions
diff --git a/dom/promise/gtest/NativeThenHandler.cpp b/dom/promise/gtest/NativeThenHandler.cpp new file mode 100644 index 0000000000..13ed6d2c11 --- /dev/null +++ b/dom/promise/gtest/NativeThenHandler.cpp @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "js/TypeDecls.h" +#include "js/Value.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/Promise-inl.h" +#include "xpcpublic.h" + +using namespace mozilla; +using namespace mozilla::dom; + +struct TraceCounts { + int32_t mValue = 0; + int32_t mId = 0; + int32_t mObject = 0; + int32_t mWrapperCache = 0; + int32_t mTenuredHeapObject = 0; + int32_t mString = 0; + int32_t mScript = 0; + int32_t mFunction = 0; +}; + +struct DummyCallbacks final : public TraceCallbacks { + void Trace(JS::Heap<JS::Value>*, const char*, void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mValue++; + } + + void Trace(JS::Heap<jsid>*, const char*, void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mId++; + } + + void Trace(JS::Heap<JSObject*>*, const char*, void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mObject++; + } + + void Trace(nsWrapperCache*, const char* aName, + void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mWrapperCache++; + } + + void Trace(JS::TenuredHeap<JSObject*>*, const char*, + void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mTenuredHeapObject++; + } + + void Trace(JS::Heap<JSString*>*, const char*, void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mString++; + } + + void Trace(JS::Heap<JSScript*>*, const char*, void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mScript++; + } + + void Trace(JS::Heap<JSFunction*>*, const char*, + void* aClosure) const override { + static_cast<TraceCounts*>(aClosure)->mFunction++; + } +}; + +TEST(NativeThenHandler, TraceValue) +{ + auto onResolve = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, + JS::Handle<JS::Value>) -> already_AddRefed<Promise> { + return nullptr; + }; + auto onReject = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, + JS::Handle<JS::Value>) -> already_AddRefed<Promise> { + return nullptr; + }; + + // Explicit type for backward compatibility with clang<7 / gcc<8 + using HandlerType = + NativeThenHandler<decltype(onResolve), decltype(onReject), std::tuple<>, + std::tuple<JS::HandleValue>>; + RefPtr<HandlerType> handler = new HandlerType( + nullptr, Some(onResolve), Some(onReject), std::make_tuple(), + std::make_tuple(JS::UndefinedHandleValue)); + + TraceCounts counts; + NS_CYCLE_COLLECTION_PARTICIPANT(HandlerType) + ->Trace(handler.get(), DummyCallbacks(), &counts); + + EXPECT_EQ(counts.mValue, 1); +} + +TEST(NativeThenHandler, TraceObject) +{ + auto onResolve = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, + JS::Handle<JSObject*>) -> already_AddRefed<Promise> { + return nullptr; + }; + auto onReject = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, + JS::Handle<JSObject*>) -> already_AddRefed<Promise> { + return nullptr; + }; + + AutoJSAPI jsapi; + MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsapi.cx(); + JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx)); + + // Explicit type for backward compatibility with clang<7 / gcc<8 + using HandlerType = + NativeThenHandler<decltype(onResolve), decltype(onReject), std::tuple<>, + std::tuple<JS::HandleObject>>; + RefPtr<HandlerType> handler = new HandlerType( + nullptr, Some(onResolve), Some(onReject), std::make_tuple(), + std::make_tuple(JS::HandleObject(obj))); + + TraceCounts counts; + NS_CYCLE_COLLECTION_PARTICIPANT(HandlerType) + ->Trace(handler.get(), DummyCallbacks(), &counts); + + EXPECT_EQ(counts.mObject, 1); +} + +TEST(NativeThenHandler, TraceMixed) +{ + auto onResolve = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, + nsIGlobalObject*, Promise*, JS::Handle<JS::Value>, + JS::Handle<JSObject*>) -> already_AddRefed<Promise> { + return nullptr; + }; + auto onReject = [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, + nsIGlobalObject*, Promise*, JS::Handle<JS::Value>, + JS::Handle<JSObject*>) -> already_AddRefed<Promise> { + return nullptr; + }; + + AutoJSAPI jsapi; + MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsapi.cx(); + nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(cx); + JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx)); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + + // Explicit type for backward compatibility with clang<7 / gcc<8 + using HandlerType = + NativeThenHandler<decltype(onResolve), decltype(onReject), + std::tuple<nsCOMPtr<nsIGlobalObject>, RefPtr<Promise>>, + std::tuple<JS::HandleValue, JS::HandleObject>>; + RefPtr<HandlerType> handler = new HandlerType( + nullptr, Some(onResolve), Some(onReject), + std::make_tuple(global, promise), + std::make_tuple(JS::UndefinedHandleValue, JS::HandleObject(obj))); + + TraceCounts counts; + NS_CYCLE_COLLECTION_PARTICIPANT(HandlerType) + ->Trace(handler.get(), DummyCallbacks(), &counts); + + EXPECT_EQ(counts.mValue, 1); + EXPECT_EQ(counts.mObject, 1); +} diff --git a/dom/promise/gtest/ThenWithCycleCollectedArgsJS.cpp b/dom/promise/gtest/ThenWithCycleCollectedArgsJS.cpp new file mode 100644 index 0000000000..31b9fde3ca --- /dev/null +++ b/dom/promise/gtest/ThenWithCycleCollectedArgsJS.cpp @@ -0,0 +1,158 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/Promise-inl.h" +#include "xpcpublic.h" + +using namespace mozilla; +using namespace mozilla::dom; + +TEST(ThenWithCycleCollectedArgsJS, Empty) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&) { return nullptr; }, + std::make_tuple(), std::make_tuple()); +} + +TEST(ThenWithCycleCollectedArgsJS, nsCOMPtr) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, nsIGlobalObject*) { + return nullptr; + }, + std::make_tuple(global), std::make_tuple()); +} + +TEST(ThenWithCycleCollectedArgsJS, RefPtr) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, Promise*) { + return nullptr; + }, + std::make_tuple(promise), std::make_tuple()); +} + +TEST(ThenWithCycleCollectedArgsJS, RefPtrAndJSHandle) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value> v, ErrorResult&, Promise*, + JS::Handle<JS::Value>) { return nullptr; }, + std::make_tuple(promise), std::make_tuple(JS::UndefinedHandleValue)); +} + +TEST(ThenWithCycleCollectedArgsJS, Mixed) +{ + AutoJSAPI jsapi; + MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsapi.cx(); + nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(cx); + JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx)); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, nsIGlobalObject*, + Promise*, JS::Handle<JS::Value>, + JS::Handle<JSObject*>) { return nullptr; }, + std::make_tuple(global, promise), + std::make_tuple(JS::UndefinedHandleValue, JS::HandleObject(obj))); +} + +TEST(ThenCatchWithCycleCollectedArgsJS, Empty) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenCatchWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&) { return nullptr; }, + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&) { return nullptr; }, + std::make_tuple(), std::make_tuple()); +} + +TEST(ThenCatchWithCycleCollectedArgsJS, nsCOMPtr) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenCatchWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, nsIGlobalObject*) { + return nullptr; + }, + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, nsIGlobalObject*) { + return nullptr; + }, + std::make_tuple(global), std::make_tuple()); +} + +TEST(ThenCatchWithCycleCollectedArgsJS, RefPtr) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenCatchWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, Promise*) { + return nullptr; + }, + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, Promise*) { + return nullptr; + }, + std::make_tuple(promise), std::make_tuple()); +} + +TEST(ThenCatchWithCycleCollectedArgsJS, RefPtrAndJSHandle) +{ + nsCOMPtr<nsIGlobalObject> global = + xpc::NativeGlobal(xpc::PrivilegedJunkScope()); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenCatchWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value> v, ErrorResult&, Promise*, + JS::Handle<JS::Value>) { return nullptr; }, + [](JSContext*, JS::Handle<JS::Value> v, ErrorResult&, Promise*, + JS::Handle<JS::Value>) { return nullptr; }, + std::make_tuple(promise), std::make_tuple(JS::UndefinedHandleValue)); +} + +TEST(ThenCatchWithCycleCollectedArgsJS, Mixed) +{ + AutoJSAPI jsapi; + MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsapi.cx(); + nsCOMPtr<nsIGlobalObject> global = xpc::CurrentNativeGlobal(cx); + JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx)); + + RefPtr<Promise> promise = Promise::Create(global, IgnoreErrors()); + auto result = promise->ThenCatchWithCycleCollectedArgsJS( + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, nsIGlobalObject*, + Promise*, JS::Handle<JS::Value>, + JS::Handle<JSObject*>) { return nullptr; }, + [](JSContext*, JS::Handle<JS::Value>, ErrorResult&, nsIGlobalObject*, + Promise*, JS::Handle<JS::Value>, + JS::Handle<JSObject*>) { return nullptr; }, + std::make_tuple(global, promise), + std::make_tuple(JS::UndefinedHandleValue, JS::HandleObject(obj))); +} diff --git a/dom/promise/gtest/moz.build b/dom/promise/gtest/moz.build new file mode 100644 index 0000000000..a220822834 --- /dev/null +++ b/dom/promise/gtest/moz.build @@ -0,0 +1,14 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at http://mozilla.org/MPL/2.0/. + +UNIFIED_SOURCES += [ + "NativeThenHandler.cpp", + "ThenWithCycleCollectedArgsJS.cpp", +] + +LOCAL_INCLUDES += ["/dom/promise"] + +FINAL_LIBRARY = "xul-gtest" |