You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "ASF GitHub Bot (JIRA)" <ji...@apache.org> on 2015/10/19 16:29:05 UTC

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

    [ https://issues.apache.org/jira/browse/GROOVY-7637?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14963381#comment-14963381 ] 

ASF GitHub Bot commented on GROOVY-7637:
----------------------------------------

GitHub user tkruse opened a pull request:

    https://github.com/apache/incubator-groovy/pull/150

    fix GROOVY-7637 and GROOVY-7636 issues around Number Comparisons

    

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/tkruse/incubator-groovy groovy-7637-compareTo

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/incubator-groovy/pull/150.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #150
    
----
commit 48767107d824976c19199e7a863d644fd926e7fe
Author: Thibault Kruse <th...@gmx.de>
Date:   2015-09-07T10:05:26Z

    GROOVY-7637: Fix inconsistent missing Symmetry in DefaultTypeTransformation.compareTo()

commit aa5ee3f98d93b22fdb0cdc89f8c3a79e6bc95f98
Author: Thibault Kruse <th...@gmx.de>
Date:   2015-10-19T13:47:01Z

    GROOVY-7636: Fall back to BigDecimalMath for custom Number implementations

----


> 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
>            Priority: Minor
>
> 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.4#6332)