Passed
Push — master ( beba88...91d9d9 )
by Björn
02:26
created

test.02.handlebars.js ➔ ???   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 518

Duplication

Lines 52
Ratio 10.04 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
c 1
b 0
f 1
nc 1
dl 52
loc 518
rs 8.2857
nop 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B test.02.handlebars.js ➔ ... ➔ ??? 52 109 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import Patternlibrary from '..';
2
3
import equal from 'assert-dir-equal';
4
import rimraf from 'rimraf';
5
import mkdirp from 'mkdirp';
6
7
var expect = require('chai').expect;
8
var $handlebars = require('../lib/vendor/handlebars');
9
var stripHtml = require('striptags');
10
11
/**
12
 * Compares the output of a $handlebars template to an expected string. Data can also be passed to the template function.
13
 * @param {string} input - String to compile into a $handlebars template.
14
 * @param {string} expected - Expected output of the template.
15
 * @param {object} data - Data to pass to the $handlebars context.
16
 * @throws {AssertionError} Throws an error if the $handlebars output and expected output are not equal.
17
 */
18
function compare(input, expected, data) {
19
  var template = $handlebars.compile(input);
20
  expect(template(data || {})).to.equal(expected);
21
}
22
23
// A note about assertions: most of these tests use the `compare()` function 
24
// above. However, in cases where the output needs to be modified in some way 
25
// before it's compared, or in cases where a substring is being searched for, 
26
// a $handlebars template is created manually inside of the test.
27
28
describe('Patternlibrary built-in Handlebars helpers', () => {
29
30
	const FIXTURES = 'test/fixtures.staticpages/';
31
32
	const CLEAN_UP = !true;
33
34
	var patternlibraryOptions = {
35
	    verbose: false,
36
	    dest : FIXTURES + 'build',
37
	    root    : FIXTURES + 'pages/',
38
	    layouts : FIXTURES + 'layouts',
39
	    partials: FIXTURES + 'partials'
40
	}
41
	
42
	describe('Structural', () => {
43
44
		describe('{{#repeat}}{{/repeat}}', () => {
45
		    it('prints content multiple times', function (done) {
46
		    
47
		        patternlibraryOptions = {
48
		            verbose : false,
49
		            dest    : FIXTURES + 'helper-repeat/build',
50
		            root    : FIXTURES + 'helper-repeat/pages/',
51
		            layouts : FIXTURES + 'helper-repeat/layouts/',
52
		            partials: FIXTURES + 'helper-repeat/partials/',
53
		            nogui   : true,
54
		            testing : true
55
		        };
56
		        rimraf.sync(FIXTURES + 'helper-repeat/build'); mkdirp(FIXTURES + 'helper-repeat/build');
57
		        var p = new Patternlibrary.Patternlibrary(patternlibraryOptions);
58
		    
59
		        p.run();
60
		    
61
		        setTimeout( function () {
62
		            equal(FIXTURES + 'helper-repeat/expected/index.html', FIXTURES + 'helper-repeat/build/index.html');
63
		            if (CLEAN_UP) rimraf.sync(FIXTURES + 'helper-repeat/build');
0 ignored issues
show
Coding Style Best Practice introduced by Björn Bartels
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
64
		            done();
65
		        }, 250);
66
		    
67
		    });
68
	    });
69
70
	    describe('{{#ifEqual}}{{/ifEqual}}', () => {
71
		    it('compares two values', function (done) {
72
		    
73
		        patternlibraryOptions = {
74
		            verbose : false,
75
		            dest    : FIXTURES + 'helper-ifequal/build',
76
		            root    : FIXTURES + 'helper-ifequal/pages/',
77
		            layouts : FIXTURES + 'helper-ifequal/layouts/',
78
		            partials: FIXTURES + 'helper-ifequal/partials/',
79
		            nogui   : true,
80
		            testing : true
81
		        };
82
		        rimraf.sync(FIXTURES + 'helper-ifequal/build'); mkdirp(FIXTURES + 'helper-ifequal/build');
83
		        var p = new Patternlibrary.Patternlibrary(patternlibraryOptions);
84
		    
85
		        p.run();
86
		    
87
		        setTimeout( function () {
88
		            equal(FIXTURES + 'helper-ifequal/expected/index.html', FIXTURES + 'helper-ifequal/build/index.html');
89
		            if (CLEAN_UP) rimraf.sync(FIXTURES + 'helper-ifequal/build');
0 ignored issues
show
Coding Style Best Practice introduced by Björn Bartels
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
90
		            done();
91
		        }, 250);
92
		    
93
		    });
94
	    });
95
96 View Code Duplication
	    describe('{{#ifpage}}{{/ifpage}}', () => {
0 ignored issues
show
Duplication introduced by Björn Bartels
This code seems to be duplicated in your project.
Loading history...
97
		    it('checks the current page', function (done) {
98
		    
99
		        patternlibraryOptions = {
100
		            verbose : false,
101
		            dest    : FIXTURES + 'helper-ifpage/build',
102
		            root    : FIXTURES + 'helper-ifpage/pages/',
103
		            layouts : FIXTURES + 'helper-ifpage/layouts/',
104
		            partials: FIXTURES + 'helper-ifpage/partials/',
105
		            nogui   : true,
106
		            testing : true
107
		        };
108
		        rimraf.sync(FIXTURES + 'helper-ifpage/build'); mkdirp(FIXTURES + 'helper-ifpage/build');
109
		        var p = new Patternlibrary.Patternlibrary(patternlibraryOptions);
110
		    
111
		        p.run();
112
		    
113
		        setTimeout( function () {
114
		            equal(FIXTURES + 'helper-ifpage/expected/index.html', FIXTURES + 'helper-ifpage/build/index.html');
115
		            equal(FIXTURES + 'helper-ifpage/expected/about.html', FIXTURES + 'helper-ifpage/build/about.html');
116
		            if (CLEAN_UP) rimraf.sync(FIXTURES + 'helper-ifpage/build');
0 ignored issues
show
Coding Style Best Practice introduced by Björn Bartels
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
117
		            done();
118
		        }, 250);
119
		    
120
		    });
121
	    });
122
123 View Code Duplication
	    describe('{{#unlesspage}}{{/unlesspage}}', () => {
0 ignored issues
show
Duplication introduced by Björn Bartels
This code seems to be duplicated in your project.
Loading history...
124
		    it('checks the current page (negation of ifpage)', function (done) {
125
		    
126
		        patternlibraryOptions = {
127
		            verbose : false,
128
		            dest    : FIXTURES + 'helper-unlesspage/build',
129
		            root    : FIXTURES + 'helper-unlesspage/pages/',
130
		            layouts : FIXTURES + 'helper-unlesspage/layouts/',
131
		            partials: FIXTURES + 'helper-unlesspage/partials/',
132
		            nogui   : true,
133
		            testing : true
134
		        };
135
		        rimraf.sync(FIXTURES + 'helper-unlesspage/build'); mkdirp(FIXTURES + 'helper-unlesspage/build');
136
		        var p = new Patternlibrary.Patternlibrary(patternlibraryOptions);
137
		    
138
		        p.run();
139
		    
140
		        setTimeout( function () {
141
		            equal(FIXTURES + 'helper-unlesspage/expected/index.html', FIXTURES + 'helper-unlesspage/build/index.html');
142
		            equal(FIXTURES + 'helper-unlesspage/expected/about.html', FIXTURES + 'helper-unlesspage/build/about.html');
143
		            if (CLEAN_UP) rimraf.sync(FIXTURES + 'helper-unlesspage/build');
0 ignored issues
show
Coding Style Best Practice introduced by Björn Bartels
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
144
		            done();
145
		        }, 250);
146
		    
147
		    });
148
	    });
149
		
150
	});
151
152
	describe('Formatting', () => {
153
154
		describe('{{#code}}{{/code}}', () => {
155
		    it('renders code blocks', function (done) {
156
		    
157
		        patternlibraryOptions = {
158
		            verbose : false,
159
		            dest    : FIXTURES + 'helper-code/build',
160
		            root    : FIXTURES + 'helper-code/pages/',
161
		            layouts : FIXTURES + 'helper-code/layouts/',
162
		            partials: FIXTURES + 'helper-code/partials/',
163
		            nogui   : true,
164
		            testing : true
165
		        };
166
		        rimraf.sync(FIXTURES + 'helper-code/build'); mkdirp(FIXTURES + 'helper-code/build');
167
		        var p = new Patternlibrary.Patternlibrary(patternlibraryOptions);
168
		    
169
		        p.run();
170
		    
171
		        setTimeout( function () {
172
		            equal(FIXTURES + 'helper-code/expected/index.html', FIXTURES + 'helper-code/build/index.html');
173
		            if (CLEAN_UP) rimraf.sync(FIXTURES + 'helper-code/build');
0 ignored issues
show
Coding Style Best Practice introduced by Björn Bartels
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
174
		            done();
175
		        }, 250);
176
		    
177
		    });
178
        });
179
180
	    describe('{{#markdown}}{{/markdown}}', () => {
181
		    it('converts Markdown to HTML (block-helper)', function (done) {
182
		    
183
		        patternlibraryOptions = {
184
		            verbose : false,
185
		            dest    : FIXTURES + 'helper-markdown/build',
186
		            root    : FIXTURES + 'helper-markdown/pages/',
187
		            layouts : FIXTURES + 'helper-markdown/layouts/',
188
		            partials: FIXTURES + 'helper-markdown/partials/',
189
		            nogui   : true,
190
		            testing : true
191
		        };
192
		        rimraf.sync(FIXTURES + 'helper-markdown/build'); mkdirp(FIXTURES + 'helper-markdown/build');
193
		        var p = new Patternlibrary.Patternlibrary(patternlibraryOptions);
194
		    
195
		        p.run();
196
		    
197
		        setTimeout( function () {
198
		            equal(FIXTURES + 'helper-markdown/expected/index.html', FIXTURES + 'helper-markdown/build/index.html');
199
		            if (CLEAN_UP) rimraf.sync(FIXTURES + 'helper-markdown/build');
0 ignored issues
show
Coding Style Best Practice introduced by Björn Bartels
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
200
		            done();
201
		        }, 250);
202
		    
203
		    });
204
        });
205
	    
206
        describe('{{md}}', () => {
207
            it('converts Markdown to HTML', () => {
208
                compare('{{md "**Bold**"}}', '<p><strong>Bold</strong></p>\n');
209
            });
210
        });
211
    
212
        describe('{{#heading}}{{/heading}}', () => {
213
            it('creates a heading of a specific level', () => {
214
                var expected = '<h1 id="title" class="docs-heading">Title<a class="docs-heading-icon" href="#title"></a></h1>';
215
        
216
                compare('{{#heading 1}}Title{{/heading}}', expected);
217
            });
218
    
219
            it('creates a heading with a custom ID', () => {
220
                var expected = '<h1 id="custom" class="docs-heading">Title<a class="docs-heading-icon" href="#custom"></a></h1>';
221
        
222
                compare('{{#heading 1 "custom"}}Title{{/heading}}', expected);
223
            });
224
        });
225
    
226
        describe('{{escape}}', () => {
227
            it('escapes text for use in a URL hash', () => {
228
                compare('{{escape "this text"}}', 'this-text');
229
            });
230
        });
231
    
232
        describe('{{toUpper}}', () => {
233
            it('capitalizes the first letter of a string', () => {
234
                compare('{{toUpper "kittens"}}', 'Kittens');
235
            });
236
        });
237
    
238
        describe('{{toLower}}', () => {
239
            it('converts a string to lowercase', () => {
240
                compare('{{toLower "SHOUT"}}', 'shout')
241
            });
242
        });
243
    
244
        describe('{{raw}}{{/raw}}', () => {
245
            it('ignores $handlebars', () => {
246
                compare('{{{{raw}}}}{{ignore}}{{{{/raw}}}}', '{{ignore}}');
247
            });
248
        });
249
    
250
        describe('{{#filter}}{{/filter}}', () => {
251
            it('filters private SassDoc and JSDoc objects', () => {
252
                var data = {
253
                    item: { access: 'private' }
254
                };
255
        
256
                compare('{{#filter item}}Private{{/filter}}', '', data);
257
            });
258
    
259
            it('displays public SassDoc and JSDoc objects', () => {
260
                var data = {
261
                    item: { access: 'public' }
262
                };
263
        
264
                compare('{{#filter item}}Public{{/filter}}', 'Public', data);
265
            });
266
    
267
            it('filters SassDoc aliases', () => {
268
                var data = {
269
                    item: { alias: true }
270
                };
271
        
272
                compare('{{#filter item}}Alias{{/filter}}', '', data);
273
            });
274
        });
275
    });
276
277
    describe('JavaScript', () => {
278
        describe('{{writeJsConstructor}}', () => {
279
            it('prints formatted JavaScript code to initialize a Patternlibrary/Siteapp plugin', () => {
280
                var template = $handlebars.compile('{{writeJsConstructor "Plugin"}}');
281
                var output = template();
282
        
283
                expect(output, 'Should be formatted by Highlight.js').to.contain('hljs');
284
                expect(stripHtml(output), 'Should include Patternlibrary/Siteapp code').to.equal('var elem = new YourApp.Plugin(element, options);');
285
            });
286
        });
287
    
288
        describe('{{writeJsFunction}}', () => {
289
            it('prints a JavaScript function with no parameters', () => {
290
                var data = {
291
                    method: {
292
                        name: 'petKitty',
293
                        params: []
294
                    }
295
                };
296
        
297
                var template = $handlebars.compile('{{writeJsFunction method}}');
298
                var output = template(data);
299
        
300
                expect(stripHtml(output)).to.equal(`$('#element').your_app('petKitty');`);
301
            });
302
    
303
            it('prints a JavaScript function with parameters', () => {
304
                var data = {
305
                    method: {
306
                        name: 'petKitty',
307
                        params: [
308
                            { name: 'param1' },
309
                            { name: 'param2' }
310
                        ]
311
                    }
312
                };
313
        
314
                var template = $handlebars.compile('{{writeJsFunction method}}');
315
                var output = template(data);
316
        
317
                expect(stripHtml(output)).to.equal(`$('#element').your_app('petKitty', param1, param2);`);
318
            });
319
        });
320
    
321
        describe('{{formatJsModule}}', () => {
322
            it('converts a JSDoc module definition to a filename', () => {
323
                compare('{{formatJsModule "module:foundation.toggler"}}', 'foundation.toggler.js');
324
            });
325
        });
326
    
327
        describe('{{formatJsOptionName}}', () => {
328
            it('converts a plugin option name to an HTML data attribute', () => {
329
                compare('{{formatJsOptionName "optionName"}}', 'data-option-name');
330
            });
331
        });
332
    
333
        describe('{{formatJsOptionValue}}', () => {
334
            it('prints non-String values as-is', () => {
335
                var data = {
336
                    value: '0'
337
                };
338
        
339
                compare('{{formatJsOptionValue value}}', '0', data);
340
            });
341
    
342
            it('prints String values without the quotes on either side', () => {
343
                var data = {
344
                    singleQuotes: "'value'",
345
                    multiQuotes: '"value"'
346
                };
347
        
348
                compare(`{{formatJsOptionValue singleQuotes}}`, 'value', data);
349
                compare(`{{formatJsOptionValue multiQuotes}}`, 'value', data);
350
            });
351
    
352
            it('returns an empty string if an option is missing a value', () => {
353
                compare('{{formatJsOptionValue undef}}', '');
354
            });
355
        });
356
    
357
        describe('{{formatJsEventName}}', () => {
358
            it('formats a JSDoc event to look like "YourApp"-namespaced events', () => {
359
                var data = {
360
                    name: 'event',
361
                    title: 'Plugin'
362
                };
363
        
364
                compare('{{formatJsEventName name title}}', 'event.zf.plugin', data);
365
            });
366
    
367
            it('handles plugin names that are intercapped', () => {
368
                var data = {
369
                    name: 'event',
370
                    title: 'PluginName'
371
                };
372
        
373
                compare('{{formatJsEventName name title}}', 'event.zf.pluginName', data);
374
            });
375
        });
376
    });
377
378
    describe('Links', () => {
379
        describe('{{editLink}}', () => {
380
            it('generates a GitHub edit link point to a repository, branch, and file', () => {
381
                compare('{{editLink "foundation-sites" "master" "docs/pages/index.html"}}', 'https://github.com/zurb/foundation-sites/edit/master/docs/pages/index.md');
382
            });
383
        });
384
    
385
        describe('{{issueLink}}', () => {
386
            it('generates a GitHub link to open a new issue, with a preset title', () => {
387
                var template = $handlebars.compile('{{issueLink "foundation-sites" "Plugin"}}');
388
                var output = template();
389
        
390
                expect(output, 'links to GitHub issue tracker').to.contain('https://github.com/zurb/foundation-sites/issues/new?title');
391
                expect(output, 'includes tag in preset title').to.contain('Plugin');
392
                expect(output, 'includes super loud title that you should replace').to.contain('ISSUE%20NAME%20HERE');
393
            });
394
        });
395
    });
396
397
    describe('Sass', () => {
398
        describe('{{writeSassMixin}}', () => {
399
            it('formats a Sass mixin with no parameters', () => {
400
            var data = {
401
                mixin: {
402
                context: { name: 'name' }
403
                }
404
            };
405
    
406
            var template = $handlebars.compile('{{writeSassMixin mixin}}');
407
            var output = stripHtml(template(data));
408
    
409
            expect(output).to.equal('@include name;');
410
            });
411
    
412
            it('formats a Sass mixin with parameters', () => {
413
                var data = {
414
                    mixin: {
415
                        context: { name: 'name' },
416
                        parameter: [
417
                            { name: 'param1' },
418
                            { name: 'param2' }
419
                        ]
420
                    }
421
                };
422
        
423
                var template = $handlebars.compile('{{writeSassMixin mixin}}');
424
                var output = stripHtml(template(data));
425
        
426
                expect(output).to.equal('@include name($param1, $param2);');
427
            });
428
    
429
            it('formats a Sass mixin with a @content directive', () => {
430
                var data = {
431
                    mixin: {
432
                        context: { name: 'name' },
433
                        content: 'Content'
434
                    }
435
                };
436
        
437
                var template = $handlebars.compile('{{writeSassMixin mixin}}');
438
                var output = stripHtml(template(data));
439
        
440
                expect(output).to.equal('@include name { }');
441
            });
442
        });
443
    
444
        describe('{{writeSassFunction}}', () => {
445
            it('formats a Sass function with no parameters', () => {
446
                var data = {
447
                    func: {
448
                    context: { name: 'name' }
449
                    }
450
                };
451
        
452
                var template = $handlebars.compile('{{writeSassFunction func}}');
453
                var output = stripHtml(template(data));
454
        
455
                expect(output).to.equal('name()');
456
            });
457
    
458
            it('formats a Sass function with parameters', () => {
459
                var data = {
460
                    func: {
461
                    context: { name: 'name' },
462
                        parameter: [
463
                            { name: 'param1' },
464
                            { name: 'param2' }
465
                        ]
466
                    }
467
                };
468
        
469
                var template = $handlebars.compile('{{writeSassFunction func}}');
470
                var output = stripHtml(template(data));
471
        
472
                expect(output).to.equal('name($param1, $param2)');
473
            });
474
        });
475
    
476
        describe('{{writeSassVariable}}', () => {
477
            it('formats a Sass variable', () => {
478
                var data = {
479
                    variable: {
480
                    context: {
481
                        name: 'name',
482
                        value: 'value'
483
                    }
484
                    }
485
                };
486
        
487
                var template = $handlebars.compile('{{writeSassVariable variable}}');
488
                var output = stripHtml(template(data));
489
        
490
                expect(output).to.equal('$name: value;');
491
            });
492
        });
493
    
494
        describe('{{formatSassTypes}}', () => {
495
            it('formats a SassDoc @type annotation with one value', () => {
496
                compare('{{formatSassTypes "String"}}', 'String');
497
            });
498
    
499
            it('formats a SassDoc @type annotation with multiple values', () => {
500
                compare('{{formatSassTypes "String|List"}}', 'String or List');
501
            });
502
    
503
            it('prints an empty string if no value is defined', () => {
504
                compare('{{formatSassTypes undef}}', '');
505
            });
506
        });
507
    
508
        describe('{{formatSassValue}}', () => {
509
            it('formats basic values as-is', () => {
510
                compare('{{formatSassValue "value"}}', 'value');
511
            });
512
    
513
            it('formats maps with each value on a separate line', () => {
514
                var template = $handlebars.compile(`{{formatSassValue '(one: one,two: two)'}}`);
515
                var output = template();
516
        
517
                expect(output).to.equal('one: one&lt;br&gt;two: two');
518
            });
519
    
520
            it('returns the word "None" for undefined values', () => {
521
                var template = $handlebars.compile('{{formatSassValue undef}}');
522
                var output = template();
523
        
524
                expect(output).to.contain('None');
525
            });
526
        });
527
    
528
        describe('{{writeSassLink}}', () => {
529
            it('formats a SassDoc @link annotation', () => {
530
                var data = {
531
                    link: [{
532
                    url: '#',
533
                    caption: 'Caption'
534
                    }]
535
                };
536
        
537
                compare('{{writeSassLink link}}', '<p><strong>Learn more:</strong> <a href="#">Caption</a></p>', data);
538
            });
539
    
540
            it('prints an empty string for an undefined link', () => {
541
                compare('{{writeSassLink undef}}', '');
542
            });
543
        });
544
    });
545
});
546