1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is C++ array template tests.
18 * The Initial Developer of the Original Code is Google Inc.
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
23 * Darin Fisher <darin@meer.net>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
42 #include "nsTPtrArray.h"
44 #include "nsAutoPtr.h"
46 #include "nsDirectoryServiceDefs.h"
47 #include "nsDirectoryServiceUtils.h"
48 #include "nsComponentManagerUtils.h"
50 #include "nsILocalFile.h"
52 namespace TestTArray
{
54 // Define this so we can use test_basic_array in test_comptr_array
56 inline bool operator<(const nsCOMPtr
<T
>& lhs
, const nsCOMPtr
<T
>& rhs
) {
57 return lhs
.get() < rhs
.get();
62 template <class ElementType
>
63 static PRBool
test_basic_array(ElementType
*data
,
65 const ElementType
& extra
) {
66 nsTArray
<ElementType
> ary
;
67 ary
.AppendElements(data
, dataLen
);
68 if (ary
.Length() != dataLen
) {
72 for (i
= 0; i
< ary
.Length(); ++i
) {
73 if (ary
[i
] != data
[i
])
76 for (i
= 0; i
< ary
.Length(); ++i
) {
77 if (ary
.SafeElementAt(i
, extra
) != data
[i
])
80 if (ary
.SafeElementAt(ary
.Length(), extra
) != extra
||
81 ary
.SafeElementAt(ary
.Length() * 10, extra
) != extra
)
83 // ensure sort results in ascending order
85 for (i
= ary
.Length(); --i
; ) {
86 if (ary
[i
] < ary
[i
- 1])
88 if (ary
[i
] == ary
[i
- 1])
89 ary
.RemoveElementAt(i
);
91 for (i
= 0; i
< ary
.Length(); ++i
) {
92 if (ary
.BinaryIndexOf(ary
[i
]) != i
)
95 if (ary
.BinaryIndexOf(extra
) != -1)
97 PRUint32 oldLen
= ary
.Length();
98 ary
.RemoveElement(data
[dataLen
/ 2]);
99 if (ary
.Length() != (oldLen
- 1))
102 PRUint32 index
= ary
.Length() / 2;
103 if (!ary
.InsertElementAt(index
, extra
))
105 if (ary
[index
] != extra
)
107 if (ary
.IndexOf(extra
) == PR_UINT32_MAX
)
109 if (ary
.LastIndexOf(extra
) == PR_UINT32_MAX
)
111 // ensure proper searching
112 if (ary
.IndexOf(extra
) > ary
.LastIndexOf(extra
))
114 if (ary
.IndexOf(extra
, index
) != ary
.LastIndexOf(extra
, index
))
117 nsTArray
<ElementType
> copy(ary
);
118 for (i
= 0; i
< copy
.Length(); ++i
) {
119 if (ary
[i
] != copy
[i
])
122 if (!ary
.AppendElements(copy
))
124 PRUint32 cap
= ary
.Capacity();
125 ary
.RemoveElementsAt(copy
.Length(), copy
.Length());
127 if (ary
.Capacity() == cap
)
131 if (!ary
.IsEmpty() || ary
.Elements() == nsnull
)
133 if (ary
.SafeElementAt(0, extra
) != extra
||
134 ary
.SafeElementAt(10, extra
) != extra
)
138 for (i
= 0; i
< copy
.Length(); ++i
) {
139 if (ary
[i
] != copy
[i
])
143 if (!ary
.InsertElementsAt(0, copy
))
145 ary
.RemoveElementsAt(0, copy
.Length());
146 for (i
= 0; i
< copy
.Length(); ++i
) {
147 if (ary
[i
] != copy
[i
])
151 // These shouldn't crash!
152 nsTArray
<ElementType
> empty
;
153 ary
.AppendElements(reinterpret_cast<ElementType
*>(0), 0);
154 ary
.AppendElements(empty
);
157 ary
.RemoveElement(extra
);
158 ary
.RemoveElement(extra
);
163 static PRBool
test_int_array() {
164 int data
[] = {4,6,8,2,4,1,5,7,3};
165 return test_basic_array(data
, NS_ARRAY_LENGTH(data
), int(14));
168 static PRBool
test_int64_array() {
169 PRInt64 data
[] = {4,6,8,2,4,1,5,7,3};
170 return test_basic_array(data
, NS_ARRAY_LENGTH(data
), PRInt64(14));
173 static PRBool
test_char_array() {
174 char data
[] = {4,6,8,2,4,1,5,7,3};
175 return test_basic_array(data
, NS_ARRAY_LENGTH(data
), char(14));
178 static PRBool
test_uint32_array() {
179 PRUint32 data
[] = {4,6,8,2,4,1,5,7,3};
180 return test_basic_array(data
, NS_ARRAY_LENGTH(data
), PRUint32(14));
189 Object(const char *str
, PRUint32 num
) : mStr(str
), mNum(num
) {
191 Object(const Object
& other
) : mStr(other
.mStr
), mNum(other
.mNum
) {
195 Object
& operator=(const Object
& other
) {
201 PRBool
operator==(const Object
& other
) const {
202 return mStr
== other
.mStr
&& mNum
== other
.mNum
;
205 PRBool
operator<(const Object
& other
) const {
206 // sort based on mStr only
207 return Compare(mStr
, other
.mStr
) < 0;
210 const char *Str() const { return mStr
.get(); }
211 PRUint32
Num() const { return mNum
; }
218 static PRBool
test_object_array() {
219 nsTArray
<Object
> objArray
;
220 const char kdata
[] = "hello world";
222 for (i
= 0; i
< NS_ARRAY_LENGTH(kdata
); ++i
) {
223 char x
[] = {kdata
[i
],'\0'};
224 if (!objArray
.AppendElement(Object(x
, i
)))
227 for (i
= 0; i
< NS_ARRAY_LENGTH(kdata
); ++i
) {
228 if (objArray
[i
].Str()[0] != kdata
[i
])
230 if (objArray
[i
].Num() != i
)
234 const char ksorted
[] = "\0 dehllloorw";
235 for (i
= 0; i
< NS_ARRAY_LENGTH(kdata
)-1; ++i
) {
236 if (objArray
[i
].Str()[0] != ksorted
[i
])
242 // nsTArray<nsAutoPtr<T>> is not supported
244 static PRBool
test_autoptr_array() {
245 nsTArray
< nsAutoPtr
<Object
> > objArray
;
246 const char kdata
[] = "hello world";
247 for (PRUint32 i
= 0; i
< NS_ARRAY_LENGTH(kdata
); ++i
) {
248 char x
[] = {kdata
[i
],'\0'};
249 nsAutoPtr
<Object
> obj(new Object(x
,i
));
250 if (!objArray
.AppendElement(obj
)) // XXX does not call copy-constructor for nsAutoPtr!!!
252 if (obj
.get() == nsnull
)
254 obj
.forget(); // the array now owns the reference
256 for (PRUint32 i
= 0; i
< NS_ARRAY_LENGTH(kdata
); ++i
) {
257 if (objArray
[i
]->Str()[0] != kdata
[i
])
259 if (objArray
[i
]->Num() != i
)
268 static PRBool
operator==(const nsCString
&a
, const char *b
) {
272 static PRBool
test_string_array() {
273 nsTArray
<nsCString
> strArray
;
274 const char kdata
[] = "hello world";
276 for (i
= 0; i
< NS_ARRAY_LENGTH(kdata
); ++i
) {
277 if (!strArray
.AppendElement(nsCString(kdata
[i
])))
280 for (i
= 0; i
< NS_ARRAY_LENGTH(kdata
); ++i
) {
281 if (strArray
[i
].CharAt(0) != kdata
[i
])
285 const char kextra
[] = "foo bar";
286 PRUint32 oldLen
= strArray
.Length();
287 if (!strArray
.AppendElement(kextra
))
289 strArray
.RemoveElement(kextra
);
290 if (oldLen
!= strArray
.Length())
293 if (strArray
.IndexOf("e") != 1)
297 const char ksorted
[] = "\0 dehllloorw";
298 for (i
= NS_ARRAY_LENGTH(kdata
); i
--; ) {
299 if (strArray
[i
].CharAt(0) != ksorted
[i
])
301 if (i
> 0 && strArray
[i
] == strArray
[i
- 1])
302 strArray
.RemoveElementAt(i
);
304 for (i
= 0; i
< strArray
.Length(); ++i
) {
305 if (strArray
.BinaryIndexOf(strArray
[i
]) != i
)
308 if (strArray
.BinaryIndexOf(EmptyCString()) != -1)
311 nsCString rawArray
[NS_ARRAY_LENGTH(kdata
)-1];
312 for (i
= 0; i
< NS_ARRAY_LENGTH(rawArray
); ++i
)
313 rawArray
[i
].Assign(kdata
+ i
); // substrings of kdata
314 return test_basic_array(rawArray
, NS_ARRAY_LENGTH(rawArray
),
320 typedef nsCOMPtr
<nsIFile
> FilePointer
;
322 class nsFileNameComparator
{
324 PRBool
Equals(const FilePointer
&a
, const char *b
) const {
326 a
->GetNativeLeafName(name
);
327 return name
.Equals(b
);
331 static PRBool
test_comptr_array() {
333 NS_GetSpecialDirectory(NS_OS_TEMP_DIR
, getter_AddRefs(tmpDir
));
336 const char *kNames
[] = {
337 "foo.txt", "bar.html", "baz.gif"
339 nsTArray
<FilePointer
> fileArray
;
341 for (i
= 0; i
< NS_ARRAY_LENGTH(kNames
); ++i
) {
343 tmpDir
->Clone(getter_AddRefs(f
));
346 if (NS_FAILED(f
->AppendNative(nsDependentCString(kNames
[i
]))))
348 fileArray
.AppendElement(f
);
351 if (fileArray
.IndexOf(kNames
[1], 0, nsFileNameComparator()) != 1)
354 // It's unclear what 'operator<' means for nsCOMPtr, but whatever...
355 return test_basic_array(fileArray
.Elements(), fileArray
.Length(),
361 class RefcountedObject
{
363 RefcountedObject() : rc(0) {}
371 ~RefcountedObject() {}
376 static PRBool
test_refptr_array() {
379 nsTArray
< nsRefPtr
<RefcountedObject
> > objArray
;
381 RefcountedObject
*a
= new RefcountedObject(); a
->AddRef();
382 RefcountedObject
*b
= new RefcountedObject(); b
->AddRef();
383 RefcountedObject
*c
= new RefcountedObject(); c
->AddRef();
385 objArray
.AppendElement(a
);
386 objArray
.AppendElement(b
);
387 objArray
.AppendElement(c
);
389 if (objArray
.IndexOf(b
) != 1)
400 static PRBool
test_ptrarray() {
401 nsTPtrArray
<PRUint32
> ary
;
402 if (ary
.SafeElementAt(0) != nsnull
)
404 if (ary
.SafeElementAt(1000) != nsnull
)
407 ary
.AppendElement(&a
);
410 if (*ary
.SafeElementAt(0) != a
)
413 nsTPtrArray
<const PRUint32
> cary
;
414 if (cary
.SafeElementAt(0) != nsnull
)
416 if (cary
.SafeElementAt(1000) != nsnull
)
418 const PRUint32 b
= 14;
419 cary
.AppendElement(&a
);
420 cary
.AppendElement(&b
);
421 if (*cary
[0] != a
|| *cary
[1] != b
)
423 if (*cary
.SafeElementAt(0) != a
|| *cary
.SafeElementAt(1) != b
)
431 // This test relies too heavily on the existance of DebugGetHeader to be
432 // useful in non-debug builds.
434 static PRBool
test_autoarray() {
435 PRUint32 data
[] = {4,6,8,2,4,1,5,7,3};
436 nsAutoTArray
<PRUint32
, NS_ARRAY_LENGTH(data
)> array
;
438 void* hdr
= array
.DebugGetHeader();
439 if (hdr
== nsTArray
<PRUint32
>().DebugGetHeader())
441 if (hdr
== nsAutoTArray
<PRUint32
, NS_ARRAY_LENGTH(data
)>().DebugGetHeader())
444 array
.AppendElement(1u);
445 if (hdr
!= array
.DebugGetHeader())
448 array
.RemoveElement(1u);
449 array
.AppendElements(data
, NS_ARRAY_LENGTH(data
));
450 if (hdr
!= array
.DebugGetHeader())
453 array
.AppendElement(2u);
454 if (hdr
== array
.DebugGetHeader())
459 if (hdr
!= array
.DebugGetHeader())
461 array
.AppendElements(data
, NS_ARRAY_LENGTH(data
));
462 if (hdr
!= array
.DebugGetHeader())
465 nsTArray
<PRUint32
> array2
;
466 void* emptyHdr
= array2
.DebugGetHeader();
467 array
.SwapElements(array2
);
468 if (emptyHdr
== array
.DebugGetHeader())
470 if (hdr
== array2
.DebugGetHeader())
473 for (i
= 0; i
< NS_ARRAY_LENGTH(data
); ++i
) {
474 if (array2
[i
] != data
[i
])
477 if (!array
.IsEmpty())
481 array
.AppendElements(data
, NS_ARRAY_LENGTH(data
));
482 PRUint32 data3
[] = {5, 7, 11};
483 nsAutoTArray
<PRUint32
, NS_ARRAY_LENGTH(data3
)> array3
;
484 array3
.AppendElements(data3
, NS_ARRAY_LENGTH(data3
));
485 array
.SwapElements(array3
);
486 for (i
= 0; i
< NS_ARRAY_LENGTH(data
); ++i
) {
487 if (array3
[i
] != data
[i
])
490 for (i
= 0; i
< NS_ARRAY_LENGTH(data3
); ++i
) {
491 if (array
[i
] != data3
[i
])
501 typedef PRBool (*TestFunc
)();
502 #define DECL_TEST(name) { #name, name }
504 static const struct Test
{
508 DECL_TEST(test_int_array
),
509 DECL_TEST(test_int64_array
),
510 DECL_TEST(test_char_array
),
511 DECL_TEST(test_uint32_array
),
512 DECL_TEST(test_object_array
),
513 DECL_TEST(test_string_array
),
514 DECL_TEST(test_comptr_array
),
515 DECL_TEST(test_refptr_array
),
516 DECL_TEST(test_ptrarray
),
518 DECL_TEST(test_autoarray
),
525 using namespace TestTArray
;
527 int main(int argc
, char **argv
) {
530 count
= atoi(argv
[1]);
532 if (NS_FAILED(NS_InitXPCOM2(nsnull
, nsnull
, nsnull
)))
536 for (const Test
* t
= tests
; t
->name
!= nsnull
; ++t
) {
537 printf("%25s : %s\n", t
->name
, t
->func() ? "SUCCESS" : "FAILURE");
541 NS_ShutdownXPCOM(nsnull
);