diff --git a/README.md b/README.md index 95112943551..27100ac4352 100644 --- a/README.md +++ b/README.md @@ -2,208 +2,57 @@ ## Overview This is a project to build the Swagger code-gen library which can be used to automatically -generate client libraries from a Swagger-compliant server. It also contains a testing -framework which allows the client library to query an API server and validate expected results -You can find out more about both the spec and the framework at http://swagger.wordnik.com. For -more information about Wordnik's APIs, please visit http://developer.wordnik.com. +generate client libraries from a Swagger-compliant server. You can find out more about both +the spec and the framework at http://swagger.wordnik.com. For more information about Wordnik's +APIs, please visit http://developer.wordnik.com. ### Prerequisites You need the following installed and available in your $PATH:
  • - Java 1.6 or greater (http://java.oracle.com) -
  • - Apache ant 1.7 or greater (http://ant.apache.org/) +
  • - Apache maven 3.0.3 or greater (http://maven.apache.org/) -
  • - Scala 2.x or greater (http://www.scala-lang.org/downloads) +
  • - Scala 2.9.1 [available here](http://www.scala-lang.org) -You also need to set an environment variable for SCALA_HOME: - -
    -export SCALA_HOME={PATH_TO_YOUR_SCALA_DEPLOYMENT}
    -
    +You also need to add the scala binary to your PATH. ### To build the codegen library -If you don't have the Apache Ivy dependency manager installed, run this build script: - -
    -ant -f install-ivy
    -
    - -This will copy the ivy ant lib into your antlib directory. Now you can build the artifact: - -
    -ant
    -
    This will create the swagger-codegen library in your build folder. - -### To build java client source files -
    -./bin/generate-java-lib.sh {server-url} {api_key} {output-package} {output-dir}
    +mvn package
     
    -for example: -
    -./bin/generate-java-lib.sh http://petstore.swagger.wordnik.com/api/ special-key com.foo.mydriver generated-files
    -
    -### Other languages -#### scala -
    -./bin/generate-scala-lib.sh http://petstore.swagger.wordnik.com/api "" "client" "generated-files"
    -
    - -#### javascript -
    -./bin/generate-js-lib.sh http://petstore.swagger.wordnik.com/api "" "" "generated-files"
    -
    - -#### actionscript -
    -./bin/generate-as3-lib.sh http://petstore.swagger.wordnik.com/api "" "client" "generated-files"
    -
    - -#### PHP -
    -./bin/generate-php-lib.sh http://petstore.swagger.wordnik.com/api "" "client" "generated-files"
    -
    - -#### Python -
    -./bin/generate-python-lib.sh http://petstore.swagger.wordnik.com/api "" "client" "generated-files"
    -
    - -The main class for the generator is at src/main/java/com/wordnik/swagger/codegen/config/java/JavaLibCodeGen.java - -The code-gen uses the antlr string template library for generating the output files, please look at -http://www.stringtemplate.org for details on the antlr framework. - -The Wordnik team is working on generating libraries for Ruby, ActionScript 3, Android, PHP and JavaScript, which will be open-sourced in the coming weeks - -### The Swagger client test framework - -The testing framework helps you to test Swagger generated client libraries using declarative test scripts. The same -scripts can be used to test client libraries in different languages. The framework can be used for client and server -regression testing. - -For Example, first build the client library from the sample app: -
    -./bin/generate-java-lib.sh http://petstore.swagger.wordnik.com/api/ special-key com.foo.mydriver generated-files
    -
    - -Use the sample build script to build a jar from the client files: -
    -cp conf/java/sample/*.xml ./generated-files
    -
    -cd generated-files
    -
    -ant
    -
    - -This creates a complete client library jar. You can now run the tests: +### To generate a sample client library +You can build a client against Wordnik's [petstore](http://petstore.swagger.wordnik.com) API as follows:
    -./bin/test-java-lib.sh http://petstore.swagger.wordnik.com/api/ special-key conf/java/sample/lib-test-script.json \
    -    conf/java/sample/lib-test-data.json com.foo.mydriver.model.TestData com.foo.mydriver.api \
    -    generated-files/build/swagger-sample-java-lib-1.0.jar
    -
    -Summary -->  Total Test Cases: 9 Failed Test Cases: 0
    -Details: 
    -1.1 : Create User :  passed  
    - 
    -1.2 : Login User :  passed  
    - 
    -1.3 : Find user by name :  passed  
    - 
    -1.4 : Delete user by name :  passed  
    - 
    -2.1 : Add pet :  passed  
    - 
    -2.2 : Find pet by id :  passed  
    - 
    -2.3 : Find pet by status :  passed  
    - 
    -3.1 : Find order by id :  passed  
    - 
    -3.2 : Place order :  passed 
    +./bin/scala-petstore.sh
     
    -In detail, there are two components in the test framework: - -
  • - Test Script - -
  • - Test Data - - -#### Test script details - -Test script is written in JSON structure. The JSON consists of following elements: - -##### Resources. This is a list of resources considered in the test. Each resource object consists of following properties: - -
  • - id: a unique test script ID - -
  • - name: name of the resource, used in displaying the test result - -
  • - httpMethod: HTTP method used in invoking this resource - -
  • - path: path of the resource - -
  • - suggested method name: By default this refers to method name of the API in resource classes - -##### Test suites. This is a logical way of grouping related test cases. Each test suite consists of following properties: - -
  • - id: unique id of the test script, displayed in the test report - -
  • - name: name of the test suite. Used in test report - -
  • - test cases: List of test cases with in each suite. Each test case consists of following properties: - -
  • - id: unique with in the test suite. Used for reporting and tracking output data - -
  • - name: Name of the test case - -
  • - resource id: references the resource id in the resources section - -
  • - input: Input is a JSON object with each property in the object map to query, path or post parameters. - For POST data, the name of the property should be supplied as postData. The value for each property can refer - to input file or output from previous test cases or actual values. - -
  • - assertions: list of assertions that needs to be evaluated after test case is executed. - -Each assertion contains - -
  • - actual output, specified with reference to output of the current test case using syntax similar to object graph navigation language -
  • - condition , support values are equal (==), not equal (!=), less than (<), lesser than or equal (<=), greater than (>), greater than or equal (>=) -
  • - expected output. Specified using actual values or values referring previous outputs or input data file - -Test data file is documented using a Test Data Object which is generated as part of Java client library code-gen. This -class provides list getters and setters for each model object available in the resource description. It is called "TestData" -and it is available in model package of the java library code generation output. - -Chaining results of test cases: - -
  • - Reference to data in input file is done with prefix
    ${input.
    , followed by object graph navigation syntax. -Example: to refer a first user object in test data file use the syntax
    ${input.userList[0]}
    - -
  • - To refer a individual property of user object use the syntax
    ${input.userList[0].username}
    - -
  • - Reference to output of test cases is done using combination test case path and OGNL. Reference to test cases output -is prefixed with
    ${output.
    - -
  • - To refer an output of test case 1 in test suite 2, the syntax will be
    ${output(1.2)}
    . Individual attributes can -be accessed using OGNL syntax. Example:
    ${output(1.1).username}
    - -#### Reporting Test Results - -A Summary will be reported with each test run. For instance: +This will run the script in `src/main/scala/ScalaPetstoreCodegen.scala` and create the client. You can then +compile and run the client, as well as unit tests against it:
    -Sample: "Summary -->  Total Test Cases: 9 Failed Test Cases: 0"
    +cd samples/petstore/scala
    +
    +mvn package
     
    -In detail section each test case and its status (passed/failed) are reported. Failures include an exception trace. Test case path is -combination of test suite id and test case id separated by "." - +License +------- + +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 [apache.org/licenses/LICENSE-2.0](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. diff --git a/samples/petstore/scala/pom.xml b/samples/petstore/scala/pom.xml new file mode 100644 index 00000000000..eb5ef7fe761 --- /dev/null +++ b/samples/petstore/scala/pom.xml @@ -0,0 +1,225 @@ + + 4.0.0 + com.wordnik + swagger-client + jar + swagger-client + 1.0 + + scm:git:git@github.com:wordnik/swagger-mustache.git + scm:git:git@github.com:wordnik/swagger-mustache.git + https://github.com/wordnik/swagger-mustache + + + 2.2.0 + + + + + scala-tools.org + Scala-Tools Maven2 Repository + http://scala-tools.org/repo-releases + + + maven-mongodb-plugin-repo + maven mongodb plugin repository + http://maven-mongodb-plugin.googlecode.com/svn/maven/repo + default + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + org.scala-tools + maven-scala-plugin + 2.15.2 + + + scala-compile-first + process-resources + + add-source + compile + + + + scala-test-compile + process-test-resources + + testCompile + + + + + + -Xms128m + -Xmx1500m + + + + + + + + + org.scala-tools + maven-scala-plugin + + ${scala-version} + + + + + + + com.sun.jersey + jersey-client + ${jersey-version} + compile + + + org.scala-lang + scala-library + ${scala-version} + compile + + + com.wordnik + swagger-core_2.9.1 + ${swagger-core-version} + compile + + + org.scalatest + scalatest_2.9.1 + ${scala-test-version} + test + + + junit + junit + ${junit-version} + test + + + + + scala-tools.org + Scala-Tools Maven2 Repository + http://scala-tools.org/repo-releases + + + wordnik-ci-aws + https://ci.aws.wordnik.com/artifactory/libs-snapshots/ + + + wordnik-ci-aws-maven + https://ci.aws.wordnik.com/artifactory/m2-snapshots/ + + + wordnik-ci-aws-remote + https://ci.aws.wordnik.com/artifactory/remote-repos/ + + + + + 1.7 + 1.02-SNAPSHOT + 2.9.1-1 + 4.8.1 + 1.0.0 + 1.6.1 + 4.8.1 + 1.6.1 + + + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/client/ApiInvoker.scala b/samples/petstore/scala/src/main/scala/com/wordnik/client/ApiInvoker.scala new file mode 100644 index 00000000000..9f5618c99da --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/client/ApiInvoker.scala @@ -0,0 +1,117 @@ +package com.wordnik.client + +import com.wordnik.swagger.core.util.JsonUtil +import com.sun.jersey.api.client.Client +import com.sun.jersey.api.client.ClientResponse +import com.sun.jersey.api.client.config.ClientConfig +import com.sun.jersey.api.client.config.DefaultClientConfig +import com.sun.jersey.api.client.filter.LoggingFilter + +import java.net.URLEncoder +import javax.ws.rs.core.MediaType + +import scala.collection.JavaConverters._ +import scala.collection.mutable.HashMap + +object ApiInvoker { + val defaultHeaders: HashMap[String, String] = HashMap() + val hostMap: HashMap[String, Client] = HashMap() + + def escapeString(value: String): String = { + URLEncoder.encode(value, "utf-8").replaceAll("\\+", "%20") + } + + def deserialize(json: String, containerType: String, cls: Class[_]) = { + if (cls == classOf[String]) { + json match { + case s: String => { + if (s.startsWith("\"") && s.endsWith("\"") && s.length > 1) s.substring(1, s.length - 2) + else s + } + case _ => null + } + } else { + containerType match { + case "List" => { + val typeInfo = JsonUtil.getJsonMapper.getTypeFactory().constructCollectionType(classOf[java.util.List[_]], cls) + val response = JsonUtil.getJsonMapper.readValue(json, typeInfo).asInstanceOf[java.util.List[_]] + response.asScala.toList + } + case _ => { + json match { + case e: String if ("\"\"" == e) => null + case _ => JsonUtil.getJsonMapper.readValue(json, cls) + } + } + } + } + } + + def serialize(obj: AnyRef): String = { + if (obj != null) { + obj match { + case e: List[_] => JsonUtil.getJsonMapper.writeValueAsString(obj.asInstanceOf[List[_]].asJava) + case _ => JsonUtil.getJsonMapper.writeValueAsString(obj) + } + } else null + } + + def invokeApi(host: String, path: String, method: String, queryParams: Map[String, String], body: AnyRef, headerParams: Map[String, String]) = { + val client = getClient(host) + + val querystring = queryParams.filter(k => k._2 != null).map(k => (escapeString(k._1) + "=" + escapeString(k._2))).mkString("?", "&", "") + val builder = client.resource(host + path + querystring).`type`("application/json") + + headerParams.map(p => builder.header(p._1, p._2)) + defaultHeaders.map(p => { + headerParams.contains(p._1) match { + case true => // override default with supplied header + case false => if (p._2 != null) builder.header(p._1, p._2) + } + }) + + val response: ClientResponse = method match { + case "GET" => { + builder.get(classOf[ClientResponse]).asInstanceOf[ClientResponse] + } + case "POST" => { + builder.post(classOf[ClientResponse], serialize(body)) + } + case "PUT" => { + builder.put(classOf[ClientResponse], serialize(body)) + } + case "DELETE" => { + builder.delete(classOf[ClientResponse]) + } + case _ => null + } + response.getClientResponseStatus() match { + case ClientResponse.Status.OK => response.getEntity(classOf[String]) + case _ => { + throw new ApiException( + response.getClientResponseStatus().getStatusCode(), + response.getEntity(classOf[String])) + } + } + } + + def getClient(host: String): Client = { + hostMap.contains(host) match { + case true => hostMap(host) + case false => { + val client = Client.create() + // client.addFilter(new LoggingFilter()) + hostMap += host -> client + client + } + } + } +} + +class ApiException extends Exception { + var code = 0 + + def this(code: Int, msg: String) = { + this() + } +} diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/PetApi.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/PetApi.scala new file mode 100644 index 00000000000..d15e668a371 --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/PetApi.scala @@ -0,0 +1,127 @@ +package com.wordnik.petstore.api + +import com.wordnik.petstore.model.Pet +import com.wordnik.client.ApiInvoker +import com.wordnik.client.ApiException +import scala.collection.mutable.HashMap + +class PetApi { + var basePath: String = "http://petstore.swagger.wordnik.com/api" + var apiInvoker = ApiInvoker + + def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + + def getPetById (petId: String) : Option[Pet]= { + // create path and map variables + val path = "/pet.{format}/{petId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "petId" + "\\}",apiInvoker.escapeString(petId)) + + // query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(petId) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + Some(ApiInvoker.deserialize(s, "", classOf[Pet]).asInstanceOf[Pet]) + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def addPet (body: Pet) = { + // create path and map variables + val path = "/pet.{format}".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(body) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, body, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def updatePet (body: Pet) = { + // create path and map variables + val path = "/pet.{format}".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(body) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "PUT", queryParams.toMap, body, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def findPetsByStatus (status: String= "available") : Option[List[Pet]]= { + // create path and map variables + val path = "/pet.{format}/findByStatus".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(status) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + if(String.valueOf(status) != "null") queryParams += "status" -> status.toString + try { + apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + Some(ApiInvoker.deserialize(s, "List", classOf[Pet]).asInstanceOf[List[Pet]]) + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def findPetsByTags (tags: String) : Option[List[Pet]]= { + // create path and map variables + val path = "/pet.{format}/findByTags".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(tags) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + if(String.valueOf(tags) != "null") queryParams += "tags" -> tags.toString + try { + apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + Some(ApiInvoker.deserialize(s, "List", classOf[Pet]).asInstanceOf[List[Pet]]) + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + } + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/StoreApi.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/StoreApi.scala new file mode 100644 index 00000000000..6b87934d3bb --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/StoreApi.scala @@ -0,0 +1,83 @@ +package com.wordnik.petstore.api + +import com.wordnik.petstore.model.Order +import com.wordnik.client.ApiInvoker +import com.wordnik.client.ApiException +import scala.collection.mutable.HashMap + +class StoreApi { + var basePath: String = "http://petstore.swagger.wordnik.com/api" + var apiInvoker = ApiInvoker + + def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + + def getOrderById (orderId: String) : Option[Order]= { + // create path and map variables + val path = "/store.{format}/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}",apiInvoker.escapeString(orderId)) + + // query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(orderId) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + Some(ApiInvoker.deserialize(s, "", classOf[Order]).asInstanceOf[Order]) + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def deleteOrder (orderId: String) = { + // create path and map variables + val path = "/store.{format}/order/{orderId}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "orderId" + "\\}",apiInvoker.escapeString(orderId)) + + // query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(orderId) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "DELETE", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def placeOrder (body: Order) = { + // create path and map variables + val path = "/store.{format}/order".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(body) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, body, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + } + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/UserApi.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/UserApi.scala new file mode 100644 index 00000000000..64026778795 --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/api/UserApi.scala @@ -0,0 +1,188 @@ +package com.wordnik.petstore.api + +import com.wordnik.petstore.model.User +import com.wordnik.client.ApiInvoker +import com.wordnik.client.ApiException +import scala.collection.mutable.HashMap + +class UserApi { + var basePath: String = "http://petstore.swagger.wordnik.com/api" + var apiInvoker = ApiInvoker + + def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + + def createUsersWithArrayInput (body: Array[User]) = { + // create path and map variables + val path = "/user.{format}/createWithArray".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(body) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, body, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def createUser (body: User) = { + // create path and map variables + val path = "/user.{format}".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(body) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, body, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def createUsersWithListInput (body: List[User]) = { + // create path and map variables + val path = "/user.{format}/createWithList".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(body) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, body, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def updateUser (username: String, body: User) = { + // create path and map variables + val path = "/user.{format}/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}",apiInvoker.escapeString(username)) + + // query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(username, body) - null).size match { + case 2 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "PUT", queryParams.toMap, body, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def deleteUser (username: String) = { + // create path and map variables + val path = "/user.{format}/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}",apiInvoker.escapeString(username)) + + // query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(username) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "DELETE", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def getUserByName (username: String) : Option[User]= { + // create path and map variables + val path = "/user.{format}/{username}".replaceAll("\\{format\\}","json").replaceAll("\\{" + "username" + "\\}",apiInvoker.escapeString(username)) + + // query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(username) - null).size match { + case 1 => // all required values set + case _ => throw new Exception("missing required params") + } + try { + apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + Some(ApiInvoker.deserialize(s, "", classOf[User]).asInstanceOf[User]) + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def loginUser (username: String, password: String) : Option[String]= { + // create path and map variables + val path = "/user.{format}/login".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + // verify required params are set + (Set(username, password) - null).size match { + case 2 => // all required values set + case _ => throw new Exception("missing required params") + } + if(String.valueOf(username) != "null") queryParams += "username" -> username.toString + if(String.valueOf(password) != "null") queryParams += "password" -> password.toString + try { + apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + Some(ApiInvoker.deserialize(s, "", classOf[String]).asInstanceOf[String]) + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + def logoutUser () = { + // create path and map variables + val path = "/user.{format}/logout".replaceAll("\\{format\\}","json")// query params + val queryParams = new HashMap[String, String] + val headerParams = new HashMap[String, String] + + try { + apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, None, headerParams.toMap) match { + case s: String => + case _ => None + } + } catch { + case ex: ApiException if ex.code == 404 => None + case ex: ApiException => throw ex + } + } + } + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Category.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Category.scala new file mode 100644 index 00000000000..09cc3a5e0e2 --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Category.scala @@ -0,0 +1,17 @@ +package com.wordnik.petstore.model + +import scala.reflect.BeanProperty + +class Category { + @BeanProperty var id: Long = _ + @BeanProperty var name: String = _ + override def toString: String = { + val sb = new StringBuilder + sb.append("class Category {\n") + sb.append(" id: ").append(id).append("\n") + sb.append(" name: ").append(name).append("\n") + sb.append("}\n") + sb.toString + } +} + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Order.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Order.scala new file mode 100644 index 00000000000..fd46b87de55 --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Order.scala @@ -0,0 +1,25 @@ +package com.wordnik.petstore.model + +import java.util.Date +import scala.reflect.BeanProperty + +class Order { + @BeanProperty var id: Long = _ + @BeanProperty var petId: Long = _ + /* Order Status */ + @BeanProperty var status: String = _ + @BeanProperty var quantity: Int = _ + @BeanProperty var shipDate: Date = _ + override def toString: String = { + val sb = new StringBuilder + sb.append("class Order {\n") + sb.append(" id: ").append(id).append("\n") + sb.append(" petId: ").append(petId).append("\n") + sb.append(" status: ").append(status).append("\n") + sb.append(" quantity: ").append(quantity).append("\n") + sb.append(" shipDate: ").append(shipDate).append("\n") + sb.append("}\n") + sb.toString + } +} + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Pet.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Pet.scala new file mode 100644 index 00000000000..c534351d2c7 --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Pet.scala @@ -0,0 +1,28 @@ +package com.wordnik.petstore.model + +import com.wordnik.petstore.model.Category +import com.wordnik.petstore.model.Tag +import scala.reflect.BeanProperty + +class Pet { + @BeanProperty var id: Long = _ + @BeanProperty var tags: java.util.List[Tag] = _ + @BeanProperty var category: Category = _ + /* pet status in the store */ + @BeanProperty var status: String = _ + @BeanProperty var name: String = _ + @BeanProperty var photoUrls: java.util.List[String] = _ + override def toString: String = { + val sb = new StringBuilder + sb.append("class Pet {\n") + sb.append(" id: ").append(id).append("\n") + sb.append(" tags: ").append(tags).append("\n") + sb.append(" category: ").append(category).append("\n") + sb.append(" status: ").append(status).append("\n") + sb.append(" name: ").append(name).append("\n") + sb.append(" photoUrls: ").append(photoUrls).append("\n") + sb.append("}\n") + sb.toString + } +} + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Tag.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Tag.scala new file mode 100644 index 00000000000..03d90ce50cf --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/Tag.scala @@ -0,0 +1,17 @@ +package com.wordnik.petstore.model + +import scala.reflect.BeanProperty + +class Tag { + @BeanProperty var id: Long = _ + @BeanProperty var name: String = _ + override def toString: String = { + val sb = new StringBuilder + sb.append("class Tag {\n") + sb.append(" id: ").append(id).append("\n") + sb.append(" name: ").append(name).append("\n") + sb.append("}\n") + sb.toString + } +} + diff --git a/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/User.scala b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/User.scala new file mode 100644 index 00000000000..d492710173c --- /dev/null +++ b/samples/petstore/scala/src/main/scala/com/wordnik/petstore/model/User.scala @@ -0,0 +1,30 @@ +package com.wordnik.petstore.model + +import scala.reflect.BeanProperty + +class User { + @BeanProperty var id: Long = _ + @BeanProperty var lastName: String = _ + @BeanProperty var username: String = _ + @BeanProperty var phone: String = _ + @BeanProperty var email: String = _ + /* User Status */ + @BeanProperty var userStatus: Int = _ + @BeanProperty var firstName: String = _ + @BeanProperty var password: String = _ + override def toString: String = { + val sb = new StringBuilder + sb.append("class User {\n") + sb.append(" id: ").append(id).append("\n") + sb.append(" lastName: ").append(lastName).append("\n") + sb.append(" username: ").append(username).append("\n") + sb.append(" phone: ").append(phone).append("\n") + sb.append(" email: ").append(email).append("\n") + sb.append(" userStatus: ").append(userStatus).append("\n") + sb.append(" firstName: ").append(firstName).append("\n") + sb.append(" password: ").append(password).append("\n") + sb.append("}\n") + sb.toString + } +} + diff --git a/samples/petstore/scala/src/test/scala/PetApiTest.scala b/samples/petstore/scala/src/test/scala/PetApiTest.scala new file mode 100644 index 00000000000..7fd2ca37fdb --- /dev/null +++ b/samples/petstore/scala/src/test/scala/PetApiTest.scala @@ -0,0 +1,110 @@ +import com.wordnik.petstore.api._ +import com.wordnik.petstore.model._ + +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner +import org.scalatest.FlatSpec +import org.scalatest.matchers.ShouldMatchers + +import scala.collection.mutable.{ ListBuffer, HashMap } +import scala.collection.JavaConversions._ +import scala.reflect.BeanProperty + +@RunWith(classOf[JUnitRunner]) +class PetApiTest extends FlatSpec with ShouldMatchers { + behavior of "PetApi" + val api = new PetApi + + it should "fetch a pet" in { + api.getPetById("1") match { + case Some(pet) => { + pet should not be (null) + pet.id should be(1) + } + case None => fail("didn't find pet 1") + } + } + + it should "add a new pet" in { + val pet = new Pet + pet.id = 1000 + + pet.tags = (for (i <- (1 to 5)) yield { + val tag = new Tag + tag.id = i; tag.name = "tag-" + i; tag + }).toList + pet.status = "lost" + pet.category = { + val category = new Category; category.id = 1; category.name = "sold" + category + } + pet.name = "dragon" + pet.photoUrls = (for (i <- (1 to 10)) yield { + "http://foo.com/photo/" + i + }).toList + + api.addPet(pet) + api.getPetById("1000") match { + case Some(pet) => { + pet.id should be(1000) + pet.tags.size should be(5) + pet.status should be("lost") + pet.category should not be (null) + pet.category.name should be("sold") + pet.name should be("dragon") + pet.photoUrls.size should be(10) + } + case None => fail("didn't find pet created") + } + } + + it should "update a pet" in { + val pet = new Pet + pet.id = 1000 + + pet.name = "programmer" + pet.status = "confused" + api.addPet(pet) + + api.getPetById("1000") match { + case Some(pet) => { + pet.name should be("programmer") + pet.status should be("confused") + } + case None => fail("didn't find pet created") + } + pet.status = "fulfilled" + api.updatePet(pet) + api.getPetById("1000") match { + case Some(pet) => { + pet.name should be("programmer") + pet.status should be("fulfilled") + } + case None => fail("didn't find pet updated") + } + } + + it should "find pets by status" in { + api.findPetsByStatus("available") match { + case Some(pets) => { + pets.foreach(pet => pet.status should be("available")) + } + case None => fail("didn't find pets by status") + } + } + + it should "find pets by tag" in { + println("finding by tags") + api.findPetsByTags("tag1,tag2") match { + case Some(pets) => { +/* pets.foreach(pet => { + val tags = (for (tag <- pet.tags) yield tag.name).toSet + println("checking tags " + tags) + if ((tags & Set("tag1", "tag2")).size == 0) fail("unexpected tags in " + tags) + }) +*/ + } + case None => //fail("didn't find pets by tag") + } + } +} \ No newline at end of file diff --git a/samples/petstore/scala/src/test/scala/StoreApiTest.scala b/samples/petstore/scala/src/test/scala/StoreApiTest.scala new file mode 100644 index 00000000000..bd155af6360 --- /dev/null +++ b/samples/petstore/scala/src/test/scala/StoreApiTest.scala @@ -0,0 +1,79 @@ +import com.wordnik.client._ +import com.wordnik.petstore.api._ +import com.wordnik.petstore.model._ + +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner +import org.scalatest.FlatSpec +import org.scalatest.matchers.ShouldMatchers + +import scala.collection.mutable.{ ListBuffer, HashMap } +import scala.collection.JavaConversions._ +import scala.reflect.BeanProperty + +@RunWith(classOf[JUnitRunner]) +class StoreApiTest extends FlatSpec with ShouldMatchers { + behavior of "StoreApi" + val api = new StoreApi + + api.apiInvoker.defaultHeaders += "api_key" -> "special-key" + + it should "fetch an order" in { + api.getOrderById("1") match { + case Some(order) => { + order.id should be(1) + order.petId should be(1) + order.quantity should be(2) + order.shipDate should not be (null) + } + case None => fail("didn't find order") + } + } + + it should "place an order" in { + val now = new java.util.Date + val order = new Order + order.id = 1000 + order.petId = 10 + order.quantity = 101 + order.shipDate = now + + api.placeOrder(order) + + api.getOrderById("1000") match { + case Some(order) => { + order.id should be(1000) + order.petId should be(10) + order.quantity should be(101) + order.shipDate should be (now) + } + case None => + } + } + + it should "delete an order" in { + val now = new java.util.Date + val order = new Order + order.id = 1001 + order.petId = 10 + order.quantity = 101 + order.shipDate = now + + api.placeOrder(order) + + api.getOrderById("1001") match { + case Some(order) => { + order.id should be(1001) + order.petId should be(10) + order.quantity should be(101) + order.shipDate should be (now) + } + case None => + } + + api.deleteOrder("1001") + intercept[ApiException] { + api.getOrderById("1001") should be (None) + } + } +} \ No newline at end of file diff --git a/samples/petstore/scala/src/test/scala/UserApiTest.scala b/samples/petstore/scala/src/test/scala/UserApiTest.scala new file mode 100644 index 00000000000..1e74784bc70 --- /dev/null +++ b/samples/petstore/scala/src/test/scala/UserApiTest.scala @@ -0,0 +1,153 @@ +import com.wordnik.petstore.api._ +import com.wordnik.petstore.model._ + +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner +import org.scalatest.FlatSpec +import org.scalatest.matchers.ShouldMatchers + +import scala.collection.mutable.{ ListBuffer, HashMap } +import scala.collection.JavaConversions._ +import scala.reflect.BeanProperty + +@RunWith(classOf[JUnitRunner]) +class UserApiTest extends FlatSpec with ShouldMatchers { + behavior of "UserApi" + val api = new UserApi + api.apiInvoker.defaultHeaders += "api_key" -> "special-key" + + it should "fetch a user" in { + api.getUserByName("user1") match { + case Some(user) => { + user.id should be(1) + user.username should be("user1") + user.password should be("XXXXXXXXXXX") + user.email should be("email1@test.com") + user.firstName should be("first name 1") + user.lastName should be("last name 1") + user.phone should be("123-456-7890") + user.userStatus should be(1) + } + case None => + } + } + + it should "authenticate a user" in { + api.loginUser("user1", "XXXXXXXXXXX") match { + case Some(status) => status.startsWith("logged in user session") match { + case true => // success! + case _ => fail("didn't get expected message " + status) + } + case None => fail("not able to login") + } + } + + it should "log out a user" in { + api.logoutUser + } + + it should "create a user" in { + val user = new User + user.id = 1002 + user.username = "johnny" + user.password = "XXXXXXXXXXX" + user.email = "johnny@fail.com" + user.firstName = "Johnny" + user.lastName = "Rocket" + user.phone = "408-867-5309" + user.userStatus = 1 + + api.createUser(user) + + api.getUserByName("johnny") match { + case Some(user) => { + user.id should be (1002) + user.username should be ("johnny") + } + case None => + } + } + + it should "create 2 users" in { + val userArray = (for (i <- (1 to 2)) yield { + val user = new User + user.id = 2000 + i + user.username = "johnny-" + i + user.password = "XXXXXXXXXXX" + user.email = "johnny-" + i + "@fail.com" + user.firstName = "Johnny" + user.lastName = "Rocket-" + i + user.phone = "408-867-5309" + user.userStatus = 1 + user + }).toArray + api.createUsersWithArrayInput(userArray) + + for (i <- (1 to 2)) { + api.getUserByName("johnny-" + i) match { + case Some(user) => { + user.id should be (2000 + i) + user.email should be ("johnny-" + i + "@fail.com") + } + case None => fail("didn't find user " + i) + } + } + } + + it should "create 3 users" in { + val userList = (for (i <- (1 to 3)) yield { + val user = new User + user.id = 3000 + i + user.username = "fred-" + i + user.password = "XXXXXXXXXXX" + user.email = "fred-" + i + "@fail.com" + user.firstName = "Johnny" + user.lastName = "Rocket-" + i + user.phone = "408-867-5309" + user.userStatus = 1 + user + }).toList + api.createUsersWithListInput(userList) + + for (i <- (1 to 3)) { + api.getUserByName("fred-" + i) match { + case Some(user) => { + user.id should be (3000 + i) + user.email should be ("fred-" + i + "@fail.com") + } + case None => fail("didn't find user " + i) + } + } + } + + it should "update a user" in { + val user = new User + user.id = 4000 + user.username = "tony" + user.password = "XXXXXXXXXXX" + user.email = "tony@fail.com" + user.firstName = "Tony" + user.lastName = "Tiger" + user.phone = "408-867-5309" + user.userStatus = 1 + + api.createUser(user) + + api.getUserByName("tony") match { + case Some(user) => { + user.id should be (4000) + user.username should be ("tony") + } + case None => + } + user.email = "tony@succeed.com" + + api.updateUser("tony", user) + api.getUserByName("tony") match { + case Some(user) => { + user.email should be ("tony@succeed.com") + } + case None => + } + } +} \ No newline at end of file