* The set of evaluator tests
* NOTE! Comment lines start with * instead of #, because # is used
* as the first character in a JSF EL delimiter
*######################################################
* testing mixture of strings and expressions
abc
java.lang.String
#{ 3}
int
a#{
java.lang.String
a#{ 5 }
java.lang.String
#{ 3 }b
java.lang.String
#{ 1 }#{ 2 }
java.lang.String
abc #{ 1} #{ 2} def
java.lang.String

* testing values that end with or contain "#"
#
java.lang.String
\#
java.lang.String
  #  
java.lang.String
test#
java.lang.String
#test
java.lang.String
test#test
java.lang.String
test###
java.lang.String
test###{ 34 }
java.lang.String
test###{ 34 }##
java.lang.String
test##{ 34 }
java.lang.String
##{ 34 }
java.lang.String
##
java.lang.String
test##
java.lang.String
test##test
java.lang.String
#{ 34 }##{ 34 }
java.lang.String


*######################################################
* basic literals
#{1}
int
#{-12}
int
#{true}
boolean
#{false}
boolean
#{null}
null
#{4.2}
double
#{-21.3}
double
#{4.}
double
#{.21}
double
#{3e-1}
double
#{.2222222222}
double


*######################################################
* basic relationals between literals

#{1 < 2}
boolean
#{1 > 2}
boolean
#{1 >= 2}
boolean
#{1 <= 2}
boolean
#{1 == 2}
boolean
#{1 != 2}
boolean
#{3 >= 3}
boolean
#{3 <= 3}
boolean
#{3 == 3}
boolean
#{3 < 3}
boolean
#{3 > 3}
boolean
#{3 != 3}
boolean


*######################################################
* relationals between booleans

#{false < true}
java.lang.Object
#{false > true}
java.lang.Object
#{true >= true}
java.lang.Object
#{true <= true}
java.lang.Object
#{true == true}
java.lang.Object
#{true != true}
java.lang.Object

*######################################################
* looking up objects in scopes

* val1b - defined in request scope
#{requestScope.val1b}
java.lang.String
#{sessionScope.val1b}
java.lang.String
#{applicationScope.val1b}
java.lang.String
#{val1b}
java.lang.String

* val1c - defined in session scope
#{requestScope.val1c}
java.lang.String
#{sessionScope.val1c}
java.lang.String
#{applicationScope.val1c}
java.lang.String
#{val1c}
java.lang.String

* val1d - defined in application scope
#{requestScope.val1d}
java.lang.String
#{sessionScope.val1d}
java.lang.String
#{applicationScope.val1d}
java.lang.String
#{val1d}
java.lang.String

*######################################################
* accessing properties

#{bean1a.int1}
int
#{bean1a.boolean1}
boolean
#{bean1a.string1}
java.lang.String
#{bean1a.bean1.int2}
java.lang.Integer
#{bean1a.bean1.bean2.string2}
java.lang.String
#{bean1a.byte1}
byte
#{bean1a.char1}
char
#{bean1a.short1}
short
#{bean1a.long1}
long
#{bean1a.float1}
float
#{bean1a.double1}
double

*######################################################
* test the entire relational comparison type promotion matrix

#{bean1a.byte1 < bean1a.byte1}
boolean
#{bean1a.byte1 < bean1a.char1}
boolean
#{bean1a.byte1 < bean1a.short1}
boolean
#{bean1a.byte1 < bean1a.int1}
boolean
#{bean1a.byte1 < bean1a.long1}
boolean
#{bean1a.byte1 < bean1a.float1}
boolean
#{bean1a.byte1 < bean1a.double1}
boolean

#{bean1a.char1 < bean1a.byte1}
boolean
#{bean1a.char1 < bean1a.char1}
boolean
#{bean1a.char1 < bean1a.short1}
boolean
#{bean1a.char1 < bean1a.int1}
boolean
#{bean1a.char1 < bean1a.long1}
boolean
#{bean1a.char1 < bean1a.float1}
boolean
#{bean1a.char1 < bean1a.double1}
boolean

