windowscodecs: Add tests for IPropertyBag2.
[wine.git] / dlls / windowscodecs / tests / propertybag.c
blobb7e515372ba34a0dac027a344844441cedcb69bd
1 /*
2 * Copyright 2013 Ludger Sprenker
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
20 #include <math.h>
22 #define COBJMACROS
23 #define CONST_VTABLE
25 #include "windef.h"
26 #include "objbase.h"
27 #include "wincodec.h"
28 #include "wincodecsdk.h"
29 #include "wine/test.h"
31 static const WCHAR wszTestProperty1[] = {'P','r','o','p','e','r','t','y','1',0};
32 static const WCHAR wszTestProperty2[] = {'P','r','o','p','e','r','t','y','2',0};
33 static const WCHAR wszTestInvalidProperty[] = {'I','n','v','a','l','i','d',0};
35 static void test_propertybag_getpropertyinfo(IPropertyBag2 *property, ULONG expected_count)
37 HRESULT hr;
38 PROPBAG2 pb[2];
39 ULONG out_count;
41 /* iProperty: Out of bounce */
42 hr = IPropertyBag2_GetPropertyInfo(property, expected_count, 1, pb, &out_count);
43 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
44 "GetPropertyInfo handled iProperty out of bounce wrong, hr=%x\n", hr);
46 /* cProperty: Out of bounce */
47 hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count+1, pb, &out_count);
48 ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
49 "GetPropertyInfo handled cProperty out of bounce wrong, hr=%x\n", hr);
51 /* GetPropertyInfo can be called for zero items on Windows 8 but not on Windows 7 (wine behaves like Win8) */
52 if (expected_count == 0)
53 return;
55 hr = IPropertyBag2_GetPropertyInfo(property, 0, expected_count, pb, &out_count);
56 ok(hr == S_OK, "GetPropertyInfo failed, hr=%x\n", hr);
57 if (FAILED(hr))
58 return;
60 ok(expected_count == out_count,
61 "GetPropertyInfo returned unexpected property count, %i != %i)\n",
62 expected_count, out_count);
64 if(expected_count != 2)
65 return;
67 ok(pb[0].vt == VT_UI1, "Invalid variant type, pb[0].vt=%x\n", pb[0].vt);
68 ok(pb[0].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[0].dwType=%x\n", pb[0].dwType);
69 ok(lstrcmpW(pb[0].pstrName, wszTestProperty1) == 0, "Invalid property name, pb[0].pstrName=%s\n", wine_dbgstr_w(pb[0].pstrName));
71 ok(pb[1].vt == VT_R4, "Invalid variant type, pb[1].vt=%x\n", pb[1].vt);
72 ok(pb[1].dwType == PROPBAG2_TYPE_DATA, "Invalid variant type, pb[1].dwType=%x\n", pb[1].dwType);
73 ok(lstrcmpW(pb[1].pstrName, wszTestProperty2) == 0, "Invalid property name, pb[1].pstrName=%s\n", wine_dbgstr_w(pb[1].pstrName));
76 static void test_propertybag_countproperties(IPropertyBag2 *property, ULONG expected_count)
78 ULONG count = (ULONG)-1;
79 HRESULT hr;
81 hr = IPropertyBag2_CountProperties(property, NULL);
82 ok(hr == E_INVALIDARG, "CountProperties returned unexpected result, hr=%x\n", hr);
84 hr = IPropertyBag2_CountProperties(property, &count);
85 ok(hr == S_OK, "CountProperties failed, hr=%x\n", hr);
87 if (FAILED(hr))
88 return;
90 ok(count == expected_count, "CountProperties returned invalid value, count=%i\n", count);
93 static void test_propertybag_read(IPropertyBag2 *property)
95 HRESULT hr;
96 PROPBAG2 options[3] = {{0}};
97 VARIANT values[3];
98 HRESULT itm_hr[3] = {S_OK, S_OK, S_OK};
100 /* 1. One unknown property */
101 options[0].pstrName = (LPOLESTR)wszTestInvalidProperty;
102 hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr);
103 ok(hr == E_FAIL,
104 "Read for an unknown property did not fail with expected code, hr=%x\n", hr);
106 /* 2. One known property */
107 options[0].pstrName = (LPOLESTR)wszTestProperty1;
108 itm_hr[0] = E_FAIL;
109 hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr);
110 ok(hr == S_OK, "Read failed, hr=%x\n", hr);
111 if (SUCCEEDED(hr))
113 ok(itm_hr[0] == S_OK,
114 "Read failed, itm_hr[0]=%x\n", itm_hr[0]);
115 ok(V_VT(&values[0]) == VT_UI1,
116 "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0]));
117 ok(V_UNION(&values[0], bVal) == 12,
118 "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal));
120 VariantClear(&values[0]);
123 /* 3. Two known properties */
124 options[0].pstrName = (LPOLESTR)wszTestProperty1;
125 options[1].pstrName = (LPOLESTR)wszTestProperty2;
126 itm_hr[0] = E_FAIL;
127 itm_hr[1] = E_FAIL;
128 hr = IPropertyBag2_Read(property, 2, options, NULL, values, itm_hr);
129 ok(hr == S_OK, "Read failed, hr=%x\n", hr);
130 if (SUCCEEDED(hr))
132 ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%x\n", itm_hr[0]);
133 ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0]));
134 ok(V_UNION(&values[0], bVal) == 12, "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal));
136 ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%x\n", itm_hr[1]);
137 ok(V_VT(&values[1]) == VT_R4, "Read failed, V_VT(&values[1])=%x\n", V_VT(&values[1]));
138 ok(V_UNION(&values[1], fltVal) == (float)3.14, "Read failed, &values[1]=%f\n", V_UNION(&values[1], fltVal));
140 VariantClear(&values[0]);
141 VariantClear(&values[1]);
145 /* 4. One unknown property between two valid */
147 /* Exotic initializations so we can detect what is unchanged */
148 itm_hr[0] = -1; itm_hr[1] = -1; itm_hr[2] = -1;
149 V_VT(&values[0]) = VT_NULL;
150 V_VT(&values[1]) = VT_NULL;
151 V_VT(&values[2]) = VT_NULL;
152 V_UNION(&values[0], bVal) = 254;
153 V_UNION(&values[1], bVal) = 254;
154 V_UNION(&values[2], bVal) = 254;
156 options[0].pstrName = (LPOLESTR)wszTestProperty1;
157 options[1].pstrName = (LPOLESTR)wszTestInvalidProperty;
158 options[2].pstrName = (LPOLESTR)wszTestProperty2;
160 hr = IPropertyBag2_Read(property, 3, options, NULL, values, itm_hr);
161 ok(hr == E_FAIL, "Read failed, hr=%x\n", hr);
162 if (hr == E_FAIL)
164 ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%x\n", itm_hr[0]);
165 ok(itm_hr[1] == -1, "Read error code has unexpected value, itm_hr[1]=%x\n", itm_hr[1]);
166 ok(itm_hr[2] == -1, "Read error code has unexpected value, itm_hr[2]=%x\n", itm_hr[2]);
168 ok(V_VT(&values[0]) == VT_UI1, "Read variant has unexpected type, V_VT(&values[0])=%x\n", V_VT(&values[0]));
169 ok(V_VT(&values[1]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[1])=%x\n", V_VT(&values[1]));
170 ok(V_VT(&values[2]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[2])=%x\n", V_VT(&values[2]));
172 ok(V_UNION(&values[0], bVal) == 12, "Read variant has unexpected value, V_UNION(&values[0])=%i\n", V_UNION(&values[0], bVal));
173 ok(V_UNION(&values[1], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[1])=%i\n", V_UNION(&values[1], bVal));
174 ok(V_UNION(&values[2], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[2])=%i\n", V_UNION(&values[2], bVal));
178 static void test_propertybag_write(IPropertyBag2 *property)
180 HRESULT hr;
181 PROPBAG2 options[2] = {{0}};
182 VARIANT values[2];
184 VariantInit(&values[0]);
185 VariantInit(&values[1]);
187 /* 1. One unknown property */
188 options[0].pstrName = (LPOLESTR)wszTestInvalidProperty;
189 hr = IPropertyBag2_Write(property, 1, options, values);
190 ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%x\n", hr);
192 /* 2. One property without correct type */
193 options[0].pstrName = (LPOLESTR)wszTestProperty1;
194 V_VT(&values[0]) = VT_UI1;
195 V_UNION(&values[0], bVal) = 1;
196 hr = IPropertyBag2_Write(property, 1, options, values);
197 ok(hr == S_OK, "Write for one property failed, hr=%x\n", hr);
199 /* 3. One property with mismatching type */
200 options[0].pstrName = (LPOLESTR)wszTestProperty1;
201 V_VT(&values[0]) = VT_I1;
202 V_UNION(&values[0], bVal) = 2;
203 hr = IPropertyBag2_Write(property, 1, options, values);
204 ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE,
205 "Write with mismatching type did not fail with expected code hr=%x\n", hr);
207 /* 4. Reset one property to empty */
208 options[0].pstrName = (LPOLESTR)wszTestProperty1;
209 VariantClear(&values[0]);
210 hr = IPropertyBag2_Write(property, 1, options, values);
211 ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE,
212 "Write to reset to empty value does not fail with expected code, hr=%x\n", hr);
214 /* 5. Set two properties */
215 options[0].pstrName = (LPOLESTR)wszTestProperty1;
216 V_VT(&values[0]) = VT_UI1;
217 V_UNION(&values[0], bVal) = 12;
218 options[1].pstrName = (LPOLESTR)wszTestProperty2;
219 V_VT(&values[1]) = VT_R4;
220 V_UNION(&values[1], fltVal) = (float)3.14;
221 hr = IPropertyBag2_Write(property, 2, options, values);
222 ok(hr == S_OK, "Write for two properties failed, hr=%x\n", hr);
225 static void test_empty_propertybag(void)
227 HRESULT hr;
228 IWICComponentFactory *factory;
229 IPropertyBag2 *property;
231 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
232 &IID_IWICComponentFactory, (void**)&factory);
233 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
235 hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, NULL, 0, &property);
237 todo_wine
238 ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr);
239 if (FAILED(hr)) return;
241 todo_wine
242 test_propertybag_countproperties(property, 0);
244 todo_wine
245 test_propertybag_getpropertyinfo(property, 0);
247 IPropertyBag2_Release(property);
249 IWICComponentFactory_Release(factory);
252 static void test_filled_propertybag(void)
254 HRESULT hr;
255 IWICComponentFactory *factory;
256 IPropertyBag2 *property;
257 PROPBAG2 opts[2]= {
258 {.pstrName = (LPOLESTR)wszTestProperty1, .vt=VT_UI1, .dwType=PROPBAG2_TYPE_DATA},
259 {.pstrName = (LPOLESTR)wszTestProperty2, .vt=VT_R4, .dwType=PROPBAG2_TYPE_DATA}
262 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
263 &IID_IWICComponentFactory, (void**)&factory);
264 ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
266 hr = IWICComponentFactory_CreateEncoderPropertyBag(factory, opts, 2, &property);
268 todo_wine
269 ok(hr == S_OK, "Creating EncoderPropertyBag failed, hr=%x\n", hr);
270 if (FAILED(hr)) return;
272 todo_wine
273 test_propertybag_countproperties(property, 2);
275 todo_wine
276 test_propertybag_getpropertyinfo(property, 2);
278 todo_wine
279 test_propertybag_write(property);
281 todo_wine
282 test_propertybag_read(property);
284 IPropertyBag2_Release(property);
286 IWICComponentFactory_Release(factory);
289 START_TEST(propertybag)
291 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
293 test_empty_propertybag();
295 test_filled_propertybag();
297 CoUninitialize();