Merge branch 'master' of github.com:wordnik/swagger-codegen

This commit is contained in:
Ivan Porto Carrero 2013-03-08 23:02:03 +01:00
commit 3cbf2abc5c
21 changed files with 9931 additions and 144 deletions

View File

@ -11,7 +11,7 @@
* @param string $className the class to attempt to load
*/
function swagger_autoloader($className) {
$currentDir = substr(__FILE__, 0, strrpos(__FILE__, '/'));
$currentDir = dirname(__FILE__);
if (file_exists($currentDir . '/' . $className . '.php')) {
include $currentDir . '/' . $className . '.php';
} elseif (file_exists($currentDir . '/models/' . $className . '.php')) {

View File

@ -11,7 +11,7 @@
* @param string $className the class to attempt to load
*/
function swagger_autoloader($className) {
$currentDir = substr(__FILE__, 0, strrpos(__FILE__, '/'));
$currentDir = dirname(__FILE__);
if (file_exists($currentDir . '/' . $className . '.php')) {
include $currentDir . '/' . $className . '.php';
} elseif (file_exists($currentDir . '/models/' . $className . '.php')) {

View File

@ -11,7 +11,7 @@
* @param string $className the class to attempt to load
*/
function swagger_autoloader($className) {
$currentDir = substr(__FILE__, 0, strrpos(__FILE__, '/'));
$currentDir = dirname(__FILE__);
if (file_exists($currentDir . '/' . $className . '.php')) {
include $currentDir . '/' . $className . '.php';
} elseif (file_exists($currentDir . '/models/' . $className . '.php')) {

View File

@ -44,15 +44,18 @@ class ApiClient:
data = None
if method == 'GET':
if queryParams:
# Need to remove None values, these should not be sent
sentQueryParams = {}
for param, value in queryParams.items():
if value != None:
sentQueryParams[param] = value
url = url + '?' + urllib.urlencode(sentQueryParams)
if queryParams:
# Need to remove None values, these should not be sent
sentQueryParams = {}
for param, value in queryParams.items():
if value != None:
sentQueryParams[param] = value
url = url + '?' + urllib.urlencode(sentQueryParams)
if method in ['GET']:
#Options to add statements later on and for compatibility
pass
elif method in ['POST', 'PUT', 'DELETE']:
@ -95,7 +98,7 @@ class ApiClient:
def sanitizeForSerialization(self, obj):
"""Dump an object into JSON for POSTing."""
if not obj:
if type(obj) == type(None):
return None
elif type(obj) in [str, int, long, float, bool]:
return obj
@ -164,6 +167,8 @@ class ApiClient:
value = attrType(value)
except UnicodeEncodeError:
value = unicode(value)
except TypeError:
value = value
setattr(instance, attr, value)
elif (attrType == 'datetime'):
setattr(instance, attr, datetime.datetime.strptime(value[:-5],

View File

@ -43,15 +43,19 @@ class ApiClient:
data = None
if method == 'GET':
if queryParams:
# Need to remove None values, these should not be sent
sentQueryParams = {}
for param, value in queryParams.items():
if value != None:
sentQueryParams[param] = value
url = url + '?' + urllib.parse.urlencode(sentQueryParams)
if queryParams:
# Need to remove None values, these should not be sent
sentQueryParams = {}
for param, value in queryParams.items():
if value != None:
sentQueryParams[param] = value
url = url + '?' + urllib.parse.urlencode(sentQueryParams)
if method in ['GET']:
#Options to add statements later on and for compatibility
pass
elif method in ['POST', 'PUT', 'DELETE']:
@ -98,7 +102,7 @@ class ApiClient:
def sanitizeForSerialization(self, obj):
"""Dump an object into JSON for POSTing."""
if not obj:
if type(obj) == type(None):
return None
elif type(obj) in [str, int, float, bool]:
return obj
@ -159,6 +163,8 @@ class ApiClient:
value = attrType(value)
except UnicodeEncodeError:
value = unicode(value)
except TypeError:
value = value
setattr(instance, attr, value)
elif (attrType == 'datetime'):
setattr(instance, attr, datetime.datetime.strptime(value[:-5],

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
site.css

View File

@ -0,0 +1,135 @@
.line-numbers {
margin-right: 1.0em;
}
.content {
padding-bottom: 100px;
}
.column_header_name {
width: 150px;
}
.column_header_path {
width: 350px;
}
.column_header_name .column_header_param_type .column_header_data_type .column_header_return_type {
width: 200px;
}
.expandable {
display: none;
}
.main_content {
margin-top: 80px;
margin-left: 25px;
margin-right: 25px;
}
.header {
position: fixed;
text-align: left;
background-color: black;
float: left;
top: 0;
width: 100%;
height: 70px auto;
padding-bottom: 20px;
box-shadow: rgba(0, 0, 0, 0.2) 0 2px 8px 5px;
}
.top-bar h1 a {
width: auto;
}
.top-bar h1#logo a {
width: auto;
display: block;
clear: none;
float: left;
background-position: left;;
color: white;
text-decoration: none;
}
.top-bar ul li {
list-style: none;
}
.top-bar h1#logo span {
display: block;
clear: none;
float: left;
padding-top: 10px;
padding-left: 10px;
margin: 0px;
}
.top-bar h1#logo a span.light {
color: #ffc97a;
color: #666666;
padding-left: 0px;
}
.top-bar ul#nav {
float: none;
clear: both;
overflow: hidden;
margin: 0;
padding: 0;
display: block;
float: right;
clear: none;
}
.top-bar ul#nav li {
float: left;
clear: none;
margin: 0;
padding: 2px 10px;
border-right: 1px solid #dddddd;
}
.top-bar ul#nav li:first-child, .top-bar ul#nav li.first {
padding-left: 0;
}
.top-bar ul#nav li:last-child, .top-bar ul#nav li.last {
padding-right: 0;
border-right: none;
}
.top-bar ul#nav li {
border: none;
padding: 0 5px;
}
.top-bar ul#nav li a {
display: block;
padding: 8px 10px 8px 10px;
color: #999999;
text-decoration: none;
}
.top-bar ul#nav li a.strong {
color: white;
}
.top-bar ul#nav li a:active, .top-bar ul#nav li a.active, .top-bar ul#nav li a:hover {
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
-o-border-radius: 4px;
-ms-border-radius: 4px;
-khtml-border-radius: 4px;
border-radius: 4px;
background-image: -webkit-gradient(linear, 0% 100%, 0% 0%, color-stop(0%, #ff5401), color-stop(100%, #ffa014));
background-image: -moz-linear-gradient(bottom, #ff5401 0%, #ffa014 100%);
background-image: linear-gradient(bottom, #ff5401 0%, #ffa014 100%);
color: white;
}
.top-bar ul#nav:hover li {
border-color: #222222;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="assets/css/bootstrap.css" media="screen">
<link rel="stylesheet" type="text/css" href="assets/css/bootstrap-responsive.css" media="screen">
<link rel="stylesheet" type="text/css" href="assets/css/style.css">
<title>REST API v1.1 Resources | Twitter Developers</title>
</head>
<body>
<div class="header">
<div class="top-bar">
<h1 id="logo"><a class="logo" href="/"><span>Swagger</span><span class="light">API Docs</span></a></h1>
</div>
</div>
<div class="main_content">
<h1>API Documentation</h1>
{{#apis}}
<h2>{{className}}</h2>
<table>
<tr>
<th class="column_header_name">Name</th>
<th class="column_header_path">Resource</th>
<th class="column_header_notes">Notes</th>
</tr>
{{#operations}}
{{#operation}}
<tr>
<td><a href="operations/{{{className}}}.html#{{{nickname}}}">{{{nickname}}}</a></td>
<td>{{path}}</td>
<td>{{{summary}}}{{#notes}}<div id="{{className}}_{{nickname}}" class="operation expandable">{{notes}}</div>{{/notes}}</td>
</tr>
{{/operation}}
{{/operations}}
</table>
{{/apis}}
</div>
</body>
</html>

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="../assets/css/bootstrap.css" media="screen">
<link rel="stylesheet" type="text/css" href="../assets/css/bootstrap-responsive.css" media="screen">
<link rel="stylesheet" type="text/css" href="../assets/css/style.css">
<title>REST API v1.1 Resources | Twitter Developers</title>
</head>
<body>
<div class="header">
<div class="top-bar">
<h1 id="logo"><a class="logo" href="/"><span>Swagger</span><span class="light">API Docs</span></a></h1>
</div>
</div>
<div class="main_content">
<h1>{{classname}}</h1>
{{#operations}}
{{#operation}}
<a name="{{nickname}}"></a>
<h2>{{nickname}}</h2>
<h3>{{httpMethod}}: {{path}}</h3>
<table>
<tr>
<th class="column_header_name">parameter</th>
<th class="column_header_param_type">param type</th>
<th class="column_header_data_type">data type</th>
<th class="column_header_return_type">response type</th>
<th class="column_header_notes">Description</th>
</tr>
<!-- body params -->
{{#bodyParams}}
<tr>
<td>{{paramName}}<br/>{{#required}}required{{/required}}{{^required}}optional{{/required}}</td>
<td>body</td>
<td>{{swaggerDataType}}{{#allowMultiple}}*{{/allowMultiple}}</td>
<td>{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}-{{/returnType}}</td>
<td>{{description}}{{#notes}}<br/><div id="{{className}}_{{nickname}}" class="operation expandable">{{notes}}</div>{{/notes}}</td>
</tr>
{{/bodyParams}}
<!-- path params -->
{{#pathParams}}
<tr>
<td>{{paramName}}<br/>{{#required}}required{{/required}}{{^required}}optional{{/required}}</td>
<td>path</td>
<td>{{swaggerDataType}}{{#allowMultiple}}*{{/allowMultiple}}</td>
<td>{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}-{{/returnType}}</td>
<td>{{description}}{{#notes}}<br/><div id="{{className}}_{{nickname}}" class="operation expandable">{{notes}}</div>{{/notes}}</td>
</tr>
{{/pathParams}}
<!-- query params -->
{{#queryParams}}
<tr>
<td>{{paramName}}<br/>{{#required}}required{{/required}}{{^required}}optional{{/required}}</td>
<td>query</td>
<td>{{swaggerDataType}}{{#allowMultiple}}*{{/allowMultiple}}</td>
<td>{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}-{{/returnType}}</td>
<td>{{description}}{{#notes}}<br/><div id="{{className}}_{{nickname}}" class="operation expandable">{{notes}}</div>{{/notes}}</td>
</tr>
{{/queryParams}}
<!-- header params -->
{{#headerParams}}
<tr>
<td>{{paramName}}<br/>{{#required}}required{{/required}}{{^required}}optional{{/required}}</td>
<td>header</td>
<td>{{swaggerDataType}}{{#allowMultiple}}*{{/allowMultiple}}</td>
<td>{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}-{{/returnType}}</td>
<td>{{description}}{{#notes}}<br/><div id="{{className}}_{{nickname}}" class="operation expandable">{{notes}}</div>{{/notes}}</td>
</tr>
{{/headerParams}}
</table>
{{/operation}}
{{/operations}}
</div>
</body>
</html>

View File

@ -55,15 +55,15 @@ class BasicJavaGenerator extends BasicGenerator {
// location of templates
override def templateDir = "Java"
// where to write generated code
override def destinationDir = "generated-code/java/src/main/java"
// template used for models
modelTemplateFiles += "model.mustache" -> ".java"
// template used for models
apiTemplateFiles += "api.mustache" -> ".java"
// where to write generated code
override def destinationDir = "src/test/java"
override def reservedWords = Set("abstract", "continue", "for", "new", "switch", "assert",
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
@ -168,4 +168,12 @@ class BasicJavaGenerator extends BasicGenerator {
throw new Exception("reserved word " + "\"" + word + "\" not allowed")
else word
}
// supporting classes
// supporting classes
override def supportingFiles =
List(
("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiInvoker.java"),
("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replaceAll("\\.", java.io.File.separator) + java.io.File.separator, "ApiException.java"),
("pom.mustache", "generated-code/java", "pom.xml"))
}

View File

@ -62,7 +62,7 @@ class SwaggerSpecValidator(private val doc: ResourceListing,
}
def validateResponseModels(subDocs: List[ApiListing]) = {
val validModelNames = CoreUtils.extractAllModels2(subDocs).map(m => m._1).toSet
val validModelNames = CoreUtils.extractAllModels(subDocs).map(m => m._1).toSet
val requiredModels = new HashSet[String]
subDocs.foreach(subDoc => {
if (subDoc.apis != null) {

View File

@ -25,11 +25,11 @@ import com.wordnik.swagger.codegen.spec.SwaggerSpec._
import scala.io.Source
object CoreUtils {
def extractAllModels2(apis: List[ApiListing]): Map[String, Model] = {
def extractAllModels(apis: List[ApiListing]): Map[String, Model] = {
val modelObjects = new HashMap[String, Model]
apis.foreach(api => {
for ((nm, model) <- extractApiModels(api)) modelObjects += nm -> model
if (api.models != null) api.models.foreach(model => modelObjects += model._1 -> model._2)
api.models.foreach(model => modelObjects += model._1 -> model._2)
})
modelObjects.toMap
}
@ -38,49 +38,13 @@ object CoreUtils {
val modelNames = new HashSet[String]
modelNames += op.responseClass
// POST, PUT, DELETE body
if (op.parameters != null) {
op.parameters.filter(p => p.paramType == "body")
.foreach(p => modelNames += p.dataType)
}
op.parameters.filter(p => p.paramType == "body")
.foreach(p => modelNames += p.dataType)
val baseNames = (for (modelName <- (modelNames.toList))
yield (extractBasePartFromType(modelName))).toSet
baseNames.toSet
}
def extractModelNames2(modelObjects: Map[String, Model], ep: Operation): Set[String] = {
val modelNames = new HashSet[String]
modelNames += ep.responseClass
// POST, PUT, DELETE body
if (ep.parameters != null)
ep.parameters.filter(p => p.paramType == "body")
.foreach(p => modelNames += p.dataType)
val baseNames = (for (modelName <- (modelNames.toList))
yield (extractBasePartFromType(modelName))).toSet
// get complex models from base
val requiredModels = modelObjects.filter(obj => baseNames.contains(obj._1))
val subNames = new HashSet[String]
// look inside top-level models
requiredModels.map(model => {
// add top level model
subNames += model._1
model._2.properties.foreach(prop => {
val subObject = prop._2
if (containers.contains(subObject.`type`)) {
subObject.items match {
case Some(item) => subNames += item.ref.getOrElse(item.`type`)
case None =>
}
}
else subNames += subObject.`type`
})
})
subNames.toSet
}
def extractBasePartFromType(datatype: String): String = {
val ComplexTypeMatcher = ".*\\[(.*)\\].*".r
datatype match {
@ -93,21 +57,16 @@ object CoreUtils {
val modelNames = new HashSet[String]
val modelObjects = new HashMap[String, Model]
// return types
if(sd.apis != null){
sd.apis.foreach(api => {
if (api.operations != null)
api.operations.foreach(op => {
modelNames += op.responseClass
// POST, PUT, DELETE body
if(op.parameters != null)
op.parameters.filter(p => p.paramType == "body")
.foreach(p => modelNames += p.dataType)
})
sd.apis.foreach(api =>
api.operations.foreach(op => {
modelNames += op.responseClass
// POST, PUT, DELETE body
op.parameters.filter(p => p.paramType == "body")
.foreach(p => modelNames += p.dataType)
})
}
if(sd.models != null)
for ((name, m) <- sd.models)
modelObjects += name -> m
)
for ((name, m) <- sd.models)
modelObjects += name -> m
// extract all base model names, strip away Containers like List[] and primitives
val baseNames = (for (modelName <- (modelNames.toList filterNot primitives.contains))
@ -118,40 +77,47 @@ object CoreUtils {
val subNames = new HashSet[String]
// look inside top-level models
requiredModels.map(model => {
model._2.properties.foreach(prop => {
val subObject = prop._2
if (containers.contains(subObject.`type`)) {
subObject.items match {
case Some(subItem) => {
val sn = subItem.ref.getOrElse(subItem.`type`)
if(sn != null)
subNames += sn
}
case _ =>
}
} else subNames += subObject.`type`
})
})
recurseModels(requiredModels.toMap, modelObjects.toMap, subNames)
// look inside submodels
modelObjects.filter(obj => subNames.contains(obj._1)).foreach(model => {
model._2.properties.foreach(prop => {
val subObject = prop._2
if (containers.contains(subObject.`type`)) {
subObject.items match {
case Some(subItem) => {
val sn = subItem.ref.getOrElse(subItem.`type`)
if(sn != null)
subNames += sn
}
case _ =>
}
} else subNames += subObject.`type`
})
})
val subModels = modelObjects.filter(obj => subNames.contains(obj._1))
val allModels = requiredModels ++ subModels
allModels.filter(m => primitives.contains(m._1) == false).toMap
}
def recurseModels(requiredModels: Map[String, Model], allModels: Map[String, Model], subNames: HashSet[String]) = {
requiredModels.map(m => recurseModel(m._2, allModels, subNames))
}
def recurseModel(model: Model, allModels: Map[String, Model], subNames: HashSet[String]): Unit = {
model.properties.foreach(prop => {
val subObject = prop._2
val propertyName = containers.contains(subObject.`type`) match {
case true => subObject.items match {
case Some(subItem) => {
Option(subItem.ref.getOrElse(subItem.`type`)) match {
case Some(sn) => Some(sn)
case _ => None
}
}
case _ => None
}
case false => Some(subObject.`type`)
}
propertyName match {
case Some(property) => subNames.contains(property) match {
case false => {
allModels.containsKey(property) match {
case true => {
recurseModel(allModels(property), allModels, subNames)
}
case false =>
}
subNames += property
}
case true =>
}
case None =>
}
})
}
}

View File

@ -233,7 +233,6 @@ class BasicScalaGeneratorTest extends FlatSpec with ShouldMatchers {
m("returnBaseType") should be (Some("Pet"))
// problem here
println("the operation has response class " + operation.responseClass)
m("returnType") should be (Some("List[Pet]"))
m("returnTypeIsPrimitive") should be (None)
m("pathParams").asInstanceOf[List[_]].size should be (0)

View File

@ -0,0 +1,265 @@
import com.wordnik.swagger.codegen.util.CoreUtils
import com.wordnik.swagger.model._
import com.wordnik.swagger.codegen.util._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.read
import scala.collection.mutable.LinkedHashMap
@RunWith(classOf[JUnitRunner])
class CoreUtilsTest extends FlatSpec with ShouldMatchers {
sys.props += "fileMap" -> "src/test/resources/petstore"
behavior of "CoreUtils"
it should "verify models are extracted" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
val apis = ApiExtractor.extractApiOperations("src/test/resources/petstore", resourceListing.apis)
val cu = CoreUtils.extractAllModels(apis)
cu.size should be (5)
(cu.keys.toSet & Set("User", "Tag", "Pet", "Category", "Order")).size should be (5)
}
it should "verify operation names" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
val apis = ApiExtractor.extractApiOperations("src/test/resources/petstore", resourceListing.apis)
val petApi = apis.filter(api => api.resourcePath == "/pet").head
val eps = petApi.apis.map(api => (api.path, api)).toMap
val ops = eps("/pet.{format}").operations.map(ep => (ep.nickname, ep)).toMap
ops.size should be (2)
(ops.keys.toSet & Set("addPet", "updatePet")).size should be (2)
}
it should "find required models" in {
val apis = CoreUtilsTest.sampleApis1
val models = CoreUtils.extractApiModels(apis.head)
models.size should be (5)
}
it should "find required models from a nested list" in {
val apis = CoreUtilsTest.sampleApis2
val models = CoreUtils.extractApiModels(apis.head)
models.size should be (5)
}
}
object CoreUtilsTest {
implicit val formats = SwaggerSerializers.formats
def sampleApis1 = {
parse("""
[
{
"apiVersion": "0.2",
"swaggerVersion": "1.1",
"basePath": "http://api.helloreverb.com/api",
"resourcePath": "/mysteries",
"apis": [
{
"path": "/mysteries.{format}/{petId}",
"description": "As the name suggests",
"operations": [
{
"httpMethod": "GET",
"summary": "You find amazing htings here",
"responseClass": "DeepMystery",
"nickname": "getMysteryById",
"parameters": [
{
"name": "id",
"description": "ID of mystery",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
}
],
"models": {
"MysteryList": {
"id": "MysteryList",
"properties": {
"id": {
"type": "long"
},
"mysteries": {
"items":{
"$ref":"Mystery1"
},
"type":"Array"
}
}
},
"DeepMystery": {
"id": "DeepMystery",
"properties": {
"id": {
"type": "Mystery1"
},
"name": {
"type": "string"
}
}
},
"Mystery1": {
"id": "Mystery1",
"properties": {
"mystery2": {
"type": "Mystery2"
},
"name": {
"type": "string"
}
}
},
"Mystery2": {
"id": "Mystery2",
"properties": {
"mystery3": {
"type": "Mystery3"
},
"name": {
"type": "string"
}
}
},
"Mystery3": {
"id": "Mystery3",
"properties": {
"mystery4": {
"type": "Mystery4"
},
"name": {
"type": "string"
}
}
},
"Mystery4": {
"id": "Mystery4",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}
]
""").extract[List[ApiListing]]
}
def sampleApis2 = {
parse("""
[
{
"apiVersion": "0.2",
"swaggerVersion": "1.1",
"basePath": "http://api.helloreverb.com/api",
"resourcePath": "/mysteries",
"apis": [
{
"path": "/mysteries.{format}/{petId}",
"description": "As the name suggests",
"operations": [
{
"httpMethod": "GET",
"summary": "You find amazing htings here",
"responseClass": "MysteryList",
"nickname": "getMysteryById",
"parameters": [
{
"name": "id",
"description": "ID of mystery",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
}
],
"models": {
"MysteryList": {
"id": "MysteryList",
"properties": {
"id": {
"type": "long"
},
"mystery1": {
"type":"Mystery1"
}
}
},
"Mystery1": {
"id": "Mystery1",
"properties": {
"mystery2": {
"type": "Mystery2"
},
"name": {
"type": "string"
}
}
},
"Mystery2": {
"id": "Mystery2",
"properties": {
"mystery3List": {
"items": {
"$ref": "Mystery3"
},
"type": "List"
},
"name": {
"type": "string"
}
}
},
"Mystery3": {
"id": "Mystery3",
"properties": {
"mystery4": {
"type": "Mystery4"
},
"name": {
"type": "string"
}
}
},
"Mystery4": {
"id": "Mystery4",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}
]
""").extract[List[ApiListing]]
}
}

View File

@ -59,7 +59,6 @@ class ResourceListingValidationTest extends FlatSpec with ShouldMatchers {
"""
parse(jsonString).extract[ResourceListing] match {
case e: ResourceListing => {
println(e)
e.apis.size should be (2)
}
case _ => fail("didn't parse the underlying apis")

View File

@ -62,33 +62,3 @@ class ApiExtractorTest extends FlatSpec with ShouldMatchers {
getOrderById.errorResponses.size should be (2)
}
}
@RunWith(classOf[JUnitRunner])
class CoreUtilsTest extends FlatSpec with ShouldMatchers {
sys.props += "fileMap" -> "src/test/resources/petstore"
behavior of "CoreUtils"
it should "verify models are extracted" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
val apis = ApiExtractor.extractApiOperations("src/test/resources/petstore", resourceListing.apis)
val cu = CoreUtils.extractAllModels2(apis)
cu.size should be (5)
(cu.keys.toSet & Set("User", "Tag", "Pet", "Category", "Order")).size should be (5)
}
it should "verify operation names" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore/resources.json")
val apis = ApiExtractor.extractApiOperations("src/test/resources/petstore", resourceListing.apis)
val petApi = apis.filter(api => api.resourcePath == "/pet").head
val eps = petApi.apis.map(api => (api.path, api)).toMap
val ops = eps("/pet.{format}").operations.map(ep => (ep.nickname, ep)).toMap
ops.size should be (2)
(ops.keys.toSet & Set("addPet", "updatePet")).size should be (2)
}
}