js303/bower_components/emblem/test/qunit_spec.coffee
2015-01-14 20:12:11 +01:00

2098 lines
50 KiB
CoffeeScript

# Test Setup: Set up an environment that'll work for both Node and Qunit tests.
Ember = window?.Emblem || @Emblem || {}
# These are needed for the full version ember to load properly
LoadedEmber = LoadedEmber || {}
Ember.Handlebars = LoadedEmber.Handlebars
Ember.warn = LoadedEmber.warn
if Emblem?
# Qunit testing
_equal = equal
equals = equal = (a, b, msg) ->
# Allow exec with missing message params
_equal(a, b, msg || '')
# In QUnit, we use module() instead of nonexistent suite()
window.suite = module
else
# Setup for Node package testing
Handlebars = require('handlebars')
EmberHandlebars = require('./resources/ember-template-compiler.js').EmberHandlebars
Emblem = require('../lib/emblem')
# TODO: replace with real expect()
`expect = function() {};`
{equal, equals, ok, throws} = require("assert")
unless CompilerContext?
# Note that this doesn't have the same context separation as the rspec test.
# Both should be run for full acceptance of the two libary modes.
CompilerContext =
compile: (template, options) ->
Emblem.compile(Handlebars, template, options)
supportsEachHelperDataKeywords = Handlebars.VERSION.slice(0, 3) >= 1.2
supportsSubexpressions = Handlebars.VERSION.slice(0, 3) >= 1.3
precompileEmber = (emblem) ->
Emblem.precompile(EmberHandlebars, emblem).toString()
shouldEmberPrecompileToHelper = (emblem, helper = 'bind-attr') ->
result = precompileEmber emblem
ok (result.match "helpers.#{helper}") or (result.match "helpers\\['#{helper}'\\]")
result
shouldCompileToString = (string, hashOrArray, expected) ->
if hashOrArray.constructor == String
shouldCompileToWithPartials(string, {}, false, hashOrArray, null, true)
else
shouldCompileToWithPartials(string, hashOrArray, false, expected, null, true)
shouldCompileTo = (string, hashOrArray, expected, message) ->
if hashOrArray.constructor == String
shouldCompileToWithPartials(string, {}, false, hashOrArray, message)
else
shouldCompileToWithPartials(string, hashOrArray, false, expected, message)
shouldCompileToWithPartials = (string, hashOrArray, partials, expected, message, strings) ->
options = null
if strings
options = {}
options.stringParams = true
result = compileWithPartials(string, hashOrArray, partials, options)
equal(result, expected, "'" + result + "' should === '" + expected + "': " + message)
compileWithPartials = (string, hashOrArray, partials, options = {}) ->
template = CompilerContext.compile(string, options)
if Object::toString.call(hashOrArray) == "[object Array]"
if helpers = hashOrArray[1]
for prop of Handlebars.helpers
helpers[prop] = helpers[prop] || Handlebars.helpers[prop]
ary = []
ary.push(hashOrArray[0])
ary.push
helpers: hashOrArray[1]
partials: hashOrArray[2]
else
ary = [hashOrArray]
template.apply(this, ary)
shouldThrow = (fn, exMessage) ->
caught = false
try
fn()
catch e
caught = true
if exMessage
ok e.message.match(exMessage), "exception message matched"
ok(caught, "an exception was thrown")
Handlebars.registerHelper 'echo', (param) ->
"ECHO #{param}"
suite "html one-liners"
test "element only", ->
shouldCompileTo "p", "<p></p>"
test "with text", ->
shouldCompileTo "p Hello", "<p>Hello</p>"
test "with more complex text", ->
shouldCompileTo "p Hello, how's it going with you today?", "<p>Hello, how's it going with you today?</p>"
test "with trailing space", ->
shouldCompileTo "p Hello ", "<p>Hello </p>"
suite "html multi-lines"
test "two lines", ->
emblem =
"""
p This is
pretty cool.
"""
shouldCompileTo emblem, "<p>This is pretty cool.</p>"
test "three lines", ->
emblem =
"""
p This is
pretty damn
cool.
"""
shouldCompileTo emblem, "<p>This is pretty damn cool.</p>"
test "three lines w/ embedded html", ->
emblem =
"""
p This is
pretty <span>damn</span>
cool.
"""
shouldCompileTo emblem, "<p>This is pretty <span>damn</span> cool.</p>"
test "indentation doesn't need to match starting inline content's", ->
emblem =
"""
span Hello,
How are you?
"""
shouldCompileTo emblem, "<span>Hello, How are you?</span>"
test "indentation may vary between parent/child, must be consistent within inline-block", ->
emblem =
"""
div
span Hello,
How are you?
Excellent.
p asd
"""
shouldCompileTo emblem, "<div><span>Hello, How are you? Excellent.</span><p>asd</p></div>"
emblem =
"""
div
span Hello,
How are you?
Excellent.
"""
shouldThrow -> CompilerContext.compile emblem
test "indentation may vary between parent/child, must be consistent within inline-block pt 2", ->
emblem =
"""
div
span Hello,
How are you?
Excellent.
"""
shouldCompileTo emblem, "<div><span>Hello, How are you? Excellent.</span></div>"
test "w/ mustaches", ->
emblem =
"""
div
span Hello,
{{foo}} are you?
Excellent.
"""
shouldCompileTo emblem, { foo: "YEAH" }, "<div><span>Hello, YEAH are you? Excellent.</span></div>"
test "w/ block mustaches", ->
emblem =
'''
p Hello, #{ sally | Hello},
and {{sally: span Hello}}!
'''
shouldCompileTo emblem,
'<p>Hello, <sally class="none">Hello</sally>, and <sally class="none"><span>Hello</span></sally>!</p>'
emblem =
'''
p Hello, #{ sally: span: a Hello}!
'''
shouldCompileTo emblem,
'<p>Hello, <sally class="none"><span><a>Hello</a></span></sally>!</p>'
test "with followup", ->
emblem =
"""
p This is
pretty cool.
p Hello.
"""
shouldCompileTo emblem, "<p>This is pretty cool.</p><p>Hello.</p>"
suite '#{} syntax'
test 'acts like {{}}', ->
emblem =
'''
span Yo #{foo}, I herd.
'''
shouldCompileTo emblem,
{ foo: '<span>123</span>' },
"<span>Yo &lt;span&gt;123&lt;/span&gt;, I herd.</span>"
test 'can start inline content', ->
emblem =
'''
span #{foo}, I herd.
'''
shouldCompileTo emblem, { foo: "dawg" }, "<span>dawg, I herd.</span>"
test 'can end inline content', ->
emblem =
'''
span I herd #{foo}
'''
shouldCompileTo emblem, { foo: "dawg" }, "<span>I herd dawg</span>"
test "doesn't screw up parsing when # used in text nodes", ->
emblem =
'''
span OMG #YOLO
'''
shouldCompileTo emblem, "<span>OMG #YOLO</span>"
test "# can be only thing on line", ->
emblem =
'''
span #
'''
shouldCompileTo emblem, "<span>#</span>"
### TODO: this
test "can be escaped", ->
emblem =
'''
span #\\{yes}
'''
shouldCompileTo emblem, '<span>#{yes}</span>'
###
runTextLineSuite = (ch) ->
sct = (emblem, obj, expected) ->
unless expected?
expected = obj
obj = {}
unless ch == '`'
expected = expected.replace /\n/g, ""
# Replace tabs with optional trailing whitespace.
if ch == "'"
expected = expected.replace /\t/g, " "
else
expected = expected.replace /\t/g, ""
emblem = emblem.replace /_/g, ch
shouldCompileTo emblem, obj, expected
suite "text lines starting with '#{ch}'"
test "basic", -> sct "_ What what", "What what\n\t"
test "with html", ->
sct '_ What <span id="woot" data-t="oof" class="f">what</span>!',
'What <span id="woot" data-t="oof" class="f">what</span>!\n\t'
test "multiline", ->
emblem =
"""
_ Blork
Snork
"""
sct emblem, "Blork\nSnork\n\t"
test "triple multiline", ->
emblem =
"""
_ Blork
Snork
Bork
"""
sct emblem, "Blork\nSnork\nBork\n\t"
test "quadruple multiline", ->
emblem =
"""
_ Blork
Snork
Bork
Fork
"""
sct emblem, "Blork\nSnork\nBork\nFork\n\t"
test "multiline w/ trailing whitespace", ->
emblem =
"""
_ Blork
Snork
"""
sct emblem, "Blork \nSnork\n\t"
test "secondline", ->
emblem =
"""
_
Good
"""
sct emblem, "Good\n\t"
test "secondline multiline", ->
emblem =
"""
_
Good
Bork
"""
sct emblem, "Good\nBork\n\t"
test "with a mustache", ->
emblem =
"""
_ Bork {{foo}}!
"""
sct emblem,
{ foo: "YEAH" },
'Bork YEAH!\n\t'
test "with mustaches", ->
emblem =
"""
_ Bork {{foo}} {{{bar}}}!
"""
sct emblem,
{ foo: "YEAH", bar: "<span>NO</span>"},
'Bork YEAH <span>NO</span>!\n\t'
test "indented, then in a row", ->
expect(0)
return "PENDING"
emblem =
"""
_
Good
riddance2
dude
gnar
foo
"""
sct emblem, "Good\n riddance2\n dude\n gnar\n foo\n\t"
test "indented, then in a row, then indented", ->
expect(0)
return "PENDING"
emblem =
"""
_
Good
riddance2
dude
gnar
foo
far
faz
"""
sct emblem, "Good \n riddance2 \n dude \n gnar \n foo \n far \n faz \n\t"
test "uneven indentation megatest", ->
expect(0)
return "PENDING"
emblem =
"""
_
Good
riddance
dude
"""
sct emblem, "Good\n riddance\ndude\n\t"
emblem =
"""
_
Good
riddance3
dude
"""
sct emblem, "Good\n riddance3\n dude\n\t"
emblem =
"""
_ Good
riddance
dude
"""
sct emblem, "Good\nriddance\n dude\n\t"
test "on each line", ->
emblem =
"""
pre
_ This
_ should
_ hopefully
_ work, and work well.
"""
sct emblem, '<pre>This\n\t should\n\t hopefully\n\t work, and work well.\n\t</pre>'
test "with blank", ->
emblem =
"""
pre
_ This
_ should
_
_ hopefully
_ work, and work well.
"""
sct emblem, '<pre>This\n\t should\n\t\n\t hopefully\n\t work, and work well.\n\t</pre>'
runTextLineSuite '|'
runTextLineSuite '`'
runTextLineSuite "'"
suite "text line starting with angle bracket"
test "can start with angle bracket html", ->
emblem =
"""
<span>Hello</span>
"""
shouldCompileTo emblem, "<span>Hello</span>"
test "can start with angle bracket html and go to multiple lines", ->
emblem =
"""
<span>Hello dude,
what's up?</span>
"""
shouldCompileTo emblem, "<span>Hello dude, what's up?</span>"
suite "preprocessor"
test "it strips out preceding whitespace", ->
emblem =
"""
p Hello
"""
shouldCompileTo emblem, "<p>Hello</p>"
test "it handles preceding indentation", ->
emblem = " p Woot\n p Ha"
shouldCompileTo emblem, "<p>Woot</p><p>Ha</p>"
test "it handles preceding indentation and newlines", ->
emblem = "\n p Woot\n p Ha"
shouldCompileTo emblem, "<p>Woot</p><p>Ha</p>"
test "it handles preceding indentation and newlines pt 2", ->
emblem = " \n p Woot\n p Ha"
shouldCompileTo emblem, "<p>Woot</p><p>Ha</p>"
suite "comments"
test "it strips out single line '/' comments", ->
emblem =
"""
p Hello
/ A comment
h1 How are you?
"""
shouldCompileTo emblem, "<p>Hello</p><h1>How are you?</h1>"
test "it strips out multi-line '/' comments", ->
emblem =
"""
p Hello
/ A comment
that goes on to two lines
even three!
h1 How are you?
"""
shouldCompileTo emblem, "<p>Hello</p><h1>How are you?</h1>"
test "it strips out multi-line '/' comments without text on the first line", ->
emblem =
"""
p Hello
/
A comment
that goes on to two lines
even three!
h1 How are you?
"""
shouldCompileTo emblem, "<p>Hello</p><h1>How are you?</h1>"
test "mix and match with various indentation", ->
emblem =
"""
/ A test
p Hello
span
/ This is gnarly
p Yessir nope.
/ Nothin but comments
so many comments.
/
p Should not show up
"""
shouldCompileTo emblem, "<p>Hello</p><span><p>Yessir nope.</p></span>"
test "uneven indentation", ->
emblem =
"""
/ nop
nope
nope
"""
shouldCompileTo emblem, ""
test "uneven indentation 2", ->
emblem =
"""
/ n
no
nop
nope
"""
shouldCompileTo emblem, ""
test "uneven indentation 3", ->
emblem =
"""
/ n
no
nop
nope
"""
shouldCompileTo emblem, ""
test "empty first line", ->
emblem =
"""
/
nop
nope
nope
no
"""
shouldCompileTo emblem, ""
test "on same line as html content", ->
emblem =
"""
.container / This comment doesn't show up
.row / Nor does this
p Hello
"""
shouldCompileTo emblem, '<div class="container"><div class="row"><p>Hello</p></div></div>'
test "on same line as mustache content", ->
shouldCompileTo 'frank text="YES" text2="NO" / omg', 'WOO: YES NO'
test "on same line as colon syntax", ->
emblem =
"""
ul: li: span / omg
| Hello
"""
shouldCompileTo emblem, '<ul><li><span>Hello</span></li></ul>'
suite "indentation"
# This test used to make sure the emblem code threw, but now we
# support multi-line syntax.
test "it doesn't throw when indenting after a line with inline content", ->
emblem =
"""
p Hello
p invalid
"""
shouldCompileTo emblem, "<p>Hello p invalid</p>"
test "it throws on half dedent", ->
emblem =
"""
p
span This is ok
span This aint
"""
shouldThrow -> CompilerContext.compile emblem
test "new indentation levels don't have to match parents'", ->
emblem =
"""
p
span
div
span yes
"""
shouldCompileTo emblem, "<p><span><div><span>yes</span></div></span></p>"
suite "whitespace fussiness"
test "spaces after html elements", ->
shouldCompileTo "p \n span asd", "<p><span>asd</span></p>"
shouldCompileTo "p \nspan \n\ndiv\nspan", "<p></p><span></span><div></div><span></span>"
test "spaces after mustaches", ->
shouldCompileTo "each foo \n p \n span", { foo: [1,2] }, "<p></p><span></span><p></p><span></span>"
suite "attribute shorthand"
test "id shorthand", ->
shouldCompileTo "#woot", '<div id="woot"></div>'
shouldCompileTo "span#woot", '<span id="woot"></span>'
test "class shorthand", ->
shouldCompileTo ".woot", '<div class="woot"></div>'
shouldCompileTo "span.woot", '<span class="woot"></span>'
shouldCompileTo "span.woot.loot", '<span class="woot loot"></span>'
test "class can come first", ->
shouldCompileTo ".woot#hello", '<div id="hello" class="woot"></div>'
shouldCompileTo "span.woot#hello", '<span id="hello" class="woot"></span>'
shouldCompileTo "span.woot.loot#hello", '<span id="hello" class="woot loot"></span>'
shouldCompileTo "span.woot.loot#hello.boot", '<span id="hello" class="woot loot boot"></span>'
suite "full attributes - tags with content"
test "class only", ->
shouldCompileTo 'p class="yes" Blork', '<p class="yes">Blork</p>'
test "id only", ->
shouldCompileTo 'p id="yes" Hyeah', '<p id="yes">Hyeah</p>'
test "class and id", ->
shouldCompileTo 'p id="yes" class="no" Blork', '<p id="yes" class="no">Blork</p>'
test "class and id and embedded html one-liner", ->
shouldCompileTo 'p id="yes" class="no" One <b>asd</b>!', '<p id="yes" class="no">One <b>asd</b>!</p>'
test "bracketed attributes", ->
emblem =
"""
p [
id="yes"
class="no" ]
| Bracketed Attributes FTW!
"""
shouldCompileTo emblem, '<p id="yes" class="no">Bracketed Attributes FTW!</p>'
test "bracketed text", ->
emblem =
"""
p [ Bracketed text is cool ]
"""
shouldCompileTo emblem, '<p>[ Bracketed text is cool ]</p>'
test "bracketed text indented", ->
emblem =
"""
p
| [ Bracketed text is cool ]
"""
shouldCompileTo emblem, '<p>[ Bracketed text is cool ]</p>'
test "nesting", ->
emblem =
"""
p class="hello" data-foo="gnarly"
span Yes
"""
shouldCompileTo emblem, '<p class="hello" data-foo="gnarly"><span>Yes</span></p>'
suite "full attributes - mixed quotes"
test "single empty", ->
shouldCompileTo "p class=''", '<p class=""></p>'
test "single full", ->
shouldCompileTo "p class='woot yeah'", '<p class="woot yeah"></p>'
test "mixed", ->
shouldCompileTo "p class='woot \"oof\" yeah'", '<p class="woot "oof" yeah"></p>'
suite "full attributes - tags without content"
test "empty", ->
shouldCompileTo 'p class=""', '<p class=""></p>'
test "class only", ->
shouldCompileTo 'p class="yes"', '<p class="yes"></p>'
test "id only", ->
shouldCompileTo 'p id="yes"', '<p id="yes"></p>'
test "class and id", ->
shouldCompileTo 'p id="yes" class="no"', '<p id="yes" class="no"></p>'
suite "full attributes w/ mustaches"
test "with mustache", ->
shouldCompileTo 'p class="foo {{yes}}"', {yes: "ALEX"}, '<p class="foo ALEX"></p>'
shouldCompileTo 'p class="foo {{yes}}" Hello', {yes: "ALEX"}, '<p class="foo ALEX">Hello</p>'
emblem =
"""
p class="foo {{yes}}"
| Hello
"""
shouldCompileTo emblem, {yes: "ALEX"}, '<p class="foo ALEX">Hello</p>'
test "with mustache calling helper", ->
shouldCompileTo 'p class="foo {{{echo "YES"}}}"', '<p class="foo ECHO YES"></p>'
shouldCompileTo 'p class="foo #{echo "NO"} and {{{echo "YES"}}}" Hello', '<p class="foo ECHO NO and ECHO YES">Hello</p>'
emblem =
"""
p class="foo {{echo "BORF"}}"
| Hello
"""
shouldCompileTo emblem, '<p class="foo ECHO BORF">Hello</p>'
suite "boolean attributes"
test "static", ->
shouldCompileTo 'p borf=true', '<p borf></p>'
shouldCompileTo 'p borf=true Woot', '<p borf>Woot</p>'
shouldCompileTo 'p borf=false', '<p></p>'
shouldCompileTo 'p borf=false Nork', '<p>Nork</p>'
shouldCompileTo 'option selected=true Thingeroo', '<option selected>Thingeroo</option>'
#test "dynamic", ->
## TODO
#shouldCompileTo 'p borf=foo', { foo: true }, '<p borf></p>'
#shouldCompileTo 'p borf=foo', { foo: false }, '<p></p>'
#shouldCompileTo 'p borf=foo Yeah', { foo: true }, '<p borf>Yeah</p>'
#shouldCompileTo 'p borf=foo Naww', { foo: false }, '<p>Naww</p>'
#shouldCompileTo 'p borf=foo Naww', { foo: null }, '<p>Naww</p>'
#shouldCompileTo 'p borf=foo Naww', { foo: undefined }, '<p>Naww</p>'
#shouldCompileTo 'p borf=foo Naww', { foo: 0 }, '<p borf="0">Naww</p>'
suite "html nested"
test "basic", ->
emblem =
"""
p
span Hello
strong Hi
div
p Hooray
"""
shouldCompileTo emblem, '<p><span>Hello</span><strong>Hi</strong></p><div><p>Hooray</p></div>'
test "empty nest", ->
emblem =
"""
p
span
strong
i
"""
shouldCompileTo emblem, '<p><span><strong><i></i></strong></span></p>'
test "empty nest w/ attribute shorthand", ->
emblem =
"""
p.woo
span#yes
strong.no.yes
i
"""
shouldCompileTo emblem, '<p class="woo"><span id="yes"><strong class="no yes"><i></i></strong></span></p>'
suite "simple mustache"
test "various one-liners", ->
emblem =
"""
= foo
arf
p = foo
span.foo
p data-foo="yes" = goo
"""
shouldCompileTo emblem,
{ foo: "ASD", arf: "QWE", goo: "WER" },
'ASDQWE<p>ASD</p><span class="foo"></span><p data-foo="yes">WER</p>'
test "double =='s un-escape", ->
emblem =
"""
== foo
foo
p == foo
"""
shouldCompileTo emblem,
{ foo: '<span>123</span>' },
'<span>123</span>&lt;span&gt;123&lt;/span&gt;<p><span>123</span></p>'
test "nested combo syntax", ->
emblem =
"""
ul = each items
li = foo
"""
shouldCompileTo emblem,
{ items: [ { foo: "YEAH"}, { foo: "BOI" } ] },
'<ul><li>YEAH</li><li>BOI</li></ul>'
suite "mustache helpers"
Handlebars.registerHelper 'booltest', (options) ->
hash = options.hash
result = if hash.what == true
"true"
else if hash.what == false
"false"
else "neither"
result
Handlebars.registerHelper 'hashtypetest', (options) ->
hash = options.hash
typeof hash.what
Handlebars.registerHelper 'typetest', (num, options) ->
typeof num
Handlebars.registerHelper 'frank', ->
options = arguments[arguments.length - 1]
"WOO: #{options.hash.text} #{options.hash.text2}"
Handlebars.registerHelper 'sally', ->
options = arguments[arguments.length - 1]
params = Array::slice.call arguments, 0, -1
param = params[0] || 'none'
if options.fn
content = options.fn @
new Handlebars.SafeString """<sally class="#{param}">#{content}</sally>"""
else
content = param
new Handlebars.SafeString """<sally class="#{param}">#{content}</sally>"""
test "basic", -> shouldCompileTo 'echo foo', {foo: "YES"}, 'ECHO YES'
test "hashed parameters should work", ->
shouldCompileTo 'frank text="YES" text2="NO"', 'WOO: YES NO'
Handlebars.registerHelper 'concatenator', ->
options = arguments[arguments.length - 1]
new Handlebars.SafeString ("'#{key}'='#{value}'" for key, value of options.hash).sort().join( " " )
test "negative integers should work", ->
shouldCompileTo 'concatenator positive=100 negative=-100', "'negative'='-100' 'positive'='100'"
test "booleans", ->
shouldCompileToString 'typetest true', 'boolean'
shouldCompileToString 'typetest false', 'boolean'
shouldCompileTo 'booltest what=false', 'false'
shouldCompileTo 'booltest what=true', 'true'
shouldCompileTo 'booltest what="false"', 'neither'
shouldCompileTo 'booltest what="true"', 'neither'
test "integers", ->
shouldCompileToString 'typetest 200', 'number'
shouldCompileTo 'hashtypetest what=1', 'number'
shouldCompileTo 'hashtypetest what=200', 'number'
test "nesting", ->
emblem =
"""
sally
p Hello
"""
shouldCompileTo emblem, '<sally class="none"><p>Hello</p></sally>'
test "recursive nesting", ->
emblem =
"""
sally
sally
p Hello
"""
shouldCompileTo emblem, '<sally class="none"><sally class="none"><p>Hello</p></sally></sally>'
test "recursive nesting pt 2", ->
emblem =
"""
sally
sally thing
p Hello
"""
shouldCompileTo emblem, { thing: "woot" }, '<sally class="none"><sally class="woot"><p>Hello</p></sally></sally>'
test "bracketed nested statement", ->
emblem =
"""
sally [
'foo'
something="false" ]
| Bracketed helper attrs!
"""
shouldCompileTo emblem, '<sally class="foo">Bracketed helper attrs!</sally>'
test "bracketed nested block", ->
emblem =
"""
sally [
'foo'
something="false" ]
p Bracketed helper attrs!
"""
shouldCompileTo emblem, '<sally class="foo"><p>Bracketed helper attrs!</p></sally>'
Handlebars.registerHelper 'view', (param, a, b, c) ->
options = arguments[arguments.length - 1]
content = param
content = options.fn @ if options.fn
hashString = ""
for own k,v of options.hash
hashString += " #{k}=#{v}"
hashString = " nohash" unless hashString
new Handlebars.SafeString """<#{param}#{hashString}>#{content}</#{param}>"""
suite "capitalized line-starter"
test "should invoke `view` helper by default", ->
emblem =
"""
SomeView
"""
shouldEmberPrecompileToHelper emblem, 'view'
#shouldCompileToString emblem, '<SomeView nohash>SomeView</SomeView>'
test "should not invoke `view` helper for vanilla HB", ->
emblem =
"""
SomeView
"""
shouldCompileToString emblem, {SomeView: "ALEX"}, 'ALEX'
test "should support block mode", ->
emblem =
"""
SomeView
p View content
"""
#shouldCompileToString emblem, '<SomeView nohash><p>View content</p></SomeView>'
shouldEmberPrecompileToHelper emblem, 'view'
test "should not kick in if preceded by equal sign", ->
emblem =
"""
= SomeView
"""
shouldCompileTo emblem, { SomeView: 'erp' }, 'erp'
test "should not kick in explicit {{mustache}}", ->
emblem =
"""
p Yeah {{SomeView}}
"""
shouldCompileTo emblem, { SomeView: 'erp' }, '<p>Yeah erp</p>'
# TODO test overriding the default helper name (instead of always "view")
suite "bang syntax defaults to `unbound` helper syntax"
Handlebars.registerHelper 'unbound', ->
options = arguments[arguments.length - 1]
params = Array::slice.call arguments, 0, -1
stringedParams = params.join(' ')
content = if options.fn then options.fn @ else stringedParams
new Handlebars.SafeString """<unbound class="#{stringedParams}">#{content}</unbound>"""
test "bang helper defaults to `unbound` invocation", ->
emblem =
"""
foo! Yar
= foo!
"""
shouldCompileToString emblem, '<unbound class="foo Yar">foo Yar</unbound><unbound class="foo">foo</unbound>'
test "bang helper works with blocks", ->
emblem =
"""
hey! you suck
= foo!
"""
shouldCompileToString emblem, '<unbound class="hey you suck"><unbound class="foo">foo</unbound></unbound>'
suite "question mark syntax defaults to `if` helper syntax"
test "? helper defaults to `if` invocation", ->
emblem =
"""
foo?
p Yeah
"""
shouldCompileTo emblem, { foo: true }, '<p>Yeah</p>'
test "else works", ->
emblem =
"""
foo?
p Yeah
else
p No
"""
shouldCompileTo emblem, { foo: false }, '<p>No</p>'
test "compound", ->
emblem =
"""
p = foo?
| Hooray
else
| No
p = bar?
| Hooray
else
| No
"""
shouldCompileTo emblem, { foo: true, bar: false }, '<p>Hooray</p><p>No</p>'
test "compound", ->
emblem =
"""
p = foo?
bar
else
baz
"""
shouldCompileTo emblem, { foo: true, bar: "borf", baz: "narsty" }, '<p>borf</p>'
suite "conditionals"
test "simple if statement", ->
emblem =
"""
if foo
| Foo
if bar
| Bar
"""
shouldCompileTo emblem, {foo: true, bar: false}, 'Foo'
test "if else ", ->
emblem =
"""
if foo
| Foo
if bar
| Bar
else
| Woot
else
| WRONG
if bar
| WRONG
else
| Hooray
"""
shouldCompileTo emblem, {foo: true, bar: false}, 'FooWootHooray'
test "else with preceding `=`", ->
emblem =
"""
= if foo
p Yeah
= else
p No
= if bar
p Yeah!
= else
p No!
=if bar
p Yeah!
=else
p No!
"""
shouldCompileTo emblem, {foo: true, bar: false}, '<p>Yeah</p><p>No!</p><p>No!</p>'
test "unless", ->
emblem =
"""
unless bar
| Foo
unless foo
| Bar
else
| Woot
else
| WRONG
unless foo
| WRONG
else
| Hooray
"""
shouldCompileTo emblem, {foo: true, bar: false}, 'FooWootHooray'
test "else followed by newline doesn't gobble else content", ->
emblem =
"""
if something
p something
else
if nothing
p nothing
else
p not nothing
"""
shouldCompileTo emblem, {}, '<p>not nothing</p>'
suite "class shorthand and explicit declaration is coalesced"
test "when literal class is used", ->
shouldCompileTo 'p.foo class="bar"', '<p class="foo bar"></p>'
test "when ember expression is used with variable", ->
shouldCompileTo 'p.foo class=bar', {bar: 'baz'}, '<p bind-attr class to :foo bar></p>'
test "when ember expression is used with variable in braces", ->
result = shouldEmberPrecompileToHelper 'p.foo class={ bar }'
ok -1 != result.indexOf '\'class\': (":foo bar")'
test "when ember expression is used with constant in braces", ->
result = shouldEmberPrecompileToHelper 'p.foo class={ :bar }'
ok -1 != result.indexOf '\'class\': (":foo :bar")'
test "when ember expression is used with constant and variable in braces", ->
result = shouldEmberPrecompileToHelper 'p.foo class={ :bar bar }'
ok -1 != result.indexOf '\'class\': (":foo :bar bar")'
test "when ember expression is used with bind-attr", ->
result = shouldEmberPrecompileToHelper 'p.foo{ bind-attr class="bar" }'
ok -1 != result.indexOf '\'class\': (":foo bar")'
test "when ember expression is used with bind-attr and multiple attrs", ->
result = shouldEmberPrecompileToHelper 'p.foo{ bind-attr something=bind class="bar" }'
ok -1 != result.indexOf '\'class\': (":foo bar")'
test "only with bind-attr helper", ->
result = shouldEmberPrecompileToHelper 'p.foo{ someHelper class="bar" }', 'someHelper'
ok -1 != result.indexOf '\'class\': ("bar")'
ok -1 != result.indexOf 'class=\\"foo\\"'
bindAttrHelper = ->
options = arguments[arguments.length - 1]
params = Array::slice.call arguments, 0, -1
bindingString = ""
for own k,v of options.hash
bindingString += " #{k} to #{v}"
bindingString = " narf" unless bindingString
param = params[0] || 'none'
"bind-attr#{bindingString}"
Handlebars.registerHelper 'bind-attr', bindAttrHelper
EmberHandlebars.registerHelper 'bind-attr', bindAttrHelper
suite "bind-attr behavior for unquoted attribute values"
test "basic", ->
emblem = 'p class=foo'
shouldCompileTo emblem, {foo:"YEAH"}, '<p class="YEAH"></p>'
shouldEmberPrecompileToHelper emblem
test "basic w/ underscore", ->
emblem = 'p class=foo_urns'
shouldCompileTo emblem, {foo_urns: "YEAH"}, '<p class="YEAH"></p>'
shouldEmberPrecompileToHelper emblem
test "subproperties", ->
emblem = 'p class=foo._death.woot'
shouldCompileTo emblem, {foo: { _death: { woot: "YEAH" } }}, '<p class="YEAH"></p>'
shouldEmberPrecompileToHelper emblem
test "multiple", ->
shouldCompileTo 'p class=foo id="yup" data-thinger=yeah Hooray', { foo: "FOO", yeah: "YEAH" },
'<p class="FOO" id="yup" data-thinger="YEAH">Hooray</p>'
test "class bind-attr special syntax", ->
emblem = 'p class=foo:bar:baz'
shouldEmberPrecompileToHelper emblem
shouldThrow (-> CompilerContext.compile emblem)
test "class bind-attr braced syntax w/ underscores and dashes", ->
shouldEmberPrecompileToHelper 'p class={f-oo:bar :b_az}'
shouldEmberPrecompileToHelper 'p class={ f-oo:bar :b_az }'
shouldEmberPrecompileToHelper 'p class={ f-oo:bar :b_az } Hello'
emblem =
"""
.input-prepend class={ filterOn:input-append }
span.add-on
"""
shouldEmberPrecompileToHelper emblem
test "exclamation modifier (vanilla)", ->
emblem = 'p class=foo!'
# exclamation is no-op in vanilla HB
shouldCompileTo emblem, {foo:"YEAH"}, '<p class="YEAH"></p>'
test "exclamation modifier (ember)", ->
emblem = 'p class=foo!'
result = precompileEmber emblem
ok result.match /p class/
ok result.match /helpers\.unbound.*foo/
suite "in-tag explicit mustache"
Handlebars.registerHelper 'inTagHelper', (p) ->
return p;
test "single", ->
shouldCompileTo 'p{inTagHelper foo}', {foo: "ALEX"}, '<p ALEX></p>'
test "double", ->
shouldCompileTo 'p{inTagHelper foo}', {foo: "ALEX"}, '<p ALEX></p>'
test "triple", ->
shouldCompileTo 'p{inTagHelper foo}', {foo: "ALEX"}, '<p ALEX></p>'
Handlebars.registerHelper 'insertClass', (p) ->
return 'class="' + p + '"'
test "with singlestache", ->
shouldCompileTo 'p{insertClass foo} Hello', {foo: "yar"}, '<p class=&quot;yar&quot;>Hello</p>'
test "singlestache can be used in text nodes", ->
shouldCompileTo 'p Hello {dork}', '<p>Hello {dork}</p>'
test "with doublestache", ->
shouldCompileTo 'p{{insertClass foo}} Hello', {foo: "yar"}, '<p class=&quot;yar&quot;>Hello</p>'
test "with triplestache", ->
shouldCompileTo 'p{{{insertClass foo}}} Hello', {foo: "yar"}, '<p class="yar">Hello</p>'
test "multiple", ->
shouldCompileTo 'p{{{insertClass foo}}}{{{insertClass boo}}} Hello',
{foo: "yar", boo: "nar"},
'<p class="yar" class="nar">Hello</p>'
test "with nesting", ->
emblem =
"""
p{{bind-attr class="foo"}}
span Hello
"""
shouldCompileTo emblem, {foo: "yar"},
'<p bind-attr class to foo><span>Hello</span></p>'
suite "actions"
Handlebars.registerHelper 'action', ->
options = arguments[arguments.length - 1]
params = Array::slice.call arguments, 0, -1
hashString = ""
paramsString = params.join('|')
# TODO: bad because it relies on hash ordering?
# is this guaranteed? guess it doesn't rreeeeeally
# matter since order's not being tested.
for own k,v of options.hash
hashString += " #{k}=#{v}"
hashString = " nohash" unless hashString
"action #{paramsString}#{hashString}"
test "basic (click)", ->
emblem =
"""
button click="submitComment" Submit Comment
"""
shouldCompileToString emblem, '<button action submitComment on=click>Submit Comment</button>'
test "basic (click) followed by attr", ->
emblem =
"""
button click="submitComment" class="foo" Submit Comment
"""
shouldCompileToString emblem, '<button action submitComment on=click class="foo">Submit Comment</button>'
emblem =
"""
button click="submitComment 'omg'" class="foo" Submit Comment
"""
shouldCompileToString emblem, '<button action submitComment|omg on=click class="foo">Submit Comment</button>'
test "nested (mouseEnter)", ->
emblem =
"""
a mouseEnter='submitComment target="view"'
| Submit Comment
"""
shouldCompileToString emblem, '<a action submitComment target=view on=mouseEnter>Submit Comment</a>'
test "nested (mouseEnter, doublequoted)", ->
emblem =
"""
a mouseEnter="submitComment target='view'"
| Submit Comment
"""
shouldCompileToString emblem, '<a action submitComment target=view on=mouseEnter>Submit Comment</a>'
test "manual", ->
emblem =
"""
a{action submitComment target="view"} Submit Comment
"""
shouldCompileToString emblem, '<a action submitComment target=view>Submit Comment</a>'
test "manual nested", ->
emblem =
"""
a{action submitComment target="view"}
p Submit Comment
"""
shouldCompileToString emblem, '<a action submitComment target=view><p>Submit Comment</p></a>'
suite "haml style"
test "basic", ->
emblem =
"""
%borf
"""
shouldCompileToString emblem, '<borf></borf>'
test "nested", ->
emblem =
"""
%borf
%sporf Hello
"""
shouldCompileToString emblem, '<borf><sporf>Hello</sporf></borf>'
test "capitalized", ->
emblem =
"""
%Alex alex
%Alex
%Woot
"""
shouldCompileToString emblem, '<Alex>alex</Alex><Alex><Woot></Woot></Alex>'
test "funky chars", ->
emblem =
"""
%borf:narf
%borf:narf Hello, {{foo}}.
%alex = foo
"""
shouldCompileToString emblem,
{ foo: "Alex" },
'<borf:narf></borf:narf><borf:narf>Hello, Alex.</borf:narf><alex>Alex</alex>'
suite "line-based errors"
test "line number is provided for pegjs error", ->
emblem =
"""
p Hello
p Hello {{narf}
"""
shouldThrow (-> CompilerContext.compile emblem), "line 2"
# https://github.com/machty/emblem.js/issues/6
test "single quote test", ->
emblem =
"""
button click='p' Frank
/ form s='d target="App"'
label I'm a label!
"""
shouldCompileToString emblem, '<button action p on=click>Frank</button>'
test "double quote test", ->
emblem =
"""
button click="p" Frank
/ form s='d target="App"'
label I'm a label!
"""
shouldCompileToString emblem, '<button action p on=click>Frank</button>'
test "no quote test", ->
emblem =
"""
button click=p Frank
/ form s='d target="App"'
label I'm a label!
"""
shouldCompileToString emblem, '<button action p on=click>Frank</button>'
suite "mustache DOM attribute shorthand"
test "tagName w/o space", ->
emblem =
"""
App.FunView%span
"""
result = precompileEmber emblem
ok result.match /helpers\.view/
ok result.match /App\.FunView/
ok result.match /tagName.*span/
test "tagName w/ space", ->
emblem =
"""
App.FunView %span
"""
result = precompileEmber emblem
ok result.match /helpers\.view/
ok result.match /App\.FunView/
ok result.match /tagName.*span/
test "tagName block", ->
emblem =
"""
view App.FunView%span
p Hello
"""
shouldCompileToString emblem, '<App.FunView tagName=span><p>Hello</p></App.FunView>'
test "class w/ space (needs space)", ->
emblem =
"""
App.FunView .bork
"""
result = precompileEmber emblem
ok result.match /helpers\.view/
ok result.match /App\.FunView/
ok result.match /class.*bork/
test "multiple classes", ->
emblem =
"""
App.FunView .bork.snork
"""
result = precompileEmber emblem
ok result.match /helpers\.view/
ok result.match /App\.FunView/
ok result.match /class.*bork.*snork/
test "elementId", ->
emblem =
"""
App.FunView#ohno
"""
result = precompileEmber emblem
ok result.match /helpers\.view/
ok result.match /App\.FunView/
ok result.match /elementId.*ohno/
test "mixed w/ hash`", ->
emblem =
"""
App.FunView .bork.snork funbags="yeah"
"""
result = precompileEmber emblem
ok result.match /helpers\.view/
ok result.match /App\.FunView/
ok result.match /class.*bork.*snork/
ok result.match /hash/
ok result.match /funbags/
ok result.match /yeah/
test "mixture of all`", ->
emblem =
"""
App.FunView%alex#hell.bork.snork funbags="yeah"
"""
result = precompileEmber emblem
ok result.match /helpers\.view/
ok result.match /App\.FunView/
ok result.match /tagName.*alex/
ok result.match /elementId.*hell/
ok result.match /class.*bork.*snork/
ok result.match /hash/
ok result.match /funbags/
ok result.match /yeah/
suite "self-closing html tags"
test "br", ->
emblem =
"""
br
"""
shouldCompileToString emblem, '<br />'
test "br paragraph example", ->
emblem =
"""
p
| LOL!
br
| BORF!
"""
shouldCompileToString emblem, '<p>LOL!<br />BORF!</p>'
test "input", ->
emblem =
"""
input type="text"
"""
shouldCompileToString emblem, '<input type="text" />'
suite "ember."
test "should precompile with EmberHandlebars", ->
emblem =
"""
input type="text"
"""
result = Emblem.precompile(EmberHandlebars, 'p Hello').toString()
ok result.match '<p>Hello</p>'
suite "old school handlebars"
test "array", ->
emblem =
'''
goodbyes
| #{text}!
| cruel #{world}!
'''
hash = {goodbyes: [{text: "goodbye"}, {text: "Goodbye"}, {text: "GOODBYE"}], world: "world"}
shouldCompileToString emblem, hash, "goodbye! Goodbye! GOODBYE! cruel world!"
hash = {goodbyes: [], world: "world"}
shouldCompileToString emblem, hash, "cruel world!"
Handlebars.registerPartial('hbPartial', '<a href="/people/{{id}}">{{name}}</a>')
test "calling handlebars partial", ->
emblem =
'''
> hbPartial
| Hello #{> hbPartial}
'''
shouldCompileToString emblem,
{ id: 666, name: "Death" },
'<a href="/people/666">Death</a>Hello <a href="/people/666">Death</a>'
Emblem.registerPartial(Handlebars, 'emblemPartial', 'a href="/people/{{id}}" = name')
Emblem.registerPartial(Handlebars, 'emblemPartialB', 'p Grr')
Emblem.registerPartial(Handlebars, 'emblemPartialC', 'p = a')
test "calling emblem partial", ->
shouldCompileToString '> emblemPartial', { id: 666, name: "Death" }, '<a href="/people/666">Death</a>'
test "calling emblem partial with context", ->
shouldCompileToString '> emblemPartialC foo', { foo: { a: "YES" } }, '<p>YES</p>'
test "partials in mustaches", ->
emblem =
"""
| Hello, {{> emblemPartialC foo}}{{>emblemPartialB}}{{>emblemPartialB }}
"""
shouldCompileToString emblem, { foo: { a: "YES" } }, 'Hello, <p>YES</p><p>Grr</p><p>Grr</p>'
test "handlebars dot-separated paths with segment-literal notation", ->
emblem =
'''
p = articles.[3]
'''
shouldCompileTo emblem, { articles: ['zero', 'one', 'two', 'three']}, '<p>three</p>'
test "handlebars dot-separated paths with segment-literal notation, more nesting", ->
emblem =
'''
p = articles.[3].[#comments].[0]
'''
shouldCompileTo emblem, { articles: [{}, {}, {}, {'#comments': ['bazinga']}]}, '<p>bazinga</p>'
test "../path as inMustacheParam recognized correctly as pathIdNode instead of classShorthand", ->
Handlebars.registerHelper 'jumpToParent', (link) ->
new Handlebars.SafeString "<a href='#{link}'>Jump to parent top</a>"
emblem =
'''
each children
jumpToParent ../parentLink
'''
shouldCompileTo emblem, {parentLink: '#anchor', children: [{}]}, '<a href=\'#anchor\'>Jump to parent top</a>'
test "block as #each", ->
emblem =
'''
thangs
p Woot #{yeah}
'''
shouldCompileToString emblem, { thangs: [{yeah: 123}, {yeah:456}] }, '<p>Woot 123</p><p>Woot 456</p>'
if supportsEachHelperDataKeywords
suite "each block helper keywords prefixed by @"
test "#each with @index", ->
emblem =
'''
thangs
p #{@index} Woot #{yeah}
'''
shouldCompileToString emblem, { thangs: [{yeah: 123}, {yeah:456}] }, '<p>0 Woot 123</p><p>1 Woot 456</p>'
test "#each with @key", ->
emblem =
'''
each thangs
p #{@key}: #{this}
'''
shouldCompileTo emblem, { thangs: {'@key': 123, 'works!':456} }, '<p>@key: 123</p><p>works!: 456</p>'
test "#each with @key, @index", ->
emblem =
'''
each thangs
p #{@index} #{@key}: #{this}
'''
shouldCompileTo emblem, { thangs: {'@key': 123, 'works!':456} }, '<p>0 @key: 123</p><p>1 works!: 456</p>'
test "#each with @key, @first", ->
emblem =
'''
each thangs
if @first
p First item
else
p #{@key}: #{this}
'''
shouldCompileTo emblem, { thangs: {'@key': 123, 'works!':456} }, '<p>First item</p><p>works!: 456</p>'
###
test "partial in block", ->
emblem =
"""
ul = people
> link
"""
data =
people: [
{ "name": "Alan", "id": 1 }
{ "name": "Yehuda", "id": 2 }
]
shouldCompileToString emblem, data, '<ul><a href="/people/1">Alan</a><a href="/people/2">Yehuda</a><ul>'
###
#suite "helper hash"
#test "quoteless values get treated as bindings", ->
#emblem =
#"""
#view SomeView a=b
#| Yes
#"""
#shouldCompileToString emblem, '<SomeView aBinding=b>Yes</SomeView>'
#test "more complex", ->
#emblem =
#"""
#view SomeView a=b foo=thing.gnar
#"""
#shouldCompileToString emblem, '<SomeView aBinding=b fooBinding=thing.gnar>SomeView</SomeView>'
suite "inline block helper"
test "text only", ->
emblem =
"""
view SomeView | Hello
"""
shouldCompileToString emblem, '<SomeView nohash>Hello</SomeView>'
test "multiline", ->
emblem =
"""
view SomeView | Hello,
How are you?
Sup?
"""
shouldCompileToString emblem, '<SomeView nohash>Hello, How are you? Sup?</SomeView>'
test "more complicated", ->
emblem =
"""
view SomeView borf="yes" | Hello,
How are you?
Sup?
"""
shouldCompileToString emblem, '<SomeView borf=yes>Hello, How are you? Sup?</SomeView>'
suite "copy paste html"
test "indented", ->
emblem =
"""
<p>
<span>This be some text</span>
<title>Basic HTML Sample Page</title>
</p>
"""
shouldCompileToString emblem, '<p><span>This be some text</span><title>Basic HTML Sample Page</title></p>'
test "flatlina", ->
emblem =
"""
<p>
<span>This be some text</span>
<title>Basic HTML Sample Page</title>
</p>
"""
shouldCompileToString emblem, '<p><span>This be some text</span><title>Basic HTML Sample Page</title></p>'
test "bigass", ->
expect(0)
return "PENDING"
emblem =
"""
<div class="content">
<p>
We design and develop ambitious web and mobile applications,
</p>
<p>
A more official portfolio page is on its way, but in the meantime,
check out
</p>
</div>
"""
expected = '<div class="content"><p> We design and develop ambitious web and mobile applications, </p><p> A more official portfolio page is on its way, but in the meantime, check out</p></div>'
shouldCompileToString emblem, expected
suite "`this` keyword"
test "basic", ->
emblem = '''
each foo
p = this
this
'''
shouldCompileTo emblem,
{ foo: [ "Alex", "Emily" ] },
'<p>Alex</p>Alex<p>Emily</p>Emily'
suite "colon separator"
test "basic", ->
emblem = 'each foo: p Hello, #{this}'
shouldCompileTo emblem,
{ foo: [ "Alex", "Emily", "Nicole" ] },
'<p>Hello, Alex</p><p>Hello, Emily</p><p>Hello, Nicole</p>'
test "html stack", ->
emblem = '.container: .row: .span5: span Hello'
shouldCompileToString emblem,
'<div class="container"><div class="row"><div class="span5"><span>Hello</span></div></div></div>'
test "epic", ->
emblem = '''
.container: .row: .span5
ul#list data-foo="yes": each foo: li
span: this
'''
shouldCompileTo emblem, { foo: ["a","b"] },
'<div class="container"><div class="row"><div class="span5"><ul id="list" data-foo="yes"><li><span>a</span></li><li><span>b</span></li></ul></div></div></div>'
test "html stack elements only", ->
emblem = 'p: span: div: p: foo'
shouldCompileToString emblem, { foo: "alex" },
'<p><span><div><p>alex</p></div></span></p>'
test "mixed separators", ->
emblem = '.fun = each foo: %nork = this'
shouldCompileTo emblem,
{ foo: [ "Alex", "Emily", "Nicole" ] },
'<div class="fun"><nork>Alex</nork><nork>Emily</nork><nork>Nicole</nork></div>'
test "mixed separators rewritten", ->
emblem = '.fun: each foo: %nork: this'
shouldCompileTo emblem,
{ foo: [ "Alex", "Emily", "Nicole" ] },
'<div class="fun"><nork>Alex</nork><nork>Emily</nork><nork>Nicole</nork></div>'
test "with text terminator", ->
emblem = '.fun: view SomeView | Hello'
shouldCompileToString emblem, '<div class="fun"><SomeView nohash>Hello</SomeView></div>'
test "test from heartsentwined", ->
shouldCompileTo 'li data-foo=bar: a', { bar: "abc" }, '<li data-foo="abc"><a></a></li>'
shouldCompileTo "li data-foo='bar': a", '<li data-foo="bar"><a></a></li>'
test "mixture of colon and indentation", ->
emblem = """
li data-foo=bar: a
baz
"""
shouldCompileTo emblem, { bar: "abc", baz: "Hello" }, '<li data-foo="abc"><a>Hello</a></li>'
test "mixture of colon and indentation pt.2", ->
emblem = """
ul
li data-foo=bar: a quux
li data-foo='bar': a quux
li data-foo=bar href='#': a quux
"""
result = precompileEmber emblem
ok(!result.match "a quux")
suite "base indent / predent"
test "predent", ->
emblem = " \n"
s =
"""
pre
` This
` should
` hopefully
` work, and work well.
"""
emblem += s
shouldCompileToString emblem, '<pre>This\n should\n hopefully\n work, and work well.\n</pre>'
test "mixture", ->
emblem = " \n"
emblem += " p Hello\n"
emblem += " p\n"
emblem += " | Woot\n"
emblem += " span yes\n"
shouldCompileToString emblem, '<p>Hello</p><p>Woot</p><span>yes</span>'
test "mixture w/o opening blank", ->
emblem = " p Hello\n"
emblem += " p\n"
emblem += " | Woot\n"
emblem += " span yes\n"
shouldCompileToString emblem, '<p>Hello</p><p>Woot</p><span>yes</span>'
test "w/ blank lines", ->
emblem = " p Hello\n"
emblem += " p\n"
emblem += "\n"
emblem += " | Woot\n"
emblem += "\n"
emblem += " span yes\n"
shouldCompileToString emblem, '<p>Hello</p><p>Woot</p><span>yes</span>'
test "w/ blank whitespaced lines", ->
emblem = " p Hello\n"
emblem += " p\n"
emblem += "\n"
emblem += " | Woot\n"
emblem += " \n"
emblem += " \n"
emblem += " \n"
emblem += "\n"
emblem += " span yes\n"
emblem += "\n"
emblem += " sally\n"
emblem += "\n"
emblem += " \n"
emblem += " | Woot\n"
shouldCompileToString emblem, '<p>Hello</p><p>Woot</p><span>yes</span><sally class="none">Woot</sally>'
suite "EOL Whitespace"
test "shouldn't be necessary to insert a space", ->
emblem =
"""
p Hello,
How are you?
p I'm fine, thank you.
"""
shouldCompileToString emblem, "<p>Hello, How are you?</p><p>I'm fine, thank you.</p>"
suite "misc."
test "end with indent", ->
expect(0)
return "PENDING"
emblem =
"""
div
p
span Butts
em fpokasd
iunw
paosdk
"""
shouldCompileToString emblem, '<div><p><span>Buttsem fpokasdiunw paosdk</span></p></div>'
test "capitalized view helper should not kick in if suffix modifiers present", ->
emblem =
"""
Foo!
"""
shouldCompileToString emblem, '<unbound class="Foo">Foo</unbound>'
test "GH-26: no need for space before equal sign", ->
emblem =
"""
span= foo
"""
shouldCompileToString emblem, {foo: "YEAH"}, '<span>YEAH</span>'
emblem =
"""
span.foo= foo
"""
shouldCompileToString emblem, {foo: "YEAH"}, '<span class="foo">YEAH</span>'
emblem =
"""
span#hooray.foo= foo
"""
shouldCompileToString emblem, {foo: "YEAH"}, '<span id="hooray" class="foo">YEAH</span>'
emblem =
"""
#hooray= foo
"""
shouldCompileToString emblem, {foo: "YEAH"}, '<div id="hooray">YEAH</div>'
emblem =
"""
.hooray= foo
"""
shouldCompileToString emblem, {foo: "YEAH"}, '<div class="hooray">YEAH</div>'
test "numbers in shorthand", ->
shouldCompileToString '#4a', '<div id="4a"></div>'
shouldCompileToString '.4a', '<div class="4a"></div>'
shouldCompileToString '.4', '<div class="4"></div>'
shouldCompileToString '#4', '<div id="4"></div>'
shouldCompileToString '%4', '<4></4>'
shouldCompileToString '%4 ermagerd', '<4>ermagerd</4>'
shouldCompileToString '%4#4.4 ermagerd', '<4 id="4" class="4">ermagerd</4>'
test "Emblem has a VERSION defined", ->
ok(Emblem.VERSION, "Emblem.VERSION should be defined")
test "Windows line endings", ->
emblem = ".navigation\r\n p Hello\r\n#main\r\n | hi"
shouldCompileToString emblem, '<div class="navigation"><p>Hello</p></div><div id="main">hi</div>'
test "backslash doesn't cause infinite loop", ->
emblem =
'''
| \\
'''
shouldCompileTo emblem, "\\"
test "backslash doesn't cause infinite loop with letter", ->
emblem =
'''
| \\a
'''
shouldCompileTo emblem, "\\a"
test "self closing tag with forward slash", ->
emblem =
'''
p/
%bork/
.omg/
#hello.boo/
p/ class="asdasd"
'''
shouldCompileTo emblem, '<p /><bork /><div class="omg" /><div id="hello" class="boo" /><p class="asdasd" />'
test "tagnames and attributes with colons", ->
emblem =
'''
%al:ex match:neer="snork" Hello!
'''
shouldCompileTo emblem, '<al:ex match:neer="snork">Hello!</al:ex>'
test "windows newlines", ->
emblem = "\r\n \r\n p Hello\r\n\r\n"
shouldCompileTo emblem, '<p>Hello</p>'
if supportsSubexpressions
suite "subexpressions"
Handlebars.registerHelper 'echo', (param) ->
"ECHO #{param}"
Handlebars.registerHelper 'echofun', ->
options = Array.prototype.pop.call(arguments)
"FUN = #{options.hash.fun}"
Handlebars.registerHelper 'hello', (param) ->
"hello"
Handlebars.registerHelper 'equal', (x, y) ->
x == y
test "arg-less helper", ->
emblem = 'p {{echo (hello)}}'
shouldCompileTo emblem, '<p>ECHO hello</p>'
emblem = '= echo (hello)'
shouldCompileTo emblem, 'ECHO hello'
test "helper w args", ->
emblem = 'p {{echo (equal 1 1)}}'
shouldCompileTo emblem, '<p>ECHO true</p>'
emblem = '= echo (equal 1 1)'
shouldCompileTo emblem, 'ECHO true'
test "supports much nesting", ->
emblem = 'p {{echo (equal (equal 1 1) true)}}'
shouldCompileTo emblem, '<p>ECHO true</p>'
emblem = '= echo (equal (equal 1 1) true)'
shouldCompileTo emblem, 'ECHO true'
test "with hashes", ->
emblem = 'p {{echo (equal (equal 1 1) true fun="yes")}}'
shouldCompileTo emblem, '<p>ECHO true</p>'
emblem = '= echo (equal (equal 1 1) true fun="yes")'
shouldCompileTo emblem, 'ECHO true'
test "as hashes", ->
emblem = 'p {{echofun fun=(equal 1 1)}}'
shouldCompileTo emblem, '<p>FUN = true</p>'
emblem = '= echofun fun=(equal 1 1)'
shouldCompileTo emblem, 'FUN = true'
test "complex expression", ->
emblem = 'p {{echofun true (hello how="are" you=false) 1 not=true fun=(equal "ECHO hello" (echo (hello))) win="yes"}}'
shouldCompileTo emblem, '<p>FUN = true</p>'
emblem = '= echofun true (hello how="are" you=false) 1 not=true fun=(equal "ECHO hello" (echo (hello))) win="yes"'
shouldCompileTo emblem, 'FUN = true'