# Tests for math library.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1998-2000 by Ajuba Solutions.
# All rights reserved.
#
# RCS: @(#) $Id: math.test 381286 2003-05-01 22:40:19Z jigen $

if {[lsearch [namespace children] ::tcltest] == -1} {
    package require tcltest
    namespace import ::tcltest::*
}

source [file join [file dirname [info script]] math.tcl]
package require math

puts "math [package present math]"

proc wrongNumArgs {name arglist count} {
    if {[package vcompare [package provide Tcl] 8.4] < 0} {
	set arg [lindex $arglist $count]
	set msg "no value given for parameter \"$arg\" to \"$name\""
    } else {
	set msg "wrong # args: should be \"$name $arglist\""
    }
    return $msg
}

test math-1.1 {math::min, wrong num args} {
    catch {math::min} msg
    set msg
} [wrongNumArgs math::min {val args} 0]
test math-1.2 {simple math::min} {
    math::min 1
} 1
test math-1.3 {simple math::min} {
    math::min 2 1
} 1
test math-1.4 {math::min} {
    math::min 2 1 0
} 0
test math-1.5 {math::min with negative numbers} {
    math::min 2 1 0 -10
} -10
test math-1.6 {math::min with floating point numbers} {
    math::min 2 1 0 -10 -10.5
} -10.5

test math-2.1 {math::max, wrong num args} {
    catch {math::max} msg
    set msg
} [wrongNumArgs math::max {val args} 0]
test math-2.2 {simple math::max} {
    math::max 1
} 1
test math-2.3 {simple math::max} {
    math::max 2 1
} 2
test math-2.4 {math::max} {
    math::max 0 2 1 0
} 2
test math-2.5 {math::max with negative numbers} {
    math::max 2 1 0 -10
} 2
test math-2.6 {math::max with floating point numbers} {
    math::max 2 1 0 -10 10.5
} 10.5

test math-3.1 {math::mean, wrong num args} {
    catch {math::mean} msg
    set msg
} [wrongNumArgs math::mean {val args} 0]
test math-3.2 {simple math::mean} {
    math::mean 1
} 1.0
test math-3.3 {simple math::mean} {
    math::mean 2 1
} 1.5
test math-3.4 {math::mean} {
    math::mean 0 2 1 0
} 0.75
test math-3.5 {math::mean with negative numbers} {
    math::mean 2 1 0 -11
} -2.0
test math-3.6 {math::mean with floating point numbers} {
    math::mean 2 1 0 -10 10.5
} 0.7

test math-4.1 {math::sum, wrong num args} {
    catch {math::sum} msg
    set msg
} [wrongNumArgs math::sum {val args} 0]
test math-4.2 {math::sum} {
    math::sum 1
} 1
test math-4.3 {math::sum} {
    math::sum 1 2 3
} 6
test math-4.4 {math::sum} {
    math::sum 0.1 0.2 0.3 1
} 1.6
test math-4.5 {math::sum} {
    math::sum -1 1
} 0

test math-5.1 {math::product, wrong num args} {
    catch {math::product} msg
    set msg
} [wrongNumArgs math::product {val args} 0]
test math-5.2 {simple math::product} {
    math::product 1
} 1
test math-5.3 {simple math::product} {
    math::product 0 1 2 3 4 5 6 7
} 0
test math-5.4 {math::product} {
    math::product 1 2 3 4 5
} 120
test math-5.5 {math::product with negative numbers} {
    math::product 2 -10
} -20
test math-5.6 {math::product with floating point numbers} {
    math::product 2 0.5
} 1.0

test math-6.1 {math::sigma, wrong num args} {
    catch {math::sigma} msg
    set msg
} [wrongNumArgs math::sigma {val1 val2 args} 0]
test math-6.2 {simple math::sigma} {
    catch {math::sigma 1} msg
    set msg
} [wrongNumArgs math::sigma {val1 val2 args} 1]
test math-6.3 {simple math::sigma} {
    expr round([ math::sigma 100 120 ])
} 14
test math-6.4 {math::sigma} {
    expr round([ math::sigma 100 110 100 100 ])
} 5
test math-6.5 {math::sigma with negative numbers} {
    math::sigma 100 100 100 -100
} 100.0
test math-6.6 {math::sigma with floating point numbers} {
    math::sigma 100 110 100 100.0
} 5.0

test math-7.1 {math::cov, wrong num args} {
    catch {math::cov} msg
    set msg
} [wrongNumArgs math::cov {val1 val2 args} 0]
test math-7.2 {simple math::cov} {
    catch {math::cov 1} msg
    set msg
} [wrongNumArgs math::cov {val1 val2 args} 1]
test math-7.3 {simple math::cov} {
    math::cov 2 1
} 100.0
test math-7.4 {math::cov} {
    catch { math::cov 0 2 1 0 } msg
    set msg
} "divide by zero"
test math-7.5 {math::cov with negative numbers} {
    math::cov 100 100 100 -100
} 200.0
test math-7.6 {math::cov with floating point numbers} {
    string range [ math::cov 100 110 100 100.0 ] 0 0
} 4

test math-8.1 {math::stats, wrong num of args} {
     catch { math::stats } msg
     set msg
} [wrongNumArgs math::stats {val1 val2 args} 0]
test math-8.2 {math::stats, wrong num of args} {
     catch { math::stats 100 } msg
     set msg
} [wrongNumArgs math::stats {val1 val2 args} 1]
test math-8.3 { simple math::stats } {
     foreach {a b c} [ math::stats 100 100 100 110 ] { break }
     set a [ expr round($a) ]
     set b [ expr round($b) ]
     set c [ expr round($c) ]
     list $a $b $c
} {102 5 5}

test math-9.1 { math::integrate, insufficient data points } {
     catch { math::integrate {1 10 2 20 3 30 4 40} } msg
     set msg
} "at least 5 x,y pairs must be given"     
test math-9.2 { simple math::integrate } {
     math::integrate {1 10 2 20 3 30 4 40 5 50 6 60 7 70 8 80 9 90 10 100}
} {500.0 0.5}     

test math-10.1 { math::random } {
    set result [expr round(srand(12345) * 1000)]
    for {set i 0} {$i < 10} {incr i} {
        lappend result [expr round([::math::random] * 1000)]
    }
    set result
} {97 834 948 36 12 51 766 585 914 784 333}
test math-10.2 { math::random value } {
    set result {}
    expr {srand(12345)}
    for {set i 0} {$i < 10} {incr i} {
        lappend result [::math::random 10]
    }
    set result
} {8 9 0 0 0 7 5 9 7 3}
test math-10.3 { math::random value value } {
    set result {}
    expr {srand(12345)}
    for {set i 0} {$i < 10} {incr i} {
        lappend result [::math::random 5 15]
    }
    set result
} {13 14 5 5 5 12 10 14 12 8}
test math-10.4 {math::random} {
    list [catch {::math::random foo bar baz} msg] $msg
} [list 1 "wrong # args: should be \"::math::random ?value1? ?value2?\""]

test math-11.1 {math::fibonacci} {
    set result {}
    for {set i 0} {$i < 15} {incr i} {
	lappend result [::math::fibonacci $i]
    }
    set result
} [list 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377]

::tcltest::cleanupTests
