Skip to content

Instantly share code, notes, and snippets.

@javierfernandes
Created May 19, 2019 22:24
Show Gist options
  • Select an option

  • Save javierfernandes/29c618215ac40a226827e5b2e1b253fb to your computer and use it in GitHub Desktop.

Select an option

Save javierfernandes/29c618215ac40a226827e5b2e1b253fb to your computer and use it in GitHub Desktop.
O3 - FP+OOP - Lepifyo: en clase (2019c1)
package ar.edu.unq.o3
// modelo
case class Programa(val elementos: List[ElementoPrograma])
trait ElementoPrograma
case class Numero(val valor: Int) extends ElementoPrograma
case class Suma(operando1: ElementoPrograma, operando2: ElementoPrograma) extends ElementoPrograma
case class Division(operando1: ElementoPrograma, operando2: ElementoPrograma) extends ElementoPrograma
// chequeador
trait Chequeador {
def chequear(programa: Programa): List[Problema]
}
class ChequeadorConfigurable extends Chequeador {
var reglas = List[Regla]()
override def chequear(programa: Programa): List[Problema] = {
programa.elementos.flatMap(chequear)
}
def chequear(elemento: ElementoPrograma): List[Problema] = {
reglas.flatMap(_.chequear(elemento))
}
def conRegla(regla: Regla): ChequeadorConfigurable = {
reglas = reglas.+:(regla)
this
}
def conRegla(fnRegla: (ElementoPrograma) => Option[Problema]): ChequeadorConfigurable = {
conRegla(new ReglaConFuncion(fnRegla))
}
def in(pfRegla: PartialFunction[ElementoPrograma, Option[Problema]]): ChequeadorConfigurable = {
conRegla(new ReglaConFuncionPF(pfRegla))
}
}
case class Problema(
val severidad: Severidad,
val mensaje: String,
val elemento: ElementoPrograma
)
trait Severidad
object Advertencia extends Severidad
object Error extends Severidad
// reglas
trait Regla {
def chequear(elemento: ElementoPrograma): Option[Problema]
}
object ReglaOperacionRedundante extends Regla {
override def chequear(elemento: ElementoPrograma): Option[Problema] = {
elemento match {
case Suma(Numero(0), _) => Some(Problema(Advertencia, "Suma Redundante", elemento))
case Suma(_, Numero(0)) => Some(Problema(Advertencia, "Suma Redundante", elemento))
case _ => None
}
}
}
object ReglaDivisionPorCero extends Regla {
override def chequear(elemento: ElementoPrograma): Option[Problema] = {
elemento match {
case Division(_, Numero(0)) => Some(Problema(Error, "Division Por Cero", elemento))
case _ => None
}
}
}
class ReglaConFuncion(fn: (ElementoPrograma) => Option[Problema]) extends Regla {
override def chequear(elemento: ElementoPrograma): Option[Problema] = {
fn(elemento)
}
}
class ReglaConFuncionPF(pf: PartialFunction[ElementoPrograma, Option[Problema]]) extends Regla {
override def chequear(elemento: ElementoPrograma): Option[Problema] = {
if (pf.isDefinedAt(elemento)) {
pf(elemento)
} else {
None
}
}
}
object Reglas {
val divisionPorCero: (ElementoPrograma) => Option[Problema] =
elemento => {
elemento match {
case Division(_, Numero(0)) => Some(Problema(Error, "Division Por Cero", elemento))
case _ => None
}
}
val sumarRedundante: (ElementoPrograma) => Option[Problema] = {
case elemento@Suma(Numero(0), _) => Some(Problema(Advertencia, "Suma Redundante", elemento))
case elemento@Suma(_, Numero(0)) => Some(Problema(Advertencia, "Suma Redundante", elemento))
case _ => None
}
val divisionPorCeroPF: PartialFunction[ElementoPrograma, Option[Problema]] = {
case e @ Division(_, Numero(0)) => Some(Problema(Error, "Division Por Cero", e))
}
val operacionRedundantePF: PartialFunction[ElementoPrograma, Option[Problema]] = {
case e @Suma(Numero(0), _) => Some(Problema(Advertencia, "Suma Redundante", e))
case e @Suma(_, Numero(0)) => Some(Problema(Advertencia, "Suma Redundante", e))
}
}
import org.scalatest.{FunSpec, Matchers}
import ar.edu.unq.o3._
class LipifyoSpec extends FunSpec with Matchers {
describe("Chequeador") {
describe("Regla: Operacion Redundante") {
it("no debe encontrar problemas en 2 + 3") {
val programa = Programa(List(
Suma(Numero(2), Numero(3))
))
val chequeador = new ChequeadorConfigurable()
// chequeador.conRegla(ReglaOperacionRedundante)
chequeador
.in(Reglas.operacionRedundantePF)
chequeador.chequear(programa) should equal(List[Problema]())
}
it("no debe encontrar problemas en 0 + 3") {
val programa = Programa(List(
Suma(Numero(0), Numero(3))
))
val chequeador = new ChequeadorConfigurable()
chequeador.conRegla(ReglaOperacionRedundante)
chequeador.chequear(programa) should equal(List[Problema](
Problema(Advertencia, "Suma Redundante", Suma(Numero(0), Numero(3)))
))
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment