From 0bc2d0b78fe36d422ce1e7f7d1d3718c81a8d93a Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Mon, 11 Feb 2013 15:16:19 +1000 Subject: [PATCH 01/13] added tests for jsdoc/util/doop --- test/specs/jsdoc/util/doop.js | 75 +++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/test/specs/jsdoc/util/doop.js b/test/specs/jsdoc/util/doop.js index c0f53292..217303de 100644 --- a/test/specs/jsdoc/util/doop.js +++ b/test/specs/jsdoc/util/doop.js @@ -1,4 +1,73 @@ /*global describe: true, it: true */ -describe("jsdoc/util/doop", function() { - // TODO -}); \ No newline at end of file +describe('jsdoc/util/doop', function() { + var doop = require('jsdoc/util/doop'); + + it('should exist', function() { + expect(doop).toBeDefined(); + expect(typeof doop).toBe('object'); + }); + + it('should export a doop function', function() { + expect(doop.doop).toBeDefined(); + expect(typeof doop.doop).toBe('function'); + }); + + // deep-clones a simple object. + describe('doop', function() { + it("should return the input object if it's simple (boolan, string etc) or a function", function() { + // .toBe uses === to test. + + // test a number... + expect(doop.doop(3)).toBe(3); + // test a string... + expect(doop.doop('asdf')).toBe('asdf'); + // test a boolean... + expect(doop.doop(true)).toBe(true); + // test a function... + var f = function () {}; + expect(doop.doop(f)).toBe(f); + }); + + it("should return a clone of an array", function() { + var inp = [1,2,3], + out = doop.doop(inp); + // toEqual is a comparison on properties; toBe is === comparison. + expect(inp).toEqual(out); + expect(inp).not.toBe(out); + }); + + it("should return a clone of an object", function() { + var inp = {a:1, b:2, 'asdf-fdsa': 3}; + out = doop.doop(inp); + // toEqual is a comparison on properties; toBe is === comparison. + expect(inp).toEqual(out); + expect(inp).not.toBe(out); + }); + + // checks that a === b if it's not an object or array (or it's af function); + // otherwise recurses down into keys and compares them. + function compareForEquality(a, b) { + if (a instanceof Object && a.constructor != Function) { + // if it's an object and not a function, it should clone. + var keys = Object.keys(a); + expect(Object.keys(a)).toEqual(Object.keys(b)); + for (var i = 0; i < keys.length; ++i) { + compareForEquality(a[keys[i]], b[keys[i]]); + } + } else { + // otherwise, it should be exactly equal. + expect(a).toBe(b); + } + } + + it("should clone recursively", function() { + var inp = {a:1, b:2, 'asdf-fdsa': {a: 'fdsa', b: [1,2,3]}}; + out = doop.doop(inp); + // toEqual is a comparison on properties; toBe is === comparison. + expect(inp).toEqual(out); + expect(inp).not.toBe(out); + // double-check + compareForEquality(inp, out); + }); + }); +}); From d93e85c0969f01381493ea46ab5c8a1b053239e8 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Mon, 11 Feb 2013 16:57:46 +1000 Subject: [PATCH 02/13] added tests for getAttribs and scopeToPunc --- test/specs/jsdoc/util/templateHelper.js | 128 ++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 7 deletions(-) diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 41ee1c15..190757ed 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -2,7 +2,8 @@ var hasOwnProp = Object.prototype.hasOwnProperty; describe("jsdoc/util/templateHelper", function() { - var helper = require('jsdoc/util/templateHelper'); + var helper = require('jsdoc/util/templateHelper'), + doclet = require('jsdoc/doclet'); helper.registerLink('test', 'path/to/test.html'); helper.registerLink('test."long blah"/blah', 'path/to/test_long_blah_blah.html'); @@ -133,8 +134,10 @@ describe("jsdoc/util/templateHelper", function() { }); }); - xdescribe("scopeToPunc", function() { - // TODO + describe("scopeToPunc", function() { + it("should map 'static' to '.', 'inner', to '~', 'instance' to '#'", function() { + expect(helper.scopeToPunc).toEqual({static: '.', inner: '~', instance: '#'}); + }); }); // disabled because Jasmine appears to execute this code twice, which causes getUniqueFilename @@ -213,8 +216,13 @@ describe("jsdoc/util/templateHelper", function() { }); }); - xdescribe("htmlsafe", function() { - // TODO + describe("htmlsafe", function() { + // turns < into < (doesn't do > or & etc...) + it('should convert all occurences of < to <', function() { + var inp = '

Potentially dangerous.

', + out = helper.htmlsafe(inp); + expect(out).toEqual('<h1>Potentially dangerous.</h1>'); + }); }); describe("find", function() { @@ -346,8 +354,114 @@ describe("jsdoc/util/templateHelper", function() { }); }); - xdescribe("getAttribs", function() { - // TODO + describe("getAttribs", function() { + var doc, attribs; + + it('should return an array of strings', function() { + doc = new doclet.Doclet('/** ljklajsdf */', {}); + attribs = helper.getAttribs(doc); + expect(attribs instanceof Array).toBe(true); + }); + + // tests is an object of test[doclet src] = + // if false, we expect attribs to either not contain anything in whatNotToContain, + // or be empty (if whatNotToContain was not provided). + function doTests(tests, whatNotToContain) { + for (var src in tests) { + if (tests.hasOwnProperty(src)) { + doc = new doclet.Doclet('/** ' + src + ' */', {}); + attribs = helper.getAttribs(doc); + if (tests[src]) { + expect(attribs).toContain(tests[src]); + } else { + if (whatNotToContain !== undefined) { + if (whatNotToContain instanceof Array) { + for (var i = 0; i < whatNotToContain.length; ++i) { + expect(attribs).not.toContain(whatNotToContain[i]); + } + } + } else { + expect(attribs.length).toEqual(0); + } + } + } + } + } + + it('should detect if a doclet is virtual', function() { + var tests = { + 'My constant. \n @virtual': 'virtual', + 'asdf': false + }; + doTests(tests); + }); + + it("should detect if a doclet's access is not public", function() { + var tests = {'@private': 'private', + '@access private': 'private', + '@protected': 'protected', + '@access protected': 'protected', + '@public': false, + '@access public': false, + 'asdf': false + }; + doTests(tests); + }); + + it("should detect if a doclet's scope is inner or static AND it is a function or member or constant", function() { + var tests = { + // by default these are members + '@inner': 'inner', + '@instance': false, + '@global': false, + '@static': 'static', + '@name Asdf.fdsa': 'static', + '@name Outer~inner': 'inner', + '@name Fdsa#asdf': false, + '@name .log': false, + // some tests with functions and constants + '@const Asdf#FOO': false, + '@const Asdf\n@inner': 'inner', + '@function Asdf#myFunction': false, + '@function Fdsa.MyFunction': 'static', + '@function Fdsa': false, + // these are not functions or members or constants, they should not have their scope recorded. + '@namespace Fdsa\n@inner': false, + '@class asdf': false + }; + doTests(tests, ['inner', 'static', 'global', 'instance']); + }); + + it("should detect if a doclet is readonly (and its kind is 'member')", function() { + var tests = { + 'asdf\n @readonly': 'readonly', + 'asdf': false, + '@name Fdsa#foo\n@readonly': 'readonly', + // kind is not 'member'. + '@const asdf\n@readonly': false, + '@function asdf\n@readonly': false, + '@function Asdf#bar\n@readonly': false + }; + doTests(tests, 'readonly'); + }); + + it("should detect if the doclet is a for constant", function() { + var tests = { + 'Enum. @enum\n@constant': 'constant', + '@function Foo#BAR\n@const': 'constant', + '@const Asdf': 'constant' + }; + doTests(tests, 'constant'); + }); + + it("should detect multiple attributes", function() { + var doc = new doclet.Doclet('/** @const module:fdsa~FOO\n@readonly\n@private */', {}); + attribs = helper.getAttribs(doc); + expect(attribs).toContain('private'); + //expect(attribs).toContain('readonly'); // kind is 'constant' not 'member'. + expect(attribs).toContain('constant'); + expect(attribs).toContain('inner'); + }); }); xdescribe("getSignatureTypes", function() { From c3f04020eff8aeb8ad05c92dd16e138b1536308f Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Tue, 12 Feb 2013 13:20:16 +1000 Subject: [PATCH 03/13] templateHelper.js: longnameToUrl, getSignatureParams, getSignatureType tests added --- test/specs/jsdoc/util/templateHelper.js | 112 ++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 190757ed..452e9bf9 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -171,8 +171,24 @@ describe("jsdoc/util/templateHelper", function() { }); }); - xdescribe("longnameToUrl", function() { - // TODO + describe("longnameToUrl", function() { + it("is an object", function() { + expect(typeof helper.longnameToUrl).toBe('object'); + }); + + it("has an entry added into it by calling registerLink", function() { + helper.registerLink('MySymbol', 'asdf.html'); + expect(helper.longnameToUrl.MySymbol).toBeDefined(); + expect(helper.longnameToUrl.MySymbol).toBe('asdf.html'); + + delete helper.longnameToUrl.MySymbol; + }); + + it("adding an entry to it allows me to link with linkto", function() { + helper.longnameToUrl.foo2 = 'bar.html'; + expect(helper.linkto('foo2')).toBe('foo2'); + delete helper.longnameToUrl.foo2; + }); }); describe("linkto", function() { @@ -464,12 +480,96 @@ describe("jsdoc/util/templateHelper", function() { }); }); - xdescribe("getSignatureTypes", function() { - // TODO + describe("getSignatureTypes", function() { + // returns links to allowed types for a doclet. + it("returns an empty array if the doclet has no specified type", function() { + var doc = new doclet.Doclet('/** @const ASDF */', {}), + types = helper.getSignatureTypes(doc); + + expect(types instanceof Array).toBe(true); + expect(types.length).toBe(0); + }); + + it("returns a string array of the doclet's types", function() { + var doc = new doclet.Doclet('/** @const {number|Array.} ASDF */', {}), + types = helper.getSignatureTypes(doc); + + expect(types.length).toBe(2); + expect(types).toContain('number'); + expect(types).toContain(helper.htmlsafe('Array.')); // should be HTML safe + }); + + it("creates links for types if relevant", function() { + // make some links. + helper.longnameToUrl.MyClass = 'MyClass.html'; + + var doc = new doclet.Doclet('/** @const {MyClass} ASDF */', {}), + types = helper.getSignatureTypes(doc); + expect(types.length).toBe(1); + expect(types).toContain('MyClass'); + + delete helper.longnameToUrl.MyClass; + }); + + it("uses the cssClass parameter for links if it is provided", function() { + // make some links. + helper.longnameToUrl.MyClass = 'MyClass.html'; + + var doc = new doclet.Doclet('/** @const {MyClass} ASDF */', {}), + types = helper.getSignatureTypes(doc, 'myCSSClass'); + expect(types.length).toBe(1); + expect(types).toContain('MyClass'); + + delete helper.longnameToUrl.MyClass; + }); }); - xdescribe("getSignatureParams", function() { - // TODO + describe("getSignatureParams", function() { + // retrieves parameter names. + // if css class is provided, optional parameters are wrapped in a with that class. + it("returns an empty array if the doclet has no specified type", function() { + var doc = new doclet.Doclet('/** @function myFunction */', {}), + params = helper.getSignatureParams(doc); + expect(params instanceof Array).toBe(true); + expect(params.length).toBe(0); + }); + + it("returns a string array of the doclet's parameter names", function() { + var doc = new doclet.Doclet('/** @function myFunction\n @param {string} foo - asdf. */', {}), + params = helper.getSignatureParams(doc); + expect(params.length).toBe(1); + expect(params).toContain('foo'); + }); + + it("wraps optional parameters in if optClass is provided", function() { + var doc = new doclet.Doclet( + '/** @function myFunction\n' + + ' * @param {boolean} foo - explanation.\n' + + ' * @param {number} [bar=1] - another explanation.\n' + + ' * @param {string} [baz] - another explanation.\n' + + ' */', {}), + params = helper.getSignatureParams(doc, 'cssClass'); + + expect(params.length).toBe(3); + expect(params).toContain('foo'); + expect(params).toContain('bar'); + expect(params).toContain('baz'); + }); + + it("doesn't wrap optional parameters in if optClass is not provided", function() { + var doc = new doclet.Doclet( + '/** @function myFunction\n' + + ' * @param {boolean} foo - explanation.\n' + + ' * @param {number} [bar=1] - another explanation.\n' + + ' * @param {string} [baz] - another explanation.\n' + + ' */', {}), + params = helper.getSignatureParams(doc); + + expect(params.length).toBe(3); + expect(params).toContain('foo'); + expect(params).toContain('bar'); + expect(params).toContain('baz'); + }); }); describe("getSignatureReturns", function() { From 9183a90aa5110fcece13c6f4c5be0b83d90fa650 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Tue, 12 Feb 2013 16:40:48 +1000 Subject: [PATCH 04/13] jsdoc/util/templateHelper: added getSignatureReturns, registerLink, resolveAuthorLinks, getAncestorLinks tests --- test/specs/jsdoc/util/templateHelper.js | 154 +++++++++++++++++++++++- 1 file changed, 150 insertions(+), 4 deletions(-) diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 452e9bf9..667cf606 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -112,6 +112,11 @@ describe("jsdoc/util/templateHelper", function() { expect(typeof helper.resolveLinks).toEqual("function"); }); + it("should export a 'resolveAuthorLinks' function", function() { + expect(helper.resolveAuthorLinks).toBeDefined(); + expect(typeof helper.resolveAuthorLinks).toEqual("function"); + }); + it("should export a 'createLink' function", function() { expect(helper.createLink).toBeDefined(); expect(typeof helper.createLink).toEqual("function"); @@ -573,7 +578,7 @@ describe("jsdoc/util/templateHelper", function() { }); describe("getSignatureReturns", function() { - // TODO: more tests + // retrieves links to types that the member can return. it("returns a value with correctly escaped HTML", function() { var mockDoclet = { @@ -592,10 +597,115 @@ describe("jsdoc/util/templateHelper", function() { expect( html.indexOf('Array.') ).toEqual(-1); expect( html.indexOf('Array.<string>') ).toBeGreaterThan(-1); }); + + it("returns an empty array if the doclet has no returns", function() { + var doc = new doclet.Doclet('/** @function myFunction */', {}), + returns = helper.getSignatureReturns(doc); + + expect(returns instanceof Array).toBe(true); + expect(returns.length).toBe(0); + }); + + it("returns an empty array if the doclet has @returns but with no type", function() { + var doc = new doclet.Doclet('/** @function myFunction\n@returns an interesting result.*/', {}), + returns = helper.getSignatureReturns(doc); + + expect(returns instanceof Array).toBe(true); + expect(returns.length).toBe(0); + }); + + it("creates links for return types if relevant", function() { + // make some links. + helper.longnameToUrl.MyClass = 'MyClass.html'; + + var doc = new doclet.Doclet('/** @function myFunction\n@returns {number|MyClass} an interesting result.*/', {}), + returns = helper.getSignatureReturns(doc); + + expect(returns.length).toBe(2); + expect(returns).toContain('MyClass'); + expect(returns).toContain('number'); + + delete helper.longnameToUrl.MyClass; + }); + + it("uses the cssClass parameter for links if it is provided", function() { + // make some links. + helper.longnameToUrl.MyClass = 'MyClass.html'; + + var doc = new doclet.Doclet('/** @function myFunction\n@returns {number|MyClass} an interesting result.*/', {}), + returns = helper.getSignatureReturns(doc, 'myCssClass'); + + expect(returns.length).toBe(2); + expect(returns).toContain('MyClass'); + expect(returns).toContain('number'); + + delete helper.longnameToUrl.MyClass; + }); }); - xdescribe("getAncestorLinks", function() { - // TODO + describe("getAncestorLinks", function() { + // make a hierarchy. + var lackeys = new doclet.Doclet('/** @member lackeys\n@memberof module:mafia/gangs.Sharks~Henchman\n@instance*/', {}), + henchman = new doclet.Doclet('/** @class Henchman\n@memberof module:mafia/gangs.Sharks\n@inner */', {}), + gang = new doclet.Doclet('/** @namespace module:mafia/gangs.Sharks */', {}), + mafia = new doclet.Doclet('/** @module mafia/gangs */', {}), + data = require('taffydb').taffy([lackeys, henchman, gang, mafia]); + + // register some links + it("returns an empty array if there are no ancestors", function() { + var links = helper.getAncestorLinks(data, mafia); + expect(links instanceof Array).toBe(true); + expect(links.length).toBe(0); + }); + + it("returns an array of ancestor names (with preceding punctuation) if there are ancestors, the direct ancestor with following punctuation too", function() { + var links = helper.getAncestorLinks(data, lackeys); + expect(links.length).toBe(3); + expect(links).toContain('~Henchman#'); + expect(links).toContain('.Sharks'); + expect(links).toContain('mafia/gangs'); + + links = helper.getAncestorLinks(data, henchman); + expect(links.length).toBe(2); + expect(links).toContain('.Sharks~'); + expect(links).toContain('mafia/gangs'); + + links = helper.getAncestorLinks(data, gang); + expect(links.length).toBe(1); + expect(links).toContain('mafia/gangs.'); + }); + + it("adds links if they exist", function() { + // register some links + helper.longnameToUrl['module:mafia/gangs'] = 'mafia_gangs.html'; + helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman'] = 'henchman.html'; + + var links = helper.getAncestorLinks(data, lackeys); + expect(links.length).toBe(3); + // BUG: the link text is ~Henchman and there is a '#' on the end. + // should probably have link text ~Henchman#. + //expect(links).toContain('~Henchman#'); + expect(links).toContain('.Sharks'); + expect(links).toContain('mafia/gangs'); + + delete helper.longnameToUrl['module:mafia/gangs']; + delete helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman']; + }); + + it("adds cssClass to any link", function() { + // register some links + helper.longnameToUrl['module:mafia/gangs'] = 'mafia_gangs.html'; + helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman'] = 'henchman.html'; + + var links = helper.getAncestorLinks(data, lackeys, 'myClass'); + expect(links.length).toBe(3); + //expect(links).toContain('~Henchman#'); + expect(links).toContain('.Sharks'); + expect(links).toContain('mafia/gangs'); + + delete helper.longnameToUrl['module:mafia/gangs']; + delete helper.longnameToUrl['module:mafia/gangs.Sharks~Henchman']; + }); }); describe("prune", function() { @@ -649,7 +759,22 @@ describe("jsdoc/util/templateHelper", function() { }); xdescribe("registerLink", function() { - // TODO + it("adds an entry to exports.longnameToUrl", function() { + helper.longnameToUrl.MySymbol = 'asdf.html'; + + expect(helper.longnameToUrl.MySymbol).toBeDefined(); + expect(helper.longnameToUrl.MySymbol).toBe('asdf.html'); + + delete helper.longnameToUrl.MySymbol; + }); + + it("allows linkto to work", function() { + helper.registerLink('MySymbol', 'asdf.html'); + + expect(helper.linkto('MySymbol')).toBe('MySymbol'); + + delete helper.longnameToUrl.MySymbol; + }); }); describe("tutorialToUrl", function() { @@ -969,4 +1094,25 @@ describe("jsdoc/util/templateHelper", function() { expect(url).toEqual('be9d9563a3.html#"*foo"'); }); }); + + describe("resolveAuthorLinks", function() { + // convert Jane Doe to a mailto link. + it('should convert email addresses in angle brackets *after* a name to mailto links', function() { + var str = ' John Doe ', + out = helper.resolveAuthorLinks(str); + expect(out).toBe('John Doe'); + }); + + it('should HTML-safe author names', function() { + var str = ' John ', + out = helper.resolveAuthorLinks(str); + expect(out).toBe('' + helper.htmlsafe('John'); + }); + + it('should simply return the input string, HTML-safe, if no email is detected', function() { + var str = 'John Doe ', + out = helper.resolveAuthorLinks(str); + expect(out).toBe(helper.htmlsafe(str)); + }); + }); }); From dad08be08a3cc92df3a73f58959c8847b7733a6c Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Tue, 12 Feb 2013 16:51:35 +1000 Subject: [PATCH 05/13] FEATURE/FIX: jsdoc/util/templateHelper.getAncestorLinks: direct parents punctuation should be part of the link text. Parent~ vs Parent~ --- lib/jsdoc/util/templateHelper.js | 7 +++++-- test/specs/jsdoc/util/templateHelper.js | 6 ++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/jsdoc/util/templateHelper.js b/lib/jsdoc/util/templateHelper.js index 94867bc4..e52ea89c 100644 --- a/lib/jsdoc/util/templateHelper.js +++ b/lib/jsdoc/util/templateHelper.js @@ -280,18 +280,21 @@ exports.getSignatureReturns = function(d, cssClass) { */ exports.getAncestorLinks = function(data, doclet, cssClass) { var ancestors = [], - doc = doclet.memberof; + doc = doclet.memberof, + directParent = false; while (doc) { doc = find( data, {longname: doc}, false ); if (doc) { doc = doc[0]; } if (!doc) { break; } + if (!directParent) { directParent = doc; } ancestors.unshift( linkto(doc.longname, (exports.scopeToPunc[doc.scope] || '') + doc.name, cssClass) ); doc = doc.memberof; } if (ancestors.length) { - ancestors[ancestors.length - 1] += (exports.scopeToPunc[doclet.scope] || ''); + var last = ancestors[ancestors.length - 1]; + ancestors[ancestors.length - 1] = last.replace(directParent.name, directParent.name + (exports.scopeToPunc[doclet.scope] || '')); } return ancestors; }; diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 667cf606..6718a820 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -682,9 +682,7 @@ describe("jsdoc/util/templateHelper", function() { var links = helper.getAncestorLinks(data, lackeys); expect(links.length).toBe(3); - // BUG: the link text is ~Henchman and there is a '#' on the end. - // should probably have link text ~Henchman#. - //expect(links).toContain('~Henchman#'); + expect(links).toContain('~Henchman#'); expect(links).toContain('.Sharks'); expect(links).toContain('mafia/gangs'); @@ -699,7 +697,7 @@ describe("jsdoc/util/templateHelper", function() { var links = helper.getAncestorLinks(data, lackeys, 'myClass'); expect(links.length).toBe(3); - //expect(links).toContain('~Henchman#'); + expect(links).toContain('~Henchman#'); expect(links).toContain('.Sharks'); expect(links).toContain('mafia/gangs'); From c37e8012913185263db330d528e35679bac4e286 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Thu, 14 Feb 2013 15:41:57 +1000 Subject: [PATCH 06/13] BUGFIX: linkto and toLink should use hasOwnProp to avoid errors from linking to reserved keywords, e.g. {@link constructor} or linkto('constructor') --- lib/jsdoc/util/templateHelper.js | 4 ++-- test/specs/jsdoc/util/templateHelper.js | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/jsdoc/util/templateHelper.js b/lib/jsdoc/util/templateHelper.js index e52ea89c..c9417064 100644 --- a/lib/jsdoc/util/templateHelper.js +++ b/lib/jsdoc/util/templateHelper.js @@ -98,7 +98,7 @@ var longnameToUrl = exports.longnameToUrl = linkMap.longnameToUrl; var linkto = exports.linkto = function(longname, linktext, cssClass) { var classString = cssClass ? util.format(' class="%s"', cssClass) : ''; var text = linktext || longname; - var url = longnameToUrl[longname]; + var url = hasOwnProp.call(longnameToUrl, longname) && longnameToUrl[longname]; if (!url) { return text; @@ -356,7 +356,7 @@ function toLink(longname, content, monospace) { } else { // the actual longname is stored in `url` if there was a delimiter. - url = linkMap.longnameToUrl[longname]; + url = hasOwnProp.call(linkMap.longnameToUrl, longname) && linkMap.longnameToUrl[longname]; } content = content || longname; diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 6718a820..f33f635e 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -235,6 +235,13 @@ describe("jsdoc/util/templateHelper", function() { var link = helper.linkto('linktoTest', 'link text', 'myclass'); expect(link).toEqual('link text'); }); + + it("is careful with longnames that are reserved words in JS", function() { + // we don't have a registered link for 'constructor' so it should return the text 'link text'. + var link = helper.linkto('constructor', 'link text'); + expect(typeof link).toBe('string'); + expect(link).toBe('link text'); + }); }); describe("htmlsafe", function() { @@ -952,6 +959,12 @@ describe("jsdoc/util/templateHelper", function() { expect(output).toEqual('Link to test'); }); + it('should be careful with linking to links whose names are reserved JS keywords', function() { + var input = 'Link to {@link constructor}', + output = helper.resolveLinks(input); + expect(output).toBe('Link to constructor'); + }); + // conf.monospaceLinks. check that // a) it works it('if conf.monospaceLinks is true, all {@link} should be monospace', function () { From 338e129edc1db384e0d378ea2d05c83c8fa030ce Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Thu, 14 Feb 2013 15:44:33 +1000 Subject: [PATCH 07/13] test improvements: toEquals vs toBe, instanceof Array vs Array.isArray, .indexOf(X).not.toEqual(-1) vs .contains(X) --- test/specs/jsdoc/util/templateHelper.js | 146 ++++++++++++------------ 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index f33f635e..4ac12483 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -9,117 +9,117 @@ describe("jsdoc/util/templateHelper", function() { it("should exist", function() { expect(helper).toBeDefined(); - expect(typeof helper).toEqual('object'); + expect(typeof helper).toBe('object'); }); it("should export a 'setTutorials' function", function() { expect(helper.setTutorials).toBeDefined(); - expect(typeof helper.setTutorials).toEqual("function"); + expect(typeof helper.setTutorials).toBe("function"); }); it("should export a 'globalName' property", function() { expect(helper.globalName).toBeDefined(); - expect(typeof helper.globalName).toEqual("string"); + expect(typeof helper.globalName).toBe("string"); }); it("should export a 'fileExtension' property", function() { expect(helper.fileExtension).toBeDefined(); - expect(typeof helper.fileExtension).toEqual("string"); + expect(typeof helper.fileExtension).toBe("string"); }); it("should export a 'scopeToPunc' property", function() { expect(helper.scopeToPunc).toBeDefined(); - expect(typeof helper.scopeToPunc).toEqual("object"); + expect(typeof helper.scopeToPunc).toBe("object"); }); it("should export a 'getUniqueFilename' function", function() { expect(helper.getUniqueFilename).toBeDefined(); - expect(typeof helper.getUniqueFilename).toEqual("function"); + expect(typeof helper.getUniqueFilename).toBe("function"); }); it("should export a 'longnameToUrl' property", function() { expect(helper.longnameToUrl).toBeDefined(); - expect(typeof helper.longnameToUrl).toEqual("object"); + expect(typeof helper.longnameToUrl).toBe("object"); }); it("should export a 'linkto' function", function() { expect(helper.linkto).toBeDefined(); - expect(typeof helper.linkto).toEqual("function"); + expect(typeof helper.linkto).toBe("function"); }); it("should export an 'htmlsafe' function", function() { expect(helper.htmlsafe).toBeDefined(); - expect(typeof helper.htmlsafe).toEqual("function"); + expect(typeof helper.htmlsafe).toBe("function"); }); it("should export a 'find' function", function() { expect(helper.find).toBeDefined(); - expect(typeof helper.find).toEqual("function"); + expect(typeof helper.find).toBe("function"); }); it("should export a 'getMembers' function", function() { expect(helper.getMembers).toBeDefined(); - expect(typeof helper.getMembers).toEqual("function"); + expect(typeof helper.getMembers).toBe("function"); }); it("should export a 'getAttribs' function", function() { expect(helper.getAttribs).toBeDefined(); - expect(typeof helper.getAttribs).toEqual("function"); + expect(typeof helper.getAttribs).toBe("function"); }); it("should export a 'getSignatureTypes' function", function() { expect(helper.getSignatureTypes).toBeDefined(); - expect(typeof helper.getSignatureTypes).toEqual("function"); + expect(typeof helper.getSignatureTypes).toBe("function"); }); it("should export a 'getSignatureParams' function", function() { expect(helper.getSignatureParams).toBeDefined(); - expect(typeof helper.getSignatureParams).toEqual("function"); + expect(typeof helper.getSignatureParams).toBe("function"); }); it("should export a 'getSignatureReturns' function", function() { expect(helper.getSignatureReturns).toBeDefined(); - expect(typeof helper.getSignatureReturns).toEqual("function"); + expect(typeof helper.getSignatureReturns).toBe("function"); }); it("should export a 'getAncestorLinks' function", function() { expect(helper.getAncestorLinks).toBeDefined(); - expect(typeof helper.getAncestorLinks).toEqual("function"); + expect(typeof helper.getAncestorLinks).toBe("function"); }); it("should export a 'prune' function", function() { expect(helper.prune).toBeDefined(); - expect(typeof helper.prune).toEqual("function"); + expect(typeof helper.prune).toBe("function"); }); it("should export a 'registerLink' function", function() { expect(helper.registerLink).toBeDefined(); - expect(typeof helper.registerLink).toEqual("function"); + expect(typeof helper.registerLink).toBe("function"); }); it("should export a 'tutorialToUrl' function", function() { expect(helper.tutorialToUrl).toBeDefined(); - expect(typeof helper.tutorialToUrl).toEqual("function"); + expect(typeof helper.tutorialToUrl).toBe("function"); }); it("should export a 'toTutorial' function", function() { expect(helper.toTutorial).toBeDefined(); - expect(typeof helper.toTutorial).toEqual("function"); + expect(typeof helper.toTutorial).toBe("function"); }); it("should export a 'resolveLinks' function", function() { expect(helper.resolveLinks).toBeDefined(); - expect(typeof helper.resolveLinks).toEqual("function"); + expect(typeof helper.resolveLinks).toBe("function"); }); it("should export a 'resolveAuthorLinks' function", function() { expect(helper.resolveAuthorLinks).toBeDefined(); - expect(typeof helper.resolveAuthorLinks).toEqual("function"); + expect(typeof helper.resolveAuthorLinks).toBe("function"); }); it("should export a 'createLink' function", function() { expect(helper.createLink).toBeDefined(); - expect(typeof helper.createLink).toEqual("function"); + expect(typeof helper.createLink).toBe("function"); }); @@ -129,13 +129,13 @@ describe("jsdoc/util/templateHelper", function() { describe("globalName", function() { it("should equal 'global'", function() { - expect(helper.globalName).toEqual('global'); + expect(helper.globalName).toBe('global'); }); }); describe("fileExtension", function() { it("should equal '.html'", function() { - expect(helper.fileExtension).toEqual('.html'); + expect(helper.fileExtension).toBe('.html'); }); }); @@ -150,7 +150,7 @@ describe("jsdoc/util/templateHelper", function() { xdescribe("getUniqueFilename", function() { it('should convert a simple string into the string plus the default extension', function() { var filename = helper.getUniqueFilename('BackusNaur'); - expect(filename).toEqual('BackusNaur.html'); + expect(filename).toBe('BackusNaur.html'); }); it('should convert a string with slashes into an alphanumeric hash plus the default extension', function() { @@ -163,7 +163,7 @@ describe("jsdoc/util/templateHelper", function() { var filename1 = helper.getUniqueFilename(name); var filename2 = helper.getUniqueFilename(name); - expect(filename1).not.toEqual(filename2); + expect(filename1).not.toBe(filename2); }); it('should not consider the same name with different letter case to be unique', function() { @@ -172,7 +172,7 @@ describe("jsdoc/util/templateHelper", function() { var filename1 = helper.getUniqueFilename(camel); var filename2 = helper.getUniqueFilename(pascal); - expect( filename1.toLowerCase() ).not.toEqual( filename2.toLowerCase() ); + expect( filename1.toLowerCase() ).not.toBe( filename2.toLowerCase() ); }); }); @@ -207,33 +207,33 @@ describe("jsdoc/util/templateHelper", function() { it('returns the longname if only the longname is specified and has no URL', function() { var link = helper.linkto('example'); - expect(link).toEqual('example'); + expect(link).toBe('example'); }); it('returns the link text if only the link text is specified', function() { var link = helper.linkto(null, 'link text'); - expect(link).toEqual('link text'); + expect(link).toBe('link text'); }); it('returns the link text if the longname does not have a URL, and both the longname and ' + 'link text are specified', function() { var link = helper.linkto('example', 'link text'); - expect(link).toEqual('link text'); + expect(link).toBe('link text'); }); it('uses the longname as the link text if no link text is provided', function() { var link = helper.linkto('linktoTest'); - expect(link).toEqual('linktoTest'); + expect(link).toBe('linktoTest'); }); it('uses the link text if it is specified', function() { var link = helper.linkto('linktoTest', 'link text'); - expect(link).toEqual('link text'); + expect(link).toBe('link text'); }); it('includes a "class" attribute in the link if a class is specified', function() { var link = helper.linkto('linktoTest', 'link text', 'myclass'); - expect(link).toEqual('link text'); + expect(link).toBe('link text'); }); it("is careful with longnames that are reserved words in JS", function() { @@ -249,7 +249,7 @@ describe("jsdoc/util/templateHelper", function() { it('should convert all occurences of < to <', function() { var inp = '

Potentially dangerous.

', out = helper.htmlsafe(inp); - expect(out).toEqual('<h1>Potentially dangerous.</h1>'); + expect(out).toBe('<h1>Potentially dangerous.</h1>'); }); }); @@ -388,7 +388,7 @@ describe("jsdoc/util/templateHelper", function() { it('should return an array of strings', function() { doc = new doclet.Doclet('/** ljklajsdf */', {}); attribs = helper.getAttribs(doc); - expect(attribs instanceof Array).toBe(true); + expect(Array.isArray(attribs)).toBe(true); }); // tests is an object of test[doclet src] = @@ -403,13 +403,13 @@ describe("jsdoc/util/templateHelper", function() { expect(attribs).toContain(tests[src]); } else { if (whatNotToContain !== undefined) { - if (whatNotToContain instanceof Array) { + if (Array.isArray(whatNotToContain)) { for (var i = 0; i < whatNotToContain.length; ++i) { expect(attribs).not.toContain(whatNotToContain[i]); } } } else { - expect(attribs.length).toEqual(0); + expect(attribs.length).toBe(0); } } } @@ -498,7 +498,7 @@ describe("jsdoc/util/templateHelper", function() { var doc = new doclet.Doclet('/** @const ASDF */', {}), types = helper.getSignatureTypes(doc); - expect(types instanceof Array).toBe(true); + expect(Array.isArray(types)).toBe(true); expect(types.length).toBe(0); }); @@ -542,7 +542,7 @@ describe("jsdoc/util/templateHelper", function() { it("returns an empty array if the doclet has no specified type", function() { var doc = new doclet.Doclet('/** @function myFunction */', {}), params = helper.getSignatureParams(doc); - expect(params instanceof Array).toBe(true); + expect(Array.isArray(params)).toBe(true); expect(params.length).toBe(0); }); @@ -601,15 +601,15 @@ describe("jsdoc/util/templateHelper", function() { }; var html = helper.getSignatureReturns(mockDoclet); - expect( html.indexOf('Array.') ).toEqual(-1); - expect( html.indexOf('Array.<string>') ).toBeGreaterThan(-1); + expect(html).not.toContain('Array.'); + expect(html).toContain('Array.<string>'); }); it("returns an empty array if the doclet has no returns", function() { var doc = new doclet.Doclet('/** @function myFunction */', {}), returns = helper.getSignatureReturns(doc); - expect(returns instanceof Array).toBe(true); + expect(Array.isArray(returns)).toBe(true); expect(returns.length).toBe(0); }); @@ -617,7 +617,7 @@ describe("jsdoc/util/templateHelper", function() { var doc = new doclet.Doclet('/** @function myFunction\n@returns an interesting result.*/', {}), returns = helper.getSignatureReturns(doc); - expect(returns instanceof Array).toBe(true); + expect(Array.isArray(returns)).toBe(true); expect(returns.length).toBe(0); }); @@ -661,7 +661,7 @@ describe("jsdoc/util/templateHelper", function() { // register some links it("returns an empty array if there are no ancestors", function() { var links = helper.getAncestorLinks(data, mafia); - expect(links instanceof Array).toBe(true); + expect(Array.isArray(links)).toBe(true); expect(links.length).toBe(0); }); @@ -874,89 +874,89 @@ describe("jsdoc/util/templateHelper", function() { var input = 'This is a {@link test}.', output = helper.resolveLinks(input); - expect(output).toEqual('This is a test.'); + expect(output).toBe('This is a test.'); }); it('should translate {@link unknown} into a simple text.', function() { var input = 'This is a {@link unknown}.', output = helper.resolveLinks(input); - expect(output).toEqual('This is a unknown.'); + expect(output).toBe('This is a unknown.'); }); it('should translate {@link test} into a HTML links multiple times.', function() { var input = 'This is a {@link test} and {@link test}.', output = helper.resolveLinks(input); - expect(output).toEqual('This is a test and test.'); + expect(output).toBe('This is a test and test.'); }); it('should translate [hello there]{@link test} into a HTML link with the custom content.', function() { var input = 'This is a [hello there]{@link test}.', output = helper.resolveLinks(input); - expect(output).toEqual('This is a hello there.'); + expect(output).toBe('This is a hello there.'); }); it('should ignore [hello there].', function() { var input = 'This is a [hello there].', output = helper.resolveLinks(input); - expect(output).toEqual(input); + expect(output).toBe(input); }); it('should translate http links in the tag', function() { var input = 'Link to {@link http://github.com}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to http://github.com'); + expect(output).toBe('Link to http://github.com'); }); it('should translate ftp links in the tag', function() { var input = 'Link to {@link ftp://foo.bar}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to ftp://foo.bar'); + expect(output).toBe('Link to ftp://foo.bar'); }); it('should allow pipe to be used as delimiter between href and text (external link)', function() { var input = 'Link to {@link http://github.com|Github}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to Github'); + expect(output).toBe('Link to Github'); }); it('should allow pipe to be used as delimiter between href and text (symbol link)', function() { var input = 'Link to {@link test|Test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to Test'); + expect(output).toBe('Link to Test'); }); it('should allow first space to be used as delimiter between href and text (external link)', function() { var input = 'Link to {@link http://github.com Github}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to Github'); + expect(output).toBe('Link to Github'); }); it('should allow first space to be used as delimiter between href and text (symbol link)', function() { var input = 'Link to {@link test My Caption}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to My Caption'); + expect(output).toBe('Link to My Caption'); }); it('if pipe and space are present in link tag, use pipe as the delimiter', function() { var input = 'Link to {@link test|My Caption}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to My Caption'); + expect(output).toBe('Link to My Caption'); }); it('Test of {@linkcode } which should be in monospace', function() { var input = 'Link to {@linkcode test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); }); it('Test of {@linkplain } which should be in normal font', function() { var input = 'Link to {@linkplain test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); }); it('should be careful with linking to links whose names are reserved JS keywords', function() { @@ -971,7 +971,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({monospaceLinks: true}); var input = 'Link to {@link test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); restoreConfTemplates(storage); }); @@ -980,7 +980,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({monospaceLinks: true}); var input = 'Link to {@linkcode test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); restoreConfTemplates(storage); }); @@ -988,7 +988,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({monospaceLinks: true}); var input = 'Link to {@linkplain test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); restoreConfTemplates(storage); }); @@ -998,7 +998,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({cleverLinks: true}); var input = 'Link to {@link test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); restoreConfTemplates(storage); }); @@ -1006,7 +1006,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({cleverLinks: true}); var input = 'Link to {@link http://github.com}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to http://github.com'); + expect(output).toBe('Link to http://github.com'); restoreConfTemplates(storage); }); @@ -1015,7 +1015,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({cleverLinks: true}); var input = 'Link to {@linkcode test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); restoreConfTemplates(storage); }); @@ -1023,7 +1023,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({cleverLinks: true}); var input = 'Link to {@linkplain test}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test'); + expect(output).toBe('Link to test'); restoreConfTemplates(storage); }); @@ -1033,7 +1033,7 @@ describe("jsdoc/util/templateHelper", function() { var storage = setConfTemplatesVariables({cleverLinks: true, monospaceLinks: true}); var input = 'Link to {@link test} and {@link http://github.com}', output = helper.resolveLinks(input); - expect(output).toEqual('Link to test and http://github.com'); + expect(output).toBe('Link to test and http://github.com'); restoreConfTemplates(storage); }); @@ -1048,7 +1048,7 @@ describe("jsdoc/util/templateHelper", function() { }, url = helper.createLink(mockDoclet); - expect(url).toEqual('global.html#foo'); + expect(url).toBe('global.html#foo'); }); it('should create a url for a namespace.', function() { @@ -1059,7 +1059,7 @@ describe("jsdoc/util/templateHelper", function() { }, url = helper.createLink(mockDoclet); - expect(url).toEqual('foo.html'); + expect(url).toBe('foo.html'); }); it('should create a url for a member of a namespace.', function() { @@ -1071,7 +1071,7 @@ describe("jsdoc/util/templateHelper", function() { }, url = helper.createLink(mockDoclet); - expect(url).toEqual('ns.html#foo'); + expect(url).toBe('ns.html#foo'); }); var nestedNamespaceDoclet = { @@ -1085,12 +1085,12 @@ describe("jsdoc/util/templateHelper", function() { it('should create a url for a member of a nested namespace.', function() { nestedNamespaceUrl = helper.createLink(nestedNamespaceDoclet); - expect(nestedNamespaceUrl).toEqual('ns1.ns2.html#foo'); + expect(nestedNamespaceUrl).toBe('ns1.ns2.html#foo'); }); it('should return the same value when called twice with the same doclet.', function() { var newUrl = helper.createLink(nestedNamespaceDoclet); - expect(newUrl).toEqual(nestedNamespaceUrl); + expect(newUrl).toBe(nestedNamespaceUrl); }); it('should create a url for a name with invalid characters using a digest.', function() { @@ -1102,7 +1102,7 @@ describe("jsdoc/util/templateHelper", function() { }, url = helper.createLink(mockDoclet); - expect(url).toEqual('be9d9563a3.html#"*foo"'); + expect(url).toBe('be9d9563a3.html#"*foo"'); }); }); From 096f1dd9d1e091a61f5878bc0f1c22a195de64de Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Thu, 14 Feb 2013 16:48:49 +1000 Subject: [PATCH 08/13] BUGFIX (tutorial/resolver, util/templateHelper): be careful when tutorial names are reserved JS keywords (e.g. 'constructor')) --- lib/jsdoc/tutorial/resolver.js | 7 +- lib/jsdoc/util/templateHelper.js | 2 +- test/specs/jsdoc/tutorial/resolver.js | 105 ++++++++++++++---------- test/specs/jsdoc/util/templateHelper.js | 37 ++++++++- 4 files changed, 100 insertions(+), 51 deletions(-) diff --git a/lib/jsdoc/tutorial/resolver.js b/lib/jsdoc/tutorial/resolver.js index 0a54bbb2..8684a5a5 100644 --- a/lib/jsdoc/tutorial/resolver.js +++ b/lib/jsdoc/tutorial/resolver.js @@ -97,7 +97,7 @@ exports.root = new tutorial.Tutorial('', ''); @return {tutorial.Tutorial} Tutorial instance. */ exports.root.getByName = function(name) { - return tutorials[name]; + return hasOwnProp.call(tutorials, name) && tutorials[name]; }; /** Load tutorials from given path. @@ -159,10 +159,11 @@ exports.load = function(_path) { exports.resolve = function() { var item, current; + //console.log(tutorials); for (var name in conf) { if ( hasOwnProp.call(conf, name) ) { // TODO: should we complain about this? - if (!(name in tutorials)) { + if (!hasOwnProp.call(tutorials, name)) { continue; } @@ -177,7 +178,7 @@ exports.resolve = function() { // add children if (item.children) { item.children.forEach(function(child) { - if (!(child in tutorials)) { + if (!hasOwnProp.call(tutorials, child)) { error.handle( new Error("Missing child tutorial: " + child) ); } else { diff --git a/lib/jsdoc/util/templateHelper.js b/lib/jsdoc/util/templateHelper.js index c9417064..c54b80ec 100644 --- a/lib/jsdoc/util/templateHelper.js +++ b/lib/jsdoc/util/templateHelper.js @@ -393,7 +393,7 @@ var tutorialToUrl = exports.tutorialToUrl = function(tutorial) { var url; // define the URL if necessary - if (!tutorialLinkMap.nameToUrl[node.name]) { + if (!hasOwnProp.call(tutorialLinkMap.nameToUrl, node.name)) { url = 'tutorial-' + getUniqueFilename(node.name); tutorialLinkMap.nameToUrl[node.name] = url; tutorialLinkMap.urlToName[url] = node.name; diff --git a/test/specs/jsdoc/tutorial/resolver.js b/test/specs/jsdoc/tutorial/resolver.js index 5d1260b0..5a4eef13 100644 --- a/test/specs/jsdoc/tutorial/resolver.js +++ b/test/specs/jsdoc/tutorial/resolver.js @@ -8,32 +8,32 @@ describe("jsdoc/tutorial/resolver", function() { /*jshint evil: true */ it("should exist", function() { expect(resolver).toBeDefined(); - expect(typeof resolver).toEqual('object'); + expect(typeof resolver).toBe('object'); }); it("should export a 'addTutorial' function", function() { expect(resolver.addTutorial).toBeDefined(); - expect(typeof resolver.addTutorial).toEqual("function"); + expect(typeof resolver.addTutorial).toBe("function"); }); it("should export a 'load' function", function() { expect(resolver.load).toBeDefined(); - expect(typeof resolver.load).toEqual("function"); + expect(typeof resolver.load).toBe("function"); }); it("should export a 'resolve' function", function() { expect(resolver.resolve).toBeDefined(); - expect(typeof resolver.resolve).toEqual("function"); + expect(typeof resolver.resolve).toBe("function"); }); it("should export a 'root' tutorial", function() { expect(resolver.root).toBeDefined(); - expect(resolver.root instanceof tutorial.Tutorial).toEqual(true); + expect(resolver.root instanceof tutorial.Tutorial).toBe(true); }); it("exported 'root' tutorial should export a 'getByName' function", function() { expect(resolver.root.getByName).toBeDefined(); - expect(typeof resolver.root.getByName).toEqual("function"); + expect(typeof resolver.root.getByName).toBe("function"); }); // note: every time we addTutorial or run the resolver, we are *adding* @@ -45,18 +45,26 @@ describe("jsdoc/tutorial/resolver", function() { describe("addTutorial", function() { it("should add a default parent of the root tutorial", function() { - expect(tute.parent).toEqual(resolver.root); + expect(tute.parent).toBe(resolver.root); }); it("should be added to the root tutorial as a child", function() { - expect(resolver.root.children[0]).toEqual(tute); + expect(resolver.root.children).toContain(tute); }); }); // root.getByName describe("root.getByName", function() { it("can retrieve tutorials by name", function() { - expect(resolver.root.getByName('myTutorial')).toEqual(tute); + expect(resolver.root.getByName('myTutorial')).toBe(tute); + }); + + it("returns nothing for non-existent tutorials", function() { + expect(resolver.root.getByName('asdf')).toBeFalsy(); + }); + + it("is careful with tutorials whose names are reserved keywords in JS", function() { + expect(resolver.root.getByName('prototype')).toBeFalsy(); }); }); @@ -66,8 +74,9 @@ describe("jsdoc/tutorial/resolver", function() { test = resolver.root.getByName('test'), test2 = resolver.root.getByName('test2'), test3 = resolver.root.getByName('test3'), - test4 = resolver.root.getByName('test4'); - test6 = resolver.root.getByName('test6'); + test4 = resolver.root.getByName('test4'), + test6 = resolver.root.getByName('test6'), + constr = resolver.root.getByName('constructor'); describe("load", function() { @@ -78,33 +87,39 @@ describe("jsdoc/tutorial/resolver", function() { expect(test3).toBeDefined(); expect(test4).toBeDefined(); expect(test6).toBeDefined(); + expect(constr).toBeDefined(); // check they are top-level in resolver.root - expect(childNames.indexOf('test')).not.toEqual(-1); - expect(childNames.indexOf('test2')).not.toEqual(-1); - expect(childNames.indexOf('test3')).not.toEqual(-1); - expect(childNames.indexOf('test4')).not.toEqual(-1); - expect(childNames.indexOf('test6')).not.toEqual(-1); + expect(childNames).toContain('test'); + expect(childNames).toContain('test2'); + expect(childNames).toContain('test3'); + expect(childNames).toContain('test4'); + expect(childNames).toContain('test6'); + }); + + it("tutorials with names equal to reserved keywords in JS still function as expected", function() { + expect(constr instanceof tutorial.Tutorial).toBe(true); }); it("non-tutorials are skipped", function() { - expect(resolver.root.getByName('multple')).toBeUndefined(); - expect(resolver.root.getByName('test5')).toBeUndefined(); + expect(resolver.root.getByName('multiple')).toBeFalsy(); + expect(resolver.root.getByName('test5')).toBeFalsy(); }); - it("tutorial types are determined correctly", function() { // test.html, test2.markdown, test3.html, test4.md, test6.xml - expect(test.type).toEqual(tutorial.TYPES.HTML); - expect(test2.type).toEqual(tutorial.TYPES.MARKDOWN); - expect(test3.type).toEqual(tutorial.TYPES.HTML); - expect(test4.type).toEqual(tutorial.TYPES.MARKDOWN); - expect(test6.type).toEqual(tutorial.TYPES.HTML); + expect(test.type).toBe(tutorial.TYPES.HTML); + expect(test2.type).toBe(tutorial.TYPES.MARKDOWN); + expect(test3.type).toBe(tutorial.TYPES.HTML); + expect(test4.type).toBe(tutorial.TYPES.MARKDOWN); + expect(test6.type).toBe(tutorial.TYPES.HTML); + expect(constr.type).toBe(tutorial.TYPES.MARKDOWN); }); }); // resolve // myTutorial + // constructor // test // |- test2 // |- test6 @@ -114,42 +129,44 @@ describe("jsdoc/tutorial/resolver", function() { resolver.resolve(); it("hierarchy is resolved properly no matter how the children property is defined", function() { // root has child 'test' - expect(resolver.root.children.length).toEqual(2); - expect(resolver.root.children.indexOf(test)).not.toEqual(-1); - expect(test.parent).toEqual(resolver.root); + expect(resolver.root.children.length).toBe(3); + expect(resolver.root.children).toContain(test); + expect(resolver.root.children).toContain(constr); + expect(test.parent).toBe(resolver.root); + expect(constr.parent).toBe(resolver.root); // test has child 'test2' - expect(test.children.length).toEqual(1); - expect(test.children[0]).toEqual(test2); - expect(test2.parent).toEqual(test); + expect(test.children.length).toBe(1); + expect(test.children).toContain(test2); + expect(test2.parent).toBe(test); // test2 has children test3, test6 - expect(test2.children.length).toEqual(2); - expect(test2.children.indexOf(test3)).not.toEqual(-1); - expect(test2.children.indexOf(test6)).not.toEqual(-1); - expect(test3.parent).toEqual(test2); - expect(test6.parent).toEqual(test2); + expect(test2.children.length).toBe(2); + expect(test2.children).toContain(test3); + expect(test2.children).toContain(test6); + expect(test3.parent).toBe(test2); + expect(test6.parent).toBe(test2); // test3 has child test4 - expect(test3.children.length).toEqual(1); - expect(test3.children[0]).toEqual(test4); - expect(test4.parent).toEqual(test3); + expect(test3.children.length).toBe(1); + expect(test3.children).toContain(test4); + expect(test4.parent).toBe(test3); }); it("tutorials without configuration files have titles matching filenames", function() { // test6.xml didn't have a metadata - expect(test6.title).toEqual('test6'); + expect(test6.title).toBe('test6'); }); - it("tutorials with configuration files have titles matching filenames", function() { + it("tutorials with configuration files have titles as specified in configuration", function() { // test.json had info for just test.json - expect(test.title).toEqual("Test tutorial"); + expect(test.title).toBe("Test tutorial"); }); it("multiple tutorials can appear in a configuration file", function() { - expect(test2.title).toEqual("Test 2"); - expect(test3.title).toEqual("Test 3"); - expect(test4.title).toEqual("Test 4"); + expect(test2.title).toBe("Test 2"); + expect(test3.title).toBe("Test 3"); + expect(test4.title).toBe("Test 4"); }); }); diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 4ac12483..c692c4fb 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -783,10 +783,9 @@ describe("jsdoc/util/templateHelper", function() { }); describe("tutorialToUrl", function() { + var resolver = require('jsdoc/tutorial/resolver'); /*jshint evil: true */ - // TODO: more tests - var lenient = !!env.opts.lenient, log = eval(console.log); @@ -795,7 +794,7 @@ describe("jsdoc/util/templateHelper", function() { } beforeEach(function() { - var root = require('jsdoc/tutorial/resolver').root; + var root = resolver.root; helper.setTutorials(root); }); @@ -816,6 +815,38 @@ describe("jsdoc/util/templateHelper", function() { expect(missingTutorial).not.toThrow(); }); + + it("does not return a tutorial if its name is a reserved JS keyword and it doesn't exist", function() { + console.log = function () {}; + env.opts.lenient = false; + expect(function () { helper.tutorialToUrl('prototype') }).toThrow(); + }); + + it("creates links to tutorials if they exist", function() { + // NOTE: we have to set lenient = true here because otherwise JSDoc will + // cry when trying to resolve the same set of tutorials twice (once + // for the tutorials tests, and once here). + env.opts.lenient = true; + console.log = function() {}; + + // load the tutorials we already have for the tutorials tests + resolver.load(__dirname + "/test/tutorials/tutorials"); + resolver.resolve(); + + var url = helper.tutorialToUrl('test'); + expect(typeof url).toBe('string'); + expect(url).toBe('tutorial-test.html'); + }); + + it("creates links for tutorials where the name is a reserved JS keyword", function() { + var url = helper.tutorialToUrl('constructor'); + expect(typeof url).toBe('string'); + expect(url).toBe('tutorial-constructor.html'); + }); + + it("returns the same link if called multiple times on the same tutorial", function() { + expect(helper.tutorialToUrl('test2')).toBe(helper.tutorialToUrl('test2')); + }); }); describe("toTutorial", function() { From 8e9e06b3e478af5582aa2fe783f0c50c5acb0bfb Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Thu, 14 Feb 2013 17:37:34 +1000 Subject: [PATCH 09/13] filled out setTutorials and toTutorial links --- test/specs/jsdoc/util/templateHelper.js | 103 +++++++++++++++++++++--- 1 file changed, 93 insertions(+), 10 deletions(-) diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index c692c4fb..a09aec5d 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -3,9 +3,9 @@ var hasOwnProp = Object.prototype.hasOwnProperty; describe("jsdoc/util/templateHelper", function() { var helper = require('jsdoc/util/templateHelper'), - doclet = require('jsdoc/doclet'); + doclet = require('jsdoc/doclet'), + resolver = require('jsdoc/tutorial/resolver'); helper.registerLink('test', 'path/to/test.html'); - helper.registerLink('test."long blah"/blah', 'path/to/test_long_blah_blah.html'); it("should exist", function() { expect(helper).toBeDefined(); @@ -123,8 +123,32 @@ describe("jsdoc/util/templateHelper", function() { }); - xdescribe("setTutorials", function() { - // TODO + describe("setTutorials", function() { + // all it does is set var tutorials = root, how to test that?! + // used in tutorialToUrl, toTutorial. + it("setting tutorials to null causes all tutorial lookups to fail", function() { + // bit of a dodgy test but the best I can manage. setTutorials doesn't do much. + helper.setTutorials(null); + // should throw error: no 'getByName' in tutorials. + expect(function () { return helper.tutorialToUrl('asdf') }).toThrow('Cannot call method "getByName" of null'); + }); + + it("setting tutorials to the root tutorial object lets lookups work", function() { + var lenient = !!env.opts.lenient, + log = eval(console.log); + + // tutorial doesn't exist, we want to muffle that error + env.opts.lenient = true; + console.log = function () {}; + + helper.setTutorials(resolver.root); + spyOn(resolver.root, 'getByName'); + helper.tutorialToUrl('asdf'); + expect(resolver.root.getByName).toHaveBeenCalled(); + + env.opts.lenient = lenient; + console.log = log; + }); }); describe("globalName", function() { @@ -763,7 +787,7 @@ describe("jsdoc/util/templateHelper", function() { }); }); - xdescribe("registerLink", function() { + describe("registerLink", function() { it("adds an entry to exports.longnameToUrl", function() { helper.longnameToUrl.MySymbol = 'asdf.html'; @@ -783,7 +807,6 @@ describe("jsdoc/util/templateHelper", function() { }); describe("tutorialToUrl", function() { - var resolver = require('jsdoc/tutorial/resolver'); /*jshint evil: true */ var lenient = !!env.opts.lenient, @@ -794,8 +817,7 @@ describe("jsdoc/util/templateHelper", function() { } beforeEach(function() { - var root = resolver.root; - helper.setTutorials(root); + helper.setTutorials(resolver.root); }); afterEach(function() { @@ -852,8 +874,6 @@ describe("jsdoc/util/templateHelper", function() { describe("toTutorial", function() { /*jshint evil: true */ - // TODO: more tests - var lenient = !!env.opts.lenient, log = eval(console.log); @@ -864,6 +884,11 @@ describe("jsdoc/util/templateHelper", function() { afterEach(function() { env.opts.lenient = lenient; console.log = log; + helper.setTutorials(null); + }); + + beforeEach(function () { + helper.setTutorials(resolver.root); }); it('throws an exception if the first param is missing and the lenient option is not enabled', function() { @@ -878,6 +903,64 @@ describe("jsdoc/util/templateHelper", function() { expect(missingParam).not.toThrow(); }); + + // missing tutorials + it("returns the tutorial name if it's missing and no missingOpts is provided", function() { + helper.setTutorials(resolver.root); + var link = helper.toTutorial('asdf'); + expect(link).toBe('asdf'); + }); + + it("returns the tutorial name wrapped in missingOpts.tag if provided and the tutorial is missing", function() { + var link = helper.toTutorial('asdf', 'lkjklasdf', {tag: 'span'}); + expect(link).toBe('asdf'); + }); + + it("returns the tutorial name wrapped in missingOpts.tag with class missingOpts.classname if provided and the tutorial is missing", function() { + var link = helper.toTutorial('asdf', 'lkjklasdf', {classname: 'missing'}); + expect(link).toBe('asdf'); + + link = helper.toTutorial('asdf', 'lkjklasdf', {tag: 'span', classname: 'missing'}); + expect(link).toBe('asdf'); + }); + + it("prefixes the tutorial name with missingOpts.prefix if provided and the tutorial is missing", function() { + var link = helper.toTutorial('asdf', 'lkjklasdf', {tag: 'span', classname: 'missing', prefix: 'TODO-'}); + expect(link).toBe('TODO-asdf'); + + link = helper.toTutorial('asdf', 'lkjklasdf', {prefix: 'TODO-'}); + expect(link).toBe('TODO-asdf'); + + link = helper.toTutorial('asdf', 'lkjklasdf', {prefix: 'TODO-', classname: 'missing'}); + expect(link).toBe('TODO-asdf'); + }); + + // now we do non-missing tutorials. + it("returns a link to the tutorial if not missing", function() { + // NOTE: we have to set lenient = true here because otherwise JSDoc will + // cry when trying to resolve the same set of tutorials twice (once + // for the tutorials tests, and once here). + env.opts.lenient = true; + console.log = function() {}; + + // load the tutorials we already have for the tutorials tests + resolver.load(__dirname + "/test/tutorials/tutorials"); + resolver.resolve(); + + + var link = helper.toTutorial('constructor', 'The Constructor tutorial'); + expect(link).toBe('The Constructor tutorial'); + }); + + it("uses the tutorial's title for the link text if no content parameter is provided", function() { + var link = helper.toTutorial('test'); + expect(link).toBe('Test tutorial'); + }); + + it("does not apply any of missingOpts if the tutorial was found", function() { + var link = helper.toTutorial('test', '', {tag: 'span', classname: 'missing', prefix: 'TODO-'}); + expect(link).toBe('Test tutorial'); + }); }); // couple of convenience functions letting me set conf variables and restore From 1674f87259f2565cefaf4121fa6d965d29173147 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Thu, 14 Feb 2013 17:49:41 +1000 Subject: [PATCH 10/13] forgot to add a fixture that is used for the templateHelper tests... --- test/tutorials/tutorials/constructor.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/tutorials/tutorials/constructor.md diff --git a/test/tutorials/tutorials/constructor.md b/test/tutorials/tutorials/constructor.md new file mode 100644 index 00000000..2f181f08 --- /dev/null +++ b/test/tutorials/tutorials/constructor.md @@ -0,0 +1 @@ +This tutorial has a tricksy name to make sure we are not loading Array.constructor or Object.constructor. From 32fe768ea7cae5ea34b198e67b4e0acaf8b4d78d Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 22 Feb 2013 12:45:04 +1000 Subject: [PATCH 11/13] minor cleanup, mainly console.log = function () {} --> spyOn(console, 'log') --- lib/jsdoc/tutorial/resolver.js | 1 - test/specs/jsdoc/util/error.js | 6 ++---- test/specs/jsdoc/util/templateHelper.js | 23 +++++++---------------- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/lib/jsdoc/tutorial/resolver.js b/lib/jsdoc/tutorial/resolver.js index 8684a5a5..2314c86e 100644 --- a/lib/jsdoc/tutorial/resolver.js +++ b/lib/jsdoc/tutorial/resolver.js @@ -159,7 +159,6 @@ exports.load = function(_path) { exports.resolve = function() { var item, current; - //console.log(tutorials); for (var name in conf) { if ( hasOwnProp.call(conf, name) ) { // TODO: should we complain about this? diff --git a/test/specs/jsdoc/util/error.js b/test/specs/jsdoc/util/error.js index 4d0a8981..4b77e789 100644 --- a/test/specs/jsdoc/util/error.js +++ b/test/specs/jsdoc/util/error.js @@ -15,8 +15,7 @@ describe("jsdoc/util/error", function() { describe("handle", function() { /*jshint evil: true */ - var lenient = !!env.opts.lenient, - log = eval(console.log); + var lenient = !!env.opts.lenient; function handleError() { handle( new Error("foo") ); @@ -28,7 +27,6 @@ describe("jsdoc/util/error", function() { afterEach(function() { env.opts.lenient = lenient; - console.log = log; }); it("should re-throw errors by default", function() { @@ -43,7 +41,7 @@ describe("jsdoc/util/error", function() { it("should not re-throw errors if lenient mode is enabled", function() { env.opts.lenient = true; - console.log = function() {}; + spyOn(console, 'log'); expect(handleError).not.toThrow(); }); diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index ebe3bc95..cb2be6a4 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -124,7 +124,6 @@ describe("jsdoc/util/templateHelper", function() { describe("setTutorials", function() { - // all it does is set var tutorials = root, how to test that?! // used in tutorialToUrl, toTutorial. it("setting tutorials to null causes all tutorial lookups to fail", function() { // bit of a dodgy test but the best I can manage. setTutorials doesn't do much. @@ -134,12 +133,11 @@ describe("jsdoc/util/templateHelper", function() { }); it("setting tutorials to the root tutorial object lets lookups work", function() { - var lenient = !!env.opts.lenient, - log = eval(console.log); + var lenient = !!env.opts.lenient; + spyOn(console, 'log'); // tutorial doesn't exist, we want to muffle that error env.opts.lenient = true; - console.log = function () {}; helper.setTutorials(resolver.root); spyOn(resolver.root, 'getByName'); @@ -147,7 +145,6 @@ describe("jsdoc/util/templateHelper", function() { expect(resolver.root.getByName).toHaveBeenCalled(); env.opts.lenient = lenient; - console.log = log; }); }); @@ -811,21 +808,20 @@ describe("jsdoc/util/templateHelper", function() { describe("tutorialToUrl", function() { /*jshint evil: true */ - var lenient = !!env.opts.lenient, - log = eval(console.log); + var lenient = !!env.opts.lenient; function missingTutorial() { var url = helper.tutorialToUrl("be-a-perfect-person-in-just-three-days"); } beforeEach(function() { + spyOn(console, 'log'); helper.setTutorials(resolver.root); }); afterEach(function() { helper.setTutorials(null); env.opts.lenient = lenient; - console.log = log; }); it('throws an exception if the tutorial is missing and the lenient option is not enabled', function() { @@ -834,14 +830,12 @@ describe("jsdoc/util/templateHelper", function() { }); it('does not throw an exception if the tutorial is missing and the lenient option is enabled', function() { - console.log = function() {}; env.opts.lenient = true; expect(missingTutorial).not.toThrow(); }); it("does not return a tutorial if its name is a reserved JS keyword and it doesn't exist", function() { - console.log = function () {}; env.opts.lenient = false; expect(function () { helper.tutorialToUrl('prototype') }).toThrow(); }); @@ -851,7 +845,6 @@ describe("jsdoc/util/templateHelper", function() { // cry when trying to resolve the same set of tutorials twice (once // for the tutorials tests, and once here). env.opts.lenient = true; - console.log = function() {}; // load the tutorials we already have for the tutorials tests resolver.load(__dirname + "/test/tutorials/tutorials"); @@ -876,8 +869,7 @@ describe("jsdoc/util/templateHelper", function() { describe("toTutorial", function() { /*jshint evil: true */ - var lenient = !!env.opts.lenient, - log = eval(console.log); + var lenient = !!env.opts.lenient; function missingParam() { helper.toTutorial(); @@ -885,7 +877,6 @@ describe("jsdoc/util/templateHelper", function() { afterEach(function() { env.opts.lenient = lenient; - console.log = log; helper.setTutorials(null); }); @@ -900,7 +891,7 @@ describe("jsdoc/util/templateHelper", function() { }); it('does not throw an exception if the first param is missing and the lenient option is enabled', function() { - console.log = function() {}; + spyOn(console, 'log'); env.opts.lenient = true; expect(missingParam).not.toThrow(); @@ -943,7 +934,7 @@ describe("jsdoc/util/templateHelper", function() { // cry when trying to resolve the same set of tutorials twice (once // for the tutorials tests, and once here). env.opts.lenient = true; - console.log = function() {}; + spyOn(console, 'log'); // load the tutorials we already have for the tutorials tests resolver.load(__dirname + "/test/tutorials/tutorials"); From 2a8166cf3b64ff337eda39a2aa750e54481d59da Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 22 Feb 2013 12:46:21 +1000 Subject: [PATCH 12/13] Revert "FEATURE/FIX: jsdoc/util/templateHelper.getAncestorLinks: direct parents punctuation should be part of the link text. Parent~ vs Parent~" This reverts commit dad08be08a3cc92df3a73f58959c8847b7733a6c. --- lib/jsdoc/util/templateHelper.js | 7 ++----- test/specs/jsdoc/util/templateHelper.js | 6 ++++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/jsdoc/util/templateHelper.js b/lib/jsdoc/util/templateHelper.js index b63514c9..50d4dc2b 100644 --- a/lib/jsdoc/util/templateHelper.js +++ b/lib/jsdoc/util/templateHelper.js @@ -285,21 +285,18 @@ exports.getSignatureReturns = function(d, cssClass) { */ exports.getAncestorLinks = function(data, doclet, cssClass) { var ancestors = [], - doc = doclet.memberof, - directParent = false; + doc = doclet.memberof; while (doc) { doc = find( data, {longname: doc}, false ); if (doc) { doc = doc[0]; } if (!doc) { break; } - if (!directParent) { directParent = doc; } ancestors.unshift( linkto(doc.longname, (exports.scopeToPunc[doc.scope] || '') + doc.name, cssClass) ); doc = doc.memberof; } if (ancestors.length) { - var last = ancestors[ancestors.length - 1]; - ancestors[ancestors.length - 1] = last.replace(directParent.name, directParent.name + (exports.scopeToPunc[doclet.scope] || '')); + ancestors[ancestors.length - 1] += (exports.scopeToPunc[doclet.scope] || ''); } return ancestors; }; diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index cb2be6a4..96412250 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -712,7 +712,9 @@ describe("jsdoc/util/templateHelper", function() { var links = helper.getAncestorLinks(data, lackeys); expect(links.length).toBe(3); - expect(links).toContain('~Henchman#'); + // BUG: the link text is ~Henchman and there is a '#' on the end. + // should probably have link text ~Henchman#. + //expect(links).toContain('~Henchman#'); expect(links).toContain('.Sharks'); expect(links).toContain('mafia/gangs'); @@ -727,7 +729,7 @@ describe("jsdoc/util/templateHelper", function() { var links = helper.getAncestorLinks(data, lackeys, 'myClass'); expect(links.length).toBe(3); - expect(links).toContain('~Henchman#'); + //expect(links).toContain('~Henchman#'); expect(links).toContain('.Sharks'); expect(links).toContain('mafia/gangs'); From 2c4d5cdd06786fe5c96e95cc57f5e8e4a13abc2a Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 22 Feb 2013 12:48:03 +1000 Subject: [PATCH 13/13] updated getAncestorLinks tests to reflect previous revert --- test/specs/jsdoc/util/templateHelper.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 96412250..56b235c8 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -712,9 +712,7 @@ describe("jsdoc/util/templateHelper", function() { var links = helper.getAncestorLinks(data, lackeys); expect(links.length).toBe(3); - // BUG: the link text is ~Henchman and there is a '#' on the end. - // should probably have link text ~Henchman#. - //expect(links).toContain('~Henchman#'); + expect(links).toContain('~Henchman#'); expect(links).toContain('.Sharks'); expect(links).toContain('mafia/gangs'); @@ -729,7 +727,7 @@ describe("jsdoc/util/templateHelper", function() { var links = helper.getAncestorLinks(data, lackeys, 'myClass'); expect(links.length).toBe(3); - //expect(links).toContain('~Henchman#'); + expect(links).toContain('~Henchman#'); expect(links).toContain('.Sharks'); expect(links).toContain('mafia/gangs');