var testnum = 0; var factory; function parserForFile(filename) { let parser = null; try { let file = do_get_file(filename); Assert.ok(!!file); parser = factory.createINIParser(file); Assert.ok(!!parser); } catch (e) { dump("INFO | caught error: " + e); // checkParserOutput will handle a null parser when it's expected. } return parser; } function checkParserOutput(parser, expected) { // If the expected output is null, we expect the parser to have // failed (and vice-versa). if (!parser || !expected) { Assert.equal(parser, null); Assert.equal(expected, null); return; } let output = getParserOutput(parser); for (let section in expected) { Assert.ok(section in output); for (let key in expected[section]) { Assert.ok(key in output[section]); Assert.equal(output[section][key], expected[section][key]); delete output[section][key]; } for (let key in output[section]) { Assert.equal(key, "wasn't expecting this key!"); } delete output[section]; } for (let section in output) { Assert.equal(section, "wasn't expecting this section!"); } } function getParserOutput(parser) { let output = {}; for (let section of parser.getSections()) { Assert.equal(false, section in output); // catch dupes output[section] = {}; for (let key of parser.getKeys(section)) { Assert.equal(false, key in output[section]); // catch dupes let value = parser.getString(section, key); output[section][key] = value; } } return output; } function run_test() { try { var testdata = [ { filename: "data/iniparser01.ini", reference: {} }, { filename: "data/iniparser02.ini", reference: {} }, { filename: "data/iniparser03.ini", reference: {} }, { filename: "data/iniparser04.ini", reference: {} }, { filename: "data/iniparser05.ini", reference: {} }, { filename: "data/iniparser06.ini", reference: {} }, { filename: "data/iniparser07.ini", reference: {} }, { filename: "data/iniparser08.ini", reference: { section1: { name1: "" } }, }, { filename: "data/iniparser09.ini", reference: { section1: { name1: "value1" } }, }, { filename: "data/iniparser10.ini", reference: { section1: { name1: "value1" } }, }, { filename: "data/iniparser11.ini", reference: { section1: { name1: "value1" } }, }, { filename: "data/iniparser12.ini", reference: { section1: { name1: "value1" } }, }, { filename: "data/iniparser13.ini", reference: { section1: { name1: "value1" } }, }, { filename: "data/iniparser14.ini", reference: { section1: { name1: "value1", name2: "value2" }, section2: { name1: "value1", name2: "foopy" }, }, }, { filename: "data/iniparser15.ini", reference: { section1: { name1: "newValue1" }, section2: { name1: "foopy" }, }, }, { filename: "data/iniparser16.ini", reference: { "☺♫": { "♫": "☻", "♪": "♥" }, "☼": { "♣": "♠", "♦": "♥" }, }, }, { filename: "data/iniparser17.ini", reference: { section: { key: "" } } }, ]; testdata.push({ filename: "data/iniparser01-utf8BOM.ini", reference: testdata[0].reference, }); testdata.push({ filename: "data/iniparser02-utf8BOM.ini", reference: testdata[1].reference, }); testdata.push({ filename: "data/iniparser03-utf8BOM.ini", reference: testdata[2].reference, }); testdata.push({ filename: "data/iniparser04-utf8BOM.ini", reference: testdata[3].reference, }); testdata.push({ filename: "data/iniparser05-utf8BOM.ini", reference: testdata[4].reference, }); testdata.push({ filename: "data/iniparser06-utf8BOM.ini", reference: testdata[5].reference, }); testdata.push({ filename: "data/iniparser07-utf8BOM.ini", reference: testdata[6].reference, }); testdata.push({ filename: "data/iniparser08-utf8BOM.ini", reference: testdata[7].reference, }); testdata.push({ filename: "data/iniparser09-utf8BOM.ini", reference: testdata[8].reference, }); testdata.push({ filename: "data/iniparser10-utf8BOM.ini", reference: testdata[9].reference, }); testdata.push({ filename: "data/iniparser11-utf8BOM.ini", reference: testdata[10].reference, }); testdata.push({ filename: "data/iniparser12-utf8BOM.ini", reference: testdata[11].reference, }); testdata.push({ filename: "data/iniparser13-utf8BOM.ini", reference: testdata[12].reference, }); testdata.push({ filename: "data/iniparser14-utf8BOM.ini", reference: testdata[13].reference, }); testdata.push({ filename: "data/iniparser15-utf8BOM.ini", reference: testdata[14].reference, }); testdata.push({ filename: "data/iniparser16-utf8BOM.ini", reference: testdata[15].reference, }); // Intentional test for appInfo that can't be preloaded. // eslint-disable-next-line mozilla/use-services let os = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS; if ("WINNT" === os) { testdata.push({ filename: "data/iniparser01-utf16leBOM.ini", reference: testdata[0].reference, }); testdata.push({ filename: "data/iniparser02-utf16leBOM.ini", reference: testdata[1].reference, }); testdata.push({ filename: "data/iniparser03-utf16leBOM.ini", reference: testdata[2].reference, }); testdata.push({ filename: "data/iniparser04-utf16leBOM.ini", reference: testdata[3].reference, }); testdata.push({ filename: "data/iniparser05-utf16leBOM.ini", reference: testdata[4].reference, }); testdata.push({ filename: "data/iniparser06-utf16leBOM.ini", reference: testdata[5].reference, }); testdata.push({ filename: "data/iniparser07-utf16leBOM.ini", reference: testdata[6].reference, }); testdata.push({ filename: "data/iniparser08-utf16leBOM.ini", reference: testdata[7].reference, }); testdata.push({ filename: "data/iniparser09-utf16leBOM.ini", reference: testdata[8].reference, }); testdata.push({ filename: "data/iniparser10-utf16leBOM.ini", reference: testdata[9].reference, }); testdata.push({ filename: "data/iniparser11-utf16leBOM.ini", reference: testdata[10].reference, }); testdata.push({ filename: "data/iniparser12-utf16leBOM.ini", reference: testdata[11].reference, }); testdata.push({ filename: "data/iniparser13-utf16leBOM.ini", reference: testdata[12].reference, }); testdata.push({ filename: "data/iniparser14-utf16leBOM.ini", reference: testdata[13].reference, }); testdata.push({ filename: "data/iniparser15-utf16leBOM.ini", reference: testdata[14].reference, }); testdata.push({ filename: "data/iniparser16-utf16leBOM.ini", reference: testdata[15].reference, }); } /* ========== 0 ========== */ factory = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].getService( Ci.nsIINIParserFactory ); Assert.ok(!!factory); // Test reading from a variety of files and strings. While we're at it, // write out each one and read it back to ensure that nothing changed. while (testnum < testdata.length) { dump("\nINFO | test #" + ++testnum); let filename = testdata[testnum - 1].filename; dump(", filename " + filename + "\n"); let parser = parserForFile(filename); checkParserOutput(parser, testdata[testnum - 1].reference); if (!parser) { continue; } Assert.ok(parser instanceof Ci.nsIINIParserWriter); // write contents out to a new file let newfilename = filename + ".new"; let newfile = do_get_file(filename); newfile.leafName += ".new"; parser.writeFile(newfile); // read new file and make sure the contents are the same. parser = parserForFile(newfilename); checkParserOutput(parser, testdata[testnum - 1].reference); // cleanup after the test newfile.remove(false); // ensure that `writeString` works correctly Assert.ok(parser instanceof Ci.nsIINIParserWriter); let formatted = parser.writeToString(); parser = factory.createINIParser(null); // re-parsing the formatted string is the easiest // way to verify correctness... parser.initFromString(formatted); checkParserOutput(parser, testdata[testnum - 1].reference); } dump("INFO | test #" + ++testnum + "\n"); // test writing to a new file. var newfile = do_get_file("data/"); newfile.append("nonexistent-file.ini"); if (newfile.exists()) { newfile.remove(false); } Assert.ok(!newfile.exists()); try { var parser = factory.createINIParser(newfile); Assert.ok(false, "Should have thrown an exception"); } catch (e) { Assert.equal( e.result, Cr.NS_ERROR_FILE_NOT_FOUND, "Caught a file not found exception" ); } parser = factory.createINIParser(); Assert.ok(!!parser); Assert.ok(parser instanceof Ci.nsIINIParserWriter); checkParserOutput(parser, {}); parser.writeFile(newfile); Assert.ok(newfile.exists()); // test adding a new section and new key parser.setString("section", "key", "value"); parser.setString("section", "key2", ""); parser.writeFile(newfile); Assert.ok(newfile.exists()); checkParserOutput(parser, { section: { key: "value", key2: "" } }); // read it in again, check for same data. parser = parserForFile("data/nonexistent-file.ini"); checkParserOutput(parser, { section: { key: "value", key2: "" } }); // cleanup after the test newfile.remove(false); dump("INFO | test #" + ++testnum + "\n"); // test modifying a existing key's value (in an existing section) parser = parserForFile("data/iniparser09.ini"); checkParserOutput(parser, { section1: { name1: "value1" } }); Assert.ok(parser instanceof Ci.nsIINIParserWriter); parser.setString("section1", "name1", "value2"); checkParserOutput(parser, { section1: { name1: "value2" } }); dump("INFO | test #" + ++testnum + "\n"); // test trying to set illegal characters var caughtError; caughtError = null; checkParserOutput(parser, { section1: { name1: "value2" } }); // Bad characters in section name try { parser.setString("bad\0", "ok", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("bad\r", "ok", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("bad\n", "ok", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("bad[", "ok", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("bad]", "ok", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("", "ok", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); // Bad characters in key name caughtError = null; try { parser.setString("ok", "bad\0", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("ok", "bad\r", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("ok", "bad\n", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("ok", "bad=", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("ok", "", "ok"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); // Bad characters in value caughtError = null; try { parser.setString("ok", "ok", "bad\0"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("ok", "ok", "bad\r"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("ok", "ok", "bad\n"); } catch (e) { caughtError = e; } Assert.ok(caughtError); Assert.equal(caughtError.result, Cr.NS_ERROR_INVALID_ARG); caughtError = null; try { parser.setString("ok", "ok", "good="); } catch (e) { caughtError = e; } Assert.ok(!caughtError); caughtError = null; } catch (e) { throw new Error(`FAILED in test #${testnum} -- ${e}`); } }