no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / xpcom / tests / unit / test_iniParser.js
bloba586c4c0608605c3aef7089ea5a4cdd240fec0f2
1 var testnum = 0;
2 var factory;
4 function parserForFile(filename) {
5   let parser = null;
6   try {
7     let file = do_get_file(filename);
8     Assert.ok(!!file);
9     parser = factory.createINIParser(file);
10     Assert.ok(!!parser);
11   } catch (e) {
12     dump("INFO | caught error: " + e);
13     // checkParserOutput will handle a null parser when it's expected.
14   }
15   return parser;
18 function checkParserOutput(parser, expected) {
19   // If the expected output is null, we expect the parser to have
20   // failed (and vice-versa).
21   if (!parser || !expected) {
22     Assert.equal(parser, null);
23     Assert.equal(expected, null);
24     return;
25   }
27   let output = getParserOutput(parser);
28   for (let section in expected) {
29     Assert.ok(section in output);
30     for (let key in expected[section]) {
31       Assert.ok(key in output[section]);
32       Assert.equal(output[section][key], expected[section][key]);
33       delete output[section][key];
34     }
35     for (let key in output[section]) {
36       Assert.equal(key, "wasn't expecting this key!");
37     }
38     delete output[section];
39   }
40   for (let section in output) {
41     Assert.equal(section, "wasn't expecting this section!");
42   }
45 function getParserOutput(parser) {
46   let output = {};
48   for (let section of parser.getSections()) {
49     Assert.equal(false, section in output); // catch dupes
50     output[section] = {};
52     for (let key of parser.getKeys(section)) {
53       Assert.equal(false, key in output[section]); // catch dupes
54       let value = parser.getString(section, key);
55       output[section][key] = value;
56     }
57   }
58   return output;
61 function run_test() {
62   try {
63     var testdata = [
64       { filename: "data/iniparser01.ini", reference: {} },
65       { filename: "data/iniparser02.ini", reference: {} },
66       { filename: "data/iniparser03.ini", reference: {} },
67       { filename: "data/iniparser04.ini", reference: {} },
68       { filename: "data/iniparser05.ini", reference: {} },
69       { filename: "data/iniparser06.ini", reference: {} },
70       { filename: "data/iniparser07.ini", reference: {} },
71       {
72         filename: "data/iniparser08.ini",
73         reference: { section1: { name1: "" } },
74       },
75       {
76         filename: "data/iniparser09.ini",
77         reference: { section1: { name1: "value1" } },
78       },
79       {
80         filename: "data/iniparser10.ini",
81         reference: { section1: { name1: "value1" } },
82       },
83       {
84         filename: "data/iniparser11.ini",
85         reference: { section1: { name1: "value1" } },
86       },
87       {
88         filename: "data/iniparser12.ini",
89         reference: { section1: { name1: "value1" } },
90       },
91       {
92         filename: "data/iniparser13.ini",
93         reference: { section1: { name1: "value1" } },
94       },
95       {
96         filename: "data/iniparser14.ini",
97         reference: {
98           section1: { name1: "value1", name2: "value2" },
99           section2: { name1: "value1", name2: "foopy" },
100         },
101       },
102       {
103         filename: "data/iniparser15.ini",
104         reference: {
105           section1: { name1: "newValue1" },
106           section2: { name1: "foopy" },
107         },
108       },
109       {
110         filename: "data/iniparser16.ini",
111         reference: {
112           "☺♫": { "♫": "☻", "♪": "♥" },
113           "☼": { "♣": "♠", "♦": "♥" },
114         },
115       },
116       { filename: "data/iniparser17.ini", reference: { section: { key: "" } } },
117     ];
119     testdata.push({
120       filename: "data/iniparser01-utf8BOM.ini",
121       reference: testdata[0].reference,
122     });
123     testdata.push({
124       filename: "data/iniparser02-utf8BOM.ini",
125       reference: testdata[1].reference,
126     });
127     testdata.push({
128       filename: "data/iniparser03-utf8BOM.ini",
129       reference: testdata[2].reference,
130     });
131     testdata.push({
132       filename: "data/iniparser04-utf8BOM.ini",
133       reference: testdata[3].reference,
134     });
135     testdata.push({
136       filename: "data/iniparser05-utf8BOM.ini",
137       reference: testdata[4].reference,
138     });
139     testdata.push({
140       filename: "data/iniparser06-utf8BOM.ini",
141       reference: testdata[5].reference,
142     });
143     testdata.push({
144       filename: "data/iniparser07-utf8BOM.ini",
145       reference: testdata[6].reference,
146     });
147     testdata.push({
148       filename: "data/iniparser08-utf8BOM.ini",
149       reference: testdata[7].reference,
150     });
151     testdata.push({
152       filename: "data/iniparser09-utf8BOM.ini",
153       reference: testdata[8].reference,
154     });
155     testdata.push({
156       filename: "data/iniparser10-utf8BOM.ini",
157       reference: testdata[9].reference,
158     });
159     testdata.push({
160       filename: "data/iniparser11-utf8BOM.ini",
161       reference: testdata[10].reference,
162     });
163     testdata.push({
164       filename: "data/iniparser12-utf8BOM.ini",
165       reference: testdata[11].reference,
166     });
167     testdata.push({
168       filename: "data/iniparser13-utf8BOM.ini",
169       reference: testdata[12].reference,
170     });
171     testdata.push({
172       filename: "data/iniparser14-utf8BOM.ini",
173       reference: testdata[13].reference,
174     });
175     testdata.push({
176       filename: "data/iniparser15-utf8BOM.ini",
177       reference: testdata[14].reference,
178     });
179     testdata.push({
180       filename: "data/iniparser16-utf8BOM.ini",
181       reference: testdata[15].reference,
182     });
184     // Intentional test for appInfo that can't be preloaded.
185     // eslint-disable-next-line mozilla/use-services
186     let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
187     if ("WINNT" === os) {
188       testdata.push({
189         filename: "data/iniparser01-utf16leBOM.ini",
190         reference: testdata[0].reference,
191       });
192       testdata.push({
193         filename: "data/iniparser02-utf16leBOM.ini",
194         reference: testdata[1].reference,
195       });
196       testdata.push({
197         filename: "data/iniparser03-utf16leBOM.ini",
198         reference: testdata[2].reference,
199       });
200       testdata.push({
201         filename: "data/iniparser04-utf16leBOM.ini",
202         reference: testdata[3].reference,
203       });
204       testdata.push({
205         filename: "data/iniparser05-utf16leBOM.ini",
206         reference: testdata[4].reference,
207       });
208       testdata.push({
209         filename: "data/iniparser06-utf16leBOM.ini",
210         reference: testdata[5].reference,
211       });
212       testdata.push({
213         filename: "data/iniparser07-utf16leBOM.ini",
214         reference: testdata[6].reference,
215       });
216       testdata.push({
217         filename: "data/iniparser08-utf16leBOM.ini",
218         reference: testdata[7].reference,
219       });
220       testdata.push({
221         filename: "data/iniparser09-utf16leBOM.ini",
222         reference: testdata[8].reference,
223       });
224       testdata.push({
225         filename: "data/iniparser10-utf16leBOM.ini",
226         reference: testdata[9].reference,
227       });
228       testdata.push({
229         filename: "data/iniparser11-utf16leBOM.ini",
230         reference: testdata[10].reference,
231       });
232       testdata.push({
233         filename: "data/iniparser12-utf16leBOM.ini",
234         reference: testdata[11].reference,
235       });
236       testdata.push({
237         filename: "data/iniparser13-utf16leBOM.ini",
238         reference: testdata[12].reference,
239       });
240       testdata.push({
241         filename: "data/iniparser14-utf16leBOM.ini",
242         reference: testdata[13].reference,
243       });
244       testdata.push({
245         filename: "data/iniparser15-utf16leBOM.ini",
246         reference: testdata[14].reference,
247       });
248       testdata.push({
249         filename: "data/iniparser16-utf16leBOM.ini",
250         reference: testdata[15].reference,
251       });
252     }
254     /* ========== 0 ========== */
255     factory = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].getService(
256       Ci.nsIINIParserFactory
257     );
258     Assert.ok(!!factory);
260     // Test reading from a variety of files and strings. While we're at it,
261     // write out each one and read it back to ensure that nothing changed.
262     while (testnum < testdata.length) {
263       dump("\nINFO | test #" + ++testnum);
264       let filename = testdata[testnum - 1].filename;
265       dump(", filename " + filename + "\n");
266       let parser = parserForFile(filename);
267       checkParserOutput(parser, testdata[testnum - 1].reference);
268       if (!parser) {
269         continue;
270       }
271       Assert.ok(parser instanceof Ci.nsIINIParserWriter);
272       // write contents out to a new file
273       let newfilename = filename + ".new";
274       let newfile = do_get_file(filename);
275       newfile.leafName += ".new";
276       parser.writeFile(newfile);
277       // read new file and make sure the contents are the same.
278       parser = parserForFile(newfilename);
279       checkParserOutput(parser, testdata[testnum - 1].reference);
280       // cleanup after the test
281       newfile.remove(false);
283       // ensure that `writeString` works correctly
284       Assert.ok(parser instanceof Ci.nsIINIParserWriter);
285       let formatted = parser.writeToString();
286       parser = factory.createINIParser(null);
287       // re-parsing the formatted string is the easiest
288       // way to verify correctness...
289       parser.initFromString(formatted);
290       checkParserOutput(parser, testdata[testnum - 1].reference);
291     }
293     dump("INFO | test #" + ++testnum + "\n");
295     // test writing to a new file.
296     var newfile = do_get_file("data/");
297     newfile.append("nonexistent-file.ini");
298     if (newfile.exists()) {
299       newfile.remove(false);
300     }
301     Assert.ok(!newfile.exists());
303     try {
304       var parser = factory.createINIParser(newfile);
305       Assert.ok(false, "Should have thrown an exception");
306     } catch (e) {
307       Assert.equal(
308         e.result,
309         Cr.NS_ERROR_FILE_NOT_FOUND,
310         "Caught a file not found exception"
311       );
312     }
313     parser = factory.createINIParser();
314     Assert.ok(!!parser);
315     Assert.ok(parser instanceof Ci.nsIINIParserWriter);
316     checkParserOutput(parser, {});
317     parser.writeFile(newfile);
318     Assert.ok(newfile.exists());
320     // test adding a new section and new key
321     parser.setString("section", "key", "value");
322     parser.setString("section", "key2", "");
323     parser.writeFile(newfile);
324     Assert.ok(newfile.exists());
325     checkParserOutput(parser, { section: { key: "value", key2: "" } });
326     // read it in again, check for same data.
327     parser = parserForFile("data/nonexistent-file.ini");
328     checkParserOutput(parser, { section: { key: "value", key2: "" } });
329     // cleanup after the test
330     newfile.remove(false);
332     dump("INFO | test #" + ++testnum + "\n");
334     // test modifying a existing key's value (in an existing section)
335     parser = parserForFile("data/iniparser09.ini");
336     checkParserOutput(parser, { section1: { name1: "value1" } });
338     Assert.ok(parser instanceof Ci.nsIINIParserWriter);
339     parser.setString("section1", "name1", "value2");
340     checkParserOutput(parser, { section1: { name1: "value2" } });
342     dump("INFO | test #" + ++testnum + "\n");
344     // test trying to set illegal characters
345     var caughtError;
346     caughtError = null;
347     checkParserOutput(parser, { section1: { name1: "value2" } });
349     // Bad characters in section name
350     try {
351       parser.setString("bad\0", "ok", "ok");
352     } catch (e) {
353       caughtError = e;
354     }
355     Assert.ok(caughtError);
356     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
357     caughtError = null;
358     try {
359       parser.setString("bad\r", "ok", "ok");
360     } catch (e) {
361       caughtError = e;
362     }
363     Assert.ok(caughtError);
364     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
365     caughtError = null;
366     try {
367       parser.setString("bad\n", "ok", "ok");
368     } catch (e) {
369       caughtError = e;
370     }
371     Assert.ok(caughtError);
372     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
373     caughtError = null;
374     try {
375       parser.setString("bad[", "ok", "ok");
376     } catch (e) {
377       caughtError = e;
378     }
379     Assert.ok(caughtError);
380     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
381     caughtError = null;
382     try {
383       parser.setString("bad]", "ok", "ok");
384     } catch (e) {
385       caughtError = e;
386     }
387     Assert.ok(caughtError);
388     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
389     caughtError = null;
390     try {
391       parser.setString("", "ok", "ok");
392     } catch (e) {
393       caughtError = e;
394     }
395     Assert.ok(caughtError);
396     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
398     // Bad characters in key name
399     caughtError = null;
400     try {
401       parser.setString("ok", "bad\0", "ok");
402     } catch (e) {
403       caughtError = e;
404     }
405     Assert.ok(caughtError);
406     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
407     caughtError = null;
408     try {
409       parser.setString("ok", "bad\r", "ok");
410     } catch (e) {
411       caughtError = e;
412     }
413     Assert.ok(caughtError);
414     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
415     caughtError = null;
416     try {
417       parser.setString("ok", "bad\n", "ok");
418     } catch (e) {
419       caughtError = e;
420     }
421     Assert.ok(caughtError);
422     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
423     caughtError = null;
424     try {
425       parser.setString("ok", "bad=", "ok");
426     } catch (e) {
427       caughtError = e;
428     }
429     Assert.ok(caughtError);
430     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
431     caughtError = null;
432     try {
433       parser.setString("ok", "", "ok");
434     } catch (e) {
435       caughtError = e;
436     }
437     Assert.ok(caughtError);
438     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
440     // Bad characters in value
441     caughtError = null;
442     try {
443       parser.setString("ok", "ok", "bad\0");
444     } catch (e) {
445       caughtError = e;
446     }
447     Assert.ok(caughtError);
448     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
449     caughtError = null;
450     try {
451       parser.setString("ok", "ok", "bad\r");
452     } catch (e) {
453       caughtError = e;
454     }
455     Assert.ok(caughtError);
456     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
457     caughtError = null;
458     try {
459       parser.setString("ok", "ok", "bad\n");
460     } catch (e) {
461       caughtError = e;
462     }
463     Assert.ok(caughtError);
464     Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG);
465     caughtError = null;
466     try {
467       parser.setString("ok", "ok", "good=");
468     } catch (e) {
469       caughtError = e;
470     }
471     Assert.ok(!caughtError);
472     caughtError = null;
473   } catch (e) {
474     throw new Error(`FAILED in test #${testnum} -- ${e}`);
475   }