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-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",

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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")
}
}

View File

@ -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 _ =>
}
}

View File

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

View File

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

View File

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

View File

@ -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 _ =>
}

View File

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

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.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 {

View File

@ -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 (

View File

@ -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"

View File

@ -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"))
}
}

View File

@ -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")

View File

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

View File

@ -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"