diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java
index 6fd620fc7f74..a7866e5675a5 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java
@@ -6,20 +6,35 @@ import java.util.*;
public class CodegenModel {
public String parent, parentSchema;
+ public List interfaces;
+
+ // References to parent and interface CodegenModels. Only set when code generator supports inheritance.
+ public CodegenModel parentModel;
+ public List interfaceModels;
+
public String name, classname, description, classVarName, modelJson, dataType;
public String classFilename; // store the class file name, mainly used for import
public String unescapedDescription;
public String discriminator;
public String defaultValue;
public List vars = new ArrayList();
+ public List allVars;
public List allowableValues;
- // list of all required parameters
- public Set mandatory = new HashSet();
-
+ // Sorted sets of required parameters.
+ public Set mandatory = new TreeSet();
+ public Set allMandatory;
+
public Set imports = new TreeSet();
public Boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum;
public ExternalDocs externalDocs;
public Map vendorExtensions;
+
+ {
+ // By default these are the same collections. Where the code generator supports inheritance, composed models
+ // store the complete closure of owned and inherited properties in allVars and allMandatory.
+ allVars = vars;
+ allMandatory = mandatory;
+ }
}
diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java
index 86bb99598ec9..300bf4192fc7 100644
--- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java
+++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java
@@ -45,9 +45,12 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
+import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -124,8 +127,36 @@ public class DefaultCodegen {
}
// override with any special post-processing for all models
- @SuppressWarnings("static-method")
+ @SuppressWarnings({ "static-method", "unchecked" })
public Map postProcessAllModels(Map objs) {
+ if (supportsInheritance) {
+ // Index all CodegenModels by name.
+ Map allModels = new HashMap();
+ for (Entry entry : objs.entrySet()) {
+ String modelName = entry.getKey();
+ Map inner = (Map) entry.getValue();
+ List
+ *
+ * A non-AMD browser application (discouraged) might do something like this:
+ *
+ * var xxxSvc = new {{moduleName}}.XxxApi(); // Allocate the API class we're going to use.
+ * var yyy = new {{moduleName}}.Yyy(); // Construct a model instance.
+ * yyyModel.someProperty = 'someValue';
+ * ...
+ * var zzz = xxxSvc.doSomething(yyyModel); // Invoke the service.
+ * ...
+ *
+ *
+ * @module index
+ * @version {{projectVersion}}
+ */{{/emitJSDoc}}
+{{=< >=}} var exports = {<#emitJSDoc>
+ /**
+ * The ApiClient constructor.
+ * @property {module:ApiClient}
+ */
+ ApiClient: ApiClient<#models>,<#emitJSDoc>
+ /**
+ * The model constructor.
+ * @property {module:<#modelPackage>/}
+ */
+ : <#apiInfo><#apis>,<#emitJSDoc>
+ /**
+ * The service constructor.
+ * @property {module:<#apiPackage>/}
+ */
+ :
};
+
+ return exports;<={{ }}=>
}));
diff --git a/modules/swagger-codegen/src/main/resources/Javascript/model.mustache b/modules/swagger-codegen/src/main/resources/Javascript/model.mustache
index 818583686686..c8849223fc4b 100644
--- a/modules/swagger-codegen/src/main/resources/Javascript/model.mustache
+++ b/modules/swagger-codegen/src/main/resources/Javascript/model.mustache
@@ -14,69 +14,87 @@
}
}(this, function(ApiClient{{#imports}}, {{import}}{{/imports}}) {
'use strict';
- {{#models}}{{#model}}
- {{#description}}/**
- * {{description}}
- **/{{/description}}
- var {{classname}} = function {{classname}}({{#vars}}{{#required}}{{name}}{{#vendorExtensions.x-codegen-hasMoreRequired}}, {{/vendorExtensions.x-codegen-hasMoreRequired}}{{/required}}{{/vars}}) { {{#parent}}/* extends {{{parent}}}*/{{/parent}}
- {{#vars}}{{#required}}
- /**{{#description}}
- * {{{description}}}{{/description}}
- * datatype: {{{datatypeWithEnum}}}
- * required {{#minimum}}
- * minimum: {{minimum}}{{/minimum}}{{#maximum}}
- * maximum: {{maximum}}{{/maximum}}
- **/
- this['{{baseName}}'] = {{name}};{{/required}}{{^required}}{{#defaultValue}}
- /**{{#description}}
- * {{{description}}}{{/description}}
- * datatype: {{{datatypeWithEnum}}}
- * required {{#minimum}}
- * minimum: {{minimum}}{{/minimum}}{{#maximum}}
- * maximum: {{maximum}}{{/maximum}}
- **/
- this['{{baseName}}'] = {{{defaultValue}}};{{/defaultValue}}{{/required}}{{/vars}}
- };
- {{classname}}.constructFromObject = function(data) {
- if (!data) {
- return null;
- }
- var _this = new {{classname}}();
- {{#vars}}
- if (data['{{baseName}}']) {
- _this['{{baseName}}']{{{defaultValueWithParam}}}
- }
- {{/vars}}
- return _this;
+{{#models}}{{#model}}{{#emitJSDoc}} /**
+ * The {{classname}} model module.
+ * @module {{#modelPackage}}{{modelPackage}}/{{/modelPackage}}{{classname}}
+ * @version {{projectVersion}}
+ */
+
+ /**
+ * Constructs a new {{classname}}.{{#description}}
+ * {{description}}{{/description}}
+ * @alias module:{{#modelPackage}}{{modelPackage}}/{{/modelPackage}}{{classname}}
+ * @class{{#useInheritance}}{{#parent}}
+ * @extends module:{{#modelPackage}}{{modelPackage}}/{{/modelPackage}}{{parent}}{{/parent}}{{#interfaces}}
+ * @implements module:{{#modelPackage}}{{modelPackage}}/{{/modelPackage}}{{.}}{{/interfaces}}{{/useInheritance}}{{#vendorExtensions.x-all-required}}
+ * @param {{.}}{{/vendorExtensions.x-all-required}}
+ */{{/emitJSDoc}}
+ var exports = function({{#vendorExtensions.x-all-required}}{{.}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-all-required}}) {
+{{#useInheritance}}{{#parentModel}} {{classname}}.call(this{{#vendorExtensions.x-all-required}}, {{.}}{{/vendorExtensions.x-all-required}});{{/parentModel}}
+{{#interfaceModels}} {{classname}}.call(this{{#vendorExtensions.x-all-required}}, {{.}}{{/vendorExtensions.x-all-required}});
+{{/interfaceModels}}{{/useInheritance}}{{#vars}}{{#required}} this['{{baseName}}'] = {{name}};{{/required}}
+{{/vars}} };
+
+{{#emitJSDoc}} /**
+ * Constructs a {{classname}} from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {{=< >=}}{module:<#modelPackage>/}<={{ }}=> obj Optional instance to populate.
+ * @return {{=< >=}}{module:<#modelPackage>/}<={{ }}=> The populated {{classname}} instance.
+ */
+{{/emitJSDoc}} exports.constructFromObject = function(data, obj) {
+ if (data) { {{!// TODO: support polymorphism: discriminator property on data determines class to instantiate.}}
+ obj = obj || new exports();
+{{#useInheritance}}{{#parent}} {{.}}.constructFromObject(data, obj);{{/parent}}
+{{#interfaces}} {{.}}.constructFromObject(data, obj);
+{{/interfaces}}{{/useInheritance}}{{#vars}} if (data.hasOwnProperty('{{baseName}}')) {
+ obj['{{baseName}}']{{{defaultValueWithParam}}}
+ }
+{{/vars}} }
+ return obj;
}
-
- {{^omitModelMethods}}
- {{#vars}}
+{{#useInheritance}}{{#parent}}
+ exports.prototype = Object.create({{parent}}.prototype);
+ exports.prototype.constructor = exports;
+{{/parent}}{{/useInheritance}}
+{{#vars}}{{#emitJSDoc}}
/**{{#description}}
- * get {{{description}}}{{/description}}{{#minimum}}
+ * {{{description}}}{{/description}}
+ * @member {{{vendorExtensions.x-jsdoc-type}}} {{baseName}}{{#defaultValue}}
+ * @default {{{defaultValue}}}{{/defaultValue}}
+ */
+{{/emitJSDoc}} exports.prototype['{{baseName}}'] = {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}undefined{{/defaultValue}};
+{{/vars}}{{#useInheritance}}{{#interfaceModels}}
+ // Implement {{classname}} interface:{{#allVars}}{{#emitJSDoc}}
+ /**{{#description}}
+ * {{{description}}}{{/description}}
+ * @member {{{vendorExtensions.x-jsdoc-type}}} {{baseName}}{{#defaultValue}}
+ * @default {{{defaultValue}}}{{/defaultValue}}
+ */
+{{/emitJSDoc}} exports.prototype['{{baseName}}'] = {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}undefined{{/defaultValue}};
+{{/allVars}}{{/interfaceModels}}{{/useInheritance}}
+{{#emitModelMethods}}{{#vars}}{{#emitJSDoc}} /**{{#description}}
+ * Returns {{{description}}}{{/description}}{{#minimum}}
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}}
- * @return {{=<% %>=}}{<% datatypeWithEnum %>}<%={{ }}=%>
- **/
- {{classname}}.prototype.{{getter}} = function() {
+ * @return {{{vendorExtensions.x-jsdoc-type}}}
+ */
+{{/emitJSDoc}} exports.prototype.{{getter}} = function() {
return this['{{baseName}}'];
}
- /**{{#description}}
- * set {{{description}}}{{/description}}
- * @param {{=<% %>=}}{<% datatypeWithEnum %>}<%={{ }}=%> {{name}}
- **/
- {{classname}}.prototype.{{setter}} = function({{name}}) {
+{{#emitJSDoc}} /**{{#description}}
+ * Sets {{{description}}}{{/description}}
+ * @param {{{vendorExtensions.x-jsdoc-type}}} {{name}}{{#description}} {{{description}}}{{/description}}
+ */
+{{/emitJSDoc}} exports.prototype.{{setter}} = function({{name}}) {
this['{{baseName}}'] = {{name}};
}
- {{/vars}}
- {{/omitModelMethods}}
- {{#vars}}{{#isEnum}}{{>enumClass}}{{/isEnum}}{{#items.isEnum}}{{#items}}
- {{>enumClass}}{{/items}}*/{{/items.isEnum}}{{/vars}}
+{{/vars}}{{/emitModelMethods}}
+{{#vars}}{{#isEnum}}{{>enumClass}}{{/isEnum}}{{#items.isEnum}}{{#items}}
+{{>enumClass}}{{/items}}*/{{/items.isEnum}}{{/vars}}
- return {{classname}};
- {{/model}}
- {{/models}}
-}));
+ return exports;
+{{/model}}{{/models}}}));
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptClientOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptClientOptionsTest.java
new file mode 100644
index 000000000000..927d4d7755b8
--- /dev/null
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptClientOptionsTest.java
@@ -0,0 +1,71 @@
+package io.swagger.codegen.javascript;
+
+import io.swagger.codegen.AbstractOptionsTest;
+import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.options.JavaScriptOptionsProvider;
+import io.swagger.codegen.languages.JavascriptClientCodegen;
+import io.swagger.codegen.options.OptionsProvider;
+
+import mockit.Expectations;
+import mockit.Tested;
+
+public class JavaScriptClientOptionsTest extends AbstractOptionsTest {
+ @Tested
+ private JavascriptClientCodegen clientCodegen;
+
+ public JavaScriptClientOptionsTest() {
+ super(new JavaScriptOptionsProvider());
+ }
+
+ protected JavaScriptClientOptionsTest(OptionsProvider optionsProvider) {
+ super(optionsProvider);
+ }
+
+ @Override
+ protected CodegenConfig getCodegenConfig() {
+ return clientCodegen;
+ }
+
+ @Override
+ protected void setExpectations() {
+ // Commented generic options not yet supported by JavaScript codegen.
+ new Expectations(clientCodegen) {{
+ clientCodegen.setModelPackage(JavaScriptOptionsProvider.MODEL_PACKAGE_VALUE);
+ times = 1;
+ clientCodegen.setApiPackage(JavaScriptOptionsProvider.API_PACKAGE_VALUE);
+ times = 1;
+ clientCodegen.setSortParamsByRequiredFlag(Boolean.valueOf(JavaScriptOptionsProvider.SORT_PARAMS_VALUE));
+ times = 1;
+// clientCodegen.setInvokerPackage(JavaScriptOptionsProvider.INVOKER_PACKAGE_VALUE);
+// times = 1;
+// clientCodegen.setGroupId(JavaScriptOptionsProvider.GROUP_ID_VALUE);
+// times = 1;
+// clientCodegen.setArtifactId(JavaScriptOptionsProvider.ARTIFACT_ID_VALUE);
+// times = 1;
+// clientCodegen.setArtifactVersion(JavaScriptOptionsProvider.ARTIFACT_VERSION_VALUE);
+// times = 1;
+ clientCodegen.setSourceFolder(JavaScriptOptionsProvider.SOURCE_FOLDER_VALUE);
+ times = 1;
+ clientCodegen.setLocalVariablePrefix(JavaScriptOptionsProvider.LOCAL_PREFIX_VALUE);
+ times = 1;
+ clientCodegen.setProjectName(JavaScriptOptionsProvider.PROJECT_NAME_VALUE);
+ times = 1;
+ clientCodegen.setModuleName(JavaScriptOptionsProvider.MODULE_NAME_VALUE);
+ times = 1;
+ clientCodegen.setProjectDescription(JavaScriptOptionsProvider.PROJECT_DESCRIPTION_VALUE);
+ times = 1;
+ clientCodegen.setProjectVersion(JavaScriptOptionsProvider.PROJECT_VERSION_VALUE);
+ times = 1;
+ clientCodegen.setProjectLicenseName(JavaScriptOptionsProvider.PROJECT_LICENSE_NAME_VALUE);
+ times = 1;
+ clientCodegen.setUsePromises(Boolean.valueOf(JavaScriptOptionsProvider.USE_PROMISES_VALUE));
+ times = 1;
+ clientCodegen.setUseInheritance(Boolean.valueOf(JavaScriptOptionsProvider.USE_INHERITANCE_VALUE));
+ times = 1;
+ clientCodegen.setEmitModelMethods(Boolean.valueOf(JavaScriptOptionsProvider.EMIT_MODEL_METHODS_VALUE));
+ times = 1;
+ clientCodegen.setEmitJSDoc(Boolean.valueOf(JavaScriptOptionsProvider.EMIT_JS_DOC_VALUE));
+ times = 1;
+ }};
+ }
+}
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptInheritanceTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptInheritanceTest.java
new file mode 100644
index 000000000000..94285e468881
--- /dev/null
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptInheritanceTest.java
@@ -0,0 +1,102 @@
+package io.swagger.codegen.javascript;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Sets;
+
+import io.swagger.codegen.CodegenModel;
+import io.swagger.codegen.languages.JavascriptClientCodegen;
+import io.swagger.models.ComposedModel;
+import io.swagger.models.Model;
+import io.swagger.models.ModelImpl;
+import io.swagger.models.RefModel;
+import io.swagger.models.properties.StringProperty;
+
+public class JavaScriptInheritanceTest {
+ @SuppressWarnings("static-method")
+ @Test(description = "convert a composed model with inheritance enabled")
+ public void javascriptInheritanceTest() {
+ ModelImpl base = new ModelImpl();
+ base.addProperty("baseProp", new StringProperty().required(true));
+ ModelImpl intf1 = new ModelImpl();
+ intf1.addProperty("intf1Prop", new StringProperty());
+ ModelImpl intf2 = new ModelImpl();
+ intf2.addProperty("intf2Prop", new StringProperty().required(true));
+ ModelImpl child = new ModelImpl();
+ child.addProperty("childProp", new StringProperty().required(true));
+
+ final Map allDefinitions = new HashMap();
+ allDefinitions.put("Base", base);
+ allDefinitions.put("Interface1", intf1);
+ allDefinitions.put("Interface2", intf2);
+
+ final Model model = new ComposedModel().parent(new RefModel("Base"))
+ .interfaces(Arrays.asList(new RefModel("Interface1"), new RefModel("Interface2")))
+ .child(child);
+
+ final JavascriptClientCodegen codegen = new JavascriptClientCodegen();
+ codegen.setUseInheritance(true);
+
+ final CodegenModel cm = codegen.fromModel("sample", model, allDefinitions);
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.parent, "Base");
+ Assert.assertEquals(cm.interfaces, Arrays.asList("Interface1", "Interface2"));
+ Assert.assertEquals(cm.imports, Sets.newHashSet("Base", "Interface1", "Interface2"));
+ Assert.assertEquals(cm.vars.size(), 1);
+ Assert.assertEquals(cm.vars.get(0).name, "childProp");
+ Assert.assertEquals(cm.allVars.size(), 4);
+ String[] allVars = {"baseProp", "intf1Prop", "intf2Prop", "childProp"};
+ for (int i = 0; i < allVars.length; i++) {
+ Assert.assertEquals(cm.allVars.get(i).name, allVars[i]);
+ }
+ Assert.assertEquals(cm.mandatory, Sets.newHashSet("childProp"));
+ Assert.assertEquals(cm.allMandatory, Sets.newHashSet("baseProp", "intf2Prop", "childProp"));
+ }
+
+ @SuppressWarnings("static-method")
+ @Test(description = "convert a composed model with inheritance disabled")
+ public void javascriptNoInheritanceTest() {
+ ModelImpl base = new ModelImpl();
+ base.addProperty("baseProp", new StringProperty().required(true));
+ ModelImpl intf1 = new ModelImpl();
+ intf1.addProperty("intf1Prop", new StringProperty());
+ ModelImpl intf2 = new ModelImpl();
+ intf2.addProperty("intf2Prop", new StringProperty().required(true));
+ ModelImpl child = new ModelImpl();
+ child.addProperty("childProp", new StringProperty().required(true));
+
+ final Map allDefinitions = new HashMap();
+ allDefinitions.put("Base", base);
+ allDefinitions.put("Interface1", intf1);
+ allDefinitions.put("Interface2", intf2);
+
+ final Model model = new ComposedModel().parent(new RefModel("Base"))
+ .interfaces(Arrays.asList(new RefModel("Interface1"), new RefModel("Interface2")))
+ .child(child);
+
+ final JavascriptClientCodegen codegen = new JavascriptClientCodegen();
+ codegen.setUseInheritance(false);
+
+ final CodegenModel cm = codegen.fromModel("sample", model, allDefinitions);
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.parent, "Base");
+ Assert.assertEquals(cm.interfaces, Arrays.asList("Interface1", "Interface2"));
+ Assert.assertEquals(cm.imports, Sets.newHashSet("Base", "Interface1", "Interface2"));
+ Assert.assertEquals(cm.vars.size(), 4);
+ Assert.assertEquals(cm.allVars.size(), 4);
+ String[] allVars = {"baseProp", "intf1Prop", "intf2Prop", "childProp"};
+ for (int i = 0; i < allVars.length; i++) {
+ Assert.assertEquals(cm.vars.get(i).name, allVars[i]);
+ Assert.assertEquals(cm.allVars.get(i).name, allVars[i]);
+ }
+ Assert.assertEquals(cm.mandatory, Sets.newHashSet("baseProp", "intf2Prop", "childProp"));
+ Assert.assertEquals(cm.allMandatory, Sets.newHashSet("baseProp", "intf2Prop", "childProp"));
+ }
+}
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptModelEnumTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptModelEnumTest.java
new file mode 100644
index 000000000000..5e2306d73fbd
--- /dev/null
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptModelEnumTest.java
@@ -0,0 +1,95 @@
+package io.swagger.codegen.javascript;
+
+import io.swagger.codegen.CodegenModel;
+import io.swagger.codegen.CodegenProperty;
+import io.swagger.codegen.DefaultCodegen;
+import io.swagger.codegen.languages.JavaClientCodegen;
+import io.swagger.codegen.languages.JavascriptClientCodegen;
+import io.swagger.models.ComposedModel;
+import io.swagger.models.Model;
+import io.swagger.models.ModelImpl;
+import io.swagger.models.RefModel;
+import io.swagger.models.properties.Property;
+import io.swagger.models.properties.StringProperty;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+@SuppressWarnings("static-method")
+public class JavaScriptModelEnumTest {
+ @Test(description = "convert a JavaScript model with an enum")
+ public void converterTest() {
+ final StringProperty enumProperty = new StringProperty();
+ enumProperty.setEnum(Arrays.asList("VALUE1", "VALUE2", "VALUE3"));
+ final ModelImpl model = new ModelImpl().property("name", enumProperty);
+
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty enumVar = cm.vars.get(0);
+ Assert.assertEquals(enumVar.baseName, "name");
+ Assert.assertEquals(enumVar.datatype, "String");
+ Assert.assertEquals(enumVar.datatypeWithEnum, "NameEnum");
+ Assert.assertEquals(enumVar.name, "name");
+ Assert.assertEquals(enumVar.defaultValue, null);
+ Assert.assertEquals(enumVar.baseType, "String");
+ Assert.assertTrue(enumVar.isEnum);
+ }
+
+ @Test(description = "not override identical parent enums")
+ public void overrideEnumTest() {
+ final StringProperty identicalEnumProperty = new StringProperty();
+ identicalEnumProperty.setEnum(Arrays.asList("VALUE1", "VALUE2", "VALUE3"));
+
+ final StringProperty subEnumProperty = new StringProperty();
+ subEnumProperty.setEnum(Arrays.asList("SUB1", "SUB2", "SUB3"));
+
+ // Add one enum property to the parent
+ final Map parentProperties = new HashMap();
+ parentProperties.put("sharedThing", identicalEnumProperty);
+
+ // Add TWO enums to the subType model; one of which is identical to the one in parent class
+ final Map subProperties = new HashMap();
+ subProperties.put("sharedThing", identicalEnumProperty);
+ subProperties.put("unsharedThing", identicalEnumProperty);
+
+ final ModelImpl parentModel = new ModelImpl();
+ parentModel.setProperties(parentProperties);
+ parentModel.name("parentModel");
+
+ final ModelImpl subModel = new ModelImpl();
+ subModel.setProperties(subProperties);
+ subModel.name("subModel");
+
+ final ComposedModel model = new ComposedModel()
+ .parent(new RefModel(parentModel.getName()))
+ .child(subModel)
+ .interfaces(new ArrayList());
+
+ final DefaultCodegen codegen = new JavaClientCodegen();
+ final Map allModels = new HashMap();
+ allModels.put(parentModel.getName(), parentModel);
+ allModels.put(subModel.getName(), subModel);
+
+ final CodegenModel cm = codegen.fromModel("sample", model, allModels);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.parent, "ParentModel");
+ Assert.assertTrue(cm.imports.contains("ParentModel"));
+
+ // Assert that only the unshared/uninherited enum remains
+ Assert.assertEquals(cm.vars.size(), 1);
+ final CodegenProperty enumVar = cm.vars.get(0);
+ Assert.assertEquals(enumVar.baseName, "unsharedThing");
+ Assert.assertEquals(enumVar.datatype, "String");
+ Assert.assertEquals(enumVar.datatypeWithEnum, "UnsharedThingEnum");
+ Assert.assertTrue(enumVar.isEnum);
+ }
+}
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptModelTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptModelTest.java
new file mode 100644
index 000000000000..bb7afb942b7d
--- /dev/null
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/javascript/JavaScriptModelTest.java
@@ -0,0 +1,491 @@
+package io.swagger.codegen.javascript;
+
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Sets;
+
+import io.swagger.codegen.CodegenModel;
+import io.swagger.codegen.CodegenParameter;
+import io.swagger.codegen.CodegenProperty;
+import io.swagger.codegen.DefaultCodegen;
+import io.swagger.codegen.languages.JavascriptClientCodegen;
+import io.swagger.models.ArrayModel;
+import io.swagger.models.Model;
+import io.swagger.models.ModelImpl;
+import io.swagger.models.parameters.QueryParameter;
+import io.swagger.models.properties.ArrayProperty;
+import io.swagger.models.properties.ByteArrayProperty;
+import io.swagger.models.properties.DateTimeProperty;
+import io.swagger.models.properties.IntegerProperty;
+import io.swagger.models.properties.LongProperty;
+import io.swagger.models.properties.MapProperty;
+import io.swagger.models.properties.RefProperty;
+import io.swagger.models.properties.StringProperty;
+
+@SuppressWarnings("static-method")
+public class JavaScriptModelTest {
+ @Test(description = "convert a simple java model")
+ public void simpleModelTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("id", new LongProperty())
+ .property("name", new StringProperty()
+ .example("Tony"))
+ .property("createdAt", new DateTimeProperty())
+ .required("id")
+ .required("name");
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 3);
+
+ final List vars = cm.vars;
+
+ final CodegenProperty property1 = vars.get(0);
+ Assert.assertEquals(property1.baseName, "id");
+ Assert.assertEquals(property1.getter, "getId");
+ Assert.assertEquals(property1.setter, "setId");
+ Assert.assertEquals(property1.datatype, "Integer");
+ Assert.assertEquals(property1.name, "id");
+ Assert.assertEquals(property1.defaultValue, null);
+ Assert.assertEquals(property1.baseType, "Integer");
+ Assert.assertTrue(property1.hasMore);
+ Assert.assertTrue(property1.required);
+ Assert.assertTrue(property1.isNotContainer);
+
+ final CodegenProperty property2 = vars.get(1);
+ Assert.assertEquals(property2.baseName, "name");
+ Assert.assertEquals(property2.getter, "getName");
+ Assert.assertEquals(property2.setter, "setName");
+ Assert.assertEquals(property2.datatype, "String");
+ Assert.assertEquals(property2.name, "name");
+ Assert.assertEquals(property2.defaultValue, null);
+ Assert.assertEquals(property2.baseType, "String");
+ Assert.assertEquals(property2.example, "Tony");
+ Assert.assertTrue(property2.hasMore);
+ Assert.assertTrue(property2.required);
+ Assert.assertTrue(property2.isNotContainer);
+
+ final CodegenProperty property3 = vars.get(2);
+ Assert.assertEquals(property3.baseName, "createdAt");
+ Assert.assertEquals(property3.getter, "getCreatedAt");
+ Assert.assertEquals(property3.setter, "setCreatedAt");
+ Assert.assertEquals(property3.datatype, "Date");
+ Assert.assertEquals(property3.name, "createdAt");
+ Assert.assertEquals(property3.defaultValue, null);
+ Assert.assertEquals(property3.baseType, "Date");
+ Assert.assertNull(property3.hasMore);
+ Assert.assertNull(property3.required);
+ Assert.assertTrue(property3.isNotContainer);
+ }
+
+ @Test(description = "convert a model with list property")
+ public void listPropertyTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("id", new LongProperty())
+ .property("urls", new ArrayProperty()
+ .items(new StringProperty()))
+ .required("id");
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 2);
+
+ final CodegenProperty property = cm.vars.get(1);
+ Assert.assertEquals(property.baseName, "urls");
+ Assert.assertEquals(property.getter, "getUrls");
+ Assert.assertEquals(property.setter, "setUrls");
+ Assert.assertEquals(property.datatype, "[String]");
+ Assert.assertEquals(property.name, "urls");
+ // FIXME: should an array property have an empty array as its default value? What if the property is required?
+ Assert.assertEquals(property.defaultValue, /*"[]"*/null);
+ Assert.assertEquals(property.baseType, "Array");
+ Assert.assertEquals(property.containerType, "array");
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isContainer);
+ }
+
+ @Test(description = "convert a model with a map property")
+ public void mapPropertyTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("translations", new MapProperty()
+ .additionalProperties(new StringProperty()))
+ .required("id");
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "translations");
+ Assert.assertEquals(property.getter, "getTranslations");
+ Assert.assertEquals(property.setter, "setTranslations");
+ Assert.assertEquals(property.datatype, "{String: String}");
+ Assert.assertEquals(property.name, "translations");
+ // FIXME: should a map property have an empty object as its default value? What if the property is required?
+ Assert.assertEquals(property.defaultValue, /*"{}"*/null);
+ Assert.assertEquals(property.baseType, "Object");
+ Assert.assertEquals(property.containerType, "map");
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isContainer);
+ }
+
+ @Test(description = "convert a model with a map with complex list property")
+ public void mapWithListPropertyTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("translations",
+ new MapProperty().additionalProperties(new ArrayProperty().items(new RefProperty("Pet"))))
+ .required("id");
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "translations");
+ Assert.assertEquals(property.getter, "getTranslations");
+ Assert.assertEquals(property.setter, "setTranslations");
+ Assert.assertEquals(property.datatype, "{String: [Pet]}");
+ Assert.assertEquals(property.name, "translations");
+ // FIXME: should a map property have an empty object as its default value? What if the property is required?
+ Assert.assertEquals(property.defaultValue, /*"{}"*/null);
+ Assert.assertEquals(property.baseType, "Object");
+ Assert.assertEquals(property.containerType, "map");
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isContainer);
+ }
+
+ @Test(description = "convert a model with a 2D list property")
+ public void list2DPropertyTest() {
+ final Model model = new ModelImpl().name("sample").property("list2D", new ArrayProperty().items(
+ new ArrayProperty().items(new RefProperty("Pet"))));
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "list2D");
+ Assert.assertEquals(property.getter, "getList2D");
+ Assert.assertEquals(property.setter, "setList2D");
+ Assert.assertEquals(property.datatype, "[[Pet]]");
+ Assert.assertEquals(property.name, "list2D");
+ // FIXME: should an array property have an empty array as its default value? What if the property is required?
+ Assert.assertEquals(property.defaultValue, /*"[]"*/null);
+ Assert.assertEquals(property.baseType, "Array");
+ Assert.assertEquals(property.containerType, "array");
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isContainer);
+ }
+
+ @Test(description = "convert a model with complex properties")
+ public void complexPropertiesTest() {
+ final Model model = new ModelImpl().description("a sample model")
+ .property("children", new RefProperty("#/definitions/Children"));
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "children");
+ Assert.assertEquals(property.getter, "getChildren");
+ Assert.assertEquals(property.setter, "setChildren");
+ Assert.assertEquals(property.datatype, "Children");
+ Assert.assertEquals(property.name, "children");
+ Assert.assertEquals(property.defaultValue, null);
+ Assert.assertEquals(property.baseType, "Children");
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isNotContainer);
+ }
+
+ @Test(description = "convert a model with complex list property")
+ public void complexListPropertyTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("children", new ArrayProperty().items(new RefProperty("#/definitions/Children")));
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "children");
+ Assert.assertEquals(property.complexType, "Children");
+ Assert.assertEquals(property.getter, "getChildren");
+ Assert.assertEquals(property.setter, "setChildren");
+ // FIXME: what should datatype be for a JavaScript array?
+// Assert.assertEquals(property.datatype, "Array");
+ Assert.assertEquals(property.name, "children");
+ // FIXME: should an array property have an empty array as its default value? What if the property is required?
+ Assert.assertEquals(property.defaultValue, /*"[]"*/null);
+ Assert.assertEquals(property.baseType, "Array");
+ Assert.assertEquals(property.containerType, "array");
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isContainer);
+ }
+
+ @Test(description = "convert a model with complex map property")
+ public void complexMapPropertyTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("children", new MapProperty().additionalProperties(new RefProperty("#/definitions/Children")));
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 1);
+ Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "children");
+ Assert.assertEquals(property.complexType, "Children");
+ Assert.assertEquals(property.getter, "getChildren");
+ Assert.assertEquals(property.setter, "setChildren");
+ // TODO: create a functional test to see whether map properties actually work.
+ Assert.assertEquals(property.datatype, /*"Object"*/"{String: Children}");
+ Assert.assertEquals(property.name, "children");
+ // FIXME: should a map property have an empty object as its default value? What if the property is required?
+ Assert.assertEquals(property.defaultValue, /*"{}"*/ null);
+ Assert.assertEquals(property.baseType, "Object");
+ Assert.assertEquals(property.containerType, "map");
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isContainer);
+ Assert.assertNull(property.isNotContainer);
+ }
+
+ @Test(description = "convert an array model")
+ public void arrayModelTest() {
+ final Model model = new ArrayModel()
+ .description("an array model")
+ .items(new RefProperty("#/definitions/Children"));
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "an array model");
+ Assert.assertEquals(cm.vars.size(), 0);
+ Assert.assertEquals(cm.parent, "Array");
+ Assert.assertEquals(cm.imports.size(), 1);
+ Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
+ }
+
+ @Test(description = "convert a map model")
+ public void mapModelTest() {
+ final Model model = new ModelImpl()
+ .description("an map model")
+ .additionalProperties(new RefProperty("#/definitions/Children"));
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "an map model");
+ Assert.assertEquals(cm.vars.size(), 0);
+ Assert.assertEquals(cm.parent, "Object");
+ Assert.assertEquals(cm.imports.size(), 1);
+ Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1);
+ }
+
+ @Test(description = "convert a model with uppercase property names")
+ public void upperCaseNamesTest() {
+ final Model model = new ModelImpl()
+ .description("a model with uppercase property names")
+ .property("NAME", new StringProperty())
+ .required("NAME");
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "NAME");
+ Assert.assertEquals(property.getter, "getNAME");
+ Assert.assertEquals(property.setter, "setNAME");
+ Assert.assertEquals(property.datatype, "String");
+ Assert.assertEquals(property.name, "NAME");
+ Assert.assertEquals(property.defaultValue, null);
+ Assert.assertEquals(property.baseType, "String");
+ Assert.assertNull(property.hasMore);
+ Assert.assertTrue(property.required);
+ Assert.assertTrue(property.isNotContainer);
+ }
+
+ @Test(description = "convert a model with a 2nd char uppercase property names")
+ public void secondCharUpperCaseNamesTest() {
+ final Model model = new ModelImpl()
+ .description("a model with a 2nd char uppercase property names")
+ .property("pId", new StringProperty())
+ .required("pId");
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "pId");
+ Assert.assertEquals(property.getter, "getPId");
+ Assert.assertEquals(property.setter, "setPId");
+ Assert.assertEquals(property.datatype, "String");
+ Assert.assertEquals(property.name, "pId");
+ Assert.assertEquals(property.defaultValue, null);
+ Assert.assertEquals(property.baseType, "String");
+ Assert.assertNull(property.hasMore);
+ Assert.assertTrue(property.required);
+ Assert.assertTrue(property.isNotContainer);
+ }
+
+ @Test(description = "convert hyphens per issue 503")
+ public void hyphensTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("created-at", new DateTimeProperty());
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "created-at");
+ Assert.assertEquals(property.getter, "getCreatedAt");
+ Assert.assertEquals(property.setter, "setCreatedAt");
+ Assert.assertEquals(property.name, "createdAt");
+ }
+
+ @Test(description = "convert query[password] to queryPassword")
+ public void squareBracketsTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("query[password]", new StringProperty());
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "query[password]");
+ Assert.assertEquals(property.getter, "getQueryPassword");
+ Assert.assertEquals(property.setter, "setQueryPassword");
+ Assert.assertEquals(property.name, "queryPassword");
+ }
+
+ @Test(description = "properly escape names per 567")
+ public void escapeNamesTest() {
+ final Model model = new ModelImpl()
+ .description("a sample model")
+ .property("created-at", new DateTimeProperty());
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("with.dots", model);
+
+ Assert.assertEquals(cm.classname, "WithDots");
+ }
+
+ @Test(description = "convert a model with binary data")
+ public void binaryDataTest() {
+ final Model model = new ModelImpl()
+ .description("model with binary")
+ .property("inputBinaryData", new ByteArrayProperty());
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "inputBinaryData");
+ Assert.assertEquals(property.getter, "getInputBinaryData");
+ Assert.assertEquals(property.setter, "setInputBinaryData");
+ Assert.assertEquals(property.datatype, "String");
+ Assert.assertEquals(property.name, "inputBinaryData");
+ Assert.assertEquals(property.defaultValue, null);
+ Assert.assertEquals(property.baseType, "String");
+ Assert.assertNull(property.hasMore);
+ Assert.assertNull(property.required);
+ Assert.assertTrue(property.isNotContainer);
+ }
+
+ @Test(description = "translate an invalid param name")
+ public void invalidParamNameTest() {
+ final Model model = new ModelImpl()
+ .description("a model with a 2nd char uppercase property name")
+ .property("_", new StringProperty());
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", model);
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "_");
+ Assert.assertEquals(property.getter, "getU");
+ Assert.assertEquals(property.setter, "setU");
+ Assert.assertEquals(property.datatype, "String");
+ Assert.assertEquals(property.name, "u");
+ Assert.assertEquals(property.defaultValue, null);
+ Assert.assertEquals(property.baseType, "String");
+ Assert.assertNull(property.hasMore);
+ Assert.assertTrue(property.isNotContainer);
+ }
+
+ @Test(description = "convert a parameter")
+ public void convertParameterTest() {
+ final QueryParameter parameter = new QueryParameter()
+ .property(new IntegerProperty())
+ .name("limit")
+ .required(true);
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenParameter cm = codegen.fromParameter(parameter, null);
+
+ Assert.assertNull(cm.allowableValues);
+ }
+
+ @DataProvider(name = "modelNames")
+ public static Object[][] primeNumbers() {
+ return new Object[][] {
+ {"sample", "Sample"},
+ {"sample_name", "SampleName"},
+ {"sample__name", "SampleName"},
+ {"/sample", "Sample"},
+ {"\\sample", "Sample"},
+ {"sample.name", "SampleName"},
+ {"_sample", "Sample"},
+ {"Sample", "Sample"},
+ };
+ }
+
+ @Test(dataProvider = "modelNames", description = "avoid inner class")
+ public void modelNameTest(String name, String expectedName) {
+ final Model model = new ModelImpl();
+ final DefaultCodegen codegen = new JavascriptClientCodegen();
+ final CodegenModel cm = codegen.fromModel(name, model);
+
+ Assert.assertEquals(cm.name, name);
+ Assert.assertEquals(cm.classname, expectedName);
+ }
+}
diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/JavaScriptOptionsProvider.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/JavaScriptOptionsProvider.java
new file mode 100644
index 000000000000..9b0f06a10312
--- /dev/null
+++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/options/JavaScriptOptionsProvider.java
@@ -0,0 +1,88 @@
+package io.swagger.codegen.options;
+
+import io.swagger.codegen.CodegenConstants;
+import io.swagger.codegen.options.OptionsProvider;
+import io.swagger.codegen.languages.JavascriptClientCodegen;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+
+public class JavaScriptOptionsProvider implements OptionsProvider {
+ public static final String ARTIFACT_ID_VALUE = "swagger-javascript-client-test";
+ public static final String MODEL_PACKAGE_VALUE = "model";
+ public static final String API_PACKAGE_VALUE = "api";
+// public static final String INVOKER_PACKAGE_VALUE = "js";
+ public static final String SORT_PARAMS_VALUE = "false";
+ public static final String GROUP_ID_VALUE = "io.swagger.test";
+ public static final String ARTIFACT_VERSION_VALUE = "1.0.0-SNAPSHOT";
+ public static final String SOURCE_FOLDER_VALUE = "src/main/javascript";
+ public static final String LOCAL_PREFIX_VALUE = "_";
+// public static final String SERIALIZABLE_MODEL_VALUE = "false";
+ public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
+ public static final String PROJECT_NAME_VALUE = "JavaScript Client Test";
+ public static final String MODULE_NAME_VALUE = "JavaScriptClient";
+ public static final String PROJECT_DESCRIPTION_VALUE = "Tests JavaScript code generator options";
+ public static final String PROJECT_VERSION_VALUE = "1.0.0";
+ public static final String PROJECT_LICENSE_NAME_VALUE = "Apache";
+ public static final String USE_PROMISES_VALUE = "true";
+ public static final String USE_INHERITANCE_VALUE = "false";
+ public static final String EMIT_MODEL_METHODS_VALUE = "true";
+ public static final String EMIT_JS_DOC_VALUE = "false";
+
+ private ImmutableMap options;
+
+ /**
+ * Create an options provider with the default options.
+ */
+ public JavaScriptOptionsProvider() {
+ // Commented generic options not yet supported by JavaScript codegen.
+ options = new ImmutableMap.Builder()
+ .put(CodegenConstants.MODEL_PACKAGE, MODEL_PACKAGE_VALUE)
+ .put(CodegenConstants.API_PACKAGE, API_PACKAGE_VALUE)
+ .put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
+ .put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
+// .put(CodegenConstants.INVOKER_PACKAGE, INVOKER_PACKAGE_VALUE)
+// .put(CodegenConstants.GROUP_ID, GROUP_ID_VALUE)
+// .put(CodegenConstants.ARTIFACT_ID, ARTIFACT_ID_VALUE)
+// .put(CodegenConstants.ARTIFACT_VERSION, ARTIFACT_VERSION_VALUE)
+ .put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE)
+ .put(CodegenConstants.LOCAL_VARIABLE_PREFIX, LOCAL_PREFIX_VALUE)
+// .put(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING, "true")
+ .put(JavascriptClientCodegen.PROJECT_NAME, PROJECT_NAME_VALUE)
+ .put(JavascriptClientCodegen.MODULE_NAME, MODULE_NAME_VALUE)
+ .put(JavascriptClientCodegen.PROJECT_DESCRIPTION, PROJECT_DESCRIPTION_VALUE)
+ .put(JavascriptClientCodegen.PROJECT_VERSION, PROJECT_VERSION_VALUE)
+ .put(JavascriptClientCodegen.PROJECT_LICENSE_NAME, PROJECT_LICENSE_NAME_VALUE)
+ .put(JavascriptClientCodegen.USE_PROMISES, USE_PROMISES_VALUE)
+ .put(JavascriptClientCodegen.USE_INHERITANCE, USE_INHERITANCE_VALUE)
+ .put(JavascriptClientCodegen.EMIT_MODEL_METHODS, EMIT_MODEL_METHODS_VALUE)
+ .put(JavascriptClientCodegen.EMIT_JS_DOC, EMIT_JS_DOC_VALUE)
+ .build();
+ }
+
+ /**
+ * Use the default options, but override the ones found in additionalOptions.
+ */
+ public JavaScriptOptionsProvider(Map additionalOptions) {
+ options = new ImmutableMap.Builder()
+ .putAll(options)
+ .putAll(additionalOptions)
+ .build();
+ }
+
+ @Override
+ public Map createOptions() {
+ return options;
+ }
+
+ @Override
+ public boolean isServer() {
+ return false;
+ }
+
+ @Override
+ public String getLanguage() {
+ return "javascript";
+ }
+}