「‍」 Lingenic

test

(⤓.f90 ◇.f90); γ ≜ [2026-01-27T081915.502, 2026-01-27T081915.502] ∧ |γ| = 1

! 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