1
0
mirror of https://github.com/mgerb/mywebsite synced 2026-01-13 03:02:49 +00:00

Added files

This commit is contained in:
2015-06-25 16:28:41 -05:00
parent 656dca9289
commit eb27b55a54
5621 changed files with 1630154 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
{expect, calls} = require 'racer/test/util'
EventDispatcher = require '../lib/EventDispatcher'
describe 'EventDispatcher', ->
# Names must be a valid object key
name1 = 'test event'
name2 = 89
# Listeners can be anything that is representable in plain JSON
listener1 = [1, 2, 'qu"a"il', "'", {arr: ['x', 'y']}]
listener2 = 0
listener3 = 'stuff'
listener4 = true
# The second and third parameters sent to trigger are simply passed through
# to the callback function. They can be anything.
value1 = 'test value'
options1 = {option: 4}
it 'should work without callbacks', ->
dispatcher = new EventDispatcher
dispatcher.bind name1, listener1
dispatcher.trigger name1, value1, options1
it 'calls onTrigger', calls 2, (done) ->
dispatcher = new EventDispatcher
onTrigger: (name, listener, value, options) ->
expect(listener).to.eql listener1
expect(value).to.equal value1
expect(options).to.equal options1
done()
dispatcher.bind name1, listener1
dispatcher.trigger name1, value1, options1
dispatcher.trigger name1, value1, options1
it 'calls onTrigger without listener', calls 2, (done) ->
dispatcher = new EventDispatcher
onTrigger: (name, listener, value, options) ->
expect(listener).to.equal undefined
expect(value).to.equal value1
expect(options).to.equal options1
done()
dispatcher.bind name1
dispatcher.trigger name1, value1, options1
dispatcher.trigger name1, value1, options1
it 'calls onTrigger for multiple listeners', calls 1, (done) ->
counts = {all: 0}
beforeExit = ->
expect(counts[listener2]).to.equal 1
expect(counts[listener3]).to.equal 3
expect(counts[listener4]).to.equal 1
done()
dispatcher = new EventDispatcher
onTrigger: (name, listener, value, options) ->
counts[listener] = (counts[listener] || 0) + 1
expect(value).to.equal value1
expect(options).to.equal options1
beforeExit() if ++counts.all == 5
dispatcher.bind name1, listener2
dispatcher.bind name1, listener3
dispatcher.bind name1, listener4
dispatcher.bind name2, listener3
dispatcher.trigger name1, value1, options1
dispatcher.trigger name2, value1, options1
dispatcher.trigger name2, value1, options1
it 'test EventDispatcher remove listener after failed trigger', calls 1, (done) ->
dispatcher = new EventDispatcher
onTrigger: ->
done()
return false
dispatcher.bind name1
dispatcher.trigger name1
dispatcher.trigger name1
it 'test EventDispatcher do not trigger twice after double bind', calls 1, (done) ->
dispatcher = new EventDispatcher onTrigger: done
dispatcher.bind name1, listener1
dispatcher.bind name1, listener1
dispatcher.trigger name1
it 'test EventDispatcher bind callback', calls 3, (done) ->
dispatcher = new EventDispatcher
onTrigger: (name, listener, value, options) ->
expect(listener).to.eql listener1
expect(value).to.equal value1
expect(options).to.equal options1
done()
onBind: (name, listener) ->
expect(name).to.equal name1
expect(listener).to.eql listener1
done()
dispatcher.bind name1, listener1
dispatcher.trigger name1, value1, options1
dispatcher.trigger name1, value1, options1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
{expect, calls} = require 'racer/test/util'
{DetachedModel: Model} = require './mocks'
View = require '../lib/View.server'
describe 'App HTML components', ->
view = model = null
beforeEach (done) ->
view = new View
model = new Model
view._init model, false, done
it 'supports void components', ->
view.make 'test', 'say "<app:test2>"'
view.make 'test2', 'hi'
expect(view.get 'test').to.equal 'say "hi"'
it 'supports <derby:view view="name"> lookup', ->
view.make 'test', 'say "<derby:view view=test2>"'
view.make 'test2', 'hi'
expect(view.get 'test').to.equal 'say "hi"'
it 'supports <derby:view view="{{name}}"> lookup', ->
view.make 'test', 'say "<derby:view view={{template}}>"'
view.make 'test2', 'hi'
expect(view.get 'test', {template: 'test2'}).to.equal 'say "hi"'
it 'supports <derby:view view="{{@name}}"> lookup', ->
view.make 'test', '<app:test2 template=test3>'
view.make 'test2', 'say "<derby:view view={{@template}}>"'
view.make 'test3', 'hi'
expect(view.get 'test').to.equal 'say "hi"'
it 'supports <derby:view view="{{@name}}"> lookup via inherit', ->
view.make 'test', '<app:test2 view=test3>'
view.make 'test2', 'say "<derby:view inherit>"'
view.make 'test3', 'hi'
expect(view.get 'test').to.equal 'say "hi"'
it 'supports literal attributes', ->
view.make 'test', 'say "<app:test2 message="Howdy">" or "<app:test2>"'
view.make 'test2', '''
{{#if @message}}
{{@message}}
{{else}}
Yo
{{/}}
'''
expect(view.get 'test').to.equal 'say "Howdy" or "Yo"'
it 'macro attributes are case-insensitive', ->
view.make 'test', 'say "<app:test2 messAGE="Howdy">" or "<app:test2>"'
view.make 'test2', '''
{{#if @messAGE}}
{{@message}}
{{else}}
Yo
{{/}}
'''
expect(view.get 'test').to.equal 'say "Howdy" or "Yo"'
it 'supports boolean and numerical attributes', ->
view.make 'test', '<app:test2 show> / <app:test2 num="-4.5"> / <app:test2>'
view.make 'test2', '''
{{#if @show}}
Hi
{{else if equal(@num, -4.5)}}
Got it
{{else}}
Nada
{{/}}
'''
expect(view.get 'test').to.equal 'Hi / Got it / Nada'
it 'supports variable attributes', ->
view.make 'test', 'say "<app:test2 message="{{myMessage}}">"'
view.make 'test2', '''
{{#if @message}}
{{@message}}
{{else}}
Yo
{{/}}
'''
expect(view.get 'test').to.equal 'say "Yo"'
expect(view.get 'test', myMessage: 'Heyo').to.equal 'say "Heyo"'
it 'supports variable object attributes', ->
view.make 'test', 'say "<app:test2 message="{{myMessage}}">"'
view.make 'test2', '''
{{#with @message}}
{{text}}
{{/}}
'''
expect(view.get 'test', myMessage: {text: 'Heyo'}).to.equal 'say "Heyo"'
it 'supports dot syntax for properties of variable object attributes', ->
view.make 'test', 'say "<app:test2 message="{{myMessage}}">"'
view.make 'test2', '''
{{@message.text}}
'''
expect(view.get 'test', myMessage: {text: 'Heyo'}).to.equal 'say "Heyo"'
it 'supports dot syntax for nested properties of variable object attributes', ->
view.make 'test', 'say "<app:test2 messages="{{myMessages}}">"'
view.make 'test2', '''
{{@messages.0.text}}
'''
expect(view.get 'test', myMessages: [{text: 'Heyo'}]).to.equal 'say "Heyo"'
it 'supports passing through literal attributes', ->
view.make 'test', '<app:test2 message=Howdy>'
view.make 'test2', '<app:test3 text={{@message}}>'
view.make 'test3', '{{@text}}'
expect(view.get 'test').to.equal 'Howdy'
it 'supports passing through bound attributes', ->
view.make 'test', '<app:test2 message={_stuff}>'
view.make 'test2', '<app:test3 text={@message}>'
view.make 'test3', '{{@text}}'
model.set '_stuff', 'Howdy'
expect(view.get 'test').to.equal 'Howdy'
it 'supports this within scope from literal attribute', ->
view.make 'test', 'say "<app:test2 message="Heyo">"'
view.make 'test2', '''
{{#with @message}}
{{this}}
{this}
{{/}}
'''
expect(view.get 'test').to.equal 'say "Heyo<!--$0-->Heyo<!--$$0-->"'
it 'supports bound attributes', ->
view.make 'test', 'say "<app:test2 message="{myMessage}">"'
view.make 'test2', '''
{#if @message}
{@message}
{else}
Yo
{/}
'''
model.set 'myMessage', 'Heyo'
expect(view.get 'test').to.equal 'say "<!--$0--><!--$1-->Heyo<!--$$1--><!--$$0-->"'
it 'supports bound attributes as element attributes', ->
view.make 'test', 'say "<app:test2 message="{myMessage}">"'
view.make 'test2', '<div title={@message}></div>'
model.set 'myMessage', 'Heyo'
expect(view.get 'test').to.equal 'say "<div id=$0 title=Heyo></div>"'
it 'supports blocks in attributes used in an attribute', ->
view.make 'test', 'say "<app:test2 message="Say {{myMessage}}">"'
view.make 'test2', '<div title="{{@message}}"></div>'
model.set 'myMessage', 'Heyo'
expect(view.get 'test').to.equal 'say "<div title="Say Heyo"></div>"'
it 'supports bound blocks in attributes used in an attribute'
# view.make 'test', 'say "<app:test2 message="Say {myMessage}">"'
# view.make 'test2', '<div title="{@message}"></div>'
# model.set 'myMessage', 'Heyo'
# expect(view.get 'test').to.equal 'say "<div id=$0 title="Say Heyo"></div>"'
it 'supports nonvoid components', ->
view.make 'test', '<ul><app:test2><b>Hi!</b></app:test2></ul>'
view.make 'test2', '<li>{{@content}}</li>', {nonvoid: true}
expect(view.get 'test').to.equal '<ul><li><b>Hi!</b></li></ul>'
it 'supports content sections', ->
view.make 'test', '<ul><app:test2><@section><i>Heyo</i></@section><b>Hi!</b></app:test2></ul>'
view.make 'test2', '<li>{{@content}}</li><li>{{@section}}</li>', {nonvoid: true}
expect(view.get 'test').to.equal '<ul><li><b>Hi!</b></li><li><i>Heyo</i></li></ul>'

