Repository: postmanlabs/postman-code-generators
Pull request #36 (2019-07-02 08:37:29)

Fixed requestTimeout issues 
 Codegens affected : 

- Added Implementation (was present in getOptions, not actually being used) : 
  - restsharp
  - js-xhr
  - ruby
- Added support for indefinite timeout : 
  - golang (also converted from seconds to milliseconds)
  - java-unirest
  - shell-httpie
  - shell-wget
  - swift
- Added as a whole new option : 
  - libcurl


Patch:
diff --git a/codegens/csharp-restsharp/lib/restsharp.js b/codegens/csharp-restsharp/lib/restsharp.js
index 3922cd1..3f0de6f 100644
--- a/codegens/csharp-restsharp/lib/restsharp.js
+++ b/codegens/csharp-restsharp/lib/restsharp.js
@@ -17,7 +17,12 @@ function makeSnippet (request, options) {
     var snippet = `var client = new RestClient("${sanitize(request.url.toString())}");\n`,
         isUnSupportedMethod = UNSUPPORTED_METHODS_LIKE_GET.includes(request.method) ||
             UNSUPPORTED_METHODS_LIKE_POST.includes(request.method);
-
+    if (options.requestTimeout) {
+        snippet += `client.Timeout = ${options.requestTimeout};\n`;
+    }
+    else {
+        snippet += 'client.Timeout = -1;\n';
+    }
     snippet += `var request = new RestRequest(${isUnSupportedMethod ? '' : ('Method.' + request.method)});\n`;
     snippet += parseRequest.parseHeader(request.toJSON(), options.trimRequestBody);
     snippet += parseRequest.parseBody(request, options.trimRequestBody);
diff --git a/codegens/golang/lib/index.js b/codegens/golang/lib/index.js
index c3a6a03..e9f6902 100644
--- a/codegens/golang/lib/index.js
+++ b/codegens/golang/lib/index.js
@@ -168,7 +168,7 @@ module.exports = {
         }
 
         if (timeout > 0) {
-            codeSnippet += `${indent}timeout := time.Duration(${timeout} * time.Second)\n`;
+            codeSnippet += `${indent}timeout := time.Duration(${timeout / 1000} * time.Second)\n`;
         }
 
         codeSnippet += indent + 'client := &http.Client {\n';
diff --git a/codegens/java-unirest/lib/unirest.js b/codegens/java-unirest/lib/unirest.js
index fb11756..432b082 100644
--- a/codegens/java-unirest/lib/unirest.js
+++ b/codegens/java-unirest/lib/unirest.js
@@ -6,11 +6,11 @@ var _ = require('./lodash'),
 const SUPPORTED_METHODS = ['GET', 'POST', 'PUT', 'HEAD', 'PATCH', 'DELETE', 'OPTIONS'];
 
 /**
- * parses request and returns java unirest code snippet 
- * 
- * @param {Object} request - Postman SDK Request Object 
+ * parses request and returns java unirest code snippet
+ *
+ * @param {Object} request - Postman SDK Request Object
  * @param {String} indentString - indentation required for code snippet
- * @param {Object} options 
+ * @param {Object} options
  * @return {String} - java unirest code snippet
  */
 function makeSnippet (request, indentString, options) {
@@ -18,7 +18,10 @@ function makeSnippet (request, indentString, options) {
         urlString = encodeURI(request.url.toString());
 
     if (options.requestTimeout > 0) {
-        snippet += `Unirest.setTimeouts(${options.requestTimeout}, 0);\n`;
+        snippet += `Unirest.setTimeouts(0, ${options.requestTimeout});\n`;
+    }
+    else {
+        snippet += 'Unirest.setTimeouts(0, 0);\n';
     }
 
     if (options.followRedirect) {
@@ -46,11 +49,11 @@ function makeSnippet (request, indentString, options) {
 
 /**
  * Converts postman sdk request object into http snippet for java unirest
- * 
+ *
  * @param {Object} request - postman-SDK request object
  * @param {Object} options
  * @param {String} options.indentType - type for indentation eg: space, tab
- * @param {String} options.indentCount - number of spaces or tabs for indentation. 
+ * @param {String} options.indentCount - number of spaces or tabs for indentation.
  * @param {Boolean} [options.includeBoilerplate] - indicates whether to include class defination in java
  * @param {Boolean} options.followRedirect - whether to enable followredirect
  * @param {Boolean} options.trimRequestBody - whether to trim fields in request body or not
diff --git a/codegens/js-xhr/lib/index.js b/codegens/js-xhr/lib/index.js
index 3d77029..9a45393 100644
--- a/codegens/js-xhr/lib/index.js
+++ b/codegens/js-xhr/lib/index.js
@@ -182,6 +182,12 @@ function convert (request, options, callback) {
     codeSnippet += `${indent}}\n});\n\n`;
 
     codeSnippet += `xhr.open("${request.method}", "${encodeURI(request.url.toString())}");\n`;
+    if (options.requestTimeout) {
+        codeSnippet += `xhr.timeout = ${options.requestTimeout};\n`;
+        codeSnippet += 'xhr.addEventListener("ontimeout", function(e) {\n';
+        codeSnippet += `${indent} console.log(e);\n`;
+        codeSnippet += '});\n';
+    }
 
     headerSnippet = parseHeaders(request.getHeaders({enabled: true}));
 
diff --git a/codegens/libcurl/lib/index.js b/codegens/libcurl/lib/index.js
index 74ceef4..7b07240 100644
--- a/codegens/libcurl/lib/index.js
+++ b/codegens/libcurl/lib/index.js
@@ -17,11 +17,13 @@ module.exports = {
       formdataString = '',
       protocol,
       BOUNDARY = '----WebKitFormBoundary7MA4YWxkTrZu0gW',
-      responseCode;
+      responseCode,
+      timeout;
 
     multiLine = options.multiLine || _.isUndefined(options.multiLine);
     trim = options.trimRequestBody ? options.trimRequestBody : false;
     protocol = options.protocol ? options.protocol : 'https';
+    timeout = options.requestTimeout;
 
     if (multiLine) {
       newline = '\n';
@@ -36,6 +38,9 @@ module.exports = {
     snippet += newline + 'if(curl) {';
     snippet += indent + `curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "${request.method}");`;
     snippet += indent + `curl_easy_setopt(curl, CURLOPT_URL, "${encodeURI(request.url.toString())}");`;
+    if (timeout) {
+      snippet += indent + `curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, ${timeout}L);`;
+    }
     snippet += indent + `curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "${protocol}");`;
     snippet += indent + 'struct curl_slist *headers = NULL;';
     headersData = request.getHeaders({ enabled: true });
@@ -174,6 +179,13 @@ module.exports = {
         type: 'boolean',
         default: true,
         description: 'Use the mime format to send formdata requests'
+      },
+      {
+        name: 'Request Timeout',
+        id: 'requestTimeout',
+        type: 'integer',
+        default: 0,
+        description: 'Integer denoting time after which the request will bail out in milliseconds'
       }
     ];
   }
diff --git a/codegens/ruby/lib/ruby.js b/codegens/ruby/lib/ruby.js
index 7367a94..8fff441 100644
--- a/codegens/ruby/lib/ruby.js
+++ b/codegens/ruby/lib/ruby.js
@@ -107,8 +107,11 @@ module.exports = {
         }
         snippet += `url = URI("${sanitize(request.url.toString(), 'url')}")\n\n`;
         if (sanitize(request.url.toString(), 'url').startsWith('https')) {
-            snippet += 'https = Net::HTTP.new(url.host, url.port)\n';
+            snippet += 'https = Net::HTTP.new(url.host, url.port);\n';
             snippet += 'https.use_ssl = true\n\n';
+            if (options.requestTimeout) {
+                snippet += `https.read_timeout = ${Math.ceil(options.requestTimeout / 1000)}\n`;
+            }
             snippet += `request = Net::HTTP::${_.capitalize(request.method)}.new(url)\n`;
             headerSnippet = parseHeaders(request.getHeaders({enabled: true}));
             if (headerSnippet !== '') {
@@ -120,7 +123,10 @@ module.exports = {
             snippet += 'puts response.read_body\n';
         }
         else {
-            snippet += 'http = Net::HTTP.new(url.host, url.port)\n\n';
+            snippet += 'http = Net::HTTP.new(url.host, url.port);\n';
+            if (options.requestTimeout) {
+                snippet += `http.read_timeout = ${Math.ceil(options.requestTimeout / 1000)}\n`;
+            }
             snippet += `request = Net::HTTP::${_.capitalize(request.method)}.new(url)\n`;
             headerSnippet = parseHeaders(request.getHeaders({enabled: true}));
 
diff --git a/codegens/shell-httpie/lib/shell-httpie.js b/codegens/shell-httpie/lib/shell-httpie.js
index c796dbd..0e700d8 100644
--- a/codegens/shell-httpie/lib/shell-httpie.js
+++ b/codegens/shell-httpie/lib/shell-httpie.js
@@ -34,7 +34,12 @@ module.exports = {
       timeout,
       url = '',
       handleRedirect = (enableRedirect) => { if (!enableRedirect) { return GAP + '--follow' + GAP; } return GAP; },
-      handleRequestTimeout = (time) => { if (time) { return '--timeout ' + (time / 1000) + GAP; } return GAP; };
+      handleRequestTimeout = (time) => {
+        if (time) {
+          return '--timeout ' + (time / 1000) + GAP;
+        }
+        return '--timeout 3600' + GAP;
+      };
 
     // check whether options was passed or not
     if (_.isFunction(options)) {
diff --git a/codegens/shell-wget/lib/shell-wget.js b/codegens/shell-wget/lib/shell-wget.js
index c013f78..61ae0a8 100644
--- a/codegens/shell-wget/lib/shell-wget.js
+++ b/codegens/shell-wget/lib/shell-wget.js
@@ -114,6 +114,9 @@ module.exports = {
         if (options.requestTimeout > 0) {
             snippet += `${indentation}--timeout=${Math.floor(options.requestTimeout / 1000)} \\\n`;
         }
+        else {
+            snippet += `${indentation}--timeout=0 \\\n`;
+        }
         // Shell-wget supports 20 redirects by default (without any specific options)
         if (typeof options.followRedirect === 'boolean' && !options.followRedirect) {
             snippet += `${indentation}--max-redirect=0 \\\n`;
diff --git a/codegens/swift/lib/swift.js b/codegens/swift/lib/swift.js
index 31d9489..6f1f516 100644
--- a/codegens/swift/lib/swift.js
+++ b/codegens/swift/lib/swift.js
@@ -235,7 +235,8 @@ module.exports = {
         if (bodySnippet !== '') {
             codeSnippet += `${bodySnippet}\n\n`;
         }
-        codeSnippet += `var request = URLRequest(url: URL(string: "${finalUrl}")!, timeoutInterval: ${timeout})\n`;
+        codeSnippet += `var request = URLRequest(url: URL(string: "${finalUrl}")!,` +
+         `timeoutInterval: ${timeout ? timeout : 'Double.infinity'})\n`;
         headerSnippet = parseHeaders(request.getHeaders({ enabled: true }), (request.body ? request.body.mode : 'raw'));
         if (headerSnippet !== '') {
             codeSnippet += headerSnippet + '\n';


Test patch:
diff --git a/codegens/csharp-restsharp/test/unit/convert.test.js b/codegens/csharp-restsharp/test/unit/convert.test.js
index 1f6c3e6..c9533e3 100644
--- a/codegens/csharp-restsharp/test/unit/convert.test.js
+++ b/codegens/csharp-restsharp/test/unit/convert.test.js
@@ -157,9 +157,9 @@ describe('csharp restsharp function', function () {
                     options = {
                         indentCount: 1,
                         indentType: 'tab',
-                        requestTimeout: 2000,
                         followRedirect: true,
-                        trimRequestBody: true
+                        trimRequestBody: true,
+                        requestTimeout: 5000
                     };
                 convert(request, options, function (error, snippet) {
                     if (error) {
@@ -179,7 +179,6 @@ describe('csharp restsharp function', function () {
                 options = {
                     indentCount: 1,
                     indentType: 'tab',
-                    requestTimeout: 2000,
                     followRedirect: true,
                     trimRequestBody: true
                 };
@@ -230,6 +229,16 @@ describe('csharp restsharp function', function () {
             });
         });
 
+        it('should add client timeout configurations when requestTimeout is set to non zero value', function () {
+            convert(request, {requestTimeout: 5}, function (error, snippet) {
+                if (error) {
+                    expect.fail(null, null, error);
+                }
+                expect(snippet).to.be.a('string');
+                expect(snippet).to.include('client.Timeout = 5');
+            });
+        });
+
     });
 
     describe('getOptions function', function () {
diff --git a/codegens/csharp-restsharp/test/unit/fixtures/testresponse.json b/codegens/csharp-restsharp/test/unit/fixtures/testresponse.json
index 574a0a5..1e71bd2 100644
--- a/codegens/csharp-restsharp/test/unit/fixtures/testresponse.json
+++ b/codegens/csharp-restsharp/test/unit/fixtures/testresponse.json
@@ -1,3 +1,3 @@
 {
-  "result": "var client = new RestClient(\"https://postman-echo.com/post/?hardik=\\\"me\\\"\");\nvar request = new RestRequest(Method.POST);\nrequest.AddHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\nrequest.AddParameter(\"1\", \"a\");\nrequest.AddParameter(\"2\", \"b\");\nrequest.AddParameter(\"\\\"\\\"12\\\"\\\"\", \"\\\"23\\\"\");\nrequest.AddParameter(\"'1\\\"2\\\\\\\"\\\"3'\", \"'1\\\"23\\\"4'\");\nIRestResponse response = client.Execute(request);\nConsole.WriteLine(response.Content);"
+  "result": "var client = new RestClient(\"https://postman-echo.com/post/?hardik=\\\"me\\\"\");\nclient.Timeout = -1;\nvar request = new RestRequest(Method.POST);\nrequest.AddHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\nrequest.AddParameter(\"1\", \"a\");\nrequest.AddParameter(\"2\", \"b\");\nrequest.AddParameter(\"\\\"\\\"12\\\"\\\"\", \"\\\"23\\\"\");\nrequest.AddParameter(\"'1\\\"2\\\\\\\"\\\"3'\", \"'1\\\"23\\\"4'\");\nIRestResponse response = client.Execute(request);\nConsole.WriteLine(response.Content);"
 }
\ No newline at end of file
diff --git a/codegens/golang/test/unit/convert.test.js b/codegens/golang/test/unit/convert.test.js
index 223db23..b2b1d13 100644
--- a/codegens/golang/test/unit/convert.test.js
+++ b/codegens/golang/test/unit/convert.test.js
@@ -125,7 +125,7 @@ describe('Golang convert function', function () {
                     options = {
                         indentCount: 1,
                         indentType: 'tab',
-                        requestTimeout: 2000,
+                        requestTimeout: 5000,
                         followRedirect: true,
                         trimRequestBody: false
                     };
@@ -201,5 +201,30 @@ describe('Golang convert function', function () {
                 expect(snippet).to.include('req.Header.Add("foz", "W/\'qw\'")');
             });
         });
+
+        it('should add time converted to seconds when input is taken in milliseconds ', function () {
+            request = new sdk.Request({
+                'method': 'GET',
+                'header': [],
+                'url': {
+                    'raw': 'https://google.com',
+                    'protocol': 'https',
+                    'host': [
+                        'google',
+                        'com'
+                    ]
+                }
+            });
+            options = {
+                requestTimeout: 3
+            };
+            convert(request, options, function (error, snippet) {
+                if (error) {
+                    expect.fail(null, null, error);
+                }
+                expect(snippet).to.be.a('string');
+                expect(snippet).to.include('timeout := time.Duration(0.003 * time.Second)');
+            });
+        });
     });
 });
diff --git a/codegens/java-unirest/test/unit/convert.test.js b/codegens/java-unirest/test/unit/convert.test.js
index d35500f..815a165 100644
--- a/codegens/java-unirest/test/unit/convert.test.js
+++ b/codegens/java-unirest/test/unit/convert.test.js
@@ -12,7 +12,7 @@ var expect = require('chai').expect,
 
 /**
  * compiles and runs codesnippet then compare it with newman output
- * 
+ *
  * @param {String} codeSnippet - code snippet that needed to run using java
  * @param {Object} collection - collection which will be run using newman
  * @param {Function} done - callback for async calls
@@ -24,7 +24,7 @@ function runSnippet (codeSnippet, collection, done) {
             return done();
         }
 
-        //  classpath of external libararies for java to compile 
+        //  classpath of external libararies for java to compile
         var classpath = 'dependencies/*',
 
             //  bash command string for compiling java
@@ -205,7 +205,23 @@ describe('java unirest convert function for test collection', function () {
                     return;
                 }
                 expect(snippet).to.be.a('string');
-                expect(snippet).to.include('.setTimeouts(1000, 0)');
+                expect(snippet).to.include('.setTimeouts(0, 1000)');
+            });
+        });
+
+        it('should return snippet with setTimeouts function setting both ' +
+            'connection and socket timeout to 0 when requestTimeout is set to 0', function () {
+            request = new sdk.Request(mainCollection.item[0].request);
+            options = {
+                requestTimeout: 0
+            };
+            convert(request, options, function (error, snippet) {
+                if (error) {
+                    expect.fail(null, null, error);
+                    return;
+                }
+                expect(snippet).to.be.a('string');
+                expect(snippet).to.include('.setTimeouts(0, 0)');
             });
         });
 
diff --git a/codegens/js-xhr/test/unit/convert.test.js b/codegens/js-xhr/test/unit/convert.test.js
index ab3942c..3c41904 100644
--- a/codegens/js-xhr/test/unit/convert.test.js
+++ b/codegens/js-xhr/test/unit/convert.test.js
@@ -217,8 +217,8 @@ describe('js-xhr convert function', function () {
 
             request = new sdk.Request(req),
             options = {
-                indentCount: 3,
-                indentType: 'tab',
+                indentCount: 2,
+                indentType: 'space',
                 trimRequestBody: false,
                 requestTimeout: 3000
             };
@@ -236,6 +236,10 @@ describe('js-xhr convert function', function () {
                 expect(snippet).to.deep.include('var data = new FormData()');
                 expect(snippet).to.deep.include('data.append("sdf", "helo")');
             });
+
+            it('should add timeout option when timeout is set to non zero value', function () {
+                expect(snippet).to.include('xhr.timeout = 3000');
+            });
         });
     });
     describe('getOptions function', function () {
diff --git a/codegens/libcurl/test/unit/convert.test.js b/codegens/libcurl/test/unit/convert.test.js
index 7218225..f3bf7f4 100644
--- a/codegens/libcurl/test/unit/convert.test.js
+++ b/codegens/libcurl/test/unit/convert.test.js
@@ -192,6 +192,19 @@ describe('libcurl convert function', function () {
 
       expect(function () { convert(request, options, callback); }).to.throw(Error);
     });
+
+    it('should set CURLOPT_TIMEOUT_MS parameter when requestTimeout is set to non zero value', function () {
+      var request = new sdk.Request(mainCollection.item[0].request),
+        options = { requestTimeout: 3000 };
+
+      convert(request, options, function (error, snippet) {
+        if (error) {
+          expect.fail(null, null, error);
+        }
+        expect(snippet).to.be.a('string');
+        expect(snippet).to.include('curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 3000L);');
+      });
+    });
   });
 
   describe('getOptions function', function () {
diff --git a/codegens/nodejs-unirest/test/unit/snippet.test.js b/codegens/nodejs-unirest/test/unit/snippet.test.js
index 319575e..23dbfde 100644
--- a/codegens/nodejs-unirest/test/unit/snippet.test.js
+++ b/codegens/nodejs-unirest/test/unit/snippet.test.js
@@ -13,7 +13,7 @@ var expect = require('chai').expect,
 
 /**
  * compiles and runs codesnippet then compare it with newman output
- * 
+ *
  * @param {String} codeSnippet - code snippet that needed to run using java
  * @param {Object} collection - collection which will be run using newman
  * @param {Function} done - callback for async call from mocha
@@ -139,7 +139,6 @@ describe('nodejs unirest convert function', function () {
 
                 //  disabling eslint for test file
                 snippet = '/* eslint-disable */\n' + snippet;
-                console.log(snippet);
                 runSnippet(snippet, collection, done);
             });
         });
diff --git a/codegens/ruby/test/unit/converter.test.js b/codegens/ruby/test/unit/converter.test.js
index 11d1bc5..c7e0224 100644
--- a/codegens/ruby/test/unit/converter.test.js
+++ b/codegens/ruby/test/unit/converter.test.js
@@ -32,7 +32,7 @@ const propertiesTodelete = ['cookies', 'headersSize', 'startedDateTime', 'client
 
 /**
  * Executes codesnippet and compares output with newman response
- * 
+ *
  * @param {String} codeSnippet - code snippet from convert function
  * @param {Object} collection - sample collection
  * @param {Function} done - callback for async calls
@@ -135,7 +135,7 @@ describe('Ruby converter', function () {
                 };
             convert(request, {indentType: 'space',
                 indentCount: 4,
-                requestTimeout: 100,
+                requestTimeout: 1000,
                 trimRequestBody: false,
                 addCacheHeader: false,
                 followRedirect: true}, function (err, snippet) {
@@ -153,4 +153,27 @@ describe('Ruby converter', function () {
             .to.throw('Ruby~convert: Callback is not a function');
     });
 
+    it('should set read_timeout when requestTimeout is set to non zero value', function () {
+        var request = new sdk.Request({
+                'method': 'GET',
+                'header': [],
+                'url': {
+                    'raw': 'http://google.com',
+                    'protocol': 'http',
+                    'host': [
+                        'google',
+                        'com'
+                    ]
+                }
+            }),
+            options = {requestTimeout: 3000};
+        convert(request, options, function (error, snippet) {
+            if (error) {
+                expect.fail(null, null, error);
+            }
+            expect(snippet).to.be.a('string');
+            expect(snippet).to.include('http.read_timeout = 3');
+        });
+    });
+
 });
diff --git a/codegens/shell-httpie/test/unit/converter.test.js b/codegens/shell-httpie/test/unit/converter.test.js
index a51e548..9288d99 100644
--- a/codegens/shell-httpie/test/unit/converter.test.js
+++ b/codegens/shell-httpie/test/unit/converter.test.js
@@ -144,6 +144,31 @@ describe('Shell-Httpie convert function', function () {
       }
     });
   });
+
+  it('should add a timeout of 1 hour (3600 seconds) for RequestTimeout set to 0', function () {
+    var request = new sdk.Request({
+        'method': 'GET',
+        'header': [],
+        'url': {
+          'raw': 'https://google.com',
+          'protocol': 'https',
+          'host': [
+            'google',
+            'com'
+          ]
+        }
+      }),
+      options = {
+        requestTimeout: 0
+      };
+    convert(request, options, function (error, snippet) {
+      if (error) {
+        expect.fail(null, null, error);
+      }
+      expect(snippet).to.be.a('string');
+      expect(snippet).to.include('--timeout 3600');
+    });
+  });
 });
 
 describe('Sanitize function', function () {
diff --git a/codegens/shell-wget/test/unit/converter.test.js b/codegens/shell-wget/test/unit/converter.test.js
index 089312f..54c603f 100644
--- a/codegens/shell-wget/test/unit/converter.test.js
+++ b/codegens/shell-wget/test/unit/converter.test.js
@@ -32,7 +32,7 @@ const propertiesTodelete = ['cookies', 'headersSize', 'startedDateTime', 'json',
 
 /**
  * Executes codesnippet and compares output with newman response
- * 
+ *
  * @param {String} codeSnippet - code snippet from convert function
  * @param {Object} collection - sample collection
  * @param {Function} done - callback for async calls
@@ -202,6 +202,16 @@ describe('Shell-Wget converter', function () {
                 }
             });
         });
+
+        it('should generate snippet with timout flag set as 0 (infinite) when requestTimeout is set as 0', function () {
+            convert(request, {requestTimeout: 0}, function (error, snippet) {
+                if (error) {
+                    expect.fail(null, null, error);
+                }
+                expect(snippet).to.be.a('string');
+                expect(snippet).to.include('--timeout=0');
+            });
+        });
     });
 
     describe('getOptions function', function () {
diff --git a/codegens/swift/test/unit/convert.test.js b/codegens/swift/test/unit/convert.test.js
index b6dd7ee..2fae6e5 100644
--- a/codegens/swift/test/unit/convert.test.js
+++ b/codegens/swift/test/unit/convert.test.js
@@ -179,6 +179,17 @@ describe('Swift Converter', function () {
                 }
             });
         });
+
+        it('should add infinite timeout when requestTimeout is set to 0', function () {
+            convert(request, { requestTimeout: 0}, function (error, snippet) {
+                if (error) {
+                    expect.fail(null, null, error);
+                }
+                expect(snippet).to.be.a('string');
+                expect(snippet).to.include('timeoutInterval: Double.infinity');
+
+            });
+        });
     });
 
     describe('getOptions function', function () {