From d7cdabe8ba415211f09fd16c7ea2466c20f8eaa1 Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Sat, 16 Apr 2011 10:26:49 -0500 Subject: [PATCH 01/10] Implemented async invocation of helpers. --- src/eco/compiler.coffee | 34 ++++++++++++++++++++++++++++++---- src/eco/preprocessor.coffee | 12 ++++++++++-- src/eco/scanner.coffee | 7 ++++--- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/eco/compiler.coffee b/src/eco/compiler.coffee index bccb881..6341f8e 100644 --- a/src/eco/compiler.coffee +++ b/src/eco/compiler.coffee @@ -12,11 +12,19 @@ eco.compile = compile = (source, options) -> identifier = options?.identifier ? "module.exports" identifier = "var #{identifier}" unless identifier.match(/\./) script = CoffeeScript.compile preprocess(source), noWrap: true - """ - #{identifier} = function(__obj) { + #{identifier} = function(__obj, __callback) { if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { + var __out = [], __async = function(safe, callback) { + return function(done) { + callback([], function(out) { + if (safe) { + out.ecoSafe = true; + } + done(out); + }); + } + }, __capture = function(callback) { var out = __out, result; __out = []; callback.call(this); @@ -55,7 +63,25 @@ eco.compile = compile = (source, options) -> #{indent script, 4} }).call(__obj); __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); + if (__callback) { + var index = 0; + function expand() { + while (index < __out.length) { + if (typeof __out[index] == "function") { + __out[index](function (out) { + Array.prototype.splice.apply(__out, [ index, 1 ].concat(out)); + expand(); + }); + return; + } + index++; + } + __callback(__out.join("")); + } + expand(); + } else { + return __out.join(""); + } }; """ diff --git a/src/eco/preprocessor.coffee b/src/eco/preprocessor.coffee index f698dd1..aaa1d12 100644 --- a/src/eco/preprocessor.coffee +++ b/src/eco/preprocessor.coffee @@ -12,6 +12,7 @@ module.exports = class Preprocessor @level = 0 @options = {} @captures = [] + @asyncs = [] preprocess: -> until @scanner.done @@ -33,7 +34,9 @@ module.exports = class Preprocessor recordCode: (code) -> if code isnt "end" if @options.print - if @options.safe + if @options.async + @record "__out.push __async #{@options.safe}, (__out, __done) => #{code}" + else if @options.safe @record "__out.push #{code}" else @record "__out.push __sanitize #{code}" @@ -42,12 +45,17 @@ module.exports = class Preprocessor indent: (capture) -> @level++ - if capture + if @options.async + @asyncs.unshift @level + else if capture @record "__capture #{capture}" @captures.unshift @level @indent() dedent: -> + if @asyncs[0] is @level + @asyncs.shift() + @record "__done(__out)" @level-- @fail "unexpected dedent" if @level < 0 if @captures[0] is @level diff --git a/src/eco/scanner.coffee b/src/eco/scanner.coffee index 48a4cfe..38d7aaa 100644 --- a/src/eco/scanner.coffee +++ b/src/eco/scanner.coffee @@ -3,7 +3,7 @@ module.exports = class Scanner @modePatterns: { - data: /(.*?)(<%%|<%(([=-])?)|\n|$)/ + data: /(.*?)(<%%|<%(((!)?[=-])?)|\n|$)/ code: /(.*?)(((:|(->|=>))\s*)?%>|\n|$)/ } @@ -49,6 +49,7 @@ module.exports = class Scanner @buffer += @scanner.getCapture 0 @tail = @scanner.getCapture 1 @directive = @scanner.getCapture 3 + @async = @scanner.getCapture 4 @arrow = @scanner.getCapture 4 scanData: (callback) -> @@ -64,7 +65,7 @@ module.exports = class Scanner else if @tail @mode = "code" callback ["printString", @flush()] - callback ["beginCode", print: @directive?, safe: @directive is "-"] + callback ["beginCode", print: @directive?, safe: @directive is "-", async: @async ] scanCode: (callback) -> if @tail is "\n" @@ -77,7 +78,7 @@ module.exports = class Scanner callback ["dedent"] if @isDedentable code callback ["recordCode", code] - callback ["indent", @arrow] if @directive + callback ["indent", @arrow ] if @directive flush: -> buffer = @buffer From 331a9e838d999725db850c9cc64e930de55df0cd Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Sat, 16 Apr 2011 18:32:58 -0500 Subject: [PATCH 02/10] Implemented async as compiler option. --- src/eco/compiler.coffee | 68 ++++++++++++++++++++++--------------- src/eco/preprocessor.coffee | 21 ++++++------ src/eco/scanner.coffee | 8 ++--- src/eco/util.coffee | 1 + 4 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/eco/compiler.coffee b/src/eco/compiler.coffee index 6341f8e..aa026b2 100644 --- a/src/eco/compiler.coffee +++ b/src/eco/compiler.coffee @@ -11,11 +11,15 @@ eco.preprocess = preprocess eco.compile = compile = (source, options) -> identifier = options?.identifier ? "module.exports" identifier = "var #{identifier}" unless identifier.match(/\./) - script = CoffeeScript.compile preprocess(source), noWrap: true - """ - #{identifier} = function(__obj, __callback) { - if (!__obj) __obj = {}; - var __out = [], __async = function(safe, callback) { + script = CoffeeScript.compile preprocess(source, options?.async), noWrap: true + if options?.async + asyncAssertions = """ + if (!__callback) { + throw new Error("Callback required."); + } + """ + asyncHelpers = """ + __async = function(safe, callback) { return function(done) { callback([], function(out) { if (safe) { @@ -24,14 +28,41 @@ eco.compile = compile = (source, options) -> done(out); }); } - }, __capture = function(callback) { + }, + """ + join = """ + var index = 0; + function expand() { + while (index < __out.length) { + if (typeof __out[index] == "function") { + __out[index](function (out) { + Array.prototype.splice.apply(__out, [ index, 1 ].concat(out)); + expand(); + }); + return; + } + index++; + } + __callback(__out.join("")); + } + expand(); + """ + else + join = """ + return __out.join(""); + """ + """ + #{identifier} = function(__obj, __callback) { + if (!__obj) __obj = {}; + #{indent asyncAssertions, 2} + var __out = [], #{indent asyncHelpers, 2}__capture = function(callback) { var out = __out, result; __out = []; callback.call(this); result = __out.join(''); __out = out; return __safe(result); - }, __sanitize = function(value) { + } , __sanitize = function(value) { if (value && value.ecoSafe) { return value; } else if (typeof value !== 'undefined' && value != null) { @@ -60,31 +91,12 @@ eco.compile = compile = (source, options) -> }; } (function() { - #{indent script, 4} + #{indent script, 4} }).call(__obj); __obj.safe = __objSafe, __obj.escape = __escape; - if (__callback) { - var index = 0; - function expand() { - while (index < __out.length) { - if (typeof __out[index] == "function") { - __out[index](function (out) { - Array.prototype.splice.apply(__out, [ index, 1 ].concat(out)); - expand(); - }); - return; - } - index++; - } - __callback(__out.join("")); - } - expand(); - } else { - return __out.join(""); - } + #{indent join, 2} }; """ - eco.render = (source, data) -> (eco source) data diff --git a/src/eco/preprocessor.coffee b/src/eco/preprocessor.coffee index aaa1d12..5c49c8a 100644 --- a/src/eco/preprocessor.coffee +++ b/src/eco/preprocessor.coffee @@ -2,11 +2,11 @@ Scanner = require "./scanner" util = require "./util" module.exports = class Preprocessor - @preprocess: (source) -> - preprocessor = new Preprocessor source + @preprocess: (source, async) -> + preprocessor = new Preprocessor source, async preprocessor.preprocess() - constructor: (source) -> + constructor: (source, @async) -> @scanner = new Scanner source @output = "" @level = 0 @@ -34,7 +34,7 @@ module.exports = class Preprocessor recordCode: (code) -> if code isnt "end" if @options.print - if @options.async + if @async and not @options.inline @record "__out.push __async #{@options.safe}, (__out, __done) => #{code}" else if @options.safe @record "__out.push #{code}" @@ -45,12 +45,13 @@ module.exports = class Preprocessor indent: (capture) -> @level++ - if @options.async - @asyncs.unshift @level - else if capture - @record "__capture #{capture}" - @captures.unshift @level - @indent() + if capture + if @async and @options.print + @asyncs.unshift @level + else + @record "__capture #{capture}" + @captures.unshift @level + @indent() dedent: -> if @asyncs[0] is @level diff --git a/src/eco/scanner.coffee b/src/eco/scanner.coffee index 38d7aaa..d36b1d4 100644 --- a/src/eco/scanner.coffee +++ b/src/eco/scanner.coffee @@ -3,7 +3,7 @@ module.exports = class Scanner @modePatterns: { - data: /(.*?)(<%%|<%(((!)?[=-])?)|\n|$)/ + data: /(.*?)(<%%|<%(([=-])?)|\n|$)/ code: /(.*?)(((:|(->|=>))\s*)?%>|\n|$)/ } @@ -49,7 +49,6 @@ module.exports = class Scanner @buffer += @scanner.getCapture 0 @tail = @scanner.getCapture 1 @directive = @scanner.getCapture 3 - @async = @scanner.getCapture 4 @arrow = @scanner.getCapture 4 scanData: (callback) -> @@ -65,7 +64,7 @@ module.exports = class Scanner else if @tail @mode = "code" callback ["printString", @flush()] - callback ["beginCode", print: @directive?, safe: @directive is "-", async: @async ] + @_directive = @directive scanCode: (callback) -> if @tail is "\n" @@ -76,9 +75,10 @@ module.exports = class Scanner code = trim @flush() code += " #{@arrow}" if @arrow + callback ["beginCode", print: @_directive?, safe: @_directive is "-", inline: not @arrow] callback ["dedent"] if @isDedentable code callback ["recordCode", code] - callback ["indent", @arrow ] if @directive + callback ["indent", @arrow] if @directive flush: -> buffer = @buffer diff --git a/src/eco/util.coffee b/src/eco/util.coffee index 9f40cf6..48765e3 100644 --- a/src/eco/util.coffee +++ b/src/eco/util.coffee @@ -4,6 +4,7 @@ exports.repeat = repeat = (string, count) -> exports.indent = (string, width) -> space = repeat " ", width lines = (space + line for line in string.split "\n") + lines[0] = lines[0].substring(width) lines.join "\n" exports.trim = (string) -> From d60bbb329fc455891baeec52869bb16019fca5b4 Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Sat, 16 Apr 2011 19:24:01 -0500 Subject: [PATCH 03/10] Unobtrusive async scanner changes, tests passing. * Altered the scanner to report the block nature of code at as part of "beginCode". This meant moving the "beginCode" invocation to after the code scan, but did not change the preprocessor. It did change the scanner tests, however, since they now detect a truncated template before they report "beginCode". I changed the test inputs, but not their meaning. * All tests are passing again. * This ends the modifications necessary to the scanner, preprocessors and compiler. The only changes now are to the helper methods in the generated code. --- src/eco/compiler.coffee | 6 ++++-- src/eco/scanner.coffee | 12 +++++++----- test/test_scanner.coffee | 28 +++++++++++++--------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/eco/compiler.coffee b/src/eco/compiler.coffee index aa026b2..83fffa3 100644 --- a/src/eco/compiler.coffee +++ b/src/eco/compiler.coffee @@ -28,7 +28,7 @@ eco.compile = compile = (source, options) -> done(out); }); } - }, + }, """ join = """ var index = 0; @@ -48,6 +48,8 @@ eco.compile = compile = (source, options) -> expand(); """ else + asyncAssertions = "" + asyncHelpers = "" join = """ return __out.join(""); """ @@ -62,7 +64,7 @@ eco.compile = compile = (source, options) -> result = __out.join(''); __out = out; return __safe(result); - } , __sanitize = function(value) { + }, __sanitize = function(value) { if (value && value.ecoSafe) { return value; } else if (typeof value !== 'undefined' && value != null) { diff --git a/src/eco/scanner.coffee b/src/eco/scanner.coffee index d36b1d4..f63f36e 100644 --- a/src/eco/scanner.coffee +++ b/src/eco/scanner.coffee @@ -48,8 +48,11 @@ module.exports = class Scanner @scanner.scanUntil Scanner.modePatterns[@mode] @buffer += @scanner.getCapture 0 @tail = @scanner.getCapture 1 - @directive = @scanner.getCapture 3 - @arrow = @scanner.getCapture 4 + if @mode is "data" + @capture = @scanner.getCapture 3 + else + @colon = @scanner.getCapture 3 + @arrow = @scanner.getCapture 4 scanData: (callback) -> if @tail is "<%%" @@ -64,7 +67,6 @@ module.exports = class Scanner else if @tail @mode = "code" callback ["printString", @flush()] - @_directive = @directive scanCode: (callback) -> if @tail is "\n" @@ -75,10 +77,10 @@ module.exports = class Scanner code = trim @flush() code += " #{@arrow}" if @arrow - callback ["beginCode", print: @_directive?, safe: @_directive is "-", inline: not @arrow] + callback ["beginCode", print: @capture?, safe: @capture is "-", inline: not @arrow] callback ["dedent"] if @isDedentable code callback ["recordCode", code] - callback ["indent", @arrow] if @directive + callback ["indent", @arrow] if @colon flush: -> buffer = @buffer diff --git a/test/test_scanner.coffee b/test/test_scanner.coffee index fd4b0eb..335f0cc 100644 --- a/test/test_scanner.coffee +++ b/test/test_scanner.coffee @@ -2,27 +2,27 @@ module.exports = "'<%' begins a code block": (test) -> - tokens = scan "<%" + tokens = scan "<% hello() %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: false, safe: false], tokens.shift() + test.same ["beginCode", print: false, safe: false, inline: true], tokens.shift() test.done() "'<%=' begins a print block": (test) -> - tokens = scan "<%=" + tokens = scan "<%= hello %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: true, safe: false], tokens.shift() + test.same ["beginCode", print: true, safe: false, inline: true], tokens.shift() test.done() "'<%-' begins a safe print block": (test) -> - tokens = scan "<%-" + tokens = scan "<%- hello %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: true, safe: true], tokens.shift() + test.same ["beginCode", print: true, safe: true, inline: true], tokens.shift() test.done() "'%>' ends a code block": (test) -> tokens = scan "<% code goes here %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: false, safe: false], tokens.shift() + test.same ["beginCode", print: false, safe: false, inline: true], tokens.shift() test.same ["recordCode", "code goes here"], tokens.shift() test.same ["printString", ""], tokens.shift() test.done() @@ -30,7 +30,7 @@ module.exports = "': %>' ends a code block and indents": (test) -> tokens = scan "<% for project in @projects: %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: false, safe: false], tokens.shift() + test.same ["beginCode", print: false, safe: false, inline: true], tokens.shift() test.same ["recordCode", "for project in @projects"], tokens.shift() test.same ["indent", undefined], tokens.shift() test.done() @@ -38,7 +38,7 @@ module.exports = "'-> %>' ends a code block and indents": (test) -> tokens = scan "<%= @render 'layout', -> %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: true, safe: false], tokens.shift() + test.same ["beginCode", print: true, safe: false, inline: false], tokens.shift() test.same ["recordCode", "@render 'layout', ->"], tokens.shift() test.same ["indent", "->"], tokens.shift() test.done() @@ -46,7 +46,7 @@ module.exports = "'=> %>' ends a code block and indents": (test) -> tokens = scan "<%= @render 'layout', => %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: true, safe: false], tokens.shift() + test.same ["beginCode", print: true, safe: false, inline: false], tokens.shift() test.same ["recordCode", "@render 'layout', =>"], tokens.shift() test.same ["indent", "=>"], tokens.shift() test.done() @@ -54,7 +54,7 @@ module.exports = "'<% else: %>' dedents, begins a code block, and indents": (test) -> tokens = scan "<% else: %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: false, safe: false], tokens.shift() + test.same ["beginCode", print: false, safe: false, inline: true], tokens.shift() test.same ["dedent"], tokens.shift() test.same ["recordCode", "else"], tokens.shift() test.same ["indent", undefined], tokens.shift() @@ -63,7 +63,7 @@ module.exports = "'<% else if ...: %>' dedents, begins a code block, and indents": (test) -> tokens = scan "<% else if @projects: %>" test.same ["printString", ""], tokens.shift() - test.same ["beginCode", print: false, safe: false], tokens.shift() + test.same ["beginCode", print: false, safe: false, inline: true], tokens.shift() test.same ["dedent"], tokens.shift() test.same ["recordCode", "else if @projects"], tokens.shift() test.same ["indent", undefined], tokens.shift() @@ -72,21 +72,19 @@ module.exports = "<%% prints an escaped <% in data mode": (test) -> tokens = scan "a <%% b <%= '<%%' %>" test.same ["printString", "a <% b "], tokens.shift() - test.same ["beginCode", print: true, safe: false], tokens.shift() + test.same ["beginCode", print: true, safe: false, inline: true], tokens.shift() test.same ["recordCode", "'<%%'"], tokens.shift() test.done() "unexpected newline in code block": (test) -> tokens = scan "foo\nhello <% do 'thing'\n %>" test.same ["printString", "foo\nhello "], tokens.shift() - test.same ["beginCode", print: false, safe: false], tokens.shift() test.same ["fail", "unexpected newline in code block"], tokens.shift() test.done() "unexpected end of template": (test) -> tokens = scan "foo\nhello <% do 'thing'" test.same ["printString", "foo\nhello "], tokens.shift() - test.same ["beginCode", print: false, safe: false], tokens.shift() test.same ["fail", "unexpected end of template"], tokens.shift() test.done() From 7817e933fefc6ad103ef4eb271c0027e20457327 Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Mon, 18 Apr 2011 19:56:51 -0500 Subject: [PATCH 04/10] API switches for async, returning error. * Passing the error (now only ever `null`) as the first parameter to the async callback. * Updated `eco` function to take addtional boolean parameter to indicate an asyc compile. * Updated `render` to accept an option third callback function, which will trigger an async compile. --- src/eco/compiler.coffee | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/eco/compiler.coffee b/src/eco/compiler.coffee index 83fffa3..48037e4 100644 --- a/src/eco/compiler.coffee +++ b/src/eco/compiler.coffee @@ -2,8 +2,8 @@ CoffeeScript = require "coffee-script" {preprocess} = require "./preprocessor" {indent} = require "./util" -module.exports = eco = (source) -> - (new Function "module", compile source) module = {} +module.exports = eco = (source, async) -> + (new Function "module", compile source, { async }) module = {} module.exports eco.preprocess = preprocess @@ -13,6 +13,7 @@ eco.compile = compile = (source, options) -> identifier = "var #{identifier}" unless identifier.match(/\./) script = CoffeeScript.compile preprocess(source, options?.async), noWrap: true if options?.async + parameters = "__obj, __callback" asyncAssertions = """ if (!__callback) { throw new Error("Callback required."); @@ -43,18 +44,19 @@ eco.compile = compile = (source, options) -> } index++; } - __callback(__out.join("")); + __callback(null, __out.join("")); } expand(); """ else + parameters = "__obj" asyncAssertions = "" asyncHelpers = "" join = """ return __out.join(""); """ """ - #{identifier} = function(__obj, __callback) { + #{identifier} = function(#{parameters}) { if (!__obj) __obj = {}; #{indent asyncAssertions, 2} var __out = [], #{indent asyncHelpers, 2}__capture = function(callback) { @@ -99,8 +101,8 @@ eco.compile = compile = (source, options) -> #{indent join, 2} }; """ -eco.render = (source, data) -> - (eco source) data +eco.render = (source, data, callback) -> + (eco source, typeof callback is "function") data, callback if require.extensions require.extensions[".eco"] = (module, filename) -> From bbeaf2181fe025ca6eef64b0ca210100f1abd823 Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Mon, 18 Apr 2011 20:15:38 -0500 Subject: [PATCH 05/10] Catch async errors, safety moot on blocks. * Catching exceptions thrown by the helpers when run asynchronously. * Forwarding caught exceptions to the callback method. * Safety is moot on blocks, since only inline printed code is escaped. --- src/eco/compiler.coffee | 15 ++++++++------- src/eco/preprocessor.coffee | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/eco/compiler.coffee b/src/eco/compiler.coffee index 48037e4..d32a5cd 100644 --- a/src/eco/compiler.coffee +++ b/src/eco/compiler.coffee @@ -20,14 +20,15 @@ eco.compile = compile = (source, options) -> } """ asyncHelpers = """ - __async = function(safe, callback) { + __async = function(callback) { return function(done) { - callback([], function(out) { - if (safe) { - out.ecoSafe = true; - } - done(out); - }); + try { + callback([], function(out) { + done(out); + }); + } catch (error) { + __callback(error); + } } }, """ diff --git a/src/eco/preprocessor.coffee b/src/eco/preprocessor.coffee index 5c49c8a..7dd1602 100644 --- a/src/eco/preprocessor.coffee +++ b/src/eco/preprocessor.coffee @@ -35,7 +35,7 @@ module.exports = class Preprocessor if code isnt "end" if @options.print if @async and not @options.inline - @record "__out.push __async #{@options.safe}, (__out, __done) => #{code}" + @record "__out.push __async (__out, __done) => #{code}" else if @options.safe @record "__out.push #{code}" else From 2110c767a5087f2d5efde6d93bf7d1381efb518d Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Mon, 18 Apr 2011 21:29:06 -0500 Subject: [PATCH 06/10] Created prepocessor async compile tests. --- test/fixtures/blocks-async.coffee | 10 ++++++++++ test/fixtures/blocks.coffee | 10 ++++++++++ test/fixtures/blocks.eco | 5 +++++ test/test_preprocessor.coffee | 8 ++++++++ 4 files changed, 33 insertions(+) create mode 100644 test/fixtures/blocks-async.coffee create mode 100644 test/fixtures/blocks.coffee create mode 100644 test/fixtures/blocks.eco diff --git a/test/fixtures/blocks-async.coffee b/test/fixtures/blocks-async.coffee new file mode 100644 index 0000000..7687321 --- /dev/null +++ b/test/fixtures/blocks-async.coffee @@ -0,0 +1,10 @@ +__out.push __async (__out, __done) => @emit => + __out.push '\n ' + __out.push __async (__out, __done) => @emit (data) -> + __out.push '\n ' + __out.push __sanitize "&" + __out.push '\n ' + __done(__out) + __out.push '\n' + __done(__out) +__out.push '\n' diff --git a/test/fixtures/blocks.coffee b/test/fixtures/blocks.coffee new file mode 100644 index 0000000..97441b7 --- /dev/null +++ b/test/fixtures/blocks.coffee @@ -0,0 +1,10 @@ +__out.push __sanitize @emit => + __capture => + __out.push '\n ' + __out.push @emit (data) -> + __capture -> + __out.push '\n ' + __out.push __sanitize "&" + __out.push '\n ' + __out.push '\n' +__out.push '\n' diff --git a/test/fixtures/blocks.eco b/test/fixtures/blocks.eco new file mode 100644 index 0000000..117affc --- /dev/null +++ b/test/fixtures/blocks.eco @@ -0,0 +1,5 @@ +<%= @emit => %> + <%- @emit (data) -> %> + <%= "&" %> + <% end %> +<% end %> diff --git a/test/test_preprocessor.coffee b/test/test_preprocessor.coffee index 27bf51a..1fd4148 100644 --- a/test/test_preprocessor.coffee +++ b/test/test_preprocessor.coffee @@ -18,6 +18,14 @@ module.exports = test.same fixture("helpers.coffee"), preprocess fixture("helpers.eco") test.done() + "preprocessing fixtures/blocks.eco": (test) -> + test.same fixture("blocks.coffee"), preprocess fixture("blocks.eco") + test.done() + + "preprocessing fixtures/blocks.eco with async": (test) -> + test.same fixture("blocks-async.coffee"), preprocess fixture("blocks.eco"), true + test.done() + "unexpected dedent": (test) -> test.expect 1 try From 74db3cb64ed4f39e18be3ea64611aca66231f83e Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Mon, 18 Apr 2011 21:30:24 -0500 Subject: [PATCH 07/10] Created compiler asyc compile tests. --- test/test_compile.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/test_compile.coffee b/test/test_compile.coffee index b692981..ab96e4e 100644 --- a/test/test_compile.coffee +++ b/test/test_compile.coffee @@ -14,6 +14,14 @@ module.exports = test.ok eco.compile fixture("helpers.eco") test.done() + "compiling fixtures/block.eco": (test) -> + test.ok eco.compile fixture("helpers.eco") + test.done() + + "compiling fixtures/block.eco with async": (test) -> + test.ok eco.compile fixture("helpers.eco"), { async: true } + test.done() + "parse error throws exception": (test) -> test.expect 1 try From 5a5e4fe307c6caf8eaec6d9ecf7f18ebefb0a9dd Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Mon, 18 Apr 2011 21:37:24 -0500 Subject: [PATCH 08/10] Created exception handling test. --- test/test_render.coffee | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/test_render.coffee b/test/test_render.coffee index 7cb45e7..3a9df39 100644 --- a/test/test_render.coffee +++ b/test/test_render.coffee @@ -60,6 +60,22 @@ module.exports = test.same fixture("capture.out.1"), output test.done() + "rendering blocks.eco": (test) -> + output = eco.render fixture("blocks.eco"), emit: (yield) -> yield() + test.same fixture("blocks.out.1"), output + test.done() + + "rendering blocks.eco async": (test) -> + output = eco.render fixture("blocks.eco"), { emit: (yield) -> yield() }, (error, output) -> + test.same fixture("blocks.out.1"), output + test.done() + + "rendering error.eco async": (test) -> + output = eco.render fixture("error.eco"), { emit: () -> throw new Error("catch me") }, (error, output) -> + test.ok error + test.same "catch me", error.message + test.done() + "HTML is escaped by default": (test) -> output = eco.render "<%= @emailAddress %>", emailAddress: "" From 189f16b03482bf28a2d49f13ce1c490a39cb2ef9 Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Wed, 4 May 2011 00:00:30 -0500 Subject: [PATCH 09/10] Forgot some test fixture files. --- test/fixtures/blocks.out.1 | 5 +++++ test/fixtures/error.eco | 1 + 2 files changed, 6 insertions(+) create mode 100644 test/fixtures/blocks.out.1 create mode 100644 test/fixtures/error.eco diff --git a/test/fixtures/blocks.out.1 b/test/fixtures/blocks.out.1 new file mode 100644 index 0000000..3fdd67d --- /dev/null +++ b/test/fixtures/blocks.out.1 @@ -0,0 +1,5 @@ + + + & + + diff --git a/test/fixtures/error.eco b/test/fixtures/error.eco new file mode 100644 index 0000000..afaf744 --- /dev/null +++ b/test/fixtures/error.eco @@ -0,0 +1 @@ +<%= @emit => %><% end %> From a6c205850d49df52a11aa390760d553ab529729f Mon Sep 17 00:00:00 2001 From: Alan Gutierrez Date: Mon, 20 Jun 2011 18:57:41 +0000 Subject: [PATCH 10/10] Test capture output. --- test/test_preprocessor.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/test_preprocessor.coffee b/test/test_preprocessor.coffee index 1fd4148..589ba9b 100644 --- a/test/test_preprocessor.coffee +++ b/test/test_preprocessor.coffee @@ -22,6 +22,14 @@ module.exports = test.same fixture("blocks.coffee"), preprocess fixture("blocks.eco") test.done() + "preprocessing fixtures/capture.eco": (test) -> + test.same fixture("capture.coffee"), preprocess fixture("capture.eco") + test.done() + + "preprocessing fixtures/capture.eco with async": (test) -> + test.same fixture("capture.coffee"), preprocess fixture("capture.eco"), true + test.done() + "preprocessing fixtures/blocks.eco with async": (test) -> test.same fixture("blocks-async.coffee"), preprocess fixture("blocks.eco"), true test.done()