#{bean1a.short1 < bean1a.byte1}
boolean
#{bean1a.short1 < bean1a.char1}
boolean
#{bean1a.short1 < bean1a.short1}
boolean
#{bean1a.short1 < bean1a.int1}
boolean
#{bean1a.short1 < bean1a.long1}
boolean
#{bean1a.short1 < bean1a.float1}
boolean
#{bean1a.short1 < bean1a.double1}
boolean

#{bean1a.int1 < bean1a.byte1}
boolean
#{bean1a.int1 < bean1a.char1}
boolean
#{bean1a.int1 < bean1a.short1}
boolean
#{bean1a.int1 < bean1a.int1}
boolean
#{bean1a.int1 < bean1a.long1}
boolean
#{bean1a.int1 < bean1a.float1}
boolean
#{bean1a.int1 < bean1a.double1}
boolean

#{bean1a.long1 < bean1a.byte1}
boolean
#{bean1a.long1 < bean1a.char1}
boolean
#{bean1a.long1 < bean1a.short1}
boolean
#{bean1a.long1 < bean1a.int1}
boolean
#{bean1a.long1 < bean1a.long1}
boolean
#{bean1a.long1 < bean1a.float1}
boolean
#{bean1a.long1 < bean1a.double1}
boolean

#{bean1a.float1 < bean1a.byte1}
boolean
#{bean1a.float1 < bean1a.char1}
boolean
#{bean1a.float1 < bean1a.short1}
boolean
#{bean1a.float1 < bean1a.int1}
boolean
#{bean1a.float1 < bean1a.long1}
boolean
#{bean1a.float1 < bean1a.float1}
boolean
#{bean1a.float1 < bean1a.double1}
boolean

#{bean1a.double1 < bean1a.byte1}
boolean
#{bean1a.double1 < bean1a.char1}
boolean
#{bean1a.double1 < bean1a.short1}
boolean
#{bean1a.double1 < bean1a.int1}
boolean
#{bean1a.double1 < bean1a.long1}
boolean
#{bean1a.double1 < bean1a.float1}
boolean
#{bean1a.double1 < bean1a.double1}
boolean

*######################################################
* test other relational comparison rules

#{null == null}
boolean
#{noSuchAttribute == noSuchAttribute}
boolean
#{noSuchAttribute == null}
boolean
#{null == noSuchAttribute}
boolean
#{bean1a == null}
boolean
#{null == bean1a}
boolean
#{bean1a == bean1a}
boolean
#{bean1a > "hello"}
boolean
#{bean1a.bean1 < 14}
boolean
#{bean1a.bean1 == "hello"}
boolean

*######################################################
* test String comparisons

#{bean1a.string1 == "hello"}
boolean
#{bean1a.string1 != "hello"}
boolean
#{bean1a.string1 == "goodbye"}
boolean
#{bean1a.string1 != "goodbye"}
boolean
#{bean1a.string1 > "goodbye"}
boolean
#{"hello" == bean1a.string1}
boolean
#{"goodbye" > bean1a.string1}
boolean

*######################################################
* test errors in property traversal

#{noSuchAttribute.abc}
java.lang.Object
#{bean1a.bean2.byte1}
java.lang.Object
#{bean1a.noProperty}
java.lang.Object
#{bean1a.noGetter}
java.lang.Object
#{bean1a.errorInGetter}
java.lang.Object
#{bean1a.bean2.string2}
java.lang.Object

*######################################################
* test accessing public properties from private classes

#{pbean1.value}
java.lang.Object
#{pbean2.value}
java.lang.Object
#{pbean3.value}
java.lang.Object
#{pbean4.value}
java.lang.Object
#{pbean5.value}
java.lang.Object
#{pbean6.value}
java.lang.Object
#{pbean7.value}
java.lang.Object


*######################################################
* test reserved words as identifiers

#{and}
java.lang.Object
#{or}
java.lang.Object
#{not}
java.lang.Object
#{eq}
java.lang.Object
#{ne}
java.lang.Object
#{lt}
java.lang.Object
#{gt}
java.lang.Object
#{le}
java.lang.Object
#{ge}
java.lang.Object
#{instanceof}
java.lang.Object
#{true}
java.lang.Object
#{false}
java.lang.Object
#{null}
java.lang.Object


*######################################################
* test reserved words as property names