View File

@@ -0,0 +1,515 @@
{expect, calls} = require 'racer/test/util'
{DetachedModel: Model, ResMock} = require './mocks'
View = require '../lib/View.server'
describe 'View.render', ->
it 'supports view.render with no defined views', ->
view = new View
res = new ResMock
res.onEnd = (html) ->
expect(html).to.match /^<!DOCTYPE html><meta charset=utf-8><title>.*<\/title><script>.*<\/script><script.*><\/script>$/
view.render res
describe 'View', ->
view = model = null
beforeEach (done) ->
view = new View
model = new Model
view._init model, false, done
it 'supports rendering a string literal view', ->
view.make 'test', """
<style>
body {
margin:
0
}
</style>
"""
# String views should have line breaks and leading whitespace removed
expect(view.get 'test').to.eql '<style>body {margin: 0}</style>'
it 'doctypes and conditional comments are maintained', ->
view.make 'test', """
<!DOCTYPE html>
<!-- This comment is removed -->
<title></title>
<!--[if gt IE 6]>
IE greater than 6
<![endif]-->
<!--[if !IE]> -->
Not IE
<!-- <![endif]-->
"""
expect(view.get 'test').to.eql '<!DOCTYPE html>' +
'<title></title>' +
'<!--[if gt IE 6]>\n' +
'IE greater than 6\n' +
'<![endif]-->' +
'<!--[if !IE]> -->Not IE<!-- <![endif]-->'
it 'supports substituting variables into text', ->
view.make 'test', '''
{{connected}}{{canConnect}} {{nada}}
<p>
{{name}}
</p>
<p>
{{age}} - {{height}} - {{weight}}
</p>
'''
ctx =
connected: false
weight: '165 lbs'
nada: null
model.set 'name', 'John'
model.set 'age', 22
model.set 'height', '6 ft 2 in'
model.set 'weight', '175 lbs'
expected = 'falsetrue ' +
'<p>John</p>' +
'<p>22 - 6 ft 2 in - 165 lbs</p>'
expect(view.get 'test', ctx).to.equal expected
it 'supports path interpolation', ->
view.make 'test', """
{{items[id]}}
{{#each ids}}
{{items[this]}}
{{/}}
{{#each others}}
{{items[.id]}}
{{/}}
"""
model.set 'id', 2
model.set 'ids', [2, 0]
ctx =
items:
0: 'red'
1: 'green'
2: 'blue'
others: [
{id: 1}
{id: 2}
]
expect(view.get 'test', ctx).to.equal 'blue' +
'blue' + 'red' +
'green' + 'blue'
it 'supports binding variables in text', ->
view.make 'test', '''
{connected}{canConnect} {nada}
<p>
{name}
</p>
<p>
{age} - {height} - {weight}
</p>
'''
ctx =
connected: false
weight: '165 lbs'
nada: null
model.set 'name', 'John'
model.set 'age', 22
model.set 'height', '6 ft 2 in'
model.set 'weight', '175 lbs'
expect(view.get 'test', ctx).to.equal '<!--$0-->false<!--$$0--><!--$1-->true<!--$$1--> <!--$2--><!--$$2-->' +
'<p id=$3>John</p>' +
'<p><!--$4-->22<!--$$4--> - <!--$5-->6 ft 2 in<!--$$5--> - <!--$6-->165 lbs<!--$$6--></p>'
it 'supports HTML escaping', ->
# Attribute values are escaped regardless of placeholder type
# Ampersands are escaped at the end of a replacement even when not
# required, because it is sometimes needed depending on the following item
template = '''<input value="{unescaped html}"> {html}x{unescaped html}'''
value = '<b id="hey">&Hi! & x& </b>&'
expected =
'<input id=$0 value="<b id=&quot;hey&quot;>&amp;Hi! & x& </b>&amp;"> ' +
'<!--$1-->&lt;b id="hey">&amp;Hi! & x& &lt;/b>&amp;<!--$$1-->x' +
'<!--$2--><b id="hey">&Hi! & x& </b>&<!--$$2-->'
view.make 'test1', template
expect(view.get 'test1', html: value).to.eql expected
view._idCount = 0
model.set 'html', value
expect(view.get 'test1').to.eql expected
view.make 'test2',
'<p a={{a}} b={{b}} c={{c}} d={{d}} e={{e}} f={{f}} g={{g}} h={{h}} i>'
expect(view.get 'test2',
{a: '"', b: "'", c: '<', d: '>', e: '=', f: ' ', g: '', h: null}
).to.eql '<p a=&quot; b="\'" c="<" d=">" e="=" f=" " g="" h="" i>'
it 'supports HTML entity unescaping in string partials', ->
view.make 'title', '{{unescaped name}} - stuff'
ctx = name: 'Cr&egrave;me Br&ucirc;l&eacute;e'
expect(view.get 'title$s', ctx).to.eql 'Crème Brûlée - stuff'
it 'supports conditional blocks in text', ->
view.make 'literal',
'{{#if show}}Yep{{else}}Nope{{/}}{{#if show}} Yes!{{/}} {{#unless show}}No{{/}}'
view.make 'bound',
'{#if show}Yep{else}Nope{/}{#if show} Yes!{/} {#unless show}No{/}'
literalTruthy = 'Yep Yes! '
literalFalsey = 'Nope No'
modelTruthy = '<!--$0-->Yep<!--$$0--><!--$1--> Yes!<!--$$1--> <!--$2--><!--$$2-->'
modelFalsey = '<!--$0-->Nope<!--$$0--><!--$1--><!--$$1--> <!--$2-->No<!--$$2-->'
expect(view.get 'literal', show: true).to.eql literalTruthy
expect(view.get 'literal', show: 1).to.eql literalTruthy
expect(view.get 'literal', show: 'x').to.eql literalTruthy
expect(view.get 'literal', show: {}).to.eql literalTruthy
expect(view.get 'literal', show: [1]).to.eql literalTruthy
expect(view.get 'literal', show: false).to.eql literalFalsey
expect(view.get 'literal', show: undefined).to.eql literalFalsey
expect(view.get 'literal', show: null).to.eql literalFalsey
expect(view.get 'literal', show: 0).to.eql literalFalsey
expect(view.get 'literal', show: '').to.eql literalFalsey
expect(view.get 'literal', show: []).to.eql literalFalsey
expect(view.get 'literal').to.eql literalFalsey
# No parameter assumes it is a model path that is undefined
view._idCount = 0
expect(view.get 'bound').to.eql modelFalsey
view._idCount = 0
model.set 'show', true
expect(view.get 'bound').to.eql modelTruthy
view._idCount = 0
model.set 'show', 1
expect(view.get 'bound').to.eql modelTruthy
view._idCount = 0
model.set 'show', 'x'
expect(view.get 'bound').to.eql modelTruthy
view._idCount = 0
model.set 'show', {}
expect(view.get 'bound').to.eql modelTruthy
view._idCount = 0
model.set 'show', false
expect(view.get 'bound').to.eql modelFalsey
view._idCount = 0
model.set 'show', undefined
expect(view.get 'bound').to.eql modelFalsey
view._idCount = 0
model.set 'show', null
expect(view.get 'bound').to.eql modelFalsey
view._idCount = 0
model.set 'show', 0
expect(view.get 'bound').to.eql modelFalsey
view._idCount = 0
model.set 'show', ''
expect(view.get 'bound').to.eql modelFalsey
view._idCount = 0
model.set 'show', []
expect(view.get 'bound').to.eql modelFalsey
it 'supports else if conditionals', ->
view.make 'test', """
{{#if equal('red', value)}}
1
{{else if equal('red', value)}}
2
{{else if equal('green', value)}}
3
{{else}}
4
{{/}}
"""
expect(view.get 'test', value: 'red').to.equal '1'
expect(view.get 'test', value: 'green').to.equal '3'
expect(view.get 'test', value: 'blue').to.equal '4'
expect(view.get 'test').to.equal '4'
it 'supports unless then else conditionals', ->
view.make 'test', """
{{#unless value}}
1
{{else}}
2
{{/}}
"""
expect(view.get 'test', value: true).to.equal '2'
expect(view.get 'test', value: false).to.equal '1'
it 'supports lists in text', ->
template = """
<ul>
{{#each arr}}
<li>{{name}}
{{else}}
<li>Nothing to see
{{/}}
</ul>
"""
view.make 'test', template
expect(view.get 'test', arr: [])
.to.eql '<ul><li>Nothing to see</ul>'
view.make 'test', template
expect(view.get 'test', arr: [{name: 'stuff'}, {name: 'more'}])
.to.eql '<ul><li>stuff<li>more</ul>'
it 'supports nesting lists with relative paths', ->
template = """
<table>
<tbody>
{{#each table.rows}}
<tr>
{{#each .cells}}
<td><input value={{.text}}></td>
{{/}}
</tr>
{{/}}
</tbody>
</table>
"""
model.set 'table.rows', [
{cells: [{text: 'A'}, {text: 'B'}, {text: 'C'}]}
{cells: [{text: 1}, {text: 2}, {text: 3}]}
]
view.make 'test', template
expect(view.get 'test').to.equal [
'<table>'
'<tbody>'
'<tr>'
'<td><input value=A></td>'
'<td><input value=B></td>'
'<td><input value=C></td>'
'</tr>'
'<tr>'
'<td><input value=1></td>'
'<td><input value=2></td>'
'<td><input value=3></td>'
'</tr>'
'</tbody>'
'</table>'
].join('')
it 'supports nesting aliases to flat lists', ->
template = """
{{#each outer as :out}}
{{#each inner as :in}}
{{#each core as :core}}
[{{:out.name}} {{:in.name}} {{:core.name}} {{equal(:out.color, :in.color)}}]
{{/}}
{{/}}
{{/}}
"""
view.make 'test', template
compiled = view.get 'test',
outer: [{name: 'stuff', color: 'blue'}, {name: 'more', color: 'pink'}]
inner: [{name: '0', color: 'pink'}, {name: '1', color: 'blue'}]
core: [{name: '0'}, {name: '1'}]
expect(compiled).to.equal [
'[stuff 0 0 false]'
'[stuff 0 1 false]'
'[stuff 1 0 true]'
'[stuff 1 1 true]'
'[more 0 0 true]'
'[more 0 1 true]'
'[more 1 0 false]'
'[more 1 1 false]'
].join('')
it 'supports aliases from relative paths on nested lists', ->
template = """
<ul>
{{#each _room.street}}
<li>Type: {{.type}}
{{#each .people as :person}}
{{#if :person.editable}}
<input value={{:person.name}}>
{{else}}
{{:person.name}}
{{/}}
{{/}}
</li>
{{/}}
</ul>
"""
model.set '_room.street', [
{
type: 'home'
people: [
{name: 'fred', editable: true}
{name: 'wilma', editable: false}
]
}, {
type: 'neighbor'
people: [
{name: 'barney', editable: false}
{name: 'betty', editable: true}
]
}
]
view.make 'test', template
expect(view.get 'test').to.equal [
'<ul>'
'<li>Type: home'
'<input value=fred>'
'wilma'
'</li>'
'<li>Type: neighbor'
'barney'
'<input value=betty>'
'</li>'
'</ul>'
].join('')
it 'supports aliases from aliases on nested lists', ->
template = """
<ul>
{{#each _room.street as :street}}
<li>Type: {{:street.type}}
{{#each :street.people as :person}}
{{#if :person.editable}}
<input value={{:person.name}}>
{{else}}
{{:person.name}}
{{/}}
{{/}}
</li>
{{/}}
</ul>
"""
model.set '_room.street', [
{
type: 'home'
people: [
{name: 'fred', editable: true}
{name: 'wilma', editable: false}
]
}, {
type: 'neighbor'
people: [
{name: 'barney', editable: false}
{name: 'betty', editable: true}
]
}
]
view.make 'test', template
expect(view.get 'test').to.equal [
'<ul>'
'<li>Type: home'
'<input value=fred>'
'wilma'
'</li>'
'<li>Type: neighbor'
'barney'
'<input value=betty>'
'</li>'
'</ul>'
].join('')
it 'supports boolean attributes', ->
view.make 'test', '<input disabled={maybe}>'
expect(view.get 'test').to.equal '<input id=$0>'
expect(view.get 'test', maybe: false).to.equal '<input id=$1>'
expect(view.get 'test', maybe: true).to.equal '<input id=$2 disabled>'
it 'supports paths containing dots for ctx object items', ->
view.make 'test', '<b>{{user.name}}</b>'
ctx = user: {name: 'John'}
expect(view.get 'test', ctx).to.equal '<b>John</b>'
it 'supports relative paths for ctx object items', ->
view.make 'test', '{{#if user}}<b>{{.name}}</b>{{/}}'
ctx = user: {name: 'John'}
expect(view.get 'test', ctx).to.equal '<b>John</b>'
it 'supports Arrays containing non-objects from ctx', ->
view.make 'test1', '{{#each bools}}<b>{{this}}</b>{{/}}'
view.make 'test2', '{{#each bools as :value}}<b>{{:value}}</b>{{/}}'
ctx = bools: [true, false, true]
expect(view.get 'test1', ctx).to.equal '<b>true</b><b>false</b><b>true</b>'
expect(view.get 'test2', ctx).to.equal '<b>true</b><b>false</b><b>true</b>'
it 'supports view helper functions', ->
view.fn 'lower', (s) -> s.toLowerCase()
view.make 'test', '''{{lower('HI')}} {lower( "HI" )}'''
expect(view.get 'test').to.equal 'hi <!--$0-->hi<!--$$0-->'
view.fn 'sum', (a, b) -> a + b
view.make 'test', '{{sum(4, 9)}}'
expect(view.get 'test').to.equal '13'
view._idCount = 0
view.make 'test', '{equal(1, sum(-5, 6))}'
expect(view.get 'test').to.equal '<!--$0-->true<!--$$0-->'
view._idCount = 0
view.make 'test', '{unescaped equal(sum(-5, 6), 1)}'
expect(view.get 'test').to.equal '<!--$0-->true<!--$$0-->'
view.make 'test', '{{sum(4, count)}}'
expect(view.get 'test', {count: 7}).to.equal '11'
model.set 'count', 13
expect(view.get 'test').to.equal '17'
view._idCount = 0
view.make 'test', '''
<select>
{{#each items}}
<option selected="{{equal(this, current)}}">{{this}}
{{/}}
</select>
'''
expect(view.get 'test',
items: ['a', 'b', 'c']
current: 'c'
).to.equal '<select id=$0><option>a<option>b<option selected>c</select>'
view.fn 'positive', (num) -> num >= 0
view.make 'test', '''
{{#each nums as :num}}
{{#if positive(:num)}}
{{:num}},
{{/}}
{{/}}
'''
expect(view.get 'test', {nums: [-4, 8, 0, 2.3, -9]}).to.equal '8,0,2.3,'
it 'supports x-no-minify', ->
view.make 'test', '''
<script type="x-test" x-no-minify>
Some text
And a new line
</script>
'''
expect(view.get 'test').to.equal '''
<script type=x-test>
Some text
And a new line
</script>
'''

