Commit f1991e76 by Amelin Konstantin

Add test cases for Template, fix render.

parent e7f90532
...@@ -5,6 +5,17 @@ import templates._ ...@@ -5,6 +5,17 @@ import templates._
object Main extends App { object Main extends App {
implicit def templateFactory(source: Node): Template = {
(source \ "trade").head.child
.filter {
case v: Elem => true
case _ => false
}(1).label match {
case "repo" => new RepoTemplate(source)
case v => throw new Exception("Undefined trade type")
}
}
val p = new PrettyPrinter(140, 2) val p = new PrettyPrinter(140, 2)
val sourceXml = XML.loadFile("src/main/resources/nsd/Repo NSD equity.xml") val sourceXml = XML.loadFile("src/main/resources/nsd/Repo NSD equity.xml")
val template = Template(sourceXml) val template = Template(sourceXml)
......
...@@ -2,16 +2,18 @@ package templates ...@@ -2,16 +2,18 @@ package templates
import scala.util.Try import scala.util.Try
import scala.xml.Node import scala.xml.Node
import templates.Template._
final class RepoTemplate(source: Node) extends TradeTemplate(source) { final class RepoTemplate(source: Node) extends TradeTemplate(source) {
trait ProductType
case object Equity extends ProductType
case object Bond extends ProductType
protected[this] def templateTrade: Node = { private[this] val productType = (source \ "trade" \ "repo" \ "productType").head.text.mkString match {
val productType = (source \ "trade" \ "repo" \ "productType").head.text.mkString match { case "Equity:Repo:EquityRepo" => Equity
case "Equity:Repo:EquityRepo" => Equity case "InterestRate:Repo:BondRepo" => Bond
case "InterestRate:Repo:BondRepo" => Bond }
}
protected[this] def templateTrade: Node = {
<fpml:trade> <fpml:trade>
<fpml:tradeHeader> <fpml:tradeHeader>
{ for (s <- source \ "trade" \ "tradeHeader" \ "partyTradeIdentifier") yield { { for (s <- source \ "trade" \ "tradeHeader" \ "partyTradeIdentifier") yield {
......
...@@ -64,26 +64,24 @@ abstract class Template(protected[this] val source: Node) { ...@@ -64,26 +64,24 @@ abstract class Template(protected[this] val source: Node) {
def template: Node def template: Node
def render: Node = { def render: Node = {
val rule1: RewriteRule = new RewriteRule { def attrIsEmpty(n: Node): Boolean = n match {
override def transform(n: Node): NodeSeq = { case v: Elem if v.child.isEmpty => v.attributes.isEmpty
val children = n.child.filter { case _ => n.attributes.isEmpty && n.child.forall(attrIsEmpty)
case c: Elem => true }
case _ => false
}
n match { val rule1: RewriteRule = new RewriteRule {
case v: Elem if v.attributes.isEmpty && children.nonEmpty && children.forall(_.text == msgNotFound) => override def transform(n: Node): NodeSeq = n match {
NodeSeq.Empty case v: Elem if v.attributes.nonEmpty && v.attributes.value.text.contains(msgNotFound) =>
case v: Elem if v.attributes.nonEmpty && v.attributes.value.text.contains(msgNotFound) => v.copy(attributes = v.attributes.filter(_.value.text != msgNotFound))
v.copy(attributes = v.attributes.filter(_.value.text != msgNotFound)) case _ => n
case _ => n
}
} }
} }
val rule2: RewriteRule = new RewriteRule { val rule2: RewriteRule = new RewriteRule {
override def transform(n: Node): NodeSeq = n match { override def transform(n: Node): NodeSeq = n match {
case v: Elem if v.text == msgNotFound => case v if v.text == msgNotFound =>
NodeSeq.Empty
case v: Elem if attrIsEmpty(v) && v.text.filterNot(_.isWhitespace).isEmpty =>
NodeSeq.Empty NodeSeq.Empty
case _ => n case _ => n
} }
...@@ -99,19 +97,7 @@ abstract class Template(protected[this] val source: Node) { ...@@ -99,19 +97,7 @@ abstract class Template(protected[this] val source: Node) {
} }
object Template { object Template {
def apply(source: Node)(implicit templateFactory: Node => Template): Template = templateFactory(source)
sealed trait ProductType
case object Equity extends ProductType
case object Bond extends ProductType
def apply(source: Node): Template = (source \ "trade").head.child
.filter {
case v: Elem => true
case _ => false
}(1).label match {
case "repo" => new RepoTemplate(source)
case v => throw new Exception("Undefined trade type")
}
} }
<?xml version="1.0"?>
<document
xmlns="https://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.w3schools.com test_valid.xsd">
<nonpublicExecutionReport>
<trade>
<tradeHeader>Header</tradeHeader>
<repo>
<title>Title</title>
<from href="From">From</from>
<to href="To">To</to>
</repo>
</trade>
</nonpublicExecutionReport>
</document>
\ No newline at end of file
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://www.w3schools.com"
xmlns="https://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="document" type="Document" />
<xs:complexType name="Document">
<xs:choice>
<xs:element name="nonpublicExecutionReport" type="MsgType" />
<xs:element name="nonpublicExecutionReportAsknowledgment" type="MsgType" />
</xs:choice>
</xs:complexType>
<xs:complexType name="MsgType">
<xs:sequence>
<xs:element name="trade" type="Trade" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Trade">
<xs:sequence>
<xs:element name="tradeHeader" type="xs:string"/>
<xs:choice>
<xs:element name="repo" type="Body"/>
<xs:element name="option" type="Body"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Body">
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="from" type="From" />
<xs:element name="to" type="To" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="From">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="href" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="To">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="href" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
\ No newline at end of file
...@@ -3,9 +3,10 @@ package templates ...@@ -3,9 +3,10 @@ package templates
import org.scalatest._ import org.scalatest._
import xmlvalid._ import xmlvalid._
import scala.xml.{Node, XML} import scala.util.Try
import scala.xml.{Elem, Node, XML}
class RepoSpec extends WordSpec { class TemplateSpec extends WordSpec {
"XMLValid for RTS example" should { "XMLValid for RTS example" should {
"successfully loadFile(xmlPath) with well formed and valid xml" in { "successfully loadFile(xmlPath) with well formed and valid xml" in {
val validXml = XMLValid("src/test/resources/templates/rts/fpml-recordkeeping-merged-schema.xsd") val validXml = XMLValid("src/test/resources/templates/rts/fpml-recordkeeping-merged-schema.xsd")
...@@ -40,8 +41,98 @@ class RepoSpec extends WordSpec { ...@@ -40,8 +41,98 @@ class RepoSpec extends WordSpec {
} }
} }
class MockTemplate(source: Node) extends Template(source) {
def template: Node = {
<document
xmlns="https://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.w3schools.com test_valid.xsd">
<nonpublicExecutionReport>
<trade>
<tradeHeader>{ get(Try { (source \\ "tradeHeader").head }) }</tradeHeader>
<repo>
<title>{ get(Try { (source \\ "repo" \ "title").head }) }</title>
<from href={ get(Try { (source \\ "repo" \ "from").head }, "href") }>
{ get(Try { (source \\ "repo" \ "from").head }) }
</from>
<to href={ get(Try { (source \\ "repo" \ "to").head }, "href") }>
{ get(Try { (source \\ "repo" \ "notExist").head }) }
</to>
</repo>
<notFoundpart>{ get(Try { (source \\ "notFoundpart").head }) }</notFoundpart>
<notFoundpartNested1>
<noElem>{ get(Try { (source \\ "notFoundpartNested1" \ "noElem").head }) }</noElem>
<noAttr href={ get(Try { (source \\ "notFoundpartNested1" \ "noAttr").head }, "href") } />
<noAttrAndElem href={ get(Try { (source \\ "notFoundpartNested1" \ "noAttrAndElem").head }, "href") }>
{ get(Try { (source \\ "notFoundpartNested1" \ "noAttrAndElem").head }) }
</noAttrAndElem>
</notFoundpartNested1>
<notFoundpartNested2>
<notFoundPartNested21>
<noElem>{ get(Try { (source \\ "notFoundpartNested21" \ "noElem").head }) }</noElem>
<noAttr href={ get(Try { (source \\ "notFoundpartNested21" \ "noAttr").head }, "href") } />
<noAttrAndElem href={ get(Try { (source \\ "notFoundpartNested21" \ "noAttrAndElem").head }, "href") }>
{ get(Try { (source \\ "notFoundpartNested21" \ "noAttrAndElem").head }) }
</noAttrAndElem>
</notFoundPartNested21>
</notFoundpartNested2>
</trade>
</nonpublicExecutionReport>
</document>
}
}
"Template" should {
"render valid xml against schema" in {
val sourceXml: Node = XML.loadFile("src/test/resources/templates/general/test_valid.xml")
val outputXml = new MockTemplate(sourceXml).render
val checkedXml = XMLValid("src/test/resources/templates/general/test_valid.xsd").loadString(outputXml.mkString)
assert(checkedXml.isInstanceOf[Node])
}
}
"RepoTemplate" should { it should {
"find template instance using source" in {
implicit def templateFactory(source: Node): Template = {
(source \\ "trade").head.child.filter {
case v: Elem => true
case _ => false
}(1).label match {
case "repo" => new MockTemplate(source)
case v => throw new Exception("Undefined trade type")
}
}
val sourceXml: Node = XML.loadFile("src/test/resources/templates/general/test_valid.xml")
val template = Template(sourceXml)
assert(template.isInstanceOf[Template])
}
}
it should {
"throw Exception if template type is undefined" in {
implicit def templateFactory(source: Node): Template = {
(source \\ "trade").head.child.filter {
case v: Elem => true
case _ => false
}(1).label match {
case "bond" => new MockTemplate(source)
case v => throw new Exception("Undefined trade type")
}
}
val sourceXml: Node = XML.loadFile("src/test/resources/templates/general/test_valid.xml")
assertThrows[Exception] {
val template = Template(sourceXml)
}
}
}
it should {
"generate valid RTS output xml using valid NSD source xml" ignore { "generate valid RTS output xml using valid NSD source xml" ignore {
val sourceXml: Node = XML.loadFile("src/test/resources/templates/nsd/Example repo NSD.xml") val sourceXml: Node = XML.loadFile("src/test/resources/templates/nsd/Example repo NSD.xml")
val outputXml = new RepoTemplate(sourceXml).template val outputXml = new RepoTemplate(sourceXml).template
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment