Kata de api fluida del Coding dojo de Huesca en Scala
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"))
}
}
Tips, tutoriales y novedades
Recibe directamente en tu correo todas las novedades, tips y tutoriales gratuitos que compartimos desde Neodoo Microsystems



0 comentarios