1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/win/variant_conversions.h"
6
7 #include <stdint.h>
8 #include <wrl/client.h>
9 #include <wrl/implements.h>
10
11 #include <set>
12 #include <utility>
13
14 #include "base/containers/contains.h"
15 #include "base/win/dispatch_stub.h"
16 #include "base/win/scoped_bstr.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using base::win::internal::VariantConverter;
20 using base::win::test::DispatchStub;
21
22 namespace base {
23 namespace win {
24
25 namespace {
26
27 static constexpr VARTYPE kSupportedVartypes[] = {
28 VT_BOOL, VT_I1, VT_UI1, VT_I2, VT_UI2, VT_I4, VT_UI4, VT_I8,
29 VT_UI8, VT_R4, VT_R8, VT_DATE, VT_BSTR, VT_UNKNOWN, VT_DISPATCH};
30
31 template <VARTYPE ElementVartype>
TestIsConvertibleTo(const std::set<VARTYPE> & allowed_vartypes)32 static bool TestIsConvertibleTo(const std::set<VARTYPE>& allowed_vartypes) {
33 for (VARTYPE vartype : kSupportedVartypes) {
34 if (VariantConverter<ElementVartype>::IsConvertibleTo(vartype) !=
35 base::Contains(allowed_vartypes, vartype)) {
36 return false;
37 }
38 }
39 return true;
40 }
41
42 template <VARTYPE ElementVartype>
TestIsConvertibleFrom(const std::set<VARTYPE> & allowed_vartypes)43 static bool TestIsConvertibleFrom(const std::set<VARTYPE>& allowed_vartypes) {
44 for (VARTYPE vartype : kSupportedVartypes) {
45 if (VariantConverter<ElementVartype>::IsConvertibleFrom(vartype) !=
46 base::Contains(allowed_vartypes, vartype)) {
47 return false;
48 }
49 }
50 return true;
51 }
52
53 } // namespace
54
TEST(VariantConverterTest,VariantTypeBool)55 TEST(VariantConverterTest, VariantTypeBool) {
56 VARIANT variant;
57 V_VT(&variant) = VT_BOOL;
58
59 VariantConverter<VT_BOOL>::RawSet(&variant, VARIANT_TRUE);
60 EXPECT_EQ(V_BOOL(&variant), VARIANT_TRUE);
61 EXPECT_EQ(VariantConverter<VT_BOOL>::RawGet(variant), VARIANT_TRUE);
62
63 const std::set<VARTYPE> allowed_vartypes = {VT_BOOL};
64 EXPECT_TRUE(TestIsConvertibleTo<VT_BOOL>(allowed_vartypes));
65 EXPECT_TRUE(TestIsConvertibleFrom<VT_BOOL>(allowed_vartypes));
66 }
67
TEST(VariantConverterTest,VariantTypeI1)68 TEST(VariantConverterTest, VariantTypeI1) {
69 VARIANT variant;
70 V_VT(&variant) = VT_I1;
71
72 VariantConverter<VT_I1>::RawSet(&variant, 34);
73 EXPECT_EQ(V_I1(&variant), 34);
74 EXPECT_EQ(VariantConverter<VT_I1>::RawGet(variant), 34);
75
76 const std::set<VARTYPE> allowed_vartypes = {VT_I1};
77 EXPECT_TRUE(TestIsConvertibleTo<VT_I1>(allowed_vartypes));
78 EXPECT_TRUE(TestIsConvertibleFrom<VT_I1>(allowed_vartypes));
79 }
80
TEST(VariantConverterTest,VariantTypeUI1)81 TEST(VariantConverterTest, VariantTypeUI1) {
82 VARIANT variant;
83 V_VT(&variant) = VT_UI1;
84
85 VariantConverter<VT_UI1>::RawSet(&variant, 34U);
86 EXPECT_EQ(V_UI1(&variant), 34U);
87 EXPECT_EQ(VariantConverter<VT_UI1>::RawGet(variant), 34U);
88
89 const std::set<VARTYPE> allowed_vartypes = {VT_UI1};
90 EXPECT_TRUE(TestIsConvertibleTo<VT_UI1>(allowed_vartypes));
91 EXPECT_TRUE(TestIsConvertibleFrom<VT_UI1>(allowed_vartypes));
92 }
93
TEST(VariantConverterTest,VariantTypeI2)94 TEST(VariantConverterTest, VariantTypeI2) {
95 VARIANT variant;
96 V_VT(&variant) = VT_I2;
97
98 VariantConverter<VT_I2>::RawSet(&variant, 8738);
99 EXPECT_EQ(V_I2(&variant), 8738);
100 EXPECT_EQ(VariantConverter<VT_I2>::RawGet(variant), 8738);
101
102 const std::set<VARTYPE> allowed_vartypes = {VT_I2};
103 EXPECT_TRUE(TestIsConvertibleTo<VT_I2>(allowed_vartypes));
104 EXPECT_TRUE(TestIsConvertibleFrom<VT_I2>(allowed_vartypes));
105 }
106
TEST(VariantConverterTest,VariantTypeUI2)107 TEST(VariantConverterTest, VariantTypeUI2) {
108 VARIANT variant;
109 V_VT(&variant) = VT_UI2;
110
111 VariantConverter<VT_UI2>::RawSet(&variant, 8738U);
112 EXPECT_EQ(V_UI2(&variant), 8738U);
113 EXPECT_EQ(VariantConverter<VT_UI2>::RawGet(variant), 8738U);
114
115 const std::set<VARTYPE> allowed_vartypes = {VT_UI2};
116 EXPECT_TRUE(TestIsConvertibleTo<VT_UI2>(allowed_vartypes));
117 EXPECT_TRUE(TestIsConvertibleFrom<VT_UI2>(allowed_vartypes));
118 }
119
TEST(VariantConverterTest,VariantTypeI4)120 TEST(VariantConverterTest, VariantTypeI4) {
121 VARIANT variant;
122 V_VT(&variant) = VT_I4;
123
124 VariantConverter<VT_I4>::RawSet(&variant, 572662306);
125 EXPECT_EQ(V_I4(&variant), 572662306);
126 EXPECT_EQ(VariantConverter<VT_I4>::RawGet(variant), 572662306);
127
128 const std::set<VARTYPE> allowed_vartypes = {VT_I4};
129 EXPECT_TRUE(TestIsConvertibleTo<VT_I4>(allowed_vartypes));
130 EXPECT_TRUE(TestIsConvertibleFrom<VT_I4>(allowed_vartypes));
131 }
132
TEST(VariantConverterTest,VariantTypeUI4)133 TEST(VariantConverterTest, VariantTypeUI4) {
134 VARIANT variant;
135 V_VT(&variant) = VT_UI4;
136
137 VariantConverter<VT_UI4>::RawSet(&variant, 572662306U);
138 EXPECT_EQ(V_UI4(&variant), 572662306U);
139 EXPECT_EQ(VariantConverter<VT_UI4>::RawGet(variant), 572662306U);
140
141 const std::set<VARTYPE> allowed_vartypes = {VT_UI4};
142 EXPECT_TRUE(TestIsConvertibleTo<VT_UI4>(allowed_vartypes));
143 EXPECT_TRUE(TestIsConvertibleFrom<VT_UI4>(allowed_vartypes));
144 }
145
TEST(VariantConverterTest,VariantTypeI8)146 TEST(VariantConverterTest, VariantTypeI8) {
147 VARIANT variant;
148 V_VT(&variant) = VT_I8;
149
150 VariantConverter<VT_I8>::RawSet(&variant, 2459565876494606882);
151 EXPECT_EQ(V_I8(&variant), 2459565876494606882);
152 EXPECT_EQ(VariantConverter<VT_I8>::RawGet(variant), 2459565876494606882);
153
154 const std::set<VARTYPE> allowed_vartypes = {VT_I8};
155 EXPECT_TRUE(TestIsConvertibleTo<VT_I8>(allowed_vartypes));
156 EXPECT_TRUE(TestIsConvertibleFrom<VT_I8>(allowed_vartypes));
157 }
158
TEST(VariantConverterTest,VariantTypeUI8)159 TEST(VariantConverterTest, VariantTypeUI8) {
160 VARIANT variant;
161 V_VT(&variant) = VT_UI8;
162
163 VariantConverter<VT_UI8>::RawSet(&variant, 2459565876494606882U);
164 EXPECT_EQ(V_UI8(&variant), 2459565876494606882U);
165 EXPECT_EQ(VariantConverter<VT_UI8>::RawGet(variant), 2459565876494606882U);
166
167 const std::set<VARTYPE> allowed_vartypes = {VT_UI8};
168 EXPECT_TRUE(TestIsConvertibleTo<VT_UI8>(allowed_vartypes));
169 EXPECT_TRUE(TestIsConvertibleFrom<VT_UI8>(allowed_vartypes));
170 }
171
TEST(VariantConverterTest,VariantTypeR4)172 TEST(VariantConverterTest, VariantTypeR4) {
173 VARIANT variant;
174 V_VT(&variant) = VT_R4;
175
176 VariantConverter<VT_R4>::RawSet(&variant, 3.14159f);
177 EXPECT_EQ(V_R4(&variant), 3.14159f);
178 EXPECT_EQ(VariantConverter<VT_R4>::RawGet(variant), 3.14159f);
179
180 const std::set<VARTYPE> allowed_vartypes = {VT_R4};
181 EXPECT_TRUE(TestIsConvertibleTo<VT_R4>(allowed_vartypes));
182 EXPECT_TRUE(TestIsConvertibleFrom<VT_R4>(allowed_vartypes));
183 }
184
TEST(VariantConverterTest,VariantTypeR8)185 TEST(VariantConverterTest, VariantTypeR8) {
186 VARIANT variant;
187 V_VT(&variant) = VT_R8;
188
189 VariantConverter<VT_R8>::RawSet(&variant, 3.14159);
190 EXPECT_EQ(V_R8(&variant), 3.14159);
191 EXPECT_EQ(VariantConverter<VT_R8>::RawGet(variant), 3.14159);
192
193 const std::set<VARTYPE> allowed_vartypes = {VT_R8};
194 EXPECT_TRUE(TestIsConvertibleTo<VT_R8>(allowed_vartypes));
195 EXPECT_TRUE(TestIsConvertibleFrom<VT_R8>(allowed_vartypes));
196 }
197
TEST(VariantConverterTest,VariantTypeDate)198 TEST(VariantConverterTest, VariantTypeDate) {
199 SYSTEMTIME sys_time;
200 ::GetSystemTime(&sys_time);
201 DATE date;
202 ::SystemTimeToVariantTime(&sys_time, &date);
203
204 VARIANT variant;
205 V_VT(&variant) = VT_DATE;
206
207 VariantConverter<VT_DATE>::RawSet(&variant, date);
208 EXPECT_EQ(V_DATE(&variant), date);
209 EXPECT_EQ(VariantConverter<VT_DATE>::RawGet(variant), date);
210
211 const std::set<VARTYPE> allowed_vartypes = {VT_DATE};
212 EXPECT_TRUE(TestIsConvertibleTo<VT_DATE>(allowed_vartypes));
213 EXPECT_TRUE(TestIsConvertibleFrom<VT_DATE>(allowed_vartypes));
214 }
215
TEST(VariantConverterTest,VariantTypeBstr)216 TEST(VariantConverterTest, VariantTypeBstr) {
217 ScopedBstr scoped_bstr;
218 scoped_bstr.Allocate(L"some text");
219
220 VARIANT variant;
221 V_VT(&variant) = VT_BSTR;
222
223 VariantConverter<VT_BSTR>::RawSet(&variant, scoped_bstr.Get());
224 EXPECT_EQ(V_BSTR(&variant), scoped_bstr.Get());
225 EXPECT_EQ(VariantConverter<VT_BSTR>::RawGet(variant), scoped_bstr.Get());
226
227 const std::set<VARTYPE> allowed_vartypes = {VT_BSTR};
228 EXPECT_TRUE(TestIsConvertibleTo<VT_BSTR>(allowed_vartypes));
229 EXPECT_TRUE(TestIsConvertibleFrom<VT_BSTR>(allowed_vartypes));
230 }
231
TEST(VariantConverterTest,VariantTypeUnknown)232 TEST(VariantConverterTest, VariantTypeUnknown) {
233 Microsoft::WRL::ComPtr<IUnknown> unknown =
234 Microsoft::WRL::Make<DispatchStub>();
235
236 VARIANT variant;
237 V_VT(&variant) = VT_UNKNOWN;
238
239 VariantConverter<VT_UNKNOWN>::RawSet(&variant, unknown.Get());
240 EXPECT_EQ(V_UNKNOWN(&variant), unknown.Get());
241 EXPECT_EQ(VariantConverter<VT_UNKNOWN>::RawGet(variant), unknown.Get());
242
243 const std::set<VARTYPE> allow_convertible_to = {VT_UNKNOWN};
244 const std::set<VARTYPE> allow_convertible_from = {VT_UNKNOWN, VT_DISPATCH};
245 EXPECT_TRUE(TestIsConvertibleTo<VT_UNKNOWN>(allow_convertible_to));
246 EXPECT_TRUE(TestIsConvertibleFrom<VT_UNKNOWN>(allow_convertible_from));
247 }
248
TEST(VariantConverterTest,VariantTypeDispatch)249 TEST(VariantConverterTest, VariantTypeDispatch) {
250 Microsoft::WRL::ComPtr<IDispatch> dispatch =
251 Microsoft::WRL::Make<DispatchStub>();
252
253 VARIANT variant;
254 V_VT(&variant) = VT_DISPATCH;
255
256 VariantConverter<VT_DISPATCH>::RawSet(&variant, dispatch.Get());
257 EXPECT_EQ(V_DISPATCH(&variant), dispatch.Get());
258 EXPECT_EQ(VariantConverter<VT_DISPATCH>::RawGet(variant), dispatch.Get());
259
260 const std::set<VARTYPE> allow_convertible_to = {VT_UNKNOWN, VT_DISPATCH};
261 const std::set<VARTYPE> allow_convertible_from = {VT_DISPATCH};
262 EXPECT_TRUE(TestIsConvertibleTo<VT_DISPATCH>(allow_convertible_to));
263 EXPECT_TRUE(TestIsConvertibleFrom<VT_DISPATCH>(allow_convertible_from));
264 }
265
266 } // namespace win
267 } // namespace base
268