summaryrefslogtreecommitdiffstats
path: root/ipc/ipdl/test/gtest/TestDataStructures.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
commitfbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch)
tree4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /ipc/ipdl/test/gtest/TestDataStructures.cpp
parentReleasing progress-linux version 124.0.1-1~progress7.99u1. (diff)
downloadfirefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz
firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ipc/ipdl/test/gtest/TestDataStructures.cpp')
-rw-r--r--ipc/ipdl/test/gtest/TestDataStructures.cpp864
1 files changed, 864 insertions, 0 deletions
diff --git a/ipc/ipdl/test/gtest/TestDataStructures.cpp b/ipc/ipdl/test/gtest/TestDataStructures.cpp
new file mode 100644
index 0000000000..b7f6a7ae95
--- /dev/null
+++ b/ipc/ipdl/test/gtest/TestDataStructures.cpp
@@ -0,0 +1,864 @@
+/* -*- 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/. */
+
+/*
+ * Test many combinations of data structures (both in argument and return
+ * position) to ensure they are transmitted correctly.
+ */
+
+#include "gtest/gtest.h"
+
+#include "mozilla/_ipdltest/IPDLUnitTest.h"
+#include "mozilla/_ipdltest/PTestDataStructuresChild.h"
+#include "mozilla/_ipdltest/PTestDataStructuresParent.h"
+#include "mozilla/_ipdltest/PTestDataStructuresSubChild.h"
+#include "mozilla/_ipdltest/PTestDataStructuresSubParent.h"
+
+#include "mozilla/Unused.h"
+
+using namespace mozilla::ipc;
+
+using RegionArray = nsTArray<nsIntRegion>;
+
+namespace mozilla::_ipdltest {
+
+static const uint32_t nactors = 10;
+
+class TestDataStructuresSubParent : public PTestDataStructuresSubParent {
+ NS_INLINE_DECL_REFCOUNTING(TestDataStructuresSubParent, override)
+
+ public:
+ explicit TestDataStructuresSubParent(uint32_t i) : mI(i) {}
+ uint32_t mI;
+
+ private:
+ ~TestDataStructuresSubParent() = default;
+};
+
+class TestDataStructuresSubChild : public PTestDataStructuresSubChild {
+ NS_INLINE_DECL_REFCOUNTING(TestDataStructuresSubChild, override)
+
+ public:
+ explicit TestDataStructuresSubChild(uint32_t i) : mI(i) {}
+ uint32_t mI;
+
+ private:
+ ~TestDataStructuresSubChild() = default;
+};
+
+inline static TestDataStructuresSubParent& Cast(
+ PTestDataStructuresSubParent* a) {
+ return *static_cast<TestDataStructuresSubParent*>(a);
+}
+
+class TestDataStructuresParent : public PTestDataStructuresParent {
+ NS_INLINE_DECL_REFCOUNTING(TestDataStructuresParent, override)
+
+ public:
+ nsTArray<NotNull<
+ SideVariant<PTestDataStructuresSubParent*, PTestDataStructuresSubChild*>>>
+ kids;
+
+ private:
+ IPCResult RecvTestArrayOfInt(nsTArray<int>&& ia,
+ nsTArray<int>* oa) final override {
+ EXPECT_EQ(5u, ia.Length());
+ for (int i = 0; i < 5; ++i) EXPECT_EQ(i, ia[i]);
+
+ *oa = std::move(ia);
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestArrayOfActor(
+ nsTArray<NotNull<PTestDataStructuresSubParent*>>&& i1,
+ nsTArray<NotNull<PTestDataStructuresSubParent*>>* o1) final override {
+ EXPECT_EQ(nactors, i1.Length());
+ for (uint32_t i = 0; i < i1.Length(); ++i) EXPECT_EQ(i, Cast(i1[i]).mI);
+ *o1 = std::move(i1);
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestUnion(const IntDouble& i1, const IntDouble& i2,
+ IntDouble* o1, IntDouble* o2) final override {
+ EXPECT_EQ(42, i1.get_int());
+ EXPECT_EQ(4.0, i2.get_double());
+
+ *o1 = i1;
+ *o2 = i2;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestArrayOfUnion(nsTArray<IntDouble>&& i1,
+ nsTArray<IntDouble>* o1) final override {
+ EXPECT_EQ(4u, i1.Length());
+ EXPECT_EQ(1, i1[0].get_int());
+ EXPECT_EQ(2.0, i1[1].get_double());
+ EXPECT_EQ(3, i1[2].get_int());
+ EXPECT_EQ(4.0, i1[3].get_double());
+
+ *o1 = std::move(i1);
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestUnionWithArray(const IntDoubleArrays& i1,
+ const IntDoubleArrays& i2,
+ const IntDoubleArrays& i3,
+ IntDoubleArrays* o1, IntDoubleArrays* o2,
+ IntDoubleArrays* o3) final override {
+ EXPECT_EQ(42, i1.get_int());
+
+ const nsTArray<int>& i2a = i2.get_ArrayOfint();
+ EXPECT_EQ(3u, i2a.Length());
+ EXPECT_EQ(1, i2a[0]);
+ EXPECT_EQ(2, i2a[1]);
+ EXPECT_EQ(3, i2a[2]);
+
+ const nsTArray<double>& i3a = i3.get_ArrayOfdouble();
+ EXPECT_EQ(3u, i3a.Length());
+ EXPECT_EQ(1.0, i3a[0]);
+ EXPECT_EQ(2.0, i3a[1]);
+ EXPECT_EQ(3.0, i3a[2]);
+
+ *o1 = i1;
+ *o2 = i2a;
+ *o3 = i3a;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestArrayOfUnionWithArray(
+ nsTArray<IntDoubleArrays>&& i1,
+ nsTArray<IntDoubleArrays>* o1) final override {
+ EXPECT_EQ(3u, i1.Length());
+
+ IntDoubleArrays id1(i1[0]);
+ EXPECT_EQ(42, id1.get_int());
+
+ nsTArray<int> i2a = i1[1].get_ArrayOfint().Clone();
+ EXPECT_EQ(3u, i2a.Length());
+ EXPECT_EQ(1, i2a[0]);
+ EXPECT_EQ(2, i2a[1]);
+ EXPECT_EQ(3, i2a[2]);
+
+ nsTArray<double> i3a = i1[2].get_ArrayOfdouble().Clone();
+ EXPECT_EQ(3u, i3a.Length());
+ EXPECT_EQ(1.0, i3a[0]);
+ EXPECT_EQ(2.0, i3a[1]);
+ EXPECT_EQ(3.0, i3a[2]);
+
+ o1->AppendElement(id1);
+ o1->AppendElement(IntDoubleArrays(i2a));
+ o1->AppendElement(IntDoubleArrays(i3a));
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestStructWithActor(const ActorWrapper& i1,
+ ActorWrapper* o1) final override {
+ EXPECT_FALSE(i1.actor().IsChild()) << "child side should be empty";
+
+ EXPECT_EQ(i1.actor(), kids[0])
+ << "should have got back same actor on parent side";
+
+ o1->actor() = kids[0];
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestUnionWithActors(const Actors& i1, const Actors& i2,
+ const Actors& i3, Actors* o1, Actors* o2,
+ Actors* o3) final override {
+ EXPECT_EQ(42, i1.get_int());
+
+ nsTArray<int> i2a = i2.get_ArrayOfint().Clone();
+ EXPECT_EQ(3u, i2a.Length());
+ EXPECT_EQ(1, i2a[0]);
+ EXPECT_EQ(2, i2a[1]);
+ EXPECT_EQ(3, i2a[2]);
+
+ const auto& a = i3.get_ArrayOfPTestDataStructuresSub();
+ EXPECT_EQ(a.Length(), kids.Length());
+ for (size_t i = 0; i < a.Length(); ++i) {
+ EXPECT_EQ(a[i], kids[i]);
+ }
+
+ *o1 = 42;
+ *o2 = i2a;
+ *o3 = kids.Clone();
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestArrayOfUnionWithActors(
+ nsTArray<Actors>&& i1, nsTArray<Actors>* o1) final override {
+ EXPECT_EQ(3u, i1.Length());
+ EXPECT_EQ(42, i1[0].get_int());
+
+ const nsTArray<int>& i2a = i1[1].get_ArrayOfint();
+ EXPECT_EQ(3u, i2a.Length());
+ EXPECT_EQ(1, i2a[0]);
+ EXPECT_EQ(2, i2a[1]);
+ EXPECT_EQ(3, i2a[2]);
+
+ EXPECT_EQ(kids, i1[2].get_ArrayOfPTestDataStructuresSub());
+
+ *o1 = std::move(i1);
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestUnions(const Unions& i1, const Unions& i2, const Unions& i3,
+ const Unions& i4, Unions* o1, Unions* o2, Unions* o3,
+ Unions* o4) final override {
+ EXPECT_EQ(42, i1.get_int());
+
+ const nsTArray<int>& i2a = i2.get_ArrayOfint();
+ EXPECT_EQ(3u, i2a.Length());
+ EXPECT_EQ(1, i2a[0]);
+ EXPECT_EQ(2, i2a[1]);
+ EXPECT_EQ(3, i2a[2]);
+
+ EXPECT_EQ(kids, i3.get_ArrayOfPTestDataStructuresSub());
+
+ const auto& i4a =
+ i4.get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub();
+ EXPECT_EQ(kids, i4a);
+
+ *o1 = i1;
+ *o2 = i2;
+ *o3 = i3;
+ *o4 = i4;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestArrayOfUnions(nsTArray<Unions>&& i1,
+ nsTArray<Unions>* o1) final override {
+ EXPECT_EQ(42, i1[0].get_int());
+
+ const nsTArray<int>& i2a = i1[1].get_ArrayOfint();
+ EXPECT_EQ(3u, i2a.Length());
+ EXPECT_EQ(1, i2a[0]);
+ EXPECT_EQ(2, i2a[1]);
+ EXPECT_EQ(3, i2a[2]);
+
+ EXPECT_EQ(kids, i1[2].get_ArrayOfPTestDataStructuresSub());
+
+ const auto& i4a =
+ i1[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub();
+ EXPECT_EQ(kids, i4a);
+
+ *o1 = std::move(i1);
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestStruct(const SIntDouble& i, SIntDouble* o) final override {
+ EXPECT_EQ(1, i.i());
+ EXPECT_EQ(2.0, i.d());
+ *o = i;
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestStructWithArrays(const SIntDoubleArrays& i,
+ SIntDoubleArrays* o) final override {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ nsTArray<double> ad;
+ ad.AppendElement(.5);
+ ad.AppendElement(1.0);
+ ad.AppendElement(2.0);
+
+ EXPECT_EQ(42, i.i());
+ EXPECT_EQ(ai, i.ai());
+ EXPECT_EQ(ad, i.ad());
+
+ *o = i;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestStructWithActors(const SActors& i,
+ SActors* o) final override {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ EXPECT_EQ(42, i.i());
+ EXPECT_EQ(ai, i.ai());
+ EXPECT_EQ(kids, i.ap());
+
+ *o = i;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestStructs(const Structs& i, Structs* o) final override {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ EXPECT_EQ(42, i.i());
+ EXPECT_EQ(ai, i.ai());
+ EXPECT_EQ(kids, i.ap());
+
+ const SActors& ia = i.aa()[0];
+ EXPECT_EQ(42, ia.i());
+ EXPECT_EQ(ai, ia.ai());
+ EXPECT_EQ(kids, ia.ap());
+
+ *o = i;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestUnionWithStructs(
+ const WithStructs& i1, const WithStructs& i2, const WithStructs& i3,
+ const WithStructs& i4, const WithStructs& i5, WithStructs* o1,
+ WithStructs* o2, WithStructs* o3, WithStructs* o4,
+ WithStructs* o5) final override {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ EXPECT_EQ(i1, int(42));
+ EXPECT_EQ(i2.get_ArrayOfint(), ai);
+ EXPECT_EQ(i3.get_ArrayOfPTestDataStructuresSub(), kids);
+
+ const SActors& ia = i4.get_ArrayOfSActors()[0];
+ EXPECT_EQ(42, ia.i());
+ EXPECT_EQ(ai, ia.ai());
+ EXPECT_EQ(kids, ia.ap());
+
+ const Structs& is = i5.get_ArrayOfStructs()[0];
+ EXPECT_EQ(42, is.i());
+ EXPECT_EQ(ai, is.ai());
+ EXPECT_EQ(kids, is.ap());
+
+ const SActors& isa = is.aa()[0];
+ EXPECT_EQ(42, isa.i());
+ EXPECT_EQ(ai, isa.ai());
+ EXPECT_EQ(kids, isa.ap());
+
+ *o1 = i1;
+ *o2 = i2;
+ *o3 = i3;
+ *o4 = i4;
+ *o5 = i5;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestStructWithUnions(const WithUnions& i,
+ WithUnions* o) final override {
+ EXPECT_EQ(i.i(), 42);
+
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+ EXPECT_EQ(ai, i.ai());
+
+ EXPECT_EQ(i.ap(), kids);
+
+ EXPECT_EQ(kids, i.aa()[0].get_ArrayOfPTestDataStructuresSub());
+
+ const nsTArray<Unions>& iau = i.au();
+ EXPECT_EQ(iau[0], 42);
+ EXPECT_EQ(ai, iau[1].get_ArrayOfint());
+ EXPECT_EQ(kids, iau[2].get_ArrayOfPTestDataStructuresSub());
+ EXPECT_EQ(
+ kids,
+ iau[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub());
+
+ *o = i;
+
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestUnionWithCxx(nsTArray<Op>&& sa) final override {
+ EXPECT_EQ(sa.Length(), (size_t)1);
+ EXPECT_EQ(Op::TSetAttrs, sa[0].type());
+ return IPC_OK();
+ }
+
+ IPCResult RecvTestNsIntRegion(RegionArray&& ra) final override {
+ for (RegionArray::index_type i = 0; i < ra.Length(); ++i) {
+ // if |ra| has been realloc()d and given a different allocator
+ // chunk, this loop will nondeterministically crash or iloop.
+ for (auto iter = ra[i].RectIter(); !iter.Done(); iter.Next()) {
+ Unused << iter.Get();
+ }
+ }
+ return IPC_OK();
+ }
+
+ ~TestDataStructuresParent() = default;
+};
+
+class TestDataStructuresChild : public PTestDataStructuresChild {
+ NS_INLINE_DECL_REFCOUNTING(TestDataStructuresChild, override)
+
+ private:
+ nsTArray<NotNull<
+ SideVariant<PTestDataStructuresSubParent*, PTestDataStructuresSubChild*>>>
+ kids;
+ nsTArray<NotNull<PTestDataStructuresSubChild*>> kidsDirect;
+
+ already_AddRefed<PTestDataStructuresSubChild>
+ AllocPTestDataStructuresSubChild(const int& i) final override {
+ auto child = MakeRefPtr<TestDataStructuresSubChild>(i);
+ kids.AppendElement(WrapNotNull(child));
+ kidsDirect.AppendElement(WrapNotNull(child));
+ return child.forget();
+ }
+
+ IPCResult RecvStart() final override {
+ TestArrayOfInt();
+ TestArrayOfActor();
+ TestUnion();
+ TestArrayOfUnion();
+ TestUnionWithArray();
+ TestArrayOfUnionWithArray();
+ TestStructWithActor();
+ TestUnionWithActors();
+ TestArrayOfUnionWithActors();
+ TestUnions();
+ TestArrayOfUnions();
+ TestStruct();
+ TestStructWithArrays();
+ TestStructWithActors();
+ TestStructs();
+ TestUnionWithStructs();
+ TestStructWithUnions();
+ TestUnionWithCxx();
+ TestNsIntRegion();
+
+ auto actors = kidsDirect.Clone();
+ for (auto& actor : actors) {
+ EXPECT_TRUE(PTestDataStructuresSubChild::Send__delete__(actor));
+ }
+
+ Close();
+
+ return IPC_OK();
+ }
+
+ void TestArrayOfInt() {
+ nsTArray<int> ia;
+
+ for (int i = 0; i < 5; ++i) ia.AppendElement(i);
+
+ nsTArray<int> oa;
+ EXPECT_TRUE(SendTestArrayOfInt(ia, &oa));
+
+ EXPECT_EQ(ia, oa);
+ }
+
+ void TestArrayOfActor() {
+ nsTArray<NotNull<PTestDataStructuresSubChild*>> oa;
+ EXPECT_TRUE(SendTestArrayOfActor(kidsDirect, &oa));
+ EXPECT_EQ(kidsDirect, oa);
+ }
+
+ void TestUnion() {
+ int i1i = 42;
+ double i2d = 4.0;
+ IntDouble i1(i1i);
+ IntDouble i2(i2d);
+ IntDouble o1, o2;
+
+ SendTestUnion(i1, i2, &o1, &o2);
+
+ EXPECT_EQ(i1i, o1.get_int());
+ EXPECT_EQ(i2d, o2.get_double());
+ }
+
+ void TestArrayOfUnion() {
+ nsTArray<IntDouble> i1;
+ i1.AppendElement(IntDouble(int(1)));
+ i1.AppendElement(IntDouble(2.0));
+ i1.AppendElement(IntDouble(int(3)));
+ i1.AppendElement(IntDouble(4.0));
+
+ nsTArray<IntDouble> o1;
+ EXPECT_TRUE(SendTestArrayOfUnion(i1, &o1));
+
+ // TODO Union::operator==()
+ EXPECT_EQ(i1.Length(), o1.Length());
+ EXPECT_EQ(1, o1[0].get_int());
+ EXPECT_EQ(2.0, o1[1].get_double());
+ EXPECT_EQ(3, o1[2].get_int());
+ EXPECT_EQ(4.0, o1[3].get_double());
+ }
+
+ void TestUnionWithArray() {
+ IntDoubleArrays i1(int(42));
+ nsTArray<int> i2;
+ i2.AppendElement(1);
+ i2.AppendElement(2);
+ i2.AppendElement(3);
+ nsTArray<double> i3;
+ i3.AppendElement(1.0);
+ i3.AppendElement(2.0);
+ i3.AppendElement(3.0);
+
+ IntDoubleArrays o1, o2, o3;
+ EXPECT_TRUE(SendTestUnionWithArray(i1, IntDoubleArrays(i2),
+ IntDoubleArrays(i3), &o1, &o2, &o3));
+
+ EXPECT_EQ(42, o1.get_int());
+ EXPECT_EQ(i2, o2.get_ArrayOfint());
+ EXPECT_EQ(i3, o3.get_ArrayOfdouble());
+ }
+
+ void TestArrayOfUnionWithArray() {
+ IntDoubleArrays id1(int(42));
+ nsTArray<int> id2;
+ id2.AppendElement(1);
+ id2.AppendElement(2);
+ id2.AppendElement(3);
+ nsTArray<double> id3;
+ id3.AppendElement(1.0);
+ id3.AppendElement(2.0);
+ id3.AppendElement(3.0);
+
+ nsTArray<IntDoubleArrays> i1;
+ i1.AppendElement(id1);
+ i1.AppendElement(IntDoubleArrays(id2));
+ i1.AppendElement(IntDoubleArrays(id3));
+
+ nsTArray<IntDoubleArrays> o1;
+ EXPECT_TRUE(SendTestArrayOfUnionWithArray(i1, &o1));
+
+ EXPECT_EQ(3u, o1.Length());
+ IntDoubleArrays od1(o1[0]);
+ nsTArray<int> od2 = o1[1].get_ArrayOfint().Clone();
+ nsTArray<double> od3 = o1[2].get_ArrayOfdouble().Clone();
+
+ EXPECT_EQ(42, od1.get_int());
+ EXPECT_EQ(id2, od2);
+ EXPECT_EQ(id3, od3);
+ }
+
+ void TestStructWithActor() {
+ ActorWrapper iaw(kidsDirect[0]);
+
+ ActorWrapper oaw;
+ EXPECT_TRUE(SendTestStructWithActor(iaw, &oaw));
+
+ EXPECT_TRUE(oaw.actor().IsChild());
+ EXPECT_EQ(oaw.actor().AsChild(), kidsDirect[0]);
+ }
+
+ void TestUnionWithActors() {
+ Actors i1(42);
+ nsTArray<int> i2a;
+ i2a.AppendElement(1);
+ i2a.AppendElement(2);
+ i2a.AppendElement(3);
+
+ Actors o1, o2, o3;
+ EXPECT_TRUE(
+ SendTestUnionWithActors(i1, Actors(i2a), Actors(kids), &o1, &o2, &o3));
+
+ EXPECT_EQ(42, o1.get_int());
+ EXPECT_EQ(i2a, o2.get_ArrayOfint());
+ EXPECT_EQ(kids, o3.get_ArrayOfPTestDataStructuresSub());
+ }
+
+ void TestArrayOfUnionWithActors() {
+ Actors i1e(42);
+ nsTArray<int> i2a;
+ i2a.AppendElement(1);
+ i2a.AppendElement(2);
+ i2a.AppendElement(3);
+
+ nsTArray<Actors> i1;
+ i1.AppendElement(i1e);
+ i1.AppendElement(i2a);
+ i1.AppendElement(kids);
+
+ nsTArray<Actors> o1;
+ EXPECT_TRUE(SendTestArrayOfUnionWithActors(i1, &o1));
+
+ EXPECT_EQ(3u, o1.Length());
+ EXPECT_EQ(42, o1[0].get_int());
+ EXPECT_EQ(i2a, o1[1].get_ArrayOfint());
+ EXPECT_EQ(kids, o1[2].get_ArrayOfPTestDataStructuresSub());
+ }
+
+ void TestUnions() {
+ Unions i1(int(42));
+
+ nsTArray<int> i2a;
+ i2a.AppendElement(1);
+ i2a.AppendElement(2);
+ i2a.AppendElement(3);
+
+ nsTArray<Actors> i4a;
+ i4a.AppendElement(kids);
+
+ Unions o1, o2, o3, o4;
+ EXPECT_TRUE(SendTestUnions(i1, Unions(i2a), Unions(kids), Unions(i4a), &o1,
+ &o2, &o3, &o4));
+
+ EXPECT_EQ(42, o1.get_int());
+ EXPECT_EQ(i2a, o2.get_ArrayOfint());
+ EXPECT_EQ(kids, o3.get_ArrayOfPTestDataStructuresSub());
+ EXPECT_EQ(kids,
+ o4.get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub());
+ }
+
+ void TestArrayOfUnions() {
+ Unions i1a(int(42));
+
+ nsTArray<int> i2a;
+ i2a.AppendElement(1);
+ i2a.AppendElement(2);
+ i2a.AppendElement(3);
+
+ nsTArray<Actors> i4a;
+ i4a.AppendElement(kids);
+
+ nsTArray<Unions> i1;
+ i1.AppendElement(i1a);
+ i1.AppendElement(Unions(i2a));
+ i1.AppendElement(Unions(kids));
+ i1.AppendElement(Unions(i4a));
+
+ nsTArray<Unions> o1;
+ EXPECT_TRUE(SendTestArrayOfUnions(i1, &o1));
+
+ EXPECT_EQ(4u, o1.Length());
+ EXPECT_EQ(42, o1[0].get_int());
+ EXPECT_EQ(i2a, o1[1].get_ArrayOfint());
+ EXPECT_EQ(kids, o1[2].get_ArrayOfPTestDataStructuresSub());
+ EXPECT_EQ(kids,
+ o1[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub());
+ }
+
+ void TestStruct() {
+ SIntDouble i(1, 2.0);
+ SIntDouble o;
+
+ EXPECT_TRUE(SendTestStruct(i, &o));
+
+ EXPECT_EQ(o.i(), 1);
+ EXPECT_EQ(o.d(), 2.0);
+ }
+
+ void TestStructWithArrays() {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ nsTArray<double> ad;
+ ad.AppendElement(.5);
+ ad.AppendElement(1.0);
+ ad.AppendElement(2.0);
+
+ SIntDoubleArrays i(42, ai, ad);
+ SIntDoubleArrays o;
+
+ EXPECT_TRUE(SendTestStructWithArrays(i, &o));
+
+ EXPECT_EQ(42, o.i());
+ EXPECT_EQ(ai, o.ai());
+ EXPECT_EQ(ad, o.ad());
+ }
+
+ void TestStructWithActors() {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ SActors i;
+ i.i() = 42;
+ i.ai() = ai.Clone();
+ i.ap() = kids.Clone();
+
+ SActors o;
+ EXPECT_TRUE(SendTestStructWithActors(i, &o));
+
+ EXPECT_EQ(42, o.i());
+ EXPECT_EQ(ai, o.ai());
+ EXPECT_EQ(kids, o.ap());
+ }
+
+ void TestStructs() {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ SActors ia;
+ ia.i() = 42;
+ ia.ai() = ai.Clone();
+ ia.ap() = kids.Clone();
+ nsTArray<SActors> aa;
+ aa.AppendElement(ia);
+
+ Structs i;
+ i.i() = 42;
+ i.ai() = ai.Clone();
+ i.ap() = kids.Clone();
+ i.aa() = aa.Clone();
+
+ Structs o;
+ EXPECT_TRUE(SendTestStructs(i, &o));
+
+ EXPECT_EQ(42, o.i());
+ EXPECT_EQ(ai, o.ai());
+ EXPECT_EQ(kids, o.ap());
+
+ const SActors& os = o.aa()[0];
+ EXPECT_EQ(42, os.i());
+ EXPECT_EQ(ai, os.ai());
+ EXPECT_EQ(kids, os.ap());
+ }
+
+ void TestUnionWithStructs() {
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+
+ SActors ia;
+ ia.i() = 42;
+ ia.ai() = ai.Clone();
+ ia.ap() = kids.Clone();
+ nsTArray<SActors> iaa;
+ iaa.AppendElement(ia);
+
+ Structs is;
+ is.i() = 42;
+ is.ai() = ai.Clone();
+ is.ap() = kids.Clone();
+ is.aa() = iaa.Clone();
+ nsTArray<Structs> isa;
+ isa.AppendElement(is);
+
+ WithStructs o1, o2, o3, o4, o5;
+ EXPECT_TRUE(SendTestUnionWithStructs(
+ WithStructs(42), WithStructs(ai), WithStructs(kids), WithStructs(iaa),
+ WithStructs(isa), &o1, &o2, &o3, &o4, &o5));
+
+ EXPECT_EQ(o1, int(42));
+ EXPECT_EQ(o2.get_ArrayOfint(), ai);
+ EXPECT_EQ(o3.get_ArrayOfPTestDataStructuresSub(), kids);
+
+ const SActors& oa = o4.get_ArrayOfSActors()[0];
+ EXPECT_EQ(42, oa.i());
+ EXPECT_EQ(ai, oa.ai());
+ EXPECT_EQ(kids, oa.ap());
+
+ const Structs& os = o5.get_ArrayOfStructs()[0];
+ EXPECT_EQ(42, os.i());
+ EXPECT_EQ(ai, os.ai());
+ EXPECT_EQ(kids, os.ap());
+
+ const SActors& osa = os.aa()[0];
+ EXPECT_EQ(42, osa.i());
+ EXPECT_EQ(ai, osa.ai());
+ EXPECT_EQ(kids, osa.ap());
+ }
+
+ void TestStructWithUnions() {
+ WithUnions i;
+
+ i.i() = 42;
+
+ nsTArray<int> ai;
+ ai.AppendElement(1);
+ ai.AppendElement(2);
+ ai.AppendElement(3);
+ i.ai() = ai.Clone();
+
+ i.ap() = kids.Clone();
+
+ nsTArray<Actors> iaa;
+ iaa.AppendElement(kids);
+ i.aa() = iaa.Clone();
+
+ nsTArray<Unions> iau;
+ iau.AppendElement(int(42));
+ iau.AppendElement(ai);
+ iau.AppendElement(kids);
+ iau.AppendElement(iaa);
+ i.au() = iau.Clone();
+
+ WithUnions o;
+ EXPECT_TRUE(SendTestStructWithUnions(i, &o));
+
+ EXPECT_EQ(42, o.i());
+ EXPECT_EQ(o.ai(), ai);
+ EXPECT_EQ(o.ap(), kids);
+
+ const Actors& oaa = o.aa()[0];
+ EXPECT_EQ(oaa.get_ArrayOfPTestDataStructuresSub(), kids);
+
+ const nsTArray<Unions>& oau = o.au();
+ EXPECT_EQ(oau[0], 42);
+ EXPECT_EQ(oau[1].get_ArrayOfint(), ai);
+ EXPECT_EQ(oau[2].get_ArrayOfPTestDataStructuresSub(), kids);
+ EXPECT_EQ(oau[3].get_ArrayOfActors()[0].get_ArrayOfPTestDataStructuresSub(),
+ kids);
+ }
+
+ void TestUnionWithCxx() {
+ Attrs attrs;
+ attrs.common() = CommonAttrs(true);
+ attrs.specific() = BarAttrs(1.0f);
+
+ nsTArray<Op> ops;
+ ops.AppendElement(SetAttrs(kids[0], attrs));
+
+ EXPECT_TRUE(SendTestUnionWithCxx(ops));
+ }
+
+ void TestNsIntRegion() {
+ const int nelements = 1000;
+ RegionArray ra;
+ // big enough to hopefully force a realloc to a different chunk of
+ // memory on the receiving side, if the workaround isn't working
+ // correctly. But SetCapacity() here because we don't want to
+ // crash on the sending side.
+ ra.SetCapacity(nelements);
+ for (int i = 0; i < nelements; ++i) {
+ nsIntRegion r;
+ r.Or(nsIntRect(0, 0, 10, 10), nsIntRect(10, 10, 10, 10));
+ ra.AppendElement(r);
+ }
+
+ EXPECT_TRUE(SendTestNsIntRegion(ra));
+ }
+
+ ~TestDataStructuresChild() = default;
+};
+
+IPDL_TEST(TestDataStructures) {
+ for (uint32_t i = 0; i < nactors; ++i) {
+ auto sub = MakeRefPtr<TestDataStructuresSubParent>(i);
+ EXPECT_TRUE(mActor->SendPTestDataStructuresSubConstructor(sub, i))
+ << "can't alloc actor";
+ mActor->kids.AppendElement(WrapNotNull(sub));
+ }
+
+ EXPECT_TRUE(mActor->SendStart()) << "can't send Start()";
+}
+
+} // namespace mozilla::_ipdltest