#{bean1a.and}
java.lang.Object
#{bean1a.or}
java.lang.Object
#{bean1a.not}
java.lang.Object
#{bean1a.eq}
java.lang.Object
#{bean1a.ne}
java.lang.Object
#{bean1a.lt}
java.lang.Object
#{bean1a.gt}
java.lang.Object
#{bean1a.le}
java.lang.Object
#{bean1a.ge}
java.lang.Object
#{bean1a.instanceof}
java.lang.Object
#{bean1a.page}
java.lang.Object
#{bean1a.request}
java.lang.Object
#{bean1a.session}
java.lang.Object
#{bean1a.application}
java.lang.Object
#{bean1a.true}
java.lang.Object
#{bean1a.false}
java.lang.Object
#{bean1a.null}
java.lang.Object

*######################################################
* test arithmetic

#{3+5}
java.lang.Object
#{3-5}
java.lang.Object
#{3/5}
java.lang.Object
#{3*5}
java.lang.Object
#{3*5.0}
java.lang.Object
#{3.0*5}
java.lang.Object
#{3.0*5.0}
java.lang.Object
#{225 % 17}
java.lang.Object

#{ 1 + 2 + 3 * 5 + 6}
java.lang.Object
#{ 1 + (2 + 3) * 5 + 6}
java.lang.Object

*######################################################
* test logical operators

#{ true}
java.lang.Object
#{ not true}
java.lang.Object
#{ not false}
java.lang.Object
#{ not not true}
java.lang.Object
#{ not not false}
java.lang.Object
#{ true and false}
java.lang.Object
#{ true and true}
java.lang.Object
#{ false and true}
java.lang.Object
#{ false and false}
java.lang.Object
#{ true or false}
java.lang.Object
#{ true or true}
java.lang.Object
#{ false or true}
java.lang.Object
#{ false or false}
java.lang.Object

#{ false or false or false or true and false}
java.lang.Object
#{ false or false or false or true and false or true}
java.lang.Object

*######################################################
* test indexed access operator

* Test as equivalent to property accessor
#{ bean1a["double1"] }
java.lang.Object
#{ bean1a["double1"].class }
java.lang.Object

* Test as array accessor
#{ bean1a.stringArray1[-1]}
java.lang.Object
#{ bean1a.stringArray1[0]}
java.lang.Object
#{ bean1a.stringArray1[1]}
java.lang.Object
#{ bean1a.stringArray1[2]}
java.lang.Object
#{ bean1a.stringArray1[3]}
java.lang.Object
#{ bean1a.stringArray1[4]}
java.lang.Object

* Test as list accessor
#{ bean1a.list1 [0] }
java.lang.Object
#{ bean1a.list1 [1] }
java.lang.Object
#{ bean1a.list1 [2][2] }
java.lang.Object

* Test as indexed property accessor
#{ bean1a.indexed1[-1]}
java.lang.Object
#{ bean1a.indexed1[0]}
java.lang.Object
#{ bean1a.indexed1[1]}
java.lang.Object
#{ bean1a.indexed1[2]}
java.lang.Object
#{ bean1a.indexed1[3]}
java.lang.Object
#{ bean1a.indexed1[4]}
java.lang.Object

* Test as map accessor
#{ bean1a.map1.noKey }
java.lang.Object
#{ bean1a.map1.key1 }
java.lang.Object
#{ bean1a.map1 ["key1"] }
java.lang.Object
#{ bean1a.map1 [14] }
java.lang.Object
#{ bean1a.map1 [2 * 7] }
java.lang.Object
#{ bean1a.map1.recurse.list1[0] }
java.lang.Object

* Test UIComponent as bean
#{view.rendered}
java.lang.Boolean
#{view.attributes.rendered}
java.lang.Boolean
#{view.children[0].value}
java.lang.String
#{view.children[0].rendered}
java.lang.Boolean

*######################################################
* test String concatenation

#{ "a" + "bcd" }
java.lang.Object
#{ "a" + (4*3) }
java.lang.Object
#{ bean1a.map1 ["key" + (5-4)] }
java.lang.Object

*######################################################
* test String comparisons

#{ "30" < "4" }
java.lang.Object
#{ 30 < "4" }
java.lang.Object
#{ 30 > "4" }
java.lang.Object
#{ "0004" == "4" }
java.lang.Object

*######################################################
* test relational comparison with alternate symbols

