• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Dawn Authors
2 //
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 
17 #include "dawn/webgpu_cpp.h"
18 
19 class Object : public wgpu::ObjectBase<Object, int*> {
20   public:
21     using ObjectBase::ObjectBase;
22     using ObjectBase::operator=;
23 
WGPUReference(int * handle)24     static void WGPUReference(int* handle) {
25         ASSERT_LE(0, *handle);
26         *handle += 1;
27     }
WGPURelease(int * handle)28     static void WGPURelease(int* handle) {
29         ASSERT_LT(0, *handle);
30         *handle -= 1;
31     }
32 };
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.
TEST(ObjectBase,CTypeConstructor)36 TEST(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.
TEST(ObjectBase,AcquireConstruction)46 TEST(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 
55 // Test .Get().
TEST(ObjectBase,Get)56 TEST(ObjectBase, Get) {
57     int refcount = 1;
58     {
59         Object obj1(&refcount);
60 
61         ASSERT_EQ(2, refcount);
62         ASSERT_EQ(&refcount, obj1.Get());
63     }
64     ASSERT_EQ(1, refcount);
65 }
66 
67 // Test that Release consumes the C++ object into a C object and doesn't release
TEST(ObjectBase,Release)68 TEST(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
TEST(ObjectBase,OperatorBool)82 TEST(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 
92 // Test the copy constructor of C++ objects
TEST(ObjectBase,CopyConstructor)93 TEST(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
TEST(ObjectBase,CopyAssignment)108 TEST(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 
123 // Test the repeated copy assignment of C++ objects
TEST(ObjectBase,RepeatedCopyAssignment)124 TEST(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 
141 // Test the copy assignment of C++ objects onto themselves
TEST(ObjectBase,CopyAssignmentSelf)142 TEST(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 
155 // Test the move constructor of C++ objects
TEST(ObjectBase,MoveConstructor)156 TEST(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
TEST(ObjectBase,MoveAssignment)170 TEST(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 
185 // Test the move assignment of C++ objects onto themselves
TEST(ObjectBase,MoveAssignmentSelf)186 TEST(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 }
198 
199 // Test the constructor using nullptr
TEST(ObjectBase,NullptrConstructor)200 TEST(ObjectBase, NullptrConstructor) {
201     Object obj(nullptr);
202     ASSERT_EQ(obj.Get(), nullptr);
203 }
204 
205 // Test assigning nullptr to the object
TEST(ObjectBase,AssignNullptr)206 TEST(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 }
215