mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-01 15:55:45 +00:00

This adds a lot more unit tests for Common::INIFile and fixes some small problems identified during their creation. Specifically: * addSection() did not check the validity of the section name, which meant it was possible to create a section that could not then be operated on by the other functions (which all check validity) * If allowNonEnglishCharacters was set, it was possible to create a key or section name starting with '[' or '#', or including a carriage return. This would not read back in correctly. * Blank section and key names were considered valid, but neither would be read back in correctly. * The struct documentation did not mention whitespcae handling or that comments include the '#' and carriage return.
173 lines
4.7 KiB
C++
173 lines
4.7 KiB
C++
#include <cxxtest/TestSuite.h>
|
|
|
|
#include "common/ini-file.h"
|
|
#include "common/memstream.h"
|
|
|
|
|
|
class IniFileTestSuite : public CxxTest::TestSuite {
|
|
public:
|
|
void test_blank_ini_file() {
|
|
Common::INIFile inifile;
|
|
|
|
TS_ASSERT(!inifile.hasSection("abc"));
|
|
|
|
Common::INIFile::SectionList sections = inifile.getSections();
|
|
TS_ASSERT_EQUALS(sections.size(), 0);
|
|
}
|
|
|
|
void test_simple_ini_file() {
|
|
static const unsigned char inistr[] = "#comment\n[s]\nabc=1\ndef=xyz";
|
|
Common::MemoryReadStream ms(inistr, sizeof(inistr));
|
|
Common::INIFile inifile;
|
|
bool result = inifile.loadFromStream(ms);
|
|
TS_ASSERT(result);
|
|
|
|
Common::INIFile::SectionList sections = inifile.getSections();
|
|
TS_ASSERT_EQUALS(sections.size(), 1);
|
|
|
|
TS_ASSERT(inifile.hasSection("s"));
|
|
TS_ASSERT(inifile.hasKey("abc", "s"));
|
|
|
|
Common::String val;
|
|
TS_ASSERT(inifile.getKey("abc", "s", val));
|
|
TS_ASSERT_EQUALS(val, "1");
|
|
TS_ASSERT(inifile.getKey("def", "s", val));
|
|
TS_ASSERT_EQUALS(val, "xyz");
|
|
inifile.setKey("abc", "s", "newval");
|
|
TS_ASSERT(inifile.getKey("abc", "s", val));
|
|
TS_ASSERT_EQUALS(val, "newval");
|
|
}
|
|
|
|
void test_multisection_ini_file() {
|
|
static const unsigned char inistr[] = "[s]\nabc=1\ndef=xyz\n#comment=no\n[empty]\n\n[s2]\n abc = 2 ";
|
|
Common::MemoryReadStream ms(inistr, sizeof(inistr));
|
|
Common::INIFile inifile;
|
|
bool result = inifile.loadFromStream(ms);
|
|
TS_ASSERT(result);
|
|
|
|
Common::INIFile::SectionList sections = inifile.getSections();
|
|
TS_ASSERT_EQUALS(sections.size(), 3);
|
|
|
|
TS_ASSERT(inifile.hasSection("s"));
|
|
TS_ASSERT(inifile.hasSection("empty"));
|
|
TS_ASSERT(inifile.hasSection("s2"));
|
|
TS_ASSERT(inifile.hasKey("abc", "s"));
|
|
TS_ASSERT(inifile.hasKey("abc", "s2"));
|
|
|
|
Common::String val;
|
|
TS_ASSERT(inifile.getKey("abc", "s", val));
|
|
TS_ASSERT_EQUALS(val, "1");
|
|
TS_ASSERT(inifile.getKey("abc", "s2", val));
|
|
TS_ASSERT_EQUALS(val, "2");
|
|
|
|
inifile.clear();
|
|
sections = inifile.getSections();
|
|
TS_ASSERT_EQUALS(sections.size(), 0);
|
|
TS_ASSERT(!inifile.hasSection("s"));
|
|
}
|
|
|
|
void test_modify_ini_file() {
|
|
Common::INIFile inifile;
|
|
|
|
TS_ASSERT(!inifile.hasSection("s"));
|
|
inifile.addSection("s");
|
|
TS_ASSERT(inifile.hasSection("s"));
|
|
|
|
inifile.setKey("k", "s", "val");
|
|
TS_ASSERT(inifile.hasKey("k", "s"));
|
|
|
|
inifile.setKey("k2", "s", "val2");
|
|
TS_ASSERT(inifile.hasKey("k2", "s"));
|
|
inifile.removeKey("k2", "s");
|
|
TS_ASSERT(!inifile.hasKey("k2", "s"));
|
|
|
|
inifile.renameSection("s", "t");
|
|
TS_ASSERT(!inifile.hasSection("s"));
|
|
TS_ASSERT(inifile.hasSection("t"));
|
|
TS_ASSERT(inifile.hasKey("k", "t"));
|
|
|
|
inifile.removeSection("t");
|
|
TS_ASSERT(!inifile.hasSection("t"));
|
|
}
|
|
|
|
void test_name_validity() {
|
|
Common::INIFile inifile;
|
|
|
|
inifile.addSection("s*");
|
|
TS_ASSERT(!inifile.hasSection("s*"));
|
|
|
|
inifile.addSection("");
|
|
TS_ASSERT(!inifile.hasSection(""));
|
|
|
|
// Valid is alphanum plus [-_:. ]
|
|
inifile.addSection("sEcT10N -_..Name:");
|
|
TS_ASSERT(inifile.hasSection("sEcT10N -_..Name:"));
|
|
|
|
const char invalids[] = "!\"#$%&'()=~[]()+?<>\r\t\n";
|
|
for (int i = 0; i < sizeof(invalids) - 1; i++) {
|
|
char c = invalids[i];
|
|
const Common::String s(c);
|
|
inifile.addSection(s);
|
|
TS_ASSERT(!inifile.hasSection(s));
|
|
}
|
|
|
|
inifile.clear();
|
|
inifile.allowNonEnglishCharacters();
|
|
for (int i = 0; i < sizeof(invalids) - 1; i++) {
|
|
char c = invalids[i];
|
|
if (c == '[' || c == ']' || c == '#' || c == '=' || c == '\r' || c == '\n')
|
|
continue;
|
|
const Common::String s(c);
|
|
inifile.addSection(s);
|
|
TS_ASSERT(inifile.hasSection(s));
|
|
}
|
|
}
|
|
|
|
void test_write_simple_ini_file() {
|
|
byte buf[1024];
|
|
Common::INIFile inifile;
|
|
{
|
|
static const unsigned char inistr[] = "#comment\n[s]\nabc=1\ndef=xyz";
|
|
Common::MemoryReadStream mrs(inistr, sizeof(inistr));
|
|
TS_ASSERT(inifile.loadFromStream(mrs));
|
|
}
|
|
|
|
// A too-small write buffer (should fail)
|
|
{
|
|
Common::MemoryWriteStream mws(buf, 10);
|
|
TS_ASSERT(!inifile.saveToStream(mws));
|
|
}
|
|
|
|
// A good sized write buffer (should work)
|
|
int len;
|
|
{
|
|
Common::MemoryWriteStream mws(buf, 1024);
|
|
TS_ASSERT(inifile.saveToStream(mws));
|
|
len = mws.pos();
|
|
}
|
|
|
|
{
|
|
Common::MemoryReadStream mrs(buf, len - 1);
|
|
Common::INIFile checkinifile;
|
|
TS_ASSERT(checkinifile.loadFromStream(mrs));
|
|
TS_ASSERT(checkinifile.hasSection("s"));
|
|
|
|
const Common::INIFile::SectionList §ions = checkinifile.getSections();
|
|
const Common::INIFile::Section §ion = sections.front();
|
|
TS_ASSERT_EQUALS(section.comment, "#comment\n");
|
|
TS_ASSERT_EQUALS(section.name, "s");
|
|
|
|
TS_ASSERT(checkinifile.hasKey("abc", "s"));
|
|
TS_ASSERT(checkinifile.hasKey("def", "s"));
|
|
|
|
Common::String val;
|
|
TS_ASSERT(inifile.getKey("abc", "s", val));
|
|
TS_ASSERT_EQUALS(val, "1");
|
|
TS_ASSERT(inifile.getKey("def", "s", val));
|
|
TS_ASSERT_EQUALS(val, "xyz");
|
|
}
|
|
|
|
}
|
|
|
|
};
|