Make initializer methods pure
[hiphop-php.git] / hphp / runtime / test / variant.cpp
blob4b696b5162624b228d675de84d5c6ece48284866
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include <gtest/gtest.h>
19 #include "hphp/runtime/base/comparisons.h"
20 #include "hphp/runtime/base/type-variant.h"
21 #include "hphp/runtime/base/dummy-resource.h"
22 #include "hphp/runtime/base/file.h"
23 #include "hphp/runtime/ext/collections/ext_collections-vector.h"
24 #include "hphp/runtime/ext/collections/ext_collections-map.h"
26 namespace HPHP {
28 TEST(Variant, Conversions) {
29 Variant v("123");
30 EXPECT_TRUE(v.toInt32() == 123);
33 TEST(Variant, Refcounts) {
35 auto ptr = req::make<DummyResource>();
36 EXPECT_TRUE(ptr->hasExactlyOneRef());
37 Variant v(std::move(ptr));
38 auto& res = v.asCResRef();
39 EXPECT_TRUE(res->hasExactlyOneRef());
43 auto ptr = req::make<DummyResource>();
44 EXPECT_TRUE(ptr->hasExactlyOneRef());
46 Variant v(ptr);
47 auto& res = v.asCResRef();
48 EXPECT_TRUE(res->hasMultipleRefs()); // count==2
50 EXPECT_TRUE(ptr->hasExactlyOneRef());
54 TEST(Variant, Casts) {
55 // Test Resource cast operations
57 EXPECT_FALSE(isa<DummyResource>(Variant()));
58 EXPECT_TRUE(isa_or_null<DummyResource>(Variant()));
59 EXPECT_FALSE(isa<DummyResource>(Variant(true)));
60 EXPECT_FALSE(isa_or_null<DummyResource>(Variant(true)));
62 auto dummy = req::make<DummyResource>();
63 Variant var(dummy);
64 Variant empty;
65 EXPECT_TRUE(isa<DummyResource>(var));
66 EXPECT_TRUE(isa_or_null<DummyResource>(var));
68 EXPECT_FALSE(isa<File>(var));
69 EXPECT_FALSE(isa_or_null<File>(var));
71 // cast tests
72 // Bad types and null pointers should throw.
73 EXPECT_EQ(cast<DummyResource>(var), dummy);
74 EXPECT_EQ(cast<ResourceData>(var), dummy);
75 try {
76 cast<File>(var);
77 ADD_FAILURE();
78 } catch(...) {
79 SUCCEED();
81 try {
82 cast<c_Map>(var);
83 ADD_FAILURE();
84 } catch(...) {
85 SUCCEED();
87 try {
88 cast<DummyResource>(empty);
89 ADD_FAILURE();
90 } catch(...) {
91 SUCCEED();
94 // cast_or_null tests
95 // Bad types should throw, null pointers are ok.
96 EXPECT_EQ(cast_or_null<ResourceData>(empty), nullptr);
97 EXPECT_EQ(cast_or_null<ResourceData>(var), dummy);
99 try {
100 cast_or_null<File>(var);
101 ADD_FAILURE();
102 } catch(...) {
103 SUCCEED();
105 try {
106 cast_or_null<c_Map>(var);
107 ADD_FAILURE();
108 } catch(...) {
109 SUCCEED();
112 // dyn_cast tests
113 // Bad types are ok, null pointers should throw.
114 EXPECT_EQ(dyn_cast<DummyResource>(var), dummy);
115 EXPECT_EQ(dyn_cast<ResourceData>(var), dummy);
116 EXPECT_EQ(dyn_cast<File>(var), nullptr);
117 EXPECT_EQ(dyn_cast<c_Map>(var), nullptr);
118 try {
119 dyn_cast<DummyResource>(Variant());
120 ADD_FAILURE();
121 } catch(...) {
122 SUCCEED();
125 // dyn_cast_or_null
126 // Bad types and null pointers are ok. Should never throw.
127 EXPECT_EQ(dyn_cast_or_null<ResourceData>(empty), nullptr);
128 EXPECT_EQ(dyn_cast_or_null<ResourceData>(var), dummy);
129 EXPECT_EQ(dyn_cast_or_null<c_Map>(var), nullptr);
132 // Test Object cast operations
134 EXPECT_FALSE(isa<c_Vector>(Variant()));
135 EXPECT_TRUE(isa_or_null<c_Vector>(Variant()));
136 EXPECT_FALSE(isa<c_Vector>(Variant(true)));
137 EXPECT_FALSE(isa_or_null<c_Vector>(Variant(true)));
139 auto dummy = req::make<c_Vector>();
140 Variant var(dummy);
141 Variant empty;
142 EXPECT_TRUE(isa<c_Vector>(var));
143 EXPECT_TRUE(isa_or_null<c_Vector>(var));
145 EXPECT_FALSE(isa<c_Map>(var));
146 EXPECT_FALSE(isa_or_null<c_Map>(var));
148 // cast tests
149 // Bad types and null pointers should throw.
150 EXPECT_EQ(cast<c_Vector>(var), dummy);
151 EXPECT_EQ(cast<ObjectData>(var), dummy);
152 try {
153 cast<c_Map>(var);
154 ADD_FAILURE();
155 } catch(...) {
156 SUCCEED();
158 try {
159 cast<c_Vector>(empty);
160 ADD_FAILURE();
161 } catch(...) {
162 SUCCEED();
164 try {
165 cast<File>(empty);
166 ADD_FAILURE();
167 } catch(...) {
168 SUCCEED();
171 // cast_or_null tests
172 // Bad types should throw, null pointers are ok.
173 EXPECT_EQ(cast_or_null<c_Vector>(empty), nullptr);
174 EXPECT_EQ(cast_or_null<c_Vector>(var), dummy);
176 try {
177 cast_or_null<File>(var);
178 ADD_FAILURE();
179 } catch(...) {
180 SUCCEED();
182 try {
183 cast_or_null<c_Map>(var);
184 ADD_FAILURE();
185 } catch(...) {
186 SUCCEED();
189 // dyn_cast tests
190 // Bad types are ok, null pointers should throw.
191 EXPECT_EQ(dyn_cast<c_Vector>(var), dummy);
192 EXPECT_EQ(dyn_cast<ObjectData>(var), dummy);
193 EXPECT_EQ(dyn_cast<c_Map>(var), nullptr);
194 EXPECT_EQ(dyn_cast<File>(var), nullptr);
195 try {
196 dyn_cast<c_Vector>(empty);
197 ADD_FAILURE();
198 } catch(...) {
199 SUCCEED();
202 // dyn_cast_or_null
203 // Bad types and null pointers are ok. Should never throw.
204 EXPECT_EQ(dyn_cast_or_null<c_Map>(empty), nullptr);
205 EXPECT_EQ(dyn_cast_or_null<c_Vector>(var), dummy);
206 EXPECT_EQ(dyn_cast_or_null<c_Map>(var), nullptr);
210 TEST(Variant, MoveCasts) {
212 auto res = unsafe_cast_or_null<DummyResource>(
213 Variant(req::make<DummyResource>()));
214 EXPECT_NE(res, nullptr);
215 auto res2 = dyn_cast<DummyResource>(
216 Variant(req::make<DummyResource>()));
217 EXPECT_NE(res2, nullptr);
218 auto res3 = dyn_cast<File>(
219 Variant(req::make<DummyResource>()));
220 EXPECT_EQ(res3, nullptr);
223 auto res = unsafe_cast_or_null<c_Vector>(
224 Variant(req::make<c_Vector>()));
225 EXPECT_NE(res, nullptr);
226 auto res2 = dyn_cast<c_Vector>(
227 Variant(req::make<c_Vector>()));
228 EXPECT_NE(res2, nullptr);
229 auto res3 = dyn_cast<c_Map>(
230 Variant(req::make<c_Vector>()));
231 EXPECT_EQ(res3, nullptr);