[Pkg-javascript-commits] [sockjs-client] 204/434: #29 - Add custom utils.quote and new test infrastructure for that

Tonnerre Lombard tonnerre-guest at moszumanska.debian.org
Wed Jan 8 00:47:14 UTC 2014


This is an automated email from the git hooks/post-receive script.

tonnerre-guest pushed a commit to branch master
in repository sockjs-client.

commit def2b1500e2a7d9fc323f879e535aa98756f5bef
Author: Marek Majkowski <majek04 at gmail.com>
Date:   Thu Nov 24 17:47:33 2011 +0000

    #29 - Add custom utils.quote and new test infrastructure for that
    
    utils.quote is a code based on Douglas Crockford JSON2.js string quoting code. With a significant difference - we also escale 756 other characters that are proven to cause problems.
    
    Additionally 2048 unicode surrogates must are encoded.
---
 Makefile                        |  6 ++-
 lib/index.js                    |  1 +
 lib/test-hooks.js               |  4 ++
 lib/utils.js                    | 93 ++++++++++++++++++++++++++++++++++++++++-
 tests/html/src/unittests.coffee | 76 +++++++++++++++++++++++++++++++++
 tests/html/unittests.html       | 42 +++++++++++++++++++
 6 files changed, 220 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 92282dd..7cbc2e2 100644
--- a/Makefile
+++ b/Makefile
@@ -23,8 +23,12 @@ tests/html/lib/tests.js: tests/html/src/tests.coffee
 	@coffee -v > /dev/null
 	coffee -o tests/html/lib/ -c --bare $<
 
+tests/html/lib/unittests.js: tests/html/src/unittests.coffee
+	@coffee -v > /dev/null
+	coffee -o tests/html/lib/ -c --bare $<
+
 test: tests
-tests: tests/html/lib/sockjs.js tests/html/lib/tests.js
+tests: tests/html/lib/sockjs.js tests/html/lib/tests.js tests/html/lib/unittests.js
 	node tests/server.js
 
 
diff --git a/lib/index.js b/lib/index.js
index 11a6003..88b5c9f 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -22,6 +22,7 @@ SockJS = (function(){
 <!-- include lib/trans-receiver-eventsource.js -->
 <!-- include lib/trans-receiver-htmlfile.js -->
 <!-- include lib/trans-receiver-xhr.js -->
+<!-- include lib/test-hooks.js -->
                   return SockJS;
           })();
 if ('_sockjs_onload' in window) setTimeout(_sockjs_onload, 1);
diff --git a/lib/test-hooks.js b/lib/test-hooks.js
new file mode 100644
index 0000000..f5820c6
--- /dev/null
+++ b/lib/test-hooks.js
@@ -0,0 +1,4 @@
+// For testing
+SockJS.getUtils = function(){
+    return utils;
+};
diff --git a/lib/utils.js b/lib/utils.js
index 00442e1..a10925c 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -353,4 +353,95 @@ utils.delay = function(t, fun) {
         t = 0;
     }
     return setTimeout(fun, t);
