migrated to json4s

This commit is contained in:
Tony Tam 2012-12-04 00:15:55 -08:00
parent 25837e3367
commit 87bad7b36d
18 changed files with 257 additions and 270 deletions

View File

@ -16,7 +16,7 @@ libraryDependencies ++= Seq(
"org.scalatra" % "scalatra-specs2" % "2.2.0-SNAPSHOT" % "test", "org.scalatra" % "scalatra-specs2" % "2.2.0-SNAPSHOT" % "test",
"org.scalatra" % "scalatra-swagger" % "2.2.0-SNAPSHOT", "org.scalatra" % "scalatra-swagger" % "2.2.0-SNAPSHOT",
"org.scalatra" % "scalatra-json" % "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", "com.wordnik" % "swagger-core_2.9.1" % "1.1.1-SNAPSHOT",
"ch.qos.logback" % "logback-classic" % "1.0.6" % "runtime", "ch.qos.logback" % "logback-classic" % "1.0.6" % "runtime",
"org.eclipse.jetty" % "jetty-webapp" % "8.1.5.v20120716" % "container", "org.eclipse.jetty" % "jetty-webapp" % "8.1.5.v20120716" % "container",

View File

@ -129,12 +129,7 @@ class BasicJavaGenerator extends BasicGenerator {
case "List" => { case "List" => {
val inner = { val inner = {
obj.items match { obj.items match {
case Some(items) => { case Some(items) => items.ref.getOrElse(items.`type`)
if(items.ref != null)
items.ref
else
items.`type`
}
case _ => throw new Exception("no inner type defined") case _ => throw new Exception("no inner type defined")
} }
} }
@ -159,12 +154,7 @@ class BasicJavaGenerator extends BasicGenerator {
case "List" => { case "List" => {
val inner = { val inner = {
obj.items match { obj.items match {
case Some(items) => { case Some(items) => items.ref.getOrElse(items.`type`)
if(items.ref != null)
items.ref
else
items.`type`
}
case _ => throw new Exception("no inner type defined") case _ => throw new Exception("no inner type defined")
} }
} }

View File

@ -139,12 +139,7 @@ class BasicPythonGenerator extends BasicGenerator {
case "list" => { case "list" => {
val inner = { val inner = {
obj.items match { obj.items match {
case Some(items) => { case Some(items) => items.ref.getOrElse(items.`type`)
if(items.ref != null)
items.ref
else
items.`type`
}
case _ => throw new Exception("no inner type defined") case _ => throw new Exception("no inner type defined")
} }
} }

View File

@ -78,12 +78,7 @@ class BasicScalaGenerator extends BasicGenerator {
case "Array" => { case "Array" => {
val inner = { val inner = {
obj.items match { obj.items match {
case Some(items) => { case Some(items) => items.ref.getOrElse(items.`type`)
if(items.ref != null)
items.ref
else
items.`type`
}
case _ => throw new Exception("no inner type defined") case _ => throw new Exception("no inner type defined")
} }
} }

View File

@ -364,12 +364,8 @@ class Codegen(config: CodegenConfig) {
// import the container // import the container
imports += Map("import" -> dt) imports += Map("import" -> dt)
propertyDocSchema.items match { propertyDocSchema.items match {
case Some(items) => { case Some(items) =>
if(items.ref != null) baseType = items.ref.getOrElse(items.`type`)
baseType = items.ref
else if (items.`type` != null)
baseType = items.`type`
}
case _ => case _ =>
} }
} }

View File

@ -138,8 +138,8 @@ abstract class CodegenConfig {
val inner = { val inner = {
obj.items match { obj.items match {
case Some(items) => { case Some(items) => {
if(items.ref != null) if(items.ref != None)
items.ref items.ref.get
else else
items.`type` items.`type`
} }

View File

@ -182,13 +182,13 @@ class SwaggerSpecValidator(private val doc: ResourceListing,
// process the sub object // process the sub object
subObject.items match { subObject.items match {
case Some(item) => { case Some(item) => {
getUpdatedType(validModelNames, item.ref) match { getUpdatedType(validModelNames, item.ref.get) match {
case Some(updatedType) => { case Some(updatedType) => {
if (!item.ref.equals(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)) !!(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) LOGGER.finest("updated subObject.items.ref " + item.ref + " to " + updatedType)
if (fix) { 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){ if (subObject.items != null && subObject.items != None && subObject.items.get.ref != null){
subObject.items match { subObject.items match {
case Some(item) => { case Some(item) => {
getUpdatedType(validModelNames, item.ref) match { getUpdatedType(validModelNames, item.ref.get) match {
case Some(updatedType) => { case Some(updatedType) => {
if (!item.ref.equals(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)) !!(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) 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 => { case None => {

View File

@ -18,6 +18,9 @@ package com.wordnik.swagger.codegen.util
import com.wordnik.swagger.model._ import com.wordnik.swagger.model._
import org.json4s.jackson.JsonMethods._
import org.json4s.native.Serialization.read
import java.net.URL import java.net.URL
import java.io.InputStream import java.io.InputStream
@ -25,31 +28,31 @@ import scala.io._
import scala.collection.mutable.{ ListBuffer, HashMap, HashSet } import scala.collection.mutable.{ ListBuffer, HashMap, HashSet }
object ApiExtractor extends RemoteUrl { 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] = { def fetchApiListings(basePath: String, apis: List[ApiListingReference], apiKey: Option[String] = None): List[ApiListing] = {
for (api <- apis) yield { for (api <- apis) yield {
val str = basePath.startsWith("http") match { val json = basePath.startsWith("http") match {
case true => { case true => {
println("calling: " + ((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json"))) println("calling: " + ((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json")))
urlToString((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 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) = { def extractApiOperations(basePath: String, references: List[ApiListingReference], apiKey: Option[String] = None) = {
for (api <- references) yield { for (api <- references) yield {
val str = basePath.startsWith("http") match { val json = basePath.startsWith("http") match {
case true => { case true => {
println("calling: " + ((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json"))) println("calling: " + ((basePath + api.path + apiKey.getOrElse("")).replaceAll(".\\{format\\}", ".json")))
urlToString((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 case false => Source.fromFile((basePath + api.path).replaceAll(".\\{format\\}", ".json")).mkString
} }
json.readValue(str, classOf[ApiListing]) parse(json).extract[ApiListing]
} }
} }

View File

@ -71,12 +71,7 @@ object CoreUtils {
val subObject = prop._2 val subObject = prop._2
if (containers.contains(subObject.`type`)) { if (containers.contains(subObject.`type`)) {
subObject.items match { subObject.items match {
case Some(item) => { case Some(item) => subNames += item.ref.getOrElse(item.`type`)
if(item.ref != null)
subNames += item.ref
else
subNames += item.`type`
}
case None => case None =>
} }
} }
@ -129,11 +124,9 @@ object CoreUtils {
if (containers.contains(subObject.`type`)) { if (containers.contains(subObject.`type`)) {
subObject.items match { subObject.items match {
case Some(subItem) => { case Some(subItem) => {
if (subItem.ref != null) { val sn = subItem.ref.getOrElse(subItem.`type`)
subNames += subItem.ref if(sn != null)
} else { subNames += sn
subNames += subItem.`type`
}
} }
case _ => case _ =>
} }
@ -148,11 +141,9 @@ object CoreUtils {
if (containers.contains(subObject.`type`)) { if (containers.contains(subObject.`type`)) {
subObject.items match { subObject.items match {
case Some(subItem) => { case Some(subItem) => {
if (subItem.ref != null) { val sn = subItem.ref.getOrElse(subItem.`type`)
subNames += subItem.ref if(sn != null)
} else { subNames += sn
subNames += subItem.`type`
}
} }
case _ => case _ =>
} }

View File

@ -18,16 +18,19 @@ package com.wordnik.swagger.codegen.util
import com.wordnik.swagger.model._ import com.wordnik.swagger.model._
import org.json4s.jackson.JsonMethods._
import org.json4s.native.Serialization.read
import scala.io._ import scala.io._
object ResourceExtractor extends RemoteUrl { object ResourceExtractor extends RemoteUrl {
def json = ScalaJsonUtil.getJsonMapper implicit val formats = SwaggerSerializers.formats
def fetchListing(path: String, apiKey: Option[String] = None): ResourceListing = { 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 true => urlToString(path + apiKey.getOrElse(""))
case false => Source.fromFile(path).mkString case false => Source.fromFile(path).mkString
} }
json.readValue(str, classOf[ResourceListing]) parse(json).extract[ResourceListing]
} }
} }

View File

@ -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 {}

View File

@ -5,8 +5,7 @@ import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._ import org.json4s.jackson.JsonMethods._
import org.json4s.native.Serialization.{read, write} import org.json4s.native.Serialization.{read, write}
import scala.collection.mutable.HashMap import scala.collection.mutable.LinkedHashMap
import scala.collection.JavaConverters._
object SwaggerSerializers { object SwaggerSerializers {
implicit val formats = DefaultFormats + implicit val formats = DefaultFormats +
@ -19,7 +18,40 @@ object SwaggerSerializers {
new ErrorResponseSerializer + new ErrorResponseSerializer +
new ApiDescriptionSerializer + new ApiDescriptionSerializer +
new ApiListingReferenceSerializer + 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 => ({ class ResourceListingSerializer extends CustomSerializer[ResourceListing](formats => ({
case json => case json =>
@ -103,7 +135,7 @@ object SwaggerSerializers {
Operation( Operation(
(json \ "httpMethod").extract[String], (json \ "httpMethod").extract[String],
(json \ "summary").extract[String], (json \ "summary").extract[String],
(json \ "notes").extract[String], (json \ "notes").extractOrElse(""),
(json \ "responseClass").extract[String], (json \ "responseClass").extract[String],
(json \ "nickname").extract[String], (json \ "nickname").extract[String],
(json \ "parameters").extract[List[Parameter]], (json \ "parameters").extract[List[Parameter]],
@ -133,13 +165,13 @@ object SwaggerSerializers {
case json => case json =>
implicit val fmts: Formats = formats implicit val fmts: Formats = formats
Parameter( Parameter(
(json \ "name").extract[String], (json \ "name").extractOrElse(""),
(json \ "description").extract[String], (json \ "description").extract[String],
(json \ "defaultValue").extract[String], (json \ "defaultValue").extractOrElse(""),
(json \ "required").extractOrElse(false), (json \ "required").extractOrElse(false),
(json \ "allowMultiple").extractOrElse(false), (json \ "allowMultiple").extractOrElse(false),
(json \ "dataType").extract[String], (json \ "dataType").extract[String],
(json \ "allowableValues").extract[AllowableValuesFoo], (json \ "allowableValues").extract[AllowableValues],
(json \ "paramType").extract[String] (json \ "paramType").extract[String]
) )
}, { }, {
@ -154,7 +186,7 @@ object SwaggerSerializers {
("allowableValues" -> { ("allowableValues" -> {
x.allowableValues match { x.allowableValues match {
case Any => JNothing // don't serialize when not a concrete type 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 case _ => JNothing
} }
}) ~ }) ~
@ -165,7 +197,7 @@ object SwaggerSerializers {
class ModelSerializer extends CustomSerializer[Model](formats => ({ class ModelSerializer extends CustomSerializer[Model](formats => ({
case json => case json =>
implicit val fmts: Formats = formats implicit val fmts: Formats = formats
val output = new HashMap[String, ModelProperty] val output = new LinkedHashMap[String, ModelProperty]
val properties = (json \ "properties") match { val properties = (json \ "properties") match {
case JObject(entries) => { case JObject(entries) => {
entries.map({ entries.map({
@ -177,8 +209,8 @@ object SwaggerSerializers {
Model( Model(
(json \ "id").extract[String], (json \ "id").extract[String],
(json \ "name").extract[String], (json \ "name").extractOrElse(""),
output.asJava, output,
(json \ "description").extractOpt[String] (json \ "description").extractOpt[String]
) )
}, { }, {
@ -188,7 +220,7 @@ object SwaggerSerializers {
("name" -> x.name) ~ ("name" -> x.name) ~
("properties" -> { ("properties" -> {
x.properties match { 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 case _ => JNothing
} }
}) })
@ -202,7 +234,7 @@ object SwaggerSerializers {
`type` = (json \ "type").extractOrElse(""), `type` = (json \ "type").extractOrElse(""),
required = ((json \ "required").extractOrElse(false)), required = ((json \ "required").extractOrElse(false)),
description = (json \ "description").extractOpt[String], description = (json \ "description").extractOpt[String],
allowableValues = (json \ "allowableValues").extract[AllowableValuesFoo], allowableValues = (json \ "allowableValues").extract[AllowableValues],
items = (json \ "items").extractOpt[ModelRef] items = (json \ "items").extractOpt[ModelRef]
) )
}, { }, {
@ -214,7 +246,7 @@ object SwaggerSerializers {
("allowableValues" -> { ("allowableValues" -> {
x.allowableValues match { x.allowableValues match {
case Any => JNothing // don't serialize when not a concrete type 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 case _ => JNothing
} }
}) ~ }) ~
@ -226,18 +258,23 @@ object SwaggerSerializers {
case json => case json =>
implicit val fmts: Formats = formats implicit val fmts: Formats = formats
ModelRef( ModelRef(
(json \ "$ref").extract[String], (json \ "type").extractOrElse(null: String),
(json \ "type").extract[String] (json \ "$ref").extractOpt[String]
) )
}, { }, {
case x: ModelRef => case x: ModelRef =>
implicit val fmts = formats implicit val fmts = formats
("$ref" -> x.ref) ~ ("type" -> {
("type" -> x.`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 => case json =>
implicit val fmts: Formats = formats implicit val fmts: Formats = formats
json \ "valueType" match { json \ "valueType" match {

View File

@ -16,7 +16,7 @@
package com.wordnik.swagger.model package com.wordnik.swagger.model
import com.fasterxml.jackson.annotation.{JsonProperty, JsonIgnore} import scala.collection.mutable.LinkedHashMap
case class ResourceListing( case class ResourceListing(
apiVersion: String, apiVersion: String,
@ -26,29 +26,27 @@ case class ResourceListing(
case class ApiListingReference(path:String, description: String) case class ApiListingReference(path:String, description: String)
trait AllowableValuesFoo trait AllowableValues
case object Any extends AllowableValues with AllowableValuesFoo case object Any extends AllowableValues
case class AllowableListValues (values: List[String] = List(), valueType: String = "LIST") extends AllowableValues with AllowableValuesFoo case class AllowableListValues (values: List[String] = List(), valueType: String = "LIST") extends AllowableValues
case class AllowableRangeValues(min: String, max: String) extends AllowableValues with AllowableValuesFoo 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( case class Model(
var id: String, var id: String,
var name: String, var name: String,
var properties: java.util.Map[String, ModelProperty], var properties: LinkedHashMap[String, ModelProperty],
description: Option[String] = None) description: Option[String] = None)
case class ModelProperty( case class ModelProperty(
var `type`: String, var `type`: String,
required: Boolean = false, required: Boolean = false,
description: Option[String] = None, description: Option[String] = None,
allowableValues: AllowableValuesFoo = Any, allowableValues: AllowableValues = Any,
var items: Option[ModelRef] = None) var items: Option[ModelRef] = None)
case class ModelRef( case class ModelRef(
@JsonProperty("$ref") ref: String = null, `type`: String,
`type`: String = null) ref: Option[String] = None)
case class ApiListing ( case class ApiListing (
apiVersion: String, apiVersion: String,
@ -80,7 +78,7 @@ case class Parameter (
required: Boolean, required: Boolean,
allowMultiple: Boolean, allowMultiple: Boolean,
var dataType: String, var dataType: String,
allowableValues: AllowableValuesFoo = Any, allowableValues: AllowableValues = Any,
paramType: String) paramType: String)
case class ErrorResponse ( case class ErrorResponse (

View File

@ -115,8 +115,7 @@
"available", "available",
"pending", "pending",
"sold" "sold"
], ]
"valueType":"LIST"
}, },
"required":true, "required":true,
"allowMultiple":true, "allowMultiple":true,
@ -197,8 +196,7 @@
"available", "available",
"pending", "pending",
"sold" "sold"
], ]
"valueType":"LIST"
}, },
"description":"pet status in the store", "description":"pet status in the store",
"type":"string" "type":"string"

View File

@ -23,9 +23,7 @@ import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers import org.scalatest.matchers.ShouldMatchers
import scala.collection.JavaConverters._ import scala.collection.mutable.{LinkedHashMap, HashMap}
import scala.collection.mutable.HashMap
import scala.collection.immutable.ListMap
@RunWith(classOf[JUnitRunner]) @RunWith(classOf[JUnitRunner])
class BasicGeneratorTest extends FlatSpec with ShouldMatchers { class BasicGeneratorTest extends FlatSpec with ShouldMatchers {
@ -46,12 +44,14 @@ class BasicGeneratorTest extends FlatSpec with ShouldMatchers {
it should "get operations" in { it should "get operations" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json") val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
val subDocs = ApiExtractor.fetchApiListings("src/test/resources/petstore", resourceListing.apis) 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" implicit val basePath = "http://localhost:8080/api"
val generator = new SampleGenerator val generator = new SampleGenerator
val ops = generator.extractApiOperations(subDocs, allModels) val ops = generator.extractApiOperations(subDocs, allModels)
allModels.size should be (5) allModels.size should be (5)
ops.size should be (16) ops.size should be (16)
@ -138,12 +138,12 @@ class BasicGeneratorTest extends FlatSpec with ShouldMatchers {
Model( Model(
"SampleObject", "SampleObject",
"SampleObject", "SampleObject",
Map( LinkedHashMap(
"stringValue" -> ModelProperty("string"), "stringValue" -> ModelProperty("string"),
"intValue" -> ModelProperty("int"), "intValue" -> ModelProperty("int"),
"longValue" -> ModelProperty("long"), "longValue" -> ModelProperty("long"),
"floatValue" -> ModelProperty("float"), "floatValue" -> ModelProperty("float"),
"doubleValue" -> ModelProperty("double")).asJava, "doubleValue" -> ModelProperty("double")),
Some("a sample object")) Some("a sample object"))
} }
} }

View File

@ -1,16 +1,16 @@
import com.wordnik.swagger.model._
import org.json4s._ import org.json4s._
import org.json4s.JsonDSL._ import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._ import org.json4s.jackson.JsonMethods._
import org.json4s.native.Serialization.{read, write} import org.json4s.native.Serialization.{read, write}
import com.wordnik.swagger.model._
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers import org.scalatest.matchers.ShouldMatchers
import scala.collection.JavaConverters._ import scala.collection.mutable.LinkedHashMap
@RunWith(classOf[JUnitRunner]) @RunWith(classOf[JUnitRunner])
class ResourceListingSerializersTest extends FlatSpec with ShouldMatchers { class ResourceListingSerializersTest extends FlatSpec with ShouldMatchers {
@ -328,6 +328,12 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
"type":"string", "type":"string",
"required":false, "required":false,
"description":"name" "description":"name"
},
"tags": {
"type":"Array",
"items": {
"type":"string"
}
} }
}, },
"description":"nice model" "description":"nice model"
@ -339,9 +345,9 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
model.id should be ("Foo") model.id should be ("Foo")
model.name should be ("Bar") model.name should be ("Bar")
model.properties should not be (null) 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.description should be (Some("nice model"))
model.properties.asScala("id") match { model.properties("id") match {
case e: ModelProperty => { case e: ModelProperty => {
e.`type` should be ("string") e.`type` should be ("string")
e.required should be (true) e.required should be (true)
@ -349,7 +355,7 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
} }
case _ => fail("missing property id") case _ => fail("missing property id")
} }
model.properties.asScala("name") match { model.properties("name") match {
case e: ModelProperty => { case e: ModelProperty => {
e.`type` should be ("string") e.`type` should be ("string")
e.required should be (false) e.required should be (false)
@ -357,13 +363,25 @@ class ModelSerializationTest extends FlatSpec with ShouldMatchers {
} }
case _ => fail("missing property name") 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") case _ => fail("expected type Model")
} }
} }
it should "serialize a model" in { 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"}}}""") 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) val json = parse(jsonString)
json.extract[ModelRef] match { json.extract[ModelRef] match {
case p: ModelRef => { case p: ModelRef => {
p.ref should be ("Foo") p.ref should be (Some("Foo"))
p.`type` should be ("Bar") p.`type` should be ("Bar")
} }
case _ => fail("expected type ModelRef") case _ => fail("expected type ModelRef")
@ -390,8 +408,8 @@ class ModelRefSerializationTest extends FlatSpec with ShouldMatchers {
} }
it should "serialize a model ref" in { it should "serialize a model ref" in {
val ref = ModelRef("Foo", "Bar") val ref = ModelRef("Foo", Some("Bar"))
write(ref) should be ("""{"$ref":"Foo","type":"Bar"}""") write(ref) should be ("""{"type":"Foo","$ref":"Bar"}""")
} }
} }
@ -410,8 +428,8 @@ class ModelPropertySerializationTest extends FlatSpec with ShouldMatchers {
"values":["1","2","3"] "values":["1","2","3"]
}, },
"items":{ "items":{
"$ref":"Foo", "type":"Foo",
"type":"Bar" "$ref":"Bar"
} }
} }
""" """
@ -427,8 +445,8 @@ class ModelPropertySerializationTest extends FlatSpec with ShouldMatchers {
} }
p.items match { p.items match {
case Some(e: ModelRef) => { case Some(e: ModelRef) => {
e.ref should be ("Foo") e.`type` should be ("Foo")
e.`type` should be ("Bar") e.ref should be (Some("Bar"))
} }
case _ => fail("expected type ModelProperty") 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 { 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"))) 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":{"$ref":"Foo","type":"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 { it should "deserialize a model property with allowable values" in {
@ -511,7 +529,7 @@ class AllowableValuesSerializersTest extends FlatSpec with ShouldMatchers {
} }
""" """
val json = parse(allowableValuesListString) val json = parse(allowableValuesListString)
json.extract[AllowableValuesFoo] match { json.extract[AllowableValues] match {
case avl: AllowableListValues => { case avl: AllowableListValues => {
avl.valueType should be ("LIST") avl.valueType should be ("LIST")
avl.values should be (List("1","2","3")) avl.values should be (List("1","2","3"))
@ -533,7 +551,7 @@ class AllowableValuesSerializersTest extends FlatSpec with ShouldMatchers {
} }
""" """
val json = parse(allowableValuesRangeString) val json = parse(allowableValuesRangeString)
json.extract[AllowableValuesFoo] match { json.extract[AllowableValues] match {
case avr: AllowableRangeValues => { case avr: AllowableRangeValues => {
avr.min should be ("abc") avr.min should be ("abc")
avr.max should be ("3") avr.max should be ("3")

View File

@ -15,7 +15,9 @@
*/ */
import com.wordnik.swagger.model._ 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.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner import org.scalatest.junit.JUnitRunner
@ -24,16 +26,15 @@ import org.scalatest.matchers.ShouldMatchers
import scala.io._ import scala.io._
import scala.collection.JavaConverters._
@RunWith(classOf[JUnitRunner]) @RunWith(classOf[JUnitRunner])
class SwaggerModelTest extends FlatSpec with ShouldMatchers { class SwaggerModelTest extends FlatSpec with ShouldMatchers {
val json = ScalaJsonUtil.getJsonMapper implicit val formats = SwaggerSerializers.formats
behavior of "Swagger Model" behavior of "Swagger Model"
it should "deserialize ResourceListing" in { it should "deserialize ResourceListing" in {
val str = Source.fromFile("src/test/resources/petstore/resources.json").mkString val json = Source.fromFile("src/test/resources/petstore/resources.json").mkString
val listing = json.readValue(str, classOf[ResourceListing]) val listing = parse(json).extract[ResourceListing]
listing.apiVersion should be ("0.2") listing.apiVersion should be ("0.2")
listing.swaggerVersion should be ("1.1") listing.swaggerVersion should be ("1.1")
@ -48,8 +49,8 @@ class SwaggerModelTest extends FlatSpec with ShouldMatchers {
} }
it should "deserialize ApiListing" in { it should "deserialize ApiListing" in {
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
val apiListing = json.readValue(str, classOf[ApiListing]) val apiListing = parse(json).extract[ApiListing]
apiListing.apiVersion should be ("0.2") apiListing.apiVersion should be ("0.2")
apiListing.swaggerVersion should be ("1.1") apiListing.swaggerVersion should be ("1.1")
@ -88,8 +89,8 @@ class SwaggerModelTest extends FlatSpec with ShouldMatchers {
} }
it should "deserialize ApiListing with AllowableValues" in { it should "deserialize ApiListing with AllowableValues" in {
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
val apiListing = json.readValue(str, classOf[ApiListing]) val apiListing = parse(json).extract[ApiListing]
val apiMap = apiListing.apis.map(api => (api.path, api)).toMap val apiMap = apiListing.apis.map(api => (api.path, api)).toMap
val petBaseApi = apiMap("/pet.{format}/findByStatus") val petBaseApi = apiMap("/pet.{format}/findByStatus")
val findPetsByStatus = petBaseApi.operations.head val findPetsByStatus = petBaseApi.operations.head
@ -111,14 +112,14 @@ class SwaggerModelTest extends FlatSpec with ShouldMatchers {
} }
it should "maintain model property order when deserializing" in { it should "maintain model property order when deserializing" in {
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
val apiListing = json.readValue(str, classOf[ApiListing]) val apiListing = parse(json).extract[ApiListing]
val models = apiListing.models val models = apiListing.models
models.size should be (3) models.size should be (3)
val pet = models("Pet") val pet = models("Pet")
val petProperties = pet.properties.asScala.toList val petProperties = pet.properties.toList
petProperties.size should be (6) petProperties.size should be (6)
petProperties(0)._1 should be ("tags") petProperties(0)._1 should be ("tags")
@ -130,8 +131,8 @@ class SwaggerModelTest extends FlatSpec with ShouldMatchers {
} }
it should "deserialize models" in { it should "deserialize models" in {
val str = Source.fromFile("src/test/resources/petstore/pet.json").mkString val json = Source.fromFile("src/test/resources/petstore/pet.json").mkString
val apiListing = json.readValue(str, classOf[ApiListing]) val apiListing = parse(json).extract[ApiListing]
val models = apiListing.models val models = apiListing.models
models.size should be (3) models.size should be (3)
@ -140,11 +141,11 @@ class SwaggerModelTest extends FlatSpec with ShouldMatchers {
pet.id should be ("Pet") pet.id should be ("Pet")
pet.properties.size should be (6) pet.properties.size should be (6)
val properties = pet.properties.asScala val properties = pet.properties
val tags = properties("tags") val tags = properties("tags")
tags.`type` should be ("Array") tags.`type` should be ("Array")
tags.items should not be (None) tags.items should not be (None)
tags.items.get.ref should be ("Tag") tags.items.get.ref should be (Some("Tag"))
val id = properties("id") val id = properties("id")
// id.`type` shoud be ("long") // id.`type` shoud be ("long")

View File

@ -15,7 +15,7 @@
*/ */
import com.wordnik.swagger.model._ 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.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner import org.scalatest.junit.JUnitRunner
@ -27,8 +27,6 @@ import scala.reflect.BeanProperty
@RunWith(classOf[JUnitRunner]) @RunWith(classOf[JUnitRunner])
class ResourceExtractorTest extends FlatSpec with ShouldMatchers { class ResourceExtractorTest extends FlatSpec with ShouldMatchers {
val json = ScalaJsonUtil.getJsonMapper
behavior of "ResourceExtractor" behavior of "ResourceExtractor"
it should "get 3 apis from a resource listing" in { it should "get 3 apis from a resource listing" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json") val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
@ -39,12 +37,11 @@ class ResourceExtractorTest extends FlatSpec with ShouldMatchers {
@RunWith(classOf[JUnitRunner]) @RunWith(classOf[JUnitRunner])
class ApiExtractorTest extends FlatSpec with ShouldMatchers { class ApiExtractorTest extends FlatSpec with ShouldMatchers {
val json = ScalaJsonUtil.getJsonMapper
behavior of "ApiExtractor" behavior of "ApiExtractor"
it should "verify the deserialization of the store api" in { it should "verify the deserialization of the store api" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json") val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
val docs = ApiExtractor.extractApiOperations("src/test/resources/petstore", resourceListing.apis) val docs = ApiExtractor.extractApiOperations("src/test/resources/petstore", resourceListing.apis)
val m = docs.map(t => (t.resourcePath, t)).toMap val m = docs.map(t => (t.resourcePath, t)).toMap
val storeApi = m("/store") val storeApi = m("/store")
@ -68,7 +65,6 @@ class ApiExtractorTest extends FlatSpec with ShouldMatchers {
@RunWith(classOf[JUnitRunner]) @RunWith(classOf[JUnitRunner])
class CoreUtilsTest extends FlatSpec with ShouldMatchers { class CoreUtilsTest extends FlatSpec with ShouldMatchers {
val json = ScalaJsonUtil.getJsonMapper
sys.props += "fileMap" -> "src/test/resources/petstore" sys.props += "fileMap" -> "src/test/resources/petstore"
behavior of "CoreUtils" behavior of "CoreUtils"