Kata de api fluida del Coding dojo de Huesca en Scala.
El viernes estuvimos en Huesca en el coding dojo organizado por frogtek con carlos ble. Fue bastante entretenido y muy interesante el programar por parejas. A pesar de que allí tiré de Java, me ha picado el gusanillo y he hecho la kata en Scala. Ahí va el código:
import FluidApi._ case class User(val name: String, val surname: String, val age: Int, val location: String) object FluidApi { def select(field: String): SelectClause = new SelectClause(field) def exec(clause: Executable) = clause.execute def getAttrib(user: User, field: String): Any = { val method = user.getClass.getDeclaredMethod(field) method.invoke(user).asInstanceOf[Object] } } trait Executable { def execute(): List[Any]; } class FromClause(fromObjs: List[User], select: SelectClause) extends Executable { def execute() : List[Any] = fromObjs.map(getAttr(_, select.field)) def where(field: String) = new WhereClause(field, this) def executeFiltered(filterfunc: (List[User]) => List[User]): List[Any] = { filterfunc(fromObjs).map(getAttrib(_, select.field)) } private def getAttr(user: User, field: String): Any = { val method = user.getClass.getDeclaredMethod(field) method.invoke(user).asInstanceOf[Object] } } class SelectClause(val field: String) { def from(fromObjs: List[User]) = new FromClause(fromObjs, this) } class WhereClause(val field: String, from: FromClause) { def greater_than(value: Int) = new ConditionValueClause(this, from, { _.filter(getAttrib(_, field) match { case v: Int => v > value }) }) def less_than(value: Int) = new ConditionValueClause(this, from, { _.filter(getAttrib(_, field) match { case v: Int => v < value }) }) } class ConditionValueClause(where: WhereClause, from: FromClause, filterfunc: (List[User]) => List[User]) extends Executable { def filter = filterfunc def execute() : List[Any] = from.executeFiltered(filterfunc) } class FluidApiTest extends FunSuite { val users = List(User("pablito", "perez", 20, "Moscow"), User("pedrin", "rodriguez", 54, "Alcorcón")) User("pepito", "lopez", 40, "San Francisco") test("select name should return the name of all users") { val names = exec(select("name").from(users)); assert(names.size === 2) assert(names.contains("pablito") && names.contains("pedrin")) } test("select age should return the age of all users") { val ages = exec(select("age").from(users)); assert(ages.size === 2) assert(ages.contains(20) && ages.contains(54)) } test("select name where age > 45 should return pedrin)") { val names = exec(select("name").from(users).where("age").greater_than(20)); assert(names.size === 1) assert(names.contains("pedrin")) } test("select name where age < 21 should return pablito)") { val names = exec(select("name").from(users).where("age").less_than(21)); assert(names.size === 1) assert(names.contains("pablito")) } }
0 comentarios