#{ 4 eq 3}
java.lang.Object
#{ 4 ne 3}
java.lang.Object
#{ 4 eq 4}
java.lang.Object
#{ 4 ne 4}
java.lang.Object
#{ 4 lt 3}
java.lang.Object
#{ 4 gt 3}
java.lang.Object
#{ 4 le 3}
java.lang.Object
#{ 4 ge 3}
java.lang.Object
#{ 4 le 4}
java.lang.Object
#{ 4 ge 4}
java.lang.Object

*######################################################
* test expressions on the left side of a value suffix

#{(3).class}
java.lang.Object
#{(bean1a.map1)["key1"]}
java.lang.Object


*######################################################
* test String/boolean logical operators

#{'true' and false}
java.lang.Object
#{'true' or true}
java.lang.Object
#{false and 'true'}
java.lang.Object
#{false or 'true'}
java.lang.Object

*######################################################
* test empty operator

#{ empty "A"}
java.lang.Object
#{ empty "" }
java.lang.Object
#{ empty null }
java.lang.Object
#{ empty false}
java.lang.Object
#{ empty 0}
java.lang.Object
#{ not empty 0}
java.lang.Object
#{ not empty empty 0}
java.lang.Object
#{ empty emptyTests.emptyArray }
java.lang.Object
#{ empty emptyTests.nonemptyArray }
java.lang.Object
#{ empty emptyTests.emptyList }
java.lang.Object
#{ empty emptyTests.nonemptyList }
java.lang.Object
#{ empty emptyTests.emptyMap }
java.lang.Object
#{ empty emptyTests.nonemptyMap }
java.lang.Object
#{ empty emptyTests.emptySet }
java.lang.Object
#{ empty emptyTests.nonemptySet }
java.lang.Object

*######################################################
* test String arithmetic

#{ "6" / "3" }
java.lang.Object
#{ 3 + "4" }
java.lang.Object
#{ "4" + 3 }
java.lang.Object
#{ 3 + "4.5" }
java.lang.Object
#{ "4.5" + 3 }
java.lang.Object
#{ 3.0 + 6.0}
java.lang.Object
#{ 31121.0 * 61553.0 }
java.lang.Object
#{ 31121 * 61553 }
java.lang.Object
#{ 65536 * 65536 * 65536 * 32759 }
java.lang.Object
#{ 9220838762064379904.0 - 9220838762064379900.0 }
java.lang.Object
#{ 9220838762064379904 - 9220838762064379900 }
java.lang.Object

*######################################################
* test relational operators involving null

#{ null == null }
java.lang.Object
#{ null != null }
java.lang.Object
#{ null > null }
java.lang.Object
#{ null < null }
java.lang.Object
#{ null >= null }
java.lang.Object
#{ null <= null }
java.lang.Object

#{ null == 3 }
java.lang.Object
#{ null != 3 }
java.lang.Object
#{ null > 3 }
java.lang.Object
#{ null < 3 }
java.lang.Object
#{ null >= 3 }
java.lang.Object
#{ null <= 3 }
java.lang.Object

#{ 3 == null }
java.lang.Object
#{ 3 != null }
java.lang.Object
#{ 3 > null }
java.lang.Object
#{ 3 < null }
java.lang.Object
#{ 3 >= null }
java.lang.Object
#{ 3 <= null }
java.lang.Object

#{ null == "" }
java.lang.Object
#{ null != "" }
java.lang.Object
#{ "" == null }
java.lang.Object
#{ "" != null }
java.lang.Object

*######################################################
* arithmetic operators involving Strings

#{ 4 + 3 }
java.lang.Object
#{ 4.0 + 3 }
java.lang.Object
#{ 4 + 3.0 }
java.lang.Object
#{ 4.0 + 3.0 }
java.lang.Object
#{ "4" + 3 }
java.lang.Object
#{ "4.0" + 3 }
java.lang.Object
#{ "4" + 3.0 }
java.lang.Object
#{ "4.0" + 3.0 }
java.lang.Object
#{ 4 + "3" }
java.lang.Object
#{ 4.0 + "3" }
java.lang.Object
#{ 4 + "3.0" }
java.lang.Object
#{ 4.0 + "3.0" }
java.lang.Object
#{ "4" + "3" }
java.lang.Object
#{ "4.0" + "3" }
java.lang.Object
#{ "4" + "3.0" }
java.lang.Object
#{ "4.0" + "3.0" }
java.lang.Object


