forked from loafle/openapi-generator-original
migrated to json4s
This commit is contained in:
parent
25837e3367
commit
87bad7b36d
@ -16,7 +16,7 @@ libraryDependencies ++= Seq(
|
||||
"org.scalatra" % "scalatra-specs2" % "2.2.0-SNAPSHOT" % "test",
|
||||
"org.scalatra" % "scalatra-swagger" % "2.2.0-SNAPSHOT",
|
||||
"org.scalatra" % "scalatra-json" % "2.2.0-SNAPSHOT",
|
||||
"org.json4s" %% "json4s-jackson" % "3.0.0-SNAPSHOT",
|
||||
"org.json4s" %% "json4s-jackson" % "3.0.0",
|
||||
"com.wordnik" % "swagger-core_2.9.1" % "1.1.1-SNAPSHOT",
|
||||
"ch.qos.logback" % "logback-classic" % "1.0.6" % "runtime",
|
||||
"org.eclipse.jetty" % "jetty-webapp" % "8.1.5.v20120716" % "container",
|
||||
|
@ -129,12 +129,7 @@ class BasicJavaGenerator extends BasicGenerator {
|
||||
case "List" => {
|
||||
val inner = {
|
||||
obj.items match {
|
||||
case Some(items) => {
|
||||
if(items.ref != null)
|
||||
items.ref
|
||||
else
|
||||
items.`type`
|
||||
}
|
||||
case Some(items) => items.ref.getOrElse(items.`type`)
|
||||
case _ => throw new Exception("no inner type defined")
|
||||
}
|
||||
}
|
||||
@ -159,12 +154,7 @@ class BasicJavaGenerator extends BasicGenerator {
|
||||
case "List" => {
|
||||
val inner = {
|
||||
obj.items match {
|
||||
case Some(items) => {
|
||||
if(items.ref != null)
|
||||
items.ref
|
||||
else
|
||||
items.`type`
|
||||
}
|
||||
case Some(items) => items.ref.getOrElse(items.`type`)
|
||||
case _ => throw new Exception("no inner type defined")
|
||||
}
|
||||
}
|
||||
|
@ -139,12 +139,7 @@ class BasicPythonGenerator extends BasicGenerator {
|
||||
case "list" => {
|
||||
val inner = {
|
||||
obj.items match {
|
||||
case Some(items) => {
|
||||
if(items.ref != null)
|
||||
items.ref
|
||||
else
|
||||
items.`type`
|
||||
}
|
||||
case Some(items) => items.ref.getOrElse(items.`type`)
|
||||
case _ => throw new Exception("no inner type defined")
|
||||
}
|
||||
}
|
||||
|
@ -78,12 +78,7 @@ class BasicScalaGenerator extends BasicGenerator {
|
||||
case "Array" => {
|
||||
val inner = {
|
||||
obj.items match {
|
||||
case Some(items) => {
|
||||
if(items.ref != null)
|
||||
items.ref
|
||||
else
|
||||
items.`type`
|
||||
}
|
||||
case Some(items) => items.ref.getOrElse(items.`type`)
|
||||
case _ => throw new Exception("no inner type defined")
|
||||
}
|
||||
}
|
||||
|
@ -364,12 +364,8 @@ class Codegen(config: CodegenConfig) {
|
||||
// import the container
|
||||
imports += Map("import" -> dt)
|
||||
propertyDocSchema.items match {
|
||||
case Some(items) => {
|
||||
if(items.ref != null)
|
||||
baseType = items.ref
|
||||
else if (items.`type` != null)
|
||||
baseType = items.`type`
|
||||
}
|
||||
case Some(items) =>
|
||||
baseType = items.ref.getOrElse(items.`type`)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
@ -138,8 +138,8 @@ abstract class CodegenConfig {
|
||||
val inner = {
|
||||
obj.items match {
|
||||
case Some(items) => {
|
||||
if(items.ref != null)
|
||||
items.ref
|
||||
if(items.ref != None)
|
||||
items.ref.get
|
||||
else
|
||||
items.`type`
|
||||
}
|
||||
|
@ -182,13 +182,13 @@ class SwaggerSpecValidator(private val doc: ResourceListing,
|
||||
// process the sub object
|
||||
subObject.items match {
|
||||
case Some(item) => {
|
||||
getUpdatedType(validModelNames, item.ref) match {
|
||||
getUpdatedType(validModelNames, item.ref.get) match {
|
||||
case Some(updatedType) => {
|
||||
if (!item.ref.equals(updatedType)) {
|
||||
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid ref (%s). Best guess: %s", item.ref, updatedType))
|
||||
LOGGER.finest("updated subObject.items.ref " + item.ref + " to " + updatedType)
|
||||
if (fix) {
|
||||
subObject.items = Some(ModelRef(ref = updatedType))
|
||||
subObject.items = Some(ModelRef(null, Some(updatedType)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,12 +202,12 @@ class SwaggerSpecValidator(private val doc: ResourceListing,
|
||||
if (subObject.items != null && subObject.items != None && subObject.items.get.ref != null){
|
||||
subObject.items match {
|
||||
case Some(item) => {
|
||||
getUpdatedType(validModelNames, item.ref) match {
|
||||
getUpdatedType(validModelNames, item.ref.get) match {
|
||||
case Some(updatedType) => {
|
||||
if (!item.ref.equals(updatedType)) {
|
||||
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid ref (%s). Best guess: %s", item.ref, updatedType))
|
||||
LOGGER.finest("updated subObject.items.ref " + item.ref + " to " + updatedType)
|
||||
if (fix) subObject.items = Some(ModelRef(ref = updatedType))
|
||||
if (fix) subObject.items = Some(ModelRef(null, Some(updatedType)))
|
||||
}
|
||||
}
|
||||
case None => {
|
||||
|
@ -18,6 +18,9 @@ package com.wordnik.swagger.codegen.util
|
||||
|
||||
import com.wordnik.swagger.model._
|
||||
|
||||
import org.json4s.jackson.JsonMethods._
|
||||
import org.json4s.native.Serialization.read
|
||||
|
||||
import java.net.URL
|
||||
import java.io.InputStream
|
||||
|
||||
@ -25,31 +28,31 @@ import scala.io._
|
||||
import scala.collection.mutable.{ ListBuffer, HashMap, HashSet }
|
||||
|
||||
object ApiExtractor extends RemoteUrl {
|
||||
def json = ScalaJsonUtil.getJsonMapper
|
||||
implicit val formats = SwaggerSerializers.formats
|
||||
|
||||
def fetchApiListings(basePath: String, apis: List[ApiListingReference], apiKey: Option[String] = None): List[ApiListing] = {
|
||||
for (api <- apis) yield {
|
||||
val str = basePath.startsWith("http") match {
|
||||
val json = basePath.startsWith("http") match {
|
||||
case true => {
|
||||
println("calling: " + ((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json")))
|
||||
urlToString((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json"))
|
||||
}
|
||||
case false => Source.fromFile((basePath + api.path).replaceAll(".\\{format\\}", ".json")).mkString
|
||||
}
|
||||
json.readValue(str, classOf[ApiListing])
|
||||
parse(json).extract[ApiListing]
|
||||
}
|
||||
}
|
||||
|
||||
def extractApiOperations(basePath: String, references: List[ApiListingReference], apiKey: Option[String] = None) = {
|
||||
for (api <- references) yield {
|
||||
val str = basePath.startsWith("http") match {
|
||||
val json = basePath.startsWith("http") match {
|
||||
case true => {
|
||||
println("calling: " + ((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json")))
|
||||
urlToString((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json"))
|
||||
}
|
||||
case false => Source.fromFile((basePath + api.path).replaceAll(".\\{format\\}", ".json")).mkString
|
||||
}
|
||||
json.readValue(str, classOf[ApiListing])
|
||||
parse(json).extract[ApiListing]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,12 +71,7 @@ object CoreUtils {
|
||||
val subObject = prop._2
|
||||
if (containers.contains(subObject.`type`)) {
|
||||
subObject.items match {
|
||||
case Some(item) => {
|
||||
if(item.ref != null)
|
||||
subNames += item.ref
|
||||
else
|
||||
subNames += item.`type`
|
||||
}
|
||||
case Some(item) => subNames += item.ref.getOrElse(item.`type`)
|
||||
case None =>
|
||||
}
|
||||
}
|
||||
@ -129,11 +124,9 @@ object CoreUtils {
|
||||
if (containers.contains(subObject.`type`)) {
|
||||
subObject.items match {
|
||||
case Some(subItem) => {
|
||||
if (subItem.ref != null) {
|
||||
subNames += subItem.ref
|
||||
} else {
|
||||
subNames += subItem.`type`
|
||||
}
|
||||
val sn = subItem.ref.getOrElse(subItem.`type`)
|
||||
if(sn != null)
|
||||
subNames += sn
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
@ -148,11 +141,9 @@ object CoreUtils {
|
||||
if (containers.contains(subObject.`type`)) {
|
||||
subObject.items match {
|
||||
case Some(subItem) => {
|
||||
if (subItem.ref != null) {
|
||||
subNames += subItem.ref
|
||||
} else {
|
||||
subNames += subItem.`type`
|
||||
}
|
||||
val sn = subItem.ref.getOrElse(subItem.`type`)
|
||||
if(sn != null)
|
||||
subNames += sn
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
|
@ -18,16 +18,19 @@ package com.wordnik.swagger.codegen.util
|
||||
|
||||
import com.wordnik.swagger.model._
|
||||
|
||||
import org.json4s.jackson.JsonMethods._
|
||||
import org.json4s.native.Serialization.read
|
||||
|
||||
import scala.io._
|
||||
|
||||
object ResourceExtractor extends RemoteUrl {
|
||||
def json = ScalaJsonUtil.getJsonMapper
|
||||
implicit val formats = SwaggerSerializers.formats
|
||||
|
||||
def fetchListing(path: String, apiKey: Option[String] = None): ResourceListing = {
|
||||
val str = path.startsWith("http") match {
|
||||
val json = path.startsWith("http") match {
|
||||
case true => urlToString(path + apiKey.getOrElse(""))
|
||||
case false => Source.fromFile(path).mkString
|
||||
}
|
||||
json.readValue(str, classOf[ResourceListing])
|
||||
parse(json).extract[ResourceListing]
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright 2012 Wordnik, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.wordnik.swagger.model;
|
||||
|
||||
import javax.xml.bind.annotation.*;
|
||||
|
||||
import com.fasterxml.jackson.annotation.*;
|
||||
|
||||
import static com.fasterxml.jackson.annotation.JsonTypeInfo.*;
|
||||
|
||||
/**
|
||||
* forgive me lord, for I used Java
|
||||
* @SeeAlso https://issues.scala-lang.org/browse/SI-5165
|
||||
**/
|
||||
@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="valueType")
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value=AllowableListValues.class, name="LIST"),
|
||||
@JsonSubTypes.Type(value=AllowableRangeValues.class, name="RANGE")
|
||||
})
|
||||
public abstract class AllowableValues {}
|
@ -5,8 +5,7 @@ import org.json4s.JsonDSL._
|
||||
import org.json4s.jackson.JsonMethods._
|
||||
import org.json4s.native.Serialization.{read, write}
|
||||
|
||||
import scala.collection.mutable.HashMap
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.collection.mutable.LinkedHashMap
|
||||
|
||||
object SwaggerSerializers {
|
||||
implicit val formats = DefaultFormats +
|
||||
@ -19,7 +18,40 @@ object SwaggerSerializers {
|
||||
new ErrorResponseSerializer +
|
||||
new ApiDescriptionSerializer +
|
||||
new ApiListingReferenceSerializer +
|
||||
new ResourceListingSerializer
|
||||
new ResourceListingSerializer +
|
||||
new ApiListingSerializer
|
||||
|
||||
class ApiListingSerializer extends CustomSerializer[ApiListing](formats => ({
|
||||
case json =>
|
||||
implicit val fmts: Formats = formats
|
||||
ApiListing(
|
||||
(json \ "apiVersion").extract[String],
|
||||
(json \ "swaggerVersion").extract[String],
|
||||
(json \ "basePath").extract[String],
|
||||
(json \ "resourcePath").extract[String],
|
||||
(json \ "apis").extract[List[ApiDescription]],
|
||||
(json \ "models").extract[Map[String, Model]]
|
||||
)
|
||||
}, {
|
||||
case x: ApiListing =>
|
||||
implicit val fmts = formats
|
||||
("apiVersion" -> x.apiVersion) ~
|
||||
("swaggerVersion" -> x.swaggerVersion) ~
|
||||
("basePath" -> x.basePath) ~
|
||||
("apis" -> {
|
||||
x.apis match {
|
||||
case e: List[ApiDescription] if (e.size > 0) => Extraction.decompose(e)
|
||||
case _ => JNothing
|
||||
}
|
||||
}) ~
|
||||
("models" -> {
|
||||
x.models match {
|
||||
case e: Map[String, Model] if (e.size > 0) => Extraction.decompose(e)
|
||||
case _ => JNothing
|
||||
}
|
||||
})
|
||||
}
|
||||
))
|
||||
|
||||
class ResourceListingSerializer extends CustomSerializer[ResourceListing](formats => ({
|
||||
case json =>
|
||||
@ -103,7 +135,7 @@ object SwaggerSerializers {
|
||||
Operation(
|
||||
(json \ "httpMethod").extract[String],
|
||||
(json \ "summary").extract[String],
|
||||
(json \ "notes").extract[String],
|
||||
(json \ "notes").extractOrElse(""),
|
||||
(json \ "responseClass").extract[String],
|
||||
(json \ "nickname").extract[String],
|
||||
(json \ "parameters").extract[List[Parameter]],
|
||||
@ -133,13 +165,13 @@ object SwaggerSerializers {
|
||||
case json =>
|
||||
implicit val fmts: Formats = formats
|
||||
Parameter(
|
||||
(json \ "name").extract[String],
|
||||
(json \ "name").extractOrElse(""),
|
||||
(json \ "description").extract[String],
|
||||
(json \ "defaultValue").extract[String],
|
||||
(json \ "defaultValue").extractOrElse(""),
|
||||
(json \ "required").extractOrElse(false),
|
||||
(json \ "allowMultiple").extractOrElse(false),
|
||||
(json \ "dataType").extract[String],
|
||||
(json \ "allowableValues").extract[AllowableValuesFoo],
|
||||
(json \ "allowableValues").extract[AllowableValues],
|
||||
(json \ "paramType").extract[String]
|
||||
)
|
||||
}, {
|
||||
@ -154,7 +186,7 @@ object SwaggerSerializers {
|
||||
("allowableValues" -> {
|
||||
x.allowableValues match {
|
||||
case Any => JNothing // don't serialize when not a concrete type
|
||||
case e:AllowableValuesFoo => Extraction.decompose(x.allowableValues)
|
||||
case e:AllowableValues => Extraction.decompose(x.allowableValues)
|
||||
case _ => JNothing
|
||||
}
|
||||
}) ~
|
||||
@ -165,7 +197,7 @@ object SwaggerSerializers {
|
||||
class ModelSerializer extends CustomSerializer[Model](formats => ({
|
||||
case json =>
|
||||
implicit val fmts: Formats = formats
|
||||
val output = new HashMap[String, ModelProperty]
|
||||
val output = new LinkedHashMap[String, ModelProperty]
|
||||
val properties = (json \ "properties") match {
|
||||
case JObject(entries) => {
|
||||
entries.map({
|
||||
@ -177,8 +209,8 @@ object SwaggerSerializers {
|
||||
|
||||
Model(
|
||||
(json \ "id").extract[String],
|
||||
(json \ "name").extract[String],
|
||||
output.asJava,
|
||||
(json \ "name").extractOrElse(""),
|
||||
output,
|
||||
(json \ "description").extractOpt[String]
|
||||
)
|
||||
}, {
|
||||
@ -188,7 +220,7 @@ object SwaggerSerializers {
|
||||
("name" -> x.name) ~
|
||||
("properties" -> {
|
||||
x.properties match {
|
||||
case e:java.util.Map[String, ModelProperty] => Extraction.decompose(e.asScala.toMap)
|
||||
case e: LinkedHashMap[String, ModelProperty] => Extraction.decompose(e.toMap)
|
||||
case _ => JNothing
|
||||
}
|
||||
})
|
||||
@ -202,7 +234,7 @@ object SwaggerSerializers {
|
||||
`type` = (json \ "type").extractOrElse(""),
|
||||
required = ((json \ "required").extractOrElse(false)),
|
||||
description = (json \ "description").extractOpt[String],
|
||||
allowableValues = (json \ "allowableValues").extract[AllowableValuesFoo],
|
||||
allowableValues = (json \ "allowableValues").extract[AllowableValues],
|
||||
items = (json \ "items").extractOpt[ModelRef]
|
||||
)
|
||||
}, {
|
||||
@ -214,7 +246,7 @@ object SwaggerSerializers {
|
||||
("allowableValues" -> {
|
||||
x.allowableValues match {
|
||||
case Any => JNothing // don't serialize when not a concrete type
|
||||
case e:AllowableValuesFoo => Extraction.decompose(x.allowableValues)
|
||||
case e:AllowableValues => Extraction.decompose(x.allowableValues)
|
||||
case _ => JNothing
|
||||
}
|
||||
}) ~
|
||||
@ -226,18 +258,23 @@ object SwaggerSerializers {
|
||||
case json =>
|
||||
implicit val fmts: Formats = formats
|
||||
ModelRef(
|
||||
(json \ "$ref").extract[String],
|
||||
(json \ "type").extract[String]
|
||||
(json \ "type").extractOrElse(null: String),
|
||||
(json \ "$ref").extractOpt[String]
|
||||
)
|
||||
}, {
|
||||
case x: ModelRef =>
|
||||
implicit val fmts = formats
|
||||
("$ref" -> x.ref) ~
|
||||
("type" -> x.`type`)
|
||||
("type" -> {
|
||||
x.`type` match {
|
||||
case e:String => Some(e)
|
||||
case _ => None
|
||||
}
|
||||
}) ~
|
||||
("$ref" -> x.ref)
|
||||
}
|
||||
))
|
||||
|
||||
class AllowableValuesSerializer extends CustomSerializer[AllowableValuesFoo](formats => ({
|
||||
class AllowableValuesSerializer extends CustomSerializer[AllowableValues](formats => ({
|
||||
case json =>
|
||||
implicit val fmts: Formats = formats
|
||||
json \ "valueType" match {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package com.wordnik.swagger.model
|
||||
|
||||
import com.fasterxml.jackson.annotation.{JsonProperty, JsonIgnore}
|
||||
import scala.collection.mutable.LinkedHashMap
|
||||
|
||||
case class ResourceListing(
|
||||
apiVersion: String,
|
||||
@ -26,29 +26,27 @@ case class ResourceListing(
|
||||
|
||||
case class ApiListingReference(path:String, description: String)
|
||||
|
||||
trait AllowableValuesFoo
|
||||
case object Any extends AllowableValues with AllowableValuesFoo
|
||||
case class AllowableListValues (values: List[String] = List(), valueType: String = "LIST") extends AllowableValues with AllowableValuesFoo
|
||||
case class AllowableRangeValues(min: String, max: String) extends AllowableValues with AllowableValuesFoo
|
||||
trait AllowableValues
|
||||
case object Any extends AllowableValues
|
||||
case class AllowableListValues (values: List[String] = List(), valueType: String = "LIST") extends AllowableValues
|
||||
case class AllowableRangeValues(min: String, max: String) extends AllowableValues
|
||||
|
||||
// using java.util.Map because Jackon 2 isn't deserializing ListMap correctly, and ordered
|
||||
// insertion is required
|
||||
case class Model(
|
||||
var id: String,
|
||||
var name: String,
|
||||
var properties: java.util.Map[String, ModelProperty],
|
||||
var properties: LinkedHashMap[String, ModelProperty],
|
||||
description: Option[String] = None)
|
||||
|
||||
case class ModelProperty(
|
||||
var `type`: String,
|
||||
required: Boolean = false,
|
||||
description: Option[String] = None,
|
||||
allowableValues: AllowableValuesFoo = Any,
|
||||
allowableValues: AllowableValues = Any,
|
||||
var items: Option[ModelRef] = None)
|
||||
|
||||
case class ModelRef(
|
||||
@JsonProperty("$ref") ref: String = null,
|
||||
`type`: String = null)
|
||||
`type`: String,
|
||||
ref: Option[String] = None)
|
||||
|
||||
case class ApiListing (
|
||||
apiVersion: String,
|
||||
@ -80,7 +78,7 @@ case class Parameter (
|
||||
required: Boolean,
|
||||
allowMultiple: Boolean,
|
||||
var dataType: String,
|
||||
allowableValues: AllowableValuesFoo = Any,
|
||||
allowableValues: AllowableValues = Any,
|
||||
paramType: String)
|
||||
|
||||
case class ErrorResponse (
|
||||
|
@ -115,8 +115,7 @@
|
||||
"available",
|
||||
"pending",
|
||||
"sold"
|
||||
],
|
||||
"valueType":"LIST"
|
||||
]
|
||||
},
|
||||
"required":true,
|
||||
"allowMultiple":true,
|
||||
@ -197,8 +196,7 @@
|
||||
"available",
|
||||
"pending",
|
||||
"sold"
|
||||
],
|
||||
"valueType":"LIST"
|
||||
]
|
||||
},
|
||||
"description":"pet status in the store",
|
||||
"type":"string"
|
||||
|
@ -23,9 +23,7 @@ import org.scalatest.junit.JUnitRunner
|
||||
import org.scalatest.FlatSpec
|
||||
import org.scalatest.matchers.ShouldMatchers
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.collection.mutable.HashMap
|
||||
import scala.collection.immutable.ListMap
|
||||
import scala.collection.mutable.{LinkedHashMap, HashMap}
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class BasicGeneratorTest extends FlatSpec with ShouldMatchers {
|
||||
@ -46,12 +44,14 @@ class BasicGeneratorTest extends FlatSpec with ShouldMatchers {
|
||||
|
||||
it should "get operations" in {
|
||||
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
|
||||
|
||||
val subDocs = ApiExtractor.fetchApiListings("src/test/resources/petstore", resourceListing.apis)
|
||||
val allModels = new HashMap[String, Model]()
|
||||
val allModels = new HashMap[String, Model]
|
||||
|
||||
implicit val basePath = "http://localhost:8080/api"
|
||||
val generator = new SampleGenerator
|
||||
val ops = generator.extractApiOperations(subDocs, allModels)
|
||||
|
||||
allModels.size should be (5)
|
||||
ops.size should be (16)
|
||||
|
||||
@ -138,12 +138,12 @@ class BasicGeneratorTest extends FlatSpec with ShouldMatchers {
|
||||
Model(
|
||||
"SampleObject",
|
||||
"SampleObject",
|
||||
Map(
|
||||
LinkedHashMap(
|
||||
"stringValue" -> ModelProperty("string"),
|
||||
"intValue" -> ModelProperty("int"),
|
||||
"longValue" -> ModelProperty("long"),
|
||||
"floatValue" -> ModelProperty("float"),
|
||||
"doubleValue" -> ModelProperty("double")).asJava,
|
||||
"doubleValue" -> ModelProperty("double")),
|
||||
Some("a sample object"))
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
import com.wordnik.swagger.model._
|
||||
|
||||
import org.json4s._
|
||||
import org.json4s.JsonDSL._
|
||||
import org.json4s.jackson.JsonMethods._
|
||||
import org.json4s.native.Serialization.{read, write}
|
||||
|
||||
import com.wordnik.swagger.model._
|
||||
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
import org.scalatest.FlatSpec
|
||||
import org.scalatest.matchers.ShouldMatchers
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
import scala.collection.mutable.LinkedHashMap
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class ResourceListingSerializersTest extends FlatSpec with ShouldMatchers {
|
||||
@ -328,6 +328,12 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
|
||||
"type":"string",
|
||||
"required":false,
|
||||
"description":"name"
|
||||
},
|
||||
"tags": {
|
||||
"type":"Array",
|
||||
"items": {
|
||||
"type":"string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description":"nice model"
|
||||
@ -339,9 +345,9 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
|
||||
model.id should be ("Foo")
|
||||
model.name should be ("Bar")
|
||||
model.properties should not be (null)
|
||||
model.properties.size should be (2)
|
||||
model.properties.size should be (3)
|
||||
model.description should be (Some("nice model"))
|
||||
model.properties.asScala("id") match {
|
||||
model.properties("id") match {
|
||||
case e: ModelProperty => {
|
||||
e.`type` should be ("string")
|
||||
e.required should be (true)
|
||||
@ -349,7 +355,7 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
|
||||
}
|
||||
case _ => fail("missing property id")
|
||||
}
|
||||
model.properties.asScala("name") match {
|
||||
model.properties("name") match {
|
||||
case e: ModelProperty => {
|
||||
e.`type` should be ("string")
|
||||
e.required should be (false)
|
||||
@ -357,13 +363,25 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
|
||||
}
|
||||
case _ => fail("missing property name")
|
||||
}
|
||||
|
||||
model.properties("tags") match {
|
||||
case e: ModelProperty => {
|
||||
e.`type` should be ("Array")
|
||||
e.required should be (false)
|
||||
e.items match {
|
||||
case Some(items) => items.`type` should be ("string")
|
||||
case _ => fail("didn't find ref for Array")
|
||||
}
|
||||
}
|
||||
case _ => fail("missing property name")
|
||||
}
|
||||
}
|
||||
case _ => fail("expected type Model")
|
||||
}
|
||||
}
|
||||
|
||||
it should "serialize a model" in {
|
||||
val ref = Model("Foo", "Bar", (Map("s" -> ModelProperty("string", true, Some("a string")))).asJava)
|
||||
val ref = Model("Foo", "Bar", (LinkedHashMap("s" -> ModelProperty("string", true, Some("a string")))))
|
||||
write(ref) should be ("""{"id":"Foo","name":"Bar","properties":{"s":{"type":"string","required":true,"description":"a string"}}}""")
|
||||
}
|
||||
}
|
||||
@ -382,7 +400,7 @@ class ModelRefSerializationTest extends FlatSpec with ShouldMatchers {
|
||||
val json = parse(jsonString)
|
||||
json.extract[ModelRef] match {
|
||||
case p: ModelRef => {
|
||||
p.ref should be ("Foo")
|
||||
p.ref should be (Some("Foo"))
|
||||
p.`type` should be ("Bar")
|
||||
}
|
||||
case _ => fail("expected type ModelRef")
|
||||
@ -390,8 +408,8 @@ class ModelRefSerializationTest extends FlatSpec with ShouldMatchers {
|
||||
}
|
||||
|
||||
it should "serialize a model ref" in {
|
||||
val ref = ModelRef("Foo", "Bar")
|
||||
write(ref) should be ("""{"$ref":"Foo","type":"Bar"}""")
|
||||
val ref = ModelRef("Foo", Some("Bar"))
|
||||
write(ref) should be ("""{"type":"Foo","$ref":"Bar"}""")
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,8 +428,8 @@ class ModelPropertySerializationTest extends FlatSpec with ShouldMatchers {
|
||||
"values":["1","2","3"]
|
||||
},
|
||||
"items":{
|
||||
"$ref":"Foo",
|
||||
"type":"Bar"
|
||||
"type":"Foo",
|
||||
"$ref":"Bar"
|
||||
}
|
||||
}
|
||||
"""
|
||||
@ -427,8 +445,8 @@ class ModelPropertySerializationTest extends FlatSpec with ShouldMatchers {
|
||||
}
|
||||
p.items match {
|
||||
case Some(e: ModelRef) => {
|
||||
e.ref should be ("Foo")
|
||||
e.`type` should be ("Bar")
|
||||
e.`type` should be ("Foo")
|
||||
e.ref should be (Some("Bar"))
|
||||
}
|
||||
case _ => fail("expected type ModelProperty")
|
||||
}
|
||||
@ -438,8 +456,8 @@ class ModelPropertySerializationTest extends FlatSpec with ShouldMatchers {
|
||||
}
|
||||
|
||||
it should "serialize a model property with allowable values and ref" in {
|
||||
val p = ModelProperty("string", false, Some("nice"), AllowableListValues(List("a","b")),Some(ModelRef("Foo","Bar")))
|
||||
write(p) should be ("""{"type":"string","required":false,"description":"nice","allowableValues":{"valueType":"LIST","values":["a","b"]},"items":{"$ref":"Foo","type":"Bar"}}""")
|
||||
val p = ModelProperty("string", false, Some("nice"), AllowableListValues(List("a","b")),Some(ModelRef("Foo",Some("Bar"))))
|
||||
write(p) should be ("""{"type":"string","required":false,"description":"nice","allowableValues":{"valueType":"LIST","values":["a","b"]},"items":{"type":"Foo","$ref":"Bar"}}""")
|
||||
}
|
||||
|
||||
it should "deserialize a model property with allowable values" in {
|
||||
@ -511,7 +529,7 @@ class AllowableValuesSerializersTest extends FlatSpec with ShouldMatchers {
|
||||
}
|
||||
"""
|
||||
val json = parse(allowableValuesListString)
|
||||
json.extract[AllowableValuesFoo] match {
|
||||
json.extract[AllowableValues] match {
|
||||
case avl: AllowableListValues => {
|
||||
avl.valueType should be ("LIST")
|
||||
avl.values should be (List("1","2","3"))
|
||||
@ -533,7 +551,7 @@ class AllowableValuesSerializersTest extends FlatSpec with ShouldMatchers {
|
||||
}
|
||||
"""
|
||||
val json = parse(allowableValuesRangeString)
|
||||
json.extract[AllowableValuesFoo] match {
|
||||
json.extract[AllowableValues] match {
|
||||
case avr: AllowableRangeValues => {
|
||||
avr.min should be ("abc")
|
||||
avr.max should be ("3")
|
||||
|
@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import com.wordnik.swagger.model._
|
||||
import com.wordnik.swagger.codegen.util.ScalaJsonUtil
|
||||
|
||||
import org.json4s.jackson.JsonMethods._
|
||||
import org.json4s.native.Serialization.read
|
||||
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -24,141 +26,140 @@ import org.scalatest.matchers.ShouldMatchers
|
||||
|
||||
import scala.io._
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class SwaggerModelTest extends FlatSpec with ShouldMatchers {
|
||||
val json = ScalaJsonUtil.getJsonMapper
|
||||
behavior of "Swagger Model"
|
||||
implicit val formats = SwaggerSerializers.formats
|
||||
|
||||
it should "deserialize ResourceListing" in {
|
||||
val str = Source.fromFile("src/test/resources/petstore/resources.json").mkString
|
||||
val listing = json.readValue(str, classOf[ResourceListing])
|
||||
behavior of "Swagger Model"
|
||||
|
||||
listing.apiVersion should be ("0.2")
|
||||
listing.swaggerVersion should be ("1.1")
|
||||
listing.basePath should be ("http://petstore.swagger.wordnik.com/api")
|
||||
listing.apis.size should be (3)
|
||||
it should "deserialize ResourceListing" in {
|
||||
val json = Source.fromFile("src/test/resources/petstore/resources.json").mkString
|
||||
val listing = parse(json).extract[ResourceListing]
|
||||
|
||||
val apis = listing.apis.map(api => (api.path, api.description)).toMap
|
||||
listing.apiVersion should be ("0.2")
|
||||
listing.swaggerVersion should be ("1.1")
|
||||
listing.basePath should be ("http://petstore.swagger.wordnik.com/api")
|
||||
listing.apis.size should be (3)
|
||||
|
||||
apis("/store.{format}") should be ("Operations about store")
|
||||
apis("/pet.{format}") should be ("Operations about pets")
|
||||
apis("/user.{format}") should be ("Operations about user")
|
||||
}
|
||||
val apis = listing.apis.map(api => (api.path, api.description)).toMap
|
||||
|
||||
it should "deserialize ApiListing" in {
|
||||
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = json.readValue(str, classOf[ApiListing])
|
||||
apis("/store.{format}") should be ("Operations about store")
|
||||
apis("/pet.{format}") should be ("Operations about pets")
|
||||
apis("/user.{format}") should be ("Operations about user")
|
||||
}
|
||||
|
||||
apiListing.apiVersion should be ("0.2")
|
||||
apiListing.swaggerVersion should be ("1.1")
|
||||
apiListing.basePath should be ("http://petstore.swagger.wordnik.com/api")
|
||||
apiListing.resourcePath should be ("/pet")
|
||||
apiListing.apis.size should be (4)
|
||||
apiListing.models.size should be (3)
|
||||
it should "deserialize ApiListing" in {
|
||||
val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = parse(json).extract[ApiListing]
|
||||
|
||||
val apiMap = apiListing.apis.map(api => (api.path, api)).toMap
|
||||
val petBaseApi = apiMap("/pet.{format}/{petId}")
|
||||
petBaseApi.description should be ("Operations about pets")
|
||||
petBaseApi.operations.size should be (1)
|
||||
apiListing.apiVersion should be ("0.2")
|
||||
apiListing.swaggerVersion should be ("1.1")
|
||||
apiListing.basePath should be ("http://petstore.swagger.wordnik.com/api")
|
||||
apiListing.resourcePath should be ("/pet")
|
||||
apiListing.apis.size should be (4)
|
||||
apiListing.models.size should be (3)
|
||||
|
||||
val getPetById = petBaseApi.operations.head
|
||||
getPetById.httpMethod should be ("GET")
|
||||
getPetById.summary should be ("Find pet by ID")
|
||||
getPetById.notes should be ("Returns a pet based on ID")
|
||||
getPetById.responseClass should be ("Pet")
|
||||
val apiMap = apiListing.apis.map(api => (api.path, api)).toMap
|
||||
val petBaseApi = apiMap("/pet.{format}/{petId}")
|
||||
petBaseApi.description should be ("Operations about pets")
|
||||
petBaseApi.operations.size should be (1)
|
||||
|
||||
getPetById.nickname should be ("getPetById")
|
||||
getPetById.parameters.size should be (1)
|
||||
val getPetById = petBaseApi.operations.head
|
||||
getPetById.httpMethod should be ("GET")
|
||||
getPetById.summary should be ("Find pet by ID")
|
||||
getPetById.notes should be ("Returns a pet based on ID")
|
||||
getPetById.responseClass should be ("Pet")
|
||||
|
||||
val param = getPetById.parameters.head
|
||||
param.name should be ("petId")
|
||||
param.description should be ("ID of pet that needs to be fetched")
|
||||
param.paramType should be ("path")
|
||||
param.required should be (true)
|
||||
param.allowMultiple should be (false)
|
||||
param.dataType should be ("string")
|
||||
getPetById.nickname should be ("getPetById")
|
||||
getPetById.parameters.size should be (1)
|
||||
|
||||
getPetById.errorResponses.size should be (2)
|
||||
val errors = getPetById.errorResponses.map(error => (error.code, error.reason)).toMap
|
||||
val param = getPetById.parameters.head
|
||||
param.name should be ("petId")
|
||||
param.description should be ("ID of pet that needs to be fetched")
|
||||
param.paramType should be ("path")
|
||||
param.required should be (true)
|
||||
param.allowMultiple should be (false)
|
||||
param.dataType should be ("string")
|
||||
|
||||
errors(400) should be ("Invalid ID supplied")
|
||||
errors(404) should be ("Pet not found")
|
||||
}
|
||||
getPetById.errorResponses.size should be (2)
|
||||
val errors = getPetById.errorResponses.map(error => (error.code, error.reason)).toMap
|
||||
|
||||
it should "deserialize ApiListing with AllowableValues" in {
|
||||
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = json.readValue(str, classOf[ApiListing])
|
||||
val apiMap = apiListing.apis.map(api => (api.path, api)).toMap
|
||||
val petBaseApi = apiMap("/pet.{format}/findByStatus")
|
||||
val findPetsByStatus = petBaseApi.operations.head
|
||||
val param = findPetsByStatus.parameters.head
|
||||
errors(400) should be ("Invalid ID supplied")
|
||||
errors(404) should be ("Pet not found")
|
||||
}
|
||||
|
||||
param.name should be ("status")
|
||||
param.description should be ("Status values that need to be considered for filter")
|
||||
param.paramType should be ("query")
|
||||
param.required should be (true)
|
||||
param.allowMultiple should be (true)
|
||||
param.dataType should be ("string")
|
||||
param.allowableValues should not be (null)
|
||||
it should "deserialize ApiListing with AllowableValues" in {
|
||||
val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = parse(json).extract[ApiListing]
|
||||
val apiMap = apiListing.apis.map(api => (api.path, api)).toMap
|
||||
val petBaseApi = apiMap("/pet.{format}/findByStatus")
|
||||
val findPetsByStatus = petBaseApi.operations.head
|
||||
val param = findPetsByStatus.parameters.head
|
||||
|
||||
param.allowableValues.isInstanceOf[AllowableListValues] should be (true)
|
||||
val allowableValues = param.allowableValues.asInstanceOf[AllowableListValues]
|
||||
allowableValues.valueType should be ("LIST")
|
||||
allowableValues.values.size should be (3)
|
||||
(allowableValues.values.toSet & Set("available", "pending", "sold")).size should be (3)
|
||||
}
|
||||
param.name should be ("status")
|
||||
param.description should be ("Status values that need to be considered for filter")
|
||||
param.paramType should be ("query")
|
||||
param.required should be (true)
|
||||
param.allowMultiple should be (true)
|
||||
param.dataType should be ("string")
|
||||
param.allowableValues should not be (null)
|
||||
|
||||
it should "maintain model property order when deserializing" in {
|
||||
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = json.readValue(str, classOf[ApiListing])
|
||||
param.allowableValues.isInstanceOf[AllowableListValues] should be (true)
|
||||
val allowableValues = param.allowableValues.asInstanceOf[AllowableListValues]
|
||||
allowableValues.valueType should be ("LIST")
|
||||
allowableValues.values.size should be (3)
|
||||
(allowableValues.values.toSet & Set("available", "pending", "sold")).size should be (3)
|
||||
}
|
||||
|
||||
val models = apiListing.models
|
||||
models.size should be (3)
|
||||
val pet = models("Pet")
|
||||
it should "maintain model property order when deserializing" in {
|
||||
val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = parse(json).extract[ApiListing]
|
||||
|
||||
val petProperties = pet.properties.asScala.toList
|
||||
val models = apiListing.models
|
||||
models.size should be (3)
|
||||
val pet = models("Pet")
|
||||
|
||||
petProperties.size should be (6)
|
||||
petProperties(0)._1 should be ("tags")
|
||||
petProperties(1)._1 should be ("id")
|
||||
petProperties(2)._1 should be ("category")
|
||||
petProperties(3)._1 should be ("status")
|
||||
petProperties(4)._1 should be ("name")
|
||||
petProperties(5)._1 should be ("photoUrls")
|
||||
}
|
||||
val petProperties = pet.properties.toList
|
||||
|
||||
it should "deserialize models" in {
|
||||
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = json.readValue(str, classOf[ApiListing])
|
||||
petProperties.size should be (6)
|
||||
petProperties(0)._1 should be ("tags")
|
||||
petProperties(1)._1 should be ("id")
|
||||
petProperties(2)._1 should be ("category")
|
||||
petProperties(3)._1 should be ("status")
|
||||
petProperties(4)._1 should be ("name")
|
||||
petProperties(5)._1 should be ("photoUrls")
|
||||
}
|
||||
|
||||
val models = apiListing.models
|
||||
models.size should be (3)
|
||||
it should "deserialize models" in {
|
||||
val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
|
||||
val apiListing = parse(json).extract[ApiListing]
|
||||
|
||||
val pet = models("Pet")
|
||||
pet.id should be ("Pet")
|
||||
pet.properties.size should be (6)
|
||||
val models = apiListing.models
|
||||
models.size should be (3)
|
||||
|
||||
val properties = pet.properties.asScala
|
||||
val tags = properties("tags")
|
||||
tags.`type` should be ("Array")
|
||||
tags.items should not be (None)
|
||||
tags.items.get.ref should be ("Tag")
|
||||
val pet = models("Pet")
|
||||
pet.id should be ("Pet")
|
||||
pet.properties.size should be (6)
|
||||
|
||||
val id = properties("id")
|
||||
// id.`type` shoud be ("long")
|
||||
val properties = pet.properties
|
||||
val tags = properties("tags")
|
||||
tags.`type` should be ("Array")
|
||||
tags.items should not be (None)
|
||||
tags.items.get.ref should be (Some("Tag"))
|
||||
|
||||
val category = properties("category")
|
||||
category.`type` should be ("Category")
|
||||
val id = properties("id")
|
||||
// id.`type` shoud be ("long")
|
||||
|
||||
val status = properties("status")
|
||||
status.`type` should be ("string")
|
||||
status.description should be (Some("pet status in the store"))
|
||||
status.allowableValues should not be (null)
|
||||
status.allowableValues.isInstanceOf[AllowableListValues] should be (true)
|
||||
val allowableValues = status.allowableValues.asInstanceOf[AllowableListValues]
|
||||
allowableValues.valueType should be ("LIST")
|
||||
(allowableValues.values.toSet & Set("available", "pending", "sold")).size should be (3)
|
||||
}
|
||||
val category = properties("category")
|
||||
category.`type` should be ("Category")
|
||||
|
||||
val status = properties("status")
|
||||
status.`type` should be ("string")
|
||||
status.description should be (Some("pet status in the store"))
|
||||
status.allowableValues should not be (null)
|
||||
status.allowableValues.isInstanceOf[AllowableListValues] should be (true)
|
||||
val allowableValues = status.allowableValues.asInstanceOf[AllowableListValues]
|
||||
allowableValues.valueType should be ("LIST")
|
||||
(allowableValues.values.toSet & Set("available", "pending", "sold")).size should be (3)
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import com.wordnik.swagger.model._
|
||||
import com.wordnik.swagger.codegen.util._
|
||||
import com.wordnik.swagger.codegen.util.{ResourceExtractor, ApiExtractor, CoreUtils}
|
||||
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -27,8 +27,6 @@ import scala.reflect.BeanProperty
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class ResourceExtractorTest extends FlatSpec with ShouldMatchers {
|
||||
val json = ScalaJsonUtil.getJsonMapper
|
||||
|
||||
behavior of "ResourceExtractor"
|
||||
it should "get 3 apis from a resource listing" in {
|
||||
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
|
||||
@ -39,12 +37,11 @@ class ResourceExtractorTest extends FlatSpec with ShouldMatchers {
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class ApiExtractorTest extends FlatSpec with ShouldMatchers {
|
||||
val json = ScalaJsonUtil.getJsonMapper
|
||||
|
||||
behavior of "ApiExtractor"
|
||||
it should "verify the deserialization of the store api" in {
|
||||
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
|
||||
val docs = ApiExtractor.extractApiOperations("src/test/resources/petstore", resourceListing.apis)
|
||||
|
||||
val m = docs.map(t => (t.resourcePath, t)).toMap
|
||||
val storeApi = m("/store")
|
||||
|
||||
@ -68,7 +65,6 @@ class ApiExtractorTest extends FlatSpec with ShouldMatchers {
|
||||
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class CoreUtilsTest extends FlatSpec with ShouldMatchers {
|
||||
val json = ScalaJsonUtil.getJsonMapper
|
||||
sys.props += "fileMap" -> "src/test/resources/petstore"
|
||||
|
||||
behavior of "CoreUtils"
|
||||
|
Loading…
x
Reference in New Issue
Block a user