# Test the implementation of the java::for command
#
# Copyright (c) 2006 by Moses DeJong.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# 2016 - reinserted in JBlend project

package require TTXN
  # package under test is JBlend 2.0
package require JBlend 2.0


java::import -package java.util Vector Hashtable Map HashMap


# Test series 1.
# Make sure the common errors are detected

Name: javaforcmd-1.1
Description: {JavaForCmd: common errors}
Test: {
    java::for
}
Expected: error {wrong # args: should be "java::for type_var collection script"}

Name: javaforcmd-1.2 
Description: {JavaForCmd: common errors}
Test: {
    java::for {}
}
Expected: error {wrong # args: should be "java::for type_var collection script"}

Name: javaforcmd-1.3
Description: {JavaForCmd: common errors}
Test: {
    java::for {} {}
}
Expected: error {wrong # args: should be "java::for type_var collection script"}

Name: javaforcmd-1.4
Description: {JavaForCmd: common errors}
Test: {
    java::for {} {} {} {}
}
Expected: error {wrong # args: should be "java::for type_var collection script"}

Name: javaforcmd-1.5
Description: {JavaForCmd: 0 arguments in type_var list}
Test: {
    java::for {} {} {}
}
Expected: error {invalid type_var ""}

Name: javaforcmd-1.6
Description: {JavaForCmd: 1 arguments in type_var list}
Test: {
    java::for {TYPE} {} {}
}
Expected: error {invalid type_var "TYPE"}

Name: javaforcmd-1.7
Description: {JavaForCmd: 3 arguments in type_var list}
Test: {
    java::for {TYPE VARNAME EXTRA} {} {}
}
Expected: error {invalid type_var "TYPE VARNAME EXTRA"}

Name: javaforcmd-1.8
Description: {JavaForCmd: 2 arguments in type_var list}
Test: {
    java::for {TYPE a(one)} {} {}
}
Expected: error {invalid type_var "TYPE a(one)", varname must be simple scalar}

Name: javaforcmd-1.9
Description: {JavaForCmd: 2 arguments in type_var list}
Test: {
    java::for {TYPE ::myglobal} {} {}
}
Expected: error {invalid type_var "TYPE ::myglobal", varname must be simple scalar}

Name: javaforcmd-1.10
Description: {JavaForCmd: 2 arguments in type_var list}
Test: {
    java::for {{} varname} {} {}
}
Expected: error {invalid type_var "{} varname"}

Name: javaforcmd-1.11
Description: {JavaForCmd: 2 arguments in type_var list}
Test: {
    java::for {TYPE {}} {} {}
}
Expected: error {invalid type_var "TYPE {}"}


# Test series 2.

Name: javaforcmd-2.1
Description: {JavaForCmd: iterate over Vector}
Test: {
    set v [java::new Vector]
    $v addElement [java::new String "One"]
    $v addElement [java::new String "Two"]

    set results [list]
    java::for {String e} $v {
        lappend results $e
    }
    set results
}
Expected: {One Two}

Name: javaforcmd-2.2
Description: {JavaForCmd: iterate over Vector of Integer as int primitive}
Test: {
    set v [java::new Vector]
    $v addElement [java::new Integer 0]
    $v addElement [java::new Integer 1]
    $v addElement [java::new Integer 2]

    set results [list]
    java::for {int e} $v {
        lappend results $e
    }
    set results
}
Expected: {0 1 2}

Name: javaforcmd-2.3
Description: {JavaForCmd: iterate over Vector of Integer as Integer object}
Test: {
    set v [java::new Vector]
    $v addElement [java::new Integer 0]
    $v addElement [java::new Integer 1]
    $v addElement [java::new Integer 2]

    set results [list]
    java::for {Integer e} $v {
        lappend results [$e toString]
    }
    set results
}
Expected: {0 1 2}

Name: javaforcmd-2.4
Description: {JavaForCmd: void not allowed}
Test: {
    set v [java::new Vector]
    list \
        [catch {java::for {void v} $v {}} err] $err \
        [catch {java::for {Void v} $v {}} err] $err \
        [catch {java::for {java.lang.Void v} $v {}} err] $err
}
Expected: [list \
    1 {void type is invalid} \
    1 {void type is invalid} \
    1 {void type is invalid} \
    ]

Name: javaforcmd-2.5
Description: {JavaForCmd: can't iterate over non-Collection object}
Test: {
    set obj [java::new Integer 0]
    java::for {Object o} $obj {}
}
Expected: error {passed collection argument of type java.lang.Integer which does not implement Collection interface}

Name: javaforcmd-2.6
Description: {JavaForCmd: iterate over Hashtable key/value pairs}
Test: {
    set t [java::new java.util.Hashtable]
    $t put "One" "onestr"
    $t put "Two" "twostr"

    set results [list]
    java::for {java.util.Map.Entry e} [$t entrySet] {
        set key [[$e getKey] toString]
        set value [[$e getValue] toString]
        lappend results [list $key $value]
    }
    set results
}
Expected: {{One onestr} {Two twostr}}

Name: javaforcmd-2.7
Description: {JavaForCmd: iterate over Hashtable key/value pairs}
Test: {
    set t [java::new Hashtable]
    $t put "One" "onestr"
    $t put "Two" "twostr"

    set results [list]
    java::for {Map.Entry e} [$t entrySet] {
        set key [[$e getKey] toString]
        set value [[$e getValue] toString]
        lappend results [list $key $value]
    }
    set results
}
Expected: {{One onestr} {Two twostr}}

Name: javaforcmd-2.8
Description: {JavaForCmd: iterate over Hashtable keys}
Test: {
    set t [java::new Hashtable]
    $t put "s1" "one"
    $t put "s2" "two"

    set results [list]
    java::for {String key} [$t keySet] {
        set value [[$t get $key] toString]
        lappend results [list $key $value]
    }
    lsort -dictionary $results
}
Expected: {{s1 one} {s2 two}}

Name: javaforcmd-2.9
Description: {JavaForCmd: iterate over Integer HashMap keys}
Test: {
    set t [java::new HashMap]
    $t put [java::new Integer 1] "one"
    $t put [java::new Integer 2] "two"

    set results [list]
    java::for {Integer key} [$t keySet] {
        set value [[$t get $key] toString]
        lappend results [list [$key toString] $value]
    }
    lsort -dictionary $results
}
Expected: {{1 one} {2 two}}


Name: javaforcmd-3.1
Description: {JavaForCmd: iterate over array of String}
Test: {
    set a [java::new {String[]} {3} {str1 str2 str3}]

    set results [list]
    java::for {String e} $a {
        lappend results $e
    }
    set results
}
Expected: {str1 str2 str3}

Name: javaforcmd-3.2
Description: {JavaForCmd: iterate over array of int}
Test: {
    set a [java::new {int[]} {3} {1 2 3}]

    set results [list]
    java::for {int e} $a {
        lappend results $e
    }
    set results
}
Expected: {1 2 3}

Name: javaforcmd-3.3
Description: {JavaForCmd: iterate over array of boolean}
Test: {
    set a [java::new {boolean[]} {2} {false true}]

    set results [list]
    java::for {boolean e} $a {
        lappend results $e
    }
    set results
}
Expected: {0 1}

Name: javaforcmd-3.4
Description: {JavaForCmd: iterate over array of long}
Test: {
    set a [java::new {long[]} {2} {2147483647 2147483648}]

    set results [list]
    java::for {long e} $a {
        lappend results $e
    }
    set results
}
Expected: {2147483647 2147483648}

Name: javaforcmd-3.5
Description: {JavaForCmd: iterate over array of float}
Test: {
    set a [java::new {float[]} {2} {0.0 1.0}]

    set results [list]
    java::for {float e} $a {
        lappend results $e
    }
    set results
}
Expected: {0.0 1.0}

Name: javaforcmd-3.6
Description: {JavaForCmd: iterate over array of double}
Test: {
    set a [java::new {double[]} {2} {0.0 2.0e3}]

    set results [list]
    java::for {double e} $a {
        lappend results $e
    }
    set results
}
Expected: {0.0 2000.0}

Name: javaforcmd-3.7
Description: {JavaForCmd: iterate over array of byte}
Test: {
    set a [java::new {byte[]} {3} {-1 0 1}]

    set results [list]
    java::for {byte e} $a {
        lappend results $e
    }
    set results
}
Expected: {-1 0 1}

Name: javaforcmd-3.8
Description: {JavaForCmd: iterate over array of short}
Test: {
    set a [java::new {short[]} {3} {-1 0 1}]

    set results [list]
    java::for {short e} $a {
        lappend results $e
    }
    set results
}
Expected: {-1 0 1}

Name: javaforcmd-3.9
Description: {JavaForCmd: iterate over array of char}
Test: {
    set a [java::new {char[]} {3} {a b c}]

    set results [list]
    java::for {char e} $a {
        lappend results $e
    }
    set results
}
Expected: {a b c}

Name: javaforcmd-3.10
Description: {JavaForCmd: iterate over array of Object}
Test: {
    set s1 [java::new String string1]
    set s2 [java::new String string2]
    set a [java::new {Object[]} {2} [list $s1 $s2]]

    set results [list]
    java::for {Object e} $a {
        lappend results [$e toString]
    }
    set results
}
Expected: {string1 string2}

Name: javaforcmd-3.11
Description: {JavaForCmd: iterate over array of Date}
Test: {
    set d1 [java::new java.util.Date]
    set d2 [java::new java.util.Date]
    set a [java::new {Object[]} {2} [list $d1 $d2]]

    set results [list]
    java::for {Object e} $a {
        set d [java::cast java.util.Date $e]
        lappend results [java::info class $d]
    }
    set results
}
Expected: {java.util.Date java.util.Date}

Name: javaforcmd-3.12
Description: {JavaForCmd: iterate over array of Integer as Integer}
Test: {
    set a [java::new {Integer[]} {3} {1 2 3}]

    set results [list]
    java::for {Integer e} $a {
        lappend results [$e toString]
    }
    set results
}
Expected: {1 2 3}

Name: javaforcmd-3.13
Description: {JavaForCmd: bad array argument}
Test: {
    # Not an array of primitive type
    set a [java::new {Object[]} 1]
    # Not an array of Object type
    set a2 [java::new {int[]} 1 {1}]

    list \
        [catch {java::for {String s} $a {}} err] $err \
        [catch {java::for {int i} $a {}} err] $err \
        [catch {java::for {boolean b} $a {}} err] $err \
        [catch {java::for {long l} $a {}} err] $err \
        [catch {java::for {float f} $a {}} err] $err \
        [catch {java::for {double d} $a {}} err] $err \
        [catch {java::for {byte b} $a {}} err] $err \
        [catch {java::for {short s} $a {}} err] $err \
        [catch {java::for {char c} $a {}} err] $err \
        [catch {java::for {Object o} $a2 {}} err] $err
}
Expected: [list \
    1 {expected collection object to be array of String} \
    1 {expected collection object to be array of int} \
    1 {expected collection object to be array of boolean} \
    1 {expected collection object to be array of long} \
    1 {expected collection object to be array of float} \
    1 {expected collection object to be array of double} \
    1 {expected collection object to be array of byte} \
    1 {expected collection object to be array of short} \
    1 {expected collection object to be array of char} \
    1 {expected collection object to be array of Object} \
    ]


Name: javaforcmd-4.1
Description: {JavaForCmd: iterate over multidimensional array of int}
Test: {
    set a [java::new {int[][]} {3 3} {{1 2 3} {4 5 6} {7 8 9}}]

    set results [list]
    java::for {int[] asub} $a {
        lappend results SUB
        java::for {int e} $asub {
            lappend results $e
        }
    }
    set results
}
Expected: {SUB 1 2 3 SUB 4 5 6 SUB 7 8 9}

Name: javaforcmd-4.2
Description: {JavaForCmd: iterate over contents of two vectors}
Test: {
    set v1 [java::new Vector]
    set v2 [java::new Vector]

    $v1 addElement [java::new String "Black"]
    $v1 addElement [java::new String "White"]

    $v2 addElement [java::new String "0"]
    $v2 addElement [java::new String "1"]
    $v2 addElement [java::new String "2"]

    set results [list]
    java::for {String s1} $v1 {
        java::for {String s2} $v2 {
            lappend results [list $s1 $s2]
        }
    }
    set results
}
Expected: {{Black 0} {Black 1} {Black 2} {White 0} {White 1} {White 2}}


Name: javaforcmd-5.0
Description: {JavaForCmd: use of break and continue}
Test: {
    set a [java::new {int[]} {3} {1 2 3 4}]

    set results [list]
    java::for {int e} $a {
        if {($e % 2) == 0} {
            continue
        }
        lappend results $e
    }
    set results
}
Expected: {1 3}

Name: javaforcmd-5.1
Description: {JavaForCmd: use of break and continue}
Test: {
    set a [java::new {int[]} {3} {1 2 3 4}]

    set results [list]
    java::for {int e} $a {
        if {$e == 3} {
            break
        }
        lappend results $e
    }
    set results
}
Expected: {1 2}

Name: javaforcmd-5.2
Description: {JavaForCmd: result}
Test: {
    set a [java::new {int[]} {3} {1 2 3 4}]

    set result [java::for {int e} $a {
        set e
    }]
    set result
}
Expected: {}


# Pass in typename that does not exist

# === cleanup ========================================

java::import -forget -package java.util
::tcltest::cleanupTests
return

