better testing
This commit is contained in:
+1
-1
@@ -4,4 +4,4 @@ echo "======================="
|
||||
echo " "
|
||||
echo "Compiling FPC Sources..."
|
||||
echo " "
|
||||
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/include/data_structures/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
|
||||
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/include/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
|
||||
@@ -24,9 +24,9 @@ unit bheap;
|
||||
interface
|
||||
|
||||
uses
|
||||
lmemorymanager,
|
||||
dstypes,
|
||||
util;
|
||||
dstypes,
|
||||
lmemorymanager,
|
||||
util;
|
||||
|
||||
{** Creates a new BinaryHeap.
|
||||
@param ElementSize Size (in bytes) of each data element.
|
||||
|
||||
@@ -87,8 +87,14 @@ uses
|
||||
**}
|
||||
procedure CFIFO_Free(Queue : PCFIFOQueue);
|
||||
|
||||
{** Runs unit tests for the contiguous FIFO queue. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings;
|
||||
|
||||
{ ---------------------------------------------------------------------------- }
|
||||
{ Internal helpers }
|
||||
{ ---------------------------------------------------------------------------- }
|
||||
@@ -222,4 +228,101 @@ begin
|
||||
kfree(void(Queue));
|
||||
end;
|
||||
|
||||
procedure UnitTest;
|
||||
var
|
||||
q : PCFIFOQueue;
|
||||
v, r : uint32;
|
||||
ok : boolean;
|
||||
p : void;
|
||||
i : uint32;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('CFIFO', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('CFIFO', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('CFIFO', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty / Size / Capacity === }
|
||||
q := CFIFO_New(sizeof(uint32), 4);
|
||||
Assert(q <> nil, 'New returns non-nil');
|
||||
Assert(CFIFO_IsEmpty(q), 'Initially empty');
|
||||
Assert(CFIFO_Size(q) = 0, 'Initial size is 0');
|
||||
Assert(CFIFO_Capacity(q) = 4, 'Initial capacity is 4');
|
||||
|
||||
{ === Fill initial capacity === }
|
||||
for i := 1 to 4 do
|
||||
begin
|
||||
v := i * 10;
|
||||
CFIFO_Enqueue(q, @v);
|
||||
end;
|
||||
Assert(CFIFO_Size(q) = 4, 'Size after 4 enqueues');
|
||||
|
||||
{ === Dequeue first two to advance Head === }
|
||||
ok := CFIFO_Dequeue(q, @r);
|
||||
Assert(ok, 'Dequeue 1 succeeds');
|
||||
Assert(r = 10, 'Dequeue 1 value');
|
||||
ok := CFIFO_Dequeue(q, @r);
|
||||
Assert(ok, 'Dequeue 2 succeeds');
|
||||
Assert(r = 20, 'Dequeue 2 value');
|
||||
Assert(CFIFO_Size(q) = 2, 'Size after 2 dequeues');
|
||||
|
||||
{ === Enqueue more to trigger compaction/growth === }
|
||||
for i := 5 to 8 do
|
||||
begin
|
||||
v := i * 10;
|
||||
CFIFO_Enqueue(q, @v);
|
||||
end;
|
||||
Assert(CFIFO_Size(q) = 6, 'Size after grow');
|
||||
|
||||
{ === Verify FIFO order: 30,40,50,60,70,80 === }
|
||||
ok := CFIFO_Dequeue(q, @r); Assert(r = 30, 'Order 30');
|
||||
ok := CFIFO_Dequeue(q, @r); Assert(r = 40, 'Order 40');
|
||||
ok := CFIFO_Dequeue(q, @r); Assert(r = 50, 'Order 50');
|
||||
ok := CFIFO_Dequeue(q, @r); Assert(r = 60, 'Order 60');
|
||||
ok := CFIFO_Dequeue(q, @r); Assert(r = 70, 'Order 70');
|
||||
ok := CFIFO_Dequeue(q, @r); Assert(r = 80, 'Order 80');
|
||||
Assert(CFIFO_IsEmpty(q), 'Empty after drain');
|
||||
|
||||
{ === Edge: peek/dequeue on empty === }
|
||||
p := CFIFO_Peek(q);
|
||||
Assert(p = nil, 'Peek on empty returns nil');
|
||||
ok := CFIFO_Dequeue(q, @r);
|
||||
Assert(not ok, 'Dequeue on empty returns false');
|
||||
|
||||
CFIFO_Free(q);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -92,8 +92,14 @@ uses
|
||||
**}
|
||||
procedure CFIFOLS_FreeAll(List : PCFIFOList);
|
||||
|
||||
{** Runs unit tests for the contiguous FIFO list. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings;
|
||||
|
||||
{ ---------------------------------------------------------------------------- }
|
||||
{ Internal helpers }
|
||||
{ ---------------------------------------------------------------------------- }
|
||||
@@ -220,4 +226,98 @@ begin
|
||||
kfree(void(List));
|
||||
end;
|
||||
|
||||
procedure UnitTest;
|
||||
var
|
||||
ls : PCFIFOList;
|
||||
q1 : PCFIFOQueue;
|
||||
q2 : PCFIFOQueue;
|
||||
q3 : PCFIFOQueue;
|
||||
got : PCFIFOQueue;
|
||||
ok : boolean;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('CFIFOLS', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('CFIFOLS', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('CFIFOLS', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty / Count === }
|
||||
ls := CFIFOLS_New(2);
|
||||
Assert(ls <> nil, 'New returns non-nil');
|
||||
Assert(CFIFOLS_IsEmpty(ls), 'Initially empty');
|
||||
Assert(CFIFOLS_Count(ls) = 0, 'Initial count is 0');
|
||||
|
||||
q1 := CFIFO_New(sizeof(uint32), 4);
|
||||
q2 := CFIFO_New(sizeof(uint32), 4);
|
||||
q3 := CFIFO_New(sizeof(uint32), 4);
|
||||
|
||||
{ === Add / Get === }
|
||||
CFIFOLS_Add(ls, q1);
|
||||
CFIFOLS_Add(ls, q2);
|
||||
CFIFOLS_Add(ls, q3);
|
||||
Assert(CFIFOLS_Count(ls) = 3, 'Count after 3 adds');
|
||||
Assert(CFIFOLS_Get(ls, 0) = q1, 'Get(0) returns q1');
|
||||
Assert(CFIFOLS_Get(ls, 1) = q2, 'Get(1) returns q2');
|
||||
Assert(CFIFOLS_Get(ls, 2) = q3, 'Get(2) returns q3');
|
||||
|
||||
{ === Out-of-bounds Get === }
|
||||
got := CFIFOLS_Get(ls, 99);
|
||||
Assert(got = nil, 'Get out-of-bounds returns nil');
|
||||
|
||||
{ === Remove middle === }
|
||||
ok := CFIFOLS_Remove(ls, 1);
|
||||
Assert(ok, 'Remove(1) succeeds');
|
||||
Assert(CFIFOLS_Count(ls) = 2, 'Count after remove');
|
||||
Assert(CFIFOLS_Get(ls, 0) = q1, 'After remove, Get(0) still q1');
|
||||
Assert(CFIFOLS_Get(ls, 1) = q3, 'After remove, Get(1) is now q3');
|
||||
|
||||
{ === Remove out-of-bounds === }
|
||||
ok := CFIFOLS_Remove(ls, 99);
|
||||
Assert(not ok, 'Remove out-of-bounds returns false');
|
||||
|
||||
CFIFOLS_Free(ls);
|
||||
CFIFO_Free(q1);
|
||||
CFIFO_Free(q2);
|
||||
CFIFO_Free(q3);
|
||||
|
||||
{ === FreeAll path === }
|
||||
ls := CFIFOLS_New(2);
|
||||
CFIFOLS_Add(ls, CFIFO_New(sizeof(uint32), 4));
|
||||
CFIFOLS_Add(ls, CFIFO_New(sizeof(uint32), 4));
|
||||
CFIFOLS_FreeAll(ls);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -88,8 +88,14 @@ uses
|
||||
**}
|
||||
procedure circ_Free(Queue : PCircularQueue);
|
||||
|
||||
{** Runs unit tests for the circular queue. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings;
|
||||
|
||||
function circ_New(Capacity : uint32; ElementSize : uint32) : PCircularQueue;
|
||||
begin
|
||||
circ_New := PCircularQueue(kalloc(sizeof(TCircularQueue)));
|
||||
@@ -162,4 +168,102 @@ begin
|
||||
kfree(void(Queue));
|
||||
end;
|
||||
|
||||
procedure UnitTest;
|
||||
var
|
||||
q : PCircularQueue;
|
||||
v, r : uint32;
|
||||
ok : boolean;
|
||||
p : void;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('CIRC', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('CIRC', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('CIRC', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty / Full / Size === }
|
||||
q := circ_New(4, sizeof(uint32));
|
||||
Assert(q <> nil, 'New returns non-nil');
|
||||
Assert(circ_IsEmpty(q), 'Initially empty');
|
||||
Assert(not circ_IsFull(q), 'Initially not full');
|
||||
Assert(circ_Size(q) = 0, 'Initial size is 0');
|
||||
|
||||
{ === Fill to capacity === }
|
||||
v := 100; ok := circ_Enqueue(q, @v); Assert(ok, 'Enqueue 1 ok');
|
||||
v := 200; ok := circ_Enqueue(q, @v); Assert(ok, 'Enqueue 2 ok');
|
||||
v := 300; ok := circ_Enqueue(q, @v); Assert(ok, 'Enqueue 3 ok');
|
||||
v := 400; ok := circ_Enqueue(q, @v); Assert(ok, 'Enqueue 4 ok');
|
||||
Assert(circ_IsFull(q), 'Full after 4 enqueues');
|
||||
Assert(circ_Size(q) = 4, 'Size is 4 when full');
|
||||
|
||||
{ === Enqueue when full === }
|
||||
v := 999;
|
||||
ok := circ_Enqueue(q, @v);
|
||||
Assert(not ok, 'Enqueue on full returns false');
|
||||
|
||||
{ === Peek === }
|
||||
p := circ_Peek(q);
|
||||
Assert(p <> nil, 'Peek non-nil');
|
||||
Assert(uint32(p^) = 100, 'Peek returns first enqueued');
|
||||
|
||||
{ === Dequeue all — FIFO order === }
|
||||
ok := circ_Dequeue(q, @r); Assert(r = 100, 'Dequeue 1 value');
|
||||
ok := circ_Dequeue(q, @r); Assert(r = 200, 'Dequeue 2 value');
|
||||
ok := circ_Dequeue(q, @r); Assert(r = 300, 'Dequeue 3 value');
|
||||
ok := circ_Dequeue(q, @r); Assert(r = 400, 'Dequeue 4 value');
|
||||
Assert(circ_IsEmpty(q), 'Empty after all dequeued');
|
||||
|
||||
{ === Edge: dequeue/peek on empty === }
|
||||
ok := circ_Dequeue(q, @r);
|
||||
Assert(not ok, 'Dequeue on empty returns false');
|
||||
p := circ_Peek(q);
|
||||
Assert(p = nil, 'Peek on empty returns nil');
|
||||
|
||||
{ === Wrap-around === }
|
||||
v := 1; circ_Enqueue(q, @v);
|
||||
v := 2; circ_Enqueue(q, @v);
|
||||
circ_Dequeue(q, @r);
|
||||
v := 3; circ_Enqueue(q, @v);
|
||||
v := 4; circ_Enqueue(q, @v);
|
||||
circ_Dequeue(q, @r); Assert(r = 2, 'Wraparound order 2');
|
||||
circ_Dequeue(q, @r); Assert(r = 3, 'Wraparound order 3');
|
||||
circ_Dequeue(q, @r); Assert(r = 4, 'Wraparound order 4');
|
||||
Assert(circ_IsEmpty(q), 'Empty after wraparound');
|
||||
|
||||
circ_Free(q);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -79,8 +79,14 @@ uses
|
||||
**}
|
||||
procedure FIFO_Free(Queue : PFIFOQueue);
|
||||
|
||||
{** Runs unit tests for the FIFO queue. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings;
|
||||
|
||||
function FIFO_New(ElementSize : uint32) : PFIFOQueue;
|
||||
begin
|
||||
FIFO_New := PFIFOQueue(kalloc(sizeof(TFIFOQueue)));
|
||||
@@ -162,4 +168,92 @@ begin
|
||||
kfree(void(Queue));
|
||||
end;
|
||||
|
||||
procedure UnitTest;
|
||||
var
|
||||
q : PFIFOQueue;
|
||||
v, r : uint32;
|
||||
ok : boolean;
|
||||
p : void;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('FIFO', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('FIFO', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('FIFO', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty / Size === }
|
||||
q := FIFO_New(sizeof(uint32));
|
||||
Assert(q <> nil, 'New returns non-nil');
|
||||
Assert(FIFO_IsEmpty(q), 'Initially empty');
|
||||
Assert(FIFO_Size(q) = 0, 'Initial size is 0');
|
||||
|
||||
{ === Enqueue / Size === }
|
||||
v := 10; FIFO_Enqueue(q, @v);
|
||||
v := 20; FIFO_Enqueue(q, @v);
|
||||
v := 30; FIFO_Enqueue(q, @v);
|
||||
Assert(FIFO_Size(q) = 3, 'Size after 3 enqueues');
|
||||
Assert(not FIFO_IsEmpty(q), 'Not empty after enqueue');
|
||||
|
||||
{ === Peek === }
|
||||
p := FIFO_Peek(q);
|
||||
Assert(p <> nil, 'Peek non-nil');
|
||||
Assert(uint32(p^) = 10, 'Peek returns first enqueued');
|
||||
|
||||
{ === Dequeue order === }
|
||||
ok := FIFO_Dequeue(q, @r);
|
||||
Assert(ok, 'Dequeue 1 succeeds');
|
||||
Assert(r = 10, 'Dequeue 1 value');
|
||||
|
||||
ok := FIFO_Dequeue(q, @r);
|
||||
Assert(ok, 'Dequeue 2 succeeds');
|
||||
Assert(r = 20, 'Dequeue 2 value');
|
||||
|
||||
ok := FIFO_Dequeue(q, @r);
|
||||
Assert(ok, 'Dequeue 3 succeeds');
|
||||
Assert(r = 30, 'Dequeue 3 value');
|
||||
|
||||
Assert(FIFO_IsEmpty(q), 'Empty after all dequeued');
|
||||
|
||||
{ === Edge: dequeue/peek on empty === }
|
||||
ok := FIFO_Dequeue(q, @r);
|
||||
Assert(not ok, 'Dequeue on empty returns false');
|
||||
p := FIFO_Peek(q);
|
||||
Assert(p = nil, 'Peek on empty returns nil');
|
||||
|
||||
FIFO_Free(q);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -79,8 +79,14 @@ uses
|
||||
**}
|
||||
procedure lifo_Free(Stack : PLIFOStack);
|
||||
|
||||
{** Runs unit tests for the LIFO stack. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings;
|
||||
|
||||
function lifo_New(ElementSize : uint32) : PLIFOStack;
|
||||
begin
|
||||
lifo_New := PLIFOStack(kalloc(sizeof(TLIFOStack)));
|
||||
@@ -152,4 +158,91 @@ begin
|
||||
kfree(void(Stack));
|
||||
end;
|
||||
|
||||
procedure UnitTest;
|
||||
var
|
||||
s : PLIFOStack;
|
||||
v, r : uint32;
|
||||
ok : boolean;
|
||||
p : void;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('LIFO', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('LIFO', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('LIFO', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty / Size === }
|
||||
s := lifo_New(sizeof(uint32));
|
||||
Assert(s <> nil, 'New returns non-nil');
|
||||
Assert(lifo_IsEmpty(s), 'Initially empty');
|
||||
Assert(lifo_Size(s) = 0, 'Initial size is 0');
|
||||
|
||||
{ === Push / Size === }
|
||||
v := 10; lifo_Push(s, @v);
|
||||
v := 20; lifo_Push(s, @v);
|
||||
v := 30; lifo_Push(s, @v);
|
||||
Assert(lifo_Size(s) = 3, 'Size after 3 pushes');
|
||||
|
||||
{ === Peek (should return last pushed) === }
|
||||
p := lifo_Peek(s);
|
||||
Assert(p <> nil, 'Peek non-nil');
|
||||
Assert(uint32(p^) = 30, 'Peek returns last pushed');
|
||||
|
||||
{ === Pop order (reverse) === }
|
||||
ok := lifo_Pop(s, @r);
|
||||
Assert(ok, 'Pop 1 succeeds');
|
||||
Assert(r = 30, 'Pop 1 value');
|
||||
|
||||
ok := lifo_Pop(s, @r);
|
||||
Assert(ok, 'Pop 2 succeeds');
|
||||
Assert(r = 20, 'Pop 2 value');
|
||||
|
||||
ok := lifo_Pop(s, @r);
|
||||
Assert(ok, 'Pop 3 succeeds');
|
||||
Assert(r = 10, 'Pop 3 value');
|
||||
|
||||
Assert(lifo_IsEmpty(s), 'Empty after all popped');
|
||||
|
||||
{ === Edge: pop/peek on empty === }
|
||||
ok := lifo_Pop(s, @r);
|
||||
Assert(not ok, 'Pop on empty returns false');
|
||||
p := lifo_Peek(s);
|
||||
Assert(p = nil, 'Peek on empty returns nil');
|
||||
|
||||
lifo_Free(s);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -80,8 +80,14 @@ uses
|
||||
**}
|
||||
procedure maxh_Free(Heap : PBinaryHeap);
|
||||
|
||||
{** Runs unit tests for the max-heap. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings, lmemorymanager;
|
||||
|
||||
function maxh_New(ElementSize : uint32; InitialCapacity : uint32) : PBinaryHeap;
|
||||
begin
|
||||
maxh_New := BHeap_New(ElementSize, InitialCapacity, false);
|
||||
@@ -117,4 +123,85 @@ begin
|
||||
BHeap_Free(Heap);
|
||||
end;
|
||||
|
||||
end.
|
||||
procedure UnitTest;
|
||||
var
|
||||
h : PBinaryHeap;
|
||||
v, r : uint32;
|
||||
ok : boolean;
|
||||
p : void;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('MAXH', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('MAXH', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('MAXH', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty === }
|
||||
h := maxh_New(sizeof(uint32), 4);
|
||||
Assert(h <> nil, 'New returns non-nil');
|
||||
Assert(maxh_IsEmpty(h), 'Initially empty');
|
||||
|
||||
{ === Insert out of order === }
|
||||
v := 30; maxh_Insert(h, 30, @v);
|
||||
v := 10; maxh_Insert(h, 10, @v);
|
||||
v := 50; maxh_Insert(h, 50, @v);
|
||||
v := 20; maxh_Insert(h, 20, @v);
|
||||
v := 40; maxh_Insert(h, 40, @v);
|
||||
Assert(maxh_Size(h) = 5, 'Size after 5 inserts');
|
||||
|
||||
{ === PeekMax === }
|
||||
p := maxh_PeekMax(h);
|
||||
Assert(p <> nil, 'PeekMax non-nil');
|
||||
Assert(uint32(p^) = 50, 'PeekMax returns 50');
|
||||
|
||||
{ === ExtractMax in descending order === }
|
||||
ok := maxh_ExtractMax(h, @r); Assert(ok, 'Extract 1 ok'); Assert(r = 50, 'Extract 50');
|
||||
ok := maxh_ExtractMax(h, @r); Assert(ok, 'Extract 2 ok'); Assert(r = 40, 'Extract 40');
|
||||
ok := maxh_ExtractMax(h, @r); Assert(ok, 'Extract 3 ok'); Assert(r = 30, 'Extract 30');
|
||||
ok := maxh_ExtractMax(h, @r); Assert(ok, 'Extract 4 ok'); Assert(r = 20, 'Extract 20');
|
||||
ok := maxh_ExtractMax(h, @r); Assert(ok, 'Extract 5 ok'); Assert(r = 10, 'Extract 10');
|
||||
Assert(maxh_IsEmpty(h), 'Empty after all extracted');
|
||||
|
||||
{ === Edge: extract/peek on empty === }
|
||||
ok := maxh_ExtractMax(h, @r);
|
||||
Assert(not ok, 'Extract on empty returns false');
|
||||
p := maxh_PeekMax(h);
|
||||
Assert(p = nil, 'PeekMax on empty returns nil');
|
||||
|
||||
maxh_Free(h);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -80,8 +80,14 @@ uses
|
||||
**}
|
||||
procedure minh_Free(Heap : PBinaryHeap);
|
||||
|
||||
{** Runs unit tests for the min-heap. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings, lmemorymanager;
|
||||
|
||||
function minh_New(ElementSize : uint32; InitialCapacity : uint32) : PBinaryHeap;
|
||||
begin
|
||||
minh_New := BHeap_New(ElementSize, InitialCapacity, true);
|
||||
@@ -117,4 +123,105 @@ begin
|
||||
BHeap_Free(Heap);
|
||||
end;
|
||||
|
||||
end.
|
||||
procedure UnitTest;
|
||||
var
|
||||
h : PBinaryHeap;
|
||||
v, r : uint32;
|
||||
ok : boolean;
|
||||
p : void;
|
||||
i : uint32;
|
||||
good : boolean;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('MINH', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('MINH', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('MINH', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty / Size === }
|
||||
h := minh_New(sizeof(uint32), 4);
|
||||
Assert(h <> nil, 'New returns non-nil');
|
||||
Assert(minh_IsEmpty(h), 'Initially empty');
|
||||
Assert(minh_Size(h) = 0, 'Initial size is 0');
|
||||
|
||||
{ === Insert out of order === }
|
||||
v := 30; minh_Insert(h, 30, @v);
|
||||
v := 10; minh_Insert(h, 10, @v);
|
||||
v := 50; minh_Insert(h, 50, @v);
|
||||
v := 20; minh_Insert(h, 20, @v);
|
||||
v := 40; minh_Insert(h, 40, @v);
|
||||
Assert(minh_Size(h) = 5, 'Size after 5 inserts');
|
||||
|
||||
{ === PeekMin === }
|
||||
p := minh_PeekMin(h);
|
||||
Assert(p <> nil, 'PeekMin non-nil');
|
||||
Assert(uint32(p^) = 10, 'PeekMin returns 10');
|
||||
|
||||
{ === ExtractMin in ascending order === }
|
||||
ok := minh_ExtractMin(h, @r); Assert(ok, 'Extract 1 ok'); Assert(r = 10, 'Extract 10');
|
||||
ok := minh_ExtractMin(h, @r); Assert(ok, 'Extract 2 ok'); Assert(r = 20, 'Extract 20');
|
||||
ok := minh_ExtractMin(h, @r); Assert(ok, 'Extract 3 ok'); Assert(r = 30, 'Extract 30');
|
||||
ok := minh_ExtractMin(h, @r); Assert(ok, 'Extract 4 ok'); Assert(r = 40, 'Extract 40');
|
||||
ok := minh_ExtractMin(h, @r); Assert(ok, 'Extract 5 ok'); Assert(r = 50, 'Extract 50');
|
||||
Assert(minh_IsEmpty(h), 'Empty after all extracted');
|
||||
|
||||
{ === Edge: extract/peek on empty === }
|
||||
ok := minh_ExtractMin(h, @r);
|
||||
Assert(not ok, 'Extract on empty returns false');
|
||||
p := minh_PeekMin(h);
|
||||
Assert(p = nil, 'PeekMin on empty returns nil');
|
||||
|
||||
minh_Free(h);
|
||||
|
||||
{ === Stress: 50 elements reverse insert === }
|
||||
h := minh_New(sizeof(uint32), 4);
|
||||
for i := 50 downto 1 do
|
||||
begin
|
||||
v := i;
|
||||
minh_Insert(h, i, @v);
|
||||
end;
|
||||
Assert(minh_Size(h) = 50, 'Stress: 50 inserted');
|
||||
good := true;
|
||||
for i := 1 to 50 do
|
||||
begin
|
||||
ok := minh_ExtractMin(h, @r);
|
||||
if (not ok) or (r <> i) then good := false;
|
||||
end;
|
||||
Assert(good, 'Stress: 50 extracted in ascending order');
|
||||
minh_Free(h);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -81,8 +81,14 @@ uses
|
||||
**}
|
||||
procedure prio_Free(Heap : PBinaryHeap);
|
||||
|
||||
{** Runs unit tests for the priority queue. **}
|
||||
procedure UnitTest;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
syslog, strings, lmemorymanager;
|
||||
|
||||
function prio_New(ElementSize : uint32; InitialCapacity : uint32) : PBinaryHeap;
|
||||
begin
|
||||
prio_New := BHeap_New(ElementSize, InitialCapacity, true);
|
||||
@@ -118,4 +124,85 @@ begin
|
||||
BHeap_Free(Heap);
|
||||
end;
|
||||
|
||||
end.
|
||||
procedure UnitTest;
|
||||
var
|
||||
h : PBinaryHeap;
|
||||
v, r : uint32;
|
||||
ok : boolean;
|
||||
p : void;
|
||||
passed, failed : uint32;
|
||||
|
||||
procedure Assert(condition : boolean; testName : pchar);
|
||||
var
|
||||
msg : pchar;
|
||||
begin
|
||||
if condition then begin
|
||||
inc(passed);
|
||||
end else begin
|
||||
inc(failed);
|
||||
msg := stringConcat('FAIL: ', testName);
|
||||
syslog.logln('PRIO', msg);
|
||||
kfree(void(msg));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure PrintSummary;
|
||||
var
|
||||
pStr, fStr, msg, tmp : pchar;
|
||||
begin
|
||||
pStr := intToString(passed);
|
||||
fStr := intToString(failed);
|
||||
msg := stringConcat(pStr, ' passed, ');
|
||||
tmp := stringConcat(msg, fStr);
|
||||
kfree(void(msg));
|
||||
msg := stringConcat(tmp, ' failed.');
|
||||
kfree(void(tmp));
|
||||
syslog.logln('PRIO', msg);
|
||||
kfree(void(msg));
|
||||
kfree(void(pStr));
|
||||
kfree(void(fStr));
|
||||
end;
|
||||
|
||||
begin
|
||||
passed := 0;
|
||||
failed := 0;
|
||||
syslog.logln('PRIO', 'Unit tests starting...');
|
||||
|
||||
{ === New / Empty === }
|
||||
h := prio_New(sizeof(uint32), 4);
|
||||
Assert(h <> nil, 'New returns non-nil');
|
||||
Assert(prio_IsEmpty(h), 'Initially empty');
|
||||
|
||||
{ === Enqueue with varying priorities === }
|
||||
v := 300; prio_Enqueue(h, 3, @v);
|
||||
v := 100; prio_Enqueue(h, 1, @v);
|
||||
v := 500; prio_Enqueue(h, 5, @v);
|
||||
v := 200; prio_Enqueue(h, 2, @v);
|
||||
v := 400; prio_Enqueue(h, 4, @v);
|
||||
Assert(prio_Size(h) = 5, 'Size after 5 enqueues');
|
||||
|
||||
{ === Peek (highest priority = lowest value) === }
|
||||
p := prio_Peek(h);
|
||||
Assert(p <> nil, 'Peek non-nil');
|
||||
Assert(uint32(p^) = 100, 'Peek returns data with priority 1');
|
||||
|
||||
{ === Dequeue by priority 1,2,3,4,5 === }
|
||||
ok := prio_Dequeue(h, @r); Assert(ok, 'Dequeue 1 ok'); Assert(r = 100, 'Dequeue pri=1');
|
||||
ok := prio_Dequeue(h, @r); Assert(ok, 'Dequeue 2 ok'); Assert(r = 200, 'Dequeue pri=2');
|
||||
ok := prio_Dequeue(h, @r); Assert(ok, 'Dequeue 3 ok'); Assert(r = 300, 'Dequeue pri=3');
|
||||
ok := prio_Dequeue(h, @r); Assert(ok, 'Dequeue 4 ok'); Assert(r = 400, 'Dequeue pri=4');
|
||||
ok := prio_Dequeue(h, @r); Assert(ok, 'Dequeue 5 ok'); Assert(r = 500, 'Dequeue pri=5');
|
||||
Assert(prio_IsEmpty(h), 'Empty after all dequeued');
|
||||
|
||||
{ === Edge: dequeue/peek on empty === }
|
||||
ok := prio_Dequeue(h, @r);
|
||||
Assert(not ok, 'Dequeue on empty returns false');
|
||||
p := prio_Peek(h);
|
||||
Assert(p = nil, 'Peek on empty returns nil');
|
||||
|
||||
prio_Free(h);
|
||||
|
||||
PrintSummary;
|
||||
end;
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
+10
-1
@@ -67,7 +67,8 @@ uses
|
||||
hashmap, vfs,
|
||||
video, vesa, doublebuffer, color, lvgl, desktop, uidebug,
|
||||
vterminal,
|
||||
graphicsrefresh, usbhotplug;
|
||||
graphicsrefresh, usbhotplug,
|
||||
fifo, cfifo, cfifols, lifo, circ, minh, maxh, prio;
|
||||
|
||||
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
|
||||
|
||||
@@ -271,6 +272,14 @@ begin
|
||||
usbhub.UnitTest;
|
||||
usb_keyboard.UnitTest;
|
||||
usb_mouse.UnitTest;
|
||||
fifo.UnitTest;
|
||||
cfifo.UnitTest;
|
||||
cfifols.UnitTest;
|
||||
lifo.UnitTest;
|
||||
circ.UnitTest;
|
||||
minh.UnitTest;
|
||||
maxh.UnitTest;
|
||||
prio.UnitTest;
|
||||
|
||||
{ Register timer-driven tasks }
|
||||
graphicsrefresh.init;
|
||||
|
||||
Reference in New Issue
Block a user