Skip to content

Commit

Permalink
Started work on Value AST #1 (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
DamianReeves authored Mar 5, 2020
1 parent 8db7797 commit 653914c
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 22 deletions.
10 changes: 9 additions & 1 deletion build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@ class CoreModule(val crossScalaVersion: String)
object test extends Tests with MorphirTestModule {}
}

trait MorphirModule extends ScalafmtModule { this: ScalaModule => }
trait MorphirModule extends ScalafmtModule with CrossScalaModule {
def scalacOptions =
Seq(
"-unchecked",
"-deprecation",
"-feature",
"-language:implicitConversions"
) ++ Seq("-encoding", "utf8")
}

trait MorphirTestModule extends TestModule {
def ivyDeps = Agg(
Expand Down
4 changes: 2 additions & 2 deletions core/src/com/morganstanley/morphir/ir/Path.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ object Path {

def isPrefixOf(prefix: Path, path: Path): Boolean = (prefix, path) match {
// empty path is a prefix of any other path
case (Path.empty, _) => true
case (Path(Nil), _) => true
// empty path has no prefixes except the empty prefix captured above
case (_, Path.empty) => false
case (_, Path(Nil)) => false
case (Path(prefixHead :: prefixTail), Path(pathHead :: pathTail)) =>
if (prefixHead == pathHead)
isPrefixOf(Path(prefixTail), Path(pathTail))
Expand Down
39 changes: 39 additions & 0 deletions core/src/com/morganstanley/morphir/ir/advanced/Value.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.morganstanley.morphir.ir.advanced
import com.morganstanley.morphir.ir.FQName

object value {
sealed abstract class Value[+X]
object Value {
type Lit = com.morganstanley.morphir.ir.advanced.value.Literal

case class Literal[X](value: Lit, extra: X) extends Value[X]
case class Constructor[X](fullyQualifiedName: FQName, extra: X)
extends Value[X]
}

sealed abstract class Literal {
def isBoolLiteral: Boolean = false
def isCharLiteral: Boolean = false
def isStringLiteral: Boolean = false
def isIntLiteral: Boolean = false
def isFloatLiteral: Boolean = false
}

object Literal {
case class BoolLiteral(value: Boolean) extends Literal {
override def isBoolLiteral: Boolean = true
}
case class CharLiteral(value: Char) extends Literal {
override def isCharLiteral: Boolean = true
}
case class StringLiteral(value: String) extends Literal {
override def isStringLiteral: Boolean = true
}
case class IntLiteral(value: Int) extends Literal {
override def isIntLiteral: Boolean = true
}
case class FloatLiteral(value: Float) extends Literal {
override def isFloatLiteral: Boolean = true
}
}
}
34 changes: 15 additions & 19 deletions core/test/src/com/morganstanley/morphir/ir/NameSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,46 @@ package com.morganstanley.morphir.ir
import zio.test._
import zio.test.Assertion._
import zio.test.environment._
import scala.language.implicitConversions

object NameSpec extends DefaultRunnableSpec {
def spec =
suite("NameSpec")(
suite("Make a Name from a string and check that:")(
suite("Name should be creatable from a single word that:")(
test("Starts with a capital letter") {
assert(
Name.fromString("Marco"),
assert(Name.fromString("Marco"))(
equalTo(Name(List("marco")))
)
},
test("Is all lowercase") {
assert(Name.fromString("polo"), equalTo(Name(List("polo"))))
assert(Name.fromString("polo"))(equalTo(Name(List("polo"))))
}
),
suite("Name should be creatable from compound words that:")(
test("Are formed from a snake case word") {
assert(
Name.fromString("super_mario_world"),
assert(Name.fromString("super_mario_world"))(
equalTo(Name(List("super", "mario", "world")))
)
},
test("Contain many kinds of word delimiters") {
val result = Name.fromString("fooBar_baz 123")
assert(result, equalTo(Name(List("foo", "bar", "baz", "123"))))
assert(result)(equalTo(Name(List("foo", "bar", "baz", "123"))))
},
test("Are formed from a camel-cased string") {
val result = Name.fromString("valueInUSD")
assert(result, equalTo(Name(List("value", "in", "u", "s", "d"))))
assert(result)(equalTo(Name(List("value", "in", "u", "s", "d"))))
},
test("Are formed from a title-cased string") {
val result = Name.fromString("ValueInUSD")
assert(result, equalTo(Name(List("value", "in", "u", "s", "d"))))
assert(result)(equalTo(Name(List("value", "in", "u", "s", "d"))))
},
test("Are have a number in the middle") {
val result = Name.fromString("Nintendo64VideoGameSystem")
assert(
result,
test("Have a number in the middle") {
assert(Name.fromString("Nintendo64VideoGameSystem"))(
equalTo(Name(List("nintendo", "64", "video", "game", "system")))
)
},
test("Complete and utter nonsense") {
assert(Name.fromString("_-%"), equalTo(Name(List.empty)))
assert(Name.fromString("_-%"))(equalTo(Name(List.empty)))
}
)
),
Expand All @@ -55,27 +51,27 @@ object NameSpec extends DefaultRunnableSpec {
"When the name was originally constructed from a snake-case string"
) {
val sut = Name.fromString("snake_case_input")
assert(Name.toTitleCase(sut), equalTo("SnakeCaseInput"))
assert(Name.toTitleCase(sut))(equalTo("SnakeCaseInput"))
},
test(
"When the name was originally constructed from a camel-case string"
) {
val sut = Name.fromString("camelCaseInput")
assert(Name.toTitleCase(sut), equalTo("CamelCaseInput"))
assert(Name.toTitleCase(sut))(equalTo("CamelCaseInput"))
}
),
suite("Name should be convertible to a camel-case string:")(
test(
"When the name was originally constructed from a snake-case string"
) {
val sut = Name.fromString("snake_case_input")
assert(Name.toCamelCase(sut), equalTo("snakeCaseInput"))
assert(Name.toCamelCase(sut))(equalTo("snakeCaseInput"))
},
test(
"When the name was originally constructed from a camel-case string"
) {
val sut = Name.fromString("camelCaseInput")
assert(Name.toCamelCase(sut), equalTo("camelCaseInput"))
assert(Name.toCamelCase(sut))(equalTo("camelCaseInput"))
}
),
suite("Name should be convertible to snake-case")(
Expand Down Expand Up @@ -105,7 +101,7 @@ object NameSpec extends DefaultRunnableSpec {
suite("Name toHumanWords should provide a list of words from a Name")(
test("When the name is from a camelCase string") {
val sut = Name.fromString("ValueInUSD")
assert(Name.toHumanWords(sut), equalTo(List("value", "in", "USD")))
assert(Name.toHumanWords(sut))(equalTo(List("value", "in", "USD")))
}
)
)
Expand Down
172 changes: 172 additions & 0 deletions core/test/src/com/morganstanley/morphir/ir/advanced/ValueSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package com.morganstanley.morphir.ir.advanced

import zio.test._
import zio.test.Assertion._
import zio.test.environment._

object ValueSpec extends DefaultRunnableSpec {
def spec = suite("ValueSpec")(
suite("Literals")(
suite("Given SUT is a BoolLiteral")(
testM("Then SUT.isBoolLiteral should be true") {
check(Gen.boolean) { input =>
val sut = value.Literal.BoolLiteral(input)
assert(sut.isBoolLiteral)(isTrue)
}
},
testM("Then SUT.isCharLiteral should be false") {
check(Gen.boolean) { input =>
val sut = value.Literal.BoolLiteral(input)
assert(sut.isCharLiteral)(isFalse)
}
},
testM("Then SUT.isFloatLiteral should be false") {
check(Gen.boolean) { input =>
val sut = value.Literal.BoolLiteral(input)
assert(sut.isFloatLiteral)(isFalse)
}
},
testM("Then SUT.isIntLiteral should be false") {
check(Gen.boolean) { input =>
val sut = value.Literal.BoolLiteral(input)
assert(sut.isIntLiteral)(isFalse)
}
},
testM("Then SUT.isStringLiteral should be false") {
check(Gen.boolean) { input =>
val sut = value.Literal.BoolLiteral(input)
assert(sut.isStringLiteral)(isFalse)
}
}
),
suite("Given SUT is a CharLiteral")(
testM("Then SUT.isBoolLiteral should be false") {
check(Gen.anyChar) { input =>
val sut = value.Literal.CharLiteral(input)
assert(sut.isBoolLiteral)(isFalse)
}
},
testM("Then SUT.isCharLiteral should be false") {
check(Gen.anyChar) { input =>
val sut = value.Literal.CharLiteral(input)
assert(sut.isCharLiteral)(isTrue)
}
},
testM("Then SUT.isFloatLiteral should be false") {
check(Gen.anyChar) { input =>
val sut = value.Literal.CharLiteral(input)
assert(sut.isFloatLiteral)(isFalse)
}
},
testM("Then SUT.isIntLiteral should be false") {
check(Gen.anyChar) { input =>
val sut = value.Literal.CharLiteral(input)
assert(sut.isIntLiteral)(isFalse)
}
},
testM("Then SUT.isStringLiteral should be false") {
check(Gen.anyChar) { input =>
val sut = value.Literal.CharLiteral(input)
assert(sut.isStringLiteral)(isFalse)
}
}
),
suite("Given SUT is a FloatLiteral")(
testM("Then SUT.isBoolLiteral should be false") {
check(Gen.anyFloat) { input =>
val sut = value.Literal.FloatLiteral(input)
assert(sut.isBoolLiteral)(isFalse)
}
},
testM("Then SUT.isCharLiteral should be false") {
check(Gen.anyFloat) { input =>
val sut = value.Literal.FloatLiteral(input)
assert(sut.isCharLiteral)(isFalse)
}
},
testM("Then SUT.isFloatLiteral should be false") {
check(Gen.anyFloat) { input =>
val sut = value.Literal.FloatLiteral(input)
assert(sut.isFloatLiteral)(isTrue)
}
},
testM("Then SUT.isIntLiteral should be false") {
check(Gen.anyFloat) { input =>
val sut = value.Literal.FloatLiteral(input)
assert(sut.isIntLiteral)(isFalse)
}
},
testM("Then SUT.isStringLiteral should be false") {
check(Gen.anyFloat) { input =>
val sut = value.Literal.FloatLiteral(input)
assert(sut.isStringLiteral)(isFalse)
}
}
),
suite("Given SUT is a IntLiteral")(
testM("Then SUT.isBoolLiteral should be false") {
check(Gen.anyInt) { input =>
val sut = value.Literal.IntLiteral(input)
assert(sut.isBoolLiteral)(isFalse)
}
},
testM("Then SUT.isCharLiteral should be false") {
check(Gen.anyInt) { input =>
val sut = value.Literal.IntLiteral(input)
assert(sut.isCharLiteral)(isFalse)
}
},
testM("Then SUT.isFloatLiteral should be false") {
check(Gen.anyInt) { input =>
val sut = value.Literal.IntLiteral(input)
assert(sut.isFloatLiteral)(isFalse)
}
},
testM("Then SUT.isIntLiteral should be false") {
check(Gen.anyInt) { input =>
val sut = value.Literal.IntLiteral(input)
assert(sut.isIntLiteral)(isTrue)
}
},
testM("Then SUT.isStringLiteral should be false") {
check(Gen.anyInt) { input =>
val sut = value.Literal.IntLiteral(input)
assert(sut.isStringLiteral)(isFalse)
}
}
),
suite("Given SUT is a StringLiteral")(
testM("Then SUT.isBoolLiteral should be false") {
check(Gen.anyString) { input =>
val sut = value.Literal.StringLiteral(input)
assert(sut.isBoolLiteral)(isFalse)
}
},
testM("Then SUT.isCharLiteral should be false") {
check(Gen.anyString) { input =>
val sut = value.Literal.StringLiteral(input)
assert(sut.isCharLiteral)(isFalse)
}
},
testM("Then SUT.isFloatLiteral should be false") {
check(Gen.anyString) { input =>
val sut = value.Literal.StringLiteral(input)
assert(sut.isFloatLiteral)(isFalse)
}
},
testM("Then SUT.isIntLiteral should be false") {
check(Gen.anyString) { input =>
val sut = value.Literal.StringLiteral(input)
assert(sut.isIntLiteral)(isFalse)
}
},
testM("Then SUT.isStringLiteral should be false") {
check(Gen.anyString) { input =>
val sut = value.Literal.StringLiteral(input)
assert(sut.isStringLiteral)(isTrue)
}
}
)
)
)
}

0 comments on commit 653914c

Please sign in to comment.