playframework/playframework — pull request #3533 by mkurz (2014-10-22 18:09:02+00:00)
Title: Add equals() and hashCode() to play.libs.F.Option

Using latest 2.4-SNAPSHOT or latest 2.3-SNAPSHOT with following routes:

GET /JOptionNull controllers.Application.jOptionRoute(id: play.libs.F.Option[Integer] = play.libs.F.Option.None[Integer])
GET /JOptionValue controllers.Application.jOptionRoute(id: play.libs.F.Option[Integer] = play.libs.F.Option.Some(12345))
GET /JOptionValue1 controllers.Application.jOptionRoute(id: play.libs.F.Option[Integer] = play.libs.F.Option.Some(98765))
GET /JOptionValue2 controllers.Application.jOptionRoute(id: play.libs.F.Option[Integer])

In a template having reverse routes for them:

@routes.Application.jOptionRoute(play.libs.F.Option.None())
@routes.Application.jOptionRoute(play.libs.F.Option.Some(12345))
@routes.Application.jOptionRoute(play.libs.F.Option.Some(98765))
@routes.Application.jOptionRoute(play.libs.F.Option.Some(11111))

Gives me the following routes:

/JOptionValue2
/JOptionValue2?id=12345
/JOptionValue2?id=98765
/JOptionValue2?id=11111

Which is wrong! Correct would be:

/JOptionNull
/JOptionValue
/JOptionValue1
/JOptionValue2?id=11111

Only when using `F.Option` reverse routing is "broken" - it works fine with any other type (`Long`, `java.lang.Long`, `java.util.UUID`, `Int`, `java.lang.Integer` and even with Scala `Option`).

The cause for this bug is that in `target/scala-2.11/src_managed/main/routes_reverseRouting.scala` Scala code like this gets generated:

def jOptionRoute(id:play.libs.F.Option[Integer]): Call = {
...
case (id) if id == play.libs.F.Option.None[Integer] =>
...
case (id) if id == play.libs.F.Option.Some(12345) =>
...
case (id) if id == play.libs.F.Option.Some(98765) =>
...
}

But `F.Option` does not have an `equals` (and `hashCode`) method, so all of the above conditions will always be `false`!

play.libs.F.Option.Some(12345) == play.libs.F.Option.Some(12345) // (in Scala) returns false - Bug!
play.libs.F.Option.Some(12345).equals(play.libs.F.Option.Some(12345)) // returns false - Bug!

This PR simply adds the equals/hashCode methods (including tests) to `F.Option` which as a consequence fixes the above reverse routing bug.