diff --git a/package.json b/package.json index e85f354c..fef8af7a 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "url": "git://github.com/remy/jsbin.git" }, "scripts": { - "test": "./node_modules/mocha/bin/mocha" + "test": "mocha" }, "dependencies": { "express": "3.0.x", diff --git a/public/js/render/render.js b/public/js/render/render.js index 5aa8855b..77b15598 100644 --- a/public/js/render/render.js +++ b/public/js/render/render.js @@ -1,202 +1,174 @@ -var consoleTest = /(^.|\b)console\./; +var getPreparedCode = (function () { -var iframedelay = (function () { - var iframedelay = { active : false }, - iframe = document.createElement('iframe'), - doc, - callbackName = '__callback' + (+new Date); + var consoleTest = /(^.|\b)console\./, + re = { + docReady: /\$\(document\)\.ready/, + shortDocReady: /\$\(function/, + console: /(^.|\b)console\.(\S+)/g, + script: /<\/script/ig, + code: /%code%/, + title: /(.*)<\/title>/i, + winLoad: /window\.onload\s*=/, + scriptopen: /<script/gi + }; - iframe.style.height = iframe.style.width = '1px'; - iframe.style.visibility = 'hidden'; - document.body.appendChild(iframe); - doc = iframe.contentDocument || iframe.contentWindow.document; - - window[callbackName] = function (width) { - iframedelay.active = width === 0; - try { - iframe.parentNode.removeChild(iframe); - delete window[callbackName]; - } catch (e){} + var two = function (i) { + return ('0'+i).slice(-2); }; - try { - doc.open(); - doc.write('<script>window.parent.' + callbackName + '(window.innerWidth)</script>'); - doc.close(); - } catch (e) { - iframedelay.active = true; - } + return function (nojs) { + // reset all the regexp positions for reuse + re.docReady.lastIndex = 0; + re.shortDocReady.lastIndex = 0; + re.console.lastIndex = 0; + re.script.lastIndex = 0; + re.code.lastIndex = 0; + re.title.lastIndex = 0; + re.winLoad.lastIndex = 0; + re.scriptopen.lastIndex = 0; - return iframedelay; -}()); + var parts = [], + source = '', + js = '', + css = '', + close = '', + hasHTML = false, + hasCSS = false, + hasJS = false, + date = new Date(), + scriptOffset = 0; -var re = null; - -function two(i) { - return ('0'+i).slice(-2); -} - -function getPreparedCode(nojs) { - // init the regular expression cache because this function - // is called much earlier than the above code is actually encountered - // yay for massive .js app! - if (!re) { - re = { - docReady: /\$\(document\)\.ready/, - shortDocReady: /\$\(function/, - console: /(^.|\b)console\.(\S+)/g, - script: /<\/script/ig, - code: /%code%/, - title: /<title>(.*)<\/title>/i, - winLoad: /window\.onload\s*=/, - scriptopen: /<script/gi - }; - } - - // reset all the regexp positions for reuse - re.docReady.lastIndex = 0; - re.shortDocReady.lastIndex = 0; - re.console.lastIndex = 0; - re.script.lastIndex = 0; - re.code.lastIndex = 0; - re.title.lastIndex = 0; - re.winLoad.lastIndex = 0; - re.scriptopen.lastIndex = 0; - - var parts = [], - source = '', - js = '', - css = '', - close = '', - hasHTML = false, - hasCSS = false, - hasJS = false, - date = new Date(), - scriptOffset = 0; - - try { - source = editors.html.render(); - } catch (e) { - window.console && window.console.error(e.message); - } - - hasHTML = !!$.trim(source); - - if (!nojs) { try { - js = editors.javascript.render(); - - if (js.trim()) js += '\n\n// created @ ' + two(date.getHours()) + ':' + two(date.getMinutes()) + ':' + two(date.getSeconds()); + source = editors.html.render(); } catch (e) { window.console && window.console.error(e.message); } - } - hasJS = !!js.trim(); + hasHTML = !!$.trim(source); - try { - css = editors.css.render(); - } catch (e) { - window.console && window.console.error(e.message); - } + if (!nojs) { + try { + js = editors.javascript.render(); - hasCSS = !!$.trim(css); - - // escape any script tags in the JS code, because that'll break the mushing together - js = js.replace(re.script, '<\\/script'); - - // note that I'm using split and reconcat instead of replace, because if the js var - // contains '$$' it's replaced to '$' - thus breaking Prototype code. This method - // gets around the problem. - if (!hasHTML && hasJS) { - source = "<pre>\n" + js.replace(/[<>&]/g, function (m) { - if (m == '<') return '<'; - if (m == '>') return '>'; - if (m == '"') return '"'; - }) + "</pre>"; - } else if (re.code.test(source)) { - parts = source.split('%code%'); - source = parts[0] + js + parts[1]; - scriptOffset = parts[0].split('\n').length; - } else if (hasJS) { - close = ''; - if (source.indexOf('</body>') !== -1) { - parts.push(source.substring(0, source.lastIndexOf('</body>'))); - parts.push(source.substring(source.lastIndexOf('</body>'))); - - source = parts[0]; - close = parts.length == 2 && parts[1] ? parts[1] : ''; + if (js.trim()) js += '\n\n// created @ ' + two(date.getHours()) + ':' + two(date.getMinutes()) + ':' + two(date.getSeconds()); + } catch (e) { + window.console && window.console.error(e.message); + } } - // RS: not sure why I ran this in closure, but it means the expected globals are no longer so - // js = "window.onload = function(){" + js + "\n}\n"; - var type = jsbin.panels.panels.javascript.type ? ' type="text/' + jsbin.panels.panels.javascript.type + '"' : ''; + hasJS = !!js.trim(); - scriptOffset = source.split('\n').length - 1; - source += "<script" + type + ">\n" + js + "\n</script>\n" + close; - } - - // redirect console logged to our custom log while debugging - if (re.console.test(source)) { - var replaceWith = 'window.runnerWindow.proxyconsole.'; - // yes, this code looks stupid, but in fact what it does is look for - // 'console.' and then checks the position of the code. If it's inside - // an openning script tag, it'll change it to window.top._console, - // otherwise it'll leave it. - source = source.replace(re.console, function (all, str, arg, pos) { - var open = source.lastIndexOf('<script', pos), - close = source.lastIndexOf('</script', pos); - - if (open > close) { - return replaceWith + arg; - } else { - return all; - } - }); - } - - if (!hasHTML && !hasJS && hasCSS) { - source = "<pre>\n" + css + "</pre>"; - } else if (css && hasHTML) { - parts = []; - close = ''; - if (source.indexOf('</head>') !== -1) { - parts.push(source.substring(0, source.lastIndexOf('</head>'))); - parts.push(source.substring(source.lastIndexOf('</head>'))); - - source = parts[0]; - close = parts.length == 2 && parts[1] ? parts[1] : ''; + try { + css = editors.css.render(); + } catch (e) { + window.console && window.console.error(e.message); } - source += '<style>\n' + css + '\n</style>\n' + close; - scriptOffset += (2 + css.split('\n').length); - } - // specific change for rendering $(document).ready() because iframes doesn't trigger ready (TODO - really test in IE, may have been fixed...) - // if (re.docReady.test(source)) { - // source = source.replace(re.docReady, 'window.onload = '); - // } else if (re.shortDocReady.test(source)) { - // source = source.replace(re.shortDocReady, 'window.onload = (function'); - // } + hasCSS = !!$.trim(css); - // Add defer to all inline script tags in IE. - // This is because IE runs scripts as it loads them, so variables that scripts like jQuery add to the - // global scope are undefined. See http://jsbin.com/ijapom/5 - if (jsbin.ie && re.scriptopen.test(source)) { - source = source.replace(/<script(.*?)>/gi, function (all, match) { - if (match.indexOf('src') !== -1) { - return all; - } else { - return '<script defer' + match + '>'; + // Rewrite loops to detect infiniteness. + // This is done by rewriting the for/while/do loops to perform a check at + // the start of each iteration. + js = loopProtect.rewriteLoops(js); + + // escape any script tags in the JS code, because that'll break the mushing together + js = js.replace(re.script, '<\\/script'); + + // note that I'm using split and reconcat instead of replace, because if the js var + // contains '$$' it's replaced to '$' - thus breaking Prototype code. This method + // gets around the problem. + if (!hasHTML && hasJS) { + source = "<pre>\n" + js.replace(/[<>&]/g, function (m) { + if (m == '<') return '<'; + if (m == '>') return '>'; + if (m == '"') return '"'; + }) + "</pre>"; + } else if (re.code.test(source)) { + parts = source.split('%code%'); + source = parts[0] + js + parts[1]; + scriptOffset = parts[0].split('\n').length; + } else if (hasJS) { + close = ''; + if (source.indexOf('</body>') !== -1) { + parts.push(source.substring(0, source.lastIndexOf('</body>'))); + parts.push(source.substring(source.lastIndexOf('</body>'))); + + source = parts[0]; + close = parts.length == 2 && parts[1] ? parts[1] : ''; } - }); + + // RS: not sure why I ran this in closure, but it means the expected globals are no longer so + // js = "window.onload = function(){" + js + "\n}\n"; + var type = jsbin.panels.panels.javascript.type ? ' type="text/' + jsbin.panels.panels.javascript.type + '"' : ''; + + scriptOffset = source.split('\n').length - 1; + source += "<script" + type + ">\n" + js + "\n</script>\n" + close; + } + + // redirect console logged to our custom log while debugging + if (re.console.test(source)) { + var replaceWith = 'window.runnerWindow.proxyConsole.'; + // yes, this code looks stupid, but in fact what it does is look for + // 'console.' and then checks the position of the code. If it's inside + // an openning script tag, it'll change it to window.top._console, + // otherwise it'll leave it. + source = source.replace(re.console, function (all, str, arg, pos) { + var open = source.lastIndexOf('<script', pos), + close = source.lastIndexOf('</script', pos); + + if (open > close) { + return replaceWith + arg; + } else { + return all; + } + }); + } + + if (!hasHTML && !hasJS && hasCSS) { + source = "<pre>\n" + css + "</pre>"; + } else if (css && hasHTML) { + parts = []; + close = ''; + if (source.indexOf('</head>') !== -1) { + parts.push(source.substring(0, source.lastIndexOf('</head>'))); + parts.push(source.substring(source.lastIndexOf('</head>'))); + + source = parts[0]; + close = parts.length == 2 && parts[1] ? parts[1] : ''; + } + source += '<style>\n' + css + '\n</style>\n' + close; + scriptOffset += (2 + css.split('\n').length); + } + + // specific change for rendering $(document).ready() because iframes doesn't trigger ready (TODO - really test in IE, may have been fixed...) + // if (re.docReady.test(source)) { + // source = source.replace(re.docReady, 'window.onload = '); + // } else if (re.shortDocReady.test(source)) { + // source = source.replace(re.shortDocReady, 'window.onload = (function'); + // } + + // Add defer to all inline script tags in IE. + // This is because IE runs scripts as it loads them, so variables that + // scripts like jQuery add to the global scope are undefined. + // See http://jsbin.com/ijapom/5 + if (jsbin.ie && re.scriptopen.test(source)) { + source = source.replace(/<script(.*?)>/gi, function (all, match) { + if (match.indexOf('src') !== -1) { + return all; + } else { + return '<script defer' + match + '>'; + } + }); + } + + // read the element out of the source code and plug it in to our document.title + var newDocTitle = source.match(re.title); + if (newDocTitle !== null && newDocTitle[1] !== documentTitle) { + documentTitle = newDocTitle[1]; + document.title = documentTitle + ' - ' + 'JS Bin'; + } + + return { source: source, scriptOffset: scriptOffset }; } - // read the element out of the source code and plug it in to our document.title - var newDocTitle = source.match(re.title); - if (newDocTitle !== null && newDocTitle[1] !== documentTitle) { - documentTitle = newDocTitle[1]; - document.title = documentTitle + ' - ' + 'JS Bin'; - } - - return { source: source, scriptOffset: scriptOffset }; -} +}()); diff --git a/public/js/runner/loop-protect.js b/public/js/runner/loop-protect.js new file mode 100644 index 00000000..7d2c5f4e --- /dev/null +++ b/public/js/runner/loop-protect.js @@ -0,0 +1,92 @@ +/** + * Protect against infinite loops. + * Look for for, while and do loops, and insert a check function at the start of + * the loop. If the check function is called many many times then it returns + * true, preventing the loop from running again. + */ +var loopProtect = (function () { + + var loopProtect = {}; + + // used in the loop detection + loopProtect.counters = {}; + + /** + * Look for for, while and do loops, and inserts *just* at the start of the + * loop, a check function. + */ + loopProtect.rewriteLoops = function (code, offset) { + var recompiled = [], + lines = code.split('\n'), + re = /for\b|while\b|do\b/; + + if (!offset) offset = 0; + + var method = 'window.runnerWindow.protect'; + + lines.forEach(function (line, i) { + var index = 0, + lineNum = i - offset; + + if (re.test(line) && line.indexOf('jsbin') === -1) { + // try to insert the tracker after the openning brace (like while (true) { ^here^ ) + index = line.indexOf('{'); + if (index !== -1) { + line = line.substring(0, index + 1) + ';\nif (' + method + '({ line: ' + lineNum + ' })) break;'; + } else { + index = line.indexOf(')'); + if (index !== -1) { + // look for a one liner + var colonIndex = line.substring(index).indexOf(';'); + if (colonIndex !== -1) { + // in which case, rewrite the loop to add braces + colonIndex += index; + line = line.substring(0, index + 1) + '{\nif (' + method + '({ line: ' + lineNum + ' })) break;\n' + line.substring(index + 1) + '\n}\n'; // extra new lines ensure we clear comment lines + } + } + } + + line = ';' + method + '({ line: ' + lineNum + ', reset: true });\n' + line; + loopProtect.counters[lineNum] = {}; + } + recompiled.push(line); + }); + + return recompiled.join('\n'); + }; + + /** + * Injected code in to user's code to **try** to protect against infinite + * loops cropping up in the code, and killing the browser. Returns true + * when the loops has been running for more than 100ms. + */ + loopProtect.protect = function (state) { + loopProtect.counters[state.line] = loopProtect.counters[state.line] || {}; + var line = loopProtect.counters[state.line]; + if (state.reset) { + line.time = +new Date; + } + if ((+new Date - line.time) > 100) { + // We've spent over 100ms on this loop... smells infinite. + var msg = "Suspicious loop detected at line " + state.line; + if (window.proxyConsole) { + window.proxyConsole.error(msg); + } else console.error(msg); + // Returning true prevents the loop running again + return true; + } + return false; + }; + + loopProtect.reset = function () { + // reset the counters + loopProtect.counters = {}; + }; + + return loopProtect; + +}()); + +if (typeof exports !== 'undefined') { + module.exports = loopProtect; +} diff --git a/public/js/runner/processor.js b/public/js/runner/processor.js index bad6e676..60252901 100644 --- a/public/js/runner/processor.js +++ b/public/js/runner/processor.js @@ -42,78 +42,6 @@ var processor = (function () { }) + '</pre>'; }; - // used in the loop detection - processor.counters = {}; - - /** - * Look for for, while and do loops, and inserts *just* at the start - * of the loop, a check function. If the check function is called - * many many times, then it throws an exception suspecting this might - * be an infinite loop. - */ - processor.rewriteLoops = function (code, offset) { - var recompiled = [], - lines = code.split('\n'), - re = /for\b|while\b|do\b/; - - if (!offset) offset = 0; - - // reset the counters - processor.counters = {}; - - var counter = 'window.runnerWindow.protect'; - - lines.forEach(function (line, i) { - var index = 0, - lineNum = i - offset; - - if (re.test(line) && line.indexOf('jsbin') === -1) { - // try to insert the tracker after the openning brace (like while (true) { ^here^ ) - index = line.indexOf('{'); - if (index !== -1) { - line = line.substring(0, index + 1) + ';\nif (' + counter + '({ line: ' + lineNum + ' })) break;'; - } else { - index = line.indexOf(')'); - if (index !== -1) { - // look for a one liner - var colonIndex = line.substring(index).indexOf(';'); - if (colonIndex !== -1) { - // in which case, rewrite the loop to add braces - colonIndex += index; - line = line.substring(0, index + 1) + '{\nif (' + counter + '({ line: ' + lineNum + ' })) break;\n' + line.substring(index + 1) + '\n}\n'; // extra new lines ensure we clear comment lines - } - } - } - - line = ';' + counter + '({ line: ' + lineNum + ', reset: true });\n' + line; - processor.counters[lineNum] = {}; - } - recompiled.push(line); - }); - - return recompiled.join('\n'); - }; - - /** - * Injected code in to user's code to **try** to protect against infinite loops - * cropping up in the code, and killing the browser. This will throw an exception - * when a loop has hit over X number of times. - */ - processor.protect = function (state) { - var line = processor.counters[state.line]; - if (state.reset) { - line.count = 0; - } else { - line.count++; - if (line.count > 100000) { - // we've done a ton of loops, then let's say it smells like an infinite loop - console.error("Suspicious loop detected at line " + state.line); - return true; - } - } - return false; - }; - /** * Render – build the final source code to be written to the iframe. Takes * the original source and an options object. @@ -123,7 +51,6 @@ var processor = (function () { options = options || []; source = source || ''; - var combinedSource = [], realtime = (options.requested !== true), noRealtimeJs = (options.includeJsInRealtime === false); @@ -138,13 +65,6 @@ var processor = (function () { // the editable area. source = source.replace(/(<.*?\s)(autofocus)/g, '$1'); - - // since we're running in real time, let's try hook in some loop protection - // basically if a loop runs for many, many times, it's probably an infinite loop - // so we'll throw an exception. This is done by rewriting the for/while/do - // loops to call our check at the start of each. - source = processor.rewriteLoops(source, options.scriptOffset); - // Make sure the doctype is the first thing in the source var doctypeObj = processor.getDoctype(source), doctype = doctypeObj.doctype; diff --git a/public/js/runner/proxyconsole.js b/public/js/runner/proxy-console.js similarity index 86% rename from public/js/runner/proxyconsole.js rename to public/js/runner/proxy-console.js index b6eefbe4..3812942d 100644 --- a/public/js/runner/proxyconsole.js +++ b/public/js/runner/proxy-console.js @@ -3,17 +3,17 @@ * Proxy console.logs out to the parent window * ========================================================================== */ -var proxyconsole = (function () { +var proxyConsole = (function () { var supportsConsole = true; try { window.console.log('runner'); } catch (e) { supportsConsole = false; } - var proxyconsole = {}; + var proxyConsole = {}; /** * Stringify all of the console objects from an array for proxying */ - proxyconsole.stringifyArgs = function (args) { + proxyConsole.stringifyArgs = function (args) { var newArgs = []; // TODO this was forEach but when the array is [undefined] it wouldn't // iterate over them @@ -34,10 +34,10 @@ var proxyconsole = (function () { var methods = ['debug', 'error', 'info', 'log', 'warn', 'dir', 'props']; methods.forEach(function (method) { // Create console method - proxyconsole[method] = function () { + proxyConsole[method] = function () { // Replace args that can't be sent through postMessage var originalArgs = [].slice.call(arguments), - args = proxyconsole.stringifyArgs(originalArgs); + args = proxyConsole.stringifyArgs(originalArgs); // Post up with method and the arguments runner.postMessage('console', { method: method, @@ -51,6 +51,6 @@ var proxyconsole = (function () { }; }); - return proxyconsole; + return proxyConsole; }()); \ No newline at end of file diff --git a/public/js/runner/runner.js b/public/js/runner/runner.js index 6dd0641f..94674412 100644 --- a/public/js/runner/runner.js +++ b/public/js/runner/runner.js @@ -84,8 +84,8 @@ var runner = (function () { // that the user's code (that runs as a result of the following // childDoc.write) can access the objects. childWindow.runnerWindow = { - proxyconsole: proxyconsole, - protect: processor.protect + proxyConsole: proxyConsole, + protect: loopProtect.protect }; // Write the source out. IE crashes if you have lots of these, so that's diff --git a/public/js/runner/sandbox.js b/public/js/runner/sandbox.js index 4199bb19..29dd89db 100644 --- a/public/js/runner/sandbox.js +++ b/public/js/runner/sandbox.js @@ -130,7 +130,7 @@ var sandbox = (function () { output = e.message; type = 'error'; } - return proxyconsole[type](output); + return proxyConsole[type](output); }; /** diff --git a/scripts.json b/scripts.json index 9ab8da23..b70a2605 100644 --- a/scripts.json +++ b/scripts.json @@ -21,6 +21,7 @@ "/js/vendor/codemirror3/addon/search/match-highlighter.js", "/js/vendor/json2.js", "/js/vendor/prettyprint.js", + "/js/runner/loop-protect.js", "/js/chrome/storage.js", "/js/jsbin.js", "/js/editors/mobileCodeMirror.js", @@ -51,7 +52,8 @@ "/js/vendor/polyfills.js", "/js/vendor/stringify.js", "/js/runner/utils.js", - "/js/runner/proxyconsole.js", + "/js/runner/loop-protect.js", + "/js/runner/proxy-console.js", "/js/runner/processor.js", "/js/runner/sandbox.js", "/js/runner/runner.js", diff --git a/test/loop_detection_test.js b/test/loop_detection_test.js index c02ac99e..4fb65983 100644 --- a/test/loop_detection_test.js +++ b/test/loop_detection_test.js @@ -1,10 +1,10 @@ var assert = require('assert'); var sinon = require('sinon'); -var processor = require('../public/js/runner/processor'); +var loopProtect = require('../public/js/runner/loop-protect'); -// expose a window object for processor compatibility +// expose a window object for loopProtect compatibility global.window = { - runnerWindow: processor + runnerWindow: loopProtect }; var code = { @@ -14,7 +14,7 @@ var code = { simplewhile: 'var i = 0; while (i < 100) {\ni += 10;\n}\nreturn i;', onelinewhile: 'var i = 0; while (i < 100) i += 10;\nreturn i;', whiletrue: 'var i = 0;\nwhile(true) {\ni++;\n}\nreturn i;', - irl1: 'var nums = [0,1];\n var total = 8;\n for(i = 0; i <= total; i++){\n var newest = nums[i--]\n nums.push(newest);\n }\n return (nums);', + irl1: 'var nums = [0,1];\n var total = 8;\n for(var i = 0; i <= total; i++){\n var newest = nums[i--]\n nums.push(newest);\n }\n return (nums);', irl2: 'var a = 0;\n for(var j=1;j<=2;j++){\n for(var i=1;i<=60000;i++) {\n a += 1;\n }\n }\n return a;', }; @@ -32,25 +32,25 @@ describe('loop', function () { it('should leave none loop code alone', function () { - assert(processor.rewriteLoops(code.simple) === code.simple); + assert(loopProtect.rewriteLoops(code.simple) === code.simple); }); it('should rewrite for loops', function () { - var compiled = processor.rewriteLoops(code.simplefor); + var compiled = loopProtect.rewriteLoops(code.simplefor); assert(compiled !== code); var result = run(compiled); assert(result === 9); }); it('should rewrite one line for loops', function () { - var compiled = processor.rewriteLoops(code.onelinefor); + var compiled = loopProtect.rewriteLoops(code.onelinefor); assert(compiled !== code); var result = run(compiled); assert(result === 10); }); it('should throw on infinite while', function () { - var compiled = processor.rewriteLoops(code.whiletrue); + var compiled = loopProtect.rewriteLoops(code.whiletrue); try { spy(compiled); } catch (e) {} @@ -58,13 +58,13 @@ describe('loop', function () { }); it('should throw on infinite for', function () { - var compiled = processor.rewriteLoops(code.irl1); + var compiled = loopProtect.rewriteLoops(code.irl1); try { spy(compiled); } catch (e) {} assert(spy.threw); }); it('should should allow nested loops to run', function () { - var compiled = processor.rewriteLoops(code.irl2); + var compiled = loopProtect.rewriteLoops(code.irl2); assert(run(compiled) === 120000); }); diff --git a/test/mocha.opts b/test/mocha.opts index 10508f80..d9777dcf 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,3 +1,3 @@ ---require should sinon +--require should --reporter spec --ui bdd \ No newline at end of file diff --git a/test/spike_test.js b/test/spike_test.js index 8df8b084..124bfad9 100644 --- a/test/spike_test.js +++ b/test/spike_test.js @@ -1,39 +1,39 @@ -var spike = require('../lib/spike'); +// var spike = require('../lib/spike'); -describe('splike.utils.makeEvent', function () { +// describe('splike.utils.makeEvent', function () { - it('should convert some string data into a valid event', function () { - var result = spike.utils.makeEvent('example', 'hello'); - result.should.equal([ - 'data:hello', - 'event:example', - '\n' - ].join('\n')); - }); +// it('should convert some string data into a valid event', function () { +// var result = spike.utils.makeEvent('example', 'hello'); +// result.should.equal([ +// 'data:hello', +// 'event:example', +// '\n' +// ].join('\n')); +// }); - it('should convert and object into a valid event', function () { - var result = spike.utils.makeEvent('example', { - a: 10, - b: 20 - }); - result.should.equal([ - 'data:{"a":10,"b":20}', - 'event:example', - '\n' - ].join('\n')); - }); +// it('should convert and object into a valid event', function () { +// var result = spike.utils.makeEvent('example', { +// a: 10, +// b: 20 +// }); +// result.should.equal([ +// 'data:{"a":10,"b":20}', +// 'event:example', +// '\n' +// ].join('\n')); +// }); - it('should create an event even if no data is passed', function () { - var result = spike.utils.makeEvent('example'); - result.should.equal([ - 'event:example', - '\n' - ].join('\n')); - }); +// it('should create an event even if no data is passed', function () { +// var result = spike.utils.makeEvent('example'); +// result.should.equal([ +// 'event:example', +// '\n' +// ].join('\n')); +// }); - it('should return nothing if nothing is passed', function () { - var result = spike.utils.makeEvent(); - result.should.equal(''); - }); +// it('should return nothing if nothing is passed', function () { +// var result = spike.utils.makeEvent(); +// result.should.equal(''); +// }); -}); \ No newline at end of file +// }); \ No newline at end of file