1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestUnicodeStringArrayAPI.cxx
5
6 -------------------------------------------------------------------------
7 Copyright 2008 Sandia Corporation.
8 Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 the U.S. Government retains certain rights in this software.
10 -------------------------------------------------------------------------
11
12 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
13 All rights reserved.
14 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
15
16 This software is distributed WITHOUT ANY WARRANTY; without even
17 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18 PURPOSE. See the above copyright notice for more information.
19
20 =========================================================================*/
21
22 #include <vtkSmartPointer.h>
23 #include <vtkUnicodeStringArray.h>
24 #include <vtkIdList.h>
25 #include <vtkDoubleArray.h>
26 #include <vtkVariant.h>
27 #include <vtkTestErrorObserver.h>
28
29 #include <iterator>
30 #include <iostream>
31 #include <sstream>
32 #include <stdexcept>
33
34 static int TestErrorsAndWarnings();
35
36 #define test_expression(expression) \
37 { \
38 if(!(expression)) \
39 { \
40 std::ostringstream buffer; \
41 buffer << "Expression failed at line " << __LINE__ << ": " << #expression; \
42 throw std::runtime_error(buffer.str()); \
43 } \
44 }
45
46 // Sample strings - nothing risque, I hope ...
47 static const vtkUnicodeString sample_utf8_ascii = vtkUnicodeString::from_utf8("abcde123");
48 static const vtkUnicodeString sample_utf8_greek = vtkUnicodeString::from_utf8("\xce\xb1\xce\xb2\xce\xb3"); // Greek lower-case alpha, beta, gamma.
49 static const vtkUnicodeString sample_utf8_thai = vtkUnicodeString::from_utf8("\xe0\xb8\x81\xe0\xb8\x82\xe0\xb8\x83"); // Thai ko kai, kho khai, kho khuat.
50 static const vtkUnicodeString sample_utf8_linear_b = vtkUnicodeString::from_utf8("\xf0\x90\x80\x80\xf0\x90\x80\x81\xf0\x90\x80\x82\xf0\x90\x80\x83\xf0\x90\x80\x84"); // Linear-B syllables a, e, i, o, u.
51 static const vtkUnicodeString sample_utf8_mixed = vtkUnicodeString::from_utf8("a\xce\xb1\xe0\xb8\x81\xf0\x90\x80\x80"); // a, alpha, ko kai, syllable-a.
52
TestUnicodeStringArrayAPI(int,char * [])53 int TestUnicodeStringArrayAPI(int, char*[])
54 {
55 try
56 {
57 vtkSmartPointer<vtkUnicodeStringArray> array =
58 vtkSmartPointer<vtkUnicodeStringArray>::New();
59 array->ClearLookup(); // noop
60 test_expression(array->GetNumberOfTuples() == 0);
61 test_expression(array->GetDataType() == VTK_UNICODE_STRING);
62 test_expression(array->GetDataTypeSize() == 0);
63 test_expression(array->GetElementComponentSize() == 4);
64 test_expression(array->IsNumeric() == 0);
65
66 array->InsertNextValue(sample_utf8_ascii);
67 test_expression(array->GetNumberOfTuples() == 1);
68 test_expression((array->GetValue(0)) == sample_utf8_ascii);
69 test_expression((array->GetVariantValue(0)) == sample_utf8_ascii);
70
71 array->InsertNextValue(vtkUnicodeString::from_utf8("foo"));
72 test_expression(array->GetNumberOfTuples() == 2);
73 test_expression(array->LookupValue(vtkUnicodeString::from_utf8("foo")) == 1);
74 test_expression(array->LookupValue(vtkUnicodeString::from_utf8("bar")) == -1);
75
76 vtkSmartPointer<vtkUnicodeStringArray> array2 =
77 vtkSmartPointer<vtkUnicodeStringArray>::New();
78 array2->SetNumberOfTuples(3);
79 array2->SetValue(2, sample_utf8_thai);
80 array2->SetValue(1, sample_utf8_greek);
81 array2->SetValue(0, sample_utf8_linear_b);
82 test_expression(array2->GetNumberOfTuples() == 3);
83
84 array2->InsertNextUTF8Value("bar");
85 test_expression(array2->GetNumberOfTuples() == 4);
86
87 array2->InsertValue(100, sample_utf8_ascii);
88 test_expression(array2->GetNumberOfTuples() == 101);
89
90 array2->SetVariantValue(100, "foo");
91 test_expression(array2->GetValue(100) == vtkUnicodeString::from_utf8("foo"));
92
93 array2->SetUTF8Value(100, "barfoo");
94 test_expression(strcmp(array2->GetUTF8Value(100), "barfoo") == 0);
95
96 array2->Initialize();
97 test_expression(array2->GetNumberOfTuples() == 0);
98
99 vtkSmartPointer<vtkUnicodeStringArray> array3 =
100 vtkSmartPointer<vtkUnicodeStringArray>::New();
101 void * ptr1 = array3->GetVoidPointer(0);
102 test_expression(ptr1 == nullptr);
103
104 array3->InsertTuple(0, 1, array);
105 test_expression(array3->GetValue(0) == array->GetValue(1));
106
107 array3->InsertTuple(100, 1, array);
108 test_expression(array3->GetValue(100) == array->GetValue(1));
109
110 array3->InsertNextTuple(1, array);
111 test_expression(array3->GetValue(101) == array->GetValue(1));
112
113 array3->SetTuple(0, 0, array);
114 test_expression(array3->GetValue(0) == array->GetValue(0));
115
116 vtkSmartPointer<vtkIdList> toIds =
117 vtkSmartPointer<vtkIdList>::New();
118 vtkSmartPointer<vtkIdList> fromIds =
119 vtkSmartPointer<vtkIdList>::New();
120 fromIds->InsertId(0, 1);
121 fromIds->InsertId(1, 0);
122 toIds->InsertId(0, array3->GetNumberOfTuples() + 1);
123 toIds->InsertId(1, 1);
124
125 array3->InsertTuples(toIds, fromIds, array);
126 test_expression(array3->GetValue(array3->GetNumberOfTuples() - 1) == array->GetValue(1));
127 test_expression(array3->GetValue(1) == array->GetValue(0));
128
129 array3->InsertNextValue(vtkUnicodeString::from_utf8("foobar"));
130 array3->InsertNextValue(vtkUnicodeString::from_utf8("foobar"));
131 array3->InsertNextValue(vtkUnicodeString::from_utf8("foobar"));
132 vtkSmartPointer<vtkIdList> lookupIds =
133 vtkSmartPointer<vtkIdList>::New();
134 array3->LookupValue(vtkUnicodeString::from_utf8("foobar"), lookupIds);
135 test_expression(lookupIds->GetNumberOfIds() == 3);
136
137 array3->DeepCopy(nullptr); // noop
138 array3->DeepCopy(array3); // noop
139 array3->DeepCopy(array);
140 test_expression(array3->GetActualMemorySize() == array->GetActualMemorySize());
141
142 vtkSmartPointer<vtkUnicodeStringArray> array4 =
143 vtkSmartPointer<vtkUnicodeStringArray>::New();
144 array4->InsertNextValue(vtkUnicodeString::from_utf8("array4_0"));
145 array4->InsertNextValue(vtkUnicodeString::from_utf8("array4_1"));
146 array4->InsertNextValue(vtkUnicodeString::from_utf8("array4_2"));
147
148 vtkSmartPointer<vtkUnicodeStringArray> array5 =
149 vtkSmartPointer<vtkUnicodeStringArray>::New();
150 array5->InsertNextValue(vtkUnicodeString::from_utf8("array5_0"));
151 array5->InsertNextValue(vtkUnicodeString::from_utf8("array5_1"));
152 array5->InsertNextValue(vtkUnicodeString::from_utf8("array5_2"));
153 array5->InsertNextValue(vtkUnicodeString::from_utf8("array5_3"));
154
155 vtkSmartPointer<vtkIdList> interpIds =
156 vtkSmartPointer<vtkIdList>::New();
157
158 array3->InterpolateTuple(5, interpIds, array4, nullptr); // noop
159
160 interpIds->InsertId(0, 0);
161 interpIds->InsertId(1, 1);
162 interpIds->InsertId(2, 2);
163 double weights[3];
164 weights[0] = .2;
165 weights[1] = .8;
166 weights[2] = .5;
167 array3->InterpolateTuple(5, interpIds, array4, weights);
168 test_expression(array3->GetValue(5) == array4->GetValue(1));
169
170 array3->InterpolateTuple(0,
171 0, array4,
172 0, array5,
173 0.1);
174 test_expression(array3->GetValue(0) == array4->GetValue(0));
175
176 array3->InterpolateTuple(1,
177 0, array4,
178 0, array5,
179 0.6);
180 test_expression(array3->GetValue(1) == array5->GetValue(0));
181
182 array3->Squeeze();
183 test_expression(array3->GetValue(5) == array4->GetValue(1));
184
185 array3->Resize(20);
186 test_expression(array3->GetValue(5) == array4->GetValue(1));
187
188 array3->GetVoidPointer(0);
189
190 if (TestErrorsAndWarnings() != 0)
191 {
192 return EXIT_FAILURE;
193 }
194 array3->Print(std::cout);
195
196 return EXIT_SUCCESS;
197 }
198 catch(std::exception& e)
199 {
200 cerr << e.what() << endl;
201 return EXIT_FAILURE;
202 }
203 }
204
TestErrorsAndWarnings()205 int TestErrorsAndWarnings()
206 {
207 int status = 0;
208 vtkSmartPointer<vtkTest::ErrorObserver> errorObserver =
209 vtkSmartPointer<vtkTest::ErrorObserver>::New();
210
211 vtkSmartPointer<vtkUnicodeStringArray> array =
212 vtkSmartPointer<vtkUnicodeStringArray>::New();
213 array->Allocate(100, 0);
214 array->AddObserver(vtkCommand::ErrorEvent, errorObserver);
215 array->AddObserver(vtkCommand::WarningEvent, errorObserver);
216
217 // ERROR: Not implemented
218 array->SetVoidArray(nullptr, 1, 1);
219 if (errorObserver->GetError())
220 {
221 std::cout << "Caught expected error: "
222 << errorObserver->GetErrorMessage();
223 }
224 else
225 {
226 std::cout << "Failed to catch expected 'Not implemented' error" << std::endl;
227 ++status;
228 }
229 errorObserver->Clear();
230
231 // ERROR: Not implemented
232 array->NewIterator();
233 if (errorObserver->GetError())
234 {
235 std::cout << "Caught expected error: "
236 << errorObserver->GetErrorMessage();
237 }
238 else
239 {
240 std::cout << "Failed to catch expected 'Not implemented' error" << std::endl;
241 ++status;
242 }
243 errorObserver->Clear();
244
245 // Warning: Input and output array data types do not match.
246 vtkSmartPointer<vtkDoubleArray> doubleArray =
247 vtkSmartPointer<vtkDoubleArray>::New();
248 array->SetTuple(0, 0, doubleArray);
249 if (errorObserver->GetWarning())
250 {
251 std::cout << "Caught expected warning: "
252 << errorObserver->GetWarningMessage();
253 }
254 else
255 {
256 std::cout << "Failed to catch expected 'Input and output array data types do not match.' warning" << std::endl;
257 ++status;
258 }
259 errorObserver->Clear();
260
261 // Warning: Input and output array data types do not match.
262 array->InsertTuple(0, 0, doubleArray);
263 if (errorObserver->GetWarning())
264 {
265 std::cout << "Caught expected warning: "
266 << errorObserver->GetWarningMessage();
267 }
268 else
269 {
270 std::cout << "Failed to catch expected 'Input and output array data types do not match.' warning" << std::endl;
271 ++status;
272 }
273 errorObserver->Clear();
274
275 // Warning: Input and output array data types do not match.
276 array->InsertNextTuple(0, doubleArray);
277 if (errorObserver->GetWarning())
278 {
279 std::cout << "Caught expected warning: "
280 << errorObserver->GetWarningMessage();
281 }
282 else
283 {
284 std::cout << "Failed to catch expected 'Input and output array data types do not match.' warning" << std::endl;
285 ++status;
286 }
287 errorObserver->Clear();
288
289 // Warning: Input and output array data types do not match.
290 array->DeepCopy(doubleArray);
291 if (errorObserver->GetWarning())
292 {
293 std::cout << "Caught expected warning: "
294 << errorObserver->GetWarningMessage();
295 }
296 else
297 {
298 std::cout << "Failed to catch expected 'Input and output array data types do not match.' warning" << std::endl;
299 ++status;
300 }
301 errorObserver->Clear();
302
303 // Warning: Input and output array data types do not match.
304 vtkSmartPointer<vtkIdList> id1 =
305 vtkSmartPointer<vtkIdList>::New();
306 array->InsertTuples(id1, id1, doubleArray);
307 if (errorObserver->GetWarning())
308 {
309 std::cout << "Caught expected warning: "
310 << errorObserver->GetWarningMessage();
311 }
312 else
313 {
314 std::cout << "Failed to catch expected 'Input and output array data types do not match.' warning" << std::endl;
315 ++status;
316 }
317 errorObserver->Clear();
318
319 // Warning: Input and output id array sizes do not match.
320 vtkSmartPointer<vtkIdList> id2 =
321 vtkSmartPointer<vtkIdList>::New();
322 id1->SetNumberOfIds(10);
323 id2->SetNumberOfIds(5);
324 array->InsertTuples(id1, id2, array);
325 if (errorObserver->GetWarning())
326 {
327 std::cout << "Caught expected warning: "
328 << errorObserver->GetWarningMessage();
329 }
330 else
331 {
332 std::cout << "Failed to catch expected 'Input and output id array sizes do not match.' warning" << std::endl;
333 ++status;
334 }
335 errorObserver->Clear();
336
337 // ERROR: Cannot CopyValue from array of type
338 array->InterpolateTuple(0, id1, doubleArray, nullptr);
339 if (errorObserver->GetError())
340 {
341 std::cout << "Caught expected warning: "
342 << errorObserver->GetErrorMessage();
343 }
344 else
345 {
346 std::cout << "Failed to catch expected 'Cannot CopyValue from array of type' error" << std::endl;
347 ++status;
348 }
349 errorObserver->Clear();
350
351 // ERROR: All arrays to InterpolateValue() must be of same type.
352 array->InterpolateTuple(0,
353 0, doubleArray,
354 2, array,
355 0.0);
356 if (errorObserver->GetError())
357 {
358 std::cout << "Caught expected warning: "
359 << errorObserver->GetErrorMessage();
360 }
361 else
362 {
363 std::cout << "Failed to catch expected 'All arrays to InterpolateValue() must be of same type.' error" << std::endl;
364 ++status;
365 }
366 errorObserver->Clear();
367
368 return status;
369 }
370