View File

@@ -0,0 +1,45 @@
{expect, calls} = require 'racer/test/util'
app = require '../lib/app'
describe 'App', ->
it 'merges a tree into an empty object', ->
root = {}
fn = ->
tree =
x:
a: 23
b: fn
y: 12
app.treeMerge root, tree
expect(root).not.equal tree
expect(root).eql tree
it 'merges a tree into a non-empty object', ->
fn2 = ->
root =
x:
c: fn2
d:
n: 2
z: 23
fn = ->
tree =
x:
a: 7
b: fn
y: 12
expected =
x:
a: 7
b: fn
c: fn2
d:
n: 2
y: 12
z: 23
app.treeMerge root, tree
expect(root).not.equal expected
expect(root).eql expected

View File

@@ -0,0 +1,28 @@
{expect, calls} = require 'racer/test/util'
fs = require "fs"
files = require "../lib/files"
derby = require "../lib/derby"
describe 'files.css', ->
it "should compile less", (done) ->
derby.configure "all", ->
derby.set "styles", "less"
expected = fs.readFileSync __dirname + "/fixtures/styles/app/expected.less.css", 'utf8'
files.css __dirname + "/fixtures", "app", false, (err, contents) ->
# nextTick because stylus.render catches assertions
process.nextTick ->
expect(contents).to.equal expected
done()
it "should compile stylus", (done) ->
derby.configure "all", ->
derby.set "styles", ["stylus"]
expected = fs.readFileSync __dirname + "/fixtures/styles/app/expected.styl.css", 'utf8'
files.css __dirname + "/fixtures", "app", false, (err, contents) ->
process.nextTick ->
expect(contents).to.equal expected
done()

