diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala
index bff968de7..1cb7a578d 100644
--- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala
+++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala
@@ -1,6 +1,7 @@
package code.api.ResourceDocs1_4_0
import java.util.Date
+
import code.api.Constant._
import code.api.Constant
import code.api.UKOpenBanking.v2_0_0.JSONFactory_UKOpenBanking_200
@@ -25,7 +26,7 @@ import com.openbankproject.commons.model
import com.openbankproject.commons.model.PinResetReason.{FORGOT, GOOD_SECURITY_PRACTICE}
import com.openbankproject.commons.model.enums.CardAttributeType
import com.openbankproject.commons.model.{UserAuthContextUpdateStatus, ViewBasic, _}
-import com.openbankproject.commons.util.ReflectUtils
+import com.openbankproject.commons.util.{ApiVersion, FieldNameApiVersions, ReflectUtils, RequiredArgs, RequiredInfo}
import scala.collection.immutable.List
@@ -432,7 +433,12 @@ object SwaggerDefinitionsJSON {
example_inbound_message = defaultJValue,
outboundAvroSchema = Some(defaultJValue),
inboundAvroSchema = Some(defaultJValue),
- adapter_implementation = adapterImplementationJson
+ adapter_implementation = adapterImplementationJson,
+ requiredFieldInfo = {
+ val fieldNameApiVersions = FieldNameApiVersions("data.bankId", List(ApiVersion.v3_1_0.toString))
+ val requiredInfo = RequiredInfo(List(fieldNameApiVersions))
+ Some(requiredInfo)
+ }
)
val messageDocsJson = MessageDocsJson(message_docs = List(messageDocJson))
diff --git a/obp-api/src/main/scala/code/api/util/CustomJsonFormats.scala b/obp-api/src/main/scala/code/api/util/CustomJsonFormats.scala
index 55b3f9cd9..f05903d3d 100644
--- a/obp-api/src/main/scala/code/api/util/CustomJsonFormats.scala
+++ b/obp-api/src/main/scala/code/api/util/CustomJsonFormats.scala
@@ -27,9 +27,9 @@ object CustomJsonFormats {
val formats: Formats = net.liftweb.json.DefaultFormats + BigDecimalSerializer + FiledRenameSerializer + ListResultSerializer + EnumValueSerializer + JsonAbleSerializer
- val losslessFormats: Formats = net.liftweb.json.DefaultFormats.lossless + BigDecimalSerializer + FiledRenameSerializer + ListResultSerializer + EnumValueSerializer
+ val losslessFormats: Formats = net.liftweb.json.DefaultFormats.lossless + BigDecimalSerializer + FiledRenameSerializer + ListResultSerializer + EnumValueSerializer + JsonAbleSerializer
- val emptyHintFormats = DefaultFormats.withHints(ShortTypeHints(List())) + BigDecimalSerializer + FiledRenameSerializer + ListResultSerializer + EnumValueSerializer
+ val emptyHintFormats = DefaultFormats.withHints(ShortTypeHints(List())) + BigDecimalSerializer + FiledRenameSerializer + ListResultSerializer + EnumValueSerializer + JsonAbleSerializer
implicit val nullTolerateFormats = formats + JNothingSerializer
@@ -37,7 +37,7 @@ object CustomJsonFormats {
val dateFormat = net.liftweb.json.DefaultFormats.dateFormat
override val typeHints = ShortTypeHints(rolesMappedToClasses)
- } + BigDecimalSerializer + FiledRenameSerializer + ListResultSerializer + EnumValueSerializer
+ } + BigDecimalSerializer + FiledRenameSerializer + ListResultSerializer + EnumValueSerializer + JsonAbleSerializer
}
object BigDecimalSerializer extends Serializer[BigDecimal] {
diff --git a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
index 7c0ff5bc0..44aa6c192 100644
--- a/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
+++ b/obp-api/src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
@@ -8,16 +8,13 @@ import code.api.v3_1_0.ListResult
import code.crm.CrmEvent.CrmEvent
import code.transactionrequests.TransactionRequestTypeCharge
import com.openbankproject.commons.model.{Product, _}
-import com.openbankproject.commons.util.{EnumValue, OBPEnumeration}
+import com.openbankproject.commons.util.{EnumValue, OBPEnumeration, ReflectUtils}
import net.liftweb.common.Full
import net.liftweb.json
import net.liftweb.json.{JDouble, JInt, JString}
import net.liftweb.json.JsonAST.{JArray, JBool, JObject, JValue}
import net.liftweb.util.StringHelpers
-import scala.reflect.runtime.currentMirror
-import scala.reflect.runtime.universe._
-
object JSONFactory1_4_0 {
@@ -403,19 +400,13 @@ object JSONFactory1_4_0 {
case v => v
}
- val r = currentMirror.reflect(extractedEntity)
val mapOfFields: Map[String, Any] = extractedEntity match {
case ListResult(name, results) => Map((name, results))
case JObject(jFields) => jFields.map(it => (it.name, it.value)).toMap
- case _ => r.symbol.typeSignature.members.toStream
- .collect { case s: TermSymbol if !s.isMethod => r.reflectField(s)}
- .map(r => r.symbol.name.toString.trim -> r.get)
- .toMap
+ case _ => ReflectUtils.getFieldValues(extractedEntity.asInstanceOf[AnyRef])()
}
-
-
val convertParamName = (name: String) => extractedEntity match {
case _ : JsonFieldReName => StringHelpers.snakify(name)
case _ => name
@@ -457,7 +448,9 @@ object JSONFactory1_4_0 {
case Some(i: String) => "\"" + key + """": {"type":"string"}"""
case List(i: String, _*) => "\"" + key + """": {"type": "array","items": {"type": "string"}}"""
case Some(List(i: String, _*)) => "\"" + key + """": {"type": "array","items": {"type": "string"}}"""
- //Int
+ case Array(i: String, _*) => "\"" + key + """": {"type": "array","items": {"type": "string"}}"""
+ case Some(Array(i: String, _*)) => "\"" + key + """": {"type": "array","items": {"type": "string"}}"""
+ //Int
case _: Int | _:JInt => "\"" + key + """": {"type":"integer"}"""
case Some(i: Int) => "\"" + key + """": {"type":"integer"}"""
case List(i: Int, _*) => "\"" + key + """": {"type": "array","items": {"type": "integer"}}"""
diff --git a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala
index fff9f68a0..43a7abdca 100644
--- a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala
+++ b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala
@@ -410,7 +410,7 @@ trait APIMethods220 {
messageDocs <- Full{connectorObject.messageDocs.toList}
} yield {
val json = JSONFactory220.createMessageDocsJson(messageDocs)
- successJsonResponse(Extraction.decompose(json))
+ successJsonResponse(Extraction.decompose(json)(CustomJsonFormats.formats))
}
}
}
diff --git a/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala b/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala
index 936e9f348..573399c32 100644
--- a/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala
+++ b/obp-api/src/main/scala/code/api/v2_2_0/JSONFactory2.2.0.scala
@@ -46,7 +46,7 @@ import code.model._
import com.openbankproject.commons.model.Product
import code.users.Users
import com.openbankproject.commons.model._
-import com.openbankproject.commons.util.{ReflectUtils, RequiredArgs, RequiredFieldValidation}
+import com.openbankproject.commons.util.{ReflectUtils, RequiredFieldValidation, RequiredInfo}
import net.liftweb.common.{Box, Full}
import net.liftweb.json.Extraction.decompose
import net.liftweb.json.JsonAST.JValue
@@ -830,7 +830,7 @@ object JSONFactory220 extends CustomJsonFormats {
outboundAvroSchema: Option[JValue] = None,
inboundAvroSchema: Option[JValue] = None,
adapter_implementation : AdapterImplementationJson,
- requiredFieldInfo: Map[String, RequiredArgs] = Map.empty
+ requiredFieldInfo: Option[RequiredInfo] = None
)
case class AdapterImplementationJson(
@@ -849,8 +849,6 @@ object JSONFactory220 extends CustomJsonFormats {
def createMessageDocJson(md: MessageDoc): MessageDocJson = {
val inBoundType = ReflectUtils.getType(md.exampleInboundMessage)
- val regex = Pattern.compile("""(code|com\.openbankproject\.commons)\..+""")
- def findRequiredInfoFor(tp: Type): Boolean = regex.matcher(tp.toString).matches()
MessageDocJson(
process = md.process,
@@ -868,7 +866,11 @@ object JSONFactory220 extends CustomJsonFormats {
md.adapterImplementation.map(_.group).getOrElse(""),
md.adapterImplementation.map(_.suggestedOrder).getOrElse(100)
),
- requiredFieldInfo = RequiredFieldValidation.getAllNestedRequiredInfo(inBoundType, findRequiredInfoFor)
+ requiredFieldInfo = {
+ val requiredArgses = RequiredFieldValidation.getAllNestedRequiredInfo(inBoundType)
+ val requiredInfo = RequiredInfo(requiredArgses)
+ Some(requiredInfo)
+ }
)
}
diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/util/Functions.scala b/obp-commons/src/main/scala/com/openbankproject/commons/util/Functions.scala
index 991b46075..67b6dcafb 100644
--- a/obp-commons/src/main/scala/com/openbankproject/commons/util/Functions.scala
+++ b/obp-commons/src/main/scala/com/openbankproject/commons/util/Functions.scala
@@ -1,5 +1,9 @@
package com.openbankproject.commons.util
+import java.util.regex.Pattern
+import scala.collection.{IterableLike, immutable}
+import scala.collection.generic.CanBuildFrom
+import scala.reflect.runtime.universe.Type
/**
* function utils
*/
@@ -14,4 +18,48 @@ object Functions {
def doNothing[T, D]: PartialFunction[T,D] = {
case _ if false => ???
}
+
+ def truePredicate[T]: T => Boolean = _ => true
+ def falsePredicate[T]: T => Boolean = _ => false
+
+ private val obpTypeNamePattern = Pattern.compile("""(code|com\.openbankproject\.commons)\..+""")
+
+ def isOBPType(tp: Type) = obpTypeNamePattern.matcher(tp.typeSymbol.fullName).matches()
+ def isOBPClass(clazz: Class[_]) = obpTypeNamePattern.matcher(clazz.getName).matches()
+
+ implicit class RichCollection[A, Repr](iterable: IterableLike[A, Repr]){
+ def distinctBy[B, That](f: A => B)(implicit canBuildFrom: CanBuildFrom[Repr, A, That]) = {
+ val builder = canBuildFrom(iterable.repr)
+ val set = scala.collection.mutable.Set[B]()
+ iterable.foreach(it => {
+ val calculatedElement = f(it)
+ if(set.add(calculatedElement)) {
+ builder += it
+ }
+ })
+ builder.result
+ }
+ def toMapByKey[K](f: A => K): immutable.Map[K, A] = {
+ val b = immutable.Map.newBuilder[K, A]
+ for (x <- iterable)
+ b += f(x) -> x
+
+ b.result()
+ }
+ def toMapByValue[V](f: A => V): immutable.Map[A, V] = {
+ val b = immutable.Map.newBuilder[A, V]
+ for (x <- iterable)
+ b += x -> f(x)
+
+ b.result()
+ }
+
+ def toMap[K, V](keyFn: A => K, valueFn: A => V): immutable.Map[K, V] = {
+ val b = immutable.Map.newBuilder[K, V]
+ for (x <- iterable)
+ b += keyFn(x) -> valueFn(x)
+
+ b.result()
+ }
+ }
}
diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/util/ReflectUtils.scala b/obp-commons/src/main/scala/com/openbankproject/commons/util/ReflectUtils.scala
index aac595315..57e68de43 100644
--- a/obp-commons/src/main/scala/com/openbankproject/commons/util/ReflectUtils.scala
+++ b/obp-commons/src/main/scala/com/openbankproject/commons/util/ReflectUtils.scala
@@ -58,9 +58,9 @@ object ReflectUtils {
val TermName(fieldName) = it.name
if(it.isLazy) {
// get lazy value
- fieldName -> instanceMirror.reflectMethod(it.asMethod)()
+ fieldName.trim -> instanceMirror.reflectMethod(it.asMethod)()
} else {
- fieldName -> instanceMirror.reflectField(it).get
+ fieldName.trim -> instanceMirror.reflectField(it).get
}
})
.toMap
diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/util/RequiredFieldValidation.scala b/obp-commons/src/main/scala/com/openbankproject/commons/util/RequiredFieldValidation.scala
index 0b26ae784..a78a56ed5 100644
--- a/obp-commons/src/main/scala/com/openbankproject/commons/util/RequiredFieldValidation.scala
+++ b/obp-commons/src/main/scala/com/openbankproject/commons/util/RequiredFieldValidation.scala
@@ -1,12 +1,13 @@
package com.openbankproject.commons.util
+import java.util.Objects
+
import com.openbankproject.commons.util.ApiVersion.allVersion
-import net.liftweb.json.JValue
-import net.liftweb.json.JsonAST.{JArray, JString}
+import net.liftweb.json.JsonAST.{JArray, JField, JObject, JString}
import scala.annotation.StaticAnnotation
-import scala.collection.immutable.ListMap
import scala.reflect.runtime.universe._
+import Functions.RichCollection
/**
@@ -37,8 +38,36 @@ class OBPRequired(value: Array[ApiVersion] = Array(ApiVersion.allVersion),
exclude: Array[ApiVersion] = Array.empty
) extends StaticAnnotation
+/**
+ * cooperate with RequiredInfo to deal with generate swagger doc and json serialization problem (show wrong structure of json)
+ * @param filedName
+ * @param apiVersions
+ */
+case class FieldNameApiVersions(filedName: String, apiVersions: List[String])
-case class RequiredArgs(include: Array[ApiVersion],
+/**
+ * cooperate with RequiredInfo to deal with generate swagger doc and json serialization problem (show wrong structure of json)
+ * @param infos
+ */
+case class RequiredInfo(infos: List[FieldNameApiVersions]) extends JsonAble {
+
+ override def toJValue: JObject = {
+ val jFields = infos.map(info => JField(
+ info.filedName,
+ JArray(info.apiVersions.map(JString(_))))
+ )
+ JObject(jFields)
+ }
+}
+
+object RequiredInfo {
+ def apply(requiredArgs: Seq[RequiredArgs]): RequiredInfo = {
+ val fieldNameApiVersionses = requiredArgs.toList.map(arg => FieldNameApiVersions(arg.fieldPath, arg.apiVersions))
+ RequiredInfo(fieldNameApiVersionses)
+ }
+}
+
+case class RequiredArgs(fieldPath:String, include: Array[ApiVersion],
exclude: Array[ApiVersion] = Array.empty) extends JsonAble {
{
val includeAll = include.contains(allVersion)
@@ -69,10 +98,10 @@ case class RequiredArgs(include: Array[ApiVersion],
}
override def equals(obj: Any): Boolean = obj match {
- case RequiredArgs(inc, exc) => include.sameElements(inc) && exclude.sameElements(exc)
+ case RequiredArgs(path, inc, exc) => Objects.equals(fieldPath, path) && include.sameElements(inc) && exclude.sameElements(exc)
case _ => false
}
- override def toJValue: JValue = (include, exclude) match {
+ override val toJValue: JArray = (include, exclude) match {
case (_, Array()) =>
val includeList = include.toList.map(_.toString).map(JString(_))
JArray(includeList)
@@ -80,6 +109,10 @@ case class RequiredArgs(include: Array[ApiVersion],
val excludeList = include.toList.map("-" + _.toString).map(JString(_))
JArray(excludeList)
}
+ val apiVersions: List[String] = (include, exclude) match {
+ case (_, Array()) => include.toList.map(_.toString)
+ case _ => include.toList.map("-" + _.toString)
+ }
}
object RequiredFieldValidation {
@@ -123,35 +156,43 @@ object RequiredFieldValidation {
* @param tp to process type
* @return map of field name to RequiredArgs
*/
- def getAnnotations(tp: Type): Map[String, RequiredArgs] = {
+ def getAnnotations(tp: Type): Iterable[RequiredArgs] = {
val members = tp.members
val constructors = members.filter(_.isConstructor).map(_.asMethod)
- def getFieldNameAndAnnotation(symbol: Symbol): List[(String, RequiredArgs)] = {
- (symbol.name.decodedName, getAnnotation(symbol)) match{
- case (TermName(name), Some(requiredArgs)) => List(name.trim -> requiredArgs)
- case _ => Nil
+ def getFieldNameAndAnnotation(symbol: Symbol): Option[RequiredArgs] = {
+ val fieldName = symbol.name.decodedName.toString.trim
+ getAnnotation(fieldName, symbol) match{
+ case some: Some[RequiredArgs] => some
+ case _ => None
}
}
// constructor param name to RequiredArgs
- val constructorParamToRequiredArgs: Map[String, RequiredArgs] = constructors
+ val constructorParamToRequiredArgs: Iterable[RequiredArgs] = constructors
.flatMap(_.paramLists.head) // all the constructor's parameters
- .flatMap(getFieldNameAndAnnotation)
- .toMap
+ .map(getFieldNameAndAnnotation)
+ .collect {
+ case Some(requiredArgs) => requiredArgs
+ }
+ val constructorParamNames = constructorParamToRequiredArgs.map(_.fieldPath).toSet
// those annotated field name to RequiredArgs
- val annotatedFieldNameToRequiredArgs: Map[String, RequiredArgs] =
- members.filter(it => {
- !it.isConstructor && !constructorParamToRequiredArgs.contains(it.name.decodedName.toString.trim)
- })
- .flatMap(getFieldNameAndAnnotation)
- .toMap
- val requiredFields: Map[String, RequiredArgs] = constructorParamToRequiredArgs ++ annotatedFieldNameToRequiredArgs
- requiredFields
+ val annotatedFieldNameToRequiredArgs: Iterable[RequiredArgs] =
+ members
+ .filter(it => {
+ !it.isConstructor && !constructorParamNames.contains(it.name.decodedName.toString.trim)
+ })
+ .map(getFieldNameAndAnnotation)
+ .collect {
+ case Some(requiredArgs) => requiredArgs
+ }
+ .distinctBy(_.fieldPath)
+
+ constructorParamToRequiredArgs ++ annotatedFieldNameToRequiredArgs
}
- def getAnnotation(symbol: Symbol): Option[RequiredArgs] = {
+ def getAnnotation(fieldName: String, symbol: Symbol): Option[RequiredArgs] = {
val annotation: Option[Annotation] =
(symbol :: symbol.overrides)
.flatMap(_.annotations)
@@ -159,47 +200,45 @@ object RequiredFieldValidation {
annotation.map { it: Annotation =>
it.tree.children.tail match {
- case (include: Tree)::(exclude: Tree)::Nil => RequiredArgs(getVersions(include), getVersions(exclude))
+ case (include: Tree)::(exclude: Tree)::Nil => RequiredArgs(fieldName, getVersions(include), getVersions(exclude))
}
}
}
- private def getAllNestedRequiredInfo(tp: Type,
- fieldName: String,
- predicate: Type => Boolean
- ): Map[String, RequiredArgs] = {
+ def getAllNestedRequiredInfo(tp: Type,
+ predicate: Type => Boolean = Functions.isOBPType,
+ fieldName: String = null
+ ): Seq[RequiredArgs] = {
if(!predicate(tp)) {
- return Map.empty
+ return Nil
}
- val fieldToRequiredInfo: Map[String, RequiredArgs] = getAnnotations(tp)
+ val fieldToRequiredInfo: Iterable[RequiredArgs] = getAnnotations(tp)
// current type's fields full path to RequiredInfo
val currentPathToRequiredInfo = fieldName match {
case null => fieldToRequiredInfo
- case _ => fieldToRequiredInfo.map(it=> (s"$fieldName.${it._1}", it._2))
+ case _ => fieldToRequiredInfo.map(it=> it.copy(fieldPath = s"$fieldName.${it.fieldPath}"))
}
// find all sub fields RequiredInfo
- val subPathToRequiredInfo: Map[String, RequiredArgs] = tp.members.collect {
- case m: MethodSymbolApi if m.isGetter => (m.name.decodedName.toString.trim, ReflectUtils.getNestFirstTypeArg(m.returnType))
- case m: TermSymbolApi if m.isCaseAccessor || m.isVal => (m.name.decodedName.toString.trim, m.info)
- }.filter(tuple => predicate(tuple._2))
+ val subPathToRequiredInfo: Iterable[RequiredArgs] = tp.members.collect {
+ case m: MethodSymbolApi if m.isGetter => {
+ (m.name.decodedName.toString.trim, ReflectUtils.getNestFirstTypeArg(m.returnType))
+ }
+ case m: TermSymbolApi if m.isCaseAccessor || m.isVal => {
+ (m.name.decodedName.toString.trim, ReflectUtils.getNestFirstTypeArg(m.info))
+ }
+ } .filter(tuple => predicate(tuple._2))
+ .distinctBy(_._1)
.flatMap(pair => {
val (memberName, membersType) = pair
val subFieldName = if(fieldName == null) memberName else s"$fieldName.$memberName"
- getAllNestedRequiredInfo(membersType, subFieldName, predicate)
- }).toMap
+ getAllNestedRequiredInfo(membersType, predicate, subFieldName)
+ })
- currentPathToRequiredInfo ++ subPathToRequiredInfo
- }
-
- def getAllNestedRequiredInfo(tp: Type,
- predicate: Type => Boolean = _ => true
- ): Map[String, RequiredArgs] = {
- val unSortedResult = getAllNestedRequiredInfo(tp, null, predicate)
- ListMap(unSortedResult.toSeq.sortBy(_._1): _*)
+ (currentPathToRequiredInfo ++ subPathToRequiredInfo).toSeq.sortBy(_.fieldPath)
}
}
diff --git a/obp-commons/src/test/scala/com/openbankproject/commons/util/RequiredFieldValidationTest.scala b/obp-commons/src/test/scala/com/openbankproject/commons/util/RequiredFieldValidationTest.scala
index 16da54be4..8fd4f94fa 100644
--- a/obp-commons/src/test/scala/com/openbankproject/commons/util/RequiredFieldValidationTest.scala
+++ b/obp-commons/src/test/scala/com/openbankproject/commons/util/RequiredFieldValidationTest.scala
@@ -1,65 +1,66 @@
package com.openbankproject.commons.util
-import com.openbankproject.commons.util.ApiVersion
import com.openbankproject.commons.util.ApiVersion._
import org.scalatest.{FlatSpec, Matchers, Tag}
import org.scalatest.PartialFunctionValues._
import scala.reflect.runtime.universe._
+import Functions.RichCollection
class RequiredFieldValidationTest extends FlatSpec with Matchers {
object tag extends Tag("RequiredFieldValidation")
"when annotated at constructor param and overriding val" should "all the annotations be extract by call RequiredFieldValidation.getAnnotations" taggedAs tag in {
- val symbols = RequiredFieldValidation.getAnnotations(typeOf[Bar])
+ val symbols = RequiredFieldValidation.getAnnotations(typeOf[Bar]).toMapByKey(_.fieldPath)
symbols should have size 3
- symbols("name") should equal(RequiredArgs(Array(ApiVersion.allVersion), Array(v3_0_0)))
+ symbols("name") should equal(RequiredArgs("name", Array(ApiVersion.allVersion), Array(v3_0_0)))
symbols("age") should equal (
- RequiredArgs(Array(v2_0_0, v1_2_1, v1_4_0), Array.empty)
+ RequiredArgs("age", Array(v2_0_0, v1_2_1, v1_4_0), Array.empty)
)
- symbols("email") should equal(RequiredArgs(Array(ApiVersion.allVersion), Array()))
+ symbols("email") should equal(RequiredArgs("email", Array(ApiVersion.allVersion), Array()))
}
"method RequiredFieldValidation.getAllNestedRequiredInfo" should "extract all nested required info" taggedAs tag in {
- val stringToArgs: Map[String, RequiredArgs] = RequiredFieldValidation.getAllNestedRequiredInfo(typeOf[Outer])
+ val requiredArgses = RequiredFieldValidation.getAllNestedRequiredInfo(typeOf[Outer])
+ val stringToArgs: Map[String, RequiredArgs] = requiredArgses.toMapByKey(_.fieldPath)
- val expectedRequireFooAnnoInfo = RequiredArgs(Array( v1_4_0))
- stringToArgs.valueAt("requireFoo") should equal (expectedRequireFooAnnoInfo)
+ val expectedRequireFooAnnoInfo = RequiredArgs("", Array( v1_4_0))
+ stringToArgs.valueAt("requireFoo") should equal (expectedRequireFooAnnoInfo.copy(fieldPath = "requireFoo"))
- val expectedNameAnnoInfo = RequiredArgs(Array(ApiVersion.allVersion))
- val expectedAgeAnnoInfo = RequiredArgs(Array(v2_0_0, v1_2_1, v1_4_0))
- val expectedEmailAnnoInfo = RequiredArgs(Array(ApiVersion.allVersion), Array(v2_0_0))
+ val expectedNameAnnoInfo = RequiredArgs("", Array(ApiVersion.allVersion))
+ val expectedAgeAnnoInfo = RequiredArgs("", Array(v2_0_0, v1_2_1, v1_4_0))
+ val expectedEmailAnnoInfo = RequiredArgs("", Array(ApiVersion.allVersion), Array(v2_0_0))
- stringToArgs.valueAt("foo.name") should equal (expectedNameAnnoInfo)
- stringToArgs.valueAt("foo.age") should equal (expectedAgeAnnoInfo)
- stringToArgs.valueAt("foo.email") should equal (expectedEmailAnnoInfo)
+ stringToArgs.valueAt("foo.name") should equal (expectedNameAnnoInfo.copy(fieldPath = "foo.name"))
+ stringToArgs.valueAt("foo.age") should equal (expectedAgeAnnoInfo.copy(fieldPath = "foo.age"))
+ stringToArgs.valueAt("foo.email") should equal (expectedEmailAnnoInfo.copy(fieldPath = "foo.email"))
- stringToArgs.valueAt("requireFoo.name") should equal (expectedNameAnnoInfo)
- stringToArgs.valueAt("requireFoo.age") should equal (expectedAgeAnnoInfo)
- stringToArgs.valueAt("requireFoo.email") should equal (expectedEmailAnnoInfo)
+ stringToArgs.valueAt("requireFoo.name") should equal (expectedNameAnnoInfo.copy(fieldPath = "requireFoo.name"))
+ stringToArgs.valueAt("requireFoo.age") should equal (expectedAgeAnnoInfo.copy(fieldPath = "requireFoo.age"))
+ stringToArgs.valueAt("requireFoo.email") should equal (expectedEmailAnnoInfo.copy(fieldPath = "requireFoo.email"))
- stringToArgs.valueAt("list.name") should equal (expectedNameAnnoInfo)
- stringToArgs.valueAt("list.age") should equal (expectedAgeAnnoInfo)
- stringToArgs.valueAt("list.email") should equal (expectedEmailAnnoInfo)
+ stringToArgs.valueAt("list.name") should equal (expectedNameAnnoInfo.copy(fieldPath = "list.name"))
+ stringToArgs.valueAt("list.age") should equal (expectedAgeAnnoInfo.copy(fieldPath = "list.age"))
+ stringToArgs.valueAt("list.email") should equal (expectedEmailAnnoInfo.copy(fieldPath = "list.email"))
- stringToArgs.valueAt("array.name") should equal (expectedNameAnnoInfo)
- stringToArgs.valueAt("array.age") should equal (expectedAgeAnnoInfo)
- stringToArgs.valueAt("array.email") should equal (expectedEmailAnnoInfo)
+ stringToArgs.valueAt("array.name") should equal (expectedNameAnnoInfo.copy(fieldPath = "array.name"))
+ stringToArgs.valueAt("array.age") should equal (expectedAgeAnnoInfo.copy(fieldPath = "array.age"))
+ stringToArgs.valueAt("array.email") should equal (expectedEmailAnnoInfo.copy(fieldPath = "array.email"))
- val expectedMiddleRequiredAnnoInfo = RequiredArgs(Array(ApiVersion.allVersion))
- stringToArgs.valueAt("middle.middleRequired") should equal (expectedMiddleRequiredAnnoInfo)
+ val expectedMiddleRequiredAnnoInfo = RequiredArgs("", Array(ApiVersion.allVersion))
+ stringToArgs.valueAt("middle.middleRequired") should equal (expectedMiddleRequiredAnnoInfo.copy(fieldPath = "middle.middleRequired"))
- stringToArgs.valueAt("middle.middleRequired.name") should equal (expectedNameAnnoInfo)
- stringToArgs.valueAt("middle.middleRequired.age") should equal (expectedAgeAnnoInfo)
- stringToArgs.valueAt("middle.middleRequired.email") should equal (expectedEmailAnnoInfo)
+ stringToArgs.valueAt("middle.middleRequired.name") should equal (expectedNameAnnoInfo.copy(fieldPath = "middle.middleRequired.name"))
+ stringToArgs.valueAt("middle.middleRequired.age") should equal (expectedAgeAnnoInfo.copy(fieldPath = "middle.middleRequired.age"))
+ stringToArgs.valueAt("middle.middleRequired.email") should equal (expectedEmailAnnoInfo.copy(fieldPath = "middle.middleRequired.email"))
- stringToArgs.valueAt("middle.middleNoRequire.name") should equal (expectedNameAnnoInfo)
- stringToArgs.valueAt("middle.middleNoRequire.age") should equal (expectedAgeAnnoInfo)
- stringToArgs.valueAt("middle.middleNoRequire.email") should equal (expectedEmailAnnoInfo)
+ stringToArgs.valueAt("middle.middleNoRequire.name") should equal (expectedNameAnnoInfo.copy(fieldPath = "middle.middleNoRequire.name"))
+ stringToArgs.valueAt("middle.middleNoRequire.age") should equal (expectedAgeAnnoInfo.copy(fieldPath = "middle.middleNoRequire.age"))
+ stringToArgs.valueAt("middle.middleNoRequire.email") should equal (expectedEmailAnnoInfo.copy(fieldPath = "middle.middleNoRequire.email"))
stringToArgs should have size (20)
}
diff --git a/pom.xml b/pom.xml
index 2f0653469..eb822f733 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
2011
2.12
- 2.12.10
+ 2.12.6
2.5.19
0.22
1.1.0