#{ 4 - 3 }
java.lang.Object
#{ 4.0 - 3 }
java.lang.Object
#{ 4 - 3.0 }
java.lang.Object
#{ 4.0 - 3.0 }
java.lang.Object
#{ "4" - 3 }
java.lang.Object
#{ "4.0" - 3 }
java.lang.Object
#{ "4" - 3.0 }
java.lang.Object
#{ "4.0" - 3.0 }
java.lang.Object
#{ 4 - "3" }
java.lang.Object
#{ 4.0 - "3" }
java.lang.Object
#{ 4 - "3.0" }
java.lang.Object
#{ 4.0 - "3.0" }
java.lang.Object
#{ "4" - "3" }
java.lang.Object
#{ "4.0" - "3" }
java.lang.Object
#{ "4" - "3.0" }
java.lang.Object
#{ "4.0" - "3.0" }
java.lang.Object


#{ 4 * 3 }
java.lang.Object
#{ 4.0 * 3 }
java.lang.Object
#{ 4 * 3.0 }
java.lang.Object
#{ 4.0 * 3.0 }
java.lang.Object
#{ "4" * 3 }
java.lang.Object
#{ "4.0" * 3 }
java.lang.Object
#{ "4" * 3.0 }
java.lang.Object
#{ "4.0" * 3.0 }
java.lang.Object
#{ 4 * "3" }
java.lang.Object
#{ 4.0 * "3" }
java.lang.Object
#{ 4 * "3.0" }
java.lang.Object
#{ 4.0 * "3.0" }
java.lang.Object
#{ "4" * "3" }
java.lang.Object
#{ "4.0" * "3" }
java.lang.Object
#{ "4" * "3.0" }
java.lang.Object
#{ "4.0" * "3.0" }
java.lang.Object


#{ 4 / 3 }
java.lang.Object
#{ 4.0 / 3 }
java.lang.Object
#{ 4 / 3.0 }
java.lang.Object
#{ 4.0 / 3.0 }
java.lang.Object
#{ "4" / 3 }
java.lang.Object
#{ "4.0" / 3 }
java.lang.Object
#{ "4" / 3.0 }
java.lang.Object
#{ "4.0" / 3.0 }
java.lang.Object
#{ 4 / "3" }
java.lang.Object
#{ 4.0 / "3" }
java.lang.Object
#{ 4 / "3.0" }
java.lang.Object
#{ 4.0 / "3.0" }
java.lang.Object
#{ "4" / "3" }
java.lang.Object
#{ "4.0" / "3" }
java.lang.Object
#{ "4" / "3.0" }
java.lang.Object
#{ "4.0" / "3.0" }
java.lang.Object


#{ 4 % 3 }
java.lang.Object
#{ 4.0 % 3 }
java.lang.Object
#{ 4 % 3.0 }
java.lang.Object
#{ 4.0 % 3.0 }
java.lang.Object
#{ "4" % 3 }
java.lang.Object
#{ "4.0" % 3 }
java.lang.Object
#{ "4" % 3.0 }
java.lang.Object
#{ "4.0" % 3.0 }
java.lang.Object
#{ 4 % "3" }
java.lang.Object
#{ 4.0 % "3" }
java.lang.Object
#{ 4 % "3.0" }
java.lang.Object
#{ 4.0 % "3.0" }
java.lang.Object
#{ "4" % "3" }
java.lang.Object
#{ "4.0" % "3" }
java.lang.Object
#{ "4" % "3.0" }
java.lang.Object
#{ "4.0" % "3.0" }
java.lang.Object


#{ "8" / "2" }
java.lang.Object
#{ "4e2" + "3" }
java.lang.Object
#{ "4" + "3e2" }
java.lang.Object
#{ "4e2" + "3e2" }
java.lang.Object


*######################################################
* unary minus operator involving Strings

#{ -3 }
java.lang.Object
#{ -3.0 }
java.lang.Object
#{ -"3" }
java.lang.Object
#{ -"3.0" }
java.lang.Object
#{ -"3e2" }
java.lang.Object
