|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "mozilla/ArrayUtils.h" |
|
7 |
|
8 #include "nsIAtom.h" |
|
9 #include "nsString.h" |
|
10 #include "UTFStrings.h" |
|
11 #include "nsIServiceManager.h" |
|
12 #include "nsStaticAtom.h" |
|
13 |
|
14 using namespace mozilla; |
|
15 |
|
16 namespace TestAtoms { |
|
17 |
|
18 bool |
|
19 test_basic() |
|
20 { |
|
21 for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) { |
|
22 nsDependentString str16(ValidStrings[i].m16); |
|
23 nsDependentCString str8(ValidStrings[i].m8); |
|
24 |
|
25 nsCOMPtr<nsIAtom> atom = do_GetAtom(str16); |
|
26 |
|
27 if (!atom->Equals(str16) || !atom->EqualsUTF8(str8)) |
|
28 return false; |
|
29 |
|
30 nsString tmp16; |
|
31 nsCString tmp8; |
|
32 atom->ToString(tmp16); |
|
33 atom->ToUTF8String(tmp8); |
|
34 if (!str16.Equals(tmp16) || !str8.Equals(tmp8)) |
|
35 return false; |
|
36 |
|
37 if (!nsDependentString(atom->GetUTF16String()).Equals(str16)) |
|
38 return false; |
|
39 |
|
40 if (!nsAtomString(atom).Equals(str16) || |
|
41 !nsDependentAtomString(atom).Equals(str16) || |
|
42 !nsAtomCString(atom).Equals(str8)) |
|
43 return false; |
|
44 } |
|
45 |
|
46 return true; |
|
47 } |
|
48 |
|
49 bool |
|
50 test_16vs8() |
|
51 { |
|
52 for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) { |
|
53 nsCOMPtr<nsIAtom> atom16 = do_GetAtom(ValidStrings[i].m16); |
|
54 nsCOMPtr<nsIAtom> atom8 = do_GetAtom(ValidStrings[i].m8); |
|
55 if (atom16 != atom8) |
|
56 return false; |
|
57 } |
|
58 |
|
59 return true; |
|
60 } |
|
61 |
|
62 bool |
|
63 test_buffersharing() |
|
64 { |
|
65 nsString unique; |
|
66 unique.AssignLiteral("this is a unique string !@#$"); |
|
67 |
|
68 nsCOMPtr<nsIAtom> atom = do_GetAtom(unique); |
|
69 |
|
70 return unique.get() == atom->GetUTF16String(); |
|
71 } |
|
72 |
|
73 bool |
|
74 test_null() |
|
75 { |
|
76 nsAutoString str(NS_LITERAL_STRING("string with a \0 char")); |
|
77 nsDependentString strCut(str.get()); |
|
78 |
|
79 if (str.Equals(strCut)) |
|
80 return false; |
|
81 |
|
82 nsCOMPtr<nsIAtom> atomCut = do_GetAtom(strCut); |
|
83 nsCOMPtr<nsIAtom> atom = do_GetAtom(str); |
|
84 |
|
85 return atom->GetLength() == str.Length() && |
|
86 atom->Equals(str) && |
|
87 atom->EqualsUTF8(NS_ConvertUTF16toUTF8(str)) && |
|
88 atom != atomCut && |
|
89 atomCut->Equals(strCut); |
|
90 } |
|
91 |
|
92 bool |
|
93 test_invalid() |
|
94 { |
|
95 for (unsigned int i = 0; i < ArrayLength(Invalid16Strings); ++i) { |
|
96 nsrefcnt count = NS_GetNumberOfAtoms(); |
|
97 |
|
98 { |
|
99 nsCOMPtr<nsIAtom> atom16 = do_GetAtom(Invalid16Strings[i].m16); |
|
100 if (!atom16->Equals(nsDependentString(Invalid16Strings[i].m16))) |
|
101 return false; |
|
102 } |
|
103 |
|
104 if (count != NS_GetNumberOfAtoms()) |
|
105 return false; |
|
106 } |
|
107 |
|
108 for (unsigned int i = 0; i < ArrayLength(Invalid8Strings); ++i) { |
|
109 nsrefcnt count = NS_GetNumberOfAtoms(); |
|
110 |
|
111 { |
|
112 nsCOMPtr<nsIAtom> atom8 = do_GetAtom(Invalid8Strings[i].m8); |
|
113 nsCOMPtr<nsIAtom> atom16 = do_GetAtom(Invalid8Strings[i].m16); |
|
114 if (atom16 != atom8 || |
|
115 !atom16->Equals(nsDependentString(Invalid8Strings[i].m16))) |
|
116 return false; |
|
117 } |
|
118 |
|
119 if (count != NS_GetNumberOfAtoms()) |
|
120 return false; |
|
121 } |
|
122 |
|
123 // Don't run this test in debug builds as that intentionally asserts. |
|
124 #ifndef DEBUG |
|
125 nsCOMPtr<nsIAtom> emptyAtom = do_GetAtom(""); |
|
126 |
|
127 for (unsigned int i = 0; i < ArrayLength(Malformed8Strings); ++i) { |
|
128 nsrefcnt count = NS_GetNumberOfAtoms(); |
|
129 |
|
130 nsCOMPtr<nsIAtom> atom8 = do_GetAtom(Malformed8Strings[i]); |
|
131 if (atom8 != emptyAtom || |
|
132 count != NS_GetNumberOfAtoms()) |
|
133 return false; |
|
134 } |
|
135 #endif |
|
136 |
|
137 return true; |
|
138 } |
|
139 |
|
140 #define FIRST_ATOM_STR "first static atom. Hello!" |
|
141 #define SECOND_ATOM_STR "second static atom. @World!" |
|
142 #define THIRD_ATOM_STR "third static atom?!" |
|
143 |
|
144 static nsIAtom* sAtom1 = 0; |
|
145 static nsIAtom* sAtom2 = 0; |
|
146 static nsIAtom* sAtom3 = 0; |
|
147 NS_STATIC_ATOM_BUFFER(sAtom1_buffer, FIRST_ATOM_STR) |
|
148 NS_STATIC_ATOM_BUFFER(sAtom2_buffer, SECOND_ATOM_STR) |
|
149 NS_STATIC_ATOM_BUFFER(sAtom3_buffer, THIRD_ATOM_STR) |
|
150 static const nsStaticAtom sAtoms_info[] = { |
|
151 NS_STATIC_ATOM(sAtom1_buffer, &sAtom1), |
|
152 NS_STATIC_ATOM(sAtom2_buffer, &sAtom2), |
|
153 NS_STATIC_ATOM(sAtom3_buffer, &sAtom3), |
|
154 }; |
|
155 |
|
156 bool |
|
157 isStaticAtom(nsIAtom* atom) |
|
158 { |
|
159 // Don't use logic && in order to ensure that all addrefs/releases are always |
|
160 // run, even if one of the tests fail. This allows us to run this code on a |
|
161 // non-static atom without affecting its refcount. |
|
162 return (atom->AddRef() == 2) & |
|
163 (atom->AddRef() == 2) & |
|
164 (atom->AddRef() == 2) & |
|
165 (atom->Release() == 1) & |
|
166 (atom->Release() == 1) & |
|
167 (atom->Release() == 1); |
|
168 } |
|
169 |
|
170 bool |
|
171 test_atomtable() |
|
172 { |
|
173 nsrefcnt count = NS_GetNumberOfAtoms(); |
|
174 |
|
175 nsCOMPtr<nsIAtom> thirdNonPerm = do_GetAtom(THIRD_ATOM_STR); |
|
176 |
|
177 if (isStaticAtom(thirdNonPerm)) |
|
178 return false; |
|
179 |
|
180 if (!thirdNonPerm || NS_GetNumberOfAtoms() != count + 1) |
|
181 return false; |
|
182 |
|
183 NS_RegisterStaticAtoms(sAtoms_info); |
|
184 |
|
185 return sAtom1 && |
|
186 sAtom1->Equals(NS_LITERAL_STRING(FIRST_ATOM_STR)) && |
|
187 isStaticAtom(sAtom1) && |
|
188 sAtom2 && |
|
189 sAtom2->Equals(NS_LITERAL_STRING(SECOND_ATOM_STR)) && |
|
190 isStaticAtom(sAtom2) && |
|
191 sAtom3 && |
|
192 sAtom3->Equals(NS_LITERAL_STRING(THIRD_ATOM_STR)) && |
|
193 isStaticAtom(sAtom3) && |
|
194 NS_GetNumberOfAtoms() == count + 3 && |
|
195 thirdNonPerm == sAtom3; |
|
196 } |
|
197 |
|
198 #define FIRST_PERM_ATOM_STR "first permanent atom. Hello!" |
|
199 #define SECOND_PERM_ATOM_STR "second permanent atom. @World!" |
|
200 |
|
201 bool |
|
202 test_permanent() |
|
203 { |
|
204 nsrefcnt count = NS_GetNumberOfAtoms(); |
|
205 |
|
206 { |
|
207 nsCOMPtr<nsIAtom> first = do_GetAtom(FIRST_PERM_ATOM_STR); |
|
208 if (!first->Equals(NS_LITERAL_STRING(FIRST_PERM_ATOM_STR)) || |
|
209 isStaticAtom(first)) |
|
210 return false; |
|
211 |
|
212 nsCOMPtr<nsIAtom> first_p = |
|
213 NS_NewPermanentAtom(NS_LITERAL_STRING(FIRST_PERM_ATOM_STR)); |
|
214 if (!first_p->Equals(NS_LITERAL_STRING(FIRST_PERM_ATOM_STR)) || |
|
215 !isStaticAtom(first_p) || |
|
216 first != first_p) |
|
217 return false; |
|
218 |
|
219 nsCOMPtr<nsIAtom> second_p = |
|
220 NS_NewPermanentAtom(NS_LITERAL_STRING(SECOND_PERM_ATOM_STR)); |
|
221 if (!second_p->Equals(NS_LITERAL_STRING(SECOND_PERM_ATOM_STR)) || |
|
222 !isStaticAtom(second_p)) |
|
223 return false; |
|
224 |
|
225 nsCOMPtr<nsIAtom> second = do_GetAtom(SECOND_PERM_ATOM_STR); |
|
226 if (!second->Equals(NS_LITERAL_STRING(SECOND_PERM_ATOM_STR)) || |
|
227 !isStaticAtom(second) || |
|
228 second != second_p) |
|
229 return false; |
|
230 } |
|
231 |
|
232 return NS_GetNumberOfAtoms() == count + 2; |
|
233 } |
|
234 |
|
235 typedef bool (*TestFunc)(); |
|
236 |
|
237 static const struct Test |
|
238 { |
|
239 const char* name; |
|
240 TestFunc func; |
|
241 } |
|
242 tests[] = |
|
243 { |
|
244 { "test_basic", test_basic }, |
|
245 { "test_16vs8", test_16vs8 }, |
|
246 { "test_buffersharing", test_buffersharing }, |
|
247 { "test_null", test_null }, |
|
248 { "test_invalid", test_invalid }, |
|
249 // FIXME: Bug 577500 TestAtoms fails when run in dist/bin due to |
|
250 // static atom table already being closed. TestStaticAtoms has similar |
|
251 // failure. |
|
252 #if 0 |
|
253 { "test_atomtable", test_atomtable }, |
|
254 { "test_permanent", test_permanent }, |
|
255 #endif |
|
256 { nullptr, nullptr } |
|
257 }; |
|
258 |
|
259 } |
|
260 |
|
261 using namespace TestAtoms; |
|
262 |
|
263 int main() |
|
264 { |
|
265 { |
|
266 nsCOMPtr<nsIServiceManager> servMan; |
|
267 NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); |
|
268 |
|
269 for (const Test* t = tests; t->name != nullptr; ++t) |
|
270 { |
|
271 printf("%25s : %s\n", t->name, t->func() ? "SUCCESS" : "FAILURE <--"); |
|
272 } |
|
273 } |
|
274 |
|
275 NS_ShutdownXPCOM(nullptr); |
|
276 |
|
277 return 0; |
|
278 } |