|
1 const Ci = Components.interfaces; |
|
2 const Cc = Components.classes; |
|
3 const Cr = Components.results; |
|
4 |
|
5 let testnum = 0; |
|
6 let factory; |
|
7 |
|
8 function parserForFile(filename) { |
|
9 let parser = null; |
|
10 try { |
|
11 let file = do_get_file(filename); |
|
12 do_check_true(!!file); |
|
13 parser = factory.createINIParser(file); |
|
14 do_check_true(!!parser); |
|
15 } catch(e) { |
|
16 dump("INFO | caught error: " + e); |
|
17 // checkParserOutput will handle a null parser when it's expected. |
|
18 } |
|
19 return parser; |
|
20 |
|
21 } |
|
22 |
|
23 function checkParserOutput(parser, expected) { |
|
24 // If the expected output is null, we expect the parser to have |
|
25 // failed (and vice-versa). |
|
26 if (!parser || !expected) { |
|
27 do_check_eq(parser, null); |
|
28 do_check_eq(expected, null); |
|
29 return; |
|
30 } |
|
31 |
|
32 let output = getParserOutput(parser); |
|
33 for (let section in expected) { |
|
34 do_check_true(section in output); |
|
35 for (let key in expected[section]) { |
|
36 do_check_true(key in output[section]); |
|
37 do_check_eq(output[section][key], expected[section][key]); |
|
38 delete output[section][key]; |
|
39 } |
|
40 for (let key in output[section]) |
|
41 do_check_eq(key, "wasn't expecting this key!"); |
|
42 delete output[section]; |
|
43 } |
|
44 for (let section in output) |
|
45 do_check_eq(section, "wasn't expecting this section!"); |
|
46 } |
|
47 |
|
48 function getParserOutput(parser) { |
|
49 let output = {}; |
|
50 |
|
51 let sections = parser.getSections(); |
|
52 do_check_true(!!sections); |
|
53 while (sections.hasMore()) { |
|
54 let section = sections.getNext(); |
|
55 do_check_false(section in output); // catch dupes |
|
56 output[section] = {}; |
|
57 |
|
58 let keys = parser.getKeys(section); |
|
59 do_check_true(!!keys); |
|
60 while (keys.hasMore()) { |
|
61 let key = keys.getNext(); |
|
62 do_check_false(key in output[section]); // catch dupes |
|
63 let value = parser.getString(section, key); |
|
64 output[section][key] = value; |
|
65 } |
|
66 } |
|
67 return output; |
|
68 } |
|
69 |
|
70 function run_test() { |
|
71 try { |
|
72 |
|
73 let testdata = [ |
|
74 { filename: "data/iniparser01.ini", reference: {} }, |
|
75 { filename: "data/iniparser02.ini", reference: {} }, |
|
76 { filename: "data/iniparser03.ini", reference: {} }, |
|
77 { filename: "data/iniparser04.ini", reference: {} }, |
|
78 { filename: "data/iniparser05.ini", reference: {} }, |
|
79 { filename: "data/iniparser06.ini", reference: {} }, |
|
80 { filename: "data/iniparser07.ini", reference: {} }, |
|
81 { filename: "data/iniparser08.ini", reference: { section1: { name1: "" }} }, |
|
82 { filename: "data/iniparser09.ini", reference: { section1: { name1: "value1" } } }, |
|
83 { filename: "data/iniparser10.ini", reference: { section1: { name1: "value1" } } }, |
|
84 { filename: "data/iniparser11.ini", reference: { section1: { name1: "value1" } } }, |
|
85 { filename: "data/iniparser12.ini", reference: { section1: { name1: "value1" } } }, |
|
86 { filename: "data/iniparser13.ini", reference: { section1: { name1: "value1" } } }, |
|
87 { filename: "data/iniparser14.ini", reference: |
|
88 { section1: { name1: "value1", name2: "value2" }, |
|
89 section2: { name1: "value1", name2: "foopy" }} }, |
|
90 { filename: "data/iniparser15.ini", reference: |
|
91 { section1: { name1: "newValue1" }, |
|
92 section2: { name1: "foopy" }} }, |
|
93 { filename: "data/iniparser16.ini", reference: |
|
94 { "☺♫": { "♫": "☻", "♪": "♥" }, |
|
95 "☼": { "♣": "♠", "♦": "♥" }} }, |
|
96 |
|
97 ]; |
|
98 |
|
99 testdata.push( { filename: "data/iniparser01-utf8BOM.ini", |
|
100 reference: testdata[0].reference } ); |
|
101 testdata.push( { filename: "data/iniparser02-utf8BOM.ini", |
|
102 reference: testdata[1].reference } ); |
|
103 testdata.push( { filename: "data/iniparser03-utf8BOM.ini", |
|
104 reference: testdata[2].reference } ); |
|
105 testdata.push( { filename: "data/iniparser04-utf8BOM.ini", |
|
106 reference: testdata[3].reference } ); |
|
107 testdata.push( { filename: "data/iniparser05-utf8BOM.ini", |
|
108 reference: testdata[4].reference } ); |
|
109 testdata.push( { filename: "data/iniparser06-utf8BOM.ini", |
|
110 reference: testdata[5].reference } ); |
|
111 testdata.push( { filename: "data/iniparser07-utf8BOM.ini", |
|
112 reference: testdata[6].reference } ); |
|
113 testdata.push( { filename: "data/iniparser08-utf8BOM.ini", |
|
114 reference: testdata[7].reference } ); |
|
115 testdata.push( { filename: "data/iniparser09-utf8BOM.ini", |
|
116 reference: testdata[8].reference } ); |
|
117 testdata.push( { filename: "data/iniparser10-utf8BOM.ini", |
|
118 reference: testdata[9].reference } ); |
|
119 testdata.push( { filename: "data/iniparser11-utf8BOM.ini", |
|
120 reference: testdata[10].reference } ); |
|
121 testdata.push( { filename: "data/iniparser12-utf8BOM.ini", |
|
122 reference: testdata[11].reference } ); |
|
123 testdata.push( { filename: "data/iniparser13-utf8BOM.ini", |
|
124 reference: testdata[12].reference } ); |
|
125 testdata.push( { filename: "data/iniparser14-utf8BOM.ini", |
|
126 reference: testdata[13].reference } ); |
|
127 testdata.push( { filename: "data/iniparser15-utf8BOM.ini", |
|
128 reference: testdata[14].reference } ); |
|
129 testdata.push( { filename: "data/iniparser16-utf8BOM.ini", |
|
130 reference: testdata[15].reference } ); |
|
131 |
|
132 let os = Cc["@mozilla.org/xre/app-info;1"] |
|
133 .getService(Ci.nsIXULRuntime).OS; |
|
134 if("WINNT" === os) { |
|
135 testdata.push( { filename: "data/iniparser01-utf16leBOM.ini", |
|
136 reference: testdata[0].reference } ); |
|
137 testdata.push( { filename: "data/iniparser02-utf16leBOM.ini", |
|
138 reference: testdata[1].reference } ); |
|
139 testdata.push( { filename: "data/iniparser03-utf16leBOM.ini", |
|
140 reference: testdata[2].reference } ); |
|
141 testdata.push( { filename: "data/iniparser04-utf16leBOM.ini", |
|
142 reference: testdata[3].reference } ); |
|
143 testdata.push( { filename: "data/iniparser05-utf16leBOM.ini", |
|
144 reference: testdata[4].reference } ); |
|
145 testdata.push( { filename: "data/iniparser06-utf16leBOM.ini", |
|
146 reference: testdata[5].reference } ); |
|
147 testdata.push( { filename: "data/iniparser07-utf16leBOM.ini", |
|
148 reference: testdata[6].reference } ); |
|
149 testdata.push( { filename: "data/iniparser08-utf16leBOM.ini", |
|
150 reference: testdata[7].reference } ); |
|
151 testdata.push( { filename: "data/iniparser09-utf16leBOM.ini", |
|
152 reference: testdata[8].reference } ); |
|
153 testdata.push( { filename: "data/iniparser10-utf16leBOM.ini", |
|
154 reference: testdata[9].reference } ); |
|
155 testdata.push( { filename: "data/iniparser11-utf16leBOM.ini", |
|
156 reference: testdata[10].reference } ); |
|
157 testdata.push( { filename: "data/iniparser12-utf16leBOM.ini", |
|
158 reference: testdata[11].reference } ); |
|
159 testdata.push( { filename: "data/iniparser13-utf16leBOM.ini", |
|
160 reference: testdata[12].reference } ); |
|
161 testdata.push( { filename: "data/iniparser14-utf16leBOM.ini", |
|
162 reference: testdata[13].reference } ); |
|
163 testdata.push( { filename: "data/iniparser15-utf16leBOM.ini", |
|
164 reference: testdata[14].reference } ); |
|
165 testdata.push( { filename: "data/iniparser16-utf16leBOM.ini", |
|
166 reference: testdata[15].reference } ); |
|
167 } |
|
168 |
|
169 /* ========== 0 ========== */ |
|
170 factory = Cc["@mozilla.org/xpcom/ini-processor-factory;1"]. |
|
171 getService(Ci.nsIINIParserFactory); |
|
172 do_check_true(!!factory); |
|
173 |
|
174 // Test reading from a variety of files. While we're at it, write out each one |
|
175 // and read it back to ensure that nothing changed. |
|
176 while (testnum < testdata.length) { |
|
177 dump("\nINFO | test #" + ++testnum); |
|
178 let filename = testdata[testnum -1].filename; |
|
179 dump(", filename " + filename + "\n"); |
|
180 let parser = parserForFile(filename); |
|
181 checkParserOutput(parser, testdata[testnum - 1].reference); |
|
182 if (!parser) |
|
183 continue; |
|
184 do_check_true(parser instanceof Ci.nsIINIParserWriter); |
|
185 // write contents out to a new file |
|
186 let newfilename = filename + ".new"; |
|
187 let newfile = do_get_file(filename); |
|
188 newfile.leafName += ".new"; |
|
189 parser.writeFile(newfile); |
|
190 // read new file and make sure the contents are the same. |
|
191 parser = parserForFile(newfilename); |
|
192 checkParserOutput(parser, testdata[testnum - 1].reference); |
|
193 // cleanup after the test |
|
194 newfile.remove(false); |
|
195 } |
|
196 |
|
197 dump("INFO | test #" + ++testnum + "\n"); |
|
198 |
|
199 // test writing to a new file. |
|
200 let newfile = do_get_file("data/"); |
|
201 newfile.append("nonexistent-file.ini"); |
|
202 if (newfile.exists()) |
|
203 newfile.remove(false); |
|
204 do_check_false(newfile.exists()); |
|
205 |
|
206 let parser = factory.createINIParser(newfile); |
|
207 do_check_true(!!parser); |
|
208 do_check_true(parser instanceof Ci.nsIINIParserWriter); |
|
209 checkParserOutput(parser, {}); |
|
210 parser.writeFile(); |
|
211 do_check_true(newfile.exists()); |
|
212 |
|
213 // test adding a new section and new key |
|
214 parser.setString("section", "key", "value"); |
|
215 parser.writeFile(); |
|
216 do_check_true(newfile.exists()); |
|
217 checkParserOutput(parser, {section: {key: "value"} }); |
|
218 // read it in again, check for same data. |
|
219 parser = parserForFile("data/nonexistent-file.ini"); |
|
220 checkParserOutput(parser, {section: {key: "value"} }); |
|
221 // cleanup after the test |
|
222 newfile.remove(false); |
|
223 |
|
224 dump("INFO | test #" + ++testnum + "\n"); |
|
225 |
|
226 // test modifying a existing key's value (in an existing section) |
|
227 parser = parserForFile("data/iniparser09.ini"); |
|
228 checkParserOutput(parser, {section1: {name1: "value1"} }); |
|
229 |
|
230 do_check_true(parser instanceof Ci.nsIINIParserWriter); |
|
231 parser.setString("section1", "name1", "value2"); |
|
232 checkParserOutput(parser, {section1: {name1: "value2"} }); |
|
233 |
|
234 dump("INFO | test #" + ++testnum + "\n"); |
|
235 |
|
236 // test trying to set illegal characters |
|
237 let caughtError; |
|
238 caughtError = false; |
|
239 checkParserOutput(parser, {section1: {name1: "value2"} }); |
|
240 |
|
241 // Bad characters in section name |
|
242 try { parser.SetString("bad\0", "ok", "ok"); } catch (e) { caughtError = true; } |
|
243 do_check_true(caughtError); |
|
244 caughtError = false; |
|
245 try { parser.SetString("bad\r", "ok", "ok"); } catch (e) { caughtError = true; } |
|
246 do_check_true(caughtError); |
|
247 caughtError = false; |
|
248 try { parser.SetString("bad\n", "ok", "ok"); } catch (e) { caughtError = true; } |
|
249 do_check_true(caughtError); |
|
250 caughtError = false; |
|
251 try { parser.SetString("bad[", "ok", "ok"); } catch (e) { caughtError = true; } |
|
252 do_check_true(caughtError); |
|
253 caughtError = false; |
|
254 try { parser.SetString("bad]", "ok", "ok"); } catch (e) { caughtError = true; } |
|
255 do_check_true(caughtError); |
|
256 |
|
257 // Bad characters in key name |
|
258 caughtError = false; |
|
259 try { parser.SetString("ok", "bad\0", "ok"); } catch (e) { caughtError = true; } |
|
260 do_check_true(caughtError); |
|
261 caughtError = false; |
|
262 try { parser.SetString("ok", "bad\r", "ok"); } catch (e) { caughtError = true; } |
|
263 do_check_true(caughtError); |
|
264 caughtError = false; |
|
265 try { parser.SetString("ok", "bad\n", "ok"); } catch (e) { caughtError = true; } |
|
266 do_check_true(caughtError); |
|
267 caughtError = false; |
|
268 try { parser.SetString("ok", "bad=", "ok"); } catch (e) { caughtError = true; } |
|
269 do_check_true(caughtError); |
|
270 |
|
271 // Bad characters in value |
|
272 caughtError = false; |
|
273 try { parser.SetString("ok", "ok", "bad\0"); } catch (e) { caughtError = true; } |
|
274 do_check_true(caughtError); |
|
275 caughtError = false; |
|
276 try { parser.SetString("ok", "ok", "bad\r"); } catch (e) { caughtError = true; } |
|
277 do_check_true(caughtError); |
|
278 caughtError = false; |
|
279 try { parser.SetString("ok", "ok", "bad\n"); } catch (e) { caughtError = true; } |
|
280 do_check_true(caughtError); |
|
281 caughtError = false; |
|
282 try { parser.SetString("ok", "ok", "bad="); } catch (e) { caughtError = true; } |
|
283 do_check_true(caughtError); |
|
284 |
|
285 } catch(e) { |
|
286 throw "FAILED in test #" + testnum + " -- " + e; |
|
287 } |
|
288 } |