OLD | NEW |
| (Empty) |
1 // Copyright 2009 Google Inc. | |
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 | |
16 #include "omaha/plugins/update/npapi/variant_utils.h" | |
17 #include <atlbase.h> | |
18 #include <string.h> | |
19 #include <stdlib.h> | |
20 #include "omaha/plugins/update/npapi/testing/dispatch_host_test_interface.h" | |
21 #include "omaha/plugins/update/npapi/testing/stubs.h" | |
22 #include "omaha/testing/unit_test.h" | |
23 | |
24 namespace omaha { | |
25 | |
26 class VariantUtilsTest : public testing::Test { | |
27 protected: | |
28 virtual void SetUp() { | |
29 VOID_TO_NPVARIANT(np_variant_); | |
30 } | |
31 | |
32 virtual void TearDown() { | |
33 NPN_ReleaseVariantValue(&np_variant_); | |
34 } | |
35 | |
36 void TestNPV2V() { | |
37 NPVariantToVariant(NULL, np_variant_, &variant_); | |
38 ExpectTypesEquivalent(); | |
39 } | |
40 | |
41 void TestV2NPV() { | |
42 NPN_ReleaseVariantValue(&np_variant_); | |
43 VariantToNPVariant(NULL, variant_, &np_variant_); | |
44 ExpectTypesEquivalent(); | |
45 } | |
46 | |
47 void ExpectTypesEquivalent() { | |
48 switch (V_VT(&variant_)) { | |
49 case VT_EMPTY: | |
50 EXPECT_TRUE(NPVARIANT_IS_VOID(np_variant_)); | |
51 return; | |
52 break; | |
53 case VT_NULL: | |
54 EXPECT_TRUE(NPVARIANT_IS_NULL(np_variant_)); | |
55 return; | |
56 break; | |
57 case VT_BOOL: | |
58 EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(np_variant_)); | |
59 return; | |
60 break; | |
61 case VT_I4: | |
62 case VT_UI4: | |
63 EXPECT_TRUE(NPVARIANT_IS_INT32(np_variant_)); | |
64 return; | |
65 break; | |
66 case VT_R8: | |
67 EXPECT_TRUE(NPVARIANT_IS_DOUBLE(np_variant_)); | |
68 return; | |
69 break; | |
70 case VT_BSTR: | |
71 EXPECT_TRUE(NPVARIANT_IS_STRING(np_variant_)); | |
72 return; | |
73 break; | |
74 case VT_DISPATCH: | |
75 EXPECT_TRUE(NPVARIANT_IS_OBJECT(np_variant_)); | |
76 return; | |
77 break; | |
78 default: | |
79 break; | |
80 } | |
81 ASSERT(false, (L"Expected equivalent types but got the following instead:\n" | |
82 L" np_variant_.type -> %d\n V_VT(&variant_) -> %d\n", | |
83 np_variant_.type, V_VT(&variant_))); | |
84 } | |
85 | |
86 NPVariant np_variant_; | |
87 CComVariant variant_; | |
88 }; | |
89 | |
90 TEST_F(VariantUtilsTest, NPVariantToVariant_Void) { | |
91 VOID_TO_NPVARIANT(np_variant_); | |
92 TestNPV2V(); | |
93 } | |
94 | |
95 TEST_F(VariantUtilsTest, NPVariantToVariant_Null) { | |
96 NULL_TO_NPVARIANT(np_variant_); | |
97 TestNPV2V(); | |
98 } | |
99 | |
100 TEST_F(VariantUtilsTest, NPVariantToVariant_Bool) { | |
101 BOOLEAN_TO_NPVARIANT(true, np_variant_); | |
102 TestNPV2V(); | |
103 EXPECT_EQ(VARIANT_TRUE, V_BOOL(&variant_)); | |
104 | |
105 BOOLEAN_TO_NPVARIANT(false, np_variant_); | |
106 TestNPV2V(); | |
107 EXPECT_EQ(VARIANT_FALSE, V_BOOL(&variant_)); | |
108 } | |
109 | |
110 TEST_F(VariantUtilsTest, NPVariantToVariant_Int32) { | |
111 INT32_TO_NPVARIANT(kint32min, np_variant_); | |
112 TestNPV2V(); | |
113 EXPECT_EQ(kint32min, V_I4(&variant_)); | |
114 | |
115 INT32_TO_NPVARIANT(0, np_variant_); | |
116 TestNPV2V(); | |
117 EXPECT_EQ(0, V_I4(&variant_)); | |
118 | |
119 INT32_TO_NPVARIANT(kint32max, np_variant_); | |
120 TestNPV2V(); | |
121 EXPECT_EQ(kint32max, V_I4(&variant_)); | |
122 } | |
123 | |
124 TEST_F(VariantUtilsTest, NPVariantToVariant_Double) { | |
125 DOUBLE_TO_NPVARIANT(-1, np_variant_); | |
126 TestNPV2V(); | |
127 EXPECT_DOUBLE_EQ(-1, V_R8(&variant_)); | |
128 | |
129 DOUBLE_TO_NPVARIANT(0, np_variant_); | |
130 TestNPV2V(); | |
131 EXPECT_DOUBLE_EQ(0, V_R8(&variant_)); | |
132 | |
133 DOUBLE_TO_NPVARIANT(static_cast<double>(kuint64max), | |
134 np_variant_); | |
135 TestNPV2V(); | |
136 EXPECT_DOUBLE_EQ(static_cast<double>(kuint64max), V_R8(&variant_)); | |
137 } | |
138 | |
139 TEST_F(VariantUtilsTest, NPVariantToVariant_String) { | |
140 // TODO(omaha): _strdup depends on an implementation detail of the stubs. | |
141 STRINGZ_TO_NPVARIANT(_strdup(""), np_variant_); | |
142 TestNPV2V(); | |
143 EXPECT_STREQ(L"", V_BSTR(&variant_)); | |
144 | |
145 // Force the length to be zero. | |
146 STRINGZ_TO_NPVARIANT(_strdup("junk"), np_variant_); | |
147 np_variant_.value.stringValue.UTF8Length = 0; | |
148 TestNPV2V(); | |
149 EXPECT_STREQ(L"", V_BSTR(&variant_)); | |
150 | |
151 STRINGZ_TO_NPVARIANT(_strdup("ROBERT'); DROP TABLE Students; --"), | |
152 np_variant_); | |
153 TestNPV2V(); | |
154 EXPECT_STREQ(L"ROBERT'); DROP TABLE Students; --", V_BSTR(&variant_)); | |
155 | |
156 // Check that NPVariantToVariant properly converts UTF-8 to UTF-16. | |
157 STRINGZ_TO_NPVARIANT(_strdup("one: \xe4\xb8\x80"), np_variant_); | |
158 TestNPV2V(); | |
159 EXPECT_STREQ(L"one: \x4e00", V_BSTR(&variant_)); | |
160 } | |
161 /* | |
162 TEST_F(VariantUtilsTest, NPVariantToVariant_Unsupported) { | |
163 // NPVariantType_Object -> VT_DISPATCH conversion is not supported. | |
164 ExpectAsserts expect_asserts; | |
165 OBJECT_TO_NPVARIANT(NULL, np_variant_); | |
166 variant_ = 24; | |
167 NPVariantToVariant(NULL, np_variant_, &variant_); | |
168 EXPECT_EQ(VT_EMPTY, V_VT(&variant_)); | |
169 // Manual cleanup, since OBJECT_TO_NPVARIANT macro was used with a NULL | |
170 // NPObject, which is normally illegal. | |
171 VOID_TO_NPVARIANT(np_variant_); | |
172 } | |
173 */ | |
174 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_EMPTY) { | |
175 variant_.ChangeType(VT_EMPTY); | |
176 TestV2NPV(); | |
177 } | |
178 | |
179 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_NULL) { | |
180 variant_.ChangeType(VT_NULL); | |
181 TestV2NPV(); | |
182 } | |
183 | |
184 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_BOOL) { | |
185 variant_ = true; | |
186 TestV2NPV(); | |
187 EXPECT_TRUE(np_variant_.value.boolValue); | |
188 | |
189 variant_ = false; | |
190 TestV2NPV(); | |
191 EXPECT_FALSE(np_variant_.value.boolValue); | |
192 } | |
193 | |
194 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_I4) { | |
195 variant_ = kint32max; | |
196 TestV2NPV(); | |
197 EXPECT_EQ(kint32max, np_variant_.value.intValue); | |
198 | |
199 variant_ = 0; | |
200 TestV2NPV(); | |
201 EXPECT_EQ(0, np_variant_.value.intValue); | |
202 | |
203 variant_ = kint32min; | |
204 TestV2NPV(); | |
205 EXPECT_EQ(kint32min, np_variant_.value.intValue); | |
206 } | |
207 | |
208 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_UI4) { | |
209 variant_ = 0U; | |
210 TestV2NPV(); | |
211 EXPECT_EQ(0, np_variant_.value.intValue); | |
212 | |
213 variant_ = static_cast<uint32>(kint32max); | |
214 TestV2NPV(); | |
215 EXPECT_EQ(kint32max, np_variant_.value.intValue); | |
216 | |
217 // MSIE can natively support VT_UI4. Unfortunately, Firefox cannot. | |
218 // Check that kuint32max wraps around to -1. | |
219 variant_ = kuint32max; | |
220 TestV2NPV(); | |
221 EXPECT_EQ(-1, np_variant_.value.intValue); | |
222 } | |
223 | |
224 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_R8) { | |
225 variant_ = 0.0; | |
226 TestV2NPV(); | |
227 EXPECT_DOUBLE_EQ(0.0, np_variant_.value.doubleValue); | |
228 | |
229 variant_ = -1.0; | |
230 TestV2NPV(); | |
231 EXPECT_DOUBLE_EQ(-1.0, np_variant_.value.doubleValue); | |
232 | |
233 variant_ = static_cast<double>(kuint64max); | |
234 TestV2NPV(); | |
235 EXPECT_DOUBLE_EQ(static_cast<double>(kuint64max), | |
236 np_variant_.value.doubleValue); | |
237 } | |
238 | |
239 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_BSTR) { | |
240 variant_ = ""; | |
241 TestV2NPV(); | |
242 EXPECT_STREQ("", np_variant_.value.stringValue.UTF8Characters); | |
243 | |
244 variant_ = L"sudo make me a sandwich"; | |
245 TestV2NPV(); | |
246 EXPECT_STREQ("sudo make me a sandwich", | |
247 np_variant_.value.stringValue.UTF8Characters); | |
248 | |
249 // A NULL BSTR should be treated as an empty string. | |
250 V_VT(&variant_) = VT_BSTR; | |
251 V_BSTR(&variant_) = NULL; | |
252 TestV2NPV(); | |
253 EXPECT_STREQ("", np_variant_.value.stringValue.UTF8Characters); | |
254 | |
255 // Check that VariantToNPVariant properly converts UTF-16 to UTF-8. | |
256 variant_ = L"one: \x4e00"; | |
257 TestV2NPV(); | |
258 EXPECT_STREQ("one: \xe4\xb8\x80", | |
259 np_variant_.value.stringValue.UTF8Characters); | |
260 } | |
261 | |
262 TEST_F(VariantUtilsTest, VariantToNPVariant_VT_DISPATCH) { | |
263 CComPtr<IDispatch> dispatch; | |
264 ASSERT_SUCCEEDED( | |
265 CComCoClass<DispatchHostTestInterface>::CreateInstance(&dispatch)); | |
266 variant_ = dispatch; | |
267 TestV2NPV(); | |
268 | |
269 // Check that the wrapped object's methods can be called. | |
270 NPIdentifierFactory identifier; | |
271 NPVariant result; | |
272 VOID_TO_NPVARIANT(result); | |
273 EXPECT_TRUE(NPN_Invoke(NULL, np_variant_.value.objectValue, | |
274 identifier.Create("Random"), NULL, 0, &result)); | |
275 EXPECT_TRUE(NPVARIANT_IS_INT32(result)); | |
276 EXPECT_EQ(42, result.value.intValue); | |
277 } | |
278 | |
279 TEST_F(VariantUtilsTest, VariantToNPVariant_Unsupported) { | |
280 // Legal variant types inferred from oaidl.idl and wtypes.h. Note that some | |
281 // types that aren't marked as appearing in VARIANTs still have a VARIANT | |
282 // field for that type, so they are included anyway... | |
283 | |
284 // Note that VT_UNKNOWN must not be the last element in the array; otherwise | |
285 // CComVariant will attempt to call Release() on a NULL pointer. | |
286 const VARTYPE kUnsupportedSimpleTypes[] = { | |
287 VT_I2, VT_R4, VT_CY, VT_DATE, VT_ERROR, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL, | |
288 VT_RECORD, VT_I1, VT_UI1, VT_UI2, VT_I8, VT_UI8, VT_INT, VT_UINT, VT_BYREF | |
289 }; | |
290 for (int i = 0; i < arraysize(kUnsupportedSimpleTypes); ++i) { | |
291 ExpectAsserts expect_asserts; | |
292 V_VT(&variant_) = kUnsupportedSimpleTypes[i]; | |
293 INT32_TO_NPVARIANT(42, np_variant_); | |
294 TestV2NPV(); | |
295 EXPECT_TRUE(NPVARIANT_IS_VOID(np_variant_)); | |
296 } | |
297 | |
298 // Compound modifiers. | |
299 const VARTYPE kCompoundModifiers[] = { | |
300 VT_ARRAY, VT_BYREF, VT_ARRAY | VT_BYREF | |
301 }; | |
302 // Compound types. | |
303 const VARTYPE kCompoundableTypes[] = { | |
304 VT_I2, VT_I4, VT_R4, VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH, VT_ERROR, | |
305 VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL, VT_RECORD, VT_I1, VT_UI1, | |
306 VT_UI2, VT_UI4, VT_I8, VT_UI8, VT_INT, VT_UINT | |
307 }; | |
308 | |
309 for (int i = 0; i < arraysize(kCompoundModifiers); ++i) { | |
310 for (int j = 0; j < arraysize(kCompoundableTypes); ++j) { | |
311 ExpectAsserts expect_asserts; | |
312 V_VT(&variant_) = kCompoundModifiers[i] | kCompoundableTypes[j]; | |
313 INT32_TO_NPVARIANT(42, np_variant_); | |
314 TestV2NPV(); | |
315 EXPECT_TRUE(NPVARIANT_IS_VOID(np_variant_)); | |
316 } | |
317 } | |
318 } | |
319 | |
320 } // namespace omaha | |
OLD | NEW |