pug.test.js 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. 'use strict';
  2. var assert = require('assert');
  3. var fs = require('fs');
  4. var path = require('path');
  5. var pug = require('../');
  6. var perfTest = fs.readFileSync(__dirname + '/fixtures/perf.pug', 'utf8')
  7. try {
  8. fs.mkdirSync(__dirname + '/temp');
  9. } catch (ex) {
  10. if (ex.code !== 'EEXIST') {
  11. throw ex;
  12. }
  13. }
  14. describe('pug', function(){
  15. describe('unit tests with .render()', function(){
  16. it('should support doctypes', function(){
  17. assert.equal('<?xml version="1.0" encoding="utf-8" ?>', pug.render('doctype xml'));
  18. assert.equal('<!DOCTYPE html>', pug.render('doctype html'));
  19. assert.equal('<!DOCTYPE foo bar baz>', pug.render('doctype foo bar baz'));
  20. assert.equal('<!DOCTYPE html>', pug.render('doctype html'));
  21. assert.equal('<!DOCTYPE html>', pug.render('doctype', { doctype:'html' }));
  22. assert.equal('<!DOCTYPE html>', pug.render('doctype html', { doctype:'xml' }));
  23. assert.equal('<html></html>', pug.render('html'));
  24. assert.equal('<!DOCTYPE html><html></html>', pug.render('html', { doctype:'html' }));
  25. assert.equal('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN>', pug.render('doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN'));
  26. });
  27. it('should support Buffers', function(){
  28. assert.equal('<p>foo</p>', pug.render(new Buffer('p foo')));
  29. });
  30. it('should support line endings', function(){
  31. var src = [
  32. 'p',
  33. 'div',
  34. 'img'
  35. ];
  36. var html = [
  37. '<p></p>',
  38. '<div></div>',
  39. '<img/>'
  40. ].join('');
  41. assert.equal(html, pug.render(src.join('\n')));
  42. assert.equal(html, pug.render(src.join('\r')));
  43. assert.equal(html, pug.render(src.join('\r\n')));
  44. html = [
  45. '<p></p>',
  46. '<div></div>',
  47. '<img>'
  48. ].join('');
  49. assert.equal(html, pug.render(src.join('\n'), { doctype:'html' }));
  50. assert.equal(html, pug.render(src.join('\r'), { doctype:'html' }));
  51. assert.equal(html, pug.render(src.join('\r\n'), { doctype:'html' }));
  52. });
  53. it('should support single quotes', function(){
  54. assert.equal("<p>'foo'</p>", pug.render("p 'foo'"));
  55. assert.equal("<p>'foo'</p>", pug.render("p\n | 'foo'"));
  56. assert.equal('<a href="/foo"></a>', pug.render("- var path = 'foo';\na(href='/' + path)"));
  57. });
  58. it('should support block-expansion', function(){
  59. assert.equal("<li><a>foo</a></li><li><a>bar</a></li><li><a>baz</a></li>", pug.render("li: a foo\nli: a bar\nli: a baz"));
  60. assert.equal("<li class=\"first\"><a>foo</a></li><li><a>bar</a></li><li><a>baz</a></li>", pug.render("li.first: a foo\nli: a bar\nli: a baz"));
  61. assert.equal('<div class="foo"><div class="bar">baz</div></div>', pug.render(".foo: .bar baz"));
  62. });
  63. it('should support tags', function(){
  64. var str = [
  65. 'p',
  66. 'div',
  67. 'img',
  68. 'br/'
  69. ].join('\n');
  70. var html = [
  71. '<p></p>',
  72. '<div></div>',
  73. '<img/>',
  74. '<br/>'
  75. ].join('');
  76. assert.equal(html, pug.render(str), 'Test basic tags');
  77. assert.equal('<fb:foo-bar></fb:foo-bar>', pug.render('fb:foo-bar'), 'Test hyphens');
  78. assert.equal('<div class="something"></div>', pug.render('div.something'), 'Test classes');
  79. assert.equal('<div id="something"></div>', pug.render('div#something'), 'Test ids');
  80. assert.equal('<div class="something"></div>', pug.render('.something'), 'Test stand-alone classes');
  81. assert.equal('<div id="something"></div>', pug.render('#something'), 'Test stand-alone ids');
  82. assert.equal('<div class="bar" id="foo"></div>', pug.render('#foo.bar'));
  83. assert.equal('<div class="bar" id="foo"></div>', pug.render('.bar#foo'));
  84. assert.equal('<div class="bar" id="foo"></div>', pug.render('div#foo(class="bar")'));
  85. assert.equal('<div class="bar" id="foo"></div>', pug.render('div(class="bar")#foo'));
  86. assert.equal('<div class="foo" id="bar"></div>', pug.render('div(id="bar").foo'));
  87. assert.equal('<div class="foo bar baz"></div>', pug.render('div.foo.bar.baz'));
  88. assert.equal('<div class="foo bar baz"></div>', pug.render('div(class="foo").bar.baz'));
  89. assert.equal('<div class="foo bar baz"></div>', pug.render('div.foo(class="bar").baz'));
  90. assert.equal('<div class="foo bar baz"></div>', pug.render('div.foo.bar(class="baz")'));
  91. assert.equal('<div class="a-b2"></div>', pug.render('div.a-b2'));
  92. assert.equal('<div class="a_b2"></div>', pug.render('div.a_b2'));
  93. assert.equal('<fb:user></fb:user>', pug.render('fb:user'));
  94. assert.equal('<fb:user:role></fb:user:role>', pug.render('fb:user:role'));
  95. assert.equal('<colgroup><col class="test"/></colgroup>', pug.render('colgroup\n col.test'));
  96. });
  97. it('should support nested tags', function(){
  98. var str = [
  99. 'ul',
  100. ' li a',
  101. ' li b',
  102. ' li',
  103. ' ul',
  104. ' li c',
  105. ' li d',
  106. ' li e',
  107. ].join('\n');
  108. var html = [
  109. '<ul>',
  110. '<li>a</li>',
  111. '<li>b</li>',
  112. '<li><ul><li>c</li><li>d</li></ul></li>',
  113. '<li>e</li>',
  114. '</ul>'
  115. ].join('');
  116. assert.equal(html, pug.render(str));
  117. var str = [
  118. 'a(href="#")',
  119. ' | foo ',
  120. ' | bar ',
  121. ' | baz'
  122. ].join('\n');
  123. assert.equal('<a href="#">foo \nbar \nbaz</a>', pug.render(str));
  124. var str = [
  125. 'ul',
  126. ' li one',
  127. ' ul',
  128. ' | two',
  129. ' li three'
  130. ].join('\n');
  131. var html = [
  132. '<ul>',
  133. '<li>one</li>',
  134. '<ul>two',
  135. '<li>three</li>',
  136. '</ul>',
  137. '</ul>'
  138. ].join('');
  139. assert.equal(html, pug.render(str));
  140. });
  141. it('should support variable length newlines', function(){
  142. var str = [
  143. 'ul',
  144. ' li a',
  145. ' ',
  146. ' li b',
  147. ' ',
  148. ' ',
  149. ' li',
  150. ' ul',
  151. ' li c',
  152. '',
  153. ' li d',
  154. ' li e',
  155. ].join('\n');
  156. var html = [
  157. '<ul>',
  158. '<li>a</li>',
  159. '<li>b</li>',
  160. '<li><ul><li>c</li><li>d</li></ul></li>',
  161. '<li>e</li>',
  162. '</ul>'
  163. ].join('');
  164. assert.equal(html, pug.render(str));
  165. });
  166. it('should support tab conversion', function(){
  167. var str = [
  168. 'ul',
  169. '\tli a',
  170. '\t',
  171. '\tli b',
  172. '\t\t',
  173. '\t\t\t\t\t\t',
  174. '\tli',
  175. '\t\tul',
  176. '\t\t\tli c',
  177. '',
  178. '\t\t\tli d',
  179. '\tli e',
  180. ].join('\n');
  181. var html = [
  182. '<ul>',
  183. '<li>a</li>',
  184. '<li>b</li>',
  185. '<li><ul><li>c</li><li>d</li></ul></li>',
  186. '<li>e</li>',
  187. '</ul>'
  188. ].join('');
  189. assert.equal(html, pug.render(str));
  190. });
  191. it('should support newlines', function(){
  192. var str = [
  193. 'ul',
  194. ' li a',
  195. ' ',
  196. ' ',
  197. '',
  198. ' ',
  199. ' li b',
  200. ' li',
  201. ' ',
  202. ' ',
  203. ' ',
  204. ' ul',
  205. ' ',
  206. ' li c',
  207. ' li d',
  208. ' li e',
  209. ].join('\n');
  210. var html = [
  211. '<ul>',
  212. '<li>a</li>',
  213. '<li>b</li>',
  214. '<li><ul><li>c</li><li>d</li></ul></li>',
  215. '<li>e</li>',
  216. '</ul>'
  217. ].join('');
  218. assert.equal(html, pug.render(str));
  219. var str = [
  220. 'html',
  221. ' ',
  222. ' head',
  223. ' != "test"',
  224. ' ',
  225. ' ',
  226. ' ',
  227. ' body'
  228. ].join('\n');
  229. var html = [
  230. '<html>',
  231. '<head>',
  232. 'test',
  233. '</head>',
  234. '<body></body>',
  235. '</html>'
  236. ].join('');
  237. assert.equal(html, pug.render(str));
  238. assert.equal('<foo></foo>something<bar></bar>', pug.render('foo\n= "something"\nbar'));
  239. assert.equal('<foo></foo>something<bar></bar>else', pug.render('foo\n= "something"\nbar\n= "else"'));
  240. });
  241. it('should support text', function(){
  242. assert.equal('foo\nbar\nbaz', pug.render('| foo\n| bar\n| baz'));
  243. assert.equal('foo \nbar \nbaz', pug.render('| foo \n| bar \n| baz'));
  244. assert.equal('(hey)', pug.render('| (hey)'));
  245. assert.equal('some random text', pug.render('| some random text'));
  246. assert.equal(' foo', pug.render('| foo'));
  247. assert.equal(' foo ', pug.render('| foo '));
  248. assert.equal(' foo \n bar ', pug.render('| foo \n| bar '));
  249. });
  250. it('should support pipe-less text', function(){
  251. assert.equal('<pre><code><foo></foo><bar></bar></code></pre>', pug.render('pre\n code\n foo\n\n bar'));
  252. assert.equal('<p>foo\n\nbar</p>', pug.render('p.\n foo\n\n bar'));
  253. assert.equal('<p>foo\n\n\n\nbar</p>', pug.render('p.\n foo\n\n\n\n bar'));
  254. assert.equal('<p>foo\n bar\nfoo</p>', pug.render('p.\n foo\n bar\n foo'));
  255. assert.equal('<script>s.parentNode.insertBefore(g,s)</script>', pug.render('script.\n s.parentNode.insertBefore(g,s)\n'));
  256. assert.equal('<script>s.parentNode.insertBefore(g,s)</script>', pug.render('script.\n s.parentNode.insertBefore(g,s)'));
  257. });
  258. it('should support tag text', function(){
  259. assert.equal('<p>some random text</p>', pug.render('p some random text'));
  260. assert.equal('<p>click<a>Google</a>.</p>', pug.render('p\n | click\n a Google\n | .'));
  261. assert.equal('<p>(parens)</p>', pug.render('p (parens)'));
  262. assert.equal('<p foo="bar">(parens)</p>', pug.render('p(foo="bar") (parens)'));
  263. assert.equal('<option value="">-- (optional) foo --</option>', pug.render('option(value="") -- (optional) foo --'));
  264. });
  265. it('should support tag text block', function(){
  266. assert.equal('<p>foo \nbar \nbaz</p>', pug.render('p\n | foo \n | bar \n | baz'));
  267. assert.equal('<label>Password:<input/></label>', pug.render('label\n | Password:\n input'));
  268. assert.equal('<label>Password:<input/></label>', pug.render('label Password:\n input'));
  269. });
  270. it('should support tag text interpolation', function(){
  271. assert.equal('yo, pug is cool', pug.render('| yo, #{name} is cool\n', { name: 'pug' }));
  272. assert.equal('<p>yo, pug is cool</p>', pug.render('p yo, #{name} is cool', { name: 'pug' }));
  273. assert.equal('yo, pug is cool', pug.render('| yo, #{name || "pug"} is cool', { name: null }));
  274. assert.equal('yo, \'pug\' is cool', pug.render('| yo, #{name || "\'pug\'"} is cool', { name: null }));
  275. assert.equal('foo &lt;script&gt; bar', pug.render('| foo #{code} bar', { code: '<script>' }));
  276. assert.equal('foo <script> bar', pug.render('| foo !{code} bar', { code: '<script>' }));
  277. });
  278. it('should support flexible indentation', function(){
  279. assert.equal('<html><body><h1>Wahoo</h1><p>test</p></body></html>', pug.render('html\n body\n h1 Wahoo\n p test'));
  280. });
  281. it('should support interpolation values', function(){
  282. assert.equal('<p>Users: 15</p>', pug.render('p Users: #{15}'));
  283. assert.equal('<p>Users: </p>', pug.render('p Users: #{null}'));
  284. assert.equal('<p>Users: </p>', pug.render('p Users: #{undefined}'));
  285. assert.equal('<p>Users: none</p>', pug.render('p Users: #{undefined || "none"}'));
  286. assert.equal('<p>Users: 0</p>', pug.render('p Users: #{0}'));
  287. assert.equal('<p>Users: false</p>', pug.render('p Users: #{false}'));
  288. });
  289. it('should support test html 5 mode', function(){
  290. assert.equal('<!DOCTYPE html><input type="checkbox" checked>', pug.render('doctype html\ninput(type="checkbox", checked)'));
  291. assert.equal('<!DOCTYPE html><input type="checkbox" checked>', pug.render('doctype html\ninput(type="checkbox", checked=true)'));
  292. assert.equal('<!DOCTYPE html><input type="checkbox">', pug.render('doctype html\ninput(type="checkbox", checked= false)'));
  293. });
  294. it('should support multi-line attrs', function(){
  295. assert.equal('<a foo="bar" bar="baz" checked="checked">foo</a>', pug.render('a(foo="bar"\n bar="baz"\n checked) foo'));
  296. assert.equal('<a foo="bar" bar="baz" checked="checked">foo</a>', pug.render('a(foo="bar"\nbar="baz"\nchecked) foo'));
  297. assert.equal('<a foo="bar" bar="baz" checked="checked">foo</a>', pug.render('a(foo="bar"\n,bar="baz"\n,checked) foo'));
  298. assert.equal('<a foo="bar" bar="baz" checked="checked">foo</a>', pug.render('a(foo="bar",\nbar="baz",\nchecked) foo'));
  299. });
  300. it('should support attrs', function(){
  301. assert.equal('<img src="&lt;script&gt;"/>', pug.render('img(src="<script>")'), 'Test attr escaping');
  302. assert.equal('<a data-attr="bar"></a>', pug.render('a(data-attr="bar")'));
  303. assert.equal('<a data-attr="bar" data-attr-2="baz"></a>', pug.render('a(data-attr="bar", data-attr-2="baz")'));
  304. assert.equal('<a title="foo,bar"></a>', pug.render('a(title= "foo,bar")'));
  305. assert.equal('<a title="foo,bar" href="#"></a>', pug.render('a(title= "foo,bar", href="#")'));
  306. assert.equal('<p class="foo"></p>', pug.render("p(class='foo')"), 'Test single quoted attrs');
  307. assert.equal('<input type="checkbox" checked="checked"/>', pug.render('input( type="checkbox", checked )'));
  308. assert.equal('<input type="checkbox" checked="checked"/>', pug.render('input( type="checkbox", checked = true )'));
  309. assert.equal('<input type="checkbox"/>', pug.render('input(type="checkbox", checked= false)'));
  310. assert.equal('<input type="checkbox"/>', pug.render('input(type="checkbox", checked= null)'));
  311. assert.equal('<input type="checkbox"/>', pug.render('input(type="checkbox", checked= undefined)'));
  312. assert.equal('<img src="/foo.png"/>', pug.render('img(src="/foo.png")'), 'Test attr =');
  313. assert.equal('<img src="/foo.png"/>', pug.render('img(src = "/foo.png")'), 'Test attr = whitespace');
  314. assert.equal('<img src="/foo.png"/>', pug.render('img(src="/foo.png")'), 'Test attr :');
  315. assert.equal('<img src="/foo.png"/>', pug.render('img(src = "/foo.png")'), 'Test attr : whitespace');
  316. assert.equal('<img src="/foo.png" alt="just some foo"/>', pug.render('img(src="/foo.png", alt="just some foo")'));
  317. assert.equal('<img src="/foo.png" alt="just some foo"/>', pug.render('img(src = "/foo.png", alt = "just some foo")'));
  318. assert.equal('<p class="foo,bar,baz"></p>', pug.render('p(class="foo,bar,baz")'));
  319. assert.equal('<a href="http://google.com" title="Some : weird = title"></a>', pug.render('a(href= "http://google.com", title= "Some : weird = title")'));
  320. assert.equal('<label for="name"></label>', pug.render('label(for="name")'));
  321. assert.equal('<meta name="viewport" content="width=device-width"/>', pug.render("meta(name= 'viewport', content='width=device-width')"), 'Test attrs that contain attr separators');
  322. assert.equal('<div style="color= white"></div>', pug.render("div(style='color= white')"));
  323. assert.equal('<div style="color: white"></div>', pug.render("div(style='color: white')"));
  324. assert.equal('<p class="foo"></p>', pug.render("p('class'='foo')"), 'Test keys with single quotes');
  325. assert.equal('<p class="foo"></p>', pug.render("p(\"class\"= 'foo')"), 'Test keys with double quotes');
  326. assert.equal('<p data-lang="en"></p>', pug.render('p(data-lang = "en")'));
  327. assert.equal('<p data-dynamic="true"></p>', pug.render('p("data-dynamic"= "true")'));
  328. assert.equal('<p class="name" data-dynamic="true"></p>', pug.render('p("class"= "name", "data-dynamic"= "true")'));
  329. assert.equal('<p data-dynamic="true"></p>', pug.render('p(\'data-dynamic\'= "true")'));
  330. assert.equal('<p class="name" data-dynamic="true"></p>', pug.render('p(\'class\'= "name", \'data-dynamic\'= "true")'));
  331. assert.equal('<p class="name" data-dynamic="true" yay="yay"></p>', pug.render('p(\'class\'= "name", \'data-dynamic\'= "true", yay)'));
  332. assert.equal('<input checked="checked" type="checkbox"/>', pug.render('input(checked, type="checkbox")'));
  333. assert.equal('<a data-foo="{ foo: \'bar\', bar= \'baz\' }"></a>', pug.render('a(data-foo = "{ foo: \'bar\', bar= \'baz\' }")'));
  334. assert.equal('<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>', pug.render('meta(http-equiv="X-UA-Compatible", content="IE=edge,chrome=1")'));
  335. assert.equal('<div style="background: url(/images/test.png)">Foo</div>', pug.render("div(style= 'background: url(/images/test.png)') Foo"));
  336. assert.equal('<div style="background = url(/images/test.png)">Foo</div>', pug.render("div(style= 'background = url(/images/test.png)') Foo"));
  337. assert.equal('<div style="foo">Foo</div>', pug.render("div(style= ['foo', 'bar'][0]) Foo"));
  338. assert.equal('<div style="bar">Foo</div>', pug.render("div(style= { foo: 'bar', baz: 'raz' }['foo']) Foo"));
  339. assert.equal('<a href="def">Foo</a>', pug.render("a(href='abcdefg'.substr(3,3)) Foo"));
  340. assert.equal('<a href="def">Foo</a>', pug.render("a(href={test: 'abcdefg'}.test.substr(3,3)) Foo"));
  341. assert.equal('<a href="def">Foo</a>', pug.render("a(href={test: 'abcdefg'}.test.substr(3,[0,3][1])) Foo"));
  342. assert.equal('<rss xmlns:atom="atom"></rss>', pug.render("rss(xmlns:atom=\"atom\")"));
  343. assert.equal('<rss xmlns:atom="atom"></rss>', pug.render("rss('xmlns:atom'=\"atom\")"));
  344. assert.equal('<rss xmlns:atom="atom"></rss>', pug.render("rss(\"xmlns:atom\"='atom')"));
  345. assert.equal('<rss xmlns:atom="atom" foo="bar"></rss>', pug.render("rss('xmlns:atom'=\"atom\", 'foo'= 'bar')"));
  346. assert.equal('<a data-obj="{ foo: \'bar\' }"></a>', pug.render("a(data-obj= \"{ foo: 'bar' }\")"));
  347. assert.equal('<meta content="what\'s up? \'weee\'"/>', pug.render('meta(content="what\'s up? \'weee\'")'));
  348. });
  349. it('should support class attr array', function(){
  350. assert.equal('<body class="foo bar baz"></body>', pug.render('body(class=["foo", "bar", "baz"])'));
  351. });
  352. it('should support attr parens', function(){
  353. assert.equal('<p foo="bar">baz</p>', pug.render('p(foo=((("bar"))))= ((("baz")))'));
  354. });
  355. it('should support code attrs', function(){
  356. assert.equal('<p></p>', pug.render('p(id= name)', { name: undefined }));
  357. assert.equal('<p></p>', pug.render('p(id= name)', { name: null }));
  358. assert.equal('<p></p>', pug.render('p(id= name)', { name: false }));
  359. assert.equal('<p id=""></p>', pug.render('p(id= name)', { name: '' }));
  360. assert.equal('<p id="tj"></p>', pug.render('p(id= name)', { name: 'tj' }));
  361. assert.equal('<p id="default"></p>', pug.render('p(id= name || "default")', { name: null }));
  362. assert.equal('<p id="something"></p>', pug.render("p(id= 'something')", { name: null }));
  363. assert.equal('<p id="something"></p>', pug.render("p(id = 'something')", { name: null }));
  364. assert.equal('<p id="foo"></p>', pug.render("p(id= (true ? 'foo' : 'bar'))"));
  365. assert.equal('<option value="">Foo</option>', pug.render("option(value='') Foo"));
  366. });
  367. it('should support code attrs class', function(){
  368. assert.equal('<p class="tj"></p>', pug.render('p(class= name)', { name: 'tj' }));
  369. assert.equal('<p class="tj"></p>', pug.render('p( class= name )', { name: 'tj' }));
  370. assert.equal('<p class="default"></p>', pug.render('p(class= name || "default")', { name: null }));
  371. assert.equal('<p class="foo default"></p>', pug.render('p.foo(class= name || "default")', { name: null }));
  372. assert.equal('<p class="default foo"></p>', pug.render('p(class= name || "default").foo', { name: null }));
  373. assert.equal('<p id="default"></p>', pug.render('p(id = name || "default")', { name: null }));
  374. assert.equal('<p id="user-1"></p>', pug.render('p(id = "user-" + 1)'));
  375. assert.equal('<p class="user-1"></p>', pug.render('p(class = "user-" + 1)'));
  376. });
  377. it('should support code buffering', function(){
  378. assert.equal('<p></p>', pug.render('p= null'));
  379. assert.equal('<p></p>', pug.render('p= undefined'));
  380. assert.equal('<p>0</p>', pug.render('p= 0'));
  381. assert.equal('<p>false</p>', pug.render('p= false'));
  382. });
  383. it('should support script text', function(){
  384. var str = [
  385. 'script.',
  386. ' p foo',
  387. '',
  388. 'script(type="text/template")',
  389. ' p foo',
  390. '',
  391. 'script(type="text/template").',
  392. ' p foo'
  393. ].join('\n');
  394. var html = [
  395. '<script>p foo\n</script>',
  396. '<script type="text/template"><p>foo</p></script>',
  397. '<script type="text/template">p foo</script>'
  398. ].join('');
  399. assert.equal(html, pug.render(str));
  400. });
  401. it('should support comments', function(){
  402. // Regular
  403. var str = [
  404. '//foo',
  405. 'p bar'
  406. ].join('\n');
  407. var html = [
  408. '<!--foo-->',
  409. '<p>bar</p>'
  410. ].join('');
  411. assert.equal(html, pug.render(str));
  412. // Between tags
  413. var str = [
  414. 'p foo',
  415. '// bar ',
  416. 'p baz'
  417. ].join('\n');
  418. var html = [
  419. '<p>foo</p>',
  420. '<!-- bar -->',
  421. '<p>baz</p>'
  422. ].join('');
  423. assert.equal(html, pug.render(str));
  424. // Quotes
  425. var str = "<!-- script(src: '/js/validate.js') -->",
  426. js = "// script(src: '/js/validate.js') ";
  427. assert.equal(str, pug.render(js));
  428. });
  429. it('should support unbuffered comments', function(){
  430. var str = [
  431. '//- foo',
  432. 'p bar'
  433. ].join('\n');
  434. var html = [
  435. '<p>bar</p>'
  436. ].join('');
  437. assert.equal(html, pug.render(str));
  438. var str = [
  439. 'p foo',
  440. '//- bar ',
  441. 'p baz'
  442. ].join('\n');
  443. var html = [
  444. '<p>foo</p>',
  445. '<p>baz</p>'
  446. ].join('');
  447. assert.equal(html, pug.render(str));
  448. });
  449. it('should support literal html', function(){
  450. assert.equal('<!--[if IE lt 9]>weeee<![endif]-->', pug.render('<!--[if IE lt 9]>weeee<![endif]-->'));
  451. });
  452. it('should support code', function(){
  453. assert.equal('test', pug.render('!= "test"'));
  454. assert.equal('test', pug.render('= "test"'));
  455. assert.equal('test', pug.render('- var foo = "test"\n=foo'));
  456. assert.equal('foo<em>test</em>bar', pug.render('- var foo = "test"\n| foo\nem= foo\n| bar'));
  457. assert.equal('test<h2>something</h2>', pug.render('!= "test"\nh2 something'));
  458. var str = [
  459. '- var foo = "<script>";',
  460. '= foo',
  461. '!= foo'
  462. ].join('\n');
  463. var html = [
  464. '&lt;script&gt;',
  465. '<script>'
  466. ].join('');
  467. assert.equal(html, pug.render(str));
  468. var str = [
  469. '- var foo = "<script>";',
  470. '- if (foo)',
  471. ' p= foo'
  472. ].join('\n');
  473. var html = [
  474. '<p>&lt;script&gt;</p>'
  475. ].join('');
  476. assert.equal(html, pug.render(str));
  477. var str = [
  478. '- var foo = "<script>";',
  479. '- if (foo)',
  480. ' p!= foo'
  481. ].join('\n');
  482. var html = [
  483. '<p><script></p>'
  484. ].join('');
  485. assert.equal(html, pug.render(str));
  486. var str = [
  487. '- var foo;',
  488. '- if (foo)',
  489. ' p.hasFoo= foo',
  490. '- else',
  491. ' p.noFoo no foo'
  492. ].join('\n');
  493. var html = [
  494. '<p class="noFoo">no foo</p>'
  495. ].join('');
  496. assert.equal(html, pug.render(str));
  497. var str = [
  498. '- var foo;',
  499. '- if (foo)',
  500. ' p.hasFoo= foo',
  501. '- else if (true)',
  502. ' p kinda foo',
  503. '- else',
  504. ' p.noFoo no foo'
  505. ].join('\n');
  506. var html = [
  507. '<p>kinda foo</p>'
  508. ].join('');
  509. assert.equal(html, pug.render(str));
  510. var str = [
  511. 'p foo',
  512. '= "bar"',
  513. ].join('\n');
  514. var html = [
  515. '<p>foo</p>bar'
  516. ].join('');
  517. assert.equal(html, pug.render(str));
  518. var str = [
  519. 'title foo',
  520. '- if (true)',
  521. ' p something',
  522. ].join('\n');
  523. var html = [
  524. '<title>foo</title><p>something</p>'
  525. ].join('');
  526. assert.equal(html, pug.render(str));
  527. var str = [
  528. 'foo',
  529. ' bar= "bar"',
  530. ' baz= "baz"',
  531. ].join('\n');
  532. var html = [
  533. '<foo>',
  534. '<bar>bar',
  535. '<baz>baz</baz>',
  536. '</bar>',
  537. '</foo>'
  538. ].join('');
  539. assert.equal(html, pug.render(str));
  540. var str = [
  541. '-',
  542. ' var a =',
  543. ' 5;',
  544. 'p= a'
  545. ].join('\n')
  546. var html = [
  547. '<p>5</p>'
  548. ].join('');
  549. assert.equal(html, pug.render(str));
  550. });
  551. it('should support each', function(){
  552. // Array
  553. var str = [
  554. '- var items = ["one", "two", "three"];',
  555. 'each item in items',
  556. ' li= item'
  557. ].join('\n');
  558. var html = [
  559. '<li>one</li>',
  560. '<li>two</li>',
  561. '<li>three</li>'
  562. ].join('');
  563. assert.equal(html, pug.render(str));
  564. // Any enumerable (length property)
  565. var str = [
  566. '- var jQuery = { length: 3, 0: 1, 1: 2, 2: 3 };',
  567. 'each item in jQuery',
  568. ' li= item'
  569. ].join('\n');
  570. var html = [
  571. '<li>1</li>',
  572. '<li>2</li>',
  573. '<li>3</li>'
  574. ].join('');
  575. assert.equal(html, pug.render(str));
  576. // Empty array
  577. var str = [
  578. '- var items = [];',
  579. 'each item in items',
  580. ' li= item'
  581. ].join('\n');
  582. assert.equal('', pug.render(str));
  583. // Object
  584. var str = [
  585. '- var obj = { foo: "bar", baz: "raz" };',
  586. 'each val in obj',
  587. ' li= val'
  588. ].join('\n');
  589. var html = [
  590. '<li>bar</li>',
  591. '<li>raz</li>'
  592. ].join('');
  593. assert.equal(html, pug.render(str));
  594. // Complex
  595. var str = [
  596. '- var obj = { foo: "bar", baz: "raz" };',
  597. 'each key in Object.keys(obj)',
  598. ' li= key'
  599. ].join('\n');
  600. var html = [
  601. '<li>foo</li>',
  602. '<li>baz</li>'
  603. ].join('');
  604. assert.equal(html, pug.render(str));
  605. // Keys
  606. var str = [
  607. '- var obj = { foo: "bar", baz: "raz" };',
  608. 'each val, key in obj',
  609. ' li #{key}: #{val}'
  610. ].join('\n');
  611. var html = [
  612. '<li>foo: bar</li>',
  613. '<li>baz: raz</li>'
  614. ].join('');
  615. assert.equal(html, pug.render(str));
  616. // Nested
  617. var str = [
  618. '- var users = [{ name: "tj" }]',
  619. 'each user in users',
  620. ' each val, key in user',
  621. ' li #{key} #{val}',
  622. ].join('\n');
  623. var html = [
  624. '<li>name tj</li>'
  625. ].join('');
  626. assert.equal(html, pug.render(str));
  627. var str = [
  628. '- var users = ["tobi", "loki", "jane"]',
  629. 'each user in users',
  630. ' li= user',
  631. ].join('\n');
  632. var html = [
  633. '<li>tobi</li>',
  634. '<li>loki</li>',
  635. '<li>jane</li>',
  636. ].join('');
  637. assert.equal(html, pug.render(str));
  638. var str = [
  639. '- var users = ["tobi", "loki", "jane"]',
  640. 'for user in users',
  641. ' li= user',
  642. ].join('\n');
  643. var html = [
  644. '<li>tobi</li>',
  645. '<li>loki</li>',
  646. '<li>jane</li>',
  647. ].join('');
  648. assert.equal(html, pug.render(str));
  649. });
  650. it('should support if', function(){
  651. var str = [
  652. '- var users = ["tobi", "loki", "jane"]',
  653. 'if users.length',
  654. ' p users: #{users.length}',
  655. ].join('\n');
  656. assert.equal('<p>users: 3</p>', pug.render(str));
  657. assert.equal('<iframe foo="bar"></iframe>', pug.render('iframe(foo="bar")'));
  658. });
  659. it('should support unless', function(){
  660. var str = [
  661. '- var users = ["tobi", "loki", "jane"]',
  662. 'unless users.length',
  663. ' p no users',
  664. ].join('\n');
  665. assert.equal('', pug.render(str));
  666. var str = [
  667. '- var users = []',
  668. 'unless users.length',
  669. ' p no users',
  670. ].join('\n');
  671. assert.equal('<p>no users</p>', pug.render(str));
  672. });
  673. it('should support else', function(){
  674. var str = [
  675. '- var users = []',
  676. 'if users.length',
  677. ' p users: #{users.length}',
  678. 'else',
  679. ' p users: none',
  680. ].join('\n');
  681. assert.equal('<p>users: none</p>', pug.render(str));
  682. });
  683. it('should else if', function(){
  684. var str = [
  685. '- var users = ["tobi", "jane", "loki"]',
  686. 'for user in users',
  687. ' if user == "tobi"',
  688. ' p awesome #{user}',
  689. ' else if user == "jane"',
  690. ' p lame #{user}',
  691. ' else',
  692. ' p #{user}',
  693. ].join('\n');
  694. assert.equal('<p>awesome tobi</p><p>lame jane</p><p>loki</p>', pug.render(str));
  695. });
  696. it('should include block', function(){
  697. var str = [
  698. 'html',
  699. ' head',
  700. ' include fixtures/scripts.pug',
  701. ' scripts(src="/app.js")',
  702. ].join('\n');
  703. assert.equal('<html><head><script src=\"/jquery.js\"></script><script src=\"/caustic.js\"></script><scripts src=\"/app.js\"></scripts></head></html>'
  704. , pug.render(str, { filename: __dirname + '/pug.test.js' }));
  705. });
  706. it('should not fail on js newlines', function(){
  707. assert.equal("<p>foo\u2028bar</p>", pug.render("p foo\u2028bar"));
  708. assert.equal("<p>foo\u2029bar</p>", pug.render("p foo\u2029bar"));
  709. });
  710. it('should display error line number correctly up to token level', function() {
  711. var str = [
  712. 'p.',
  713. ' Lorem ipsum dolor sit amet, consectetur',
  714. ' adipisicing elit, sed do eiusmod tempor',
  715. ' incididunt ut labore et dolore magna aliqua.',
  716. 'p.',
  717. ' Ut enim ad minim veniam, quis nostrud',
  718. ' exercitation ullamco laboris nisi ut aliquip',
  719. ' ex ea commodo consequat.',
  720. 'p.',
  721. ' Duis aute irure dolor in reprehenderit',
  722. ' in voluptate velit esse cillum dolore eu',
  723. ' fugiat nulla pariatur.',
  724. 'a(href="#" Next',
  725. ].join('\n');
  726. var errorLocation = function(str) {
  727. try {
  728. pug.render(str);
  729. } catch (err) {
  730. return err.message.split('\n')[0];
  731. }
  732. };
  733. assert.equal(errorLocation(str), "Pug:13:16");
  734. });
  735. });
  736. describe('.compileFile()', function () {
  737. it('does not produce warnings for issue-1593', function () {
  738. pug.compileFile(__dirname + '/fixtures/issue-1593/index.pug');
  739. });
  740. it('should support caching (pass 1)', function () {
  741. fs.writeFileSync(__dirname + '/temp/input-compileFile.pug', '.foo bar');
  742. var fn = pug.compileFile(__dirname + '/temp/input-compileFile.pug',
  743. { cache: true });
  744. var expected = '<div class="foo">bar</div>';
  745. assert(fn() === expected);
  746. });
  747. it('should support caching (pass 2)', function () {
  748. // Poison the input file
  749. fs.writeFileSync(__dirname + '/temp/input-compileFile.pug', '.big fat hen');
  750. var fn = pug.compileFile(__dirname + '/temp/input-compileFile.pug',
  751. { cache: true });
  752. var expected = '<div class="foo">bar</div>';
  753. assert(fn() === expected);
  754. });
  755. });
  756. describe('.render()', function () {
  757. it('should support .pug.render(str, fn)', function(){
  758. pug.render('p foo bar', function(err, str){
  759. assert.ok(!err);
  760. assert.equal('<p>foo bar</p>', str);
  761. });
  762. });
  763. it('should support .pug.render(str, options, fn)', function(){
  764. pug.render('p #{foo}', { foo: 'bar' }, function(err, str){
  765. assert.ok(!err);
  766. assert.equal('<p>bar</p>', str);
  767. });
  768. });
  769. it('should support .pug.render(str, options, fn) cache', function(){
  770. pug.render('p bar', { cache: true }, function(err, str){
  771. assert.ok(/the "filename" option is required for caching/.test(err.message));
  772. });
  773. pug.render('p foo bar', { cache: true, filename: 'test' }, function(err, str){
  774. assert.ok(!err);
  775. assert.equal('<p>foo bar</p>', str);
  776. });
  777. });
  778. })
  779. describe('.compile()', function(){
  780. it('should support .compile()', function(){
  781. var fn = pug.compile('p foo');
  782. assert.equal('<p>foo</p>', fn());
  783. });
  784. it('should support .compile() locals', function(){
  785. var fn = pug.compile('p= foo');
  786. assert.equal('<p>bar</p>', fn({ foo: 'bar' }));
  787. });
  788. it('should support .compile() locals in \'self\' hash', function(){
  789. var fn = pug.compile('p= self.foo', {self: true});
  790. assert.equal('<p>bar</p>', fn({ foo: 'bar' }));
  791. });
  792. it('should support .compile() no debug', function(){
  793. var fn = pug.compile('p foo\np #{bar}', {compileDebug: false});
  794. assert.equal('<p>foo</p><p>baz</p>', fn({bar: 'baz'}));
  795. });
  796. it('should support .compile() no debug and global helpers', function(){
  797. var fn = pug.compile('p foo\np #{bar}', {compileDebug: false, helpers: 'global'});
  798. assert.equal('<p>foo</p><p>baz</p>', fn({bar: 'baz'}));
  799. });
  800. it('should be reasonably fast', function(){
  801. pug.compile(perfTest, {})
  802. });
  803. it('allows trailing space (see #1586)', function () {
  804. var res = pug.render('ul \n li An Item');
  805. assert.equal('<ul> <li>An Item</li></ul>', res);
  806. });
  807. });
  808. describe('.compileClient()', function () {
  809. it('should support pug.compileClient(str)', function () {
  810. var src = fs.readFileSync(__dirname + '/cases/basic.pug');
  811. var expected = fs.readFileSync(__dirname + '/cases/basic.html', 'utf8').replace(/\s/g, '');
  812. var fn = pug.compileClient(src);
  813. fn = Function('pug', fn.toString() + '\nreturn template;')(pug.runtime);
  814. var actual = fn({name: 'foo'}).replace(/\s/g, '');
  815. expect(actual).toBe(expected);
  816. });
  817. it('should support pug.compileClient(str, options)', function () {
  818. var src = '.bar= self.foo';
  819. var fn = pug.compileClient(src, {self: true});
  820. fn = Function('pug', fn.toString() + '\nreturn template;')(pug.runtime);
  821. var actual = fn({foo: 'baz'});
  822. expect(actual).toBe('<div class="bar">baz</div>');
  823. });
  824. it('should support module syntax in pug.compileClient(str, options) when inlineRuntimeFunctions it true', function () {
  825. var src = '.bar= self.foo';
  826. var fn = pug.compileClient(src, {self: true, module: true, inlineRuntimeFunctions: true});
  827. expect(fn).toMatchSnapshot();
  828. fs.writeFileSync(__dirname + '/temp/input-compileModuleFileClient.js', fn);
  829. var expected = '<div class="bar">baz</div>';
  830. var fn = require(__dirname + '/temp/input-compileModuleFileClient.js');
  831. expect(fn({foo: 'baz'})).toBe('<div class="bar">baz</div>');
  832. });
  833. it('should support module syntax in pug.compileClient(str, options) when inlineRuntimeFunctions it false', function () {
  834. var src = '.bar= self.foo';
  835. var fn = pug.compileClient(src, {self: true, module: true, inlineRuntimeFunctions: false});
  836. expect(fn).toMatchSnapshot();
  837. fs.writeFileSync(__dirname + '/temp/input-compileModuleFileClient.js', fn);
  838. var fn = require(__dirname + '/temp/input-compileModuleFileClient.js');
  839. expect(fn({foo: 'baz'})).toBe('<div class="bar">baz</div>');
  840. });
  841. });
  842. describe('.renderFile()', function () {
  843. it('will synchronously return a string', function () {
  844. var expected = fs.readFileSync(__dirname + '/cases/basic.html', 'utf8').replace(/\s/g, '');
  845. var actual = pug.renderFile(__dirname + '/cases/basic.pug', {name: 'foo'}).replace(/\s/g, '');
  846. assert(actual === expected);
  847. });
  848. it('when given a callback, it calls that rather than returning', function (done) {
  849. var expected = fs.readFileSync(__dirname + '/cases/basic.html', 'utf8').replace(/\s/g, '');
  850. pug.renderFile(__dirname + '/cases/basic.pug', {name: 'foo'}, function (err, actual) {
  851. if (err) return done(err);
  852. assert(actual.replace(/\s/g, '') === expected);
  853. done();
  854. });
  855. });
  856. it('when given a callback, it calls that rather than returning even if there are no options', function (done) {
  857. var expected = fs.readFileSync(__dirname + '/cases/basic.html', 'utf8').replace(/\s/g, '');
  858. pug.renderFile(__dirname + '/cases/basic.pug', function (err, actual) {
  859. if (err) return done(err);
  860. assert(actual.replace(/\s/g, '') === expected);
  861. done();
  862. });
  863. });
  864. it('when given a callback, it calls that with any errors', function (done) {
  865. pug.renderFile(__dirname + '/fixtures/runtime.error.pug', function (err, actual) {
  866. assert.ok(err);
  867. done();
  868. });
  869. });
  870. it('should support caching (pass 1)', function (done) {
  871. fs.writeFileSync(__dirname + '/temp/input-renderFile.pug', '.foo bar');
  872. pug.renderFile(__dirname + '/temp/input-renderFile.pug', { cache: true }, function (err, actual) {
  873. if (err) return done(err);
  874. assert.equal('<div class="foo">bar</div>', actual);
  875. done();
  876. });
  877. });
  878. it('should support caching (pass 2)', function (done) {
  879. // Poison the input file
  880. fs.writeFileSync(__dirname + '/temp/input-renderFile.pug', '.big fat hen');
  881. pug.renderFile(__dirname + '/temp/input-renderFile.pug', { cache: true }, function (err, actual) {
  882. if (err) return done(err);
  883. assert.equal('<div class="foo">bar</div>', actual);
  884. done();
  885. });
  886. });
  887. });
  888. describe('.compileFileClient(path, options)', function () {
  889. it('returns a string form of a function called `template`', function () {
  890. var src = pug.compileFileClient(__dirname + '/cases/basic.pug');
  891. var expected = fs.readFileSync(__dirname + '/cases/basic.html', 'utf8').replace(/\s/g, '');
  892. var fn = Function('pug', src + '\nreturn template;')(pug.runtime);
  893. var actual = fn({name: 'foo'}).replace(/\s/g, '');
  894. assert(actual === expected);
  895. });
  896. it('accepts the `name` option to rename the resulting function', function () {
  897. var src = pug.compileFileClient(__dirname + '/cases/basic.pug', {name: 'myTemplateName'});
  898. var expected = fs.readFileSync(__dirname + '/cases/basic.html', 'utf8').replace(/\s/g, '');
  899. var fn = Function('pug', src + '\nreturn myTemplateName;')(pug.runtime);
  900. var actual = fn({name: 'foo'}).replace(/\s/g, '');
  901. assert(actual === expected);
  902. });
  903. it('should support caching (pass 1)', function () {
  904. fs.writeFileSync(__dirname + '/temp/input-compileFileClient.pug', '.foo bar');
  905. var src = pug.compileFileClient(__dirname + '/temp/input-compileFileClient.pug',
  906. { name: 'myTemplateName',
  907. cache: true });
  908. var expected = '<div class="foo">bar</div>';
  909. var fn = Function('pug', src + '\nreturn myTemplateName;')(pug.runtime);
  910. assert(fn() === expected);
  911. });
  912. it('should support caching (pass 2)', function () {
  913. // Poison the input file
  914. fs.writeFileSync(__dirname + '/temp/input-compileFileClient.pug', '.big fat hen');
  915. var src = pug.compileFileClient(__dirname + '/temp/input-compileFileClient.pug',
  916. { name: 'myTemplateName',
  917. cache: true });
  918. var expected = '<div class="foo">bar</div>';
  919. var fn = Function('pug', src + '\nreturn myTemplateName;')(pug.runtime);
  920. assert(fn() === expected);
  921. });
  922. });
  923. describe('.runtime', function () {
  924. describe('.merge', function () {
  925. it('merges two attribute objects, giving precedensce to the second object', function () {
  926. assert.deepEqual(pug.runtime.merge({}, {'class': ['foo', 'bar'], 'foo': 'bar'}), {'class': ['foo', 'bar'], 'foo': 'bar'});
  927. assert.deepEqual(pug.runtime.merge({'class': ['foo'], 'foo': 'baz'}, {'class': ['bar'], 'foo': 'bar'}), {'class': ['foo', 'bar'], 'foo': 'bar'});
  928. assert.deepEqual(pug.runtime.merge({'class': ['foo', 'bar'], 'foo': 'bar'}, {}), {'class': ['foo', 'bar'], 'foo': 'bar'});
  929. });
  930. });
  931. describe('.attrs', function () {
  932. it('Renders the given attributes object', function () {
  933. assert.equal(pug.runtime.attrs({}), '');
  934. assert.equal(pug.runtime.attrs({'class': []}), '');
  935. assert.equal(pug.runtime.attrs({'class': ['foo']}), ' class="foo"');
  936. assert.equal(pug.runtime.attrs({'class': ['foo'], 'id': 'bar'}), ' class="foo" id="bar"');
  937. });
  938. });
  939. });
  940. describe('filter indentation', function () {
  941. it('is maintained', function () {
  942. var filters = {
  943. indents: function(str){
  944. return str.split(/\n/).map(function (line) { return line.match(/^ */)[0].length; }).join(",");
  945. }
  946. };
  947. var indents = [
  948. ':indents',
  949. ' x',
  950. ' x',
  951. ' x',
  952. ' x',
  953. ' x',
  954. ' x',
  955. ' x',
  956. ' x',
  957. ' x',
  958. ' x',
  959. ' x',
  960. ' x',
  961. ' x',
  962. ' x',
  963. ' x'
  964. ].join('\n');
  965. assert.equal(pug.render(indents, {filters: filters}), '0,1,2,3,0,4,4,3,3,4,2,0,2,0,1');
  966. });
  967. });
  968. describe('.compile().dependencies', function() {
  969. it('should list the filename of the template referenced by extends', function(){
  970. var filename = __dirname + '/dependencies/extends1.pug';
  971. var str = fs.readFileSync(filename, 'utf8');
  972. var info = pug.compile(str, {filename: filename});
  973. assert.deepEqual([
  974. path.resolve(__dirname + '/dependencies/dependency1.pug')
  975. ], info.dependencies);
  976. });
  977. it('should list the filename of the template referenced by an include', function() {
  978. var filename = __dirname + '/dependencies/include1.pug';
  979. var str = fs.readFileSync(filename, 'utf8');
  980. var info = pug.compile(str, {filename: filename});
  981. assert.deepEqual([
  982. path.resolve(__dirname + '/dependencies/dependency1.pug')
  983. ], info.dependencies);
  984. });
  985. it('should list the dependencies of extends dependencies', function() {
  986. var filename = __dirname + '/dependencies/extends2.pug';
  987. var str = fs.readFileSync(filename, 'utf8');
  988. var info = pug.compile(str, {filename: filename});
  989. assert.deepEqual([
  990. path.resolve(__dirname + '/dependencies/dependency2.pug'),
  991. path.resolve(__dirname + '/dependencies/dependency3.pug')
  992. ], info.dependencies);
  993. });
  994. it('should list the dependencies of include dependencies', function() {
  995. var filename = __dirname + '/dependencies/include2.pug';
  996. var str = fs.readFileSync(filename, 'utf8');
  997. var info = pug.compile(str, {filename: filename});
  998. assert.deepEqual([
  999. path.resolve(__dirname + '/dependencies/dependency2.pug'),
  1000. path.resolve(__dirname + '/dependencies/dependency3.pug')
  1001. ],info.dependencies);
  1002. });
  1003. });
  1004. describe('.name', function() {
  1005. it('should have a name attribute', function() {
  1006. assert.strictEqual(pug.name, 'Pug');
  1007. });
  1008. });
  1009. });