diff --git a/README.md b/README.md
index bef96642..af85abd3 100644
--- a/README.md
+++ b/README.md
@@ -55,6 +55,12 @@ In addition to the common options listed below, `getCustomCode()` *requires* a `
lint:
type: boolean
description: whether or not to run jslint on the generated code
+ language:
+ type: string
+ description: currently only 'typescript' is supported, but could potentially be 'coffeescript', 'es2015'...
+ framework:
+ type: string
+ description: currently only 'angular' is supported, but could potentially be 'react', 'polymer'...
esnext:
type: boolean
description: passed through to jslint
diff --git a/lib/codegen.js b/lib/codegen.js
index 65b356d1..9acb4448 100644
--- a/lib/codegen.js
+++ b/lib/codegen.js
@@ -41,6 +41,7 @@ var getViewForSwagger2 = function(opts, type){
className: opts.className,
imports: opts.imports,
domain: (swagger.schemes && swagger.schemes.length > 0 && swagger.host && swagger.basePath) ? swagger.schemes[0] + '://' + swagger.host + swagger.basePath.replace(/\/+$/g,'') : '',
+ basePath: swagger.basePath,
methods: [],
definitions: []
};
@@ -57,7 +58,7 @@ var getViewForSwagger2 = function(opts, type){
}
});
_.forEach(api, function(op, m){
- if(authorizedMethods.indexOf(m.toUpperCase()) === -1) {
+ if(authorizedMethods.indexOf(m.toUpperCase()) === -1 || m.toUpperCase() == 'OPTIONS') {
return;
}
var method = {
@@ -74,7 +75,7 @@ var getViewForSwagger2 = function(opts, type){
headers: []
};
- if(op.produces) {
+ if (op.produces) {
var headers = [];
headers.value = [];
@@ -85,17 +86,40 @@ var getViewForSwagger2 = function(opts, type){
}
var consumes = op.consumes || swagger.consumes;
- if(consumes) {
+ if (consumes) {
method.headers.push({name: 'Content-Type', value: '\'' + consumes + '\'' });
}
var params = [];
- if(_.isArray(op.parameters)) {
+ if (_.isArray(op.parameters)) {
params = op.parameters;
}
+
+ method.hasBody = false;
+ method.hasForm = false;
+ method.tsType = 'void';
+ method.hasVoidReturn = true;
+
+ if (op.responses) {
+ _.some(['200', '201'], function(code) {
+ if (op.responses[code]) {
+ method.tsType = ts.convertType(op.responses[code]);
+ if (method.tsType.isRef) {
+ method.tsType = method.tsType.target.charAt(0).toUpperCase() + method.tsType.target.substring(1);
+ } else {
+ method.tsType = method.tsType.tsType;
+ }
+ if (method.tsType != 'any') {
+ method.hasVoidReturn = false;
+ }
+ return true;
+ }
+ });
+ }
+
params = params.concat(globalParams);
_.forEach(params, function(parameter) {
- //Ignore parameters which contain the x-exclude-from-bindings extension
+ // Ignore parameters which contain the x-exclude-from-bindings extension
if(parameter['x-exclude-from-bindings'] === true) {
return;
}
@@ -114,8 +138,10 @@ var getViewForSwagger2 = function(opts, type){
parameter.isSingleton = true;
parameter.singleton = parameter.enum[0];
}
+ parameter.paramType = parameter.in;
if(parameter.in === 'body'){
parameter.isBodyParameter = true;
+ method.hasBody = true;
} else if(parameter.in === 'path'){
parameter.isPathParameter = true;
} else if(parameter.in === 'query'){
@@ -128,6 +154,7 @@ var getViewForSwagger2 = function(opts, type){
parameter.isHeaderParameter = true;
} else if(parameter.in === 'formData'){
parameter.isFormParameter = true;
+ method.hasForm = true;
}
parameter.tsType = ts.convertType(parameter);
parameter.cardinality = parameter.required ? '' : '?';
@@ -137,11 +164,10 @@ var getViewForSwagger2 = function(opts, type){
});
});
- _.forEach(swagger.definitions, function(definition, name){
- data.definitions.push({
- name: name,
- tsType: ts.convertType(definition)
- });
+ _.forEach(swagger.definitions, function(definition, name) {
+ var type = ts.convertType(definition);
+ type.name = name.charAt(0).toUpperCase() + name.substring(1);
+ data.definitions.push(type);
});
return data;
@@ -159,6 +185,8 @@ var getViewForSwagger1 = function(opts, type){
};
swagger.apis.forEach(function(api){
api.operations.forEach(function(op){
+ if (op.method == 'OPTIONS') return;
+
var method = {
path: api.path,
className: opts.className,
@@ -210,23 +238,65 @@ var getViewForSwagger1 = function(opts, type){
return data;
};
+var fileExists = function(filePath) {
+ try {
+ return fs.statSync(filePath).isFile();
+ } catch (err) {
+ return false;
+ }
+};
+
+/**
+ * @param path eg: __dirname + '/../templates/'
+ * @param language eg: 'typescript', 'coffeescript'
+ * @param framework eg: 'angular', 'angular2', 'react', 'polymer'
+ * @param suffix eg: 'class.mustache'
+ */
+var locateTemplate = function(path, language, framework, suffix) {
+ if (language && framework && fileExists(path + language + '-' + framework + '-' + suffix)) {
+ return path + language + '-' + framework + '-' + suffix;
+ }
+ if (language && fileExists(path + language + '-' + suffix)) {
+ return path + language + '-' + suffix;
+ }
+ if (framework && fileExists(path + framework + '-' + suffix)) {
+ return path + framework + '-' + suffix;
+ }
+ return path + suffix;
+};
+
+var readTemplate = function(path, language, framework, suffix) {
+ return fs.readFileSync(locateTemplate(path, language, framework, suffix), 'utf-8');
+};
+
+/**
+ * @param {{ template?: {}, framework?: string, language?: string }} opts
+ * @param type - 'typescript', 'angular', 'node'
+ */
+var selectTemplates = function(opts, type) {
+ if (!_.isObject(opts.template)) {
+ opts.template = {};
+ }
+ var templates = __dirname + '/../templates/';
+ var language = opts.language || (type === 'typescript' ? type : undefined);
+ var framework = opts.framework || (type !== 'typescript' ? type : undefined);
+
+ opts.template.class = opts.template.class || readTemplate(templates, language, framework, 'class.mustache');
+ opts.template.method = opts.template.method || readTemplate(templates, language, framework, 'method.mustache');
+ if(type === 'typescript') {
+ opts.template.type = readTemplate(templates, language, framework, 'type.mustache');
+ }
+};
+
var getCode = function(opts, type) {
// For Swagger Specification version 2.0 value of field 'swagger' must be a string '2.0'
var data = opts.swagger.swagger === '2.0' ? getViewForSwagger2(opts, type) : getViewForSwagger1(opts, type);
if (type === 'custom') {
if (!_.isObject(opts.template) || !_.isString(opts.template.class) || !_.isString(opts.template.method)) {
- throw new Error('Unprovided custom template. Please use the following template: template: { class: "...", method: "...", request: "..." }');
+ throw new Error('Unprovided custom template. Please use the following template: template: { class: "...", method: "..." }');
}
} else {
- if (!_.isObject(opts.template)) {
- opts.template = {};
- }
- var templates = __dirname + '/../templates/';
- opts.template.class = opts.template.class || fs.readFileSync(templates + type + '-class.mustache', 'utf-8');
- opts.template.method = opts.template.method || fs.readFileSync(templates + (type === 'typescript' ? 'typescript-' : '') + 'method.mustache', 'utf-8');
- if(type === 'typescript') {
- opts.template.type = opts.template.type || fs.readFileSync(templates + 'type.mustache', 'utf-8');
- }
+ selectTemplates(opts, type);
}
if (opts.mustache) {
@@ -247,7 +317,7 @@ var getCode = function(opts, type) {
lintOptions.esnext = true;
}
- if(type === 'typescript') {
+ if (type === 'typescript') {
opts.lint = false;
}
diff --git a/lib/typescript.js b/lib/typescript.js
index b33070c4..ae7a6897 100644
--- a/lib/typescript.js
+++ b/lib/typescript.js
@@ -14,14 +14,39 @@ var _ = require('lodash');
function convertType(swaggerType) {
var typespec = {};
+ if (swaggerType.hasOwnProperty('allOf')) {
+ typespec.isIntersection = true;
+ typespec.items = swaggerType.allOf.map(function(item) {
+ // join with '&' and avoid 'RangeError: Maximum call stack size exceeded'
+ return Object.assign(convertType(item), {hasPrefix: true, isIntersection: false});
+ });
+ typespec.items[0].hasPrefix = false;
+ typespec.tsType = 'intersection';
- if (swaggerType.hasOwnProperty('schema')) {
+ } else if (swaggerType.hasOwnProperty('schema')) {
return convertType(swaggerType.schema);
} else if (_.isString(swaggerType.$ref)) {
typespec.tsType = 'ref';
typespec.target = swaggerType.$ref.substring(swaggerType.$ref.lastIndexOf('/') + 1);
+ } else if (swaggerType.type === 'array') {
+ if (swaggerType.in === 'query' && swaggerType.collectionFormat !== 'multi') {
+ // arrays in query parameters are merged by csv, ssv, tsv or pipes
+ typespec.tsType = 'string';
+ if (swaggerType.hasOwnProperty('enum')) {
+ // doesn't affect the compiler, but useful for documentation
+ typespec.tsType += ' | ' + swaggerType.enum.map(function (str) {
+ return typeof str == 'string' ? '\'' + str + '\'' : JSON.stringify(str);
+ }).join(' | ');
+ typespec.isAtomic = true;
+ }
+ } else {
+ typespec.tsType = 'array';
+ }
+ typespec.elementType = convertType(swaggerType.items);
} else if (swaggerType.hasOwnProperty('enum')) {
- typespec.tsType = swaggerType.enum.map(function(str) { return JSON.stringify(str); }).join(' | ');
+ typespec.tsType = swaggerType.enum.map(function(str) {
+ return typeof str == 'string' ? '\'' + str + '\'' : JSON.stringify(str);
+ }).join(' | ');
typespec.isAtomic = true;
} else if (swaggerType.type === 'string') {
typespec.tsType = 'string';
@@ -29,20 +54,18 @@ function convertType(swaggerType) {
typespec.tsType = 'number';
} else if (swaggerType.type === 'boolean') {
typespec.tsType = 'boolean';
- } else if (swaggerType.type === 'array') {
- typespec.tsType = 'array';
- typespec.elementType = convertType(swaggerType.items);
} else if (swaggerType.type === 'object') {
typespec.tsType = 'object';
typespec.properties = [];
-
_.forEach(swaggerType.properties, function (propertyType, propertyName) {
var property = convertType(propertyType);
property.name = propertyName;
+ property.isOptional = !(swaggerType.required && _.includes(swaggerType.required, propertyName));
typespec.properties.push(property);
});
} else {
// type unknown or unsupported... just map to 'any'...
+ // TODO: probably void
typespec.tsType = 'any';
}
@@ -51,9 +74,10 @@ function convertType(swaggerType) {
typespec.isObject = typespec.tsType === 'object';
typespec.isArray = typespec.tsType === 'array';
typespec.isAtomic = typespec.isAtomic || _.includes(['string', 'number', 'boolean', 'any'], typespec.tsType);
+ typespec.isOptional = !swaggerType.required;
+ typespec.description = swaggerType.description;
return typespec;
-
}
module.exports.convertType = convertType;
diff --git a/package.json b/package.json
index 8f4c0852..5e16dcdf 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "swagger-js-codegen",
"main": "./lib/codegen.js",
- "version": "1.7.12",
+ "version": "1.7.15-c",
"description": "A Swagger codegen for JavaScript",
"scripts": {
"test": "grunt",
diff --git a/templates/type.mustache b/templates/type.mustache
index d8f2518d..bd9b87fa 100644
--- a/templates/type.mustache
+++ b/templates/type.mustache
@@ -1,11 +1,12 @@
{{#tsType}}
{{! must use different delimiters to avoid ambiguities when delimiters directly follow a literal brace {. }}
{{=<% %>=}}
-<%#isRef%><%target%><%/isRef%><%!
+<%#isIntersection%><%#items%><%#hasPrefix%>&<%/hasPrefix%><%>type%><%/items%><%/isIntersection%><%!
+%><%#isRef%><%target%><%/isRef%><%!
%><%#isAtomic%><%&tsType%><%/isAtomic%><%!
-%><%#isObject%>{<%#properties%>
-'<%name%>': <%>type%><%/properties%>
+%><%#isObject%>{<%#properties%><%#description%>/** <%description%> */<%/description%>
+<%name%><%#isOptional%>?<%/isOptional%>: <%>type%>;<%/properties%>
}<%/isObject%><%!
-%><%#isArray%>Array<<%#elementType%><%>type%><%/elementType%>>|<%#elementType%><%>type%><%/elementType%><%/isArray%>
-<%={{ }}=%>
-{{/tsType}}
\ No newline at end of file
+%><%#isArray%>Array<<%#elementType%><%>type%><%/elementType%>><%/isArray%><%!
+%><%#isBoolean%>boolean<%/isBoolean%><%!
+%><%={{ }}=%>{{/tsType}}
diff --git a/templates/typescript-angular-class.mustache b/templates/typescript-angular-class.mustache
new file mode 100644
index 00000000..23891bde
--- /dev/null
+++ b/templates/typescript-angular-class.mustache
@@ -0,0 +1,45 @@
+/* tslint:disable */
+import * as angular from 'angular';
+
+export module {{moduleName}} {
+
+{{#definitions}}
+ {{#description}}/** {{description}} */{{/description}}
+ export type {{&name}} = {{#tsType}}{{> type}}{{/tsType}};
+
+{{/definitions}}
+
+/**
+* {{&description}}
+* @class {{&className}}
+* @param {ng.IHttpService} $http
+* @param {ng.IQService} $q
+* @param {string} domain - The project domain.
+* provide using .constant('domain', '//example.com') or .factory('domain', function(){return '//example.com'})
+*/
+export class {{&className}} {
+ static $inject = ['$http', '$q', 'domain'];
+
+ constructor(private $http: ng.IHttpService, private $q: ng.IQService, private domain: string) {}
+
+{{#methods}}
+ {{> method}}
+
+{{/methods}}
+
+ private static transformRequest(obj: any): string {
+ var str = [];
+ for(var p in obj) {
+ var val = obj[p];
+ if(angular.isArray(val)) {
+ val.forEach(function(val){
+ str.push(encodeURIComponent(p) + '=' + encodeURIComponent(val));
+ });
+ } else {
+ str.push(encodeURIComponent(p) + '=' + encodeURIComponent(val));
+ }
+ }
+ return str.join('&');
+ }
+}
+}
diff --git a/templates/typescript-angular-method.mustache b/templates/typescript-angular-method.mustache
new file mode 100644
index 00000000..6fd01f68
--- /dev/null
+++ b/templates/typescript-angular-method.mustache
@@ -0,0 +1,151 @@
+/**
+* {{&summary}}
+* @method
+{{#externalDocs}}
+* @see {@link {{&url}}|{{#description}}{{&description}}{{/description}}{{^description}}External docs{{/description}}}
+{{/externalDocs}}
+* @name {{&className}}#{{&methodName}}
+{{#parameters}}
+ {{^isSingleton}} * @param {{=<% %>=}}{<%&type%>}<%={{ }}=%> {{&camelCaseName}} - {{&description}}{{/isSingleton}}
+{{/parameters}}
+*/
+{{&methodName}}(parameters: {
+{{#parameters}}{{^isSingleton}}{{&camelCaseName}}{{&cardinality}}: {{> type}},
+{{/isSingleton}}{{/parameters}}
+ $queryParameters?: {},
+ },
+ opts: {
+ $timeout?: number;
+ $refresh?: boolean;
+ $cache?: {
+ get:(key: string) => string|Object
+ put:(key: string, value: string|Object, options?: {}) => void;
+ };
+ $cacheItemOpts?: {};
+ } = {}): ng.IPromise<{{&tsType}}|any> {
+ let domain = this.domain;
+ let path = '{{&basePath}}{{&path}}';
+ {{#hasBody}}
+ let body;
+ {{/hasBody}}
+ let queryParameters = {};
+ let headers = {};
+ {{#hasForm}}
+ let form = {};
+ {{/hasForm}}
+ let deferred = this.$q.defer();
+
+{{#headers}}
+ headers['{{&name}}'] = [{{&value}}];
+{{/headers}}
+
+{{#parameters}}
+ {{#isQueryParameter}}
+ {{#isSingleton}}
+ queryParameters['{{&name}}'] = '{{&singleton}}';
+ {{/isSingleton}}
+ {{^isSingleton}}
+ {{#isPatternType}}
+ Object.keys(parameters).forEach(function(parameterName) {
+ if(new RegExp('{{&pattern}}').test(parameterName)){
+ queryParameters[parameterName] = parameters[parameterName];
+ }
+ });
+ {{/isPatternType}}
+ {{^isPatternType}}
+ if(parameters['{{&camelCaseName}}'] !== undefined){
+ queryParameters['{{&name}}'] = parameters['{{&camelCaseName}}'];
+ }
+ {{/isPatternType}}
+ {{/isSingleton}}
+ {{/isQueryParameter}}
+
+ {{#isPathParameter}}
+ path = path.replace('{{=<% %>=}}{<%&name%>}<%={{ }}=%>', parameters['{{&camelCaseName}}']);
+ {{/isPathParameter}}
+
+ {{#isHeaderParameter}}
+ {{#isSingleton}}
+ headers['{{&name}}'] = '{{&singleton}}';
+ {{/isSingleton}}
+ {{^isSingleton}}
+ if(parameters['{{&camelCaseName}}'] !== undefined){
+ headers['{{&name}}'] = parameters['{{&camelCaseName}}'];
+ }
+ {{/isSingleton}}
+ {{/isHeaderParameter}}
+
+ {{#isBodyParameter}}
+ if(parameters['{{&camelCaseName}}'] !== undefined){
+ body = parameters['{{&camelCaseName}}'];
+ }
+ {{/isBodyParameter}}
+
+ {{#isFormParameter}}
+ {{#isSingleton}}
+ form['{{&name}}'] = '{{&singleton}}';
+ {{/isSingleton}}
+ {{^isSingleton}}
+ if(parameters['{{&camelCaseName}}'] !== undefined){
+ form['{{&name}}'] = parameters['{{&camelCaseName}}'];
+ }
+ {{/isSingleton}}
+ {{/isFormParameter}}
+{{/parameters}}
+
+if(parameters.$queryParameters) {
+ Object.keys(parameters.$queryParameters).forEach(function(parameterName){
+ var parameter = parameters.$queryParameters[parameterName];
+ queryParameters[parameterName] = parameter;
+ });
+}
+
+var url = domain + path;
+{{#isGET}}
+var cached = opts.$cache && opts.$cache.get(url);
+if(cached !== undefined && opts.$refresh !== true) {
+ deferred.resolve(cached);
+ return deferred.promise;
+}
+{{/isGET}}
+var options = {
+ timeout: opts.$timeout,
+ method: '{{method}}',
+ url: url,
+ params: queryParameters,
+{{#hasBody}}
+ data: body,
+{{/hasBody}}
+{{#hasForm}}
+ data: form,
+{{/hasForm}}
+ headers: headers
+};
+{{! I don't think this is actually needed #hasBody} }
+if(typeof(body) === 'object' && !(body.constructor.name === 'Buffer')) {
+ options.headers['Content-Type'] = 'application/json';
+{ {/hasBody}}
+{{#hasForm}}
+options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
+options.transformRequest = {{&className}}.transformRequest;
+{{/hasForm}}
+
+this.$http(options).then(function(response: ng.IHttpPromiseCallbackArg<{{&tsType}}|any>){
+ if(response.status >= 400) {
+ deferred.reject(response);
+ } else {
+ {{#hasVoidReturn}}
+ deferred.resolve();
+ {{/hasVoidReturn}}
+ {{^hasVoidReturn}}
+ deferred.resolve(response.data);
+ if(opts.$cache !== undefined) {
+ opts.$cache.put(url, response.data, opts.$cacheItemOpts ? opts.$cacheItemOpts : {});
+ }
+ {{/hasVoidReturn}}
+ }
+}, deferred.reject);
+
+return deferred.promise;
+
+}
diff --git a/templates/typescript-class.mustache b/templates/typescript-class.mustache
index d4f81ddf..bdf1988a 100644
--- a/templates/typescript-class.mustache
+++ b/templates/typescript-class.mustache
@@ -1,7 +1,6 @@
{{#imports}}
///
{{/imports}}
-
import * as request from "superagent";
import {SuperAgentStatic} from "superagent";
@@ -10,13 +9,20 @@ type CallbackHandler = (err: any, res?: request.Response) => void;
type {{&name}} = {{#tsType}}{{> type}}{{/tsType}};
{{/definitions}}
+module {{moduleName}} {
+
+{{#definitions}}
+{{#description}}/** {{description}} */{{/description}}
+interface {{name}} {{> type}}
+
+{{/definitions}}
+
/**
* {{&description}}
* @class {{&className}}
- * @param {(string)} [domainOrOptions] - The project domain.
+ * @param {string} domain - The project domain.
*/
export default class {{&className}} {
-
private domain: string = "{{&domain}}";
private errorHandlers: CallbackHandler[] = [];
diff --git a/templates/typescript-method.mustache b/templates/typescript-method.mustache
index 45bf93d6..47ceb2b7 100644
--- a/templates/typescript-method.mustache
+++ b/templates/typescript-method.mustache
@@ -6,7 +6,7 @@ $domain?: string
}): string {
let queryParameters: any = {};
const domain = parameters.$domain ? parameters.$domain : this.domain;
- let path = '{{&path}}';
+ let path = '{{&basePath}}{{&path}}';
{{#parameters}}
{{#isQueryParameter}}
{{#isSingleton}}
@@ -71,18 +71,22 @@ $domain?: string
const domain = parameters.$domain ? parameters.$domain : this.domain;
const errorHandlers = this.errorHandlers;
const request = this.request;
- let path = '{{&path}}';
+ const path = '{{&path}}';
+ {{#hasBody}}
let body: any;
+ {{/hasBody}}
let queryParameters: any = {};
let headers: any = {};
+ {{#hasForm}}
let form: any = {};
+ {{/hasForm}}
+
return new Promise(function(resolve, reject) {
{{#headers}}
headers['{{&name}}'] = {{&value}};
{{/headers}}
{{#parameters}}
-
{{#isQueryParameter}}
{{#isSingleton}}
queryParameters['{{&name}}'] = '{{&singleton}}';
@@ -134,22 +138,14 @@ $domain?: string
}
{{/isSingleton}}
{{/isFormParameter}}
-
- {{#required}}
- if(parameters['{{&camelCaseName}}'] === undefined){
- reject(new Error('Missing required {{¶mType}} parameter: {{&camelCaseName}}'));
- return;
- }
- {{/required}}
-
{{/parameters}}
-if(parameters.$queryParameters) {
- Object.keys(parameters.$queryParameters).forEach(function(parameterName){
- var parameter = parameters.$queryParameters[parameterName];
- queryParameters[parameterName] = parameter;
- });
-}
+ if(parameters.$queryParameters) {
+ Object.keys(parameters.$queryParameters).forEach(function(parameterName){
+ var parameter = parameters.$queryParameters[parameterName];
+ queryParameters[parameterName] = parameter;
+ });
+ }
{{^isBodyParameter}}
{{#isPOST}}
@@ -161,4 +157,4 @@ if(parameters.$queryParameters) {
request('{{method}}', domain + path, body, headers, queryParameters, form, reject, resolve, errorHandlers);
});
-};
+}
diff --git a/tests/utilities.js b/tests/utilities.js
new file mode 100644
index 00000000..23b57c09
--- /dev/null
+++ b/tests/utilities.js
@@ -0,0 +1,65 @@
+'use strict';
+
+var assert = require('assert');
+var rewire = require('rewire');
+var vows = require('vows');
+
+var CodeGen = rewire('../lib/codegen.js');
+
+vows.describe('Test Utilities').addBatch({
+ 'selectTemplates': {
+ topic: function(){
+ var locateTemplate = CodeGen.__get__('locateTemplate');
+ CodeGen.__set__('readTemplate', function(path, language, framework, suffix) {
+ return locateTemplate(path, language, framework, suffix);
+ });
+ return CodeGen.__get__('selectTemplates');
+ },
+ 'should be backward-compatible': {
+ topic: function(selectTemplates) {
+ return selectTemplates; //_.curry(selectTemplates)({});
+ },
+ 'with angular': function(selectTemplates) {
+ var opts = {};
+ var dirname = __dirname.replace(/tests$/, 'lib') + '/../templates/';
+ selectTemplates(opts, 'angular');
+ assert.equal(opts.template.class, dirname + 'angular-class.mustache');
+ assert.equal(opts.template.method, dirname + 'method.mustache');
+ assert.equal(opts.template.type, undefined);
+ },
+ 'with node': function(selectTemplates) {
+ var opts = {};
+ var dirname = __dirname.replace(/tests$/, 'lib') + '/../templates/';
+ selectTemplates(opts, 'node');
+ assert.equal(opts.template.class, dirname + 'node-class.mustache');
+ assert.equal(opts.template.method, dirname + 'method.mustache');
+ assert.equal(opts.template.type, undefined);
+ },
+ 'with typescript': function(selectTemplates) {
+ var opts = {};
+ var dirname = __dirname.replace(/tests$/, 'lib') + '/../templates/';
+ selectTemplates(opts, 'typescript');
+ assert.equal(opts.template.class, dirname + 'typescript-class.mustache');
+ assert.equal(opts.template.method, dirname + 'typescript-method.mustache');
+ assert.equal(opts.template.type, dirname + 'type.mustache');
+ }
+ }
+ },
+ 'locateTemplate': {
+ topic: function(){
+ return CodeGen.__get__('locateTemplate');
+ },
+ 'should find templates for language and framework': function(locateTemplate) {
+ assert.equal(locateTemplate(__dirname + '/../templates/', 'typescript', 'angular', 'class.mustache'),
+ __dirname + '/../templates/typescript-angular-class.mustache');
+ },
+ 'should find templates for language': function(locateTemplate) {
+ assert.equal(locateTemplate(__dirname + '/../templates/', 'typescript', undefined, 'class.mustache'),
+ __dirname + '/../templates/typescript-class.mustache');
+ },
+ 'should find templates for framework': function(locateTemplate) {
+ assert.equal(locateTemplate(__dirname + '/../templates/', undefined, 'angular', 'class.mustache'),
+ __dirname + '/../templates/angular-class.mustache');
+ }
+ }
+}).export(module);