blob: 51244c7e0a3c067c174290df267b6b371052813f [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001// Copyright 2017 The Dawn Authors
Corentin Wallez2d641142017-05-30 11:10:47 -04002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <gtest/gtest.h>
16
Corentin Wallez45b51f52019-10-28 22:15:47 +000017#include "dawn/webgpu_cpp.h"
Corentin Wallez2d641142017-05-30 11:10:47 -040018
Corentin Wallez2c8b5c62019-10-21 20:04:10 +000019class Object : public wgpu::ObjectBase<Object, int*> {
20 public:
21 using ObjectBase::ObjectBase;
22 using ObjectBase::operator=;
Corentin Wallez2d641142017-05-30 11:10:47 -040023
Corentin Wallez2c8b5c62019-10-21 20:04:10 +000024 static void WGPUReference(int* handle) {
25 ASSERT_LE(0, *handle);
26 *handle += 1;
27 }
28 static void WGPURelease(int* handle) {
29 ASSERT_LT(0, *handle);
30 *handle -= 1;
31 }
Corentin Wallez2d641142017-05-30 11:10:47 -040032};
33
34// Test that creating an C++ object from a C object takes a ref.
35// Also test that the C++ object destructor removes a ref.
36TEST(ObjectBase, CTypeConstructor) {
37 int refcount = 1;
38 {
39 Object obj(&refcount);
40 ASSERT_EQ(2, refcount);
41 }
42 ASSERT_EQ(1, refcount);
43}
44
45// Test consuming a C object into a C++ object doesn't take a ref.
46TEST(ObjectBase, AcquireConstruction) {
47 int refcount = 1;
48 {
49 Object object = Object::Acquire(&refcount);
50 ASSERT_EQ(1, refcount);
51 }
52 ASSERT_EQ(0, refcount);
53}
54
Corentin Wallezaa7109c2018-10-25 10:42:49 +000055// Test .Get().
56TEST(ObjectBase, Get) {
Corentin Wallez2d641142017-05-30 11:10:47 -040057 int refcount = 1;
58 {
59 Object obj1(&refcount);
Corentin Wallez2d641142017-05-30 11:10:47 -040060
Corentin Wallezaa7109c2018-10-25 10:42:49 +000061 ASSERT_EQ(2, refcount);
Corentin Wallez2d641142017-05-30 11:10:47 -040062 ASSERT_EQ(&refcount, obj1.Get());
Corentin Wallez2d641142017-05-30 11:10:47 -040063 }
64 ASSERT_EQ(1, refcount);
65}
66
67// Test that Release consumes the C++ object into a C object and doesn't release
68TEST(ObjectBase, Release) {
69 int refcount = 1;
70 {
71 Object obj(&refcount);
72 ASSERT_EQ(2, refcount);
73
74 ASSERT_EQ(&refcount, obj.Release());
75 ASSERT_EQ(nullptr, obj.Get());
76 ASSERT_EQ(2, refcount);
77 }
78 ASSERT_EQ(2, refcount);
79}
80
81// Test using C++ objects in conditions
82TEST(ObjectBase, OperatorBool) {
83 int refcount = 1;
84 Object trueObj(&refcount);
85 Object falseObj;
86
87 if (falseObj || !trueObj) {
88 ASSERT_TRUE(false);
89 }
90}
91
Corentin Wallezaa7109c2018-10-25 10:42:49 +000092// Test the copy constructor of C++ objects
93TEST(ObjectBase, CopyConstructor) {
94 int refcount = 1;
95
96 Object source(&refcount);
97 Object destination(source);
98
99 ASSERT_EQ(source.Get(), &refcount);
100 ASSERT_EQ(destination.Get(), &refcount);
101 ASSERT_EQ(3, refcount);
102
103 destination = Object();
104 ASSERT_EQ(refcount, 2);
105}
106
107// Test the copy assignment of C++ objects
108TEST(ObjectBase, CopyAssignment) {
109 int refcount = 1;
110 Object source(&refcount);
111
112 Object destination;
113 destination = source;
114
115 ASSERT_EQ(source.Get(), &refcount);
116 ASSERT_EQ(destination.Get(), &refcount);
117 ASSERT_EQ(3, refcount);
118
119 destination = Object();
120 ASSERT_EQ(refcount, 2);
121}
122
Ben Claytondb7def52021-06-28 10:26:08 +0000123// Test the repeated copy assignment of C++ objects
124TEST(ObjectBase, RepeatedCopyAssignment) {
125 int refcount = 1;
126 Object source(&refcount);
127
128 Object destination;
129 for (int i = 0; i < 10; i++) {
130 destination = source;
131 }
132
133 ASSERT_EQ(source.Get(), &refcount);
134 ASSERT_EQ(destination.Get(), &refcount);
135 ASSERT_EQ(3, refcount);
136
137 destination = Object();
138 ASSERT_EQ(refcount, 2);
139}
140
Corentin Wallezaa7109c2018-10-25 10:42:49 +0000141// Test the copy assignment of C++ objects onto themselves
142TEST(ObjectBase, CopyAssignmentSelf) {
143 int refcount = 1;
144
145 Object obj(&refcount);
146
147 // Fool the compiler to avoid a -Wself-assign-overload
148 Object* objPtr = &obj;
149 obj = *objPtr;
150
151 ASSERT_EQ(obj.Get(), &refcount);
152 ASSERT_EQ(refcount, 2);
153}
154
Corentin Wallez2d641142017-05-30 11:10:47 -0400155// Test the move constructor of C++ objects
156TEST(ObjectBase, MoveConstructor) {
157 int refcount = 1;
158 Object source(&refcount);
159 Object destination(std::move(source));
160
161 ASSERT_EQ(source.Get(), nullptr);
162 ASSERT_EQ(destination.Get(), &refcount);
163 ASSERT_EQ(2, refcount);
164
165 destination = Object();
166 ASSERT_EQ(refcount, 1);
167}
168
169// Test the move assignment of C++ objects
170TEST(ObjectBase, MoveAssignment) {
171 int refcount = 1;
172 Object source(&refcount);
173
174 Object destination;
175 destination = std::move(source);
176
177 ASSERT_EQ(source.Get(), nullptr);
178 ASSERT_EQ(destination.Get(), &refcount);
179 ASSERT_EQ(2, refcount);
180
181 destination = Object();
182 ASSERT_EQ(refcount, 1);
183}
184
Corentin Wallezaa7109c2018-10-25 10:42:49 +0000185// Test the move assignment of C++ objects onto themselves
186TEST(ObjectBase, MoveAssignmentSelf) {
187 int refcount = 1;
188
189 Object obj(&refcount);
190
191 // Fool the compiler to avoid a -Wself-move
192 Object* objPtr = &obj;
193 obj = std::move(*objPtr);
194
195 ASSERT_EQ(obj.Get(), &refcount);
196 ASSERT_EQ(refcount, 2);
197}
Corentin Wallezf48e6b72018-12-04 12:13:03 +0000198
199// Test the constructor using nullptr
200TEST(ObjectBase, NullptrConstructor) {
201 Object obj(nullptr);
202 ASSERT_EQ(obj.Get(), nullptr);
203}
204
205// Test assigning nullptr to the object
206TEST(ObjectBase, AssignNullptr) {
207 int refcount = 1;
208
209 Object obj(&refcount);
210 ASSERT_EQ(refcount, 2);
211
212 obj = nullptr;
213 ASSERT_EQ(refcount, 1);
214}