! HSV Parser Tests (Fortran)
program test_hsv
use hsv_module
implicit none
integer :: passed, failed
passed = 0
failed = 0
print '(A)', '=================================================='
print '(A)', 'HSV Parser Tests (Fortran)'
print '(A)', '=================================================='
call test_basic()
call test_multiple_records()
call test_array_values()
call test_header()
call test_newlines()
call test_quotes()
call test_mixed_content()
call test_multiple_blocks()
print '(A)', '=================================================='
print '(I0,A,I0,A)', passed, ' passed, ', failed, ' failed'
print '(A)', '=================================================='
contains
subroutine assert(cond, name)
logical, intent(in) :: cond
character(len=*), intent(in) :: name
if (cond) then
print '(A,A)', '✓ ', name
passed = passed + 1
else
print '(A,A)', '✗ ', name
failed = failed + 1
end if
end subroutine assert
subroutine test_basic()
type(hsv_doc) :: doc
character(len=256) :: input
input = STX // 'name' // US // 'Alice' // RS // 'age' // US // '30' // ETX
call parse(input, doc)
call assert(doc%rec_count == 1, 'Basic: 1 record')
call assert(trim(get_val(doc%records(1), 'name')) == 'Alice', 'Basic: name=Alice')
call assert(trim(get_val(doc%records(1), 'age')) == '30', 'Basic: age=30')
end subroutine test_basic
subroutine test_multiple_records()
type(hsv_doc) :: doc
character(len=256) :: input
input = STX // 'name' // US // 'Alice' // FS // 'name' // US // 'Bob' // ETX
call parse(input, doc)
call assert(doc%rec_count == 2, 'Multiple records: 2 records')
end subroutine test_multiple_records
subroutine test_array_values()
type(hsv_doc) :: doc
character(len=256) :: input
input = STX // 'tags' // US // 'a' // GS // 'b' // GS // 'c' // ETX
call parse(input, doc)
call assert(doc%rec_count == 1, 'Array: 1 record')
call assert(doc%records(1)%props(1)%is_array, 'Array: tags is array')
call assert(doc%records(1)%props(1)%arr_count == 3, 'Array: 3 elements')
end subroutine test_array_values
subroutine test_header()
type(hsv_doc) :: doc
character(len=256) :: input
input = SOH // 'hsv' // US // '1.0' // RS // 'type' // US // 'users' // &
STX // 'name' // US // 'Alice' // ETX
call parse(input, doc)
call assert(doc%has_header, 'Header: has header')
call assert(trim(get_val(doc%header, 'hsv')) == '1.0', 'Header: hsv=1.0')
call assert(trim(get_val(doc%header, 'type')) == 'users', 'Header: type=users')
call assert(doc%rec_count == 1, 'Header: 1 record')
end subroutine test_header
subroutine test_newlines()
type(hsv_doc) :: doc
character(len=256) :: input
character(len=256) :: expected
input = STX // 'text' // US // 'line1' // char(10) // 'line2' // char(10) // 'line3' // ETX
expected = 'line1' // char(10) // 'line2' // char(10) // 'line3'
call parse(input, doc)
call assert(trim(get_val(doc%records(1), 'text')) == trim(expected), 'Newlines: preserved')
end subroutine test_newlines
subroutine test_quotes()
type(hsv_doc) :: doc
character(len=256) :: input
input = STX // 'msg' // US // 'He said "hello"' // ETX
call parse(input, doc)
call assert(trim(get_val(doc%records(1), 'msg')) == 'He said "hello"', 'Quotes: no escaping')
end subroutine test_quotes
subroutine test_mixed_content()
type(hsv_doc) :: doc
character(len=256) :: input
input = 'ignored' // STX // 'name' // US // 'Alice' // ETX // 'also ignored'
call parse(input, doc)
call assert(doc%rec_count == 1, 'Mixed: 1 record')
call assert(trim(get_val(doc%records(1), 'name')) == 'Alice', 'Mixed: name=Alice')
end subroutine test_mixed_content
subroutine test_multiple_blocks()
type(hsv_doc) :: doc
character(len=256) :: input
input = STX // 'a' // US // '1' // ETX // 'junk' // STX // 'b' // US // '2' // ETX
call parse(input, doc)
call assert(doc%rec_count == 2, 'Multiple blocks: 2 records')
end subroutine test_multiple_blocks
end program test_hsv