View File

@@ -0,0 +1,2 @@
<box:>
<div class="box"></div>

View File

@@ -0,0 +1,2 @@
<button: nonvoid>
<button>{{@content}}</button>

View File

@@ -0,0 +1,7 @@
<dropdown:>
<!-- a :self path alias is automatically created per component -->
<!-- x-as can be used to pass a reference to an element to the script -->
<div x-as="container" class="{#if :self.open}open{/}">
<button x-bind="click: clickButton">{@value}</button>
<menu></menu>
</div>

View File

@@ -0,0 +1 @@
exports.create = function(self, dom) {}

View File

@@ -0,0 +1,13 @@
var config = {
filename: __filename
, scripts: {
dropdown: require('./dropdown')
}
}
module.exports = plugin
plugin.decorate = 'derby'
function plugin(derby, options) {
derby.createLibrary(config, options)
}

View File

@@ -0,0 +1,3 @@
#less {
color: #4d926f;
}

View File

@@ -0,0 +1,3 @@
#styl {
color: #4d926f;
}

View File

@@ -0,0 +1,5 @@
@color: #4D926F;
#less {
color: @color;
}

View File

@@ -0,0 +1,2 @@
#styl
color #4D926F

View File

@@ -0,0 +1,28 @@
{expect} = require 'racer/test/util'
{DetachedModel: Model} = require './mocks'
derby = require '../lib/derby'
View = require '../lib/View.server'
ui = require './fixtures/components/ui'
describe 'Component libraries', ->
derby.use ui
view = null
beforeEach (done) ->
view = new View(derby._libraries)
model = new Model
view._init model, false, done
it 'supports void components from libraries', ->
view.make 'test', 'give me a <ui:box>'
expect(view.get 'test').to.equal 'give me a <div class=box></div>'
it 'supports non-void components from libraries', ->
view.make 'test', 'give me a <ui:button>Click</ui:button>'
expect(view.get 'test').to.equal 'give me a <button>Click</button>'
it 'supports rendering full components from libraries', ->
view.make 'test', 'give me a <ui:dropdown>'
expect(view.get 'test').to.equal 'give me a <div id=$0 class="">' +
'<button id=$1></button><menu></menu></div>'

View File

@@ -0,0 +1,6 @@
--colors
--reporter spec
--timeout 1200
--growl
--debug
--compilers coffee:coffee-script

View File

@@ -0,0 +1,21 @@
{Model} = require('racer').protected
DetachedModel = exports.DetachedModel = ->
Model.apply this, arguments
return
DetachedModel:: =
__proto__: Model::
_commit: ->
ResMock = exports.ResMock = ->
@html = ''
return
ResMock:: =
getHeader: ->
setHeader: ->
write: write = (value) ->
@html += value
send: write
end: (value) ->
write value
@onEnd? @html