;;; Chickadee Game Toolkit ;;; Copyright © 2024 David Thompson ;;; ;;; Licensed under the Apache License, Version 2.0 (the "License"); ;;; you may not use this file except in compliance with the License. ;;; You may obtain a copy of the License at ;;; ;;; http://www.apache.org/licenses/LICENSE-2.0 ;;; ;;; Unless required by applicable law or agreed to in writing, software ;;; distributed under the License is distributed on an "AS IS" BASIS, ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ;;; See the License for the specific language governing permissions and ;;; limitations under the License. (define-module (tests bytestruct) #:use-module (chickadee data bytestruct) #:use-module (srfi srfi-64) #:use-module (system foreign) #:use-module (tests utils)) ;; For testing basic structs. (define-bytestruct (struct (x f32) (y f32))) (define-bytestruct (struct (xy ) (uv ))) ;; For testing arrays. (define-bytestruct (array 16 f32)) ;; For testing variable length arrays. (define-bytestruct (struct (items (* f32)))) ;; For testing unions. (define-bytestruct (struct (type u8) (x s32) (y s32))) (define-bytestruct (struct (type u8) (button u8) (state u8) (x s32) (y s32))) (define-bytestruct (union (type u8) (mouse-move ) (mouse-button ))) ;; For testing recursive types. (define-bytestruct (struct (item int) (next (* )))) (with-tests "bytestruct" (test-group "bytestruct?" (test-assert (bytestruct? (bytestruct-alloc ))) (test-assert (not (bytestruct? 'vec2))) (test-assert (bytestruct? (bytestruct-alloc ))) (test-assert (not (bytestruct? (bytestruct-alloc ))))) (test-group "bytestruct=?" (test-assert (bytestruct=? (bytestruct-alloc ((x) 42) ((y) 69)) (bytestruct-alloc ((x) 42) ((y) 69)))) (test-assert (not (bytestruct=? (bytestruct-alloc ((x) 42) ((y) 69)) (bytestruct-alloc ((x) 77) ((y) 89)))))) (test-group "bytestruct->sexp" (test-equal '(struct (x 42.0) (y 69.0)) (bytestruct->sexp (bytestruct-alloc ((x) 42) ((y) 69)))) (test-equal '(struct (xy (struct (x 42.0) (y 69.0))) (uv (struct (x 77.0) (y 89.0)))) (bytestruct->sexp (bytestruct-alloc ((xy x) 42) ((xy y) 69) ((uv x) 77) ((uv y) 89)))) (test-equal '(union (type 1) (mouse-move (struct (type 1) (x 0) (y 0))) (mouse-button (struct (type 1) (button 0) (state 0) (x 0) (y 0)))) (bytestruct->sexp (bytestruct-alloc ((type) 1)))) (test-equal '(struct (item 42) (next null)) (bytestruct->sexp (bytestruct-alloc ((item) 42))))) (test-group "bytestruct->pointer" (test-equal #vu8(0 0 40 66 0 0 138 66) (let ((v (bytestruct-alloc ((x) 42) ((y) 69)))) (pointer->bytevector (bytestruct->pointer v) (bytestruct-sizeof ))))) (test-group "pointer->bytestruct" (test-equal 69.0 (let ((v (bytestruct-alloc ((x) 42) ((y) 69)))) (bytestruct-ref (y) (pointer->bytestruct (bytestruct->pointer v)))))) (test-group "bytestruct-wrap" (test-equal 69.0 (bytestruct-ref (y) (bytestruct-wrap (f32vector 13 42 69) 4)))) (test-group "bytestruct-unwrap" (test-equal '(#vu8(0 0 40 66 0 0 138 66) 0) (call-with-values (lambda () (bytestruct-unwrap (bytestruct-alloc ((x) 42) ((y) 69)))) list))) (test-group "bytestruct-alignof" (test-equal (alignof (list float float)) (bytestruct-alignof )) (test-equal (alignof (list (list float float) (list float float))) (bytestruct-alignof )) (test-equal (alignof (make-list 16 float)) (bytestruct-alignof )) (test-equal (alignof (list uint8 int32 int32)) (bytestruct-alignof )) (test-equal (alignof (list uint8 uint8 uint8 int32 int32)) (bytestruct-alignof )) (test-equal (max (alignof (list uint8)) (alignof (list uint8 int32 int32)) (alignof (list uint8 uint8 uint8 int32 int32))) (bytestruct-alignof ))) (test-group "bytestruct-sizeof" (test-equal (sizeof (list float float)) (bytestruct-sizeof )) (test-equal (sizeof (list (list float float) (list float float))) (bytestruct-sizeof )) (test-equal (sizeof (make-list 16 float)) (bytestruct-sizeof )) (test-equal (sizeof (list uint8 int32 int32)) (bytestruct-sizeof )) (test-equal (sizeof (list uint8 uint8 uint8 int32 int32)) (bytestruct-sizeof )) (test-equal (max (sizeof (list uint8)) (sizeof (list uint8 int32 int32)) (sizeof (list uint8 uint8 uint8 int32 int32))) (bytestruct-sizeof ))) (test-group "bytestruct-ref" (test-equal 69.0 (bytestruct-ref (y) (bytestruct-alloc ((x) 42) ((y) 69)))) (test-equal 42.0 (bytestruct-ref (uv x) (bytestruct-alloc ((uv x) 42)))) (test-equal 4.0 (let ((bv (f32vector 1 2 3 4))) (bytestruct-ref (items (* 3)) (bytestruct-alloc ((items) (bytevector->pointer bv)))))) (test-equal %null-pointer (bytestruct-ref (next) (bytestruct-alloc )))) (test-group "bytestruct-&ref" (let ((bv (f32vector 42 69))) (test-equal (bytevector->pointer bv 4) (bytestruct-&ref (y) (bytestruct-wrap bv 0))))) (test-group "bytestruct-set!" (test-equal 42.0 (let ((v (bytestruct-alloc ))) (bytestruct-set! (y) v 42) (bytestruct-ref (y) v))) (test-equal 42.0 (let ((a (bytestruct-alloc ))) (bytestruct-set! (7) a 42) (bytestruct-ref (7) a))) (test-equal 42.0 (let* ((bv (f32vector 0 0 0 0)) (f (bytestruct-alloc ))) (bytestruct-set! (items) f (bytevector->pointer bv)) (bytestruct-set! (items (* 3)) f 42) (bytestruct-ref (items (* 3)) f))) (test-equal 42 (let ((e (bytestruct-alloc ))) (bytestruct-set! (mouse-move y) e 42) (bytestruct-ref (mouse-move y) e))) (test-equal 69 (let* ((a (bytestruct-alloc ((item) 42))) (b (bytestruct-alloc ((item) 69)))) (bytestruct-set! (next) a (bytestruct->pointer b)) (bytestruct-ref (next * item) a)))) (test-group "bytestruct-pack!" (test-equal (f32vector 42 69) (let ((bv (f32vector 0 0))) (bytestruct-pack! (((x) 42) ((y) 69)) bv 0) bv)) (test-equal (f32vector 1 2 3 4) (let ((bv (f32vector 0 0 0 0))) (bytestruct-pack! (((xy) (bytestruct-alloc ((x) 1) ((y) 2))) ((uv x) 3) ((uv y) 4)) bv 0) bv)) (test-equal (f32vector 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1) (let ((bv (f32vector 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))) (bytestruct-pack! (((0) 1) ((5) 1) ((10) 1) ((15) 1)) bv 0) bv)) (test-equal (u8vector 1 2 0 0 3 0 0 0 4 0 0 0) (let ((bv (make-u8vector (bytestruct-sizeof ) 0))) (bytestruct-pack! (((mouse-button type) 1) ((mouse-button button) 2) ((mouse-button state) 0) ((mouse-button x) 3) ((mouse-button y) 4)) bv 0) bv))) (test-group "bytestruct-unpack" (test-equal '(42.0 69.0) (let ((bv (f32vector 42 69))) (call-with-values (lambda () (bytestruct-unpack ((x) (y)) bv 0)) list))) (test-equal (list 1.0 2.0 3.0 4.0) (let ((bv (f32vector 1 2 3 4))) (call-with-values (lambda () (bytestruct-unpack ((xy x) (xy y) (uv x) (uv y)) bv 0)) list))) (test-equal '(1.0 1.0 1.0 1.0) (let ((bv (f32vector 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1))) (call-with-values (lambda () (bytestruct-unpack ((0) (5) (10) (15)) bv 0)) list))) (test-equal '(1 2 0 3 4) (let ((bv (u8vector 1 2 0 0 3 0 0 0 4 0 0 0))) (call-with-values (lambda () (bytestruct-unpack ((mouse-button type) (mouse-button button) (mouse-button state) (mouse-button x) (mouse-button y)) bv 0)) list)))) (test-group "bytestruct-copy" (test-equal '(42.0 69.0) (let* ((v (bytestruct-alloc ((x) 42) ((y) 69))) (v* (bytestruct-copy v))) (list (bytestruct-ref (x) v*) (bytestruct-ref (y) v*))))) (test-group "bytestruct-copy!" (test-equal '(42.0 69.0) (let* ((v (bytestruct-alloc ((x) 42) ((y) 69))) (v* (bytestruct-alloc ))) (bytestruct-copy! v v*) (list (bytestruct-ref (x) v*) (bytestruct-ref (y) v*))))))