Browse Source

Add tests for `ArrayList`/`HashTable` iterators

pull/8/head
Anton Tarasenko 2 years ago
parent
commit
6a0eda9362
  1. 174
      sources/Data/Collections/Tests/TEST_Iterator.uc
  2. 142
      sources/Data/Collections/Tests/TEST_IteratorOld.uc

174
sources/Data/Collections/Tests/TEST_Iterator.uc

@ -1,6 +1,6 @@
/**
* Set of tests for `Iterator` classes.
* Copyright 2020 Anton Tarasenko
* Copyright 2022 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
@ -28,6 +28,7 @@ protected static function CreateItems()
{
local int i;
ResetFlags();
default.items.length = 0;
for (i = 0; i < default.TESTED_ITEMS_AMOUNT; i += 1) {
default.items[default.items.length] = __().ref.float(i*2 + 1/i);
}
@ -39,15 +40,30 @@ protected static function ResetFlags()
default.seenFlags.length = default.TESTED_ITEMS_AMOUNT;
}
protected static function DoTestIterator(Iter iter)
protected static function DoTestIterator(
string issueSubjectAllocation,
string issueSubjectAmount,
Iter iter)
{
local int i;
local int seenCount;
local AcediaObject nextObject;
ResetFlags();
Issue(issueSubjectAllocation);
while (!iter.HasFinished())
{
nextObject = iter.Get();
// Create + insert into collection + get reference
TEST_ExpectTrue(nextObject._getRefCount() == 3);
if (iter.class == class'ArrayListIterator') {
// `ArrayList` creates keys to return on-the-fly
TEST_ExpectTrue(iter.GetKey()._getRefCount() == 1);
}
else {
// Create + insert into collection + get reference
TEST_ExpectTrue(iter.GetKey()._getRefCount() == 3);
}
for (i = 0; i < default.items.length; i += 1)
{
if (default.items[i] == nextObject)
@ -61,33 +77,35 @@ protected static function DoTestIterator(Iter iter)
}
iter.Next();
}
Issue(issueSubjectAmount);
TEST_ExpectTrue(seenCount == default.TESTED_ITEMS_AMOUNT);
}
protected static function TESTS()
{
// Prepare
CreateItems();
// Test
Test_DynamicArray();
Test_AssociativeArray();
Test_ArrayList();
CreateItems();
Test_HashTable();
Test_IterationAndNone();
}
protected static function Test_DynamicArray()
protected static function Test_ArrayList()
{
local int i;
local Iter iter;
local DynamicArray array;
array = DynamicArray(__().memory.Allocate(class'DynamicArray'));
local int i;
local Iter iter;
local ArrayList array;
array = ArrayList(__().memory.Allocate(class'ArrayList'));
iter = array.Iterate();
Context("Testing iterator for `DynamicArray`");
Issue("`DynamicArray` returns `none` iterator.");
Context("Testing iterator for `ArrayList`");
Issue("`ArrayList` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("Iterator for empty `DynamicArray` is not finished by default.");
Issue("Iterator for empty `ArrayList` is not finished by default.");
TEST_ExpectTrue(iter.HasFinished());
Issue("Iterator for empty `DynamicArray` does not return `none` as"
Issue("Iterator for empty `ArrayList` does not return `none` as"
@ "a current item.");
TEST_ExpectNone(iter.Get());
TEST_ExpectNone(iter.Next().Get());
@ -96,28 +114,32 @@ protected static function Test_DynamicArray()
array.AddItem(default.items[i]);
}
iter = array.Iterate();
Issue("`DynamicArray` returns `none` iterator.");
Issue("`ArrayList` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("`DynamicArray`'s iterator iterates over incorrect set of items.");
DoTestIterator(iter);
Issue("`ArrayList`'s iterator iterates over incorrect set of items.");
DoTestIterator(
"`ArrayList`'s iterator incorrectly handles reference counting.",
"`ArrayList`'s iterator iterates over incorrect set of items.",
iter);
}
protected static function Test_AssociativeArray()
protected static function Test_HashTable()
{
local int i;
local Iter iter;
local AssociativeArray array;
array = AssociativeArray(__().memory.Allocate(class'AssociativeArray'));
local int i;
local Iter iter;
local HashTable array;
array = HashTable(__().memory.Allocate(class'HashTable'));
iter = array.Iterate();
Context("Testing iterator for `AssociativeArray`");
Issue("`AssociativeArray` returns `none` iterator.");
Context("Testing iterator for `HashTable`");
Issue("`HashTable` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("Iterator for empty `AssociativeArray` is not finished by default.");
Issue("Iterator for empty `HashTable` is not finished by default.");
TEST_ExpectTrue(iter.HasFinished());
Issue("Iterator for empty `AssociativeArray` does not return `none` as"
Issue("Iterator for empty `HashTable` does not return `none` as"
@ "a current item.");
TEST_ExpectNone(iter.Get());
TEST_ExpectNone(iter.Next().Get());
@ -126,17 +148,103 @@ protected static function Test_AssociativeArray()
array.SetItem(__().box.int(i), default.items[i]);
}
iter = array.Iterate();
Issue("`AssociativeArray` returns `none` iterator.");
Issue("`HashTable` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("`AssociativeArray`'s iterator iterates over incorrect set of"
@ "items.");
DoTestIterator(iter);
DoTestIterator(
"`HashTable`'s iterator incorrectly handles reference counting.",
"`HashTable`'s iterator iterates over incorrect set of items.",
iter);
}
protected static function Test_IterationAndNone()
{
Context("Testing how collections iterate over `none` references.");
SubTest_ArrayListIterationAndNone();
SubTest_HashTableIterationAndNone();
}
protected static function SubTest_ArrayListIterationAndNone()
{
local bool sawNone;
local int counter;
local Iter iter;
local ArrayList list;
list = __().collections.EmptyArrayList();
list.AddItem(__().box.int(1));
list.AddItem(none);
list.AddItem(__().box.int(3));
list.AddItem(none);
list.AddItem(__().box.int(5));
Issue("`ArrayList` doesn't properly iterate over `none` items by default.");
iter = list.Iterate();
while (!iter.HasFinished())
{
sawNone = sawNone || (iter.Get() == none);
counter += 1;
iter.Next();
}
TEST_ExpectTrue(sawNone);
TEST_ExpectTrue(counter == 5);
Issue("`ArrayList` iterates over `none` items even after"
@ "`LeaveOnlyNotNone()` call.");
sawNone = false;
counter = 0;
iter = list.Iterate().LeaveOnlyNotNone();
while (!iter.HasFinished())
{
sawNone = sawNone || (iter.Get() == none);
counter += 1;
iter.Next();
}
TEST_ExpectFalse(sawNone);
TEST_ExpectTrue(counter == 3);
}
protected static function SubTest_HashTableIterationAndNone()
{
local bool sawNone;
local int counter;
local Iter iter;
local HashTable table;
table = __().collections.EmptyHashTable();
table.SetItem(__().box.float(1.0), __().box.int(1));
table.SetItem(__().box.float(0.3453), none);
table.SetItem(__().box.float(423.3), __().box.int(3));
table.SetItem(__().box.float(7), none);
table.SetItem(__().box.float(1.1), __().box.int(5));
Issue("`HashTable` doesn't properly iterate over `none` items by default.");
iter = table.Iterate();
while (!iter.HasFinished())
{
sawNone = sawNone || (iter.Get() == none);
counter += 1;
iter.Next();
}
TEST_ExpectTrue(sawNone);
TEST_ExpectTrue(counter == 5);
Issue("`HashTable` iterates over `none` items even after"
@ "`LeaveOnlyNotNone()` call.");
sawNone = false;
counter = 0;
iter = table.Iterate().LeaveOnlyNotNone();
while (!iter.HasFinished())
{
sawNone = sawNone || (iter.Get() == none);
counter += 1;
iter.Next();
}
TEST_ExpectFalse(sawNone);
TEST_ExpectTrue(counter == 3);
}
defaultproperties
{
caseGroup = "Collections"
caseName = "Iterator"
caseGroup = "Collections"
caseName = "Iterator"
TESTED_ITEMS_AMOUNT = 100
}

142
sources/Data/Collections/Tests/TEST_IteratorOld.uc

@ -0,0 +1,142 @@
/**
* Set of tests for `Iterator` classes.
* Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
* Acedia is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License, or
* (at your option) any later version.
*
* Acedia is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/
class TEST_IteratorOld extends TestCase
abstract;
var const int TESTED_ITEMS_AMOUNT;
var array<AcediaObject> items;
var array<byte> seenFlags;
protected static function CreateItems()
{
local int i;
ResetFlags();
for (i = 0; i < default.TESTED_ITEMS_AMOUNT; i += 1) {
default.items[default.items.length] = __().ref.float(i*2 + 1/i);
}
}
protected static function ResetFlags()
{
default.seenFlags.length = 0;
default.seenFlags.length = default.TESTED_ITEMS_AMOUNT;
}
protected static function DoTestIterator(Iter iter)
{
local int i;
local int seenCount;
local AcediaObject nextObject;
ResetFlags();
while (!iter.HasFinished())
{
nextObject = iter.Get();
for (i = 0; i < default.items.length; i += 1)
{
if (default.items[i] == nextObject)
{
if (default.seenFlags[i] == 0) {
seenCount += 1;
}
default.seenFlags[i] = 1;
continue;
}
}
iter.Next();
}
TEST_ExpectTrue(seenCount == default.TESTED_ITEMS_AMOUNT);
}
protected static function TESTS()
{
// Prepare
CreateItems();
// Test
Test_DynamicArray();
Test_AssociativeArray();
}
protected static function Test_DynamicArray()
{
local int i;
local Iter iter;
local DynamicArray array;
array = DynamicArray(__().memory.Allocate(class'DynamicArray'));
iter = array.Iterate();
Context("Testing iterator for `DynamicArray`");
Issue("`DynamicArray` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("Iterator for empty `DynamicArray` is not finished by default.");
TEST_ExpectTrue(iter.HasFinished());
Issue("Iterator for empty `DynamicArray` does not return `none` as"
@ "a current item.");
TEST_ExpectNone(iter.Get());
TEST_ExpectNone(iter.Next().Get());
for (i = 0; i < default.items.length; i += 1) {
array.AddItem(default.items[i]);
}
iter = array.Iterate();
Issue("`DynamicArray` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("`DynamicArray`'s iterator iterates over incorrect set of items.");
DoTestIterator(iter);
}
protected static function Test_AssociativeArray()
{
local int i;
local Iter iter;
local AssociativeArray array;
array = AssociativeArray(__().memory.Allocate(class'AssociativeArray'));
iter = array.Iterate();
Context("Testing iterator for `AssociativeArray`");
Issue("`AssociativeArray` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("Iterator for empty `AssociativeArray` is not finished by default.");
TEST_ExpectTrue(iter.HasFinished());
Issue("Iterator for empty `AssociativeArray` does not return `none` as"
@ "a current item.");
TEST_ExpectNone(iter.Get());
TEST_ExpectNone(iter.Next().Get());
for (i = 0; i < default.items.length; i += 1) {
array.SetItem(__().box.int(i), default.items[i]);
}
iter = array.Iterate();
Issue("`AssociativeArray` returns `none` iterator.");
TEST_ExpectNotNone(iter);
Issue("`AssociativeArray`'s iterator iterates over incorrect set of"
@ "items.");
DoTestIterator(iter);
}
defaultproperties
{
caseGroup = "Collections"
caseName = "IteratorOld"
TESTED_ITEMS_AMOUNT = 100
}
Loading…
Cancel
Save