You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2017/05/02 02:04:15 UTC

[jira] [Closed] (GROOVY-7637) DefaultTypeTransformation.compareTo not symmetrical

     [ https://issues.apache.org/jira/browse/GROOVY-7637?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Paul King closed GROOVY-7637.
-----------------------------

> DefaultTypeTransformation.compareTo not symmetrical
> ---------------------------------------------------
>
>                 Key: GROOVY-7637
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7637
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-jdk
>            Reporter: Thibault Kruse
>            Assignee: Paul King
>            Priority: Minor
>             Fix For: 2.5.0-alpha-1
>
>
> DefaultTypeTransformation.compareTo(Object left, Object right) is being used in plenty of places in Groovy.
> However, for several corner cases, it does not provide symmetry, that is: when compareTo(a, b) returns a value (does not fail), then:
> signum(compareTo(a, b)) == - signum(compareTo(b, a))
> To reproduce:
> {code}
>   static class MyNumber extends Number {
>         def n
>         MyNumber(n) {
>             this.n = n
>         }
>         int intValue(){n}
>         long longValue(){n}
>         float floatValue(){n}
>         double doubleValue(){n}
>         int hashCode(){-n}
>         boolean equals(other) {
>             if (other instanceof MyNumber) { return n==other.n}
>             return false
>         }
>         String toString() {n.toString()}
>     }
>     static class MyNumberCompareTo extends MyNumber {
>         MyNumberCompareTo(Object n) {
>             super(n)
>         }
>         int compareTo(MyNumber other) {
>             return n <=> other.n
>         }
>     }
>     static class MyNumberComparable extends MyNumberCompareTo implements Comparable<MyNumber> {
>         MyNumberComparable(Object n) {
>             super(n)
>         }
>         int compareTo(Object other) {
>             return n <=>  (MyNumber) other;
>         }
>     }
>     void testCompareTo() {
>         def object1 = new Object()
>         def object2 = new Object()
>         // objects
>         assert compareTo(null, null) == 0
>         assert compareTo(object1, null) == 1
>         assert compareTo(null, object1) == -1
>         assert compareTo(1, 1) == 0
>         shouldFail(GroovyRuntimeException) {
>             compareTo(object1, object2)
>         }
>         // chars, int values 49 and 50
>         Character char1 = '1' as Character
>         Character char2 = '2' as Character
>         checkCompareToSymmetricSmallerThan(char1, char2)
>         MyNumber number1 = new MyNumber(49)
>         MyNumber number2 = new MyNumber(50)
>         MyNumberCompareTo numCompTo1 = new MyNumberCompareTo(49)
>         MyNumberCompareTo numCompTo2 = new MyNumberCompareTo(50)
>         MyNumberComparable numComp1 = new MyNumberComparable(49)
>         MyNumberComparable numComp2 = new MyNumberComparable(50)
>         List lowers = [49, 49L, 49.0, 49.0G, 49.00G, char1, '1', number1, numCompTo1, numComp1]
>         List highers = [50, 50L, 50.0, 50.0G, 50.00G, char2, '2', number2, numCompTo2, numComp2]
>         lowers.each { def lower ->
>             assert compareTo(lower, lower) == 0
>             highers.each { def higher ->
>                 checkCompareToSymmetricSmallerThan(lower, higher)
>             }
>         }
>         // glitch, failing with ClassCastException
>         shouldFail(GroovyRuntimeException) {
>             compareTo(1, "22")
>         }
>         shouldFail(GroovyRuntimeException) {
>             compareTo("22", 1)
>         }
>         // strings and chars
>         assert compareTo('aa1', '2' as Character) > 0
>         // bug, classCast exception
>         assert compareTo('2' as Character, 'aa1') < 0
>         assert compareTo("aa${1}", '2' as Character) > 0
>         // bug, classCast exception
>         assert compareTo('2' as Character, "aa${1}") < 0
>         // Strings and GStrings
>         List lowers2 = ['aa1', "aa${1}"]
>         List highers2 = ['bb2', "b${2}"]
>         lowers2.each { def lower ->
>             assert compareTo(lower, lower) == 0
>             highers2.each { def higher ->
>                 checkCompareToSymmetricSmallerThan(lower, higher)
>             }
>         }
>     }
>     static void checkCompareToSymmetricSmallerThan(a, b) {
>         try {
>             assert compareTo(a, b) < 0
>             assert compareTo(b, a) > 0
>         } catch (AssertionError e) {
>             System.err.print(a.class.toString() + ' compared to ' + b.class.toString() )
>             throw e
>         }
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)