amxmodx/plugins/testsuite/utf8test.sma
2014-08-04 13:18:41 -05:00

244 lines
7.5 KiB
Plaintext

// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#include <amxmodx>
/**
* Warning: To get expected result, file encoding must be UTF-8 without BOM.
*/
public plugin_init()
{
register_plugin("UTF-8 Test", AMXX_VERSION_STR, "AMXX Dev Team");
register_srvcmd("utf8test", "OnServerCommand");
}
new ErrorCount;
new TestNumber;
enum TestType
{
TT_Equal = 0,
TT_LessThan,
TT_GreaterThan,
TT_LessThanEqual,
TT_GreaterThanEqual,
TT_NotEqual
};
new const TestWords[TestType][] =
{
"==",
"<",
">",
"<=",
">=",
"!="
};
test(any:a, any:b = true, TestType:type = TT_Equal)
{
++TestNumber;
new passed = 0;
switch (type)
{
case TT_Equal: passed = a == b;
case TT_LessThan: passed = a < b;
case TT_GreaterThan: passed = a > b;
case TT_LessThanEqual: passed = a <= b;
case TT_GreaterThanEqual: passed = a >= b;
case TT_NotEqual: passed = a != b;
}
if (!passed)
{
server_print("^tFailed test #%d (%d %s %d)", TestNumber, a, bool:TestWords[type], b);
ErrorCount++;
}
}
showResult()
{
if (!ErrorCount)
{
server_print("All tests passed (%d/%d).", TestNumber, TestNumber);
}
else
{
server_print("Test failed %d/%d, aborting.", TestNumber - ErrorCount, TestNumber);
}
}
public OnServerCommand()
{
/**
* Initiliaze some data.
*/
new reference[] = "𤭢hi AMXX® Hello㋡ crab?ൠ";
new Array:a = ArrayCreate(sizeof reference);
ArrayPushString(a, reference);
new Trie:t = TrieCreate();
TrieSetString(t, "reference", reference);
new DataPack:d = CreateDataPack();
WritePackString(d, reference);
ResetPack(d);
set_localinfo("reference", reference);
server_print("Counting character bytes...");
{
test(get_char_bytes("®") == 2);
test(get_char_bytes("㋡") == 3);
test(get_char_bytes("𤭢") == 4);
test(get_char_bytes("ൠ") == 3);
}
server_print("Checking character bytes...");
{
/**
* is_char_mb() returns also number of bytes if not 0.
*/
test(is_char_mb(reference[0]) != 0); // 𤭢
test(is_char_mb(reference[11]) != 0); // ®
test(is_char_mb(reference[19]) != 0); // ㋡
test(is_char_mb(reference[29]) != 0); // ൠ
}
server_print("Checking truncated character bytes - atcprintf...");
{
/**
* Truncating '𤭢' at different index. '𤭢' = 4 bytes
* A buffer of 4 = 3 bytes + EOS.
* Expected result: empty buffer.
*/
new buffer1[4];
for(new i = charsmax(buffer1), length1; i >= 0; --i)
{
length1 = formatex(buffer1, i, "%s", reference);
test(buffer1[0] == EOS && length1 == 0);
}
/**
* Truncating inside '®'.
* Expected result: '®' should be skipped.
*/
new buffer2[12];
new length2 = formatex(buffer2, charsmax(buffer2), "%s", reference);
test(strcmp(buffer2, "𤭢hi AMXX") == 0 && length2 == strlen("𤭢hi AMXX"));
/**
* Truncating inside 'ൠ'.
* Buffer of 14: Enough to hold "㋡ crab?ൠ"
* Retrieve 11 characters using precision format from '㋡' to inside 'ൠ'..
* Expected result: 'ൠ'. should be skipped.
*/
new buffer3[14];
new length3 = formatex(buffer3, charsmax(buffer3), "%.11s", reference[19]);
test(strcmp(buffer3, "㋡ crab?") == 0 && length3 == get_char_bytes("㋡") + strlen(" crab?"));
}
server_print("Checking truncated character bytes - set_amxstring_utf8...");
{
/**
* Splits string at '㋡'.
* Buffer can hold only 16 characters.
* Expected result: '㋡' should not be included and returned position should be after '㋡'.
*/
new buffer1[16];
new index1 = split_string(reference, "㋡", buffer1, charsmax(buffer1));
test(strcmp(buffer1, "𤭢hi AMXX® H") == 0 && index1 == strlen("𤭢hi AMXX® Hello") + get_char_bytes("㋡"));
/**
* Splits string at '𤭢'.
* Expected result: Empty string and returned position should be after '𤭢'.
*/
new buffer2[5];
new index2 = split_string(reference, "𤭢", buffer2, charsmax(buffer2));
test(buffer2[0] == EOS && index2 == get_char_bytes("𤭢"));
/**
* Splits string at '\ൠ'.
* Expected result: Empty string and returned position should -1 (not found).
*/
new buffer3[12];
new index3 = split_string(reference, "\ൠ", buffer3, charsmax(buffer3));
test(buffer3[0] == EOS && index3 == -1);
/**
* Truncating '𤭢' at different index. '𤭢' = 4 bytes
* A buffer of 4 = 3 bytes + EOS.
* Expected result: empty buffer.
*/
new buffer4[4];
for(new i = charsmax(buffer4), length4; i >= 0; --i)
{
length4 = get_localinfo("reference", buffer4, i);
test(buffer4[0] == EOS && length4 == 0);
}
}
server_print("Checking truncated character bytes - direct copy...");
{
/**
* Replaces '®' by '𤭢'.
* Expected result: '𤭢' should eat '® He" which counts 4 bytes.
*/
new count1 = replace_string(reference, charsmax(reference), "®", "𤭢");
test(strcmp(reference, "𤭢hi AMXX𤭢ello㋡ crab?ൠ") == 0 && count1 == 1);
/**
* Replaces '®' by '𤭢'.
* Expected result: not found.
*/
new count2 = replace_string(reference, charsmax(reference), "®", "𤭢");
test(strcmp(reference, "𤭢hi AMXX𤭢ello㋡ crab?ൠ") == 0 && count2 == 0);
/**
* Replaces 'ൠ' by '𤭢'.
* Expected result: 'ൠ' = 3 bytes, '𤭢' = 4 bytes. Not enough spaces to hold '𤭢', skipping it.
*/
new count3 = replace_string(reference, charsmax(reference), "ൠ", "𤭢");
test(strcmp(reference, "𤭢hi AMXX𤭢ello㋡ crab?") == 0 && count3 == 1);
/**
* Gets reference string with limited buffer.
* Expected result: '㋡' should be ignored as no spaces.
*/
new buffer[charsmax(reference) - 9];
ArrayGetString(a, 0, buffer, charsmax(buffer));
test(strcmp(buffer, "𤭢hi AMXX® Hello") == 0);
/**
* Gets reference string with limited buffer.
* Expected result: '㋡' should be ignored as no spaces.
*/
TrieGetString(t, "reference", buffer, charsmax(buffer));
test(strcmp(buffer, "𤭢hi AMXX® Hello") == 0);
/**
* Gets reference string with limited buffer.
* Expected result: '㋡' should be ignored as no room.
*/
new length = ReadPackString(d, buffer, charsmax(buffer));
test(strcmp(buffer, "𤭢hi AMXX® Hello") == 0 && length == strlen("𤭢hi AMXX® Hello"));
}
ArrayDestroy(a);
TrieDestroy(t);
DestroyDataPack(d);
showResult();
}