converters/test-numeric.ss
#lang scheme

(require (planet synx/displayz))

(require (prefix-in numeric: "numeric.ss")
         (prefix-in general: "general.ss")
         "engine.ss")

; to generate this table, I used psql and for instance:
; SELECT encode(numeric_send(15.0::numeric(7,5)),'hex');
; thanks to a tip from RhodiumToad

(define casts
  `(("negative"   
     (,(/ -100000000003 1000) 8)
     . #"\x00\x04\x00\x02\x40\x00\x00\x08\x00\x01\x00\x00\x00\x00\x00\x1e")
    ("fractional" 
     (,(/ 150 10) 5)    
     . #"\x00\x01\x00\x00\x00\x00\x00\x05\x00\x0f")
    ("scale"
     (,(/ 150 10) 4)
     . #"\x00\x01\x00\x00\x00\x00\x00\x04\x00\x0f")
    ("one"
     (1 6)
     . #"\x00\x01\x00\x00\x00\x00\x00\x06\x00\x01")
    ("scale again"
     (1 7)
     . #"\x00\x01\x00\x00\x00\x00\x00\x07\x00\x01")
    ("more fractions"
     (,(/ 1234 1000) 6)
     . #"\x00\x02\x00\x00\x00\x00\x00\x06\x00\x01\x09\x24")
    ("zero"
     (0 0)
     . #"\x00\x00\x00\x00\x00\x00\x00\x00")
    ("negative one"
     (-1 6)
     . #"\x00\x01\x00\x00\x40\x00\x00\x06\x00\x01")
    ("basic"
     (150 5)
     . #"\x00\x01\x00\x00\x00\x00\x00\x05\x00\x96")
    ("really low"
     (-10000000000000000000000000 0)
     . #"\x00\x01\x00\x06\x40\x00\x00\x00\x00\x0a")
    ("no clue"
     (150 4)
     . #"\x00\x01\x00\x00\x00\x00\x00\x04\x00\x96")))

(require "codec-check.ss")

(general:set-info! (get-engine))
(numeric:set-info! (get-engine))

(define tests 
  (let ([engine (get-engine)])
    (test-codec 
     "numeric" casts 
     (λ (pair)
       (let ([value (car pair)] [scale (cadr pair)]) ; scale is really useless...
         (let ([bytes (send engine encode 1700 value)])
           (bytes-set! bytes 6 0)
           (bytes-set! bytes 7 scale)
           bytes)))
     (λ (bytes)
       (let ([value (send engine decode 1700 bytes)]
             [scale (integer-bytes->integer (subbytes bytes 6 8) #t #t)])
         (list value scale))))))

(provide tests)