307 lines
7.0 KiB
NASM
307 lines
7.0 KiB
NASM
%include "src/constants.asm"
|
|
|
|
;addTestHeader(var, func)
|
|
%define addTestHeader(var, func) \
|
|
var db NL,"TEST ",func,"()",NL,EOS
|
|
;addTest(var, msg)
|
|
%define addTest(var, msg) \
|
|
var db TAB,msg,":",NL,EOS
|
|
;printTestHeader var
|
|
%macro printTestHeader 1
|
|
lea rdi, [rel %1]
|
|
call print
|
|
%endmacro
|
|
;printTest var
|
|
%macro printTest 1
|
|
lea rdi, [rel %1]
|
|
call printf
|
|
%endmacro
|
|
;assert value, jmp instruction, testMsg_X
|
|
%macro assert 3
|
|
inc r13
|
|
mov rsi, %1
|
|
mov rdx, %1
|
|
mov rcx, rax
|
|
cmp rax, %1
|
|
%2 %%true
|
|
lea r8, [rel testMsg_False]
|
|
jmp %%cnt
|
|
%%true:
|
|
inc r14
|
|
%if TESTS_PRINT_ALL_OUTPUTS
|
|
lea r8, [rel testMsg_True]
|
|
%else
|
|
jmp %%end
|
|
%endif
|
|
%%cnt:
|
|
lea rdi, [rel %3]
|
|
call printf
|
|
%%end:
|
|
nop
|
|
%endmacro
|
|
|
|
;core.asm
|
|
extern exit
|
|
extern islower
|
|
extern isupper
|
|
extern tolower
|
|
extern toupper
|
|
extern min
|
|
extern minu
|
|
extern max
|
|
extern maxu
|
|
extern clamp
|
|
extern clampu
|
|
;console.asm
|
|
extern print
|
|
extern puts
|
|
extern printf
|
|
;string.asm
|
|
extern strlen
|
|
extern strcpy
|
|
extern strcat
|
|
extern strclr
|
|
extern strcmp
|
|
;convert.asm
|
|
extern atoi
|
|
extern itoa
|
|
extern utoa
|
|
|
|
section .rodata
|
|
;;;
|
|
;;; enable/disable tests
|
|
;;;
|
|
TESTS_PRINT_ALL_OUTPUTS equ 1 ;If set to 0, only print expected/got and FAIL if failed. Otherwise always print outputs.
|
|
;Note: when set to 0, tests are silent (ie it prints the current test and does not print any output, not even OK)
|
|
;core.asm
|
|
TEST_islower equ 1
|
|
TEST_isupper equ 1
|
|
TEST_tolower equ 1
|
|
TEST_toupper equ 1
|
|
TEST_min equ 1
|
|
TEST_minu equ 1
|
|
TEST_max equ 1
|
|
TEST_maxu equ 1
|
|
TEST_clamp equ 1
|
|
TEST_clampu equ 1
|
|
;console.asm
|
|
TEST_print equ 1
|
|
TEST_puts equ 1
|
|
TEST_printf equ 1
|
|
;string.asm_
|
|
TEST_strlen equ 1
|
|
TEST_strcpy equ 1
|
|
TEST_strcat equ 1
|
|
TEST_strclr equ 1
|
|
TEST_strcmp equ 1
|
|
;convert.asm
|
|
TEST_atoi equ 1
|
|
TEST_itoa equ 1
|
|
TEST_utoa equ 1
|
|
|
|
;;;
|
|
;;; Global test messages
|
|
;;;
|
|
testMsg_assertIEqual db "\t\tassert(output == %d):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertINEqual db "\t\tassert(output != %d):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertILess db "\t\tassert(output < %d):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertILessE db "\t\tassert(output <= %d):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertIMore db "\t\tassert(output > %d):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertIMoreE db "\t\tassert(output >= %d):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertUEqual db "\t\tassert(output == %u):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertUNEqual db "\t\tassert(output != %u):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertULess db "\t\tassert(output < %u):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertULessE db "\t\tassert(output <= %u):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertUMore db "\t\tassert(output > %u):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_assertUMoreE db "\t\tassert(output >= %u):\n\t\t\tExpected:\t%d\n\t\t\tGot:\t\t%d\n\t\t\t%s",NL,EOS
|
|
testMsg_False db "<!> FAIL",EOS
|
|
testMsg_True db "< > OK",EOS
|
|
testMsg_Results db "\n*** Test Results ***\n* Total tests:\t\t%d\n* Succeeded tests:\t%d\n* Failed tests:\t\t%d\n",EOS
|
|
|
|
;;;
|
|
;;; Specific test data
|
|
;;;
|
|
;islower()
|
|
addTestHeader(_islower, "islower")
|
|
addTest(islower_d, "islower('d')")
|
|
addTest(islower_D, "islower('D')")
|
|
addTest(islower_em, "islower('!')")
|
|
;isupper()
|
|
addTestHeader(_isupper, "isupper")
|
|
addTest(isupper_d, "isupper('d')")
|
|
addTest(isupper_D, "isupper('D')")
|
|
addTest(isupper_em, "isupper('!')")
|
|
;tolower()
|
|
addTestHeader(_tolower, "tolower")
|
|
addTest(tolower_d, "tolower('d')")
|
|
addTest(tolower_D, "tolower('D')")
|
|
addTest(tolower_em, "tolower('em')")
|
|
addTest(tolower_cb, "tolower('}')")
|
|
;toupper()
|
|
addTestHeader(_toupper, "toupper")
|
|
addTest(toupper_d, "toupper('d')")
|
|
addTest(toupper_D, "toupper('D')")
|
|
addTest(toupper_em, "toupper('em')")
|
|
addTest(toupper_cb, "toupper('}')")
|
|
;min()
|
|
addTestHeader(_min, "min")
|
|
addTest(min1, "min(-1337, 1337)")
|
|
addTest(min2, "min(MIN_INT64, MAX_INT64)")
|
|
addTest(min3, "min(MIN_UINT64, MAX_UINT64)")
|
|
addTest(min4, "min(-1, 0)")
|
|
addTest(min5, "min(MIN_UINT64, MIN_INT8)")
|
|
|
|
section .data
|
|
|
|
section .bss
|
|
|
|
section .text
|
|
global _start
|
|
_start:
|
|
xor r13, r13 ;total tests
|
|
xor r14, r14 ;OK tests (assert => true)
|
|
|
|
;--- islower()
|
|
%if TEST_tolower
|
|
printTestHeader(_islower)
|
|
|
|
; TEST 1: islower('d')
|
|
printTest(islower_d)
|
|
mov rdi, 'd'
|
|
call islower
|
|
assert 1, je, testMsg_assertIEqual
|
|
; TEST 2: islower('D')
|
|
printTest(islower_D)
|
|
mov rdi, 'D'
|
|
call islower
|
|
assert 0, je, testMsg_assertIEqual
|
|
; TEST 3: islower('!')
|
|
printTest(islower_em)
|
|
mov rdi, '!'
|
|
call islower
|
|
assert 0, je, testMsg_assertIEqual
|
|
%endif
|
|
|
|
;--- isupper()
|
|
%if TEST_isupper
|
|
printTestHeader(_isupper)
|
|
|
|
; TEST 1: isupper('d')
|
|
printTest(isupper_d)
|
|
mov rdi, 'd'
|
|
call isupper
|
|
assert 0, je, testMsg_assertIEqual
|
|
; TEST 2: isupper('D')
|
|
printTest(isupper_D)
|
|
mov rdi, 'D'
|
|
call isupper
|
|
assert 1, je, testMsg_assertIEqual
|
|
; TEST 3: isupper('!')
|
|
printTest(isupper_em)
|
|
mov rdi, '!'
|
|
call isupper
|
|
assert 0, je, testMsg_assertIEqual
|
|
%endif
|
|
|
|
;--- tolower()
|
|
%if TEST_tolower
|
|
printTestHeader(_tolower)
|
|
|
|
; TEST 1: tolower('d')
|
|
printTest(tolower_d)
|
|
mov rdi, 'd'
|
|
call tolower
|
|
assert 'd', je, testMsg_assertIEqual
|
|
; TEST 2: tolower('D')
|
|
printTest(tolower_D)
|
|
mov rdi, 'D'
|
|
call tolower
|
|
assert 'd', je, testMsg_assertIEqual
|
|
; TEST 3: tolower('!')
|
|
printTest(tolower_em)
|
|
mov rdi, '!'
|
|
call tolower
|
|
assert '!', je, testMsg_assertIEqual
|
|
; TEST 4: tolower('}')
|
|
printTest(tolower_cb)
|
|
mov rdi, '}'
|
|
call tolower
|
|
assert '}', je, testMsg_assertIEqual
|
|
%endif
|
|
|
|
;--- toupper()
|
|
%if TEST_toupper
|
|
printTestHeader(_toupper)
|
|
|
|
; TEST 1: toupper('d')
|
|
printTest(toupper_d)
|
|
mov rdi, 'd'
|
|
call toupper
|
|
assert 'D', je, testMsg_assertIEqual
|
|
; TEST 2: toupper('D')
|
|
printTest(toupper_D)
|
|
mov rdi, 'D'
|
|
call toupper
|
|
assert 'D', je, testMsg_assertIEqual
|
|
; TEST 3: toupper('!')
|
|
printTest(toupper_em)
|
|
mov rdi, '!'
|
|
call toupper
|
|
assert '!', je, testMsg_assertIEqual
|
|
; TEST 4: toupper('}')
|
|
printTest(toupper_cb)
|
|
mov rdi, '}'
|
|
call toupper
|
|
assert '}', je, testMsg_assertIEqual
|
|
%endif
|
|
|
|
;--- min()
|
|
%if TEST_min
|
|
printTestHeader(_min)
|
|
|
|
; TEST 1: min(-1337, 1337)
|
|
printTest(min1)
|
|
mov rdi, -1337
|
|
mov rsi, 1337
|
|
call min
|
|
assert rdi, je, testMsg_assertIEqual
|
|
; TEST 2: min(MIN_INT64, MAX_INT64)
|
|
printTest(min2)
|
|
mov rdi, MIN_INT64
|
|
mov rsi, MAX_INT64
|
|
call min
|
|
assert rdi, je, testMsg_assertIEqual
|
|
; TEST 3: min(MIN_UINT64, MAX_UINT64)
|
|
printTest(min3)
|
|
mov rdi, MIN_UINT64
|
|
mov rsi, MAX_UINT64
|
|
call min
|
|
assert rdi, je, testMsg_assertIEqual
|
|
; TEST 4: min(-1, 0)
|
|
printTest(min4)
|
|
mov rdi, -1
|
|
xor rsi, rdx
|
|
call min
|
|
assert rdi, je, testMsg_assertIEqual
|
|
; TEST 5: min(MIN_UINT64, MIN_INT8)
|
|
printTest(min5)
|
|
mov rdi, MIN_UINT64
|
|
mov rsi, MIN_INT8
|
|
call min
|
|
assert rsi, je, testMsg_assertIEqual
|
|
%endif
|
|
|
|
;;;
|
|
;;; TEST RESULTS
|
|
;;;
|
|
lea rdi, [rel testMsg_Results]
|
|
mov rsi, r13
|
|
mov rdx, r14
|
|
mov rcx, r13
|
|
sub rcx, r14
|
|
call printf
|
|
|
|
;--- exit()
|
|
xor rdi, rdi
|
|
call exit
|