UNPKG

caveman

Version:
473 lines (451 loc) 13.6 kB
Caveman = require('../caveman.js') beforeEach -> Caveman.options.openTag = '{{' Caveman.options.closeTag = '}}' Caveman.options.shrinkWrap = true Caveman.options.escapeByDefault = false describe 'Macros', -> template = '<ul>{{- for d.uls as ul }}<li>{{ul.li}}</li>{{/}}</ul>' Caveman.register('unorderedList', template) template = '{{- for d.divs as div }}<div>{{- render unorderedList div }}</div>{{/}}' Caveman.register('listOfDivs', template) it 'if with truthy comparison', -> data = { tests: { boolTrue: true boolFalse: false zero: 0 one: 1 emptyString: '' emptyObject: {} emptyArray: [] } } template = """ {{- each d.tests }} {{- if d }} <truthy>{{_key}}</truthy> {{- end }} {{- end }} """ expected = '<truthy>boolTrue</truthy>' + '<truthy>one</truthy>' + '<truthy>emptyObject</truthy>' + '<truthy>emptyArray</truthy>' expect(Caveman(template, data)).toEqual(expected) it 'if with strict comparison', -> data = { emptyString: '' emptyArray: [] arrayWithOne: [1] } template = """ {{- if d.emptyString === '' }} <true>d.emptyString === ''</true> {{- end }} {{- if d.emptyArray.length === 0 }} <true>d.emptyArray.length === 0</true> {{- end }} {{- if d.arrayWithOne.length > 0 }} <true>d.arrayWithOne.length > 0</true> {{- end }} """ expected = "<true>d.emptyString === ''</true>" + '<true>d.emptyArray.length === 0</true>' + '<true>d.arrayWithOne.length > 0</true>' expect(Caveman(template, data)).toEqual(expected) it 'unless with falsey comparison', -> data = { tests: { boolTrue: true boolFalse: false zero: 0 one: 1 emptyString: '' emptyObject: {} emptyArray: [] } } template = """ {{- each d.tests }} {{- unless d }} <falsey>{{_key}}</falsey> {{- end }} {{- end }} """ expected = '<falsey>boolFalse</falsey>' + '<falsey>zero</falsey>' + '<falsey>emptyString</falsey>' expect(Caveman(template, data)).toEqual(expected) it 'shortcuts', -> data = { tests: { boolTrue: true boolFalse: false zero: 0 one: 1 emptyString: '' emptyObject: {} emptyArray: [] } } template = """ {{? d.tests.boolTrue }} <span>boolTrue</span> {{/}} {{?d.tests.one === 1}} <span>boolTrue</span> {{/}} {{^ d.tests.emptyString }} <span>emptyString</span> {{/}} {{^d.tests.zero > 0}} <span>zero</span> {{/}} """ expected = '<span>boolTrue</span>' + '<span>boolTrue</span>' + '<span>emptyString</span>' + '<span>zero</span>' expect(Caveman(template, data)).toEqual(expected) it 'for', -> data = { nullValue: null users: [ { name: 'Jimmy' } { name: 'Ralph' } { name: 'Joe' } ] } template = """ <div class="users"> {{- for d.nullValue }} <!-- Should handle non-array values --> {{- end }} {{- for d.undef }} <!-- Should handle non-array values --> {{- end }} {{- for d.users }} {{- for d }} <!-- Won't work for objects either --> {{- end }} <div class="user">{{d.name}}</div> {{- end }} </div> """ expected = '<div class="users">' + '<div class="user">Jimmy</div>' + '<div class="user">Ralph</div>' + '<div class="user">Joe</div>' + '</div>' expect(Caveman(template, data)).toEqual(expected) it 'nested for', -> data = { posts: [ { title: 'My Blog Post' comments: ['First!', 'Great!', 'I hate this.'] images: [ { src: '/image1.jpg' } ] } { title: 'My Crappy Blog Post' comments: ['Crickets.'] images: [ { src: '/image1.jpg' }, { src: '/image2.jpg', alt: 'My Alt Text' }, { src: '/image3.jpg' } ] } ] } template = """ <div class="posts"> {{- for d.posts as post }} <div class="post"> <h1>{{post.title}}</h1> <div class="images"> {{- for post.images as image}} <img src="{{image.src}}" alt="{{image.alt}}" /> {{- end }} </div> <div class="comments"> {{- for post.comments as comment}} <div class="comment">{{comment}}</div> {{- end }} </div> </div> {{- end }} </div> """ expected = '' + '<div class="posts">' + '<div class="post">' + '<h1>My Blog Post</h1>' + '<div class="images">' + '<img src="/image1.jpg" alt="" />' + '</div>' + '<div class="comments">' + '<div class="comment">First!</div>' + '<div class="comment">Great!</div>' + '<div class="comment">I hate this.</div>' + '</div>' + '</div>' + '<div class="post">' + '<h1>My Crappy Blog Post</h1>' + '<div class="images">' + '<img src="/image1.jpg" alt="" />' + '<img src="/image2.jpg" alt="My Alt Text" />' + '<img src="/image3.jpg" alt="" />' + '</div>' + '<div class="comments">' + '<div class="comment">Crickets.</div>' + '</div>' + '</div>' + '</div>' expect(Caveman(template, data)).toEqual(expected) it 'for blocks inside partials inside for blocks', -> data = { divs: [ { uls: [ { li: 'a1' }, { li: 'a2' } ] } { uls: [ { li: 'b1' }, { li: 'b2' } ] } { uls: [ { li: 'c1' }, { li: 'c2' } ] } ] } template = '<div>{{- for d.divs as div }}{{- for div.uls as ul }}{{ul.li}}{{/}}{{/}}</div><div>{{- render listOfDivs }}</div>' expected = '<div>a1a2b1b2c1c2</div>' + '<div>' + '<div><ul><li>a1</li><li>a2</li></ul></div>' + '<div><ul><li>b1</li><li>b2</li></ul></div>' + '<div><ul><li>c1</li><li>c2</li></ul></div>' + '</div>' expect(Caveman(template, data)).toEqual(expected) it 'deeply nested for blocks with if blocks', -> data = { arr: [ [ [ [ [ 'a1', 'a2', 'a3' ], [ 'b1', 'b2', 'b3' ] ] ] ] ] } template = """ {{- if d.arr }} {{- for d.arr }} {{_i}}, {{- for d }} {{_i}}, {{- for d }} {{_i}}, {{- if d }} {{- for d }} {{_i}}, {{- for d }} {{d}}, {{/}} {{/}} {{/}} {{/}} {{/}} {{/}} {{- for d.arr as a }} {{- for a as a }} {{- for a as a }} {{- for a as a }} {{- if d }} {{- for a as a }} {{a}} {{/}} {{/}} {{/}} {{/}} {{/}} {{/}} {{/}} """ expected = '0,0,0,0,a1,a2,a3,1,b1,b2,b3,a1a2a3b1b2b3' expect(Caveman(template, data)).toEqual(expected) it 'each', -> data = { car: { make: 'Volvo' model: '245s' year: 1976 color: 'Orange' } } template = """ <div class="attributes"> {{- each d.car }} <div class="attribute">{{_key}}: {{d}}</div> {{- end }} </div> """ expected = '<div class="attributes">' + '<div class="attribute">make: Volvo</div>' + '<div class="attribute">model: 245s</div>' + '<div class="attribute">year: 1976</div>' + '<div class="attribute">color: Orange</div>' + '</div>' expect(Caveman(template, data)).toEqual(expected) it 'nested each', -> data = { posts: [ { title: 'My Blog Post' comments: ['First!', 'Great!', 'I hate this.'] images: [ { src: '/image1.jpg' } ] } { title: 'My Crappy Blog Post' comments: ['Crickets.'] images: [ { src: '/image1.jpg' }, { src: '/image2.jpg', alt: 'My Alt Text' }, { src: '/image3.jpg' } ] } ] } template = """ <div class="posts"> {{- each d.posts as post }} <div class="post"> <h1>{{post.title}}</h1> <div class="images"> {{- each post.images as image}} <img src="{{image.src}}" alt="{{image.alt}}" /> {{- end }} </div> <div class="comments"> {{- each post.comments as comment}} {{- if _key === 0 }} <span>{{d.posts.length}} posts</span> {{- end }} <div class="comment">{{comment}}</div> {{- end }} </div> </div> {{- end }} </div> """ expected = '' + '<div class="posts">' + '<div class="post">' + '<h1>My Blog Post</h1>' + '<div class="images">' + '<img src="/image1.jpg" alt="" />' + '</div>' + '<div class="comments">' + '<span>2 posts</span>' + '<div class="comment">First!</div>' + '<div class="comment">Great!</div>' + '<div class="comment">I hate this.</div>' + '</div>' + '</div>' + '<div class="post">' + '<h1>My Crappy Blog Post</h1>' + '<div class="images">' + '<img src="/image1.jpg" alt="" />' + '<img src="/image2.jpg" alt="My Alt Text" />' + '<img src="/image3.jpg" alt="" />' + '</div>' + '<div class="comments">' + '<span>2 posts</span>' + '<div class="comment">Crickets.</div>' + '</div>' + '</div>' + '</div>' expect(Caveman(template, data)).toEqual(expected) it 'with', -> data = { foo: { a: 123 b: 234 } } template = """ {{- with d.foo }} <span>a: {{d.a}}</span> <span>b: {{d.b}}</span> {{- end }} {{- with d.foo as foo }} <span>a: {{foo.a}}</span> <span>b: {{foo.b}}</span> {{- end }} """ expected = '<span>a: 123</span><span>b: 234</span><span>a: 123</span><span>b: 234</span>' expect(Caveman(template, data)).toEqual(expected) it 'script execution', -> data = { rows: [ 1, 2, 3, 4, 5 ] } template = """ <table> {{- for d.rows }} {{- everyThirdStripe = [_i % 3 ? '': 'zebra-stripe'] }} <tr class="{{everyThirdStripe}}"> <td>{{d}}</td> </tr> {{- end }} </table> """ expected = '<table>' + '<tr class="zebra-stripe"><td>1</td></tr>' + '<tr class=""><td>2</td></tr>' + '<tr class=""><td>3</td></tr>' + '<tr class="zebra-stripe"><td>4</td></tr>' + '<tr class=""><td>5</td></tr>' + '</table>' expect(Caveman(template, data)).toEqual(expected) it 'print', -> data = { rows: [ 1, 2, 3 ] } template = """ {{- for d.rows }} <div>{{d}} x {{d}} = {{- print d * d }}</div> {{- end }} """ expected = '<div>1 x 1 = 1</div>' + '<div>2 x 2 = 4</div>' + '<div>3 x 3 = 9</div>' expect(Caveman(template, data)).toEqual(expected) describe 'Escaping', -> it 'does not escape by default', -> data = { html: '<script>alert("HELLO XSS!");</script> & \'' } template = '<div>{{d.html}}</div>' expected = '<div><script>alert("HELLO XSS!");</script> & \'</div>' expect(Caveman(template, data)).toEqual(expected) it 'escape macro', -> data = { html: '<script>alert("HELLO XSS!");</script> & \'', zero: 0 } template = '<div>{{- escape d.html }}{{- escape d.zero }}</div>' expected = '<div>&lt;script&gt;alert(&quot;HELLO XSS!&quot;);&lt;/script&gt; &amp; &#39;0</div>' expect(Caveman(template, data)).toEqual(expected) it 'escape macro will not double-escape if escapeByDefault is true', -> data = { html: '<script>alert("HELLO XSS!");</script> & \'' } template = '<div>{{- escape d.html }}</div>' expected = '<div>&lt;script&gt;alert(&quot;HELLO XSS!&quot;);&lt;/script&gt; &amp; &#39;</div>' Caveman.options.escapeByDefault = true expect(Caveman(template, data)).toEqual(expected) it 'escapes by default using the escapeByDefault option', -> data = { html: '<script>alert("HELLO XSS!");</script> & \'' } template = '<div>{{d.html}}</div>' expected = '<div>&lt;script&gt;alert(&quot;HELLO XSS!&quot;);&lt;/script&gt; &amp; &#39;</div>' Caveman.options.escapeByDefault = true expect(Caveman(template, data)).toEqual(expected) it 'unescape overrides escapeByDefault', -> data = { html: '<script>alert("HELLO XSS!");</script> & \'' } template = '<div>{{- unescape d.html }}</div>' expected = '<div><script>alert("HELLO XSS!");</script> & \'</div>' Caveman.options.escapeByDefault = true expect(Caveman(template, data)).toEqual(expected)