add unit tests

This commit is contained in:
DieMyst 2023-11-06 18:14:28 +07:00
parent 4231c2f55c
commit 4528e80c3a
4 changed files with 58 additions and 2 deletions

View File

@ -5,9 +5,12 @@ import aqua.semantics.rules.report.ReportAlgebra
import aqua.types.{BoxType, StreamType, Type}
import cats.data.State
import scala.annotation.tailrec
object TypesChecker {
// check if this type can exist in aqua code
@tailrec
def checkType[S[_], X](name: Token[S], `type`: Type)(using report: ReportAlgebra[S, State[X, *]]): State[X, Unit] = {
`type` match {
case StreamType(StreamType(_)) =>
@ -21,7 +24,7 @@ object TypesChecker {
case _ =>
State.pure(())
}
case t =>
case _ =>
State.pure(())
}
}

View File

@ -138,7 +138,8 @@ class TypesInterpreter[S[_], X](using
case (field, (fieldName, t: DataType)) =>
t match {
case _: StreamType =>
report.error(fieldName, s"Field '$field' has stream type. This is forbidden for data structures.").as(none)
// TODO: move these checks into TypesChecker?
report.error(fieldName, s"Field '$field' has stream type. This is forbidden for data structures").as(none)
case _ =>
TypesChecker.checkType(fieldName, t) >> (field -> t).some.pure[ST]
}

View File

@ -0,0 +1,48 @@
package aqua.semantics
import aqua.parser.lexer.Name
import aqua.semantics.rules.report.{ReportAlgebra, ReportInterpreter, ReportState}
import aqua.semantics.rules.types.TypesChecker
import aqua.types.{ArrayType, OptionType, ScalarType, StreamType, Type}
import cats.Id
import cats.data.State
import monocle.{Iso, Lens}
import org.scalatest.matchers.should.Matchers
import org.scalatest.Inside
import org.scalatest.flatspec.AnyFlatSpec
class TypesCheckerSpec extends AnyFlatSpec with Matchers with Inside {
val emptyR = ReportState[Id]()
def checkType(t: Type) = {
type Interpreter[A] = State[ReportState[Id], A]
given Lens[ReportState[Id], ReportState[Id]] = Iso.id[ReportState[Id]]
given ReportAlgebra[Id, Interpreter] =
new ReportInterpreter[Id, ReportState[Id]]
TypesChecker.checkType[Id, ReportState[Id]](Name[Id]("t"), t).run(emptyR).value._1.errors.headOption
}
"checker" should "report an error on invalid types" in {
// **string
checkType(StreamType(StreamType(ScalarType.string))) should not be empty
// []*string
checkType(ArrayType(StreamType(ScalarType.string))) should not be empty
// ?*string
checkType(OptionType(StreamType(ScalarType.string))) should not be empty
// ?[]*string
checkType(OptionType(ArrayType(StreamType(ScalarType.string)))) should not be empty
// [][]*string
checkType(OptionType(ArrayType(StreamType(ScalarType.string)))) should not be empty
// string
checkType(ScalarType.string) shouldBe empty
}
}

View File

@ -50,6 +50,10 @@ object Utils {
prog.apply(emptyS).run(blankCS).value._2
}
def getState(prog: Prog[State[CompilerState[cats.Id], *], Raw]): CompilerState[Id] = {
prog.apply(emptyS).run(blankCS).value._1
}
def getState(
startState: Raw
)(prog: Prog[State[CompilerState[cats.Id], *], Raw]): CompilerState[Id] = {