Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merge swagger changes

  • Loading branch information...
commit 6e5ec750b2609129fc9e810e4ac8dcabca599d2e 2 parents 57db379 + 8a1bff8
@casualjim casualjim authored
View
2  README.markdown
@@ -1,4 +1,4 @@
-## Scalatra [![Build Status](https://jenkins.backchat.io/job/scalatra-2.2.x_2.10/badge/icon)](https://jenkins.backchat.io/job/scalatra-2.2.x_2.10/)
+## Scalatra [![Build Status](http://jenkins.backchat.io/job/scalatra-2.2.x_2.10/badge/icon)](http://jenkins.backchat.io/job/scalatra-2.2.x_2.10/)
Scalatra is a tiny, [Sinatra](http://www.sinatrarb.com/)-like web framework for
[Scala](http://www.scala-lang.org/).
View
3  project/build.scala
@@ -265,6 +265,7 @@ object ScalatraBuild extends Build {
lazy val jettyWebapp = "org.eclipse.jetty" % "jetty-webapp" % jettyVersion
lazy val jodaConvert = "org.joda" % "joda-convert" % "1.2"
lazy val jodaTime = "joda-time" % "joda-time" % "2.2"
+// lazy val json4sAst = "org.json4s" %% "json4s-ast" % json4sVersion
lazy val json4sCore = "org.json4s" %% "json4s-core" % json4sVersion
lazy val json4sExt = "org.json4s" %% "json4s-ext" % json4sVersion
lazy val json4sJackson = "org.json4s" %% "json4s-jackson" % json4sVersion
@@ -309,7 +310,7 @@ object ScalatraBuild extends Build {
private val jettyVersion = "8.1.10.v20130312"
- private val json4sVersion = "3.2.4"
+ private val json4sVersion = "3.2.3"
private val scalateArtifact: String => String = {
case sv if sv startsWith "2.8." => "scalate-core"
View
25 swagger/src/main/scala/org/scalatra/swagger/Swagger.scala
@@ -9,8 +9,10 @@ import format.ISODateTimeFormat
import grizzled.slf4j.Logger
import java.util.Date
import reflect.{ScalaType, PrimitiveDescriptor, ClassDescriptor, Reflector}
-import com.wordnik.swagger.core.ApiPropertiesReader
+import com.wordnik.swagger.core.{DocumentationAllowableValues, DocumentationAllowableRangeValues, DocumentationAllowableListValues, ApiPropertiesReader}
import collection.JavaConverters._
+import org.scalatra.swagger.AllowableValues.AllowableValuesList
+import org.scalatra.swagger.AllowableValues.AllowableRangeValues
trait SwaggerEngine[T <: SwaggerApi[_]] {
@@ -79,12 +81,25 @@ object Swagger {
val name = docObj.getName
val flds = docObj.getFields.asScala.filter(d => d.paramType != null)
- val fields = for (field <- flds)
- yield (field.name -> ModelField(field.name, field.notes, DataType(field.paramType)))
+ val fields = for (field <- flds) yield {
+ (field.name ->
+ ModelField(field.name,
+ field.description,
+ DataType(field.paramType),
+ allowableValues = allowableValuesToString(field.allowableValues))) }
Some(Model(name, name, fields.toMap))
}
}
+ private def allowableValuesToString(allowableValues: DocumentationAllowableValues) = {
+ import scala.collection.JavaConversions._
+
+ allowableValues match {
+ case list:DocumentationAllowableListValues => AllowableValuesList(list.getValues.toList)
+ case range:DocumentationAllowableRangeValues => AllowableRangeValues(Range(range.getMin.toInt, range.getMax.toInt))
+ case _ => AllowableValues.AnyValue
+ }
+ }
}
/**
@@ -204,7 +219,8 @@ private[swagger] object SwaggerSerializers {
case x: ModelField => {
val c = ("description" -> x.description) ~
("defaultValue" -> x.defaultValue) ~
- ("required" -> x.required)
+ ("required" -> x.required) ~
+ ("allowableValues" -> Extraction.decompose(x.allowableValues))
c merge serializeDataType("type", x.`type`)
}
}
@@ -379,6 +395,7 @@ case class ModelField(name: String,
description: String,
`type`: DataType.DataType,
defaultValue: Option[String] = None,
+ allowableValues: AllowableValues = AllowableValues.AnyValue,
required: Boolean = true)
object ModelField {
View
8 swagger/src/main/scala/org/scalatra/swagger/package.scala
@@ -14,4 +14,10 @@ package object swagger {
val Description = Symbol("swagger.description")
val AllSymbols = Set(Summary, Notes, Nickname, ResponseClass, Parameters, Errors, Endpoint, Allows, Operation)
}
-}
+
+ object annotations {
+ import scala.annotation.meta.getter
+
+ type ApiProperty = com.wordnik.swagger.annotations.ApiProperty @getter
+ }
+}
View
33 swagger/src/test/resources/pet.json
@@ -170,45 +170,48 @@
"properties": {
"category": {
"description": null,
- "enum": [],
- "name": "category",
"required": true,
"type": "Category"
},
"id": {
"description": null,
- "enum": [],
- "name": "id",
"required": true,
"type": "long"
},
"name": {
"description": null,
- "enum": [],
- "name": "name",
"required": true,
"type": "string"
},
"status": {
- "description": null,
- "enum": [],
- "name": "status",
+ "description": "pet availability",
"required": true,
+ "allowableValues": {
+ "valueType": "LIST",
+ "values": [
+ "available",
+ "sold"
+ ]
+ },
"type": "string"
},
"tags": {
"description": null,
- "enum": [],
- "name": "tags",
"required": true,
- "type": "List[Tag]"
+ "type": "Array",
+ "uniqueItems": false,
+ "items": {
+ "$ref": "Tag"
+ }
},
"urls": {
"description": null,
- "enum": [],
- "name": "urls",
"required": true,
- "type": "List[string]"
+ "type": "Array",
+ "uniqueItems": false,
+ "items": {
+ "type": "string"
+ }
}
}
}
View
37 swagger/src/test/scala/org/scalatra/swagger/ModelSpec.scala
@@ -0,0 +1,37 @@
+package org.scalatra.swagger
+
+import org.specs2.mutable.Specification
+import org.scalatra.swagger.annotations.ApiProperty
+import org.scalatra.swagger.AllowableValues.{AllowableRangeValues, AllowableValuesList}
+
+object ModelSpec {
+
+ case class WithDescription(@ApiProperty(value = "a description", allowableValues = "item1,item2")
+ id: String)
+ case class WithAllowableValues(@ApiProperty(allowableValues = "item1,item2")
+ id: String)
+ case class WithAllowableRangeValues(@ApiProperty(allowableValues = "range[1,10]")
+ id: String)
+
+ def swaggerProperties[T](implicit mf: Manifest[T]) = Swagger.modelToSwagger(mf.erasure).get.properties.get("id").get
+
+}
+
+class ModelSpec extends Specification {
+ import ModelSpec._
+
+ "Model to Swagger" should {
+
+ "convert a populated description property of an ApiProperty annotation" in {
+ swaggerProperties[WithDescription].description must_== "a description"
+ }
+
+ "convert a populated allowable values property of an ApiProperty annotation" in {
+ swaggerProperties[WithAllowableValues].allowableValues must_== AllowableValuesList(List("item1", "item2"))
+ }
+ "convert a populated allowable values property of an ApiProperty annotation when it is a range" in {
+ swaggerProperties[WithAllowableRangeValues].allowableValues must_== AllowableRangeValues(Range(1, 10))
+ }
+ }
+
+}
View
16 swagger/src/test/scala/org/scalatra/swagger/SwaggerSpec.scala
@@ -12,6 +12,7 @@ import org.json4s.native.JsonParser
import org.scalatra.json.{JValueResult, NativeJsonSupport}
import scala.io.Source
import java.net.ServerSocket
+import org.scalatra.swagger.annotations.ApiProperty
class SwaggerSpec extends ScalatraSpec with JsonMatchers { def is = sequential ^
"Swagger integration should" ^
@@ -53,7 +54,8 @@ class SwaggerSpec extends ScalatraSpec with JsonMatchers { def is = sequential ^
val bo = JsonParser.parseOpt(body)
bo must beSome[JValue] and
verifyCommon(bo.get) and
- operations.map(verifyOperation(bo.get, _)).reduce(_ and _)
+ operations.map(verifyOperation(bo.get, _)).reduce(_ and _) and
+ verifyPetModel(bo.get)
}
}
@@ -78,6 +80,15 @@ class SwaggerSpec extends ScalatraSpec with JsonMatchers { def is = sequential ^
}
}
+ def verifyPetModel(actualPetJson: JValue) = {
+ def petProperties(jv: JValue) = jv \ "models" \ "Pet" \ "properties"
+ val actualPetProps = petProperties(actualPetJson)
+ val expectedPetProps = petProperties(listOperationsJValue)
+
+ val m = verifyFields(actualPetProps, expectedPetProps, "category", "id", "name", "status", "tags", "urls")
+ m setMessage (m.message + " of the pet model")
+ }
+
def verifyFields(actual: JValue, expected: JValue, fields: String*): MatchResult[Any] = {
def verifyField(act: JValue, exp: JValue, fn: String): MatchResult[Any] = {
fn match {
@@ -202,7 +213,8 @@ class SwaggerTestServlet(protected val swagger:Swagger) extends ScalatraServlet
class SwaggerResourcesServlet(val swagger: Swagger) extends ScalatraServlet with NativeSwaggerBase
-case class Pet(id: Long, category: Category, name: String, urls: List[String], tags: List[Tag], status: String)
+case class Pet(id: Long, category: Category, name: String, urls: List[String], tags: List[Tag],
+ @ApiProperty(value = "pet availability", allowableValues = "available,sold") status: String)
case class Tag(id: Long, name: String)
case class Category(id: Long, name: String)
Please sign in to comment.
Something went wrong with that request. Please try again.