Seleccionar página

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"))
	}
}

 

#codingdojohuesca

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies

Pin It on Pinterest