Initial commit
This commit is contained in:
273
test/common/algorithm.h
Normal file
273
test/common/algorithm.h
Normal file
@@ -0,0 +1,273 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/util.h"
|
||||
#include "common/func.h"
|
||||
#include "common/algorithm.h"
|
||||
#include "common/list.h"
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
|
||||
class AlgorithmTestSuite : public CxxTest::TestSuite {
|
||||
template<typename T, class StrictWeakOrdering>
|
||||
bool checkSort(T first, T last, StrictWeakOrdering comp = StrictWeakOrdering()) {
|
||||
if (first == last)
|
||||
return true;
|
||||
|
||||
// Check whether the container is sorted by the given binary predicate, which
|
||||
// decides whether the first value passed precedes the second value passed.
|
||||
//
|
||||
// To do that it checks an item and its follower in the container with the
|
||||
// given predicate in reverse order, when it returns false everything is
|
||||
// fine, when it returns false, the follower precedes the item and thus
|
||||
// the order is violated.
|
||||
for (T prev = first++; first != last; ++prev, ++first) {
|
||||
if (comp(*first, *prev))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auxiliary function to check the equality of two generic collections (A and B), from one_first to one_last.
|
||||
*
|
||||
* @note: It assumes that other has at least (one_last - one-first) length, starting from other_first.
|
||||
*
|
||||
* @param one_first: The first element of the first collection to be compared.
|
||||
* @param one_last: The last element of the first collection to be compared.
|
||||
* @param other_first: The first element of the collection to be compared.
|
||||
* @return true if, for each index i in [one_first, one_last), A[i] == B[i], false otherwise.
|
||||
*/
|
||||
template<typename It>
|
||||
bool checkEqual(It one_first, It one_last, It other_first) {
|
||||
if (one_first == one_last)
|
||||
return true;
|
||||
|
||||
// Check whether two containers have the same items in the same order,
|
||||
// starting from some iterators one_first and other_first
|
||||
//
|
||||
// It iterates through the containers, comparing the elements one by one.
|
||||
// If it finds a discrepancy, it returns false. Otherwise, it returns true.
|
||||
|
||||
for (; one_first != one_last; ++one_first, ++other_first)
|
||||
if (*one_first != *other_first)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Item {
|
||||
int value;
|
||||
Item(int v) : value(v) {}
|
||||
|
||||
bool operator<(const Item &r) const {
|
||||
return value < r.value;
|
||||
}
|
||||
};
|
||||
public:
|
||||
void test_check_sort() {
|
||||
const int arraySorted[] = { 1, 2, 3, 3, 4, 5 };
|
||||
const int arrayUnsorted[] = { 5, 3, 1, 2, 4, 3 };
|
||||
|
||||
TS_ASSERT_EQUALS(checkSort(arraySorted, ARRAYEND(arraySorted), Common::Less<int>()), true);
|
||||
TS_ASSERT_EQUALS(checkSort(arraySorted, ARRAYEND(arraySorted), Common::Greater<int>()), false);
|
||||
|
||||
TS_ASSERT_EQUALS(checkSort(arrayUnsorted, ARRAYEND(arrayUnsorted), Common::Less<int>()), false);
|
||||
TS_ASSERT_EQUALS(checkSort(arrayUnsorted, ARRAYEND(arrayUnsorted), Common::Greater<int>()), false);
|
||||
}
|
||||
|
||||
void test_pod_sort() {
|
||||
{
|
||||
int dummy;
|
||||
Common::sort(&dummy, &dummy);
|
||||
TS_ASSERT_EQUALS(checkSort(&dummy, &dummy, Common::Less<int>()), true);
|
||||
}
|
||||
{
|
||||
int array[] = { 12 };
|
||||
Common::sort(array, ARRAYEND(array));
|
||||
TS_ASSERT_EQUALS(checkSort(array, ARRAYEND(array), Common::Less<int>()), true);
|
||||
|
||||
// already sorted
|
||||
Common::sort(array, ARRAYEND(array));
|
||||
TS_ASSERT_EQUALS(checkSort(array, ARRAYEND(array), Common::Less<int>()), true);
|
||||
}
|
||||
{
|
||||
int array[] = { 63, 11, 31, 72, 1, 48, 32, 69, 38, 31 };
|
||||
Common::sort(array, ARRAYEND(array));
|
||||
TS_ASSERT_EQUALS(checkSort(array, ARRAYEND(array), Common::Less<int>()), true);
|
||||
|
||||
int sortedArray[] = { 1, 11, 31, 31, 32, 38, 48, 63, 69, 72 };
|
||||
for (size_t i = 0; i < 10; ++i)
|
||||
TS_ASSERT_EQUALS(array[i], sortedArray[i]);
|
||||
|
||||
// already sorted
|
||||
Common::sort(array, ARRAYEND(array));
|
||||
TS_ASSERT_EQUALS(checkSort(array, ARRAYEND(array), Common::Less<int>()), true);
|
||||
}
|
||||
{
|
||||
int array[] = { 90, 80, 70, 60, 50, 40, 30, 20, 10 };
|
||||
Common::sort(array, ARRAYEND(array));
|
||||
TS_ASSERT_EQUALS(checkSort(array, ARRAYEND(array), Common::Less<int>()), true);
|
||||
|
||||
Common::sort(array, ARRAYEND(array), Common::Greater<int>());
|
||||
TS_ASSERT_EQUALS(checkSort(array, ARRAYEND(array), Common::Greater<int>()), true);
|
||||
}
|
||||
}
|
||||
|
||||
void test_container_sort() {
|
||||
const int n = 1000;
|
||||
|
||||
Common::List<Item> list;
|
||||
for(int i = 0; i < n; ++i)
|
||||
list.push_back(Item(i * 0xDEADBEEF % 1337));
|
||||
|
||||
Common::sort(list.begin(), list.end(), Common::Less<Item>());
|
||||
TS_ASSERT_EQUALS(checkSort(list.begin(), list.end(), Common::Less<Item>()), true);
|
||||
|
||||
// already sorted
|
||||
Common::sort(list.begin(), list.end());
|
||||
TS_ASSERT_EQUALS(checkSort(list.begin(), list.end(), Common::Less<Item>()), true);
|
||||
}
|
||||
|
||||
void test_string_replace() {
|
||||
|
||||
Common::String original = "Hello World";
|
||||
Common::String expected = "Hells Wsrld";
|
||||
|
||||
Common::replace(original.begin(), original.end(), 'o', 's');
|
||||
|
||||
TS_ASSERT_EQUALS(original, expected);
|
||||
}
|
||||
|
||||
void test_container_replace() {
|
||||
|
||||
Common::List<int> original;
|
||||
Common::List<int> expected;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
original.push_back(i);
|
||||
if (i == 3) {
|
||||
expected.push_back(5);
|
||||
} else {
|
||||
expected.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
Common::replace(original.begin(), original.end(), 3, 5);
|
||||
|
||||
TS_ASSERT_EQUALS(checkEqual(original.begin(), original.end(), expected.begin()), true);
|
||||
}
|
||||
|
||||
void test_container_remove() {
|
||||
{
|
||||
Common::Array<int> original {1, 2, 3, 10, 4, 5};
|
||||
Common::Array<int> expected {1, 2, 3, 4, 5};
|
||||
|
||||
Common::Array<int>::iterator r = Common::remove(original.begin(), original.end(), 10);
|
||||
|
||||
TS_ASSERT_EQUALS(checkEqual(original.begin(), r, expected.begin()), true);
|
||||
}
|
||||
{
|
||||
Common::Array<int> original {1, 2, 2, 3, 4, 4, 2, 1, 0};
|
||||
Common::Array<int> expected {1, 3, 4, 4, 1, 0};
|
||||
|
||||
Common::Array<int>::iterator r = Common::remove(original.begin(), original.end(), 2);
|
||||
|
||||
TS_ASSERT_EQUALS(checkEqual(original.begin(), r, expected.begin()), true);
|
||||
}
|
||||
{
|
||||
Common::Array<int> original {0, 1, 2, 3, 0, 3, 2, 1, 0};
|
||||
Common::Array<int> expected {1, 2, 3, 3, 2, 1};
|
||||
|
||||
Common::Array<int>::iterator r = Common::remove(original.begin(), original.end(), 0);
|
||||
|
||||
TS_ASSERT_EQUALS(checkEqual(original.begin(), r, expected.begin()), true);
|
||||
}
|
||||
}
|
||||
|
||||
void test_lower_bound_equal_found() {
|
||||
const auto test = [](const int *first, const int *last, int value) {
|
||||
const auto it = Common::lowerBound(first, last, value);
|
||||
TS_ASSERT(first <= it && it < last);
|
||||
TS_ASSERT_EQUALS(*it, value);
|
||||
};
|
||||
const int one[] = {1};
|
||||
const int values[] = {1, 2, 4, 10, 50, 100, 900, 1000};
|
||||
test(one, one + ARRAYSIZE(one), 1);
|
||||
test(values, values + ARRAYSIZE(values), 1);
|
||||
test(values, values + ARRAYSIZE(values), 1000);
|
||||
test(values, values + ARRAYSIZE(values), 4);
|
||||
}
|
||||
|
||||
void test_lower_bound_greater_found() {
|
||||
const auto test = [](const int *first, const int *last, int value, int expected) {
|
||||
const auto it = Common::lowerBound(first, last, value);
|
||||
TS_ASSERT(first <= it && it < last);
|
||||
TS_ASSERT_EQUALS(*it, expected);
|
||||
};
|
||||
const int one[] = {1};
|
||||
const int values[] = {2, 3, 4, 10, 50, 100, 900, 1000};
|
||||
test(one, one + ARRAYSIZE(one), 0, 1);
|
||||
test(values, values + ARRAYSIZE(values), 1, 2);
|
||||
test(values, values + ARRAYSIZE(values), 950, 1000);
|
||||
test(values, values + ARRAYSIZE(values), 20, 50);
|
||||
}
|
||||
|
||||
void test_lower_bound_element_nothing_found() {
|
||||
const int values[] = {1, 2, 3, 6, 8, 10, 20, 50};
|
||||
const auto last = values + ARRAYSIZE(values);
|
||||
const auto it = Common::lowerBound(values, last, 100);
|
||||
TS_ASSERT_EQUALS(it, last);
|
||||
}
|
||||
|
||||
void test_lower_bound_empty_input() {
|
||||
{
|
||||
const int values[] = {1};
|
||||
const auto last = values + ARRAYSIZE(values);
|
||||
const auto it = Common::lowerBound(last, last, 1);
|
||||
TS_ASSERT_EQUALS(it, last);
|
||||
}
|
||||
{
|
||||
const auto it = Common::lowerBound((int *)nullptr, (int *)nullptr, 1);
|
||||
TS_ASSERT_EQUALS(it, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void test_upper_bound_element_found() {
|
||||
const auto test = [](const int *first, const int *last, int value, int expected) {
|
||||
const auto it = Common::upperBound(first, last, value);
|
||||
TS_ASSERT(first <= it && it < last);
|
||||
TS_ASSERT_EQUALS(*it, expected);
|
||||
};
|
||||
const int one[] = {1};
|
||||
const int values[] = {2, 3, 4, 10, 50, 100, 900, 1000};
|
||||
test(one, one + ARRAYSIZE(one), 0, 1);
|
||||
test(values, values + ARRAYSIZE(values), 1, 2);
|
||||
test(values, values + ARRAYSIZE(values), 950, 1000);
|
||||
test(values, values + ARRAYSIZE(values), 20, 50);
|
||||
}
|
||||
|
||||
void test_upper_bound_nothing_found() {
|
||||
const int values[] = {1, 2, 3, 6, 8, 10, 20, 50};
|
||||
const auto last = values + ARRAYSIZE(values);
|
||||
{
|
||||
const auto it = Common::upperBound(values, last, 50);
|
||||
TS_ASSERT_EQUALS(it, last);
|
||||
}
|
||||
{
|
||||
const auto it = Common::upperBound(values, last, 100);
|
||||
TS_ASSERT_EQUALS(it, last);
|
||||
}
|
||||
}
|
||||
|
||||
void test_upper_bound_empty_input() {
|
||||
{
|
||||
const int values[] = {1};
|
||||
const auto last = values + ARRAYSIZE(values);
|
||||
const auto it = Common::upperBound(last, last, 1);
|
||||
TS_ASSERT_EQUALS(it, last);
|
||||
}
|
||||
{
|
||||
const auto it = Common::upperBound((int *)nullptr, (int *)nullptr, 1);
|
||||
TS_ASSERT_EQUALS(it, nullptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
617
test/common/array.h
Normal file
617
test/common/array.h
Normal file
@@ -0,0 +1,617 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/noncopyable.h"
|
||||
#include "common/str.h"
|
||||
|
||||
|
||||
struct ArrayTestMovable {
|
||||
ArrayTestMovable() : _value(0), _wasMoveConstructed(false), _wasMovedFrom(false) {}
|
||||
|
||||
explicit ArrayTestMovable(int value) : _value(value), _wasMoveConstructed(false), _wasMovedFrom(false) {}
|
||||
|
||||
ArrayTestMovable(const ArrayTestMovable &other)
|
||||
: _value(other._value), _wasMoveConstructed(false), _wasMovedFrom(false) {
|
||||
}
|
||||
|
||||
ArrayTestMovable(ArrayTestMovable &&other) noexcept
|
||||
: _value(other._value), _wasMoveConstructed(true), _wasMovedFrom(false) {
|
||||
other._wasMovedFrom = true;
|
||||
}
|
||||
|
||||
int _value;
|
||||
bool _wasMoveConstructed;
|
||||
bool _wasMovedFrom;
|
||||
};
|
||||
|
||||
// Hopefully temporary until Common::Pair can be updated to have move constructor/assign operator
|
||||
struct ArrayTestMovablePair {
|
||||
ArrayTestMovablePair(ArrayTestMovable &&pFirst, ArrayTestMovable &&pSecond)
|
||||
: first(Common::move(pFirst)), second(Common::move(pSecond)) {
|
||||
}
|
||||
|
||||
ArrayTestMovablePair(const ArrayTestMovable &&pFirst, const ArrayTestMovable &&pSecond)
|
||||
: first(pFirst), second(pSecond) {
|
||||
}
|
||||
|
||||
ArrayTestMovable first;
|
||||
ArrayTestMovable second;
|
||||
};
|
||||
|
||||
class ArrayTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_empty_clear() {
|
||||
Common::Array<int> array;
|
||||
TS_ASSERT(array.empty());
|
||||
array.push_back(17);
|
||||
array.push_back(33);
|
||||
TS_ASSERT(!array.empty());
|
||||
array.clear();
|
||||
TS_ASSERT(array.empty());
|
||||
}
|
||||
|
||||
void test_iterator() {
|
||||
Common::Array<int> array;
|
||||
Common::Array<int>::iterator iter;
|
||||
|
||||
// Fill the array with some random data
|
||||
array.push_back(17);
|
||||
array.push_back(33);
|
||||
array.push_back(-11);
|
||||
|
||||
// Iterate over the array and verify that we encounter the elements in
|
||||
// the order we expect them to be.
|
||||
|
||||
iter = array.begin();
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 17);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, array.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 33);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, array.end());
|
||||
|
||||
// Also test the postinc
|
||||
TS_ASSERT_EQUALS(*iter, -11);
|
||||
iter++;
|
||||
TS_ASSERT_EQUALS(iter, array.end());
|
||||
}
|
||||
|
||||
void test_erase_iterator() {
|
||||
Common::Array<int> array;
|
||||
Common::Array<int>::iterator iter;
|
||||
|
||||
// Fill the array with some random data
|
||||
array.push_back(17);
|
||||
array.push_back(33);
|
||||
array.push_back(-11);
|
||||
|
||||
iter = array.begin();
|
||||
++iter;
|
||||
|
||||
iter = array.erase(iter);
|
||||
TS_ASSERT_DIFFERS(iter, array.end());
|
||||
TS_ASSERT_EQUALS(*iter, -11);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)2);
|
||||
TS_ASSERT_EQUALS(array[0], 17);
|
||||
TS_ASSERT_EQUALS(array[1], -11);
|
||||
}
|
||||
|
||||
void test_erase_iterator_range() {
|
||||
Common::Array<int> array;
|
||||
Common::Array<int>::iterator first, last;
|
||||
|
||||
// Fill the array with some random data
|
||||
array.push_back(17);
|
||||
array.push_back(33);
|
||||
array.push_back(66);
|
||||
array.push_back(99);
|
||||
array.push_back(-11);
|
||||
|
||||
first = array.begin();
|
||||
++first;
|
||||
|
||||
last = array.end();
|
||||
--last;
|
||||
|
||||
first = array.erase(first, last);
|
||||
TS_ASSERT_DIFFERS(first, array.end());
|
||||
TS_ASSERT_EQUALS(*first, -11);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)2);
|
||||
TS_ASSERT_EQUALS(array[0], 17);
|
||||
TS_ASSERT_EQUALS(array[1], -11);
|
||||
}
|
||||
|
||||
void test_insert_iterator() {
|
||||
Common::Array<int> array;
|
||||
Common::Array<int>::iterator iter;
|
||||
|
||||
// Fill the array with some random data
|
||||
array.push_back(17);
|
||||
array.push_back(33);
|
||||
array.push_back(-11);
|
||||
|
||||
iter = array.begin();
|
||||
++iter;
|
||||
|
||||
array.insert(iter, 99);
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 99);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)4);
|
||||
TS_ASSERT_EQUALS(array[0], 17);
|
||||
TS_ASSERT_EQUALS(array[1], 99);
|
||||
TS_ASSERT_EQUALS(array[2], 33);
|
||||
TS_ASSERT_EQUALS(array[3], -11);
|
||||
}
|
||||
|
||||
void test_direct_access() {
|
||||
Common::Array<int> array;
|
||||
|
||||
// Fill the array with some random data
|
||||
array.push_back(17);
|
||||
array.push_back(33);
|
||||
array.push_back(-11);
|
||||
|
||||
TS_ASSERT_EQUALS(array[0], 17);
|
||||
TS_ASSERT_EQUALS(array[1], 33);
|
||||
TS_ASSERT_EQUALS(array[2], -11);
|
||||
}
|
||||
|
||||
void test_insert_at() {
|
||||
Common::Array<int> array;
|
||||
|
||||
// First of all some data
|
||||
array.push_back(-12);
|
||||
array.push_back(17);
|
||||
array.push_back(25);
|
||||
array.push_back(-11);
|
||||
|
||||
// Insert some data
|
||||
array.insert_at(2, 33);
|
||||
|
||||
TS_ASSERT_EQUALS(array[0], -12);
|
||||
TS_ASSERT_EQUALS(array[1], 17);
|
||||
TS_ASSERT_EQUALS(array[2], 33);
|
||||
TS_ASSERT_EQUALS(array[3], 25);
|
||||
TS_ASSERT_EQUALS(array[4], -11);
|
||||
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)5);
|
||||
}
|
||||
|
||||
void test_insert_at_array() {
|
||||
Common::Array<int> array;
|
||||
Common::Array<int> array2;
|
||||
|
||||
// First of all some data
|
||||
array.push_back(-12);
|
||||
array.push_back(17);
|
||||
array.push_back(25);
|
||||
array.push_back(-11);
|
||||
|
||||
array2.push_back(42);
|
||||
array2.push_back(105);
|
||||
array2.push_back(-1);
|
||||
|
||||
// Insert some data
|
||||
array.insert_at(2, array2);
|
||||
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)7);
|
||||
|
||||
TS_ASSERT_EQUALS(array[0], -12);
|
||||
TS_ASSERT_EQUALS(array[1], 17);
|
||||
TS_ASSERT_EQUALS(array[2], 42);
|
||||
TS_ASSERT_EQUALS(array[3], 105);
|
||||
TS_ASSERT_EQUALS(array[4], -1);
|
||||
TS_ASSERT_EQUALS(array[5], 25);
|
||||
TS_ASSERT_EQUALS(array[6], -11);
|
||||
|
||||
}
|
||||
|
||||
void test_self_insert() {
|
||||
Common::Array<int> array;
|
||||
int i;
|
||||
|
||||
// Insert some data -- and make sure we have enough space for
|
||||
// *twice* as much data. This way, there is no need to allocate
|
||||
// new storage, so if the insert() operation is "clever", it
|
||||
// will try to reuse the existing storage.
|
||||
// This in turn may uncover bugs if the insertion code does not
|
||||
// expect self-insertions.
|
||||
array.reserve(128);
|
||||
for (i = 0; i < 64; ++i)
|
||||
array.push_back(i);
|
||||
|
||||
// Now insert the array into the middle of itself
|
||||
array.insert_at(12, array);
|
||||
|
||||
// Verify integrity
|
||||
TS_ASSERT_EQUALS(array.size(), 128UL);
|
||||
|
||||
for (i = 0; i < 12; ++i)
|
||||
TS_ASSERT_EQUALS(array[i], i);
|
||||
for (i = 0; i < 64; ++i)
|
||||
TS_ASSERT_EQUALS(array[i+12], i);
|
||||
for (i = 12; i < 64; ++i)
|
||||
TS_ASSERT_EQUALS(array[i+64], i);
|
||||
}
|
||||
|
||||
|
||||
void test_remove_at() {
|
||||
Common::Array<int> array;
|
||||
|
||||
// First of all some data
|
||||
array.push_back(-12);
|
||||
array.push_back(17);
|
||||
array.push_back(33);
|
||||
array.push_back(25);
|
||||
array.push_back(-11);
|
||||
|
||||
// Remove some data
|
||||
array.remove_at(1);
|
||||
|
||||
TS_ASSERT_EQUALS(array[0], -12);
|
||||
TS_ASSERT_EQUALS(array[1], 33);
|
||||
TS_ASSERT_EQUALS(array[2], 25);
|
||||
TS_ASSERT_EQUALS(array[3], -11);
|
||||
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)4);
|
||||
}
|
||||
|
||||
void test_push_back() {
|
||||
Common::Array<int> array1, array2;
|
||||
|
||||
// Some data for both
|
||||
array1.push_back(-3);
|
||||
array1.push_back(5);
|
||||
array1.push_back(9);
|
||||
|
||||
array2.push_back(3);
|
||||
array2.push_back(-2);
|
||||
array2.push_back(-131);
|
||||
|
||||
array1.push_back(array2);
|
||||
|
||||
TS_ASSERT_EQUALS(array1[0], -3);
|
||||
TS_ASSERT_EQUALS(array1[1], 5);
|
||||
TS_ASSERT_EQUALS(array1[2], 9);
|
||||
TS_ASSERT_EQUALS(array1[3], 3);
|
||||
TS_ASSERT_EQUALS(array1[4], -2);
|
||||
TS_ASSERT_EQUALS(array1[5], -131);
|
||||
|
||||
TS_ASSERT_EQUALS(array1.size(), (unsigned int)6);
|
||||
TS_ASSERT_EQUALS(array2.size(), (unsigned int)3);
|
||||
}
|
||||
|
||||
struct SafeInt {
|
||||
int val;
|
||||
SafeInt() : val(0) {}
|
||||
SafeInt(int v) : val(v) {}
|
||||
~SafeInt() { val = -1; }
|
||||
bool operator==(int v) {
|
||||
return val == v;
|
||||
}
|
||||
};
|
||||
|
||||
void test_push_back_ex() {
|
||||
// This test makes sure that inserting an element invalidates
|
||||
// references/iterators/pointers to elements in the array itself
|
||||
// only *after* their value has been copied.
|
||||
Common::Array<SafeInt> array;
|
||||
|
||||
array.push_back(42);
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
array.push_back(array[0]);
|
||||
TS_ASSERT_EQUALS(array[i], 42);
|
||||
}
|
||||
}
|
||||
|
||||
void test_copy_constructor() {
|
||||
Common::Array<int> array1;
|
||||
|
||||
// Some data for both
|
||||
array1.push_back(-3);
|
||||
array1.push_back(5);
|
||||
array1.push_back(9);
|
||||
|
||||
Common::Array<int> array2(array1);
|
||||
|
||||
// Alter the original array
|
||||
array1[0] = 7;
|
||||
array1[1] = -5;
|
||||
array1[2] = 2;
|
||||
|
||||
TS_ASSERT_EQUALS(array2[0], -3);
|
||||
TS_ASSERT_EQUALS(array2[1], 5);
|
||||
TS_ASSERT_EQUALS(array2[2], 9);
|
||||
|
||||
TS_ASSERT_EQUALS(array2.size(), (unsigned int)3);
|
||||
}
|
||||
|
||||
void test_equals() {
|
||||
Common::Array<int> array1;
|
||||
|
||||
// Some data for both
|
||||
array1.push_back(-3);
|
||||
array1.push_back(5);
|
||||
array1.push_back(9);
|
||||
|
||||
Common::Array<int> array2(array1);
|
||||
|
||||
TS_ASSERT(array1 == array2);
|
||||
array1.push_back(42);
|
||||
TS_ASSERT(array1 != array2);
|
||||
array2.push_back(42);
|
||||
TS_ASSERT(array1 == array2);
|
||||
}
|
||||
|
||||
void test_array_constructor() {
|
||||
const int array1[] = { -3, 5, 9 };
|
||||
|
||||
Common::Array<int> array2(array1, 3);
|
||||
|
||||
TS_ASSERT_EQUALS(array2[0], -3);
|
||||
TS_ASSERT_EQUALS(array2[1], 5);
|
||||
TS_ASSERT_EQUALS(array2[2], 9);
|
||||
|
||||
TS_ASSERT_EQUALS(array2.size(), (unsigned int)3);
|
||||
}
|
||||
|
||||
class Copyable {
|
||||
bool _copied;
|
||||
int _value;
|
||||
Copyable &operator=(Copyable &);
|
||||
public:
|
||||
Copyable() : _copied(false), _value(1) {}
|
||||
explicit Copyable(const int v) : _copied(false), _value(v) {}
|
||||
Copyable(const Copyable &other) : _copied(true), _value(other._value) {}
|
||||
bool copied() const { return _copied; }
|
||||
int value() const { return _value; }
|
||||
};
|
||||
|
||||
void test_array_constructor_count() {
|
||||
Common::Array<int> array(10);
|
||||
TS_ASSERT_EQUALS(array.size(), 10U);
|
||||
TS_ASSERT_EQUALS(array[0], 0);
|
||||
TS_ASSERT_EQUALS(array[9], 0);
|
||||
|
||||
// This will fail at compile time if it is not possible to construct an
|
||||
// array without copy-construction
|
||||
Common::Array<Common::NonCopyable> nonCopyable(1);
|
||||
}
|
||||
|
||||
void test_array_constructor_list() {
|
||||
Common::Array<int> array = {1, 42, 255};
|
||||
TS_ASSERT_EQUALS(array.size(), 3U);
|
||||
TS_ASSERT_EQUALS(array[0], 1);
|
||||
TS_ASSERT_EQUALS(array[1], 42);
|
||||
TS_ASSERT_EQUALS(array[2], 255);
|
||||
}
|
||||
|
||||
void test_array_constructor_count_copy_value() {
|
||||
Common::Array<int> trivial(5, 1);
|
||||
TS_ASSERT_EQUALS(trivial.size(), 5U);
|
||||
TS_ASSERT_EQUALS(trivial[0], 1);
|
||||
TS_ASSERT_EQUALS(trivial[4], 1);
|
||||
|
||||
Copyable c(123);
|
||||
typedef Common::Array<Copyable> NonTrivialArray;
|
||||
|
||||
NonTrivialArray nonTrivialCopy(3, c);
|
||||
TS_ASSERT_EQUALS(nonTrivialCopy.size(), 3U);
|
||||
for (NonTrivialArray::size_type i = 0; i < nonTrivialCopy.size(); ++i) {
|
||||
TS_ASSERT_EQUALS(nonTrivialCopy[0].value(), 123);
|
||||
TS_ASSERT(nonTrivialCopy[0].copied());
|
||||
}
|
||||
|
||||
NonTrivialArray nonTrivialDefault(3);
|
||||
TS_ASSERT_EQUALS(nonTrivialDefault.size(), 3U);
|
||||
for (NonTrivialArray::size_type i = 0; i < nonTrivialDefault.size(); ++i) {
|
||||
TS_ASSERT_EQUALS(nonTrivialDefault[0].value(), 1);
|
||||
TS_ASSERT(!nonTrivialDefault[0].copied());
|
||||
}
|
||||
}
|
||||
|
||||
void test_array_constructor_str() {
|
||||
const char *array1[] = { "a", "b", "c" };
|
||||
|
||||
Common::Array<Common::String> array2(array1, 3);
|
||||
|
||||
TS_ASSERT_EQUALS(array2[0], "a");
|
||||
TS_ASSERT_EQUALS(array2[1], "b");
|
||||
TS_ASSERT_EQUALS(array2[2], "c");
|
||||
|
||||
TS_ASSERT_EQUALS(array2.size(), (unsigned int)3);
|
||||
}
|
||||
|
||||
void test_data() {
|
||||
Common::Array<int> array;
|
||||
TS_ASSERT(array.data() == nullptr);
|
||||
array.resize(2);
|
||||
TS_ASSERT(array.data() != nullptr);
|
||||
TS_ASSERT_EQUALS(array.data(), &array.front());
|
||||
TS_ASSERT_EQUALS(array.data() + array.size() - 1, &array.back());
|
||||
}
|
||||
|
||||
void test_front_back_push_pop() {
|
||||
Common::Array<int> container;
|
||||
|
||||
container.push_back( 42);
|
||||
container.push_back(-23);
|
||||
|
||||
TS_ASSERT_EQUALS(container.front(), 42);
|
||||
TS_ASSERT_EQUALS(container.back(), -23);
|
||||
|
||||
container.front() = -17;
|
||||
container.back() = 163;
|
||||
TS_ASSERT_EQUALS(container.front(), -17);
|
||||
TS_ASSERT_EQUALS(container.back(), 163);
|
||||
|
||||
container.pop_back();
|
||||
TS_ASSERT_EQUALS(container.front(), -17);
|
||||
TS_ASSERT_EQUALS(container.back(), -17);
|
||||
}
|
||||
|
||||
void test_resize() {
|
||||
Common::Array<int> array;
|
||||
|
||||
array.resize(3);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)3);
|
||||
|
||||
array[0] = -3;
|
||||
array[1] = 163;
|
||||
array[2] = 17;
|
||||
|
||||
array.resize(100);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)100);
|
||||
TS_ASSERT_EQUALS(array[0], -3);
|
||||
TS_ASSERT_EQUALS(array[1], 163);
|
||||
TS_ASSERT_EQUALS(array[2], 17);
|
||||
|
||||
TS_ASSERT_EQUALS(array[99], 0);
|
||||
|
||||
array.resize(2);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)2);
|
||||
TS_ASSERT_EQUALS(array[0], -3);
|
||||
TS_ASSERT_EQUALS(array[1], 163);
|
||||
|
||||
array.resize(4, 42);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)4);
|
||||
TS_ASSERT_EQUALS(array[0], -3);
|
||||
TS_ASSERT_EQUALS(array[1], 163);
|
||||
TS_ASSERT_EQUALS(array[2], 42);
|
||||
TS_ASSERT_EQUALS(array[3], 42);
|
||||
|
||||
array.resize(2, 42);
|
||||
TS_ASSERT_EQUALS(array.size(), (unsigned int)2);
|
||||
TS_ASSERT_EQUALS(array[0], -3);
|
||||
TS_ASSERT_EQUALS(array[1], 163);
|
||||
}
|
||||
|
||||
void test_swap() {
|
||||
Common::Array<int> array1, array2;
|
||||
|
||||
array1.push_back(-3);
|
||||
array1.push_back(163);
|
||||
array1.push_back(17);
|
||||
array2.push_back(5);
|
||||
array2.push_back(9);
|
||||
|
||||
TS_ASSERT_EQUALS(array1.size(), 3u);
|
||||
TS_ASSERT_EQUALS(array1[0], -3);
|
||||
TS_ASSERT_EQUALS(array1[1], 163);
|
||||
TS_ASSERT_EQUALS(array1[2], 17);
|
||||
TS_ASSERT_EQUALS(array2.size(), 2u);
|
||||
TS_ASSERT_EQUALS(array2[0], 5);
|
||||
TS_ASSERT_EQUALS(array2[1], 9);
|
||||
|
||||
array1.swap(array2);
|
||||
|
||||
TS_ASSERT_EQUALS(array1.size(), 2u);
|
||||
TS_ASSERT_EQUALS(array1[0], 5);
|
||||
TS_ASSERT_EQUALS(array1[1], 9);
|
||||
TS_ASSERT_EQUALS(array2.size(), 3u);
|
||||
TS_ASSERT_EQUALS(array2[0], -3);
|
||||
TS_ASSERT_EQUALS(array2[1], 163);
|
||||
TS_ASSERT_EQUALS(array2[2], 17);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct ListElement {
|
||||
int value;
|
||||
int tag;
|
||||
|
||||
ListElement(int v, int t = 0) : value(v), tag(t) {}
|
||||
};
|
||||
|
||||
static int compareInts(const void *a, const void *b) {
|
||||
return ((const ListElement *)a)->value - ((const ListElement *)b)->value;
|
||||
}
|
||||
|
||||
class SortedArrayTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_insert() {
|
||||
Common::SortedArray<ListElement *> container(compareInts);
|
||||
Common::SortedArray<ListElement *>::iterator iter;
|
||||
|
||||
// Fill the container with some random data
|
||||
container.insert(new ListElement(1));
|
||||
container.insert(new ListElement(7));
|
||||
container.insert(new ListElement(8));
|
||||
container.insert(new ListElement(3));
|
||||
container.insert(new ListElement(5));
|
||||
container.insert(new ListElement(4));
|
||||
container.insert(new ListElement(9));
|
||||
container.insert(new ListElement(2));
|
||||
container.insert(new ListElement(6));
|
||||
|
||||
// Verify contents are correct
|
||||
iter = container.begin();
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
TS_ASSERT_EQUALS((*iter)->value, i);
|
||||
++iter;
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
|
||||
// Cleanup
|
||||
for(iter = container.begin(); iter != container.end(); iter++) {
|
||||
delete *iter;
|
||||
}
|
||||
}
|
||||
|
||||
void test_stability() {
|
||||
Common::SortedArray<ListElement *> container(compareInts);
|
||||
Common::SortedArray<ListElement *>::iterator iter;
|
||||
|
||||
// Check stability, using duplicate keys and sequential tags.
|
||||
container.insert(new ListElement(1, 3));
|
||||
container.insert(new ListElement(0, 1));
|
||||
container.insert(new ListElement(4, 8));
|
||||
container.insert(new ListElement(1, 4));
|
||||
container.insert(new ListElement(0, 2));
|
||||
container.insert(new ListElement(2, 6));
|
||||
container.insert(new ListElement(1, 5));
|
||||
container.insert(new ListElement(3, 7));
|
||||
container.insert(new ListElement(4, 9));
|
||||
|
||||
// Verify contents are correct
|
||||
iter = container.begin();
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
TS_ASSERT_EQUALS((*iter)->tag, i);
|
||||
++iter;
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
|
||||
// Cleanup
|
||||
for(iter = container.begin(); iter != container.end(); iter++) {
|
||||
delete *iter;
|
||||
}
|
||||
}
|
||||
|
||||
void test_emplace() {
|
||||
Common::Array<ArrayTestMovablePair> movablePairArray;
|
||||
movablePairArray.emplace_back(ArrayTestMovable(1), ArrayTestMovable(2));
|
||||
|
||||
TS_ASSERT(movablePairArray[0].first._wasMoveConstructed);
|
||||
TS_ASSERT_EQUALS(movablePairArray[0].first._value, 1);
|
||||
TS_ASSERT(movablePairArray[0].second._wasMoveConstructed);
|
||||
TS_ASSERT_EQUALS(movablePairArray[0].second._value, 2);
|
||||
}
|
||||
|
||||
void test_push_back_move() {
|
||||
ArrayTestMovable movable(3);
|
||||
|
||||
Common::Array<ArrayTestMovable> movableArray;
|
||||
movableArray.push_back(Common::move(movable));
|
||||
|
||||
TS_ASSERT(movable._wasMovedFrom);
|
||||
TS_ASSERT_EQUALS(movableArray[0]._value, 3);
|
||||
TS_ASSERT(movableArray[0]._wasMoveConstructed);
|
||||
}
|
||||
};
|
||||
128
test/common/base64.h
Normal file
128
test/common/base64.h
Normal file
@@ -0,0 +1,128 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/base64.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
static const char *base64_test_string[] = {
|
||||
"",
|
||||
"a",
|
||||
"abc",
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
("12345678901234567890123456789012345678901234567890123456789012"
|
||||
"345678901234567890")
|
||||
};
|
||||
|
||||
static const char *base64_test_encoded[] = {
|
||||
"",
|
||||
"YQ==",
|
||||
"YWJj",
|
||||
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=",
|
||||
("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdH"
|
||||
"V2d3h5ejAxMjM0NTY3ODk="),
|
||||
("MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Nj"
|
||||
"c4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTA=")
|
||||
};
|
||||
|
||||
static const char *base64_validate_tests[] = {
|
||||
"YQ", // missing padding
|
||||
"!@#$", // characters not in encoding table
|
||||
"YQ==YWJj", // data after padding
|
||||
};
|
||||
|
||||
#include "common/pack-start.h" // START STRUCT PACKING
|
||||
|
||||
struct Base64TestStruct {
|
||||
uint32 x;
|
||||
byte y;
|
||||
uint16 z;
|
||||
uint32 a;
|
||||
byte b;
|
||||
} PACKED_STRUCT;
|
||||
|
||||
#include "common/pack-end.h" // END STRUCT PACKING
|
||||
|
||||
class Base64TestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_b64Validate() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Common::String encoded = base64_test_encoded[i];
|
||||
// All of these should return true.
|
||||
TS_ASSERT_EQUALS(Common::b64Validate(encoded), true);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Common::String encoded = base64_validate_tests[i];
|
||||
// All of these should return false.
|
||||
TS_ASSERT_EQUALS(Common::b64Validate(encoded), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void test_b64EncodeString() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Common::String string = base64_test_string[i];
|
||||
Common::String encoded = Common::b64EncodeString(string);
|
||||
TS_ASSERT_EQUALS(encoded, base64_test_encoded[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_b64EncodeStream() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Common::MemoryReadStream stream((const byte *)base64_test_string[i], strlen(base64_test_string[i]));
|
||||
Common::String encoded = Common::b64EncodeStream(stream);
|
||||
TS_ASSERT_EQUALS(encoded, base64_test_encoded[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_b64EncodeData() {
|
||||
Base64TestStruct *test = new Base64TestStruct();
|
||||
test->x = TO_LE_32(1);
|
||||
test->y = 2;
|
||||
test->z = TO_LE_16(3);
|
||||
test->a = TO_LE_32(4);
|
||||
test->b = 5;
|
||||
|
||||
Common::String encoded = Common::b64EncodeData(test, sizeof(Base64TestStruct));
|
||||
TS_ASSERT_EQUALS(encoded, "AQAAAAIDAAQAAAAF");
|
||||
delete test;
|
||||
}
|
||||
|
||||
void test_b64DecodeString() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Common::String encoded = base64_test_encoded[i];
|
||||
Common::String string = Common::b64DecodeString(encoded);
|
||||
TS_ASSERT_EQUALS(string, base64_test_string[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_b64DecodeStream() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Common::String encoded = base64_test_encoded[i];
|
||||
Common::MemoryReadStream *stream = Common::b64DecodeStream(encoded, strlen(base64_test_string[i]));
|
||||
TS_ASSERT_EQUALS(stream->size(), (int64)strlen(base64_test_string[i]));
|
||||
|
||||
char *data = (char *)malloc(stream->size());
|
||||
stream->read(data, stream->size());
|
||||
delete stream;
|
||||
|
||||
Common::String string(data, strlen(base64_test_string[i]));
|
||||
TS_ASSERT_EQUALS(string, base64_test_string[i]);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void test_b64DecodeData() {
|
||||
Base64TestStruct *test = new Base64TestStruct();
|
||||
|
||||
Common::String encoded = "AQAAAAIDAAQAAAAF";
|
||||
bool success = Common::b64DecodeData(encoded, test);
|
||||
TS_ASSERT_EQUALS(success, true);
|
||||
|
||||
TS_ASSERT_EQUALS(FROM_LE_32(test->x), 1u);
|
||||
TS_ASSERT_EQUALS(test->y, 2u);
|
||||
TS_ASSERT_EQUALS(FROM_LE_16(test->z), 3u);
|
||||
TS_ASSERT_EQUALS(FROM_LE_32(test->a), 4u);
|
||||
TS_ASSERT_EQUALS(test->b, 5u);
|
||||
delete test;
|
||||
}
|
||||
};
|
||||
258
test/common/bitstream.h
Normal file
258
test/common/bitstream.h
Normal file
@@ -0,0 +1,258 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/bitstream.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
class BitStreamTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_get_bit() {
|
||||
byte contents[] = { 'a' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.getBit(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.getBit(), 1u);
|
||||
TS_ASSERT_EQUALS(bs.getBit(), 1u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 3u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_get_bit() {
|
||||
tmpl_get_bit<Common::MemoryReadStream, Common::BitStream8MSB>();
|
||||
tmpl_get_bit<Common::BitStreamMemoryStream, Common::BitStreamMemory8MSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_get_bits() {
|
||||
byte contents[] = { 'a', 'b' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.getBits(3), 3u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 3u);
|
||||
TS_ASSERT_EQUALS(bs.getBits(8), 11u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 11u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_get_bits() {
|
||||
tmpl_get_bits<Common::MemoryReadStream, Common::BitStream8MSB>();
|
||||
tmpl_get_bits<Common::BitStreamMemoryStream, Common::BitStreamMemory8MSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_skip() {
|
||||
byte contents[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.skip(5);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 5u);
|
||||
bs.skip(4);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 9u);
|
||||
TS_ASSERT_EQUALS(bs.getBits(3), 6u);
|
||||
bs.skip(65);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 77u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_skip() {
|
||||
tmpl_skip<Common::MemoryReadStream, Common::BitStream8MSB>();
|
||||
tmpl_skip<Common::BitStreamMemoryStream, Common::BitStreamMemory8MSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_rewind() {
|
||||
byte contents[] = { 'a' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.skip(5);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 5u);
|
||||
bs.rewind();
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.getBits(3), 3u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
|
||||
TS_ASSERT_EQUALS(bs.size(), 8u);
|
||||
}
|
||||
public:
|
||||
void test_rewind() {
|
||||
tmpl_rewind<Common::MemoryReadStream, Common::BitStream8MSB>();
|
||||
tmpl_rewind<Common::BitStreamMemoryStream, Common::BitStreamMemory8MSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_peek_bit() {
|
||||
byte contents[] = { 'a' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.peekBit(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.getBit(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 1u);
|
||||
TS_ASSERT_EQUALS(bs.peekBit(), 1u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 1u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_peek_bit() {
|
||||
tmpl_peek_bit<Common::MemoryReadStream, Common::BitStream8MSB>();
|
||||
tmpl_peek_bit<Common::BitStreamMemoryStream, Common::BitStreamMemory8MSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_peek_bits() {
|
||||
byte contents[] = { 'a', 'b' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.peekBits(3), 3u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.skip(3);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 3u);
|
||||
TS_ASSERT_EQUALS(bs.peekBits(8), 11u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 3u);
|
||||
bs.skip(8);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 11u);
|
||||
TS_ASSERT_EQUALS(bs.peekBits(6), 4u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_peek_bits() {
|
||||
tmpl_peek_bits<Common::MemoryReadStream, Common::BitStream8MSB>();
|
||||
tmpl_peek_bits<Common::BitStreamMemoryStream, Common::BitStreamMemory8MSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_eos() {
|
||||
byte contents[] = { 'a', 'b' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
bs.skip(11);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 11u);
|
||||
TS_ASSERT_EQUALS(bs.getBits(5), 2u);
|
||||
TS_ASSERT(bs.eos());
|
||||
|
||||
bs.rewind();
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_eos() {
|
||||
tmpl_eos<Common::MemoryReadStream, Common::BitStream8MSB>();
|
||||
tmpl_eos<Common::BitStreamMemoryStream, Common::BitStreamMemory8MSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_get_bits_lsb() {
|
||||
byte contents[] = { 'a', 'b' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.getBits(3), 1u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 3u);
|
||||
TS_ASSERT_EQUALS(bs.getBits(8), 76u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 11u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_get_bits_lsb() {
|
||||
tmpl_get_bits_lsb<Common::MemoryReadStream, Common::BitStream8LSB>();
|
||||
tmpl_get_bits_lsb<Common::BitStreamMemoryStream, Common::BitStreamMemory8LSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_peek_bits_lsb() {
|
||||
byte contents[] = { 'a', 'b' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
TS_ASSERT_EQUALS(bs.peekBits(3), 1u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.skip(3);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 3u);
|
||||
TS_ASSERT_EQUALS(bs.peekBits(8), 76u);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 3u);
|
||||
bs.skip(8);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 11u);
|
||||
TS_ASSERT_EQUALS(bs.peekBits(20), 12u);
|
||||
TS_ASSERT(!bs.eos());
|
||||
}
|
||||
public:
|
||||
void test_peek_bits_lsb() {
|
||||
tmpl_peek_bits_lsb<Common::MemoryReadStream, Common::BitStream8LSB>();
|
||||
tmpl_peek_bits_lsb<Common::BitStreamMemoryStream, Common::BitStreamMemory8LSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_align() {
|
||||
byte contents[] = { 'a', 'b' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.align();
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.skip(3);
|
||||
bs.align();
|
||||
TS_ASSERT_EQUALS(bs.pos(), 8u);
|
||||
}
|
||||
public:
|
||||
void test_align() {
|
||||
tmpl_align<Common::MemoryReadStream, Common::BitStream8LSB>();
|
||||
tmpl_align<Common::BitStreamMemoryStream, Common::BitStreamMemory8LSB>();
|
||||
}
|
||||
|
||||
private:
|
||||
template<class MS, class BS>
|
||||
void tmpl_align_16() {
|
||||
byte contents[] = { 'a', 'b' };
|
||||
|
||||
MS ms(contents, sizeof(contents));
|
||||
|
||||
BS bs(ms);
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.align();
|
||||
TS_ASSERT_EQUALS(bs.pos(), 0u);
|
||||
bs.skip(3);
|
||||
bs.align();
|
||||
TS_ASSERT_EQUALS(bs.pos(), 16u);
|
||||
}
|
||||
public:
|
||||
void test_align_16() {
|
||||
tmpl_align_16<Common::MemoryReadStream, Common::BitStream16BELSB>();
|
||||
tmpl_align_16<Common::BitStreamMemoryStream, Common::BitStreamMemory16BELSB>();
|
||||
}
|
||||
};
|
||||
60
test/common/bufferedreadstream.h
Normal file
60
test/common/bufferedreadstream.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
#include "common/bufferedstream.h"
|
||||
|
||||
class BufferedReadStreamTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_traverse() {
|
||||
byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Common::MemoryReadStream ms(contents, 10);
|
||||
|
||||
// Use a buffer size of 4 -- note that 10 % 4 != 0,
|
||||
// so we test what happens if the cache can't be completely
|
||||
// refilled.
|
||||
Common::ReadStream &srs = *Common::wrapBufferedReadStream(&ms, 4, DisposeAfterUse::NO);
|
||||
|
||||
byte i, b;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
TS_ASSERT(!srs.eos());
|
||||
|
||||
b = srs.readByte();
|
||||
TS_ASSERT_EQUALS(i, b);
|
||||
}
|
||||
|
||||
TS_ASSERT(!srs.eos());
|
||||
|
||||
b = srs.readByte();
|
||||
|
||||
TS_ASSERT(srs.eos());
|
||||
|
||||
delete &srs;
|
||||
}
|
||||
|
||||
void test_traverse2() {
|
||||
byte contents[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
Common::MemoryReadStream ms(contents, 9);
|
||||
|
||||
Common::ReadStream &brs = *Common::wrapBufferedReadStream(&ms, 4, DisposeAfterUse::NO);
|
||||
|
||||
// Traverse the stream with reads of 2 bytes. The size is not
|
||||
// a multiple of 2, so we can test the final partial read.
|
||||
|
||||
byte i, b[2];
|
||||
for (i = 0; i < 4; ++i) {
|
||||
TS_ASSERT(!brs.eos());
|
||||
|
||||
int n = brs.read(b, 2);
|
||||
TS_ASSERT_EQUALS(n, 2);
|
||||
}
|
||||
|
||||
TS_ASSERT(!brs.eos());
|
||||
|
||||
int n = brs.read(b, 2);
|
||||
TS_ASSERT_EQUALS(n, 1);
|
||||
|
||||
TS_ASSERT(brs.eos());
|
||||
|
||||
delete &brs;
|
||||
}
|
||||
};
|
||||
94
test/common/bufferedseekablereadstream.h
Normal file
94
test/common/bufferedseekablereadstream.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
#include "common/bufferedstream.h"
|
||||
|
||||
class BufferedSeekableReadStreamTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_traverse() {
|
||||
byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Common::MemoryReadStream ms(contents, 10);
|
||||
|
||||
Common::SeekableReadStream &ssrs
|
||||
= *Common::wrapBufferedSeekableReadStream(&ms, 4, DisposeAfterUse::NO);
|
||||
|
||||
byte i, b;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
|
||||
TS_ASSERT_EQUALS(i, ssrs.pos());
|
||||
|
||||
ssrs.read(&b, 1);
|
||||
TS_ASSERT_EQUALS(i, b);
|
||||
}
|
||||
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
|
||||
TS_ASSERT_EQUALS((uint)0, ssrs.read(&b, 1));
|
||||
TS_ASSERT(ssrs.eos());
|
||||
|
||||
delete &ssrs;
|
||||
}
|
||||
|
||||
void test_seek() {
|
||||
byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Common::MemoryReadStream ms(contents, 10);
|
||||
|
||||
Common::SeekableReadStream &ssrs
|
||||
= *Common::wrapBufferedSeekableReadStream(&ms, 4, DisposeAfterUse::NO);
|
||||
byte b;
|
||||
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 0);
|
||||
|
||||
ssrs.seek(1, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 1);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 1);
|
||||
|
||||
ssrs.seek(5, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 7);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 7);
|
||||
|
||||
ssrs.seek(-3, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 5);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 5);
|
||||
|
||||
ssrs.seek(0, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 10);
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT(ssrs.eos());
|
||||
|
||||
ssrs.seek(-3, SEEK_END);
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 7);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 7);
|
||||
|
||||
ssrs.seek(-8, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 2);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 2);
|
||||
|
||||
ssrs.seek(5, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 8);
|
||||
ssrs.seek(-1, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 7);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 7);
|
||||
|
||||
byte readBuffer[8];
|
||||
ssrs.seek(0, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 0);
|
||||
ssrs.readByte();
|
||||
b = ssrs.read(&readBuffer, 8);
|
||||
ssrs.seek(-1, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 8);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 8);
|
||||
|
||||
delete &ssrs;
|
||||
}
|
||||
};
|
||||
97
test/common/compression/huffman.h
Normal file
97
test/common/compression/huffman.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/compression/huffman.h"
|
||||
#include "common/bitstream.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
/**
|
||||
* A test suite for the Huffman decoder in common/compression/huffman.h
|
||||
* The encoding used comes from the example on the Wikipedia page
|
||||
* for Huffman.
|
||||
* TODO: It could be improved by generating one at runtime.
|
||||
*/
|
||||
class HuffmanTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_get_with_full_symbols() {
|
||||
|
||||
/*
|
||||
* The class can be initialized with or without providing
|
||||
* a max_length and a symbol table.
|
||||
* We test with a table.
|
||||
*
|
||||
* Encoding (arbitrary, for testing purpouses):
|
||||
* 0xA=010
|
||||
* 0xB=011
|
||||
* 0xC=11
|
||||
* 0xD=00
|
||||
* 0xE=10
|
||||
*/
|
||||
|
||||
uint32 codeCount = 5;
|
||||
uint8 maxLength = 3;
|
||||
const uint8 lengths[] = {3,3,2,2,2};
|
||||
const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2};
|
||||
const uint32 symbols[] = {0xA, 0xB, 0xC, 0xD, 0xE};
|
||||
|
||||
Common::Huffman<Common::BitStream8MSB> h(maxLength, codeCount, codes, lengths, symbols);
|
||||
|
||||
byte input[] = {0x4F, 0x20};
|
||||
// Provided input...
|
||||
uint32 expected[] = {0xA, 0xB, 0xC, 0xD, 0xE, 0xD, 0xD};
|
||||
// ..and expected output.
|
||||
|
||||
/*
|
||||
* What should be going on:
|
||||
* 010 011 11 00 10 00 00 = A B C D E D D
|
||||
* = 0100 1111 0010 0000 = 0x4F20
|
||||
*/
|
||||
|
||||
Common::MemoryReadStream ms(input, sizeof(input));
|
||||
Common::BitStream8MSB bs(ms);
|
||||
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[0]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[1]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[2]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[3]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[4]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[5]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[6]);
|
||||
}
|
||||
|
||||
void test_get_without_symbols() {
|
||||
|
||||
/*
|
||||
* This is basically the same as test_get_with_full_symbols, but
|
||||
* I only pass the minimal required arguments.
|
||||
* Specifically, I avoid passing the symbols table, so that
|
||||
* array indices are used instead.
|
||||
*
|
||||
* Encoding becomes:
|
||||
*
|
||||
* 0=010
|
||||
* 1=011
|
||||
* 2=11
|
||||
* 3=00
|
||||
* 4=10
|
||||
*/
|
||||
|
||||
uint32 codeCount = 5;
|
||||
const uint8 lengths[] = {3,3,2,2,2};
|
||||
const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2};
|
||||
|
||||
Common::Huffman<Common::BitStream8MSB> h(0, codeCount, codes, lengths, 0);
|
||||
|
||||
byte input[] = {0x4F, 0x20};
|
||||
uint32 expected[] = {0, 1, 2, 3, 4, 3 ,3};
|
||||
|
||||
Common::MemoryReadStream ms(input, sizeof(input));
|
||||
Common::BitStream8MSB bs(ms);
|
||||
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[0]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[1]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[2]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[3]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[4]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[5]);
|
||||
TS_ASSERT_EQUALS(h.getSymbol(bs), expected[6]);
|
||||
}
|
||||
};
|
||||
73
test/common/crc.h
Normal file
73
test/common/crc.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/crc.h"
|
||||
#include "common/crc_slow.h"
|
||||
|
||||
namespace {
|
||||
const byte *testStringCRC = (const byte *)"The quick brown fox jumps over the lazy dog";
|
||||
const int testLenCRC = 43;
|
||||
}
|
||||
|
||||
class CrcTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_crc32() {
|
||||
Common::CRC32 crc;
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testStringCRC, testLenCRC), 0x414fa339U);
|
||||
uint32 running = crc.getInitRemainder();
|
||||
for (const byte *ptr = testStringCRC; *ptr; ptr++) {
|
||||
running = crc.processByte(*ptr, running);
|
||||
}
|
||||
TS_ASSERT_EQUALS(crc.finalize(running), 0x414fa339U);
|
||||
}
|
||||
|
||||
void test_crc16() {
|
||||
Common::CRC16 crc;
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testStringCRC, testLenCRC), 0xfcdfU);
|
||||
uint16 running = crc.getInitRemainder();
|
||||
for (const byte *ptr = testStringCRC; *ptr; ptr++) {
|
||||
running = crc.processByte(*ptr, running);
|
||||
}
|
||||
TS_ASSERT_EQUALS(crc.finalize(running), 0xfcdfU);
|
||||
}
|
||||
|
||||
void test_crc_ccitt() {
|
||||
Common::CRC_CCITT crc; // aka ccitt-false
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testStringCRC, testLenCRC), 0x8fddU);
|
||||
uint16 running = crc.getInitRemainder();
|
||||
for (const byte *ptr = testStringCRC; *ptr; ptr++) {
|
||||
running = crc.processByte(*ptr, running);
|
||||
}
|
||||
TS_ASSERT_EQUALS(crc.finalize(running), 0x8fddU);
|
||||
}
|
||||
|
||||
void test_crc_binhex() {
|
||||
Common::CRC_BINHEX crc; // Aka xmodem
|
||||
TS_ASSERT_EQUALS(crc.crcFast(testStringCRC, testLenCRC), 0xf0c8U);
|
||||
uint16 running = crc.getInitRemainder();
|
||||
for (const byte *ptr = testStringCRC; *ptr; ptr++) {
|
||||
running = crc.processByte(*ptr, running);
|
||||
}
|
||||
TS_ASSERT_EQUALS(crc.finalize(running), 0xf0c8U);
|
||||
}
|
||||
|
||||
void test_crc32_slow() {
|
||||
Common::CRC32_Slow crc;
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testStringCRC, testLenCRC), 0x414fa339U);
|
||||
}
|
||||
|
||||
void test_crc16_slow() {
|
||||
Common::CRC16_Slow crc;
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testStringCRC, testLenCRC), 0xfcdfU);
|
||||
}
|
||||
|
||||
void test_crc_ccitt_slow() {
|
||||
Common::CRC_CCITT_Slow crc; // aka ccitt-false
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testStringCRC, testLenCRC), 0x8fddU);
|
||||
}
|
||||
|
||||
void test_crc_binhex_slow() {
|
||||
Common::CRC_BINHEX_Slow crc; // Aka xmodem
|
||||
TS_ASSERT_EQUALS(crc.crcSlow(testStringCRC, testLenCRC), 0xf0c8U);
|
||||
}
|
||||
};
|
||||
274
test/common/encoding.h
Normal file
274
test/common/encoding.h
Normal file
@@ -0,0 +1,274 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
#include "../system/null_osystem.h"
|
||||
|
||||
// We support CJK on all the platforms but it relies on OSystem to read
|
||||
// file which *in test environments* is available only on some platforms
|
||||
#if NULL_OSYSTEM_IS_AVAILABLE
|
||||
#define TEST_CJK 1
|
||||
#else
|
||||
#define TEST_CJK 0
|
||||
#endif
|
||||
|
||||
class EncodingTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_korean() {
|
||||
#if TEST_CJK
|
||||
Common::install_null_g_system();
|
||||
const byte utf8[] = {
|
||||
0xea, 0xb2, 0x8c, 0xec, 0x9e, 0x84, 0xec, 0xa4,
|
||||
0x91, 0xec, 0xa7, 0x80, 0x20, 0xea, 0xb3, 0x84,
|
||||
0xec, 0x86, 0x8d, 0xed, 0x95, 0x98, 0xeb, 0xa0,
|
||||
0xa4, 0xeb, 0xa9, 0xb4, 0x20, 0xec, 0x8a, 0xa4,
|
||||
0xed, 0x8e, 0x98, 0xec, 0x9d, 0xb4, 0xec, 0x8a,
|
||||
0xa4, 0xed, 0x82, 0xa4, 0xeb, 0xa5, 0xbc, 0x20,
|
||||
0xec, 0xb9, 0x98, 0xec, 0x8b, 0x9c, 0xec, 0x98,
|
||||
0xa4, 0x2e, 0x00,
|
||||
};
|
||||
|
||||
const Common::u32char_type_t utf32[] = {
|
||||
0xac8c, 0xc784, 0xc911, 0xc9c0, 0x0020, 0xacc4,
|
||||
0xc18d, 0xd558, 0xb824, 0xba74, 0x0020, 0xc2a4,
|
||||
0xd398, 0xc774, 0xc2a4, 0xd0a4, 0xb97c, 0x0020,
|
||||
0xce58, 0xc2dc, 0xc624, 0x002e, 0
|
||||
};
|
||||
|
||||
const byte uhc[] = {
|
||||
0xb0, 0xd4, 0xc0, 0xd3, 0xc1, 0xdf, 0xc1, 0xf6,
|
||||
0x20, 0xb0, 0xe8, 0xbc, 0xd3, 0xc7, 0xcf, 0xb7,
|
||||
0xc1, 0xb8, 0xe9, 0x20, 0xbd, 0xba, 0xc6, 0xe4,
|
||||
0xc0, 0xcc, 0xbd, 0xba, 0xc5, 0xb0, 0xb8, 0xa6,
|
||||
0x20, 0xc4, 0xa1, 0xbd, 0xc3, 0xbf, 0xc0, 0x2e,
|
||||
0x00
|
||||
};
|
||||
Common::U32String ustr_from_utf8((const char *) utf8, Common::kUtf8);
|
||||
Common::U32String ustr_from_uhc((const char *) uhc, Common::kWindows949);
|
||||
Common::U32String ustr(utf32);
|
||||
Common::String utf8_to_uhc = ustr_from_utf8.encode(Common::kWindows949);
|
||||
Common::String uhc_to_utf8 = ustr_from_uhc.encode(Common::kUtf8);
|
||||
TS_ASSERT_EQUALS(ustr_from_utf8, ustr);
|
||||
TS_ASSERT_EQUALS(ustr_from_uhc, ustr);
|
||||
TS_ASSERT(strcmp((const char *) utf8, uhc_to_utf8.c_str()) == 0);
|
||||
TS_ASSERT(strcmp((const char *) uhc, utf8_to_uhc.c_str()) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_chinese() {
|
||||
#if TEST_CJK
|
||||
Common::install_null_g_system();
|
||||
const byte utf8[] = {
|
||||
0xe9, 0x81, 0x8a, 0xe6, 0x88, 0xb2, 0xe6, 0x9a,
|
||||
0xab, 0xe5, 0x81, 0x9c, 0xe3, 0x80, 0x82, 0xe6,
|
||||
0x8c, 0x89, 0xe4, 0xb8, 0x8b, 0xe7, 0xa9, 0xba,
|
||||
0x21, 0xe7, 0x99, 0xbd, 0xe9, 0x8d, 0xb5, 0xe7,
|
||||
0xb9, 0xbc, 0xe7, 0xba, 0x8c, 0xe9, 0x81, 0x8a,
|
||||
0xe6, 0x88, 0xb2, 0xe3, 0x80, 0x82, 0x00,
|
||||
};
|
||||
|
||||
const Common::u32char_type_t utf32[] = {
|
||||
0x904a, 0x6232, 0x66ab, 0x505c, 0x3002, 0x6309,
|
||||
0x4e0b, 0x7a7a, 0x0021, 0x767d, 0x9375, 0x7e7c,
|
||||
0x7e8c, 0x904a, 0x6232, 0x3002, 0
|
||||
};
|
||||
|
||||
const byte big5[] = {
|
||||
0xb9, 0x43, 0xc0, 0xb8, 0xbc, 0xc8, 0xb0, 0xb1,
|
||||
0xa1, 0x43, 0xab, 0xf6, 0xa4, 0x55, 0xaa, 0xc5,
|
||||
0x21, 0xa5, 0xd5, 0xc1, 0xe4, 0xc4, 0x7e, 0xc4,
|
||||
0xf2, 0xb9, 0x43, 0xc0, 0xb8, 0xa1, 0x43, 0x00
|
||||
};
|
||||
Common::U32String ustr_from_utf8((const char *) utf8, Common::kUtf8);
|
||||
Common::U32String ustr_from_big5((const char *) big5, Common::kWindows950);
|
||||
Common::U32String ustr(utf32);
|
||||
Common::String utf8_to_big5 = ustr_from_utf8.encode(Common::kWindows950);
|
||||
Common::String big5_to_utf8 = ustr_from_big5.encode(Common::kUtf8);
|
||||
TS_ASSERT_EQUALS(ustr_from_utf8, ustr);
|
||||
TS_ASSERT_EQUALS(ustr_from_big5, ustr);
|
||||
TS_ASSERT(strcmp((const char *) utf8, big5_to_utf8.c_str()) == 0);
|
||||
TS_ASSERT(strcmp((const char *) big5, utf8_to_big5.c_str()) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_japanese() {
|
||||
#if TEST_CJK
|
||||
Common::install_null_g_system();
|
||||
const byte utf8[] = {
|
||||
0xe4, 0xb8, 0x80, 0xe6, 0x99, 0x82, 0xe5, 0x81,
|
||||
0x9c, 0xe6, 0xad, 0xa2, 0xe3, 0x80, 0x82, 0xe7,
|
||||
0xb6, 0x9a, 0xe3, 0x81, 0x91, 0xe3, 0x82, 0x8b,
|
||||
0xe5, 0xa0, 0xb4, 0xe5, 0x90, 0x88, 0xe3, 0x81,
|
||||
0xaf, 0xe3, 0x82, 0xb9, 0xe3, 0x83, 0x9a, 0xe3,
|
||||
0x83, 0xbc, 0xe3, 0x82, 0xb9, 0xe3, 0x83, 0x90,
|
||||
0xe3, 0x83, 0xbc, 0xe3, 0x82, 0x92, 0xe6, 0x8a,
|
||||
0xbc, 0xe3, 0x81, 0x97, 0xe3, 0x81, 0xa6, 0xe3,
|
||||
0x81, 0x8f, 0xe3, 0x81, 0xa0, 0xe3, 0x81, 0x95,
|
||||
0xe3, 0x81, 0x84, 0xe3, 0x80, 0x82, 0
|
||||
};
|
||||
|
||||
const Common::u32char_type_t utf32[] = {
|
||||
0x4e00, 0x6642, 0x505c, 0x6b62, 0x3002, 0x7d9a,
|
||||
0x3051, 0x308b, 0x5834, 0x5408, 0x306f, 0x30b9,
|
||||
0x30da, 0x30fc, 0x30b9, 0x30d0, 0x30fc, 0x3092,
|
||||
0x62bc, 0x3057, 0x3066, 0x304f, 0x3060, 0x3055,
|
||||
0x3044, 0x3002, 0
|
||||
};
|
||||
|
||||
const byte cp932[] = {
|
||||
0x88, 0xea, 0x8e, 0x9e, 0x92, 0xe2, 0x8e, 0x7e,
|
||||
0x81, 0x42, 0x91, 0xb1, 0x82, 0xaf, 0x82, 0xe9,
|
||||
0x8f, 0xea, 0x8d, 0x87, 0x82, 0xcd, 0x83, 0x58,
|
||||
0x83, 0x79, 0x81, 0x5b, 0x83, 0x58, 0x83, 0x6f,
|
||||
0x81, 0x5b, 0x82, 0xf0, 0x89, 0x9f, 0x82, 0xb5,
|
||||
0x82, 0xc4, 0x82, 0xad, 0x82, 0xbe, 0x82, 0xb3,
|
||||
0x82, 0xa2, 0x81, 0x42, 0
|
||||
};
|
||||
Common::U32String ustr_from_utf8((const char *) utf8, Common::kUtf8);
|
||||
Common::U32String ustr_from_cp932((const char *) cp932, Common::kWindows932);
|
||||
Common::U32String ustr(utf32);
|
||||
Common::String utf8_to_cp932 = ustr_from_utf8.encode(Common::kWindows932);
|
||||
Common::String cp932_to_utf8 = ustr_from_cp932.encode(Common::kUtf8);
|
||||
TS_ASSERT_EQUALS(ustr_from_utf8, ustr);
|
||||
TS_ASSERT_EQUALS(ustr_from_cp932, ustr);
|
||||
TS_ASSERT(strcmp((const char *) utf8, cp932_to_utf8.c_str()) == 0);
|
||||
TS_ASSERT(strcmp((const char *) cp932, utf8_to_cp932.c_str()) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_unicode_machine_endian() {
|
||||
// |dolar| cent | euro |
|
||||
unsigned char utf8[] = {0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0};
|
||||
#ifdef SCUMM_BIG_ENDIAN
|
||||
//| dolar | cent | euro |
|
||||
unsigned char utf16be[] = {0, 0x24, 0, 0xA2, 0x20, 0xAC, 0, 0};
|
||||
//| dolar | cent | euro
|
||||
unsigned char utf32be[] = {0, 0, 0, 0x24, 0, 0, 0, 0xA2, 0, 0, 0x20, 0xAC, 0, 0, 0, 0};
|
||||
|
||||
unsigned char *utf16 = utf16be;
|
||||
unsigned char *utf32 = utf32be;
|
||||
#else
|
||||
//| dolar | cent | euro |
|
||||
unsigned char utf16le[] = {0x24, 0, 0xA2, 0, 0xAC, 0x20, 0, 0};
|
||||
//| dolar | cent | euro
|
||||
unsigned char utf32le[] = {0x24, 0, 0, 0, 0xA2, 0, 0, 0, 0xAC, 0x20, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
unsigned char *utf16 = utf16le;
|
||||
unsigned char *utf32 = utf32le;
|
||||
#endif
|
||||
|
||||
// UTF16 to UTF8
|
||||
Common::String resultstr8 = Common::U32String::decodeUTF16Native((uint16 *) utf16, 3).encode(Common::kUtf8);
|
||||
TS_ASSERT(resultstr8.c_str() != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(resultstr8.c_str(), utf8, 7), 0)
|
||||
|
||||
// UTF32 to UTF8
|
||||
|
||||
resultstr8 = Common::U32String((Common::u32char_type_t *) utf32, 3).encode(Common::kUtf8);
|
||||
TS_ASSERT(resultstr8.c_str() != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(resultstr8.c_str(), utf8, 7), 0);
|
||||
|
||||
// UTF32 to UTF16
|
||||
uint16 *result16 = Common::U32String((Common::u32char_type_t *) utf32, 3).encodeUTF16Native(NULL);
|
||||
TS_ASSERT(result16 != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(result16, utf16, 8), 0);
|
||||
delete[] result16;
|
||||
|
||||
// UTF8 to UTF16
|
||||
|
||||
result16 = Common::U32String((char *) utf8, 6, Common::kUtf8).encodeUTF16Native(NULL);
|
||||
TS_ASSERT(result16 != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(result16, utf16, 8), 0);
|
||||
delete[] result16;
|
||||
|
||||
// UTF8 to UTF32
|
||||
Common::U32String resultustr = Common::String((const char *) utf8, 6).decode(Common::kUtf8);
|
||||
TS_ASSERT_EQUALS(memcmp(resultustr.c_str(), utf32, 16), 0);
|
||||
|
||||
// UTF16 to UTF32
|
||||
resultustr = Common::U32String::decodeUTF16Native((uint16 *) utf16, 3);
|
||||
TS_ASSERT_EQUALS(memcmp(resultustr.c_str(), utf32, 16), 0);
|
||||
}
|
||||
|
||||
void test_conversion_unicode_big_endian() {
|
||||
// |dolar| cent | euro |
|
||||
unsigned char utf8[] = {0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0};
|
||||
//| dolar | cent | euro |
|
||||
unsigned char utf16be[] = {0, 0x24, 0, 0xA2, 0x20, 0xAC, 0, 0};
|
||||
|
||||
// UTF16 to UTF8
|
||||
Common::String resultstr8 = Common::U32String::decodeUTF16BE((uint16 *) utf16be, 3).encode(Common::kUtf8);
|
||||
TS_ASSERT(resultstr8.c_str() != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(resultstr8.c_str(), utf8, 7), 0);
|
||||
|
||||
|
||||
// UTF8 to UTF16
|
||||
uint16 *result16 = Common::U32String((char *) utf8, 6, Common::kUtf8).encodeUTF16BE(NULL);
|
||||
TS_ASSERT(result16 != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(result16, utf16be, 8), 0);
|
||||
delete[] result16;
|
||||
|
||||
}
|
||||
|
||||
void test_conversion_unicode_little_endian() {
|
||||
// |dolar| cent | euro |
|
||||
unsigned char utf8[] = {0x24, 0xC2, 0xA2, 0xE2, 0x82, 0xAC, 0};
|
||||
//| dolar | cent | euro |
|
||||
unsigned char utf16le[] = {0x24, 0, 0xA2, 0, 0xAC, 0x20, 0, 0};
|
||||
|
||||
// UTF16 to UTF8
|
||||
Common::String resultstr8 = Common::U32String::decodeUTF16LE((uint16 *) utf16le, 3).encode(Common::kUtf8);
|
||||
TS_ASSERT(resultstr8.c_str() != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(resultstr8.c_str(), utf8, 7), 0);
|
||||
|
||||
// UTF8 to UTF16
|
||||
uint16 *result16 = Common::U32String((char *) utf8, 6, Common::kUtf8).encodeUTF16LE(NULL);
|
||||
TS_ASSERT(result16 != NULL);
|
||||
TS_ASSERT_EQUALS(memcmp(result16, utf16le, 8), 0);
|
||||
delete[] result16;
|
||||
|
||||
}
|
||||
|
||||
void test_cyrillic_transliteration() {
|
||||
unsigned char utf8[] = {/* Z */0xD0, 0x97, /* d */ 0xD0, 0xB4, /* r */ 0xD1, 0x80, /* a */ 0xD0, 0xB0, /* v */ 0xD0, 0xB2, /* s */ 0xD1, 0x81, /* t */ 0xD1, 0x82, /* v */ 0xD0, 0xB2, /* u */ 0xD1, 0x83, /* j */ 0xD0, 0xB9, /* t */ 0xD1, 0x82, /* e */ 0xD0, 0xB5, 0};
|
||||
unsigned char iso_8859_5[] = {0xB7, 0xD4, 0xE0, 0xD0, 0xD2, 0xE1, 0xE2, 0xD2, 0xE3, 0xD9, 0xE2, 0xD5, 0};
|
||||
unsigned char ascii[] = "Zdravstvujte";
|
||||
|
||||
Common::String result = Common::U32String((const char *) utf8, 24, Common::kUtf8).encode(Common::kASCII);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), ascii, 13), 0);
|
||||
|
||||
result = Common::U32String((const char *) iso_8859_5, 12, Common::kISO8859_5).encode(Common::kASCII);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), ascii, 13), 0);
|
||||
|
||||
result = Common::U32String((const char *) iso_8859_5, 12, Common::kISO8859_5).encode(Common::kUtf8);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), utf8, 25), 0);
|
||||
|
||||
result = Common::U32String((const char *) utf8, 24, Common::kUtf8).encode(Common::kISO8859_5);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), iso_8859_5, 13), 0);
|
||||
|
||||
// this should stay the same
|
||||
result = Common::U32String((const char *) ascii, 12, Common::kASCII).encode(Common::kISO8859_5);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), ascii, 13), 0);
|
||||
}
|
||||
|
||||
void test_other_conversions() {
|
||||
unsigned char cp850[] = {0x99, 0xE0, 0xEA, 0x41, 0x64, 0};
|
||||
unsigned char utf8_1[] = {0xC3, 0x96, 0xC3, 0x93, 0xC3, 0x9B, 0x41, 0x64, 0};
|
||||
|
||||
unsigned char iso_8859_2[] = {0xA9, 0xE1, 0x6C, 0x65, 0xE8, 0x65, 0x6B, 0};
|
||||
unsigned char utf8_2[] = {0xC5, 0xA0, 0xC3, 0xA1, 0x6C, 0x65, 0xC4, 0x8D, 0x65, 0x6B, 0};
|
||||
|
||||
Common::String result = Common::U32String((const char *) cp850, sizeof(cp850)-1, Common::kDos850).encode(Common::kUtf8);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), utf8_1, sizeof(utf8_1)), 0);
|
||||
|
||||
result = Common::U32String((const char *) utf8_1, sizeof(utf8_1)-1, Common::kUtf8).encode(Common::kDos850);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), cp850, sizeof(cp850)), 0);
|
||||
|
||||
result = Common::U32String((const char *) iso_8859_2, sizeof(iso_8859_2)-1, Common::kISO8859_2).encode(Common::kUtf8);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), utf8_2, sizeof(utf8_2)), 0);
|
||||
|
||||
result = Common::U32String((const char *) utf8_2, sizeof(utf8_2)-1, Common::kUtf8).encode(Common::kISO8859_2);
|
||||
TS_ASSERT_EQUALS(memcmp(result.c_str(), iso_8859_2, sizeof(iso_8859_2)), 0);
|
||||
}
|
||||
};
|
||||
114
test/common/endian.h
Normal file
114
test/common/endian.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/endian.h"
|
||||
|
||||
class EndianTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_MKTAG() {
|
||||
const char *str_tag = "ABCD";
|
||||
uint32 tag = READ_BE_UINT32(str_tag);
|
||||
TS_ASSERT_EQUALS(MKTAG('A','B','C','D'), tag);
|
||||
}
|
||||
|
||||
void test_READ_BE_UINT64() {
|
||||
const byte data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
|
||||
uint64 value = READ_BE_UINT64(data);
|
||||
TS_ASSERT_EQUALS(value, 0x123456789ABCDEFFULL);
|
||||
}
|
||||
|
||||
void test_READ_LE_UINT64() {
|
||||
const byte data[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
|
||||
uint64 value = READ_LE_UINT64(data);
|
||||
TS_ASSERT_EQUALS(value, 0xFFDEBC9A78563412ULL);
|
||||
}
|
||||
|
||||
void test_READ_BE_UINT32() {
|
||||
const char data[4] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
uint32 value = READ_BE_UINT32(data);
|
||||
TS_ASSERT_EQUALS(value, 0x12345678UL);
|
||||
}
|
||||
|
||||
void test_READ_LE_UINT32() {
|
||||
const char data[4] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
uint32 value = READ_LE_UINT32(data);
|
||||
TS_ASSERT_EQUALS(value, 0x78563412UL);
|
||||
}
|
||||
|
||||
void test_READ_BE_UINT16() {
|
||||
const char data[4] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
uint32 value = READ_BE_UINT16(data);
|
||||
TS_ASSERT_EQUALS(value, 0x1234UL);
|
||||
}
|
||||
|
||||
void test_READ_LE_UINT16() {
|
||||
const char data[4] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
uint32 value = READ_LE_UINT16(data);
|
||||
TS_ASSERT_EQUALS(value, 0x3412UL);
|
||||
}
|
||||
|
||||
void test_READ_BE_FLOAT32() {
|
||||
const uint8 data[4] = { 0x40, 0x49, 0x0f, 0xdc };
|
||||
float value = READ_BE_FLOAT32(data);
|
||||
TS_ASSERT_EQUALS(value, 3.141593f);
|
||||
}
|
||||
|
||||
void test_READ_LE_FLOAT32() {
|
||||
const uint8 data[4] = { 0xdc, 0x0f, 0x49, 0x40 };
|
||||
float value = READ_LE_FLOAT32(data);
|
||||
TS_ASSERT_EQUALS(value, 3.141593f);
|
||||
}
|
||||
|
||||
void test_READ_BE_FLOAT64() {
|
||||
const uint8 data[8] = { 0x40, 0x09, 0x21, 0xfb, 0x82, 0xc2, 0xbd, 0x7f };
|
||||
double value = READ_BE_FLOAT64(data);
|
||||
TS_ASSERT_EQUALS(value, 3.141593);
|
||||
}
|
||||
|
||||
void test_READ_LE_FLOAT64() {
|
||||
const uint8 data[8] = { 0x7f, 0xbd, 0xc2, 0x82, 0xfb, 0x21, 0x09, 0x40 };
|
||||
double value = READ_LE_FLOAT64(data);
|
||||
TS_ASSERT_EQUALS(value, 3.141593);
|
||||
}
|
||||
|
||||
void test_READ_FPA_FLOAT64() {
|
||||
const uint8 data[8] = { 0xfb, 0x21, 0x09, 0x40, 0x7f, 0xbd, 0xc2, 0x82 };
|
||||
double value = READ_FPA_FLOAT64(data);
|
||||
TS_ASSERT_EQUALS(value, 3.141593);
|
||||
}
|
||||
|
||||
void test_WRITE_BE_FLOAT32() {
|
||||
const uint8 data[4] = { 0x40, 0x49, 0x0f, 0xdc };
|
||||
uint8 out[4];
|
||||
WRITE_BE_FLOAT32(out, 3.141593f);
|
||||
TS_ASSERT_EQUALS(memcmp(data, out, 4), 0);
|
||||
}
|
||||
|
||||
void test_WRITE_LE_FLOAT32() {
|
||||
const uint8 data[4] = { 0xdc, 0x0f, 0x49, 0x40 };
|
||||
uint8 out[4];
|
||||
WRITE_LE_FLOAT32(out, 3.141593f);
|
||||
TS_ASSERT_EQUALS(memcmp(data, out, 4), 0);
|
||||
}
|
||||
|
||||
void test_WRITE_BE_FLOAT64() {
|
||||
const uint8 data[8] = { 0x40, 0x09, 0x21, 0xfb, 0x82, 0xc2, 0xbd, 0x7f };
|
||||
uint8 out[8];
|
||||
WRITE_BE_FLOAT64(out, 3.141593);
|
||||
TS_ASSERT_EQUALS(memcmp(data, out, 8), 0);
|
||||
}
|
||||
|
||||
void test_WRITE_LE_FLOAT64() {
|
||||
const uint8 data[8] = { 0x7f, 0xbd, 0xc2, 0x82, 0xfb, 0x21, 0x09, 0x40 };
|
||||
uint8 out[8];
|
||||
WRITE_LE_FLOAT64(out, 3.141593);
|
||||
TS_ASSERT_EQUALS(memcmp(data, out, 8), 0);
|
||||
}
|
||||
|
||||
void test_WRITE_FPA_FLOAT64() {
|
||||
const uint8 data[8] = { 0xfb, 0x21, 0x09, 0x40, 0x7f, 0xbd, 0xc2, 0x82 };
|
||||
uint8 out[8];
|
||||
WRITE_FPA_FLOAT64(out, 3.141593);
|
||||
TS_ASSERT_EQUALS(memcmp(data, out, 8), 0);
|
||||
}
|
||||
|
||||
};
|
||||
83
test/common/fixedstack.h
Normal file
83
test/common/fixedstack.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/stack.h"
|
||||
|
||||
class FixedStackTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_empty_clear() {
|
||||
Common::FixedStack<int> stack;
|
||||
TS_ASSERT(stack.empty());
|
||||
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
TS_ASSERT(!stack.empty());
|
||||
|
||||
stack.clear();
|
||||
|
||||
TS_ASSERT(stack.empty());
|
||||
}
|
||||
|
||||
void test_size() {
|
||||
typedef Common::FixedStack<int> Stack;
|
||||
|
||||
Stack stack;
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)0);
|
||||
|
||||
stack.push(5);
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)1);
|
||||
|
||||
stack.push(9);
|
||||
stack.push(0);
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)3);
|
||||
|
||||
stack.pop();
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)2);
|
||||
}
|
||||
|
||||
void test_top_pop() {
|
||||
Common::FixedStack<int> stack;
|
||||
|
||||
stack.push( 42);
|
||||
stack.push(-23);
|
||||
|
||||
TS_ASSERT_EQUALS(stack[0], 42);
|
||||
TS_ASSERT_EQUALS(stack.top(), -23);
|
||||
|
||||
stack[0] = -23;
|
||||
stack.top() = 42;
|
||||
TS_ASSERT_EQUALS(stack[0], -23);
|
||||
TS_ASSERT_EQUALS(stack.top(), 42);
|
||||
|
||||
stack.pop();
|
||||
TS_ASSERT_EQUALS(stack[0], -23);
|
||||
}
|
||||
|
||||
void test_assign() {
|
||||
Common::FixedStack<int> q1, q2;
|
||||
|
||||
for (int i = 0; i <= 4; ++i) {
|
||||
q1.push(4-i);
|
||||
q2.push(i);
|
||||
}
|
||||
|
||||
Common::FixedStack<int> q3(q1);
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
TS_ASSERT_EQUALS(q3.top(), i);
|
||||
q3.pop();
|
||||
}
|
||||
|
||||
TS_ASSERT(q3.empty());
|
||||
|
||||
q3 = q2;
|
||||
|
||||
for (int i = 4; i >= 0; --i) {
|
||||
TS_ASSERT_EQUALS(q3.top(), i);
|
||||
q3.pop();
|
||||
}
|
||||
|
||||
TS_ASSERT(q3.empty());
|
||||
TS_ASSERT(!q1.empty());
|
||||
TS_ASSERT(!q2.empty());
|
||||
}
|
||||
};
|
||||
83
test/common/formats/quicktime.h
Normal file
83
test/common/formats/quicktime.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/util.h"
|
||||
#include "common/formats/quicktime.h"
|
||||
|
||||
static const byte VALID_MOOV_DATA[] = { // a minimally 'correct' quicktime file.
|
||||
// size 'moov' size 'mdat'
|
||||
0x0, 0x0, 0x0, 0x8, 0x6d, 0x6f, 0x6f, 0x76, 0x0, 0x0, 0x0, 0x8, 0x6d, 0x64, 0x61, 0x74
|
||||
};
|
||||
|
||||
static const byte VALID_MHDR_DATA[] = { // a 'correct' quicktime file with a header
|
||||
// size (incl mvhd) 'moov'
|
||||
0x0, 0x0, 0x0, 0x74, 0x6d, 0x6f, 0x6f, 0x76,
|
||||
//size (27*4) 'mvhd' vers 3bytes flags
|
||||
0x0, 0x0, 0x0, 0x6c, 0x6d, 0x76, 0x68, 0x64, 0x00, 0xff, 0xff, 0xff,
|
||||
// creation modification timescale (60?) length (999 * 60)+ 1
|
||||
0x65, 0x52, 0xef, 0x5b, 0x65, 0x52, 0xef, 0x5b, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0xea, 0x25,
|
||||
// preferred scale, vol, [10 bytes reserved]
|
||||
0x0, 0x0, 0x0, 0x1, 0x0, 0x10, 0,0,0,0,0,0,0,0,0,0,
|
||||
// display matrix, mostly ignored by parser except xMod (0x8000) and yMod (0xa000)
|
||||
0x0, 0x0, 0x80, 0x0, 0,0,0,0,0,0,0,0,0,0,0,0, 0x0, 0x0, 0xa0, 0x0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
// 7 more 32-bit values
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
|
||||
// size 'mdat'
|
||||
0x0, 0x0, 0x0, 0x8, 0x6d, 0x64, 0x61, 0x74
|
||||
};
|
||||
|
||||
|
||||
class QuickTimeTestParser : public Common::QuickTimeParser {
|
||||
public:
|
||||
uint32 getDuration() const { return _duration; }
|
||||
const Common::Rational &getScaleFactorX() const { return _scaleFactorX; }
|
||||
const Common::Rational &getScaleFactorY() const { return _scaleFactorY; }
|
||||
const Common::Array<Track *> &getTracks() const { return _tracks; }
|
||||
|
||||
SampleDesc *readSampleDesc(Track *track, uint32 format, uint32 descSize) override {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class QuicktimeParserTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_streamAtEOS() {
|
||||
QuickTimeTestParser parser;
|
||||
const byte data[] = "";
|
||||
Common::MemoryReadStream stream(data, sizeof(data));
|
||||
stream.readByte(); // read the null char
|
||||
bool result = parser.parseStream(&stream, DisposeAfterUse::NO);
|
||||
TS_ASSERT(!result);
|
||||
}
|
||||
|
||||
void test_streamInvalid() {
|
||||
QuickTimeTestParser parser;
|
||||
const byte data[] = "not a moov";
|
||||
Common::MemoryReadStream stream(data, sizeof(data));
|
||||
bool result = parser.parseStream(&stream, DisposeAfterUse::NO);
|
||||
TS_ASSERT(!result);
|
||||
}
|
||||
|
||||
void test_moov() {
|
||||
QuickTimeTestParser parser;
|
||||
Common::MemoryReadStream stream(VALID_MOOV_DATA, sizeof(VALID_MOOV_DATA));
|
||||
bool result = parser.parseStream(&stream, DisposeAfterUse::NO);
|
||||
TS_ASSERT(result);
|
||||
}
|
||||
|
||||
void test_mhdr() {
|
||||
QuickTimeTestParser parser;
|
||||
Common::MemoryReadStream stream(VALID_MHDR_DATA, sizeof(VALID_MHDR_DATA));
|
||||
bool result = parser.parseStream(&stream, DisposeAfterUse::NO);
|
||||
TS_ASSERT(result);
|
||||
TS_ASSERT_EQUALS(parser.getDuration(), 999*60 + 1);
|
||||
TS_ASSERT_EQUALS(parser.getScaleFactorX(), Common::Rational(0x10000, 0x8000));
|
||||
TS_ASSERT_EQUALS(parser.getScaleFactorY(), Common::Rational(0x10000, 0xa000));
|
||||
}
|
||||
|
||||
void test_mhdrEarlyEOF() {
|
||||
QuickTimeTestParser parser;
|
||||
Common::MemoryReadStream stream(VALID_MHDR_DATA, sizeof(VALID_MHDR_DATA) - 10);
|
||||
bool result = parser.parseStream(&stream, DisposeAfterUse::NO);
|
||||
TS_ASSERT(!result);
|
||||
}
|
||||
|
||||
};
|
||||
60
test/common/func.h
Normal file
60
test/common/func.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/func.h"
|
||||
|
||||
void myFunction1(int &dst, const int src) { dst = src; }
|
||||
void myFunction2(const int src, int &dst) { dst = src; }
|
||||
|
||||
class FuncTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_bind1st() {
|
||||
int dst = 0;
|
||||
Common::bind1st(Common::ptr_fun(myFunction1), dst)(1);
|
||||
TS_ASSERT_EQUALS(dst, 1);
|
||||
}
|
||||
|
||||
void test_bind2nd() {
|
||||
int dst = 0;
|
||||
Common::bind2nd(Common::ptr_fun(myFunction2), dst)(1);
|
||||
TS_ASSERT_EQUALS(dst, 1);
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
void fooAdd(int &foo) {
|
||||
++foo;
|
||||
}
|
||||
|
||||
void fooSub(int &foo) const {
|
||||
--foo;
|
||||
}
|
||||
};
|
||||
|
||||
void test_mem_fun_ref() {
|
||||
Foo myFoos[4];
|
||||
int counter = 0;
|
||||
|
||||
Common::for_each(myFoos, myFoos+4, Common::bind2nd(Common::mem_fun_ref(&Foo::fooAdd), counter));
|
||||
TS_ASSERT_EQUALS(counter, 4);
|
||||
|
||||
Common::for_each(myFoos, myFoos+4, Common::bind2nd(Common::mem_fun_ref(&Foo::fooSub), counter));
|
||||
TS_ASSERT_EQUALS(counter, 0);
|
||||
}
|
||||
|
||||
void test_mem_fun() {
|
||||
Foo *myFoos[4];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
myFoos[i] = new Foo;
|
||||
|
||||
int counter = 0;
|
||||
|
||||
Common::for_each(myFoos, myFoos+4, Common::bind2nd(Common::mem_fun(&Foo::fooAdd), counter));
|
||||
TS_ASSERT_EQUALS(counter, 4);
|
||||
|
||||
Common::for_each(myFoos, myFoos+4, Common::bind2nd(Common::mem_fun(&Foo::fooSub), counter));
|
||||
TS_ASSERT_EQUALS(counter, 0);
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
delete myFoos[i];
|
||||
}
|
||||
};
|
||||
164
test/common/hash-str.h
Normal file
164
test/common/hash-str.h
Normal file
@@ -0,0 +1,164 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/hash-str.h"
|
||||
|
||||
/**
|
||||
* Test suite for common/hash-str.h
|
||||
* We test a number of case sensitive/insensitive hash and compare functions
|
||||
* using example strings and known hashes, trying to tackle
|
||||
* as much edge cases as possible.
|
||||
*/
|
||||
class HashStrTestSuite : public CxxTest::TestSuite {
|
||||
|
||||
public:
|
||||
void test_case_sensitive_string_equal_to() {
|
||||
|
||||
// Name says it all.
|
||||
// This verifies that the function returns true
|
||||
// for exactly the same string, false for the same
|
||||
// string in mixed case and false for some edge cases
|
||||
// with various spacings plus one character replaced
|
||||
// by itself+128 (if there's some processing done after
|
||||
// conversion to 7-bit ASCII this might yield funny results).
|
||||
|
||||
const Common::String lower("test");
|
||||
const Common::String lower1("test");
|
||||
const Common::String mixed("tESt");
|
||||
const Common::String spaced("test ");
|
||||
const Common::String doublespaced("test ");
|
||||
const Common::String tabbed("test\t");
|
||||
const Common::String plus128("t\345est");
|
||||
// 'e'+128 = 0xE5 = 0o345
|
||||
|
||||
Common::CaseSensitiveString_EqualTo css_et;
|
||||
TS_ASSERT_EQUALS(css_et(lower, mixed), false);
|
||||
TS_ASSERT_EQUALS(css_et(lower, lower1), true);
|
||||
TS_ASSERT_EQUALS(css_et(lower, lower), true);
|
||||
|
||||
// Different sorts of whitespace are to be treated differently.
|
||||
TS_ASSERT_EQUALS(css_et(lower, spaced), false);
|
||||
TS_ASSERT_EQUALS(css_et(lower, tabbed), false);
|
||||
TS_ASSERT_EQUALS(css_et(spaced, tabbed), false);
|
||||
TS_ASSERT_EQUALS(css_et(spaced, doublespaced), false);
|
||||
TS_ASSERT_EQUALS(css_et(lower, plus128), false);
|
||||
}
|
||||
|
||||
void test_ignore_case_equal_to() {
|
||||
|
||||
// This should be probably called case_insensitive_string_equal_to
|
||||
// or something,but it's basically the same thing as
|
||||
// test_case_sensitive_string_equal_to, only it's case
|
||||
// insensitive.
|
||||
|
||||
const Common::String lower("test");
|
||||
const Common::String lower1("test");
|
||||
const Common::String mixed("tESt");
|
||||
const Common::String spaced("test ");
|
||||
const Common::String mixedspaced("tESt ");
|
||||
const Common::String doublespaced("test ");
|
||||
const Common::String tabbed("test\t");
|
||||
const Common::String plus128("t\345est");
|
||||
|
||||
Common::IgnoreCase_EqualTo ic_et;
|
||||
TS_ASSERT_EQUALS(ic_et(lower, mixed), true);
|
||||
TS_ASSERT_EQUALS(ic_et(lower, lower1), true);
|
||||
TS_ASSERT_EQUALS(ic_et(lower, lower), true);
|
||||
// Edge case:
|
||||
TS_ASSERT_EQUALS(ic_et(spaced, mixedspaced), true);
|
||||
|
||||
// Different sorts of whitespace are to be treated differently.
|
||||
TS_ASSERT_EQUALS(ic_et(lower, spaced), false);
|
||||
TS_ASSERT_EQUALS(ic_et(lower, tabbed), false);
|
||||
TS_ASSERT_EQUALS(ic_et(spaced, tabbed), false);
|
||||
TS_ASSERT_EQUALS(ic_et(spaced, doublespaced), false);
|
||||
TS_ASSERT_EQUALS(ic_et(lower, plus128), false);
|
||||
}
|
||||
|
||||
void test_case_sensitive_string_hash() {
|
||||
|
||||
// Here we compute string hashes for different
|
||||
// strings and see that the functor is case sensitive
|
||||
// and does not ignore spaces.
|
||||
|
||||
const Common::String lower("test");
|
||||
const Common::String lower1("test");
|
||||
const Common::String mixed("tESt");
|
||||
const Common::String spaced("test ");
|
||||
const Common::String mixedspaced("tESt ");
|
||||
const Common::String doublespaced("test ");
|
||||
const Common::String tabbed("test\t");
|
||||
|
||||
Common::CaseSensitiveString_Hash css_h;
|
||||
TS_ASSERT_EQUALS(css_h(lower), css_h(lower1));
|
||||
TS_ASSERT_DIFFERS(css_h(mixed), css_h(lower));
|
||||
TS_ASSERT_DIFFERS(css_h(spaced), css_h(lower));
|
||||
TS_ASSERT_DIFFERS(css_h(tabbed), css_h(spaced));
|
||||
TS_ASSERT_DIFFERS(css_h(spaced), css_h(doublespaced));
|
||||
}
|
||||
|
||||
void test_ignore_case_hash() {
|
||||
// Same as test_case_sensitive_string_hash, but case insensitive.
|
||||
const Common::String lower("test");
|
||||
const Common::String lower1("test");
|
||||
const Common::String mixed("tESt");
|
||||
const Common::String spaced("test ");
|
||||
const Common::String mixedspaced("tESt ");
|
||||
const Common::String doublespaced("test ");
|
||||
const Common::String tabbed("test\t");
|
||||
|
||||
Common::IgnoreCase_Hash ic_h;
|
||||
TS_ASSERT_EQUALS(ic_h(lower), ic_h(lower1));
|
||||
TS_ASSERT_EQUALS(ic_h(mixed), ic_h(lower));
|
||||
TS_ASSERT_EQUALS(ic_h(spaced), ic_h(mixedspaced));
|
||||
TS_ASSERT_DIFFERS(ic_h(tabbed), ic_h(lower));
|
||||
TS_ASSERT_DIFFERS(ic_h(spaced), ic_h(doublespaced));
|
||||
}
|
||||
|
||||
void test_cpp_string_hash()
|
||||
{
|
||||
// We run the same tests with Hash<String>,
|
||||
// a template specialization of Hash, also a functor.
|
||||
// It is supposed to be case sensitive.
|
||||
|
||||
const Common::String lower("test");
|
||||
const Common::String lower1("test");
|
||||
const Common::String mixed("tESt");
|
||||
const Common::String spaced("test ");
|
||||
const Common::String mixedspaced("tESt ");
|
||||
const Common::String doublespaced("test ");
|
||||
const Common::String tabbed("test\t");
|
||||
|
||||
Common::Hash<Common::String> h;
|
||||
TS_ASSERT_EQUALS(h(lower), h(lower1));
|
||||
TS_ASSERT_DIFFERS(h(mixed), h(lower));
|
||||
TS_ASSERT_DIFFERS(h(spaced), h(lower));
|
||||
TS_ASSERT_DIFFERS(h(tabbed), h(spaced));
|
||||
TS_ASSERT_DIFFERS(h(spaced), h(doublespaced));
|
||||
}
|
||||
|
||||
void test_c_style_string_hash()
|
||||
{
|
||||
// Same as test_cpp_string_hash but with Hash<const char*>,
|
||||
// a template specialization of Hash, also a functor,
|
||||
// that works with C-Style strings.
|
||||
// It is supposed to be case sensitive.
|
||||
|
||||
char lower[] = "test";
|
||||
char lower1[] = "test";
|
||||
char mixed[] = "tESt";
|
||||
char spaced[] = "test ";
|
||||
char mixedspaced[] = "tESt ";
|
||||
char doublespaced[] = "test ";
|
||||
char tabbed[] = "test\t";
|
||||
|
||||
Common::Hash<const char *> h;
|
||||
TS_ASSERT_EQUALS(h(lower), h(lower1));
|
||||
TS_ASSERT_DIFFERS(h(mixed), h(lower));
|
||||
TS_ASSERT_DIFFERS(h(spaced), h(lower));
|
||||
TS_ASSERT_DIFFERS(h(spaced), h(mixedspaced));
|
||||
TS_ASSERT_DIFFERS(h(tabbed), h(spaced));
|
||||
TS_ASSERT_DIFFERS(h(spaced), h(doublespaced));
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
234
test/common/hashmap.h
Normal file
234
test/common/hashmap.h
Normal file
@@ -0,0 +1,234 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/hashmap.h"
|
||||
#include "common/hash-str.h"
|
||||
|
||||
class HashMapTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_empty_clear() {
|
||||
Common::HashMap<int, int> container;
|
||||
TS_ASSERT(container.empty());
|
||||
container[0] = 17;
|
||||
container[1] = 33;
|
||||
TS_ASSERT(!container.empty());
|
||||
container.clear();
|
||||
TS_ASSERT(container.empty());
|
||||
|
||||
Common::StringMap container2;
|
||||
TS_ASSERT(container2.empty());
|
||||
container2["foo"] = "bar";
|
||||
container2["quux"] = "blub";
|
||||
TS_ASSERT(!container2.empty());
|
||||
container2.clear();
|
||||
TS_ASSERT(container2.empty());
|
||||
}
|
||||
|
||||
void test_contains() {
|
||||
Common::HashMap<int, int> container;
|
||||
container[0] = 17;
|
||||
container[1] = 33;
|
||||
TS_ASSERT(container.contains(0));
|
||||
TS_ASSERT(container.contains(1));
|
||||
TS_ASSERT(!container.contains(17));
|
||||
TS_ASSERT(!container.contains(-1));
|
||||
|
||||
Common::StringMap container2;
|
||||
container2["foo"] = "bar";
|
||||
container2["quux"] = "blub";
|
||||
TS_ASSERT(container2.contains("foo"));
|
||||
TS_ASSERT(container2.contains("quux"));
|
||||
TS_ASSERT(!container2.contains("bar"));
|
||||
TS_ASSERT(!container2.contains("asdf"));
|
||||
}
|
||||
|
||||
void test_add_remove() {
|
||||
Common::HashMap<int, int> container;
|
||||
container[0] = 17;
|
||||
container[1] = 33;
|
||||
container[2] = 45;
|
||||
container[3] = 12;
|
||||
container[4] = 96;
|
||||
TS_ASSERT(container.contains(1));
|
||||
container.erase(1);
|
||||
TS_ASSERT(!container.contains(1));
|
||||
container[1] = 42;
|
||||
TS_ASSERT(container.contains(1));
|
||||
container.erase(0);
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(1);
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(2);
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(3);
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(4);
|
||||
TS_ASSERT(container.empty());
|
||||
container[1] = 33;
|
||||
TS_ASSERT(container.contains(1));
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(1);
|
||||
TS_ASSERT(container.empty());
|
||||
}
|
||||
|
||||
void test_add_remove_iterator() {
|
||||
Common::HashMap<int, int> container;
|
||||
container[0] = 17;
|
||||
container[1] = 33;
|
||||
container[2] = 45;
|
||||
container[3] = 12;
|
||||
container[4] = 96;
|
||||
TS_ASSERT(container.contains(1));
|
||||
container.erase(container.find(1));
|
||||
TS_ASSERT(!container.contains(1));
|
||||
container[1] = 42;
|
||||
TS_ASSERT(container.contains(1));
|
||||
container.erase(container.find(0));
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(container.find(1));
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(container.find(2));
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(container.find(3));
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(container.find(4));
|
||||
TS_ASSERT(container.empty());
|
||||
container[1] = 33;
|
||||
TS_ASSERT(container.contains(1));
|
||||
TS_ASSERT(!container.empty());
|
||||
container.erase(container.find(1));
|
||||
TS_ASSERT(container.empty());
|
||||
}
|
||||
|
||||
void test_lookup() {
|
||||
Common::HashMap<int, int> container;
|
||||
container[0] = 17;
|
||||
container[1] = -1;
|
||||
container[2] = 45;
|
||||
container[3] = 12;
|
||||
container[4] = 96;
|
||||
|
||||
TS_ASSERT_EQUALS(container[0], 17);
|
||||
TS_ASSERT_EQUALS(container[1], -1);
|
||||
TS_ASSERT_EQUALS(container[2], 45);
|
||||
TS_ASSERT_EQUALS(container[3], 12);
|
||||
TS_ASSERT_EQUALS(container[4], 96);
|
||||
}
|
||||
|
||||
void test_lookup_with_default() {
|
||||
Common::HashMap<int, int> container;
|
||||
container[0] = 17;
|
||||
container[1] = -1;
|
||||
container[2] = 45;
|
||||
container[3] = 12;
|
||||
container[4] = 96;
|
||||
|
||||
// We take a const ref now to ensure that the map
|
||||
// is not modified by getValOrDefault.
|
||||
const Common::HashMap<int, int> &containerRef = container;
|
||||
|
||||
TS_ASSERT_EQUALS(containerRef.getValOrDefault(0), 17);
|
||||
TS_ASSERT_EQUALS(containerRef.getValOrDefault(17), 0);
|
||||
TS_ASSERT_EQUALS(containerRef.getValOrDefault(0, -10), 17);
|
||||
TS_ASSERT_EQUALS(containerRef.getValOrDefault(17, -10), -10);
|
||||
}
|
||||
|
||||
void test_iterator_begin_end() {
|
||||
Common::HashMap<int, int> container;
|
||||
|
||||
// The container is initially empty ...
|
||||
TS_ASSERT_EQUALS(container.begin(), container.end());
|
||||
|
||||
// ... then non-empty ...
|
||||
container[324] = 33;
|
||||
TS_ASSERT_DIFFERS(container.begin(), container.end());
|
||||
|
||||
// ... and again empty.
|
||||
container.clear();
|
||||
TS_ASSERT_EQUALS(container.begin(), container.end());
|
||||
}
|
||||
|
||||
void test_hash_map_copy() {
|
||||
Common::HashMap<int, int> map1, container2;
|
||||
map1[323] = 32;
|
||||
container2 = map1;
|
||||
TS_ASSERT_EQUALS(container2[323], 32);
|
||||
}
|
||||
|
||||
void test_collision() {
|
||||
// NB: The usefulness of this example depends strongly on the
|
||||
// specific hashmap implementation.
|
||||
// It is constructed to insert multiple colliding elements.
|
||||
Common::HashMap<int, int> h;
|
||||
h[5] = 1;
|
||||
h[32+5] = 1;
|
||||
h[64+5] = 1;
|
||||
h[128+5] = 1;
|
||||
TS_ASSERT(h.contains(5));
|
||||
TS_ASSERT(h.contains(32+5));
|
||||
TS_ASSERT(h.contains(64+5));
|
||||
TS_ASSERT(h.contains(128+5));
|
||||
h.erase(32+5);
|
||||
TS_ASSERT(h.contains(5));
|
||||
TS_ASSERT(h.contains(64+5));
|
||||
TS_ASSERT(h.contains(128+5));
|
||||
h.erase(5);
|
||||
TS_ASSERT(h.contains(64+5));
|
||||
TS_ASSERT(h.contains(128+5));
|
||||
h[32+5] = 1;
|
||||
TS_ASSERT(h.contains(32+5));
|
||||
TS_ASSERT(h.contains(64+5));
|
||||
TS_ASSERT(h.contains(128+5));
|
||||
h[5] = 1;
|
||||
TS_ASSERT(h.contains(5));
|
||||
TS_ASSERT(h.contains(32+5));
|
||||
TS_ASSERT(h.contains(64+5));
|
||||
TS_ASSERT(h.contains(128+5));
|
||||
h.erase(5);
|
||||
TS_ASSERT(h.contains(32+5));
|
||||
TS_ASSERT(h.contains(64+5));
|
||||
TS_ASSERT(h.contains(128+5));
|
||||
h.erase(64+5);
|
||||
TS_ASSERT(h.contains(32+5));
|
||||
TS_ASSERT(h.contains(128+5));
|
||||
h.erase(128+5);
|
||||
TS_ASSERT(h.contains(32+5));
|
||||
h.erase(32+5);
|
||||
TS_ASSERT(h.empty());
|
||||
}
|
||||
|
||||
void test_iterator() {
|
||||
Common::HashMap<int, int> container;
|
||||
container[0] = 17;
|
||||
container[1] = 33;
|
||||
container[2] = 45;
|
||||
container[3] = 12;
|
||||
container[4] = 96;
|
||||
container.erase(1);
|
||||
container[1] = 42;
|
||||
container.erase(0);
|
||||
container.erase(1);
|
||||
|
||||
int found = 0;
|
||||
Common::HashMap<int, int>::iterator i;
|
||||
for (i = container.begin(); i != container.end(); ++i) {
|
||||
int key = i->_key;
|
||||
TS_ASSERT(key >= 0 && key <= 4);
|
||||
TS_ASSERT(!(found & (1 << key)));
|
||||
found |= 1 << key;
|
||||
}
|
||||
TS_ASSERT(found == 16+8+4);
|
||||
|
||||
found = 0;
|
||||
Common::HashMap<int, int>::const_iterator j;
|
||||
for (j = container.begin(); j != container.end(); ++j) {
|
||||
int key = j->_key;
|
||||
TS_ASSERT(key >= 0 && key <= 4);
|
||||
TS_ASSERT(!(found & (1 << key)));
|
||||
found |= 1 << key;
|
||||
}
|
||||
TS_ASSERT(found == 16+8+4);
|
||||
}
|
||||
|
||||
// TODO: Add test cases for iterators, find, ...
|
||||
};
|
||||
172
test/common/ini-file.h
Normal file
172
test/common/ini-file.h
Normal file
@@ -0,0 +1,172 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/formats/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(), 0U);
|
||||
}
|
||||
|
||||
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(), 1U);
|
||||
|
||||
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 \n ; comment=no";
|
||||
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(), 3U);
|
||||
|
||||
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(), 0U);
|
||||
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 (uint 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 (uint 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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
18
test/common/intrinsics.h
Normal file
18
test/common/intrinsics.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/intrinsics.h"
|
||||
|
||||
class IntrinsicsTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_intLog2() {
|
||||
// Test special case for 0
|
||||
TS_ASSERT_EQUALS(Common::intLog2(0), -1);
|
||||
|
||||
// intLog2 should round the result towards 0
|
||||
TS_ASSERT_EQUALS(Common::intLog2(7), 2);
|
||||
|
||||
// Some simple test for 2^10
|
||||
TS_ASSERT_EQUALS(Common::intLog2(1024), 10);
|
||||
}
|
||||
};
|
||||
285
test/common/list.h
Normal file
285
test/common/list.h
Normal file
@@ -0,0 +1,285 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/list.h"
|
||||
|
||||
class ListTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_empty_clear() {
|
||||
Common::List<int> container;
|
||||
TS_ASSERT(container.empty());
|
||||
container.push_back(17);
|
||||
container.push_back(33);
|
||||
TS_ASSERT(!container.empty());
|
||||
container.clear();
|
||||
TS_ASSERT(container.empty());
|
||||
}
|
||||
|
||||
public:
|
||||
void test_size() {
|
||||
Common::List<int> container;
|
||||
TS_ASSERT_EQUALS(container.size(), (unsigned int)0);
|
||||
container.push_back(17);
|
||||
TS_ASSERT_EQUALS(container.size(), (unsigned int)1);
|
||||
container.push_back(33);
|
||||
TS_ASSERT_EQUALS(container.size(), (unsigned int)2);
|
||||
container.clear();
|
||||
TS_ASSERT_EQUALS(container.size(), (unsigned int)0);
|
||||
}
|
||||
|
||||
void test_iterator_begin_end() {
|
||||
Common::List<int> container;
|
||||
|
||||
// The container is initially empty ...
|
||||
TS_ASSERT_EQUALS(container.begin(), container.end());
|
||||
|
||||
// ... then non-empty ...
|
||||
container.push_back(33);
|
||||
TS_ASSERT_DIFFERS(container.begin(), container.end());
|
||||
|
||||
// ... and again empty.
|
||||
container.clear();
|
||||
TS_ASSERT_EQUALS(container.begin(), container.end());
|
||||
}
|
||||
|
||||
void test_iterator() {
|
||||
Common::List<int> container;
|
||||
Common::List<int>::iterator iter;
|
||||
Common::List<int>::const_iterator cIter;
|
||||
|
||||
// Fill the container with some random data
|
||||
container.push_back(17);
|
||||
container.push_back(33);
|
||||
container.push_back(-11);
|
||||
|
||||
// Iterate over the container and verify that we encounter the elements in
|
||||
// the order we expect them to be.
|
||||
|
||||
iter = container.begin();
|
||||
cIter = container.begin();
|
||||
|
||||
TS_ASSERT_EQUALS(iter, cIter);
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 17);
|
||||
++iter;
|
||||
++cIter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
TS_ASSERT_DIFFERS(cIter, container.end());
|
||||
TS_ASSERT_EQUALS(iter, cIter);
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 33);
|
||||
++iter;
|
||||
++cIter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
TS_ASSERT_DIFFERS(cIter, container.end());
|
||||
TS_ASSERT_EQUALS(iter, cIter);
|
||||
|
||||
// Also test the postinc
|
||||
TS_ASSERT_EQUALS(*iter, -11);
|
||||
iter++;
|
||||
cIter++;
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
TS_ASSERT_EQUALS(cIter, container.end());
|
||||
TS_ASSERT_EQUALS(iter, cIter);
|
||||
|
||||
cIter = iter;
|
||||
TS_ASSERT_EQUALS(iter, cIter);
|
||||
}
|
||||
|
||||
void test_insert() {
|
||||
Common::List<int> container;
|
||||
Common::List<int>::iterator iter;
|
||||
|
||||
// Fill the container with some random data
|
||||
container.push_back(17);
|
||||
container.push_back(33);
|
||||
container.push_back(-11);
|
||||
|
||||
// Iterate to after the second element
|
||||
iter = container.begin();
|
||||
++iter;
|
||||
++iter;
|
||||
|
||||
// Insert a value before the final one
|
||||
container.insert(iter, 42);
|
||||
|
||||
// Insert another value before the final one and check the return value
|
||||
iter = container.insert(iter, 43);
|
||||
TS_ASSERT_EQUALS(*iter, 43);
|
||||
|
||||
// Insert a value before the previously inserted one
|
||||
container.insert(iter, 44);
|
||||
|
||||
// Verify contents are correct
|
||||
iter = container.begin();
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 17);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 33);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 42);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 44);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 43);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, -11);
|
||||
++iter;
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
}
|
||||
|
||||
void test_erase() {
|
||||
Common::List<int> container;
|
||||
Common::List<int>::iterator first, last;
|
||||
|
||||
// Fill the container with some random data
|
||||
container.push_back(17);
|
||||
container.push_back(33);
|
||||
container.push_back(-11);
|
||||
container.push_back(42);
|
||||
container.push_back(43);
|
||||
|
||||
// Iterate to after the second element
|
||||
first = container.begin();
|
||||
++first;
|
||||
++first;
|
||||
|
||||
// Iterate to after the fourth element
|
||||
last = first;
|
||||
++last;
|
||||
++last;
|
||||
|
||||
// Now erase that range
|
||||
container.erase(first, last);
|
||||
|
||||
// Verify contents are correct
|
||||
Common::List<int>::iterator iter = container.begin();
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 17);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 33);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 43);
|
||||
++iter;
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
}
|
||||
|
||||
void test_remove() {
|
||||
Common::List<int> container;
|
||||
Common::List<int>::iterator first, last;
|
||||
|
||||
// Fill the container with some random data
|
||||
container.push_back(-11);
|
||||
container.push_back(17);
|
||||
container.push_back(33);
|
||||
container.push_back(42);
|
||||
container.push_back(-11);
|
||||
container.push_back(42);
|
||||
container.push_back(43);
|
||||
|
||||
// Remove some stuff
|
||||
container.remove(42);
|
||||
container.remove(-11);
|
||||
|
||||
// Now erase that range
|
||||
container.erase(first, last);
|
||||
|
||||
// Verify contents are correct
|
||||
Common::List<int>::iterator iter = container.begin();
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 17);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 33);
|
||||
++iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 43);
|
||||
++iter;
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
}
|
||||
|
||||
void test_reverse() {
|
||||
Common::List<int> container;
|
||||
Common::List<int>::iterator iter;
|
||||
|
||||
// Fill the container with some random data
|
||||
container.push_back(17);
|
||||
container.push_back(33);
|
||||
container.push_back(-11);
|
||||
|
||||
iter = container.reverse_begin();
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, -11);
|
||||
--iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 33);
|
||||
--iter;
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, 17);
|
||||
--iter;
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
|
||||
iter = container.reverse_begin();
|
||||
|
||||
iter = container.reverse_erase(iter);
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
TS_ASSERT_EQUALS(*iter, 33);
|
||||
|
||||
iter = container.reverse_erase(iter);
|
||||
TS_ASSERT_DIFFERS(iter, container.end());
|
||||
TS_ASSERT_EQUALS(*iter, 17);
|
||||
|
||||
iter = container.reverse_erase(iter);
|
||||
TS_ASSERT_EQUALS(iter, container.end());
|
||||
|
||||
TS_ASSERT_EQUALS(container.begin(), container.end());
|
||||
TS_ASSERT_EQUALS(container.reverse_begin(), container.end());
|
||||
}
|
||||
|
||||
void test_front_back_push_pop() {
|
||||
Common::List<int> container;
|
||||
|
||||
container.push_back( 42);
|
||||
container.push_back(-23);
|
||||
|
||||
TS_ASSERT_EQUALS(container.front(), 42);
|
||||
TS_ASSERT_EQUALS(container.back(), -23);
|
||||
|
||||
container.front() = -17;
|
||||
container.back() = 163;
|
||||
TS_ASSERT_EQUALS(container.front(), -17);
|
||||
TS_ASSERT_EQUALS(container.back(), 163);
|
||||
|
||||
container.pop_front();
|
||||
TS_ASSERT_EQUALS(container.front(), 163);
|
||||
TS_ASSERT_EQUALS(container.back(), 163);
|
||||
|
||||
container.push_front(99);
|
||||
TS_ASSERT_EQUALS(container.front(), 99);
|
||||
TS_ASSERT_EQUALS(container.back(), 163);
|
||||
|
||||
container.pop_back();
|
||||
TS_ASSERT_EQUALS(container.front(), 99);
|
||||
TS_ASSERT_EQUALS(container.back(), 99);
|
||||
}
|
||||
};
|
||||
50
test/common/md5.h
Normal file
50
test/common/md5.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/md5.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
/*
|
||||
* those are the standard RFC 1321 test vectors
|
||||
*/
|
||||
static const char *md5_test_string[] = {
|
||||
"",
|
||||
"a",
|
||||
"abc",
|
||||
"message digest",
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
("12345678901234567890123456789012345678901234567890123456789012"
|
||||
"345678901234567890")
|
||||
};
|
||||
|
||||
static const char *md5_test_digest[] = {
|
||||
"d41d8cd98f00b204e9800998ecf8427e",
|
||||
"0cc175b9c0f1b6a831c399e269772661",
|
||||
"900150983cd24fb0d6963f7d28e17f72",
|
||||
"f96b697d7cb7938d525a2f31aaf161d0",
|
||||
"c3fcd3d76192e4007dfb496cca67e13b",
|
||||
"d174ab98d277d9f5a5611c2c9f419d9f",
|
||||
"57edf4a22be3c955ac49da2e2107b67a"
|
||||
};
|
||||
|
||||
class MD5TestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_computeStreamMD5() {
|
||||
int i, j;
|
||||
char output[33];
|
||||
unsigned char md5sum[16];
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
Common::MemoryReadStream stream((const byte *)md5_test_string[i], strlen(md5_test_string[i]));
|
||||
Common::computeStreamMD5(stream, md5sum);
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
snprintf(output + j * 2, 3, "%02x", md5sum[j]);
|
||||
}
|
||||
|
||||
Common::String tmp(output);
|
||||
TS_ASSERT_EQUALS(tmp, md5_test_digest[i]);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
63
test/common/memory.h
Normal file
63
test/common/memory.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memory.h"
|
||||
|
||||
class MemoryTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_memset16() {
|
||||
uint16 expected[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
const uint16 step1[8] = { 0, 1, 1, 1, 1, 1, 1, 0 };
|
||||
const uint16 step2[8] = { 0, 1, 2, 2, 2, 2, 1, 0 };
|
||||
const uint16 step3[8] = { 0, 1, 2, 3, 3, 2, 1, 0 };
|
||||
|
||||
Common::memset16(expected + 1, 1, 6);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step1, sizeof(expected)), 0);
|
||||
|
||||
Common::memset16(expected + 2, 2, 4);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step2, sizeof(expected)), 0);
|
||||
|
||||
Common::memset16(expected + 3, 3, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step3, sizeof(expected)), 0);
|
||||
}
|
||||
|
||||
void test_memset32() {
|
||||
uint32 expected[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
const uint32 step1[8] = { 0, 1, 1, 1, 1, 1, 1, 0 };
|
||||
const uint32 step2[8] = { 0, 1, 2, 2, 2, 2, 1, 0 };
|
||||
const uint32 step3[8] = { 0, 1, 2, 3, 3, 2, 1, 0 };
|
||||
|
||||
Common::memset32(expected + 1, 1, 6);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step1, sizeof(expected)), 0);
|
||||
|
||||
Common::memset32(expected + 2, 2, 4);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step2, sizeof(expected)), 0);
|
||||
|
||||
Common::memset32(expected + 3, 3, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step3, sizeof(expected)), 0);
|
||||
}
|
||||
|
||||
void test_memset64() {
|
||||
uint64 expected[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
const uint64 step1[8] = { 0, 1, 1, 1, 1, 1, 1, 0 };
|
||||
const uint64 step2[8] = { 0, 1, 2, 2, 2, 2, 1, 0 };
|
||||
const uint64 step3[8] = { 0, 1, 2, 3, 3, 2, 1, 0 };
|
||||
|
||||
Common::memset64(expected + 1, 1, 6);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step1, sizeof(expected)), 0);
|
||||
|
||||
Common::memset64(expected + 2, 2, 4);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step2, sizeof(expected)), 0);
|
||||
|
||||
Common::memset64(expected + 3, 3, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(memcmp(expected, step3, sizeof(expected)), 0);
|
||||
}
|
||||
};
|
||||
107
test/common/memoryreadstream.h
Normal file
107
test/common/memoryreadstream.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
|
||||
class MemoryReadStreamTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_seek_set() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c', '\n' };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
ms.seek(0, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 0);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(1, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 1);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(5, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 5);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_cur() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c' };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
ms.seek(3, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 3);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-1, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(3, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 5);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-1, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 4);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_end() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c' };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
ms.seek(0, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 5);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-1, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 4);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-5, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 0);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_read_le() {
|
||||
byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
TS_ASSERT_EQUALS(ms.readUint16LE(), 0x0201UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT_EQUALS(ms.readUint32LE(), 0x06050403UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 6);
|
||||
TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 14);
|
||||
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 15);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_read_be() {
|
||||
byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
TS_ASSERT_EQUALS(ms.readUint16BE(), 0x0102UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 6);
|
||||
TS_ASSERT_EQUALS(ms.readUint64BE(), 0x0708090A0B0C0D0EULL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 14);
|
||||
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 15);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_eos() {
|
||||
byte contents[] = { 1, 2, 3, 4, 5, 6, 7 };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
// Read after the end of the stream
|
||||
for (int32 i = 0; i <= ms.size(); ++i)
|
||||
ms.readByte();
|
||||
|
||||
// The eos flag should be set here
|
||||
TS_ASSERT(ms.eos());
|
||||
|
||||
// Seeking should reset the eos flag
|
||||
ms.seek(0, SEEK_SET);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
};
|
||||
121
test/common/memoryreadstreamendian.h
Normal file
121
test/common/memoryreadstreamendian.h
Normal file
@@ -0,0 +1,121 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
|
||||
class MemoryReadStreamEndianTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_seek_set() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c', '\n' };
|
||||
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
|
||||
|
||||
ms.seek(0, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 0);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(1, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 1);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(5, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 5);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_cur() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c' };
|
||||
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
|
||||
|
||||
ms.seek(3, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 3);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-1, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(3, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 5);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-1, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 4);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_end() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c' };
|
||||
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
|
||||
|
||||
ms.seek(0, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 5);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-1, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 4);
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
ms.seek(-5, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 0);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_read_le() {
|
||||
byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
|
||||
|
||||
TS_ASSERT_EQUALS(ms.readUint16LE(), 0x0201UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT_EQUALS(ms.readUint32LE(), 0x06050403UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 6);
|
||||
TS_ASSERT_EQUALS(ms.readUint64LE(), 0x0E0D0C0B0A090807ULL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 14);
|
||||
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 15);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_read_be() {
|
||||
byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
|
||||
|
||||
TS_ASSERT_EQUALS(ms.readUint16BE(), 0x0102UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT_EQUALS(ms.readUint32BE(), 0x03040506UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 6);
|
||||
TS_ASSERT_EQUALS(ms.readUint64BE(), 0x0708090A0B0C0D0EULL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 14);
|
||||
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 15);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_read_le2() {
|
||||
byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), false);
|
||||
|
||||
TS_ASSERT_EQUALS(ms.readUint16(), 0x0201UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT_EQUALS(ms.readUint32(), 0x06050403UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 6);
|
||||
TS_ASSERT_EQUALS(ms.readUint64(), 0x0E0D0C0B0A090807ULL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 14);
|
||||
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 15);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
|
||||
void test_seek_read_be2() {
|
||||
byte contents[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
Common::MemoryReadStreamEndian ms(contents, sizeof(contents), true);
|
||||
|
||||
TS_ASSERT_EQUALS(ms.readUint16(), 0x0102UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 2);
|
||||
TS_ASSERT_EQUALS(ms.readUint32(), 0x03040506UL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 6);
|
||||
TS_ASSERT_EQUALS(ms.readUint64(), 0x0708090A0B0C0D0EULL);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 14);
|
||||
TS_ASSERT_EQUALS(ms.readByte(), 0x0F);
|
||||
TS_ASSERT_EQUALS(ms.pos(), 15);
|
||||
TS_ASSERT(!ms.eos());
|
||||
}
|
||||
};
|
||||
31
test/common/memorywritestream.h
Normal file
31
test/common/memorywritestream.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
|
||||
class MemoryWriteStreamTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_err() {
|
||||
byte temp = 0;
|
||||
|
||||
Common::MemoryWriteStream stream(&temp, 0);
|
||||
TS_ASSERT(!stream.err());
|
||||
|
||||
// Make sure the error indicator gets set
|
||||
stream.write(&temp, 1);
|
||||
TS_ASSERT(stream.err());
|
||||
|
||||
// Test whether the error indicator can be cleared
|
||||
stream.clearErr();
|
||||
TS_ASSERT(!stream.err());
|
||||
}
|
||||
|
||||
void test_write() {
|
||||
byte buffer[7] = {};
|
||||
Common::MemoryWriteStream stream(buffer, sizeof(buffer));
|
||||
|
||||
const byte data[7] = { 7, 4, 3, 0, 10, 12, 1 };
|
||||
stream.write(data, sizeof(data));
|
||||
TS_ASSERT(memcmp(buffer, data, sizeof(data)) == 0);
|
||||
TS_ASSERT(!stream.err());
|
||||
}
|
||||
};
|
||||
34
test/common/pack.h
Normal file
34
test/common/pack.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#include "common/pack-start.h" // START STRUCT PACKING
|
||||
|
||||
struct TestStruct {
|
||||
uint32 x;
|
||||
byte y;
|
||||
uint16 z;
|
||||
uint32 a;
|
||||
byte b;
|
||||
} PACKED_STRUCT;
|
||||
|
||||
#include "common/pack-end.h" // END STRUCT PACKING
|
||||
|
||||
#define OFFS(type,item) (((ptrdiff_t)(&((type *)42)->type::item))-42)
|
||||
|
||||
class PackTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_packing() {
|
||||
TS_ASSERT_EQUALS(sizeof(TestStruct), size_t(4+1+2+4+1));
|
||||
}
|
||||
|
||||
void test_offsets() {
|
||||
TS_ASSERT_EQUALS(OFFS(TestStruct, x), (ptrdiff_t)0);
|
||||
TS_ASSERT_EQUALS(OFFS(TestStruct, y), (ptrdiff_t)4);
|
||||
TS_ASSERT_EQUALS(OFFS(TestStruct, z), (ptrdiff_t)5);
|
||||
TS_ASSERT_EQUALS(OFFS(TestStruct, a), (ptrdiff_t)7);
|
||||
TS_ASSERT_EQUALS(OFFS(TestStruct, b), (ptrdiff_t)11);
|
||||
}
|
||||
};
|
||||
608
test/common/path.h
Normal file
608
test/common/path.h
Normal file
@@ -0,0 +1,608 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "test/common/str-helper.h"
|
||||
|
||||
#include "common/path.h"
|
||||
#include "common/hashmap.h"
|
||||
|
||||
static const char *TEST_PATH = "parent/dir/file.txt";
|
||||
static const char *TEST_ESCAPED1_PATH = "|parent/dir/file.txt";
|
||||
static const char *TEST_ESCAPED2_PATH = "par/ent\\dir\\file.txt";
|
||||
static const char *TEST_ESCAPED3_PATH = "parent\\dir\\fi|le.txt";
|
||||
static const char *TEST_BS_PATH = "parent\\dir\\file.txt";
|
||||
|
||||
class PathTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_Path() {
|
||||
Common::Path p;
|
||||
TS_ASSERT_EQUALS(p.toString(), "");
|
||||
TS_ASSERT_EQUALS(p.empty(), true);
|
||||
|
||||
Common::Path p2(TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p2.toString(), TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p2.toString('|'), "parent|dir|file.txt");
|
||||
TS_ASSERT_EQUALS(p2.toString('\\'), "parent\\dir\\file.txt");
|
||||
|
||||
Common::Path p3(TEST_ESCAPED1_PATH);
|
||||
TS_ASSERT_EQUALS(p3.toString(), TEST_ESCAPED1_PATH);
|
||||
TS_ASSERT_EQUALS(p3.toString('\\'), "|parent\\dir\\file.txt");
|
||||
|
||||
Common::Path p4(TEST_ESCAPED2_PATH, '\\');
|
||||
TS_ASSERT_EQUALS(p4.toString('\\'), TEST_ESCAPED2_PATH);
|
||||
|
||||
Common::Path p5(TEST_ESCAPED3_PATH, '\\');
|
||||
TS_ASSERT_EQUALS(p5.toString('\\'), TEST_ESCAPED3_PATH);
|
||||
TS_ASSERT_EQUALS(p5.baseName(), "fi|le.txt");
|
||||
|
||||
Common::Path p6(TEST_BS_PATH, '\\');
|
||||
TS_ASSERT_EQUALS(p6.toString('\\'), TEST_BS_PATH);
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
Common::Path::_shownSeparatorCollisionWarning = false;
|
||||
TS_ASSERT_EQUALS(p3.toString('|'), "|parent|dir|file.txt");
|
||||
TS_ASSERT_EQUALS(Common::Path::_shownSeparatorCollisionWarning, true);
|
||||
|
||||
Common::Path::_shownSeparatorCollisionWarning = false;
|
||||
TS_ASSERT_EQUALS(p3.toString('i'), "|parentidirifile.txt");
|
||||
TS_ASSERT_EQUALS(Common::Path::_shownSeparatorCollisionWarning, true);
|
||||
|
||||
Common::Path::_shownSeparatorCollisionWarning = false;
|
||||
TS_ASSERT_EQUALS(p4.toString('/'), "par/ent/dir/file.txt");
|
||||
TS_ASSERT_EQUALS(Common::Path::_shownSeparatorCollisionWarning, true);
|
||||
|
||||
Common::Path::_shownSeparatorCollisionWarning = false;
|
||||
TS_ASSERT_EQUALS(p6.toString('i'), "parentidirifile.txt");
|
||||
TS_ASSERT_EQUALS(Common::Path::_shownSeparatorCollisionWarning, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_clear() {
|
||||
Common::Path p(TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p.empty(), false);
|
||||
|
||||
p.clear();
|
||||
TS_ASSERT_EQUALS(p.empty(), true);
|
||||
|
||||
TS_ASSERT(p.equals(Common::Path()));
|
||||
TS_ASSERT(p != Common::Path(TEST_PATH));
|
||||
}
|
||||
|
||||
void test_getLastComponent() {
|
||||
Common::Path p;
|
||||
TS_ASSERT_EQUALS(p.getLastComponent().toString(), "");
|
||||
TS_ASSERT_EQUALS(p.getLastComponent(), Common::Path());
|
||||
|
||||
Common::Path p2(TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p2.getLastComponent().toString(), "file.txt");
|
||||
TS_ASSERT_EQUALS(p2.getLastComponent(), Common::Path("file.txt"));
|
||||
|
||||
Common::Path p3("parent/dir/|file.txt");
|
||||
TS_ASSERT_EQUALS(p3.getLastComponent().toString(), "|file.txt");
|
||||
TS_ASSERT_EQUALS(p3.getLastComponent(), Common::Path("|file.txt"));
|
||||
}
|
||||
|
||||
void test_baseName() {
|
||||
Common::Path p;
|
||||
TS_ASSERT_EQUALS(p.baseName(), "");
|
||||
|
||||
Common::Path p2(TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p2.baseName(), "file.txt");
|
||||
|
||||
Common::Path p3("parent\\dir\\fi/le.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p3.baseName(), "fi/le.txt");
|
||||
|
||||
Common::Path p4("parent/dir/file.txt/");
|
||||
TS_ASSERT_EQUALS(p4.baseName(), "file.txt");
|
||||
|
||||
Common::Path p5("File I/O", ':');
|
||||
TS_ASSERT_EQUALS(p5.baseName(), "File I/O");
|
||||
}
|
||||
|
||||
void test_getParent() {
|
||||
Common::Path p;
|
||||
TS_ASSERT_EQUALS(p.getParent().toString(), "");
|
||||
|
||||
Common::Path p2(TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p2.getParent().toString(), "parent/dir/");
|
||||
// TODO: should this work?
|
||||
TS_ASSERT_EQUALS(p2.getParent().getLastComponent().toString(), "dir/");
|
||||
|
||||
Common::Path p3(TEST_ESCAPED1_PATH);
|
||||
TS_ASSERT_EQUALS(p3.getParent().toString(), "|parent/dir/");
|
||||
// TODO: should this work?
|
||||
TS_ASSERT_EQUALS(p3.getParent().getLastComponent().toString(), "dir/");
|
||||
|
||||
Common::Path p4(TEST_ESCAPED2_PATH, '\\');
|
||||
TS_ASSERT_EQUALS(p4.getParent().toString('\\'), "par/ent\\dir\\");
|
||||
// TODO: should this work?
|
||||
TS_ASSERT_EQUALS(p4.getParent().getLastComponent().toString('\\'), "dir\\");
|
||||
}
|
||||
|
||||
void test_join() {
|
||||
Common::Path p("dir");
|
||||
Common::Path p2 = p.join("file.txt");
|
||||
TS_ASSERT_EQUALS(p2.toString(), "dir/file.txt");
|
||||
p2 = p.join("");
|
||||
TS_ASSERT_EQUALS(p2.toString(), "dir");
|
||||
p2 = p.join(Common::Path());
|
||||
TS_ASSERT_EQUALS(p2.toString(), "dir");
|
||||
|
||||
Common::Path p3;
|
||||
Common::Path p4 = p3.join("file.txt");
|
||||
TS_ASSERT_EQUALS(p4.toString(), "file.txt");
|
||||
p4 = p3.join(Common::String("file.txt"));
|
||||
TS_ASSERT_EQUALS(p4.toString(), "file.txt");
|
||||
p4 = p3.join(Common::Path("file.txt"));
|
||||
TS_ASSERT_EQUALS(p4.toString(), "file.txt");
|
||||
|
||||
Common::Path p5(TEST_PATH);
|
||||
Common::Path p6 = p5.getParent().join("other.txt");
|
||||
TS_ASSERT_EQUALS(p6.toString(), "parent/dir/other.txt");
|
||||
p6 = p5.getParent().join("|child\\other.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p6.toString(), "parent/dir/|child/other.txt");
|
||||
p6 = p5.getParent().join("/child\\other.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p6.toString('|'), "parent|dir|/child|other.txt");
|
||||
p6 = p5.getParent().join(Common::Path("|other.txt"));
|
||||
TS_ASSERT_EQUALS(p6.toString(), "parent/dir/|other.txt");
|
||||
p6 = p5.getParent().join(Common::Path("oth/er.txt", '\\'));
|
||||
TS_ASSERT_EQUALS(p6.toString('\\'), "parent\\dir\\oth/er.txt");
|
||||
|
||||
Common::Path p7(TEST_ESCAPED1_PATH);
|
||||
Common::Path p8 = p7.getParent().join("other.txt");
|
||||
TS_ASSERT_EQUALS(p8.toString(), "|parent/dir/other.txt");
|
||||
p8 = p7.getParent().join(Common::Path("other.txt"));
|
||||
TS_ASSERT_EQUALS(p8.toString(), "|parent/dir/other.txt");
|
||||
p8 = p7.getParent().join(Common::Path("|other.txt"));
|
||||
TS_ASSERT_EQUALS(p8.toString(), "|parent/dir/|other.txt");
|
||||
}
|
||||
|
||||
// Ensure we can joinInPlace correctly with leading or trailing separators
|
||||
void test_joinInPlace() {
|
||||
Common::Path p("abc/def");
|
||||
p.joinInPlace("file.txt");
|
||||
TS_ASSERT_EQUALS(p.toString(), "abc/def/file.txt");
|
||||
|
||||
Common::Path p2("xyz/def");
|
||||
p2.joinInPlace(Common::Path("file.txt"));
|
||||
TS_ASSERT_EQUALS(p2.toString(), "xyz/def/file.txt");
|
||||
|
||||
Common::Path p3("ghi/def/");
|
||||
p3.joinInPlace(Common::Path("file.txt"));
|
||||
TS_ASSERT_EQUALS(p3.toString(), "ghi/def/file.txt");
|
||||
|
||||
Common::Path p4("123/def");
|
||||
p4.joinInPlace(Common::Path("/file4.txt"));
|
||||
TS_ASSERT_EQUALS(p4.toString(), "123/def/file4.txt");
|
||||
|
||||
Common::Path p5("abc/def");
|
||||
p5.joinInPlace(Common::String("file.txt"));
|
||||
TS_ASSERT_EQUALS(p5.toString(), "abc/def/file.txt");
|
||||
}
|
||||
|
||||
void test_append() {
|
||||
Common::Path p("abc/def");
|
||||
p.appendInPlace("");
|
||||
TS_ASSERT_EQUALS(p.toString(), "abc/def");
|
||||
|
||||
Common::Path p2;
|
||||
p2.appendInPlace("file.txt");
|
||||
TS_ASSERT_EQUALS(p2.toString(), "file.txt");
|
||||
|
||||
Common::Path p3("abc/def");
|
||||
p3.appendInPlace(Common::Path());
|
||||
TS_ASSERT_EQUALS(p3.toString(), "abc/def");
|
||||
|
||||
Common::Path p4;
|
||||
p4.appendInPlace(Common::Path("file.txt"));
|
||||
TS_ASSERT_EQUALS(p4.toString(), "file.txt");
|
||||
|
||||
TS_ASSERT_EQUALS(p4.append("a|b", '|').toString(), "file.txta/b");
|
||||
TS_ASSERT_EQUALS(p4.append(Common::String("a|b"), '|').toString('/'), "file.txta/b");
|
||||
TS_ASSERT_EQUALS(p4.append(p3).toString(), "file.txtabc/def");
|
||||
}
|
||||
|
||||
void test_appendComponent() {
|
||||
Common::Path p("abc/def");
|
||||
Common::Path p2 = p.appendComponent("");
|
||||
TS_ASSERT_EQUALS(p2.toString(), "abc/def");
|
||||
|
||||
Common::Path p3;
|
||||
Common::Path p4 = p3.appendComponent("file.txt");
|
||||
TS_ASSERT_EQUALS(p4.toString(), "file.txt");
|
||||
|
||||
p2 = p.appendComponent("file.txt");
|
||||
TS_ASSERT_EQUALS(p2.toString(), "abc/def/file.txt");
|
||||
|
||||
p2 = p.appendComponent("fi/le.txt");
|
||||
TS_ASSERT_EQUALS(p2.toString('\\'), "abc\\def\\fi/le.txt");
|
||||
|
||||
Common::Path p5("abc\\de/f", '\\');
|
||||
Common::Path p6 = p5.appendComponent(Common::String("fi/le.txt"));
|
||||
TS_ASSERT_EQUALS(p6.toString('\\'), "abc\\de/f\\fi/le.txt");
|
||||
}
|
||||
|
||||
void test_separator() {
|
||||
Common::Path p(TEST_PATH, '\\');
|
||||
TS_ASSERT_EQUALS(p.getLastComponent().toString(), TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p.getParent().toString(), "");
|
||||
|
||||
Common::Path p2(TEST_PATH, 'e');
|
||||
TS_ASSERT_EQUALS(p2.getLastComponent().toString(), ".txt");
|
||||
TS_ASSERT_EQUALS(p2.getParent().toString('#'), "par#nt/dir/fil#");
|
||||
TS_ASSERT_EQUALS(p2.getParent().getParent().toString('#'), "par#");
|
||||
}
|
||||
|
||||
void test_splitComponents() {
|
||||
Common::Path p(TEST_PATH);
|
||||
Common::StringArray array = p.splitComponents();
|
||||
|
||||
TS_ASSERT_EQUALS(array.size(), 3u);
|
||||
|
||||
Common::StringArray::iterator iter = array.begin();
|
||||
|
||||
TS_ASSERT_EQUALS(*iter, "parent");
|
||||
++iter;
|
||||
TS_ASSERT_EQUALS(*iter, "dir");
|
||||
++iter;
|
||||
TS_ASSERT_EQUALS(*iter, "file.txt");
|
||||
|
||||
Common::Path p2;
|
||||
Common::StringArray array2 = p2.splitComponents();
|
||||
TS_ASSERT_EQUALS(array2.size(), 1u);
|
||||
Common::StringArray::iterator iter2 = array2.begin();
|
||||
TS_ASSERT_EQUALS(*iter2, "");
|
||||
|
||||
Common::Path p3(TEST_ESCAPED1_PATH);
|
||||
Common::StringArray array3 = p3.splitComponents();
|
||||
|
||||
TS_ASSERT_EQUALS(array3.size(), 3u);
|
||||
|
||||
Common::StringArray::iterator iter3 = array3.begin();
|
||||
|
||||
TS_ASSERT_EQUALS(*iter3, "|parent");
|
||||
++iter3;
|
||||
TS_ASSERT_EQUALS(*iter3, "dir");
|
||||
++iter3;
|
||||
TS_ASSERT_EQUALS(*iter3, "file.txt");
|
||||
|
||||
}
|
||||
|
||||
void test_joinComponents() {
|
||||
Common::StringArray array;
|
||||
Common::Path p = Common::Path::joinComponents(array);
|
||||
TS_ASSERT_EQUALS(p.toString(), "");
|
||||
|
||||
array.push_back("");
|
||||
p = Common::Path::joinComponents(array);
|
||||
TS_ASSERT_EQUALS(p.toString(), "");
|
||||
|
||||
Common::StringArray array2;
|
||||
array2.push_back("par/ent");
|
||||
array2.push_back("dir");
|
||||
array2.push_back("file.txt");
|
||||
p = Common::Path::joinComponents(array2);
|
||||
TS_ASSERT_EQUALS(p.toString('\\'), TEST_ESCAPED2_PATH);
|
||||
}
|
||||
|
||||
void test_removeTrailingSeparators() {
|
||||
Common::Path p;
|
||||
p.removeTrailingSeparators();
|
||||
TS_ASSERT_EQUALS(p.toString(), "");
|
||||
|
||||
Common::Path p2(TEST_PATH);
|
||||
p2.removeTrailingSeparators();
|
||||
TS_ASSERT_EQUALS(p2.toString(), TEST_PATH);
|
||||
|
||||
Common::Path p3("parent/dir/file.txt///");
|
||||
p3.removeTrailingSeparators();
|
||||
TS_ASSERT_EQUALS(p3.toString(), "parent/dir/file.txt");
|
||||
|
||||
Common::Path p4("//");
|
||||
p4.removeTrailingSeparators();
|
||||
TS_ASSERT_EQUALS(p4.toString(), "/");
|
||||
}
|
||||
|
||||
void test_isRelativeTo() {
|
||||
Common::Path p, p1(TEST_PATH), p2(TEST_ESCAPED1_PATH);
|
||||
|
||||
// Everything is relative to empty
|
||||
TS_ASSERT_EQUALS(p1.isRelativeTo(p), true);
|
||||
TS_ASSERT_EQUALS(p2.isRelativeTo(p), true);
|
||||
// Everything is relative to itself
|
||||
TS_ASSERT_EQUALS(p1.isRelativeTo(p1), true);
|
||||
TS_ASSERT_EQUALS(p2.isRelativeTo(p2), true);
|
||||
|
||||
// A path is not relative to empty one
|
||||
TS_ASSERT_EQUALS(p.isRelativeTo(p1), false);
|
||||
|
||||
TS_ASSERT_EQUALS(p1.isRelativeTo(Common::Path("parent/dir")), true);
|
||||
TS_ASSERT_EQUALS(p1.isRelativeTo(Common::Path("parent/dir/")), true);
|
||||
TS_ASSERT_EQUALS(p1.isRelativeTo(Common::Path("parent/dir/fi")), false);
|
||||
|
||||
TS_ASSERT_EQUALS(p1.isRelativeTo(Common::Path("|parent/dir")), false);
|
||||
|
||||
Common::Path p3("parent\\dir\\fi/le.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p3.isRelativeTo(Common::Path("parent/dir")), true);
|
||||
TS_ASSERT_EQUALS(p3.isRelativeTo(Common::Path("parent/dir/")), true);
|
||||
TS_ASSERT_EQUALS(p3.isRelativeTo(Common::Path("parent/dir/fi")), false);
|
||||
TS_ASSERT_EQUALS(p3.isRelativeTo(Common::Path("parent/dir/fa")), false);
|
||||
|
||||
Common::Path p4("par|ent\\dir\\fi/le.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p4.isRelativeTo(Common::Path("par|ent/dir")), true);
|
||||
}
|
||||
|
||||
void test_relativeTo() {
|
||||
Common::Path p, p1(TEST_PATH), p2(TEST_ESCAPED1_PATH);
|
||||
|
||||
// Everything is relative to empty
|
||||
TS_ASSERT_EQUALS(p1.relativeTo(p).toString(), TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p2.relativeTo(p).toString(), TEST_ESCAPED1_PATH);
|
||||
// Everything is relative to itself
|
||||
TS_ASSERT_EQUALS(p1.relativeTo(p1), p);
|
||||
TS_ASSERT_EQUALS(p2.relativeTo(p2), p);
|
||||
|
||||
// A path is not relative to empty one
|
||||
TS_ASSERT_EQUALS(p.relativeTo(p1), p);
|
||||
|
||||
TS_ASSERT_EQUALS(p1.relativeTo(Common::Path("parent/dir")).toString(), "file.txt");
|
||||
TS_ASSERT_EQUALS(p1.relativeTo(Common::Path("parent/dir/")).toString(), "file.txt");
|
||||
TS_ASSERT_EQUALS(p1.relativeTo(Common::Path("parent/dir/fi")), p1);
|
||||
|
||||
TS_ASSERT_EQUALS(p1.relativeTo(Common::Path("|parent/dir")), p1);
|
||||
|
||||
Common::Path p3("parent\\dir\\fi/le.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p3.relativeTo(Common::Path("parent/dir")).toString('\\'), "fi/le.txt");
|
||||
TS_ASSERT_EQUALS(p3.relativeTo(Common::Path("parent/dir/")).toString('\\'), "fi/le.txt");
|
||||
TS_ASSERT_EQUALS(p3.relativeTo(Common::Path("parent/dir/fi")), p3);
|
||||
TS_ASSERT_EQUALS(p3.relativeTo(Common::Path("parent/dir/fa")), p3);
|
||||
|
||||
Common::Path p4("par|ent\\dir\\fi/le.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p4.relativeTo(Common::Path("par|ent/dir")).toString('\\'), "fi/le.txt");
|
||||
|
||||
Common::Path p5("par|ent\\dir\\\\\\fi/le.txt", '\\');
|
||||
TS_ASSERT_EQUALS(p5.relativeTo(Common::Path("par|ent/dir")).toString('\\'), "fi/le.txt");
|
||||
}
|
||||
|
||||
void test_normalize() {
|
||||
TS_ASSERT_EQUALS(Common::Path("/", '/').normalize().toString(), "/");
|
||||
TS_ASSERT_EQUALS(Common::Path("///", '/').normalize().toString(), "/");
|
||||
TS_ASSERT_EQUALS(Common::Path("/foo/bar", '/').normalize().toString(), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("/foo//bar/", '/').normalize().toString(), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("/foo/./bar", '/').normalize().toString(), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("/foo//./bar//", '/').normalize().toString(), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("/foo//.bar//", '/').normalize().toString(), "/foo/.bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::Path("", '/').normalize().toString(), "");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo/bar", '/').normalize().toString(), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo//bar/", '/').normalize().toString(), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo/./bar", '/').normalize().toString(), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo//./bar//", '/').normalize().toString(), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo//.bar//", '/').normalize().toString(), "foo/.bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::Path("..", '/').normalize().toString(), "..");
|
||||
TS_ASSERT_EQUALS(Common::Path("../", '/').normalize().toString(), "..");
|
||||
TS_ASSERT_EQUALS(Common::Path("/..", '/').normalize().toString(), "/..");
|
||||
TS_ASSERT_EQUALS(Common::Path("../bar", '/').normalize().toString(), "../bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo//../", '/').normalize().toString(), "");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo/../bar", '/').normalize().toString(), "bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo//../bar//", '/').normalize().toString(), "bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo//..bar//", '/').normalize().toString(), "foo/..bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::Path("foo/../../bar//", '/').normalize().toString(), "../bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("../foo/../bar", '/').normalize().toString(), "../bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("../../foo/bar/", '/').normalize().toString(), "../../foo/bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::Path("foo/../|bar", '/').normalize().toString(), "|bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo/^..^bar", '^').normalize().toString('^'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::Path("foo^..^bar/", '^').normalize().toString('^'), "bar/");
|
||||
}
|
||||
|
||||
void test_punycode() {
|
||||
Common::Path p;
|
||||
Common::Path p2 = p.punycodeDecode();
|
||||
TS_ASSERT_EQUALS(p.toString(), "");
|
||||
|
||||
Common::Path p3("parent/dir/xn--Sound Manager 3.1 SoundLib-lba84k/Sound");
|
||||
Common::Path p4 = p3.punycodeDecode();
|
||||
|
||||
TS_ASSERT_EQUALS(p4.toString(':'), "parent:dir:Sound Manager 3.1 / SoundLib:Sound");
|
||||
Common::Path p5 = p4.punycodeEncode();
|
||||
TS_ASSERT_EQUALS(p5.toString('/'), "parent/dir/xn--Sound Manager 3.1 SoundLib-lba84k/Sound");
|
||||
|
||||
Common::Path p6 = p3.punycodeEncode();
|
||||
TS_ASSERT_EQUALS(p6.toString('/'), "parent/dir/xn--xn--Sound Manager 3.1 SoundLib-lba84k-/Sound");
|
||||
|
||||
Common::Path p7 = p6.punycodeDecode();
|
||||
TS_ASSERT_EQUALS(p7.toString('/'), "parent/dir/xn--Sound Manager 3.1 SoundLib-lba84k/Sound");
|
||||
|
||||
typedef Common::HashMap<Common::Path, bool,
|
||||
Common::Path::IgnoreCaseAndMac_Hash, Common::Path::IgnoreCaseAndMac_EqualTo> TestPathMap;
|
||||
TestPathMap map;
|
||||
|
||||
map.setVal(p3, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 1u);
|
||||
map.setVal(p4, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 1u);
|
||||
map.setVal(p5, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 1u);
|
||||
|
||||
map.setVal(p, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 2u);
|
||||
}
|
||||
|
||||
void test_lowerupper() {
|
||||
Common::Path p2(TEST_PATH);
|
||||
p2.toUppercase();
|
||||
TS_ASSERT_EQUALS(p2.toString('/'), "PARENT/DIR/FILE.TXT");
|
||||
|
||||
p2 = TEST_PATH;
|
||||
p2.toLowercase();
|
||||
TS_ASSERT_EQUALS(p2.toString('/'), TEST_PATH);
|
||||
|
||||
Common::Path p3(TEST_ESCAPED1_PATH);
|
||||
p3.toUppercase();
|
||||
TS_ASSERT_EQUALS(p3.toString('/'), "|PARENT/DIR/FILE.TXT");
|
||||
|
||||
Common::String s3(TEST_ESCAPED1_PATH);
|
||||
s3.toUppercase();
|
||||
p3 = s3;
|
||||
p3.toLowercase();
|
||||
TS_ASSERT_EQUALS(p3.toString('/'), TEST_ESCAPED1_PATH);
|
||||
}
|
||||
|
||||
void test_caseinsensitive() {
|
||||
Common::Path p;
|
||||
Common::Path p2("parent:dir:Sound Manager 3.1 / SoundLib:Sound", ':');
|
||||
Common::Path p3("parent:dir:sound manager 3.1 / soundlib:sound", ':');
|
||||
Common::Path p4("parent/dir/xn--Sound Manager 3.1 SoundLib-lba84k/Sound");
|
||||
|
||||
typedef Common::HashMap<Common::Path, bool,
|
||||
Common::Path::IgnoreCase_Hash, Common::Path::IgnoreCase_EqualTo> TestPathMap;
|
||||
TestPathMap map;
|
||||
|
||||
map.setVal(p2, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 1u);
|
||||
map.setVal(p3, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 1u);
|
||||
map.setVal(p4, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 2u);
|
||||
|
||||
map.setVal(p, false);
|
||||
TS_ASSERT_EQUALS(map.size(), 3u);
|
||||
}
|
||||
|
||||
void test_casesensitive() {
|
||||
Common::Path p2("parent:dir:Sound Manager 3.1 / SoundLib:Sound", ':');
|
||||
Common::Path p3("parent:dir:sound manager 3.1 / soundlib:sound", ':');
|
||||
Common::Path p4("parent/dir/xn--Sound Manager 3.1 SoundLib-lba84k/Sound");
|
||||
|
||||
TS_ASSERT_DIFFERS(p2.hash(), p3.hash());
|
||||
TS_ASSERT_DIFFERS(p2.hash(), p4.hash());
|
||||
TS_ASSERT_DIFFERS(p3.hash(), p4.hash());
|
||||
}
|
||||
|
||||
void test_matchString() {
|
||||
TS_ASSERT(Common::Path("").matchPattern(""));
|
||||
TS_ASSERT(Common::Path("a").matchPattern("*"));
|
||||
TS_ASSERT(Common::Path("monkey.s01").matchPattern("*"));
|
||||
|
||||
TS_ASSERT(!Common::Path("").matchPattern("?"));
|
||||
TS_ASSERT(Common::Path("a").matchPattern("?"));
|
||||
TS_ASSERT(!Common::Path("monkey.s01").matchPattern("?"));
|
||||
|
||||
TS_ASSERT(Common::Path("monkey.s01").matchPattern("monkey.s??"));
|
||||
TS_ASSERT(Common::Path("monkey.s99").matchPattern("monkey.s??"));
|
||||
TS_ASSERT(!Common::Path("monkey.s101").matchPattern("monkey.s??"));
|
||||
|
||||
TS_ASSERT(Common::Path("monkey.s01").matchPattern("monkey.s?1"));
|
||||
TS_ASSERT(!Common::Path("monkey.s99").matchPattern("monkey.s?1"));
|
||||
TS_ASSERT(!Common::Path("monkey.s101").matchPattern("monkey.s?1"));
|
||||
|
||||
TS_ASSERT(Common::Path("monkey.s01").matchPattern("monkey.s*"));
|
||||
TS_ASSERT(Common::Path("monkey.s99").matchPattern("monkey.s*"));
|
||||
TS_ASSERT(Common::Path("monkey.s101").matchPattern("monkey.s*"));
|
||||
|
||||
TS_ASSERT(Common::Path("monkey.s01").matchPattern("monkey.s*1"));
|
||||
TS_ASSERT(!Common::Path("monkey.s99").matchPattern("monkey.s*1"));
|
||||
TS_ASSERT(Common::Path("monkey.s101").matchPattern("monkey.s*1"));
|
||||
|
||||
TS_ASSERT(Common::Path("monkey.s01").matchPattern("monkey.s##"));
|
||||
TS_ASSERT(!Common::Path("monkey.s01").matchPattern("monkey.###"));
|
||||
|
||||
TS_ASSERT(Common::Path("monkey.s0#").matchPattern("monkey.s0\\#"));
|
||||
TS_ASSERT(!Common::Path("monkey.s0#").matchPattern("monkey.s0#"));
|
||||
TS_ASSERT(!Common::Path("monkey.s01").matchPattern("monkey.s0\\#"));
|
||||
|
||||
TS_ASSERT(Common::Path("test/monkey.s01").matchPattern("*/*"));
|
||||
TS_ASSERT(!Common::Path("test/monkey.s01").matchPattern("|test/*"));
|
||||
TS_ASSERT(Common::Path("|test/monkey.s01").matchPattern("*/*"));
|
||||
TS_ASSERT(!Common::Path("test/monkey.s01").matchPattern("*"));
|
||||
TS_ASSERT(!Common::Path("test/monkey.s01").matchPattern(Common::Path("test\\fi/le.txt", '\\')));
|
||||
}
|
||||
|
||||
// These tests are here to exercise cases currently not used
|
||||
// This allow to reach 100% code coverage (except unescape error)
|
||||
void test_findLastSeparator() {
|
||||
Common::Path p(TEST_PATH);
|
||||
TS_ASSERT_EQUALS(p.findLastSeparator(), 10u);
|
||||
|
||||
Common::Path p2("file.txt");
|
||||
TS_ASSERT_EQUALS(p2.findLastSeparator(), Common::String::npos);
|
||||
}
|
||||
|
||||
void test_extract() {
|
||||
Common::Path p(TEST_PATH);
|
||||
Common::Path p2 = p.extract(p._str.c_str(), p._str.c_str());
|
||||
TS_ASSERT_EQUALS(p2, Common::Path());
|
||||
|
||||
Common::Path p3("file.txt");
|
||||
TS_ASSERT_EQUALS(p3.extract(p3._str.c_str()), p3);
|
||||
}
|
||||
|
||||
void test_canUnescape() {
|
||||
TS_ASSERT(Common::Path::canUnescape(true, true, ""));
|
||||
}
|
||||
|
||||
void test_removeExtension() {
|
||||
Common::Path p(TEST_PATH);
|
||||
p.removeExtension();
|
||||
TS_ASSERT_EQUALS(p.toString(), "parent/dir/file");
|
||||
|
||||
Common::Path p2("parent/dir/file.txt.gz");
|
||||
p2.removeExtension();
|
||||
TS_ASSERT_EQUALS(p2.toString(), "parent/dir/file.txt");
|
||||
|
||||
Common::Path p3("parent/dir/file.");
|
||||
p3.removeExtension();
|
||||
TS_ASSERT_EQUALS(p3.toString(), "parent/dir/file");
|
||||
|
||||
Common::Path p4("parent/dir/file.txt.txt");
|
||||
p4.removeExtension(".txt");
|
||||
TS_ASSERT_EQUALS(p4.toString(), "parent/dir/file.txt");
|
||||
|
||||
Common::Path p5("parent/dir/file.txt");
|
||||
p5.removeExtension(".txt");
|
||||
TS_ASSERT_EQUALS(p5.toString(), "parent/dir/file");
|
||||
|
||||
Common::Path p6("parent/dir.txt/file.gz");
|
||||
p6.removeExtension(".txt");
|
||||
TS_ASSERT_EQUALS(p6.toString(), "parent/dir.txt/file.gz");
|
||||
|
||||
Common::Path p7("parent/dir/xn--Sound Manager 3.1 SoundLib-lba84k/Sound.txt");
|
||||
p7.removeExtension(".txt");
|
||||
TS_ASSERT_EQUALS(p7.toString(), "parent/dir/xn--Sound Manager 3.1 SoundLib-lba84k/Sound");
|
||||
|
||||
Common::Path p8("parent/dir/Sound/xn--dialred.dir-qa21d");
|
||||
p8.removeExtension(".dir");
|
||||
TS_ASSERT_EQUALS(p8.toString(), "parent/dir/Sound/xn--dialred.dir-qa21d");
|
||||
|
||||
Common::Path p9("parent/dir/.ab");
|
||||
p9.removeExtension();
|
||||
TS_ASSERT_EQUALS(p9.toString(), "parent/dir/");
|
||||
|
||||
Common::Path p10("parent/dir/.ab");
|
||||
p10.removeExtension(".abc");
|
||||
TS_ASSERT_EQUALS(p10.toString(), "parent/dir/.ab");
|
||||
|
||||
Common::Path p11(".ab");
|
||||
p11.removeExtension(".abc");
|
||||
TS_ASSERT_EQUALS(p11.toString(), ".ab");
|
||||
|
||||
Common::Path p12("test.dir");
|
||||
p12.removeExtension(".dir");
|
||||
TS_ASSERT_EQUALS(p12.toString(), "test");
|
||||
|
||||
Common::Path p13("test.dir");
|
||||
p13.removeExtension(".txt");
|
||||
TS_ASSERT_EQUALS(p13.toString(), "test.dir");
|
||||
|
||||
Common::Path p14("test.dir.txt");
|
||||
p14.removeExtension(".dir");
|
||||
TS_ASSERT_EQUALS(p14.toString(), "test.dir.txt");
|
||||
|
||||
Common::Path p15(".dir");
|
||||
p15.removeExtension(".dir");
|
||||
TS_ASSERT_EQUALS(p15.toString(), "");
|
||||
}
|
||||
};
|
||||
172
test/common/ptr.h
Normal file
172
test/common/ptr.h
Normal file
@@ -0,0 +1,172 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/ptr.h"
|
||||
|
||||
class PtrTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
|
||||
struct A {
|
||||
int a;
|
||||
};
|
||||
|
||||
struct B : public A {
|
||||
int b;
|
||||
};
|
||||
|
||||
// A simple class which keeps track of all its instances
|
||||
class InstanceCountingClass {
|
||||
public:
|
||||
static int count;
|
||||
InstanceCountingClass() { count++; }
|
||||
InstanceCountingClass(const InstanceCountingClass&) { count++; }
|
||||
~InstanceCountingClass() { count--; }
|
||||
};
|
||||
|
||||
void test_deletion() {
|
||||
TS_ASSERT_EQUALS(InstanceCountingClass::count, 0);
|
||||
{
|
||||
Common::SharedPtr<InstanceCountingClass> p1(new InstanceCountingClass());
|
||||
TS_ASSERT_EQUALS(InstanceCountingClass::count, 1);
|
||||
|
||||
Common::ScopedPtr<InstanceCountingClass> p2(new InstanceCountingClass());
|
||||
TS_ASSERT_EQUALS(InstanceCountingClass::count, 2);
|
||||
}
|
||||
TS_ASSERT_EQUALS(InstanceCountingClass::count, 0);
|
||||
}
|
||||
|
||||
struct CustomDeleter {
|
||||
static bool invoked;
|
||||
void operator()(int *object) {
|
||||
invoked = true;
|
||||
delete object;
|
||||
}
|
||||
};
|
||||
|
||||
void test_scoped_deleter() {
|
||||
CustomDeleter::invoked = false;
|
||||
|
||||
{
|
||||
Common::ScopedPtr<int, CustomDeleter> a(new int(0));
|
||||
TS_ASSERT(!CustomDeleter::invoked);
|
||||
}
|
||||
|
||||
TS_ASSERT(CustomDeleter::invoked);
|
||||
}
|
||||
|
||||
void test_disposable_deleter() {
|
||||
CustomDeleter::invoked = false;
|
||||
|
||||
{
|
||||
Common::DisposablePtr<int, CustomDeleter> a1(new int, DisposeAfterUse::YES);
|
||||
TS_ASSERT(!CustomDeleter::invoked);
|
||||
}
|
||||
|
||||
TS_ASSERT(CustomDeleter::invoked);
|
||||
CustomDeleter::invoked = false;
|
||||
|
||||
int *a = new int;
|
||||
{
|
||||
Common::DisposablePtr<int, CustomDeleter> a2(a, DisposeAfterUse::NO);
|
||||
}
|
||||
|
||||
TS_ASSERT(!CustomDeleter::invoked);
|
||||
delete a;
|
||||
}
|
||||
|
||||
void test_scoped_deref() {
|
||||
A *raw = new A();
|
||||
raw->a = 123;
|
||||
Common::ScopedPtr<A> a(raw);
|
||||
TS_ASSERT_EQUALS(&*a, &*raw);
|
||||
TS_ASSERT_EQUALS(a->a, raw->a);
|
||||
}
|
||||
|
||||
void test_disposable_deref() {
|
||||
A *raw = new A();
|
||||
raw->a = 123;
|
||||
Common::DisposablePtr<A> a(raw, DisposeAfterUse::YES);
|
||||
TS_ASSERT_EQUALS(&*a, &*raw);
|
||||
TS_ASSERT_EQUALS(a->a, raw->a);
|
||||
}
|
||||
|
||||
void test_assign() {
|
||||
Common::SharedPtr<int> p1(new int(1));
|
||||
TS_ASSERT(p1.unique());
|
||||
TS_ASSERT_EQUALS(*p1, 1);
|
||||
|
||||
{
|
||||
Common::SharedPtr<int> p2 = p1;
|
||||
TS_ASSERT(!p1.unique());
|
||||
TS_ASSERT_EQUALS(p1.refCount(), p2.refCount());
|
||||
TS_ASSERT_EQUALS(p1.refCount(), 2);
|
||||
TS_ASSERT_EQUALS(p1, p2);
|
||||
TS_ASSERT_EQUALS(*p2, 1);
|
||||
{
|
||||
Common::SharedPtr<int> p3;
|
||||
p3 = p2;
|
||||
TS_ASSERT_EQUALS(p3, p2);
|
||||
TS_ASSERT_EQUALS(p3, p1);
|
||||
TS_ASSERT_EQUALS(p1.refCount(), 3);
|
||||
TS_ASSERT_EQUALS(*p3, 1);
|
||||
*p3 = 0;
|
||||
TS_ASSERT_EQUALS(*p3, 0);
|
||||
}
|
||||
TS_ASSERT_EQUALS(*p2, 0);
|
||||
TS_ASSERT_EQUALS(p1.refCount(), 2);
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(*p1, 0);
|
||||
TS_ASSERT(p1.unique());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct Deleter {
|
||||
bool *test;
|
||||
void operator()(T *ptr) { *test = true; delete ptr; }
|
||||
};
|
||||
|
||||
void test_deleter() {
|
||||
Deleter<int> myDeleter;
|
||||
bool test = false;
|
||||
myDeleter.test = &test;
|
||||
|
||||
{
|
||||
Common::SharedPtr<int> p(new int(1), myDeleter);
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(test, true);
|
||||
}
|
||||
|
||||
void test_compare() {
|
||||
Common::SharedPtr<int> p1(new int(1));
|
||||
Common::SharedPtr<int> p2;
|
||||
|
||||
TS_ASSERT(p1);
|
||||
TS_ASSERT(!p2);
|
||||
|
||||
TS_ASSERT(p1 != 0);
|
||||
TS_ASSERT(p2 == 0);
|
||||
|
||||
p1.reset();
|
||||
TS_ASSERT(!p1);
|
||||
}
|
||||
|
||||
void test_cast() {
|
||||
Common::SharedPtr<B> b(new B);
|
||||
Common::SharedPtr<A> a(b);
|
||||
a = b;
|
||||
}
|
||||
|
||||
void test_weak_ptr() {
|
||||
Common::SharedPtr<B> b(new B);
|
||||
Common::WeakPtr<A> a(b);
|
||||
TS_ASSERT(a.lock() == b);
|
||||
TS_ASSERT(!a.expired());
|
||||
b.reset();
|
||||
TS_ASSERT(a.expired());
|
||||
TS_ASSERT(!a.lock());
|
||||
}
|
||||
};
|
||||
|
||||
int PtrTestSuite::InstanceCountingClass::count = 0;
|
||||
bool PtrTestSuite::CustomDeleter::invoked = false;
|
||||
42
test/common/punycode.h
Normal file
42
test/common/punycode.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/punycode.h"
|
||||
|
||||
/**
|
||||
* Test suite for the functions in common/util.h
|
||||
*/
|
||||
static const char *strings[] = {
|
||||
"Icon\r", "xn--Icon-ja6e", "1",
|
||||
"ascii", "ascii", "0",
|
||||
"ends with dot .", "xn--ends with dot .-", "1",
|
||||
"ends with space ", "xn--ends with space -", "1",
|
||||
"バッドデイ(Power PC)", "xn--(Power PC)-jx4ilmwb1a7h", "1",
|
||||
"Hello*", "xn--Hello-la10a", "1",
|
||||
"File I/O", "xn--File IO-oa82b", "1",
|
||||
"HDにコピーして下さい。G3", "xn--HDG3-rw3c5o2dpa9kzb2170dd4tzyda5j4k", "1",
|
||||
"Buried in Time™ Demo", "xn--Buried in Time Demo-eo0l", "1",
|
||||
"•Main Menu", "xn--Main Menu-zd0e", "1",
|
||||
"Spaceship Warlock™", "xn--Spaceship Warlock-306j", "1",
|
||||
"ワロビージャックの大冒険<デモ>", "xn--baa0pja0512dela6bueub9gshf1k1a1rt742c060a2x4u", "1",
|
||||
"Jönssonligan går på djupet.exe", "xn--Jnssonligan gr p djupet.exe-glcd70c", "1",
|
||||
"Jönssonligan.exe", "xn--Jnssonligan.exe-8sb", "1",
|
||||
"G3フォルダ", "xn--G3-3g4axdtexf", "1",
|
||||
"Big[test]", "Big[test]", "0",
|
||||
"Where \\ Do <you> Want / To: G* ? ;Unless=nowhere,or|\"(everything)/\":*|\\?%<>,;=", "xn--Where Do you Want To G ;Unless=nowhere,or(everything),;=-5baedgdcbtamaaaaaaaaa99woa3wnnmb82aqb71ekb9g3c1f1cyb7bx6rfcv2pxa", "1",
|
||||
"Buried in Timeェ Demo", "xn--Buried in Time Demo-yp97h", "1",
|
||||
0
|
||||
};
|
||||
class PunycodeTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
|
||||
void test_punycode() {
|
||||
for (const char **a = strings; *a; a += 3) {
|
||||
Common::U32String string_in(a[0]);
|
||||
Common::String string_out(a[1]);
|
||||
bool need = (a[2][0] == '1');
|
||||
|
||||
TS_ASSERT_EQUALS(punycode_decodefilename(string_out), string_in);
|
||||
TS_ASSERT_EQUALS(punycode_encodefilename(string_in), string_out);
|
||||
TS_ASSERT_EQUALS(punycode_needEncode(string_in), need);
|
||||
}
|
||||
}
|
||||
};
|
||||
82
test/common/queue.h
Normal file
82
test/common/queue.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/queue.h"
|
||||
|
||||
class QueueTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_empty_clear() {
|
||||
Common::Queue<int> queue;
|
||||
TS_ASSERT(queue.empty());
|
||||
|
||||
queue.push(1);
|
||||
queue.push(2);
|
||||
TS_ASSERT(!queue.empty());
|
||||
|
||||
queue.clear();
|
||||
|
||||
TS_ASSERT(queue.empty());
|
||||
}
|
||||
|
||||
void test_size() {
|
||||
Common::Queue<int> queue;
|
||||
TS_ASSERT_EQUALS(queue.size(), 0);
|
||||
|
||||
queue.push(5);
|
||||
TS_ASSERT_EQUALS(queue.size(), 1);
|
||||
|
||||
queue.push(9);
|
||||
queue.push(0);
|
||||
TS_ASSERT_EQUALS(queue.size(), 3);
|
||||
|
||||
queue.pop();
|
||||
TS_ASSERT_EQUALS(queue.size(), 2);
|
||||
}
|
||||
|
||||
void test_front_back_push_pop() {
|
||||
Common::Queue<int> container;
|
||||
|
||||
container.push( 42);
|
||||
container.push(-23);
|
||||
|
||||
TS_ASSERT_EQUALS(container.front(), 42);
|
||||
TS_ASSERT_EQUALS(container.back(), -23);
|
||||
|
||||
container.front() = -17;
|
||||
container.back() = 163;
|
||||
TS_ASSERT_EQUALS(container.front(), -17);
|
||||
TS_ASSERT_EQUALS(container.back(), 163);
|
||||
|
||||
container.pop();
|
||||
TS_ASSERT_EQUALS(container.front(), 163);
|
||||
TS_ASSERT_EQUALS(container.back(), 163);
|
||||
}
|
||||
|
||||
void test_assign() {
|
||||
Common::Queue<int> q1, q2;
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
q1.push(i);
|
||||
q2.push(4-i);
|
||||
}
|
||||
|
||||
Common::Queue<int> q3(q1);
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
TS_ASSERT_EQUALS(q3.front(), i);
|
||||
q3.pop();
|
||||
}
|
||||
|
||||
TS_ASSERT(q3.empty());
|
||||
|
||||
q3 = q2;
|
||||
|
||||
for (int i = 4; i >= 0; --i) {
|
||||
TS_ASSERT_EQUALS(q3.front(), i);
|
||||
q3.pop();
|
||||
}
|
||||
|
||||
TS_ASSERT(q3.empty());
|
||||
TS_ASSERT(!q1.empty());
|
||||
TS_ASSERT(!q2.empty());
|
||||
}
|
||||
};
|
||||
144
test/common/rational.h
Normal file
144
test/common/rational.h
Normal file
@@ -0,0 +1,144 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/rational.h"
|
||||
|
||||
class RationalTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_operators() {
|
||||
Common::Rational r0(6, 3);
|
||||
Common::Rational r1(1, 2);
|
||||
|
||||
Common::Rational r2(62, 2);
|
||||
Common::Rational r3(34, 4);
|
||||
|
||||
Common::Rational r4 = (r0 + r1) * 3;
|
||||
Common::Rational r5 = (r2 - r3) / 3;
|
||||
|
||||
Common::Rational r6 = r5 - 1;
|
||||
|
||||
TS_ASSERT(r4 == r5);
|
||||
TS_ASSERT(!(r4 != r5));
|
||||
|
||||
TS_ASSERT(r4 != r6);
|
||||
TS_ASSERT(!(r4 == r6));
|
||||
|
||||
TS_ASSERT(-r4 == -r5);
|
||||
|
||||
TS_ASSERT(r0 == 2);
|
||||
TS_ASSERT(!(r0 != 2));
|
||||
TS_ASSERT(!(r3 == 2));
|
||||
TS_ASSERT(r3 != 2);
|
||||
|
||||
TS_ASSERT( r4 > r6);
|
||||
TS_ASSERT( r4 >= r6);
|
||||
TS_ASSERT(!(r4 < r6));
|
||||
TS_ASSERT(!(r4 <= r6));
|
||||
|
||||
TS_ASSERT( r4 > 7);
|
||||
TS_ASSERT( r4 >= 7);
|
||||
TS_ASSERT(!(r4 < 7));
|
||||
TS_ASSERT(!(r4 <= 7));
|
||||
|
||||
TS_ASSERT( 7 < r4);
|
||||
TS_ASSERT( 7 <= r4);
|
||||
TS_ASSERT(!(7 > r4));
|
||||
TS_ASSERT(!(7 >= r4));
|
||||
}
|
||||
|
||||
void test_assign() {
|
||||
Common::Rational r0(6, 3);
|
||||
Common::Rational r1(1, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(r0, 2);
|
||||
TS_ASSERT_EQUALS(r1, Common::Rational(1, 2));
|
||||
|
||||
r0 = r1;
|
||||
TS_ASSERT_EQUALS(r0, r1);
|
||||
TS_ASSERT_EQUALS(r0, Common::Rational(1, 2));
|
||||
}
|
||||
|
||||
void test_negative() {
|
||||
Common::Rational r0(6, 3);
|
||||
Common::Rational r1(1, 2);
|
||||
|
||||
r0 = -r0;
|
||||
r1 = -r1;
|
||||
TS_ASSERT_EQUALS(r0, -2);
|
||||
TS_ASSERT_EQUALS(r1, Common::Rational(-1, 2));
|
||||
TS_ASSERT_EQUALS(r1, Common::Rational(1, -2));
|
||||
|
||||
TS_ASSERT_EQUALS(r1, Common::Rational(-25, 50));
|
||||
TS_ASSERT_EQUALS(r1, Common::Rational(25, -50));
|
||||
}
|
||||
|
||||
void test_add_sub() {
|
||||
const Common::Rational r0(6, 3);
|
||||
const Common::Rational r1(1, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(r0 + r1, Common::Rational(5, 2));
|
||||
TS_ASSERT_EQUALS(r1 + r0, Common::Rational(5, 2));
|
||||
TS_ASSERT_EQUALS(r0 - r1, Common::Rational(3, 2));
|
||||
TS_ASSERT_EQUALS(r1 - r0, Common::Rational(-3, 2));
|
||||
|
||||
TS_ASSERT_EQUALS(1 + r1, Common::Rational(3, 2));
|
||||
TS_ASSERT_EQUALS(r1 + 1, Common::Rational(3, 2));
|
||||
TS_ASSERT_EQUALS(1 - r1, Common::Rational(1, 2));
|
||||
TS_ASSERT_EQUALS(r1 - 1, Common::Rational(-1, 2));
|
||||
}
|
||||
|
||||
void test_add_sub2() {
|
||||
// Make sure cancelation works correctly
|
||||
const Common::Rational r0(4, 15); // = 8 / 30
|
||||
const Common::Rational r1(1, 6); // = 5 / 30
|
||||
|
||||
TS_ASSERT_EQUALS(r0 + r1, Common::Rational(13, 30));
|
||||
TS_ASSERT_EQUALS(r1 + r0, Common::Rational(13, 30));
|
||||
TS_ASSERT_EQUALS(r0 - r1, Common::Rational(1, 10));
|
||||
TS_ASSERT_EQUALS(r1 - r0, Common::Rational(-1, 10));
|
||||
|
||||
TS_ASSERT_EQUALS(1 + r1, Common::Rational(7, 6));
|
||||
TS_ASSERT_EQUALS(r1 + 1, Common::Rational(7, 6));
|
||||
TS_ASSERT_EQUALS(1 - r1, Common::Rational(5, 6));
|
||||
TS_ASSERT_EQUALS(r1 - 1, Common::Rational(-5, 6));
|
||||
}
|
||||
|
||||
void test_mul() {
|
||||
const Common::Rational r0(6, 3);
|
||||
const Common::Rational r1(1, 2);
|
||||
|
||||
const Common::Rational r2(15, 14);
|
||||
const Common::Rational r3(7,3);
|
||||
const Common::Rational r4(5,2);
|
||||
|
||||
TS_ASSERT_EQUALS(r0 * r1, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(r2 * r3, r4);
|
||||
TS_ASSERT_EQUALS((-r2) * r3, -r4);
|
||||
TS_ASSERT_EQUALS(r2 * (-r3), -r4);
|
||||
TS_ASSERT_EQUALS((-r2) * (-r3), r4);
|
||||
|
||||
TS_ASSERT_EQUALS(r1 * 2, 1);
|
||||
TS_ASSERT_EQUALS(2 * r1, 1);
|
||||
}
|
||||
|
||||
void test_div() {
|
||||
Common::Rational r0(6, 3);
|
||||
Common::Rational r1(1, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(r0 / r1, 4);
|
||||
|
||||
TS_ASSERT_EQUALS(r1 / 2, Common::Rational(1, 4));
|
||||
TS_ASSERT_EQUALS(2 / r1, Common::Rational(4, 1));
|
||||
}
|
||||
|
||||
void test_isOne() {
|
||||
Common::Rational r0(5, 5);
|
||||
Common::Rational r1(1, 2);
|
||||
Common::Rational r2(2, 1);
|
||||
Common::Rational r3(1, 1);
|
||||
TS_ASSERT(r0.isOne());
|
||||
TS_ASSERT(!r1.isOne());
|
||||
TS_ASSERT(!r2.isOne());
|
||||
TS_ASSERT(r3.isOne());
|
||||
}
|
||||
};
|
||||
62
test/common/rect.h
Normal file
62
test/common/rect.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
class RectTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_point_sqrDist() {
|
||||
Common::Point p0;
|
||||
Common::Point p11(1, 1);
|
||||
Common::Point p21(2, 1);
|
||||
Common::Point p23(2, 3);
|
||||
Common::Point p32(3, 2);
|
||||
TS_ASSERT_EQUALS(p0.sqrDist(p11), (uint) 2);
|
||||
TS_ASSERT_EQUALS(p0.sqrDist(p21), (uint) 5);
|
||||
TS_ASSERT_EQUALS(p0.sqrDist(p23), p0.sqrDist(p32));
|
||||
TS_ASSERT_EQUALS(p11.sqrDist(p11), (uint) 0);
|
||||
TS_ASSERT_EQUALS(p11.sqrDist(p23), (uint) 5);
|
||||
}
|
||||
|
||||
void test_intersects() {
|
||||
TS_ASSERT(Common::Rect(0, 0, 2, 2).intersects(Common::Rect(0, 0, 1, 1)));
|
||||
TS_ASSERT(Common::Rect(0, 0, 2, 2).intersects(Common::Rect(1, 1, 2, 2)));
|
||||
TS_ASSERT(!Common::Rect(0, 0, 1, 1).intersects(Common::Rect(1, 1, 2, 2)));
|
||||
}
|
||||
|
||||
void test_contains() {
|
||||
Common::Rect r0;
|
||||
Common::Rect r1(0, 0, 1, 1);
|
||||
Common::Rect r2(0, 0, 2, 2);
|
||||
TS_ASSERT(!r0.contains(r1));
|
||||
TS_ASSERT(!r0.contains(r2));
|
||||
TS_ASSERT(!r1.contains(r2));
|
||||
TS_ASSERT(r0.contains(r0));
|
||||
|
||||
TS_ASSERT(r1.contains(r0));
|
||||
TS_ASSERT(r1.contains(r1));
|
||||
|
||||
TS_ASSERT(r2.contains(r0));
|
||||
TS_ASSERT(r2.contains(r1));
|
||||
TS_ASSERT(r2.contains(r2));
|
||||
}
|
||||
|
||||
void test_extend() {
|
||||
Common::Rect r0;
|
||||
Common::Rect r1(0, 0, 1, 1);
|
||||
Common::Rect r2(0, 0, 2, 2);
|
||||
TS_ASSERT(!r0.contains(r1));
|
||||
r0.extend(r1);
|
||||
TS_ASSERT(r0.contains(r1));
|
||||
TS_ASSERT_EQUALS(r0.top, 0);
|
||||
TS_ASSERT_EQUALS(r0.left, 0);
|
||||
TS_ASSERT_EQUALS(r0.bottom, 1);
|
||||
TS_ASSERT_EQUALS(r0.right, 1);
|
||||
r2.extend(r1);
|
||||
TS_ASSERT_EQUALS(r2.top, 0);
|
||||
TS_ASSERT_EQUALS(r2.left, 0);
|
||||
TS_ASSERT_EQUALS(r2.bottom, 2);
|
||||
TS_ASSERT_EQUALS(r2.right, 2);
|
||||
}
|
||||
|
||||
};
|
||||
83
test/common/rendermode.h
Normal file
83
test/common/rendermode.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/rendermode.h"
|
||||
#include "common/gui_options.h"
|
||||
#include "common/str.h"
|
||||
|
||||
class RenderModeTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_parse_render_mode_good() {
|
||||
/*
|
||||
* Tests for parseRenderMode.
|
||||
* It takes a code (case-insensitive) and spits a RenderMode back at you.
|
||||
* These cases should work - the inputs are standard, there's just some
|
||||
* fun with caps being had in here.
|
||||
*/
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("fMTOwNs"), Common::kRenderFMTowns);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("hercGrEen"), Common::kRenderHercG);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("hercAmbeR"), Common::kRenderHercA);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("CgA"), Common::kRenderCGA);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("ega"), Common::kRenderEGA);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("Vga"), Common::kRenderVGA);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("AmigA"), Common::kRenderAmiga);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("pc98-256c"), Common::kRenderPC98_256c);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("PC98-16c"), Common::kRenderPC98_16c);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("0"), Common::kRenderDefault);
|
||||
}
|
||||
|
||||
|
||||
void test_parse_render_mode_bad() {
|
||||
/*
|
||||
* These cases, according to the specification, should return the default.
|
||||
* It is only mentioned that the function must be case insensitive.
|
||||
* Whitespaces, in particular, should not be automatically trimmed.
|
||||
*/
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("fmtowns "), Common::kRenderDefault);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("FM-TOWNS "), Common::kRenderDefault);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode(" cga"), Common::kRenderDefault);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("\tC g A"), Common::kRenderDefault);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("\t"), Common::kRenderDefault);
|
||||
// This is the only interesting bit: if the function was really, really
|
||||
// broken it could be tempted to test for +-0x20.
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("pc Y8 -256c "), Common::kRenderDefault);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode(" PC\t98-16c "), Common::kRenderDefault);
|
||||
TS_ASSERT_EQUALS(Common::parseRenderMode("0"), Common::kRenderDefault);
|
||||
}
|
||||
|
||||
void test_get_render_mode_code_back_and_forth() {
|
||||
/*
|
||||
* What does getRenderModeCode return?
|
||||
* Notably, the output should not be in mixed case.
|
||||
*/
|
||||
TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("FMTOWNS")), "fmtowns", 7);
|
||||
TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("CGA")), "cga", 3);
|
||||
TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("vga")), "vga", 3);
|
||||
TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("Ega")), "ega", 3);
|
||||
TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("AmiGa")), "amiga", 5);
|
||||
TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("PC98-256C")), "pc98-256c", 9);
|
||||
TS_ASSERT_SAME_DATA(Common::getRenderModeCode(Common::parseRenderMode("PC98-16C")), "pc98-16c", 8);
|
||||
// Slightly more interesting:
|
||||
// Make sure that we get a null pointer for 0 (and not the "0" string or stuff)
|
||||
char *null_p = 0;
|
||||
TS_ASSERT_EQUALS(Common::getRenderModeCode(Common::kRenderDefault), null_p);
|
||||
}
|
||||
|
||||
void test_render_2_guio() {
|
||||
/*
|
||||
* Verify that a rendermode is taken and the corresponding
|
||||
* GUIO_xxxxx is returned.
|
||||
*/
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderHercG), GUIO_RENDERHERCGREEN);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderHercA), GUIO_RENDERHERCAMBER);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderCGA), GUIO_RENDERCGA);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderEGA), GUIO_RENDEREGA);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderVGA), GUIO_RENDERVGA);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderAmiga), GUIO_RENDERAMIGA);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderFMTowns), GUIO_RENDERFMTOWNS);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderPC98_256c), GUIO_RENDERPC98_256C);
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderPC98_16c), GUIO_RENDERPC98_16C);
|
||||
// renderMode2GUIO is supposed to return an empty string
|
||||
// if given kRenderDefault as an argument
|
||||
Common::String empty;
|
||||
TS_ASSERT_EQUALS(Common::renderMode2GUIO(Common::kRenderDefault), empty);
|
||||
}
|
||||
};
|
||||
73
test/common/seekablesubreadstream.h
Normal file
73
test/common/seekablesubreadstream.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
#include "common/substream.h"
|
||||
|
||||
class SeekableSubReadStreamTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_traverse() {
|
||||
byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Common::MemoryReadStream ms(contents, 10);
|
||||
|
||||
int start = 2, end = 8;
|
||||
|
||||
Common::SeekableSubReadStream ssrs(&ms, start, end);
|
||||
|
||||
int i;
|
||||
byte b;
|
||||
for (i = start; i < end; ++i) {
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
|
||||
TS_ASSERT_EQUALS(i - start, ssrs.pos());
|
||||
|
||||
ssrs.read(&b, 1);
|
||||
TS_ASSERT_EQUALS(i, b);
|
||||
}
|
||||
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
TS_ASSERT_EQUALS((uint)0, ssrs.read(&b, 1));
|
||||
TS_ASSERT(ssrs.eos());
|
||||
}
|
||||
|
||||
void test_seek() {
|
||||
byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Common::MemoryReadStream ms(contents, 10);
|
||||
|
||||
Common::SeekableSubReadStream ssrs(&ms, 1, 9);
|
||||
byte b;
|
||||
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 0);
|
||||
|
||||
ssrs.seek(1, SEEK_SET);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 1);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 2);
|
||||
|
||||
ssrs.seek(5, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 7);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 8);
|
||||
|
||||
ssrs.seek(-3, SEEK_CUR);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 5);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 6);
|
||||
|
||||
ssrs.seek(0, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 8);
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT(ssrs.eos());
|
||||
|
||||
ssrs.seek(-3, SEEK_END);
|
||||
TS_ASSERT(!ssrs.eos());
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 5);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 6);
|
||||
|
||||
ssrs.seek(-8, SEEK_END);
|
||||
TS_ASSERT_EQUALS(ssrs.pos(), 0);
|
||||
b = ssrs.readByte();
|
||||
TS_ASSERT_EQUALS(b, 1);
|
||||
}
|
||||
};
|
||||
111
test/common/serializer.h
Normal file
111
test/common/serializer.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/serializer.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
class SerializerTestSuite : public CxxTest::TestSuite {
|
||||
Common::SeekableReadStream *_inStreamV1;
|
||||
Common::SeekableReadStream *_inStreamV2;
|
||||
public:
|
||||
void setUp() {
|
||||
// Our pseudo data format is as follows:
|
||||
// * magic id - string "MAGI"
|
||||
// * Version - uint32, LE
|
||||
// * uint32, LE (available in v2 onward)
|
||||
// * uint16, BE (available in v1 onward)
|
||||
// * sint16, LE (available only in v1)
|
||||
// * byte (always available)
|
||||
static const byte contents_v1[] = {
|
||||
'M', 'A', 'G', 'I', // magic id
|
||||
0x01, 0x00, 0x00, 0x00, // Version
|
||||
0x06, 0x07, // uint16, BE (available in v1 onward)
|
||||
0xfe, 0xff, // sint16, LE (available only in v1)
|
||||
0x0a // byte (always available)
|
||||
};
|
||||
static const byte contents_v2[] = {
|
||||
'M', 'A', 'G', 'I', // magic id
|
||||
0x02, 0x00, 0x00, 0x00, // Version
|
||||
0x02, 0x03, 0x04, 0x05, // uint32, LE (available in v2 onward)
|
||||
0x06, 0x07, // uint16, BE (available in v1 onward)
|
||||
0x0a // byte (always available)
|
||||
};
|
||||
|
||||
_inStreamV1 = new Common::MemoryReadStream(contents_v1, sizeof(contents_v1));
|
||||
_inStreamV2 = new Common::MemoryReadStream(contents_v2, sizeof(contents_v2));
|
||||
}
|
||||
|
||||
void tearDown() {
|
||||
delete _inStreamV1;
|
||||
delete _inStreamV2;
|
||||
}
|
||||
|
||||
// A method which reads a v1 file
|
||||
void readVersioned_v1(Common::SeekableReadStream *stream, Common::Serializer::Version version) {
|
||||
Common::Serializer ser(stream, 0);
|
||||
|
||||
TS_ASSERT(ser.matchBytes("MAGI", 4));
|
||||
|
||||
TS_ASSERT(ser.syncVersion(1));
|
||||
TS_ASSERT_EQUALS(ser.getVersion(), version);
|
||||
|
||||
uint32 tmp = 0;
|
||||
|
||||
ser.syncAsUint16BE(tmp, Common::Serializer::Version(1));
|
||||
TS_ASSERT_EQUALS(tmp, (uint16)0x0607);
|
||||
|
||||
ser.syncAsSint16LE(tmp, Common::Serializer::Version(1));
|
||||
TS_ASSERT_EQUALS((int16)tmp, -2);
|
||||
|
||||
ser.syncAsByte(tmp);
|
||||
TS_ASSERT_EQUALS(tmp, (uint8)0x0a);
|
||||
}
|
||||
|
||||
// A method which reads a v2 file
|
||||
void readVersioned_v2(Common::SeekableReadStream *stream, Common::Serializer::Version version) {
|
||||
Common::Serializer ser(stream, 0);
|
||||
|
||||
TS_ASSERT(ser.matchBytes("MAGI", 4));
|
||||
|
||||
TS_ASSERT(ser.syncVersion(2));
|
||||
TS_ASSERT_EQUALS(ser.getVersion(), version);
|
||||
|
||||
uint32 tmp;
|
||||
|
||||
// Read a value only available starting with v2.
|
||||
// Thus if we load an old save, it must be
|
||||
// manually set. To simplify that, no sync method should
|
||||
// modify the value passed to it if nothing was read!
|
||||
tmp = 0x12345678;
|
||||
ser.syncAsUint32LE(tmp, Common::Serializer::Version(2));
|
||||
if (ser.getVersion() < 2) {
|
||||
TS_ASSERT_EQUALS(tmp, (uint32)0x12345678);
|
||||
} else {
|
||||
TS_ASSERT_EQUALS(tmp, (uint32)0x05040302);
|
||||
}
|
||||
|
||||
ser.syncAsUint16BE(tmp, Common::Serializer::Version(1));
|
||||
TS_ASSERT_EQUALS(tmp, (uint32)0x0607);
|
||||
|
||||
// Skip over obsolete data
|
||||
ser.skip(2, Common::Serializer::Version(1), Common::Serializer::Version(1));
|
||||
|
||||
ser.syncAsByte(tmp);
|
||||
TS_ASSERT_EQUALS(tmp, (uint8)0x0a);
|
||||
}
|
||||
|
||||
void test_read_v1_as_v1() {
|
||||
readVersioned_v1(_inStreamV1, 1);
|
||||
}
|
||||
|
||||
// There is no test_read_v2_as_v1() because a v1 parser cannot possibly
|
||||
// read v2 data correctly. It should instead error out if it
|
||||
// detects a version newer than its current version.
|
||||
|
||||
void test_read_v1_as_v2() {
|
||||
readVersioned_v2(_inStreamV1, 1);
|
||||
}
|
||||
|
||||
void test_read_v2_as_v2() {
|
||||
readVersioned_v2(_inStreamV2, 2);
|
||||
}
|
||||
};
|
||||
810
test/common/span.h
Normal file
810
test/common/span.h
Normal file
@@ -0,0 +1,810 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
class SpanTestSuite;
|
||||
|
||||
#include "common/span.h"
|
||||
#include "common/str.h"
|
||||
|
||||
class SpanTestSuite : public CxxTest::TestSuite {
|
||||
struct Foo {
|
||||
int a;
|
||||
};
|
||||
|
||||
template <typename ValueType, template <typename> class Derived>
|
||||
class SiblingSpanImpl : public Common::SpanImpl<ValueType, Derived> {
|
||||
typedef Common::SpanImpl<ValueType, Derived> super_type;
|
||||
public:
|
||||
COMMON_SPAN_TYPEDEFS;
|
||||
SiblingSpanImpl() = default;
|
||||
SiblingSpanImpl(pointer data_, size_type size_) : super_type(data_, size_) {}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
class SiblingSpan : public SiblingSpanImpl<ValueType, SiblingSpan> {
|
||||
typedef SiblingSpanImpl<ValueType, ::SpanTestSuite::SiblingSpan> super_type;
|
||||
public:
|
||||
COMMON_SPAN_TYPEDEFS;
|
||||
SiblingSpan() = default;
|
||||
SiblingSpan(pointer data_, size_type size_) : super_type(data_, size_) {}
|
||||
};
|
||||
|
||||
template <typename ValueType, template <typename> class Derived>
|
||||
class SubSpanImpl : public Common::NamedSpanImpl<ValueType, Derived> {
|
||||
typedef Common::NamedSpanImpl<ValueType, Derived> super_type;
|
||||
public:
|
||||
COMMON_SPAN_TYPEDEFS;
|
||||
SubSpanImpl() = default;
|
||||
SubSpanImpl(pointer data_,
|
||||
size_type size_,
|
||||
const Common::String &name_ = Common::String(),
|
||||
const size_type sourceByteOffset_ = 0) :
|
||||
super_type(data_, size_, name_, sourceByteOffset_) {}
|
||||
|
||||
template <typename Other>
|
||||
SubSpanImpl(const Other &other) : super_type(other) {}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
class SubSpan : public SubSpanImpl<ValueType, SubSpan> {
|
||||
typedef SubSpanImpl<ValueType, ::SpanTestSuite::SubSpan> super_type;
|
||||
public:
|
||||
COMMON_SPAN_TYPEDEFS;
|
||||
SubSpan() = default;
|
||||
SubSpan(pointer data_,
|
||||
size_type size_,
|
||||
const Common::String &name_ = Common::String(),
|
||||
const size_type sourceByteOffset_ = 0) :
|
||||
super_type(data_, size_, name_, sourceByteOffset_) {}
|
||||
|
||||
template <typename Other>
|
||||
SubSpan(const Other &other) : super_type(other) {}
|
||||
};
|
||||
|
||||
public:
|
||||
void test_sibling_span() {
|
||||
byte data[] = { 'h', 'e', 'l', 'l', 'o' };
|
||||
SiblingSpan<byte> ss(data, sizeof(data));
|
||||
Common::Span<byte> superInstance = ss;
|
||||
TS_ASSERT_EQUALS(ss.data(), data);
|
||||
TS_ASSERT_EQUALS(superInstance.data(), data);
|
||||
}
|
||||
|
||||
void test_sub_span() {
|
||||
byte data[] = { 'h', 'e', 'l', 'l', 'o' };
|
||||
SubSpan<byte> ss(data, sizeof(data), "custom subspan");
|
||||
Common::NamedSpan<byte> namedSuper = ss;
|
||||
Common::Span<byte> unnamedSuper = ss;
|
||||
TS_ASSERT(ss.name() == "custom subspan");
|
||||
TS_ASSERT(namedSuper.name() == ss.name());
|
||||
TS_ASSERT(unnamedSuper.name() == Common::String::format("%p", (void *)data));
|
||||
}
|
||||
|
||||
void test_span_iterator_const() {
|
||||
byte data[] = { 'h', 'e', 'l', 'l', 'o' };
|
||||
const Common::Span<byte> span(data, sizeof(data));
|
||||
|
||||
Common::Span<byte>::const_iterator it = span.cbegin();
|
||||
|
||||
Common::Span<byte>::const_iterator sameIt(it);
|
||||
|
||||
TS_ASSERT_EQUALS(sameIt, it);
|
||||
|
||||
uint i;
|
||||
for (i = 0; it != span.cend(); ++i, ++it) {
|
||||
TS_ASSERT_EQUALS(*it, data[i]);
|
||||
TS_ASSERT_LESS_THAN(i, sizeof(data));
|
||||
}
|
||||
TS_ASSERT_EQUALS(i, sizeof(data));
|
||||
|
||||
it = span.cend() - 1;
|
||||
for (i = sizeof(data) - 1; it != span.cbegin(); --i, --it) {
|
||||
TS_ASSERT_EQUALS(data[i], *it);
|
||||
}
|
||||
TS_ASSERT_EQUALS(i, 0U);
|
||||
|
||||
it = span.cbegin();
|
||||
|
||||
it += 4;
|
||||
TS_ASSERT_EQUALS(data[4], *it);
|
||||
|
||||
it -= 4;
|
||||
TS_ASSERT_EQUALS(data[0], *it);
|
||||
|
||||
TS_ASSERT_EQUALS(data[0], *it++);
|
||||
|
||||
TS_ASSERT_EQUALS(data[1], *it--);
|
||||
|
||||
TS_ASSERT_EQUALS(span.cend() - span.cbegin(), 5);
|
||||
|
||||
TS_ASSERT_EQUALS(*(span.cbegin() + 4), data[4]);
|
||||
|
||||
TS_ASSERT_EQUALS(*(span.cend() - 4), data[1]);
|
||||
|
||||
TS_ASSERT(span.cbegin() < span.cend());
|
||||
|
||||
TS_ASSERT(span.cbegin() <= span.cend());
|
||||
TS_ASSERT(span.cbegin() <= span.cbegin());
|
||||
|
||||
TS_ASSERT(span.cend() > span.cbegin());
|
||||
|
||||
TS_ASSERT(span.cend() >= span.cbegin());
|
||||
TS_ASSERT(span.cend() >= span.cend());
|
||||
}
|
||||
|
||||
void test_span_iterator() {
|
||||
byte data[] = { 'h', 'e', 'l', 'l', 'o' };
|
||||
Common::Span<byte> span(data, sizeof(data));
|
||||
|
||||
// empty iterator should default construct OK
|
||||
Common::Span<byte>::iterator defaultIt;
|
||||
|
||||
Common::Span<byte>::iterator it = span.begin();
|
||||
|
||||
Common::Span<byte>::iterator sameIt(it);
|
||||
|
||||
TS_ASSERT_EQUALS(sameIt, it);
|
||||
|
||||
uint i;
|
||||
for (i = 0; it != span.end(); ++i, ++it) {
|
||||
TS_ASSERT_EQUALS(*it, data[i]);
|
||||
TS_ASSERT_LESS_THAN(i, sizeof(data));
|
||||
}
|
||||
TS_ASSERT_EQUALS(i, sizeof(data));
|
||||
|
||||
it = span.end() - 1;
|
||||
for (i = sizeof(data) - 1; it != span.begin(); --i, --it) {
|
||||
TS_ASSERT_EQUALS(data[i], *it);
|
||||
}
|
||||
TS_ASSERT_EQUALS(i, 0U);
|
||||
|
||||
it = span.begin();
|
||||
|
||||
it += 4;
|
||||
TS_ASSERT_EQUALS(data[4], *it);
|
||||
|
||||
it -= 4;
|
||||
TS_ASSERT_EQUALS(data[0], *it);
|
||||
|
||||
TS_ASSERT_EQUALS(data[0], *it++);
|
||||
|
||||
TS_ASSERT_EQUALS(data[1], *it--);
|
||||
|
||||
TS_ASSERT_EQUALS(span.end() - span.begin(), 5);
|
||||
|
||||
TS_ASSERT_EQUALS(*(span.begin() + 4), data[4]);
|
||||
|
||||
TS_ASSERT_EQUALS(*(span.end() - 4), data[1]);
|
||||
|
||||
TS_ASSERT(span.begin() < span.end());
|
||||
|
||||
TS_ASSERT(span.begin() <= span.end());
|
||||
TS_ASSERT(span.begin() <= span.begin());
|
||||
|
||||
TS_ASSERT(span.end() > span.begin());
|
||||
|
||||
TS_ASSERT(span.end() >= span.begin());
|
||||
TS_ASSERT(span.end() >= span.end());
|
||||
|
||||
it = span.begin();
|
||||
for (i = 0; it != span.end(); ++i, ++it) {
|
||||
*it = 'a' + i;
|
||||
}
|
||||
|
||||
it = span.begin();
|
||||
for (i = 0; it != span.end(); ++i, ++it) {
|
||||
TS_ASSERT_EQUALS(*it, 'a' + i);
|
||||
TS_ASSERT_EQUALS(data[i], 'a' + i);
|
||||
}
|
||||
}
|
||||
|
||||
void test_span_iterator_integers() {
|
||||
const byte data[] = { 0xFF, 1, 2, 3, 2, 1, 0xFF };
|
||||
Common::Span<const byte> span(data, sizeof(data));
|
||||
Common::Span<const byte>::const_iterator it = span.cbegin();
|
||||
|
||||
TS_ASSERT_EQUALS(it.getInt8(), -1);
|
||||
TS_ASSERT_EQUALS(it.getUint8(), 255);
|
||||
TS_ASSERT_EQUALS(it.getInt16BE(), -255);
|
||||
TS_ASSERT_EQUALS(it.getUint16BE(), 65281U);
|
||||
TS_ASSERT_EQUALS((it + 5).getInt16LE(), -255);
|
||||
TS_ASSERT_EQUALS((it + 5).getUint16LE(), 65281U);
|
||||
TS_ASSERT_EQUALS(it.getUint24LE(), 131583U);
|
||||
#if defined(SCUMM_LITTLE_ENDIAN)
|
||||
TS_ASSERT_EQUALS((it + 3).getUint32(), 4278256131U);
|
||||
#elif defined(SCUMM_BIG_ENDIAN)
|
||||
TS_ASSERT_EQUALS(it.getUint32(), 4278256131U);
|
||||
#else
|
||||
#error No endianness detected
|
||||
#endif
|
||||
TS_ASSERT_EQUALS(it.getInt32BE(), -16711165);
|
||||
TS_ASSERT_EQUALS(it.getUint32BE(), 4278256131U);
|
||||
TS_ASSERT_EQUALS((it + 3).getInt32LE(), -16711165);
|
||||
TS_ASSERT_EQUALS((it + 3).getUint32LE(), 4278256131U);
|
||||
}
|
||||
|
||||
void test_span_iterator_ptr() {
|
||||
Foo foo[2];
|
||||
foo[0].a = 1;
|
||||
foo[1].a = 2;
|
||||
|
||||
const Common::Span<Foo> span(foo, 2);
|
||||
Common::Span<Foo>::const_iterator it = span.cbegin();
|
||||
TS_ASSERT_EQUALS(it->a, 1);
|
||||
++it;
|
||||
TS_ASSERT_EQUALS(it->a, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(it[0].a, 2);
|
||||
TS_ASSERT_EQUALS(it[-1].a, 1);
|
||||
--it;
|
||||
TS_ASSERT_EQUALS(it[1].a, 2);
|
||||
}
|
||||
|
||||
void test_span_owner() {
|
||||
Common::SpanOwner<Common::Span<byte> > owner;
|
||||
owner->allocate(3);
|
||||
owner[0] = 'a';
|
||||
owner[1] = 'b';
|
||||
owner[2] = 'c';
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TS_ASSERT_EQUALS(owner->getUint8At(i), 'a' + i);
|
||||
TS_ASSERT_EQUALS((*owner)[i], 'a' + i);
|
||||
}
|
||||
|
||||
{
|
||||
Common::SpanOwner<Common::NamedSpan<byte> > owner2;
|
||||
TS_ASSERT(owner2->data() == nullptr);
|
||||
owner2->allocateFromSpan(*owner);
|
||||
TS_ASSERT(owner2->data() != nullptr);
|
||||
TS_ASSERT_DIFFERS(owner->data(), owner2->data());
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TS_ASSERT_EQUALS(owner2->getUint8At(i), 'a' + i);
|
||||
TS_ASSERT_EQUALS((*owner2)[i], 'a' + i);
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS((bool)owner2, true);
|
||||
owner2.clear();
|
||||
TS_ASSERT_EQUALS((bool)owner2, false);
|
||||
}
|
||||
|
||||
{
|
||||
Common::SpanOwner<Common::Span<byte> > owner2;
|
||||
TS_ASSERT(owner2->data() == nullptr);
|
||||
owner2 = owner;
|
||||
TS_ASSERT(owner2->data() != nullptr);
|
||||
TS_ASSERT_DIFFERS(owner->data(), owner2->data());
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TS_ASSERT_EQUALS(owner2->getUint8At(i), 'a' + i);
|
||||
TS_ASSERT_EQUALS((*owner2)[i], 'a' + i);
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS((bool)owner2, true);
|
||||
owner2.clear();
|
||||
TS_ASSERT_EQUALS((bool)owner2, false);
|
||||
}
|
||||
|
||||
{
|
||||
Common::SpanOwner<Common::Span<byte> > owner2;
|
||||
TS_ASSERT_EQUALS((bool)owner, true);
|
||||
void *dataPtr = owner->data();
|
||||
owner2.moveFrom(owner);
|
||||
TS_ASSERT_EQUALS((bool)owner, false);
|
||||
TS_ASSERT(owner->data() == nullptr);
|
||||
TS_ASSERT_EQUALS(owner2->data(), dataPtr);
|
||||
|
||||
// tests destruction of held pointer by reassignment
|
||||
owner2 = owner;
|
||||
|
||||
// tests nullipotence of assignment to self
|
||||
dataPtr = owner2->data();
|
||||
owner2 = owner2;
|
||||
TS_ASSERT(owner2->data() == dataPtr);
|
||||
}
|
||||
|
||||
{
|
||||
char *data = new char[6];
|
||||
Common::strlcpy(data, "hello", 6);
|
||||
const Common::SpanOwner<Common::Span<const char> > constOwner(Common::Span<const char>(data, 6));
|
||||
TS_ASSERT_EQUALS((*constOwner)[0], 'h');
|
||||
TS_ASSERT_EQUALS(constOwner->getUint8At(1), 'e');
|
||||
TS_ASSERT_EQUALS(constOwner[2], 'l');
|
||||
}
|
||||
|
||||
{
|
||||
TS_ASSERT_EQUALS((bool)owner, false);
|
||||
Common::SpanOwner<Common::Span<byte> > owner2(owner);
|
||||
TS_ASSERT_EQUALS((bool)owner2, false);
|
||||
}
|
||||
|
||||
{
|
||||
owner->allocate(1);
|
||||
TS_ASSERT_EQUALS((bool)owner, true);
|
||||
Common::SpanOwner<Common::Span<byte> > owner2(owner);
|
||||
TS_ASSERT_EQUALS((bool)owner2, true);
|
||||
TS_ASSERT_DIFFERS(owner->data(), owner2->data());
|
||||
}
|
||||
|
||||
{
|
||||
TS_ASSERT_EQUALS((bool)owner, true);
|
||||
byte *dataPtr = owner->data();
|
||||
TS_ASSERT_EQUALS(owner.release(), dataPtr);
|
||||
TS_ASSERT_EQUALS((bool)owner, false);
|
||||
delete[] dataPtr;
|
||||
}
|
||||
}
|
||||
|
||||
void test_span_owner_named_span() {
|
||||
Common::SpanOwner<Common::NamedSpan<byte> > owner;
|
||||
owner->allocate(3, "foo");
|
||||
owner[0] = 'a';
|
||||
owner[1] = 'b';
|
||||
owner[2] = 'c';
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TS_ASSERT_EQUALS(owner->getUint8At(i), 'a' + i);
|
||||
TS_ASSERT_EQUALS((*owner)[i], 'a' + i);
|
||||
}
|
||||
TS_ASSERT(owner->name() == "foo");
|
||||
|
||||
{
|
||||
Common::SpanOwner<Common::NamedSpan<byte> > owner2;
|
||||
TS_ASSERT(owner2->data() == nullptr);
|
||||
owner2->allocateFromSpan(*owner);
|
||||
TS_ASSERT(owner2->data() != nullptr);
|
||||
TS_ASSERT_DIFFERS(owner->data(), owner2->data());
|
||||
TS_ASSERT(owner2->name() == "foo");
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TS_ASSERT_EQUALS(owner2->getUint8At(i), 'a' + i);
|
||||
TS_ASSERT_EQUALS((*owner2)[i], 'a' + i);
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS((bool)owner2, true);
|
||||
owner2.clear();
|
||||
TS_ASSERT_EQUALS((bool)owner2, false);
|
||||
}
|
||||
|
||||
{
|
||||
Common::SpanOwner<Common::NamedSpan<byte> > owner2;
|
||||
TS_ASSERT_EQUALS((bool)owner, true);
|
||||
void *dataPtr = owner->data();
|
||||
owner2.moveFrom(owner);
|
||||
TS_ASSERT_EQUALS((bool)owner, false);
|
||||
TS_ASSERT(owner->data() == nullptr);
|
||||
TS_ASSERT_EQUALS(owner2->data(), dataPtr);
|
||||
|
||||
// tests destruction of held pointer by reassignment
|
||||
owner2 = owner;
|
||||
}
|
||||
|
||||
{
|
||||
char *data = new char[6];
|
||||
Common::strlcpy(data, "hello", 6);
|
||||
const Common::SpanOwner<Common::NamedSpan<const char> > constOwner(Common::NamedSpan<const char>(data, 6));
|
||||
TS_ASSERT_EQUALS((*constOwner)[0], 'h');
|
||||
TS_ASSERT_EQUALS(constOwner->getUint8At(1), 'e');
|
||||
TS_ASSERT_EQUALS(constOwner[2], 'l');
|
||||
}
|
||||
|
||||
{
|
||||
TS_ASSERT_EQUALS((bool)owner, false);
|
||||
Common::SpanOwner<Common::NamedSpan<byte> > owner2(owner);
|
||||
TS_ASSERT_EQUALS((bool)owner2, false);
|
||||
}
|
||||
|
||||
{
|
||||
owner->allocate(1);
|
||||
TS_ASSERT_EQUALS((bool)owner, true);
|
||||
Common::SpanOwner<Common::NamedSpan<byte> > owner2(owner);
|
||||
TS_ASSERT_EQUALS((bool)owner2, true);
|
||||
TS_ASSERT_DIFFERS(owner->data(), owner2->data());
|
||||
}
|
||||
|
||||
{
|
||||
TS_ASSERT_EQUALS((bool)owner, true);
|
||||
byte *dataPtr = owner->data();
|
||||
TS_ASSERT_EQUALS(owner.release(), dataPtr);
|
||||
TS_ASSERT_EQUALS((bool)owner, false);
|
||||
delete[] dataPtr;
|
||||
}
|
||||
}
|
||||
|
||||
void test_span_allocate_from_stream() {
|
||||
byte data[] = "hello";
|
||||
Common::MemoryReadStream stream(data, sizeof(data));
|
||||
Common::SpanOwner<Common::Span<byte> > owner;
|
||||
owner->allocateFromStream(stream, 2);
|
||||
TS_ASSERT(owner->data() != data);
|
||||
TS_ASSERT_EQUALS(owner->size(), 2U);
|
||||
TS_ASSERT_EQUALS(owner[0], 'h');
|
||||
TS_ASSERT_EQUALS(owner[1], 'e');
|
||||
owner.clear();
|
||||
TS_ASSERT(owner->data() == nullptr);
|
||||
stream.seek(0, SEEK_SET);
|
||||
|
||||
owner->allocateFromStream(stream);
|
||||
TS_ASSERT(owner->data() != data);
|
||||
TS_ASSERT_EQUALS(owner->size(), sizeof(data));
|
||||
TS_ASSERT_EQUALS(owner[0], 'h');
|
||||
TS_ASSERT_EQUALS(owner[1], 'e');
|
||||
TS_ASSERT_EQUALS(owner[2], 'l');
|
||||
TS_ASSERT_EQUALS(owner[3], 'l');
|
||||
TS_ASSERT_EQUALS(owner[4], 'o');
|
||||
|
||||
Common::SpanOwner<Common::NamedSpan<const byte> > owner2;
|
||||
stream.seek(0, SEEK_SET);
|
||||
owner2->allocateFromStream(stream, Common::kSpanMaxSize, "streamname");
|
||||
TS_ASSERT(owner2->data() != data);
|
||||
TS_ASSERT_EQUALS(owner2->size(), sizeof(data));
|
||||
TS_ASSERT_EQUALS(owner2[0], 'h');
|
||||
TS_ASSERT_EQUALS(owner2[1], 'e');
|
||||
TS_ASSERT_EQUALS(owner2[2], 'l');
|
||||
TS_ASSERT_EQUALS(owner2[3], 'l');
|
||||
TS_ASSERT_EQUALS(owner2[4], 'o');
|
||||
TS_ASSERT_EQUALS(owner2->name(), "streamname");
|
||||
}
|
||||
|
||||
void test_span_byte() {
|
||||
{
|
||||
byte data[] = { 'h', 'e', 'l', 'l', 'o' };
|
||||
Common::Span<byte> span(data, sizeof(data));
|
||||
|
||||
TS_ASSERT_EQUALS(span.size(), sizeof(data));
|
||||
TS_ASSERT_EQUALS(span.byteSize(), sizeof(data));
|
||||
|
||||
Common::Span<byte> other(span);
|
||||
TS_ASSERT_EQUALS(span, other);
|
||||
other.clear();
|
||||
TS_ASSERT(span != other);
|
||||
|
||||
TS_ASSERT_EQUALS(span[0], 'h');
|
||||
TS_ASSERT_EQUALS(span[1], 'e');
|
||||
span[1] = 'o';
|
||||
TS_ASSERT_EQUALS(span[1], 'o');
|
||||
|
||||
TS_ASSERT((bool)span);
|
||||
span.clear();
|
||||
TS_ASSERT(!(bool)span);
|
||||
}
|
||||
|
||||
{
|
||||
byte data[] = { 'h', 'e', 'l', 'l', 'o' };
|
||||
const Common::Span<const byte> span(data, sizeof(data));
|
||||
|
||||
TS_ASSERT_EQUALS(span.size(), sizeof(data));
|
||||
TS_ASSERT_EQUALS(span.byteSize(), sizeof(data));
|
||||
|
||||
const Common::Span<const byte> other(span);
|
||||
TS_ASSERT_EQUALS(span, other);
|
||||
|
||||
TS_ASSERT_EQUALS(span[0], 'h');
|
||||
TS_ASSERT_EQUALS(span[1], 'e');
|
||||
}
|
||||
}
|
||||
|
||||
void test_span_integers() {
|
||||
const byte data[] = { 0xFF, 1, 2, 3, 2, 1, 0xFF };
|
||||
Common::Span<const byte> span(data, sizeof(data));
|
||||
|
||||
TS_ASSERT_EQUALS(span[0], 255);
|
||||
TS_ASSERT_EQUALS(span.getInt8At(0), -1);
|
||||
TS_ASSERT_EQUALS(span.getUint8At(0), 255U);
|
||||
TS_ASSERT_EQUALS(span.getInt16BEAt(0), -255);
|
||||
TS_ASSERT_EQUALS(span.getUint16BEAt(0), 65281U);
|
||||
TS_ASSERT_EQUALS(span.getInt16LEAt(5), -255);
|
||||
TS_ASSERT_EQUALS(span.getUint16LEAt(5), 65281U);
|
||||
TS_ASSERT_EQUALS(span.getUint24LEAt(0), 131583U);
|
||||
TS_ASSERT_EQUALS(span.getInt32BEAt(0), -16711165);
|
||||
TS_ASSERT_EQUALS(span.getUint32BEAt(0), 4278256131U);
|
||||
TS_ASSERT_EQUALS(span.getInt32LEAt(3), -16711165);
|
||||
TS_ASSERT_EQUALS(span.getUint32LEAt(3), 4278256131U);
|
||||
|
||||
#if defined(SCUMM_LITTLE_ENDIAN)
|
||||
TS_ASSERT_EQUALS(span.getUint32At(3), 4278256131U);
|
||||
#elif defined(SCUMM_BIG_ENDIAN)
|
||||
TS_ASSERT_EQUALS(span.getUint32At(0), 4278256131U);
|
||||
#else
|
||||
#error No endianness detected
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_span_string() {
|
||||
char data[] = "hello";
|
||||
Common::Span<char> span(data, sizeof(data));
|
||||
TS_ASSERT_EQUALS(span[sizeof(data) - 1], '\0');
|
||||
|
||||
TS_ASSERT(span.getStringAt(0) == data);
|
||||
TS_ASSERT(span.getStringAt(0, 2) == "he");
|
||||
TS_ASSERT(span.getStringAt(2) == "llo");
|
||||
TS_ASSERT(span.getStringAt(2, 3) == "llo");
|
||||
span[3] = '\0';
|
||||
TS_ASSERT(span.getStringAt(0) == "hel");
|
||||
}
|
||||
|
||||
void test_span_unsafe_data() {
|
||||
char data[] = "hello";
|
||||
Common::Span<char> span(data, sizeof(data));
|
||||
|
||||
char *ptr = span.getUnsafeDataAt(0, 6);
|
||||
TS_ASSERT_EQUALS(ptr, data);
|
||||
ptr = span.getUnsafeDataAt(0);
|
||||
TS_ASSERT_EQUALS(ptr, data);
|
||||
|
||||
const Common::Span<const char> span2(data, sizeof(data));
|
||||
const char *ptr2 = span2.getUnsafeDataAt(0, 6);
|
||||
TS_ASSERT_EQUALS(ptr2, data);
|
||||
ptr2 = span2.getUnsafeDataAt(0);
|
||||
TS_ASSERT_EQUALS(ptr2, data);
|
||||
}
|
||||
|
||||
void test_span_subspan() {
|
||||
{
|
||||
byte data[] = { 1, 2, 3, 4, 5, 6 };
|
||||
Common::Span<byte> span(data, sizeof(data));
|
||||
|
||||
TS_ASSERT_EQUALS(span.subspan(0).size(), sizeof(data) - 0);
|
||||
TS_ASSERT_EQUALS(span.subspan(2).size(), sizeof(data) - 2);
|
||||
TS_ASSERT_EQUALS(span.subspan(2, 2).size(), 2U);
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0).size(), sizeof(data) / 2);
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0).byteSize(), sizeof(data));
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).size(), 1U);
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).byteSize(), 2U);
|
||||
|
||||
#if defined(SCUMM_LITTLE_ENDIAN)
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 4 << 8 | 3);
|
||||
#elif defined(SCUMM_BIG_ENDIAN)
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 3 << 8 | 4);
|
||||
#else
|
||||
#error No endianness detected
|
||||
#endif
|
||||
|
||||
Common::Span<uint16> shortSpan = span.subspan<uint16>(0);
|
||||
TS_ASSERT_EQUALS(shortSpan.byteSize(), span.byteSize());
|
||||
TS_ASSERT(shortSpan.size() != span.size());
|
||||
shortSpan[1] = 0xFFFF;
|
||||
Common::Span<byte> byteSpan = shortSpan.subspan<byte>(1);
|
||||
TS_ASSERT_EQUALS(byteSpan.size(), sizeof(data) - 1 * sizeof(uint16));
|
||||
TS_ASSERT_EQUALS(byteSpan[0], 0xFF);
|
||||
TS_ASSERT_EQUALS(byteSpan[1], 0xFF);
|
||||
}
|
||||
|
||||
{
|
||||
byte data[] = { 1, 2, 3, 4, 5, 6 };
|
||||
const Common::Span<const byte> span(data, sizeof(data));
|
||||
|
||||
TS_ASSERT_EQUALS(span.subspan(0).size(), sizeof(data) - 0);
|
||||
TS_ASSERT_EQUALS(span.subspan(2).size(), sizeof(data) - 2);
|
||||
TS_ASSERT_EQUALS(span.subspan(2, 2).size(), 2U);
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0).size(), sizeof(data) / 2);
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0).byteSize(), sizeof(data));
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).size(), 1U);
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0, 2).byteSize(), 2U);
|
||||
|
||||
#if defined(SCUMM_LITTLE_ENDIAN)
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 4 << 8 | 3);
|
||||
#elif defined(SCUMM_BIG_ENDIAN)
|
||||
TS_ASSERT_EQUALS(span.subspan<uint16>(0)[1], 3 << 8 | 4);
|
||||
#else
|
||||
#error No endianness detected
|
||||
#endif
|
||||
|
||||
const Common::Span<uint16> shortSpan = span.subspan<uint16>(0);
|
||||
TS_ASSERT_EQUALS(shortSpan.byteSize(), span.byteSize());
|
||||
TS_ASSERT(shortSpan.size() != span.size());
|
||||
Common::Span<byte> byteSpan = shortSpan.subspan<byte>(1);
|
||||
TS_ASSERT_EQUALS(byteSpan.size(), sizeof(data) - 1 * sizeof(uint16));
|
||||
TS_ASSERT_EQUALS(byteSpan[0], 3);
|
||||
TS_ASSERT_EQUALS(byteSpan[1], 4);
|
||||
}
|
||||
}
|
||||
|
||||
void test_span_to_stream() {
|
||||
const byte data[] = { 0, 1, 2, 3 };
|
||||
Common::Span<const byte> span(data, sizeof(data));
|
||||
|
||||
{
|
||||
Common::MemoryReadStream stream(span.toStream(1, 2));
|
||||
byte out;
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
|
||||
TS_ASSERT_EQUALS(out, 1);
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
|
||||
TS_ASSERT_EQUALS(out, 2);
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 0U);
|
||||
}
|
||||
|
||||
{
|
||||
Common::MemoryReadStream stream = span.toStream();
|
||||
byte out;
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
|
||||
TS_ASSERT_EQUALS(out, 0);
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
|
||||
TS_ASSERT_EQUALS(out, 1);
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
|
||||
TS_ASSERT_EQUALS(out, 2);
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 1U);
|
||||
TS_ASSERT_EQUALS(out, 3);
|
||||
TS_ASSERT_EQUALS(stream.read(&out, 1), 0U);
|
||||
}
|
||||
}
|
||||
|
||||
void test_span_copying() {
|
||||
const byte data[] = { 0, 1, 2, 3, 4, 5 };
|
||||
Common::Span<const byte> span(data, sizeof(data));
|
||||
|
||||
byte targetData[sizeof(data)] = {};
|
||||
Common::Span<byte> target(targetData, sizeof(targetData));
|
||||
span.copyDataTo(target);
|
||||
for (uint i = 0; i < sizeof(data); ++i) {
|
||||
TS_ASSERT_EQUALS(target[i], i);
|
||||
}
|
||||
|
||||
byte out[sizeof(data)];
|
||||
span.unsafeCopyDataTo(out);
|
||||
for (uint i = 0; i < sizeof(data); ++i) {
|
||||
TS_ASSERT_EQUALS(out[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
void test_span_validation() {
|
||||
byte data[6];
|
||||
Common::Span<byte> span(data, sizeof(data));
|
||||
TS_ASSERT(!span.checkInvalidBounds(0, 0));
|
||||
TS_ASSERT(!span.checkInvalidBounds(0, 6));
|
||||
TS_ASSERT(!span.checkInvalidBounds(2, 4));
|
||||
TS_ASSERT(!span.checkInvalidBounds(4, 2));
|
||||
TS_ASSERT(!span.checkInvalidBounds(6, 0));
|
||||
TS_ASSERT(!span.checkInvalidBounds(2, -2));
|
||||
TS_ASSERT(span.checkInvalidBounds(-2, 2)); // negative index disallowed
|
||||
TS_ASSERT(span.checkInvalidBounds(6, 1)); // combined positive overflow (+7)
|
||||
TS_ASSERT(span.checkInvalidBounds(2, -4)); // negative overflow (-2)
|
||||
TS_ASSERT(span.checkInvalidBounds(0, 10)); // delta positive overflow
|
||||
|
||||
const Common::Span<byte>::difference_type big = (Common::Span<byte>::difference_type)1 << (8 * sizeof(Common::Span<byte>::difference_type) - 1);
|
||||
TS_ASSERT(span.checkInvalidBounds(big, 0));
|
||||
TS_ASSERT(span.checkInvalidBounds(0, big));
|
||||
TS_ASSERT(span.checkInvalidBounds(big, big));
|
||||
}
|
||||
|
||||
void test_span_validation_message() {
|
||||
byte data[1];
|
||||
Common::Span<byte> span(data, sizeof(data));
|
||||
|
||||
Common::String source = span.name();
|
||||
Common::String actual;
|
||||
Common::String expected;
|
||||
|
||||
actual = span.getValidationMessage(12, 34, Common::kValidateRead);
|
||||
expected = Common::String::format("Access violation reading %s: 12 + 34 > 1", source.c_str());
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
|
||||
actual = span.getValidationMessage(23, 45, Common::kValidateWrite);
|
||||
expected = Common::String::format("Access violation writing %s: 23 + 45 > 1", source.c_str());
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
|
||||
actual = span.getValidationMessage(0, -56, Common::kValidateSeek);
|
||||
expected = Common::String::format("Access violation seeking %s: 0 + -56 > 1", source.c_str());
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
}
|
||||
|
||||
void test_span_comparators() {
|
||||
byte data[2] = { 0 };
|
||||
Common::Span<const byte> span0(data, sizeof(data));
|
||||
Common::Span<const byte> span1(data, sizeof(data));
|
||||
Common::Span<const byte> span2(data, sizeof(data) - 1);
|
||||
Common::Span<const byte> span3(data + 1, sizeof(data) - 1);
|
||||
Common::Span<const byte> span4(data + 2, sizeof(data) - 2);
|
||||
|
||||
TS_ASSERT(span0 == span1);
|
||||
TS_ASSERT(span0 != span2);
|
||||
TS_ASSERT(span0 <= span1);
|
||||
TS_ASSERT(span0 <= span3);
|
||||
TS_ASSERT(span0 < span3);
|
||||
TS_ASSERT(span3 < span4);
|
||||
TS_ASSERT(span4 > span3);
|
||||
TS_ASSERT(span3 > span0);
|
||||
TS_ASSERT(span4 >= span4);
|
||||
TS_ASSERT(span0 >= span1);
|
||||
|
||||
TS_ASSERT_EQUALS(span1 - span0, 0);
|
||||
TS_ASSERT_EQUALS(span3 - span0, 1);
|
||||
TS_ASSERT_EQUALS(span4 - span0, 2);
|
||||
TS_ASSERT_EQUALS(span0 - span1, 0);
|
||||
TS_ASSERT_EQUALS(span0 - span3, -1);
|
||||
TS_ASSERT_EQUALS(span0 - span4, -2);
|
||||
}
|
||||
|
||||
void test_named_span() {
|
||||
byte data[6] = { 0, 1, 2, 3, 4, 5 };
|
||||
Common::NamedSpan<byte> span(data, sizeof(data), "foo.data");
|
||||
TS_ASSERT_EQUALS(span.name(), "foo.data");
|
||||
|
||||
Common::String actual;
|
||||
Common::String expected;
|
||||
|
||||
actual = span.getValidationMessage(12, 34, Common::kValidateRead);
|
||||
expected = "Access violation reading foo.data: 12 + 34 > 6 (abs: 12 + 34 > 6)";
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
|
||||
{
|
||||
Common::NamedSpan<byte> subspan = span.subspan(2);
|
||||
|
||||
expected = "Access violation reading foo.data: 23 + 45 > 4 (abs: 25 + 45 > 6)";
|
||||
actual = subspan.getValidationMessage(23, 45, Common::kValidateRead);
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
}
|
||||
|
||||
{
|
||||
Common::NamedSpan<byte> subspan = span.subspan(2, Common::kSpanMaxSize, "new.data");
|
||||
expected = "Access violation reading new.data: 0 + -56 > 4 (abs: 2 + -56 > 6)";
|
||||
actual = subspan.getValidationMessage(0, -56, Common::kValidateRead);
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
}
|
||||
|
||||
{
|
||||
Common::NamedSpan<byte> subspan = span.subspan(2, Common::kSpanMaxSize, "new.data", 0);
|
||||
expected = "Access violation reading new.data: 0 + -56 > 4 (abs: 0 + -56 > 4)";
|
||||
actual = subspan.getValidationMessage(0, -56, Common::kValidateRead);
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
}
|
||||
|
||||
Common::NamedSpan<byte> span2;
|
||||
span = span2 = span;
|
||||
TS_ASSERT_EQUALS(span2, span);
|
||||
TS_ASSERT(span2.name() == span.name());
|
||||
TS_ASSERT(span2.sourceByteOffset() == span.sourceByteOffset());
|
||||
|
||||
Common::Span<byte> superclassInstance;
|
||||
superclassInstance = span;
|
||||
TS_ASSERT_EQUALS(span, superclassInstance);
|
||||
|
||||
Common::Span<byte> subclassInstance(superclassInstance);
|
||||
TS_ASSERT_EQUALS(subclassInstance, superclassInstance);
|
||||
|
||||
const Common::NamedSpan<const byte> constSpan(span);
|
||||
|
||||
{
|
||||
Common::NamedSpan<const byte> subspan = constSpan.subspan(2);
|
||||
|
||||
expected = "Access violation reading foo.data: 23 + 45 > 4 (abs: 25 + 45 > 6)";
|
||||
actual = subspan.getValidationMessage(23, 45, Common::kValidateRead);
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
TS_ASSERT_EQUALS(subspan.sourceByteOffset(), 2U);
|
||||
}
|
||||
|
||||
{
|
||||
Common::NamedSpan<const byte> subspan = constSpan.subspan(2, Common::kSpanMaxSize, "new.data");
|
||||
expected = "Access violation reading new.data: 0 + -56 > 4 (abs: 2 + -56 > 6)";
|
||||
actual = subspan.getValidationMessage(0, -56, Common::kValidateRead);
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
}
|
||||
|
||||
{
|
||||
Common::NamedSpan<const byte> subspan = constSpan.subspan(2, Common::kSpanMaxSize, "new.data", 0);
|
||||
expected = "Access violation reading new.data: 0 + -56 > 4 (abs: 0 + -56 > 4)";
|
||||
actual = subspan.getValidationMessage(0, -56, Common::kValidateRead);
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
}
|
||||
|
||||
{
|
||||
Common::NamedSpan<const byte> subspan = constSpan.subspan(2, Common::kSpanMaxSize, "new.data", 0);
|
||||
subspan.sourceByteOffset() = 2;
|
||||
expected = "Access violation reading new.data: 0 + -56 > 4 (abs: 2 + -56 > 6)";
|
||||
actual = subspan.getValidationMessage(0, -56, Common::kValidateRead);
|
||||
TS_ASSERT_EQUALS(actual, expected);
|
||||
}
|
||||
|
||||
{
|
||||
Common::MemoryReadStream *stream = new Common::MemoryReadStream(data, sizeof(data));
|
||||
Common::File file;
|
||||
file.open(stream, "test.txt");
|
||||
Common::SpanOwner<Common::NamedSpan<const byte> > fileOwner;
|
||||
fileOwner->allocateFromStream(file);
|
||||
TS_ASSERT_EQUALS(fileOwner->size(), (uint)file.size());
|
||||
file.close();
|
||||
TS_ASSERT(fileOwner->name() == "test.txt");
|
||||
for (uint i = 0; i < fileOwner->size(); ++i) {
|
||||
TS_ASSERT_EQUALS(fileOwner->getInt8At(i), data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
83
test/common/stack.h
Normal file
83
test/common/stack.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/stack.h"
|
||||
|
||||
class StackTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_empty_clear() {
|
||||
Common::Stack<int> stack;
|
||||
TS_ASSERT(stack.empty());
|
||||
|
||||
stack.push(1);
|
||||
stack.push(2);
|
||||
TS_ASSERT(!stack.empty());
|
||||
|
||||
stack.clear();
|
||||
|
||||
TS_ASSERT(stack.empty());
|
||||
}
|
||||
|
||||
void test_size() {
|
||||
typedef Common::Stack<int> Stack;
|
||||
|
||||
Stack stack;
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)0);
|
||||
|
||||
stack.push(5);
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)1);
|
||||
|
||||
stack.push(9);
|
||||
stack.push(0);
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)3);
|
||||
|
||||
stack.pop();
|
||||
TS_ASSERT_EQUALS(stack.size(), (Stack::size_type)2);
|
||||
}
|
||||
|
||||
void test_top_pop() {
|
||||
Common::Stack<int> stack;
|
||||
|
||||
stack.push( 42);
|
||||
stack.push(-23);
|
||||
|
||||
TS_ASSERT_EQUALS(stack[0], 42);
|
||||
TS_ASSERT_EQUALS(stack.top(), -23);
|
||||
|
||||
stack[0] = -23;
|
||||
stack.top() = 42;
|
||||
TS_ASSERT_EQUALS(stack[0], -23);
|
||||
TS_ASSERT_EQUALS(stack.top(), 42);
|
||||
|
||||
stack.pop();
|
||||
TS_ASSERT_EQUALS(stack[0], -23);
|
||||
}
|
||||
|
||||
void test_assign() {
|
||||
Common::Stack<int> q1, q2;
|
||||
|
||||
for (int i = 0; i <= 4; ++i) {
|
||||
q1.push(4-i);
|
||||
q2.push(i);
|
||||
}
|
||||
|
||||
Common::Stack<int> q3(q1);
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
TS_ASSERT_EQUALS(q3.top(), i);
|
||||
q3.pop();
|
||||
}
|
||||
|
||||
TS_ASSERT(q3.empty());
|
||||
|
||||
q3 = q2;
|
||||
|
||||
for (int i = 4; i >= 0; --i) {
|
||||
TS_ASSERT_EQUALS(q3.top(), i);
|
||||
q3.pop();
|
||||
}
|
||||
|
||||
TS_ASSERT(q3.empty());
|
||||
TS_ASSERT(!q1.empty());
|
||||
TS_ASSERT(!q2.empty());
|
||||
}
|
||||
};
|
||||
23
test/common/str-helper.h
Normal file
23
test/common/str-helper.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef TEST_COMMON_HELPER_H
|
||||
#define TEST_COMMON_HELPER_H
|
||||
|
||||
#include "common/str.h"
|
||||
|
||||
namespace CxxTest
|
||||
{
|
||||
CXXTEST_TEMPLATE_INSTANTIATION
|
||||
class ValueTraits<const Common::String &>
|
||||
{
|
||||
ValueTraits &operator=( const ValueTraits & );
|
||||
Common::String _str;
|
||||
|
||||
public:
|
||||
ValueTraits( const Common::String &value ) : _str( value ) {}
|
||||
ValueTraits( const ValueTraits &other ) : _str( other._str ) {}
|
||||
const char *asString( void ) const { return _str.c_str(); }
|
||||
};
|
||||
CXXTEST_COPY_CONST_TRAITS( Common::String &);
|
||||
CXXTEST_COPY_TRAITS( Common::String, const Common::String &);
|
||||
}
|
||||
|
||||
#endif
|
||||
774
test/common/str.h
Normal file
774
test/common/str.h
Normal file
@@ -0,0 +1,774 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
#include "test/common/str-helper.h"
|
||||
|
||||
class StringTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_constructors() {
|
||||
Common::String str("test-string");
|
||||
TS_ASSERT_EQUALS(str, "test-string");
|
||||
str = Common::String(str.c_str()+5, 3);
|
||||
TS_ASSERT_EQUALS(str, "str");
|
||||
str = "test-string";
|
||||
TS_ASSERT_EQUALS(str, "test-string");
|
||||
str = Common::String(str.c_str()+5, str.c_str()+8);
|
||||
TS_ASSERT_EQUALS(str, "str");
|
||||
str = Common::String(5, 'a');
|
||||
TS_ASSERT_EQUALS(str, "aaaaa");
|
||||
}
|
||||
|
||||
void test_trim() {
|
||||
Common::String str(" This is a s tring with spaces ");
|
||||
Common::String str2 = str;
|
||||
str.trim();
|
||||
TS_ASSERT_EQUALS(str, "This is a s tring with spaces");
|
||||
TS_ASSERT_EQUALS(str2, " This is a s tring with spaces ");
|
||||
}
|
||||
|
||||
void test_chop() {
|
||||
Common::String str("test-string");
|
||||
Common::String str2 = str;
|
||||
str.chop();
|
||||
TS_ASSERT_EQUALS(str, "test-strin");
|
||||
TS_ASSERT_EQUALS(str2, "test-string");
|
||||
|
||||
str = "test-string";
|
||||
str.chop(2);
|
||||
TS_ASSERT_EQUALS(str, "test-stri");
|
||||
|
||||
str = "test-string";
|
||||
str.chop(10);
|
||||
TS_ASSERT_EQUALS(str, "t");
|
||||
|
||||
str = "test-string";
|
||||
str.chop(11);
|
||||
TS_ASSERT(str.empty());
|
||||
|
||||
str = "test-string";
|
||||
str.chop(200);
|
||||
TS_ASSERT(str.empty());
|
||||
}
|
||||
|
||||
void test_empty_clear() {
|
||||
Common::String str("test");
|
||||
TS_ASSERT(!str.empty());
|
||||
str.clear();
|
||||
TS_ASSERT(str.empty());
|
||||
}
|
||||
|
||||
void test_lastChar() {
|
||||
Common::String str;
|
||||
TS_ASSERT_EQUALS(str.lastChar(), '\0');
|
||||
str = "test";
|
||||
TS_ASSERT_EQUALS(str.lastChar(), 't');
|
||||
Common::String str2("bar");
|
||||
TS_ASSERT_EQUALS(str2.lastChar(), 'r');
|
||||
}
|
||||
|
||||
void test_firstChar() {
|
||||
Common::String str;
|
||||
TS_ASSERT_EQUALS(str.firstChar(), '\0');
|
||||
str = "first_test";
|
||||
TS_ASSERT_EQUALS(str.firstChar(), 'f');
|
||||
Common::String str2("bar");
|
||||
TS_ASSERT_EQUALS(str2.firstChar(), 'b');
|
||||
}
|
||||
|
||||
void test_assign1() {
|
||||
Common::String str("foobar");
|
||||
str.assign("bar");
|
||||
TS_ASSERT_EQUALS(str, "bar");
|
||||
}
|
||||
|
||||
void test_assign2() {
|
||||
Common::String str("foobar");
|
||||
str.assign("abcdef", 3);
|
||||
TS_ASSERT_EQUALS(str, "abc");
|
||||
}
|
||||
|
||||
void test_assign3() {
|
||||
Common::String str("foobar");
|
||||
str.assign(3, '0');
|
||||
TS_ASSERT_EQUALS(str, "000");
|
||||
}
|
||||
|
||||
void test_concat1() {
|
||||
Common::String str("foo");
|
||||
Common::String str2("bar");
|
||||
str += str2;
|
||||
TS_ASSERT_EQUALS(str, "foobar");
|
||||
TS_ASSERT_EQUALS(str2, "bar");
|
||||
}
|
||||
|
||||
void test_concat2() {
|
||||
Common::String str("foo");
|
||||
str += "bar";
|
||||
TS_ASSERT_EQUALS(str, "foobar");
|
||||
}
|
||||
|
||||
void test_concat3() {
|
||||
Common::String str("foo");
|
||||
str += 'X';
|
||||
TS_ASSERT_EQUALS(str, "fooX");
|
||||
}
|
||||
|
||||
void test_concat4() {
|
||||
Common::String str("foo");
|
||||
str.append(2, '+');
|
||||
TS_ASSERT_EQUALS(str, "foo++");
|
||||
}
|
||||
|
||||
void test_refCount() {
|
||||
// using internal storage
|
||||
Common::String foo1("foo");
|
||||
Common::String foo2(foo1);
|
||||
Common::String foo3(foo2);
|
||||
foo3 += 'X';
|
||||
TS_ASSERT_EQUALS(foo1, "foo");
|
||||
TS_ASSERT_EQUALS(foo2, "foo");
|
||||
TS_ASSERT_EQUALS(foo3, "foo""X");
|
||||
foo2 = 'x';
|
||||
TS_ASSERT_EQUALS(foo1, "foo");
|
||||
TS_ASSERT_EQUALS(foo2, "x");
|
||||
TS_ASSERT_EQUALS(foo3, "foo""X");
|
||||
}
|
||||
|
||||
void test_refCount2() {
|
||||
// using external storage
|
||||
Common::String foo1("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
Common::String foo2(foo1);
|
||||
Common::String foo3(foo2);
|
||||
foo3 += 'X';
|
||||
TS_ASSERT_EQUALS(foo1, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
TS_ASSERT_EQUALS(foo2, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
TS_ASSERT_EQUALS(foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""X");
|
||||
foo2 = 'x';
|
||||
TS_ASSERT_EQUALS(foo1, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
TS_ASSERT_EQUALS(foo2, "x");
|
||||
TS_ASSERT_EQUALS(foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""X");
|
||||
}
|
||||
|
||||
void test_refCount3() {
|
||||
Common::String foo1("0123456789abcdefghijk");
|
||||
Common::String foo2(foo1);
|
||||
Common::String foo3(foo2);
|
||||
foo3 += "0123456789abcdefghijk";
|
||||
TS_ASSERT_EQUALS(foo1, foo2);
|
||||
TS_ASSERT_EQUALS(foo2, "0123456789abcdefghijk");
|
||||
TS_ASSERT_EQUALS(foo3, "0123456789abcdefghijk""0123456789abcdefghijk");
|
||||
foo2 = 'x';
|
||||
TS_ASSERT_EQUALS(foo1, "0123456789abcdefghijk");
|
||||
TS_ASSERT_EQUALS(foo2, "x");
|
||||
TS_ASSERT_EQUALS(foo3, "0123456789abcdefghijk""0123456789abcdefghijk");
|
||||
}
|
||||
|
||||
void test_refCount4() {
|
||||
Common::String foo1("fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
Common::String foo2(foo1);
|
||||
Common::String foo3(foo2);
|
||||
foo3 += "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd";
|
||||
TS_ASSERT_EQUALS(foo1, foo2);
|
||||
TS_ASSERT_EQUALS(foo2, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
TS_ASSERT_EQUALS(foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
foo2 = 'x';
|
||||
TS_ASSERT_EQUALS(foo1, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
TS_ASSERT_EQUALS(foo2, "x");
|
||||
TS_ASSERT_EQUALS(foo3, "fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd""fooasdkadklasdjklasdjlkasjdlkasjdklasjdlkjasdasd");
|
||||
}
|
||||
|
||||
void test_refCount5() {
|
||||
// using external storage
|
||||
Common::String foo1("HelloHelloHelloHelloAndHi");
|
||||
Common::String foo2(foo1);
|
||||
|
||||
for (Common::String::iterator i = foo2.begin(); i != foo2.end(); ++i)
|
||||
*i = 'h';
|
||||
|
||||
TS_ASSERT_EQUALS(foo1, "HelloHelloHelloHelloAndHi");
|
||||
TS_ASSERT_EQUALS(foo2, "hhhhhhhhhhhhhhhhhhhhhhhhh");
|
||||
}
|
||||
|
||||
void test_refCount6() {
|
||||
// using internal storage
|
||||
Common::String foo1("Hello");
|
||||
Common::String foo2(foo1);
|
||||
|
||||
for (Common::String::iterator i = foo2.begin(); i != foo2.end(); ++i)
|
||||
*i = 'h';
|
||||
|
||||
TS_ASSERT_EQUALS(foo1, "Hello");
|
||||
TS_ASSERT_EQUALS(foo2, "hhhhh");
|
||||
}
|
||||
|
||||
void test_self_asignment() {
|
||||
Common::String foo1("12345678901234567890123456789012");
|
||||
foo1 = foo1.c_str() + 2;
|
||||
TS_ASSERT_EQUALS(foo1, "345678901234567890123456789012");
|
||||
|
||||
Common::String foo2("123456789012");
|
||||
foo2 = foo2.c_str() + 2;
|
||||
TS_ASSERT_EQUALS(foo2, "3456789012");
|
||||
|
||||
// "foo3" and "foo4" will be using allocated storage from construction on.
|
||||
Common::String foo3("12345678901234567890123456789012");
|
||||
foo3 += foo3.c_str();
|
||||
TS_ASSERT_EQUALS(foo3, "12345678901234567890123456789012""12345678901234567890123456789012");
|
||||
|
||||
Common::String foo4("12345678901234567890123456789012");
|
||||
foo4 += foo4;
|
||||
TS_ASSERT_EQUALS(foo4, "12345678901234567890123456789012""12345678901234567890123456789012");
|
||||
|
||||
// Based on our current Common::String implementation "foo5" and "foo6" will first use the internal storage,
|
||||
// and on "operator +=" they will change to allocated memory.
|
||||
Common::String foo5("123456789012");
|
||||
foo5 += foo5.c_str();
|
||||
TS_ASSERT_EQUALS(foo5, "123456789012""123456789012");
|
||||
|
||||
Common::String foo6("123456789012");
|
||||
foo6 += foo6;
|
||||
TS_ASSERT_EQUALS(foo6, "123456789012""123456789012");
|
||||
|
||||
// "foo7" and "foo8" will purely operate on internal storage.
|
||||
Common::String foo7("1234");
|
||||
foo7 += foo7.c_str();
|
||||
TS_ASSERT_EQUALS(foo7, "1234""1234");
|
||||
|
||||
Common::String foo8("1234");
|
||||
foo8 += foo8;
|
||||
TS_ASSERT_EQUALS(foo8, "1234""1234");
|
||||
|
||||
Common::String foo9("123456789012345678901234567889012");
|
||||
foo9 = foo9.c_str();
|
||||
TS_ASSERT_EQUALS(foo9, "123456789012345678901234567889012");
|
||||
foo9 = foo9;
|
||||
TS_ASSERT_EQUALS(foo9, "123456789012345678901234567889012");
|
||||
|
||||
Common::String foo10("1234");
|
||||
foo10 = foo10.c_str();
|
||||
TS_ASSERT_EQUALS(foo10, "1234");
|
||||
foo10 = foo10;
|
||||
TS_ASSERT_EQUALS(foo10, "1234");
|
||||
}
|
||||
|
||||
void test_hasPrefix() {
|
||||
Common::String str("this/is/a/test, haha");
|
||||
TS_ASSERT_EQUALS(str.hasPrefix(""), true);
|
||||
TS_ASSERT_EQUALS(str.hasPrefix("this"), true);
|
||||
TS_ASSERT_EQUALS(str.hasPrefix("thit"), false);
|
||||
TS_ASSERT_EQUALS(str.hasPrefix("foo"), false);
|
||||
}
|
||||
|
||||
void test_hasSuffix() {
|
||||
Common::String str("this/is/a/test, haha");
|
||||
TS_ASSERT_EQUALS(str.hasSuffix(""), true);
|
||||
TS_ASSERT_EQUALS(str.hasSuffix("haha"), true);
|
||||
TS_ASSERT_EQUALS(str.hasSuffix("hahb"), false);
|
||||
TS_ASSERT_EQUALS(str.hasSuffix("hahah"), false);
|
||||
}
|
||||
|
||||
void test_contains() {
|
||||
Common::String str("this/is/a/test, haha");
|
||||
TS_ASSERT_EQUALS(str.contains(""), true);
|
||||
TS_ASSERT_EQUALS(str.contains("haha"), true);
|
||||
TS_ASSERT_EQUALS(str.contains("hahb"), false);
|
||||
TS_ASSERT_EQUALS(str.contains("test"), true);
|
||||
|
||||
TS_ASSERT_EQUALS(str.contains('/'), true);
|
||||
TS_ASSERT_EQUALS(str.contains('x'), false);
|
||||
}
|
||||
|
||||
void test_toLowercase() {
|
||||
Common::String str("Test it, NOW! 42");
|
||||
Common::String str2 = str;
|
||||
str.toLowercase();
|
||||
TS_ASSERT_EQUALS(str, "test it, now! 42");
|
||||
TS_ASSERT_EQUALS(str2, "Test it, NOW! 42");
|
||||
}
|
||||
|
||||
void test_toUppercase() {
|
||||
Common::String str("Test it, NOW! 42");
|
||||
Common::String str2 = str;
|
||||
str.toUppercase();
|
||||
TS_ASSERT_EQUALS(str, "TEST IT, NOW! 42");
|
||||
TS_ASSERT_EQUALS(str2, "Test it, NOW! 42");
|
||||
}
|
||||
|
||||
void test_deleteChar() {
|
||||
Common::String str("01234567890123456789012345678901");
|
||||
str.deleteChar(10);
|
||||
TS_ASSERT_EQUALS(str, "0123456789123456789012345678901");
|
||||
str.deleteChar(10);
|
||||
TS_ASSERT_EQUALS(str, "012345678923456789012345678901");
|
||||
}
|
||||
|
||||
void test_erase() {
|
||||
Common::String str("01234567890123456789012345678901");
|
||||
str.erase(18);
|
||||
TS_ASSERT_EQUALS(str, "012345678901234567");
|
||||
str.erase(7, 5);
|
||||
TS_ASSERT_EQUALS(str, "0123456234567");
|
||||
}
|
||||
|
||||
void test_sharing() {
|
||||
Common::String str("01234567890123456789012345678901");
|
||||
Common::String str2(str);
|
||||
TS_ASSERT_EQUALS(str2, "01234567890123456789012345678901");
|
||||
str.deleteLastChar();
|
||||
TS_ASSERT_EQUALS(str, "0123456789012345678901234567890");
|
||||
TS_ASSERT_EQUALS(str2, "01234567890123456789012345678901");
|
||||
}
|
||||
|
||||
void test_lastPathComponent() {
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("/", '/'), "");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("/foo/bar", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("/foo//bar/", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("/foo/./bar", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("/foo//./bar//", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("/foo//.bar//", '/'), ".bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("", '/'), "");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("foo/bar", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("foo//bar/", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("foo/./bar", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("foo//./bar//", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("foo//.bar//", '/'), ".bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::lastPathComponent("foo", '/'), "foo");
|
||||
}
|
||||
|
||||
void test_normalizePath() {
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("/", '/'), "/");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("/foo/bar", '/'), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("/foo//bar/", '/'), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("/foo/./bar", '/'), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("/foo//./bar//", '/'), "/foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("/foo//.bar//", '/'), "/foo/.bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("", '/'), "");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo/bar", '/'), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo//bar/", '/'), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo/./bar", '/'), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo//./bar//", '/'), "foo/bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo//.bar//", '/'), "foo/.bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("..", '/'), "..");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("../", '/'), "..");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("/..", '/'), "/..");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("../bar", '/'), "../bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo//../", '/'), "");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo/../bar", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo//../bar//", '/'), "bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo//..bar//", '/'), "foo/..bar");
|
||||
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("foo/../../bar//", '/'), "../bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("../foo/../bar", '/'), "../bar");
|
||||
TS_ASSERT_EQUALS(Common::normalizePath("../../foo/bar/", '/'), "../../foo/bar");
|
||||
}
|
||||
|
||||
void test_matchString() {
|
||||
TS_ASSERT(Common::matchString("", "*"));
|
||||
TS_ASSERT(Common::matchString("a", "*"));
|
||||
TS_ASSERT(Common::matchString("monkey.s01", "*"));
|
||||
|
||||
TS_ASSERT(!Common::matchString("", "?"));
|
||||
TS_ASSERT(Common::matchString("a", "?"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s01", "?"));
|
||||
|
||||
TS_ASSERT(Common::matchString("monkey.s01", "monkey.s??"));
|
||||
TS_ASSERT(Common::matchString("monkey.s99", "monkey.s??"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s101", "monkey.s??"));
|
||||
|
||||
TS_ASSERT(Common::matchString("monkey.s01", "monkey.s?1"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s99", "monkey.s?1"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s101", "monkey.s?1"));
|
||||
|
||||
TS_ASSERT(Common::matchString("monkey.s01", "monkey.s*"));
|
||||
TS_ASSERT(Common::matchString("monkey.s99", "monkey.s*"));
|
||||
TS_ASSERT(Common::matchString("monkey.s101", "monkey.s*"));
|
||||
|
||||
TS_ASSERT(Common::matchString("monkey.s01", "monkey.s*1"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s99", "monkey.s*1"));
|
||||
TS_ASSERT(Common::matchString("monkey.s101", "monkey.s*1"));
|
||||
|
||||
TS_ASSERT(Common::matchString("monkey.s01", "monkey.s##"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s01", "monkey.###"));
|
||||
|
||||
TS_ASSERT(Common::matchString("monkey.s0#", "monkey.s0\\#"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s0#", "monkey.s0#"));
|
||||
TS_ASSERT(!Common::matchString("monkey.s01", "monkey.s0\\#"));
|
||||
|
||||
TS_ASSERT(!Common::String("").matchString("*_"));
|
||||
TS_ASSERT(Common::String("a").matchString("a***"));
|
||||
}
|
||||
|
||||
void test_string_printf() {
|
||||
TS_ASSERT_EQUALS( Common::String::format(" "), " " );
|
||||
TS_ASSERT_EQUALS( Common::String::format("%s", "test"), "test" );
|
||||
TS_ASSERT_EQUALS( Common::String::format("%s.s%.02d", "monkey", 1), "monkey.s01" );
|
||||
TS_ASSERT_EQUALS( Common::String::format("Some %s to make this string longer than the default built-in %s %d", "text", "capacity", 123456), "Some text to make this string longer than the default built-in capacity 123456" );
|
||||
|
||||
Common::String s = Common::String::format("%s%X", "test", 1234);
|
||||
TS_ASSERT_EQUALS(s, "test4D2");
|
||||
TS_ASSERT_EQUALS(s.size(), 7U);
|
||||
}
|
||||
|
||||
void test_ustring_printf() {
|
||||
//Ideally should be the same as above (make String template?)
|
||||
TS_ASSERT_EQUALS( Common::U32String::format(" ").encode(), " " );
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%s", "test").encode(), "test" );
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%s%c%s", "Press ", 'X', " to win").encode(), "Press X to win" );
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("Some %s to make this string longer than the default built-in %s %d", "text", "capacity", 123456).encode(), "Some text to make this string longer than the default built-in capacity 123456" );
|
||||
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%u", 0).encode(), "0" );
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%u", 1234).encode(), "1234" );
|
||||
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%d", 0).encode(), "0" );
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%d", 1234).encode(), "1234" );
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%d", -1234).encode(), "-1234" );
|
||||
|
||||
TS_ASSERT_EQUALS( Common::U32String::format("%u %%", 100).encode(), "100 %" );
|
||||
}
|
||||
|
||||
void test_strlcpy() {
|
||||
static const char * const testString = "1234567890";
|
||||
|
||||
char test1[4];
|
||||
TS_ASSERT_EQUALS(Common::strlcpy(test1, testString, 4), strlen(testString));
|
||||
TS_ASSERT_EQUALS(strcmp(test1, "123"), 0);
|
||||
|
||||
char test2[12];
|
||||
test2[11] = 'X';
|
||||
TS_ASSERT_EQUALS(Common::strlcpy(test2, testString, 11), strlen(testString));
|
||||
TS_ASSERT_EQUALS(strcmp(test2, testString), 0);
|
||||
TS_ASSERT_EQUALS(test2[11], 'X');
|
||||
|
||||
char test3[1] = { 'X' };
|
||||
TS_ASSERT_EQUALS(Common::strlcpy(test3, testString, 0), strlen(testString));
|
||||
TS_ASSERT_EQUALS(test3[0], 'X');
|
||||
|
||||
char test4[12];
|
||||
TS_ASSERT_EQUALS(Common::strlcpy(test4, testString, 12), strlen(testString));
|
||||
TS_ASSERT_EQUALS(strcmp(test4, testString), 0);
|
||||
}
|
||||
|
||||
void test_strlcat() {
|
||||
static const char * const initialString = "123";
|
||||
static const char * const appendString = "4567890";
|
||||
static const char * const resultString = "1234567890";
|
||||
|
||||
char test1[4];
|
||||
TS_ASSERT_EQUALS(Common::strlcpy(test1, initialString, 4), strlen(initialString));
|
||||
TS_ASSERT_EQUALS(strcmp(test1, initialString), 0);
|
||||
TS_ASSERT_EQUALS(Common::strlcat(test1, appendString, 4), strlen(resultString));
|
||||
TS_ASSERT_EQUALS(strcmp(test1, initialString), 0);
|
||||
|
||||
char test2[12];
|
||||
test2[11] = 'X';
|
||||
TS_ASSERT_EQUALS(Common::strlcpy(test2, initialString, 11), strlen(initialString));
|
||||
TS_ASSERT_EQUALS(strcmp(test2, initialString), 0);
|
||||
TS_ASSERT_EQUALS(Common::strlcat(test2, appendString, 11), strlen(resultString));
|
||||
TS_ASSERT_EQUALS(strcmp(test2, resultString), 0);
|
||||
TS_ASSERT_EQUALS(test2[11], 'X');
|
||||
|
||||
char test3[1];
|
||||
test3[0] = 'X';
|
||||
TS_ASSERT_EQUALS(Common::strlcat(test3, appendString, 0), strlen(appendString));
|
||||
TS_ASSERT_EQUALS(test3[0], 'X');
|
||||
|
||||
char test4[11];
|
||||
TS_ASSERT_EQUALS(Common::strlcpy(test4, initialString, 11), strlen(initialString));
|
||||
TS_ASSERT_EQUALS(strcmp(test4, initialString), 0);
|
||||
TS_ASSERT_EQUALS(Common::strlcat(test4, appendString, 11), strlen(resultString));
|
||||
TS_ASSERT_EQUALS(strcmp(test4, resultString), 0);
|
||||
}
|
||||
|
||||
void test_strnlen() {
|
||||
static const char * const testString = "123";
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testString, 0), 0u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testString, 1), 1u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testString, 2), 2u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testString, 3), 3u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testString, 4), 3u);
|
||||
|
||||
const char testArray[4] = { '1', '2', '3', '4' };
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray, 0), 0u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray, 1), 1u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray, 2), 2u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray, 3), 3u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray, 4), 4u);
|
||||
|
||||
const char testArray2[4] = { '1', '\0', '3', '4' };
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray2, 0), 0u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray2, 1), 1u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray2, 2), 1u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray2, 3), 1u);
|
||||
TS_ASSERT_EQUALS(Common::strnlen(testArray2, 4), 1u);
|
||||
}
|
||||
|
||||
void test_scumm_stricmp() {
|
||||
TS_ASSERT_EQUALS(scumm_stricmp("abCd", "abCd"), 0);
|
||||
TS_ASSERT_EQUALS(scumm_stricmp("abCd", "ABCd"), 0);
|
||||
TS_ASSERT_LESS_THAN(scumm_stricmp("abCd", "ABCe"), 0);
|
||||
TS_ASSERT_LESS_THAN(scumm_stricmp("abCd", "ABCde"), 0);
|
||||
}
|
||||
|
||||
void test_scumm_strnicmp() {
|
||||
TS_ASSERT_EQUALS(scumm_strnicmp("abCd", "abCd", 3), 0);
|
||||
TS_ASSERT_EQUALS(scumm_strnicmp("abCd", "ABCd", 4), 0);
|
||||
TS_ASSERT_EQUALS(scumm_strnicmp("abCd", "ABCd", 5), 0);
|
||||
TS_ASSERT_EQUALS(scumm_strnicmp("abCd", "ABCe", 3), 0);
|
||||
TS_ASSERT_LESS_THAN(scumm_strnicmp("abCd", "ABCe", 4), 0);
|
||||
TS_ASSERT_EQUALS(scumm_strnicmp("abCd", "ABCde", 4), 0);
|
||||
TS_ASSERT_LESS_THAN(scumm_strnicmp("abCd", "ABCde", 5), 0);
|
||||
}
|
||||
|
||||
void test_wordWrap() {
|
||||
Common::String testString("123456");
|
||||
testString.wordWrap(10);
|
||||
TS_ASSERT(testString == "123456");
|
||||
testString.wordWrap(2);
|
||||
TS_ASSERT(testString == "12\n34\n56");
|
||||
testString = "1234 5678";
|
||||
testString.wordWrap(4);
|
||||
TS_ASSERT(testString == "1234\n5678");
|
||||
testString = "12 3 45";
|
||||
testString.wordWrap(4);
|
||||
TS_ASSERT(testString == "12 3\n45");
|
||||
testString = "\n1\n23 45\n\n";
|
||||
testString.wordWrap(3);
|
||||
TS_ASSERT(testString == "\n1\n23\n45\n\n");
|
||||
testString = "123 ";
|
||||
testString.wordWrap(4);
|
||||
TS_ASSERT(testString == "123 ");
|
||||
testString.wordWrap(3);
|
||||
TS_ASSERT(testString == "123\n");
|
||||
}
|
||||
|
||||
void test_replace() {
|
||||
// Tests created with the results of the STL std::string class
|
||||
|
||||
// --------------------------
|
||||
// Tests without displacement
|
||||
// --------------------------
|
||||
Common::String testString = Common::String("This is the original string.");
|
||||
|
||||
// Positions and sizes as parameters, string as replacement
|
||||
testString.replace(12, 8, Common::String("newnewne"));
|
||||
TS_ASSERT_EQUALS(testString, Common::String("This is the newnewne string."));
|
||||
|
||||
// The same but with char*
|
||||
testString.replace(0, 4, "That");
|
||||
TS_ASSERT_EQUALS(testString, Common::String("That is the newnewne string."));
|
||||
|
||||
// Using iterators (also a terribly useless program as a test).
|
||||
testString.replace(testString.begin(), testString.end(), "That is the supernew string.");
|
||||
TS_ASSERT_EQUALS(testString, Common::String("That is the supernew string."));
|
||||
|
||||
// With sub strings of character arrays.
|
||||
testString.replace(21, 6, "That phrase is new.", 5, 6);
|
||||
TS_ASSERT_EQUALS(testString, Common::String("That is the supernew phrase."));
|
||||
|
||||
// Now with substrings.
|
||||
testString.replace(12, 2, Common::String("That hy is new."), 5, 2);
|
||||
TS_ASSERT_EQUALS(testString, Common::String("That is the hypernew phrase."));
|
||||
|
||||
// --------------------------
|
||||
// Tests with displacement
|
||||
// --------------------------
|
||||
testString = Common::String("Hello World");
|
||||
|
||||
// Positions and sizes as parameters, string as replacement
|
||||
testString.replace(6, 5, Common::String("friends"));
|
||||
TS_ASSERT_EQUALS(testString, Common::String("Hello friends"));
|
||||
|
||||
// The same but with char*
|
||||
testString.replace(0, 5, "Good");
|
||||
TS_ASSERT_EQUALS(testString, Common::String("Good friends"));
|
||||
|
||||
// Using iterators (also a terribly useless program as a test)
|
||||
testString.replace(testString.begin() + 4, testString.begin() + 5, " coffee ");
|
||||
TS_ASSERT_EQUALS(testString, Common::String("Good coffee friends"));
|
||||
|
||||
// With sub strings of character arrays
|
||||
testString.replace(4, 0, "Lorem ipsum expresso dolor sit amet", 11, 9);
|
||||
TS_ASSERT_EQUALS(testString, Common::String("Good expresso coffee friends"));
|
||||
|
||||
// Now with substrings
|
||||
testString.replace(5, 9, Common::String("Displaced ristretto string"), 10, 10);
|
||||
TS_ASSERT_EQUALS(testString, Common::String("Good ristretto coffee friends"));
|
||||
|
||||
// -----------------------
|
||||
// Deep copy compliance
|
||||
// -----------------------
|
||||
|
||||
// Makes a deep copy without changing the length of the original
|
||||
Common::String s1 = "TestTestTestTestTestTestTestTestTestTestTest";
|
||||
Common::String s2(s1);
|
||||
TS_ASSERT_EQUALS(s1, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
TS_ASSERT_EQUALS(s2, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
s1.replace(0, 4, "TEST");
|
||||
TS_ASSERT_EQUALS(s1, "TESTTestTestTestTestTestTestTestTestTestTest");
|
||||
TS_ASSERT_EQUALS(s2, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
|
||||
// Makes a deep copy when we shorten the string
|
||||
Common::String s3 = "TestTestTestTestTestTestTestTestTestTestTest";
|
||||
Common::String s4(s3);
|
||||
s3.replace(0, 32, "");
|
||||
TS_ASSERT_EQUALS(s3, "TestTestTest");
|
||||
TS_ASSERT_EQUALS(s4, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
}
|
||||
|
||||
void test_ustring_replace() {
|
||||
// These tests are inspired from the above string tests
|
||||
|
||||
// --------------------------
|
||||
// Tests without displacement
|
||||
// --------------------------
|
||||
Common::U32String testString = Common::U32String("This is the original string.");
|
||||
|
||||
// Positions and sizes as parameters, U32String as replacement
|
||||
testString.replace(12, 8, Common::U32String("newnewne"));
|
||||
TS_ASSERT_EQUALS(testString, Common::U32String("This is the newnewne string."));
|
||||
|
||||
// Using iterators (also a terribly useless program as a test).
|
||||
testString.replace(testString.begin(), testString.end(), Common::U32String("That is the supernew string."));
|
||||
TS_ASSERT_EQUALS(testString, Common::U32String("That is the supernew string."));
|
||||
|
||||
// With substrings.
|
||||
testString.replace(12, 2, Common::U32String("That hy is new."), 5, 2);
|
||||
TS_ASSERT_EQUALS(testString, Common::U32String("That is the hypernew string."));
|
||||
|
||||
// --------------------------
|
||||
// Tests with displacement
|
||||
// --------------------------
|
||||
testString = Common::U32String("Hello World");
|
||||
|
||||
// Positions and sizes as parameters, string as replacement
|
||||
testString.replace(6, 5, Common::U32String("friends"));
|
||||
TS_ASSERT_EQUALS(testString, Common::U32String("Hello friends"));
|
||||
|
||||
// Using iterators (also a terribly useless program as a test)
|
||||
testString.replace(testString.begin() + 5, testString.begin() + 6, Common::U32String(" good "));
|
||||
TS_ASSERT_EQUALS(testString, Common::U32String("Hello good friends"));
|
||||
|
||||
// With substrings
|
||||
testString.replace(6, 0, Common::U32String("Displaced my string"), 10, 3);
|
||||
TS_ASSERT_EQUALS(testString, Common::U32String("Hello my good friends"));
|
||||
|
||||
// -----------------------
|
||||
// Deep copy compliance
|
||||
// -----------------------
|
||||
|
||||
// Makes a deep copy without changing the length of the original
|
||||
Common::U32String s1 = Common::U32String("TestTestTestTestTestTestTestTestTestTestTest");
|
||||
Common::U32String s2(s1);
|
||||
TS_ASSERT_EQUALS(s1, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
TS_ASSERT_EQUALS(s2, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
s1.replace(0, 4, Common::U32String("TEST"));
|
||||
TS_ASSERT_EQUALS(s1, "TESTTestTestTestTestTestTestTestTestTestTest");
|
||||
TS_ASSERT_EQUALS(s2, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
|
||||
// Makes a deep copy when we shorten the string
|
||||
Common::U32String s3 = Common::U32String("TestTestTestTestTestTestTestTestTestTestTest");
|
||||
Common::U32String s4(s3);
|
||||
s3.replace(0, 32, Common::U32String());
|
||||
TS_ASSERT_EQUALS(s3, "TestTestTest");
|
||||
TS_ASSERT_EQUALS(s4, "TestTestTestTestTestTestTestTestTestTestTest");
|
||||
}
|
||||
|
||||
void test_find() {
|
||||
Common::String a("0123012"), b;
|
||||
|
||||
TS_ASSERT_EQUALS(a.find('1'), 1u);
|
||||
TS_ASSERT_EQUALS(a.find('3'), 3u);
|
||||
TS_ASSERT_EQUALS(a.find('1', 3), 5u);
|
||||
TS_ASSERT_EQUALS(b.find('*'), Common::String::npos);
|
||||
TS_ASSERT_EQUALS(b.find('*', 1), Common::String::npos);
|
||||
|
||||
TS_ASSERT_EQUALS(a.rfind('1'), 5u);
|
||||
TS_ASSERT_EQUALS(a.rfind('3'), 3u);
|
||||
TS_ASSERT_EQUALS(a.rfind('1', 3), 1u);
|
||||
TS_ASSERT_EQUALS(b.rfind('*'), Common::String::npos);
|
||||
TS_ASSERT_EQUALS(b.rfind('*', 1), Common::String::npos);
|
||||
}
|
||||
|
||||
void test_setChar() {
|
||||
Common::String testString("123456");
|
||||
testString.setChar('2', 0);
|
||||
TS_ASSERT(testString == "223456");
|
||||
testString.setChar('0', 5);
|
||||
TS_ASSERT(testString == "223450");
|
||||
}
|
||||
|
||||
void test_insertChar() {
|
||||
Common::String testString("123456");
|
||||
testString.insertChar('2', 0);
|
||||
TS_ASSERT(testString == "2123456");
|
||||
testString.insertChar('0', 5);
|
||||
TS_ASSERT(testString == "21234056");
|
||||
testString.insertChar('7', 8);
|
||||
TS_ASSERT(testString == "212340567");
|
||||
}
|
||||
|
||||
void test_insertString() {
|
||||
Common::String testString("123456");
|
||||
testString.insertString("12", 0);
|
||||
TS_ASSERT(testString == "12123456");
|
||||
testString.insertString("01", 6);
|
||||
TS_ASSERT(testString == "1212340156");
|
||||
testString.insertString("78", 10);
|
||||
TS_ASSERT(testString == "121234015678");
|
||||
}
|
||||
|
||||
void test_comparison() {
|
||||
Common::String a("0123"), ax("01234"), b("0124"), e;
|
||||
TS_ASSERT_EQUALS(a, a);
|
||||
TS_ASSERT_EQUALS(ax, ax);
|
||||
TS_ASSERT_EQUALS(b, b);
|
||||
TS_ASSERT_EQUALS(e, e);
|
||||
|
||||
TS_ASSERT_DIFFERS(a, ax);
|
||||
TS_ASSERT_DIFFERS(a, b);
|
||||
TS_ASSERT_DIFFERS(a, e);
|
||||
TS_ASSERT_DIFFERS(ax, b);
|
||||
TS_ASSERT_DIFFERS(ax, e);
|
||||
TS_ASSERT_DIFFERS(b, ax);
|
||||
TS_ASSERT_DIFFERS(b, e);
|
||||
|
||||
TS_ASSERT_LESS_THAN(e, a);
|
||||
TS_ASSERT_LESS_THAN(e, ax);
|
||||
TS_ASSERT_LESS_THAN(e, b);
|
||||
TS_ASSERT_LESS_THAN(a, ax);
|
||||
TS_ASSERT_LESS_THAN(a, b);
|
||||
TS_ASSERT_LESS_THAN(ax, b);
|
||||
}
|
||||
|
||||
void test_ustr_comparison() {
|
||||
Common::U32String a("abc"), b("abd"), c, d("");
|
||||
|
||||
TS_ASSERT_EQUALS(a, a);
|
||||
TS_ASSERT_EQUALS(b, b);
|
||||
|
||||
TS_ASSERT_DIFFERS(a, b);
|
||||
|
||||
TS_ASSERT_LESS_THAN(a, b);
|
||||
|
||||
TS_ASSERT_LESS_THAN_EQUALS(a, b);
|
||||
TS_ASSERT_LESS_THAN_EQUALS(a, a);
|
||||
TS_ASSERT_LESS_THAN_EQUALS(b, b);
|
||||
|
||||
//U32String does not define compare, so test both sides
|
||||
TS_ASSERT(a >= a);
|
||||
TS_ASSERT(b > a);
|
||||
TS_ASSERT(b >= b);
|
||||
TS_ASSERT(b >= a);
|
||||
|
||||
TS_ASSERT(c == d);
|
||||
TS_ASSERT(a > c);
|
||||
TS_ASSERT(c < a);
|
||||
}
|
||||
};
|
||||
46
test/common/stream.h
Normal file
46
test/common/stream.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
|
||||
class ReadLineStreamTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_readline() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c', '\n' };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
char buffer[100];
|
||||
|
||||
TS_ASSERT_DIFFERS((char *)0, ms.readLine(buffer, sizeof(buffer)));
|
||||
TS_ASSERT_EQUALS(0, strcmp(buffer, "ab\n"));
|
||||
|
||||
TS_ASSERT_DIFFERS((char *)0, ms.readLine(buffer, sizeof(buffer)));
|
||||
TS_ASSERT_EQUALS(0, strcmp(buffer, "\n"));
|
||||
|
||||
TS_ASSERT_DIFFERS((char *)0, ms.readLine(buffer, sizeof(buffer)));
|
||||
TS_ASSERT_EQUALS(0, strcmp(buffer, "c\n"));
|
||||
|
||||
TS_ASSERT(!ms.eos());
|
||||
|
||||
TS_ASSERT_EQUALS((char *)0, ms.readLine(buffer, sizeof(buffer)));
|
||||
|
||||
TS_ASSERT(ms.eos());
|
||||
}
|
||||
|
||||
void test_readline2() {
|
||||
byte contents[] = { 'a', 'b', '\n', '\n', 'c' };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
char buffer[100];
|
||||
|
||||
TS_ASSERT_DIFFERS((char *)0, ms.readLine(buffer, sizeof(buffer)));
|
||||
TS_ASSERT_EQUALS(0, strcmp(buffer, "ab\n"));
|
||||
|
||||
TS_ASSERT_DIFFERS((char *)0, ms.readLine(buffer, sizeof(buffer)));
|
||||
TS_ASSERT_EQUALS(0, strcmp(buffer, "\n"));
|
||||
|
||||
TS_ASSERT_DIFFERS((char *)0, ms.readLine(buffer, sizeof(buffer)));
|
||||
TS_ASSERT_EQUALS(0, strcmp(buffer, "c"));
|
||||
|
||||
TS_ASSERT(ms.eos());
|
||||
}
|
||||
};
|
||||
47
test/common/subreadstream.h
Normal file
47
test/common/subreadstream.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "common/memstream.h"
|
||||
#include "common/substream.h"
|
||||
|
||||
class SubReadStreamTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_traverse() {
|
||||
byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Common::MemoryReadStream ms(contents, 10);
|
||||
|
||||
int end = 5;
|
||||
|
||||
Common::SubReadStream srs(&ms, end);
|
||||
|
||||
int i;
|
||||
byte b;
|
||||
for (i = 0; i < end; ++i) {
|
||||
TS_ASSERT(!srs.eos());
|
||||
|
||||
b = srs.readByte();
|
||||
TS_ASSERT_EQUALS(i, b);
|
||||
}
|
||||
|
||||
TS_ASSERT(!srs.eos());
|
||||
b = srs.readByte();
|
||||
TS_ASSERT(srs.eos());
|
||||
}
|
||||
|
||||
void test_safe_eos() {
|
||||
byte contents[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Common::MemoryReadStream ms(contents, sizeof(contents));
|
||||
|
||||
Common::SafeSeekableSubReadStream ssrs1(&ms, 0, sizeof(contents));
|
||||
Common::SafeSeekableSubReadStream ssrs2(&ms, 0, sizeof(contents));
|
||||
|
||||
// Read after the end of the stream of the first sub stream
|
||||
for (int32 i = 0; i <= ssrs1.size(); ++i)
|
||||
ssrs1.readByte();
|
||||
|
||||
// eos should be set for the first sub stream
|
||||
TS_ASSERT(ssrs1.eos());
|
||||
|
||||
// eos should not be set for the second sub stream
|
||||
TS_ASSERT(!ssrs2.eos());
|
||||
}
|
||||
};
|
||||
57
test/common/tokenizer.h
Normal file
57
test/common/tokenizer.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/util.h"
|
||||
#include "common/tokenizer.h"
|
||||
|
||||
class TokenizerTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_nextToken() {
|
||||
|
||||
// test normal behavior
|
||||
Common::StringTokenizer strTokenizer("Now, this is a test!", " ,!");
|
||||
Common::String tokenArray[] = {"Now", "this", "is", "a", "test"};
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(tokenArray); ++i) {
|
||||
// make sure nextToken works correctly
|
||||
TS_ASSERT_EQUALS(tokenArray[i], strTokenizer.nextToken());
|
||||
}
|
||||
TS_ASSERT(strTokenizer.empty());
|
||||
|
||||
// Test edge cases:
|
||||
|
||||
// empty string
|
||||
Common::StringTokenizer s1("");
|
||||
TS_ASSERT_EQUALS("", s1.nextToken());
|
||||
TS_ASSERT(s1.empty());
|
||||
|
||||
// empty delimiter
|
||||
Common::StringTokenizer s2("test String", "");
|
||||
TS_ASSERT_EQUALS("test String", s2.nextToken());
|
||||
|
||||
// string is the delimiter
|
||||
Common::StringTokenizer s3("abc", "abc");
|
||||
TS_ASSERT_EQUALS("", s3.nextToken());
|
||||
TS_ASSERT(s3.empty());
|
||||
|
||||
// consecutive delimiters in the string
|
||||
Common::StringTokenizer s4("strstr,after all!!", "str, !");
|
||||
TS_ASSERT_EQUALS("af", s4.nextToken());
|
||||
}
|
||||
|
||||
void test_resetAndEmpty() {
|
||||
Common::StringTokenizer strTokenizer("Just, another test!", " ,!");
|
||||
|
||||
// test reset()
|
||||
Common::String token1 = strTokenizer.nextToken(); //Just
|
||||
TS_ASSERT_EQUALS(token1, "Just");
|
||||
strTokenizer.reset();
|
||||
Common::String token2 = strTokenizer.nextToken(); //Just
|
||||
TS_ASSERT_EQUALS(token2, "Just");
|
||||
|
||||
// test empty()
|
||||
TS_ASSERT(!strTokenizer.empty());
|
||||
strTokenizer.nextToken(); //another
|
||||
strTokenizer.nextToken(); //test
|
||||
TS_ASSERT(strTokenizer.empty());
|
||||
}
|
||||
|
||||
};
|
||||
253
test/common/util.h
Normal file
253
test/common/util.h
Normal file
@@ -0,0 +1,253 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "common/util.h"
|
||||
|
||||
/**
|
||||
* Test suite for the functions in common/util.h
|
||||
*/
|
||||
class UtilTestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_parsebool_yesno() {
|
||||
|
||||
// First test for the parseBool function.
|
||||
// These are the mixed case yes/no cases that must work
|
||||
|
||||
bool valasbool;
|
||||
bool success;
|
||||
|
||||
Common::String string_1("Yes");
|
||||
success = Common::parseBool(string_1, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 1);
|
||||
TS_ASSERT_EQUALS(valasbool, 1);
|
||||
|
||||
Common::String string_2("nO");
|
||||
success = Common::parseBool(string_2, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 1);
|
||||
TS_ASSERT_EQUALS(valasbool, 0);
|
||||
}
|
||||
|
||||
void test_parsebool_truefalse() {
|
||||
|
||||
// First test for the parseBool function.
|
||||
// These are the mixed case true/false cases that must work
|
||||
|
||||
bool valasbool;
|
||||
bool success;
|
||||
|
||||
Common::String string_3("tRuE");
|
||||
success = Common::parseBool(string_3, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 1);
|
||||
TS_ASSERT_EQUALS(valasbool, 1);
|
||||
|
||||
Common::String string_4("fAlSe");
|
||||
success = Common::parseBool(string_4, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 1);
|
||||
TS_ASSERT_EQUALS(valasbool, 0);
|
||||
}
|
||||
|
||||
void test_parsebool_onezero() {
|
||||
|
||||
// Third test for the parseBool function.
|
||||
// These are the 1/0 cases that must work.
|
||||
// Note that while 'a-z'+0x20 must work just fine,
|
||||
// '0-1'+0x20 should NOT; this is addressed in
|
||||
// parsebool_bad
|
||||
|
||||
bool valasbool;
|
||||
bool success;
|
||||
|
||||
Common::String string_5("1");
|
||||
success = Common::parseBool(string_5, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 1);
|
||||
TS_ASSERT_EQUALS(valasbool, 1);
|
||||
|
||||
Common::String string_6("0");
|
||||
success = Common::parseBool(string_6, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 1);
|
||||
TS_ASSERT_EQUALS(valasbool, 0);
|
||||
|
||||
}
|
||||
|
||||
void test_parsebool_bad() {
|
||||
|
||||
bool valasbool;
|
||||
bool success;
|
||||
|
||||
// Bad cases that should not return success #1:
|
||||
// Random string
|
||||
Common::String string_1("u_f1ght_l1k3_a_c0w");
|
||||
success = Common::parseBool(string_1, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 0);
|
||||
|
||||
// Bad cases that should not return success #2, #3:
|
||||
// The function should NOT accept trailing whitespaces:
|
||||
Common::String string_2(" yes");
|
||||
success = Common::parseBool(string_2, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 0);
|
||||
|
||||
Common::String string_3("yes ");
|
||||
success = Common::parseBool(string_3, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 0);
|
||||
|
||||
// While 'a-z'+0x20 must work just fine,
|
||||
// '0-1'+0x20 should NOT. '2' is not good either.
|
||||
|
||||
Common::String string_4("\x50");
|
||||
success = Common::parseBool(string_4, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 0);
|
||||
|
||||
Common::String string_5("\x51");
|
||||
success = Common::parseBool(string_5, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 0);
|
||||
|
||||
Common::String string_6("2");
|
||||
success = Common::parseBool(string_6, valasbool);
|
||||
TS_ASSERT_EQUALS(success, 0);
|
||||
}
|
||||
|
||||
void test_is_al_num() {
|
||||
|
||||
// Test the isAlnum function
|
||||
// Should return true if and only if the input is an alphanumeric char
|
||||
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('a'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('A'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('z'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('Z'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('1'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('0'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('\xA7'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('$'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum(' '), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('\n'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum('\b'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum(0), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlnum(255), 0);
|
||||
|
||||
}
|
||||
|
||||
void test_is_alpha() {
|
||||
|
||||
// Test the isAlpha function
|
||||
// Should return true if and only if the input is an alphanumeric char
|
||||
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('a'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('A'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('z'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('Z'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('1'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('0'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('\xA7'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('$'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha(' '), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('\n'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha('\b'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha(0), 0);
|
||||
TS_ASSERT_EQUALS(Common::isAlpha(255), 0);
|
||||
|
||||
}
|
||||
|
||||
void test_is_digit() {
|
||||
|
||||
// Test the isDigit function
|
||||
// Should return true if and only if the input is a single digit
|
||||
|
||||
TS_ASSERT_EQUALS(Common::isDigit('a'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('A'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('z'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('Z'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('1'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('0'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('\xA7'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('$'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit(' '), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('\n'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit('\b'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit(0), 0);
|
||||
TS_ASSERT_EQUALS(Common::isDigit(255), 0);
|
||||
|
||||
}
|
||||
|
||||
void test_is_lower() {
|
||||
|
||||
// Test the isLower function
|
||||
// Should return true if and only if the input is a lowercase char
|
||||
|
||||
TS_ASSERT_EQUALS(Common::isLower('a'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isLower('A'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower('z'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isLower('Z'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower('1'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower('0'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower('\xA7'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower('$'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower(' '), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower('\n'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower('\b'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower(0), 0);
|
||||
TS_ASSERT_EQUALS(Common::isLower(255), 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_is_upper() {
|
||||
|
||||
// Test the isUpper function
|
||||
// Should return true if and only if the input is an uppercase char
|
||||
|
||||
TS_ASSERT_EQUALS(Common::isUpper('a'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('A'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('z'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('Z'), 1);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('1'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('0'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('\xA7'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('$'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper(' '), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('\n'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper('\b'), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper(0), 0);
|
||||
TS_ASSERT_EQUALS(Common::isUpper(255), 0);
|
||||
|
||||
}
|
||||
void test_is_space() {
|
||||
// isSpace should return true iff the character is some kind of whitespace
|
||||
// or tab character
|
||||
for (int c = 0; c < 255; c++) {
|
||||
if (c == ' ' || c == '\t' ||
|
||||
c == '\r' || c == '\n' ||
|
||||
c == '\v' || c == '\f') {
|
||||
TS_ASSERT_EQUALS(Common::isSpace(c), 1);
|
||||
} else {
|
||||
TS_ASSERT_EQUALS(Common::isSpace(c), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_is_print() {
|
||||
// isPrint should return true iff the input is a printable ascii char.
|
||||
// That is to say, 0x20 to 0x7E.
|
||||
for (int c = 0; c < 255; c++) {
|
||||
if (c >= 0x20 && c <= 0x7E) {
|
||||
TS_ASSERT_EQUALS(Common::isPrint(c), 1);
|
||||
} else {
|
||||
TS_ASSERT_EQUALS(Common::isPrint(c), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
void test_is_punct() {
|
||||
// isPunct should return true if the input is a punctation ascii char.
|
||||
for (int c = 0; c < 255; c++) {
|
||||
if (c >= 33 && c <= 47) {
|
||||
TS_ASSERT_EQUALS(Common::isPunct(c), 1);
|
||||
} else if (c >= 58 && c <= 64) {
|
||||
TS_ASSERT_EQUALS(Common::isPunct(c), 1);
|
||||
} else if (c >= 91 && c <= 96) {
|
||||
TS_ASSERT_EQUALS(Common::isPunct(c), 1);
|
||||
} else if (c >= 123 && c <= 126) {
|
||||
TS_ASSERT_EQUALS(Common::isPunct(c), 1);
|
||||
} else {
|
||||
TS_ASSERT_EQUALS(Common::isPunct(c), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user