-};
\ No newline at end of file
+};
+
+
+// Chars worth escaping, as defined by Douglas Crockford:
+//   https://github.com/douglascrockford/JSON-js/blob/47a9882cddeb1e8529e07af9736218075372b8ac/json2.js#L196
+var json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+    json_unrolled_meta = {
+"\u0000":"\\u0000","\u0001":"\\u0001","\u0002":"\\u0002","\u0003":"\\u0003",
+"\u0004":"\\u0004","\u0005":"\\u0005","\u0006":"\\u0006","\u0007":"\\u0007",
+"\b":"\\b","\t":"\\t","\n":"\\n","\u000b":"\\u000b","\f":"\\f","\r":"\\r",
+"\u000e":"\\u000e","\u000f":"\\u000f","\u0010":"\\u0010","\u0011":"\\u0011",
+"\u0012":"\\u0012","\u0013":"\\u0013","\u0014":"\\u0014","\u0015":"\\u0015",
+"\u0016":"\\u0016","\u0017":"\\u0017","\u0018":"\\u0018","\u0019":"\\u0019",
+"\u001a":"\\u001a","\u001b":"\\u001b","\u001c":"\\u001c","\u001d":"\\u001d",
+"\u001e":"\\u001e","\u001f":"\\u001f","\"":"\\\"","\\":"\\\\",
+"\u007f":"\\u007f","\u0080":"\\u0080","\u0081":"\\u0081","\u0082":"\\u0082",
+"\u0083":"\\u0083","\u0084":"\\u0084","\u0085":"\\u0085","\u0086":"\\u0086",
+"\u0087":"\\u0087","\u0088":"\\u0088","\u0089":"\\u0089","\u008a":"\\u008a",
+"\u008b":"\\u008b","\u008c":"\\u008c","\u008d":"\\u008d","\u008e":"\\u008e",
+"\u008f":"\\u008f","\u0090":"\\u0090","\u0091":"\\u0091","\u0092":"\\u0092",
+"\u0093":"\\u0093","\u0094":"\\u0094","\u0095":"\\u0095","\u0096":"\\u0096",
+"\u0097":"\\u0097","\u0098":"\\u0098","\u0099":"\\u0099","\u009a":"\\u009a",
+"\u009b":"\\u009b","\u009c":"\\u009c","\u009d":"\\u009d","\u009e":"\\u009e",
+"\u009f":"\\u009f","\u00ad":"\\u00ad","\u0600":"\\u0600","\u0601":"\\u0601",
+"\u0602":"\\u0602","\u0603":"\\u0603","\u0604":"\\u0604","\u070f":"\\u070f",
+"\u17b4":"\\u17b4","\u17b5":"\\u17b5","\u200c":"\\u200c","\u200d":"\\u200d",
+"\u200e":"\\u200e","\u200f":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029",
+"\u202a":"\\u202a","\u202b":"\\u202b","\u202c":"\\u202c","\u202d":"\\u202d",
+"\u202e":"\\u202e","\u202f":"\\u202f","\u2060":"\\u2060","\u2061":"\\u2061",
+"\u2062":"\\u2062","\u2063":"\\u2063","\u2064":"\\u2064","\u2065":"\\u2065",
+"\u2066":"\\u2066","\u2067":"\\u2067","\u2068":"\\u2068","\u2069":"\\u2069",
+"\u206a":"\\u206a","\u206b":"\\u206b","\u206c":"\\u206c","\u206d":"\\u206d",
+"\u206e":"\\u206e","\u206f":"\\u206f","\ufeff":"\\ufeff","\ufff0":"\\ufff0",
+"\ufff1":"\\ufff1","\ufff2":"\\ufff2","\ufff3":"\\ufff3","\ufff4":"\\ufff4",
+"\ufff5":"\\ufff5","\ufff6":"\\ufff6","\ufff7":"\\ufff7","\ufff8":"\\ufff8",
+"\ufff9":"\\ufff9","\ufffa":"\\ufffa","\ufffb":"\\ufffb","\ufffc":"\\ufffc",
+"\ufffd":"\\ufffd","\ufffe":"\\ufffe","\uffff":"\\uffff"};
+
+// Some extra characters that Chrome gets wrong, and substitutes with
+// something else on the wire.
+var extra_escapable = /[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0 [...]
+    extra_unrolled_meta;
+
+// JSON Quote string. Use native implementation when possible.
+var JSONQuote = (JSON && JSON.stringify) || function(string) {
+    json_escapable.lastIndex = 0;
+    if (json_escapable.test(string)) {
+        string = string.replace(json_escapable, function(a) {
+            return json_unrolled_meta[a];
+        });
+    }
+    return '"' + string + '"';
+};
+
+// This may be quite slow, so let's delay until user actually uses bad
+// characters.
+var unroll_meta = function(escapable) {
+    var i;
+    var unrolled = {}
+    var c = []
+    for(i=0; i<65536; i++) {
+        c.push( String.fromCharCode(i) );
+    }
+    escapable.lastIndex = 0;
+    c.join('').replace(escapable, function (a) {
+        unrolled[ a ] = '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+        return '';
+    });
+    escapable.lastIndex = 0;
+    return unrolled;
+};
+
+// Quote string, also taking care of unicode characters that browsers
+// often break. Especially, take care of unicode surrogates:
+//    http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates
+utils.quote = function(string) {
+    var quoted = JSONQuote(string);
+
+    // In most cases this is enough.
+    extra_escapable.lastIndex = 0;
+    if(!extra_escapable.test(quoted)) {
+        return quoted;
+    }
+
+    if(!extra_unrolled_meta) extra_unrolled_meta = unroll_meta(extra_escapable);
+
+    return quoted.replace(extra_escapable, function(a) {
+        return extra_unrolled_meta[a];
+    });
+}
+
+
diff --git a/tests/html/src/unittests.coffee b/tests/html/src/unittests.coffee
new file mode 100644
index 0000000..147e0d4
--- /dev/null
+++ b/tests/html/src/unittests.coffee
@@ -0,0 +1,76 @@
+module('Utils')
+
+u = SockJS.getUtils()
+
+test 'random_string', ->
+    notEqual(u.random_string(8), u.random_string(8))
+    for i in [1,2,3,128]
+        equal(u.random_string(i).length, i)
+    equal(u.random_string(4, 1), 'aaaa')
+
+test 'random_number_string', ->
+    for i in [0..10]
+        equal(u.random_number_string(10).length, 1)
+        equal(u.random_number_string(100).length, 2)
+        equal(u.random_number_string(1000).length, 3)
+        equal(u.random_number_string(10000).length, 4)
+        equal(u.random_number_string(100000).length, 5)
+
+test 'getOrigin', ->
+    equal(u.getOrigin('http://a.b/'), 'http://a.b')
+    equal(u.getOrigin('http://a.b/c'), 'http://a.b')
+    equal(u.getOrigin('http://a.b:123/c'), 'http://a.b:123')
+
+test 'objectExtend', ->
+    deepEqual(u.objectExtend({}, {}), {})
+    a = {a:1};
+    equal(u.objectExtend(a, {}), a)
+    equal(u.objectExtend(a, {b:1}), a)
+    a = {a:1}; b = {b:2}
+    deepEqual(u.objectExtend(a, b), {a:1, b:2})
+    deepEqual(a, {a:1, b:2})
+    deepEqual(b, {b:2})
+
+test 'bind', ->
+    o = {}
+    fun = ->
+        return this
+    deepEqual(fun(), window)
+    bound_fun = u.bind(fun, o)
+    deepEqual(bound_fun(), o)
+
+test 'amendUrl', ->
+    dl = document.location
+
+    equal(u.amendUrl('//blah:1/abc'), dl.protocol + '//blah:1/abc')
+    equal(u.amendUrl('/abc'), dl.protocol + '//' + dl.host + '/abc')
+    equal(u.amendUrl('http://a:1/abc'), 'http://a:1/abc')
+    equal(u.amendUrl('http://a:1/abc/'), 'http://a:1/abc')
+    equal(u.amendUrl('http://a:1/abc//'), 'http://a:1/abc')
+    t = -> u.amendUrl('')
+    raises(t, 'Wrong url')
+    t = -> u.amendUrl(false)
+    raises(t, 'Wrong url')
+
+test 'arrIndexOf', ->
+    a = [1,2,3,4,5]
+    equal(u.arrIndexOf(a, 1), 0)
+    equal(u.arrIndexOf(a, 5), 4)
+    equal(u.arrIndexOf(a, null), -1)
+    equal(u.arrIndexOf(a, 6), -1)
+
+test 'quote', ->
+    equal(u.quote(''), '""');
+    equal(u.quote('a'), '"a"');
+    equal(u.quote('\t'), '"\\t"')
+    equal(u.quote('\n'), '"\\n"')
+    equal(u.quote('\x00\udfff\ufffe\uffff'), '"\\u0000\\udfff\\ufffe\\uffff"')
+    # Unicode surrogates, formally incorrect unicode datapoints:
+    equal(u.quote('\ud85c\udff7\ud800\ud8ff'), '"\\ud85c\\udff7\\ud800\\ud8ff"')
+    equal(u.quote('\u2000\u2001\u0300\u0301'), '"\\u2000\\u2001\\u0300\\u0301"')
+
+    # And a sanity check.
+    c = for i in [0..65535]
+            String.fromCharCode(i)
+    all_chars = c.join('')
+    ok(JSON.parse(u.quote(all_chars)) is all_chars, "Quote/unquote all 64K chars.")
diff --git a/tests/html/unittests.html b/tests/html/unittests.html
new file mode 100644
index 0000000..6c4d197
--- /dev/null
+++ b/tests/html/unittests.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+  <meta charset="UTF-8" />
+
+  <script type="text/javascript" src="lib/sockjs.js"></script>
+
+  <script type="text/javascript" src="static/jquery.min.js"></script>
+
+  <link rel="stylesheet" href="static/qunit.css" type="text/css" media="screen">
+  <script type="text/javascript" src="static/qunit.min.js"></script>
+
+  <script type="text/javascript" src="config.js"></script>
+  <script type="text/javascript" src="lib/unittests.js"></script>
+</head>
+<body>
+  <p>
+    <h1 id="qunit-header">SockJS Unit Tests</h1>
+    <h2 id="qunit-banner"></h2>
+    <div id="qunit-testrunner-toolbar"></div>
+    <h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests"></ol>
+    <div id="qunit-fixture">test markup</div>
+    </p>
+  <br>
+  <code id="logs" style="height:200px; overflow:auto; display: block; border: 1px grey solid;">
+  </code>
+
+<script>
+    function log(a, e) {
+            if ('console' in window && 'log' in window.console) {
+                console.log(a, e);
+            }
+            $('#logs').append($("<code>").text(a));
+            $('#logs').append($("<pre>").text(JSON.stringify(e, null, 4)));
+            $('#logs').append($("<br>"));
+            $('#logs').scrollTop($('#logs').scrollTop()+10000);
+      }
+</script>
+</body>
+</html>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/sockjs-client.git



More information about the Pkg-javascript-commits mailing list