From 0bc2d0b78fe36d422ce1e7f7d1d3718c81a8d93a Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Mon, 11 Feb 2013 15:16:19 +1000 Subject: [PATCH 01/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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/40] 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 52528958da70039f11a2f117625404704b48836b Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 12:15:59 +1000 Subject: [PATCH 11/40] @returns: fixed typo in test description --- test/specs/tags/returnstag.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/specs/tags/returnstag.js b/test/specs/tags/returnstag.js index 9b3750c9..a401ae48 100644 --- a/test/specs/tags/returnstag.js +++ b/test/specs/tags/returnstag.js @@ -10,9 +10,9 @@ describe("@returns tag", function() { expect(find.returns[0].description).toEqual('The names of the found item(s).'); }); - it('When a symbol has an @param tag with only a type and name, the doclet has a returns array property that includes that param.', function() { + it('When a symbol has an @returns tag with only a description, the doclet has a returns array property that includes that return.', function() { expect(typeof bind.returns).toEqual('object'); expect(bind.returns.length).toEqual(1); expect(bind.returns[0].description).toEqual('The binding id.'); }); -}); \ No newline at end of file +}); From 2ca61c1beb2f30f51e7a120c519ae939079d9c2f Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 12:25:41 +1000 Subject: [PATCH 12/40] existing tags tests: toEqual -> toBe where appropriate --- test/specs/tags/abstracttag.js | 4 +-- test/specs/tags/accesstag.js | 8 ++--- test/specs/tags/augmentstag.js | 52 ++++++++++++++-------------- test/specs/tags/authortag.js | 2 +- test/specs/tags/borrowstag.js | 8 ++--- test/specs/tags/classtag.js | 6 ++-- test/specs/tags/constructortag.js | 6 ++-- test/specs/tags/constructstag.js | 24 ++++++------- test/specs/tags/copyrighttag.js | 2 +- test/specs/tags/defaulttag.js | 10 +++--- test/specs/tags/deprecatedtag.js | 4 +-- test/specs/tags/enumtag.js | 10 +++--- test/specs/tags/eventfirestag.js | 8 ++--- test/specs/tags/exceptiontag.js | 12 +++---- test/specs/tags/exportstag.js | 40 +++++++++++----------- test/specs/tags/globaltag.js | 12 +++---- test/specs/tags/ignoretag.js | 4 +-- test/specs/tags/memberoftag.js | 32 +++++++++--------- test/specs/tags/moduletag.js | 20 +++++------ test/specs/tags/overviewtag.js | 4 +-- test/specs/tags/paramtag.js | 56 +++++++++++++++---------------- test/specs/tags/privatetag.js | 2 +- test/specs/tags/propertytag.js | 14 ++++---- test/specs/tags/readonlytag.js | 2 +- test/specs/tags/requirestag.js | 10 +++--- test/specs/tags/returnstag.js | 14 ++++---- test/specs/tags/seetag.js | 8 ++--- test/specs/tags/sincetag.js | 2 +- test/specs/tags/thistag.js | 10 +++--- test/specs/tags/typedeftag.js | 16 ++++----- test/specs/tags/typekind.js | 8 ++--- test/specs/tags/typetag.js | 8 ++--- test/specs/tags/versiontag.js | 2 +- 33 files changed, 210 insertions(+), 210 deletions(-) diff --git a/test/specs/tags/abstracttag.js b/test/specs/tags/abstracttag.js index 4d6c7e19..be2b7862 100644 --- a/test/specs/tags/abstracttag.js +++ b/test/specs/tags/abstracttag.js @@ -8,13 +8,13 @@ describe("@abstract tag", function() { }); it("should set the doclet's 'virtual' property to true when ' @abstract tag is present", function() { - expect(pez.virtual).toEqual(true); + expect(pez.virtual).toBe(true); }); // same as... it("should set the doclet's 'virtual' property to true when ' @abstract tag is present", function() { pez = docSet.getByLongname('OtherThingy#pez')[0]; - expect(pez.virtual).toEqual(true); + expect(pez.virtual).toBe(true); }); }); \ No newline at end of file diff --git a/test/specs/tags/accesstag.js b/test/specs/tags/accesstag.js index 8f260ade..3bfa3973 100644 --- a/test/specs/tags/accesstag.js +++ b/test/specs/tags/accesstag.js @@ -8,13 +8,13 @@ describe("@access tag", function() { pez2 = docSet.getByLongname('OtherThingy#pez')[0]; it("should set the doclet's 'access' property to 'private' when there is an @access private tag", function() { - expect(foo.access).toEqual('private'); - expect(foo2.access).toEqual('private'); + expect(foo.access).toBe('private'); + expect(foo2.access).toBe('private'); }); it("should set the doclet's 'access' property to 'protected' when there is an @access protected tag", function() { - expect(_bar.access).toEqual('protected'); - expect(_bar2.access).toEqual('protected'); + expect(_bar.access).toBe('protected'); + expect(_bar2.access).toBe('protected'); }); it("should set no 'access' property on the doclet when there is an @access public tag", function() { diff --git a/test/specs/tags/augmentstag.js b/test/specs/tags/augmentstag.js index 56d5faaa..e03aae60 100644 --- a/test/specs/tags/augmentstag.js +++ b/test/specs/tags/augmentstag.js @@ -27,8 +27,8 @@ qux = docSet2.getByLongname('Qux')[0]; it('When a symbol has an @augments tag, the doclet has a augments property that includes that value.', function() { - expect(typeof bar.augments).toEqual('object'); - expect(bar.augments[0]).toEqual('Foo'); + expect(typeof bar.augments).toBe('object'); + expect(bar.augments[0]).toBe('Foo'); }); it('When an object is extended, the original is not modified', function() { @@ -36,50 +36,50 @@ }); it('When an object is extended, it inherits properties set in parent constructor', function() { - expect(fooProp1.memberof).toEqual("Foo"); - expect(barProp1.memberof).toEqual("Bar"); - expect(barProp1.description).toEqual(fooProp1.description); + expect(fooProp1.memberof).toBe("Foo"); + expect(barProp1.memberof).toBe("Bar"); + expect(barProp1.description).toBe(fooProp1.description); }); it('When an object is extended, it inherits properties set on parent prototype', function() { - expect(fooProp2.memberof).toEqual("Foo"); - expect(barProp2.memberof).toEqual("Bar"); - expect(barProp2.description).toEqual(fooProp2.description); + expect(fooProp2.memberof).toBe("Foo"); + expect(barProp2.memberof).toBe("Bar"); + expect(barProp2.description).toBe(fooProp2.description); }); it('When an object is extended, it inherits methods set on parent prototype', function() { - expect(fooMethod1.memberof).toEqual("Foo"); - expect(barMethod1.memberof).toEqual("Bar"); - expect(barMethod1.description).toEqual(fooMethod1.description); + expect(fooMethod1.memberof).toBe("Foo"); + expect(barMethod1.memberof).toBe("Bar"); + expect(barMethod1.description).toBe(fooMethod1.description); }); it('When an object is extended, it may override methods set on parent prototype', function() { - expect(fooMethod2.memberof).toEqual("Foo"); - expect(fooMethod2.description).toEqual("Second parent method."); - expect(barMethod2.memberof).toEqual("Bar"); - expect(barMethod2.description).toEqual("Second child method."); + expect(fooMethod2.memberof).toBe("Foo"); + expect(fooMethod2.description).toBe("Second parent method."); + expect(barMethod2.memberof).toBe("Bar"); + expect(barMethod2.description).toBe("Second child method."); }); it('When an object is extended, and it overrides an ancestor method, the child does not include docs for the ancestor method.', function() { - expect(barMethod2All.length).toEqual(1); + expect(barMethod2All.length).toBe(1); }); it('When an object is extended, it inherits properties set on grandparent prototype', function() { - expect(fooProp1.memberof).toEqual("Foo"); - expect(barProp1.memberof).toEqual("Bar"); - expect(bazProp1.memberof).toEqual("Baz"); - expect(bazProp1.description).toEqual("Override prop1"); - expect(bazMethod1.memberof).toEqual("Baz"); - expect(bazMethod2.memberof).toEqual("Baz"); - expect(bazMethod3.memberof).toEqual("Baz"); + expect(fooProp1.memberof).toBe("Foo"); + expect(barProp1.memberof).toBe("Bar"); + expect(bazProp1.memberof).toBe("Baz"); + expect(bazProp1.description).toBe("Override prop1"); + expect(bazMethod1.memberof).toBe("Baz"); + expect(bazMethod2.memberof).toBe("Baz"); + expect(bazMethod3.memberof).toBe("Baz"); }); it('When an object is extended, and it overrides an ancestor property, the child does not include docs for the ancestor property.', function() { - expect(bazProp1All.length).toEqual(1); + expect(bazProp1All.length).toBe(1); }); it('When a symbol has an @augments tag, and the parent is not documented, the doclet still has an augments property', function() { - expect(typeof qux.augments).toEqual('object'); - expect(qux.augments[0]).toEqual('UndocumentedThing'); + expect(typeof qux.augments).toBe('object'); + expect(qux.augments[0]).toBe('UndocumentedThing'); }); }); diff --git a/test/specs/tags/authortag.js b/test/specs/tags/authortag.js index 4db3fb37..42ca0cc6 100644 --- a/test/specs/tags/authortag.js +++ b/test/specs/tags/authortag.js @@ -3,6 +3,6 @@ describe("@author tag", function() { Thingy = docSet.getByLongname('Thingy')[0]; it('When a symbol has a @author tag, the doclet has a author property with that value.', function() { - expect(Thingy.author[0]).toEqual('Michael Mathews '); + expect(Thingy.author[0]).toBe('Michael Mathews '); }); }); \ No newline at end of file diff --git a/test/specs/tags/borrowstag.js b/test/specs/tags/borrowstag.js index 6b0d2316..4a6fdf57 100644 --- a/test/specs/tags/borrowstag.js +++ b/test/specs/tags/borrowstag.js @@ -4,9 +4,9 @@ describe("@borrows tag", function() { util = docSet.getByLongname('util').filter(function($) { return ! $.undocumented; })[0]; - expect(util.borrowed.length).toEqual(1); - expect(util.borrowed[0].from).toEqual('trstr'); - expect(util.borrowed[0].as).toEqual('trim'); + expect(util.borrowed.length).toBe(1); + expect(util.borrowed[0].from).toBe('trstr'); + expect(util.borrowed[0].as).toBe('trim'); }); it('When a symbol has a @borrows tag, the borrowed symbol is added to the symbol.', function() { @@ -19,6 +19,6 @@ describe("@borrows tag", function() { return ! $.undocumented; })[0]; - expect(typeof str_rtrim).toEqual('object'); + expect(typeof str_rtrim).toBe('object'); }); }); \ No newline at end of file diff --git a/test/specs/tags/classtag.js b/test/specs/tags/classtag.js index 2a54a1d8..0a28a54d 100644 --- a/test/specs/tags/classtag.js +++ b/test/specs/tags/classtag.js @@ -4,11 +4,11 @@ describe("@class tag", function() { news = docSet.getByLongname('NewsSource')[0]; it('When a symbol has a @class tag, the doclet has a kind property set to "class".', function() { - expect(ticker.kind).toEqual('class'); + expect(ticker.kind).toBe('class'); }); it('When a symbol has a @class tag with a value, the doclet has a name property set to that value.', function() { - expect(news.kind).toEqual('class'); - expect(news.longname).toEqual('NewsSource'); + expect(news.kind).toBe('class'); + expect(news.longname).toBe('NewsSource'); }); }); \ No newline at end of file diff --git a/test/specs/tags/constructortag.js b/test/specs/tags/constructortag.js index 48ec7ea4..dd2bedad 100644 --- a/test/specs/tags/constructortag.js +++ b/test/specs/tags/constructortag.js @@ -3,11 +3,11 @@ describe("@constructor tag", function() { feed = docSet.getByLongname('Feed')[0]; it('When a symbol has an @constructor tag, it is documented as a class.', function() { - expect(feed.kind).toEqual('class'); + expect(feed.kind).toBe('class'); }); it('When a symbol has an @constructor tag and a @class tag, the value of the @class tag becomes the classdesc property.', function() { - expect(feed.classdesc).toEqual('Describe your class here.'); - expect(feed.description).toEqual('Describe your constructor function here.'); + expect(feed.classdesc).toBe('Describe your class here.'); + expect(feed.description).toBe('Describe your constructor function here.'); }); }); \ No newline at end of file diff --git a/test/specs/tags/constructstag.js b/test/specs/tags/constructstag.js index 661267fb..a7198a4c 100644 --- a/test/specs/tags/constructstag.js +++ b/test/specs/tags/constructstag.js @@ -4,24 +4,24 @@ describe("@constructs tag", function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag.js'), textblock = docSet.getByLongname('TextBlock')[0]; - expect(textblock.kind).toEqual('class'); - expect(textblock.longname).toEqual('TextBlock'); + expect(textblock.kind).toBe('class'); + expect(textblock.longname).toBe('TextBlock'); }); it('When a symbol has an @constructs tag, it is documented as a class.', function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag2.js'), menu = docSet.getByLongname('Menu')[0]; - expect(menu.name).toEqual('Menu'); - expect(menu.kind).toEqual('class'); + expect(menu.name).toBe('Menu'); + expect(menu.kind).toBe('class'); }); it('When a function symbol has an @constructs tag, any this-variables are ducumented as instance members of the class.', function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag3.js'), personName = docSet.getByLongname('Person#name')[0]; - expect(personName.memberof).toEqual('Person'); - expect(personName.scope).toEqual('instance'); + expect(personName.memberof).toBe('Person'); + expect(personName.scope).toBe('instance'); }); it('When a function symbol has an @constructs tag with no value, in a @lends block with a "Name#" value, the function is documented as a constructor of "Name".', function() { @@ -30,15 +30,15 @@ describe("@constructs tag", function() { return ! $.undocumented; })[0]; - expect(person.kind).toEqual('class'); + expect(person.kind).toBe('class'); }); it('When a function symbol has an @constructs tag with no value, any this-variables are documented as instance members of the class.', function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/constructstag4.js'), personName = docSet.getByLongname('Person#name')[0]; - expect(personName.memberof).toEqual('Person'); - expect(personName.scope).toEqual('instance'); + expect(personName.memberof).toBe('Person'); + expect(personName.scope).toBe('instance'); }); it('When a object literal property has an @constructs tag with no value, and the object has a @lends, the property is documented as the lent class.', function() { @@ -47,8 +47,8 @@ describe("@constructs tag", function() { return ! $.undocumented; })[0]; - expect(duck.longname).toEqual('Duck'); - expect(duck.kind).toEqual('class'); - expect(duck.description).toEqual('Constructs a duck.'); + expect(duck.longname).toBe('Duck'); + expect(duck.kind).toBe('class'); + expect(duck.description).toBe('Constructs a duck.'); }); }); \ No newline at end of file diff --git a/test/specs/tags/copyrighttag.js b/test/specs/tags/copyrighttag.js index f63a3fdd..c9c7a5f1 100644 --- a/test/specs/tags/copyrighttag.js +++ b/test/specs/tags/copyrighttag.js @@ -3,6 +3,6 @@ describe("@copyright tag", function() { Thingy = docSet.getByLongname('Thingy')[0]; it('When a symbol has a @copyright tag, the doclet has a copyright property with that value.', function() { - expect(Thingy.copyright).toEqual('(c) 2011 Michael Mathews'); + expect(Thingy.copyright).toBe('(c) 2011 Michael Mathews'); }); }); \ No newline at end of file diff --git a/test/specs/tags/defaulttag.js b/test/specs/tags/defaulttag.js index 77ff096b..ca4b086b 100644 --- a/test/specs/tags/defaulttag.js +++ b/test/specs/tags/defaulttag.js @@ -9,23 +9,23 @@ describe("@default tag", function() { header = (docSet.getByLongname('header') || [])[0]; it('When symbol set to null has a @default tag with no text, the doclet\'s defaultValue property should be: null', function() { - expect(request.defaultvalue).toEqual('null'); + expect(request.defaultvalue).toBe('null'); }); it('When symbol set to a string has a @default tag with no text, the doclet\'s defaultValue property should be that quoted string', function() { - expect(response.defaultvalue).toEqual('"ok"'); + expect(response.defaultvalue).toBe('"ok"'); }); it('When symbol set to a number has a @default tag with no text, the doclet\'s defaultValue property should be that number.', function() { - expect(rcode.defaultvalue).toEqual('200'); + expect(rcode.defaultvalue).toBe('200'); }); it('When symbol has a @default tag with text, the doclet\'s defaultValue property should be that text.', function() { - expect(win.defaultvalue).toEqual('the parent window'); + expect(win.defaultvalue).toBe('the parent window'); }); it('When symbol has a @default tag with true.', function() { - expect(rvalid.defaultvalue).toEqual('true'); + expect(rvalid.defaultvalue).toBe('true'); }); it('When symbol has a @default tag with false.', function() { diff --git a/test/specs/tags/deprecatedtag.js b/test/specs/tags/deprecatedtag.js index b87a1111..0e60ce29 100644 --- a/test/specs/tags/deprecatedtag.js +++ b/test/specs/tags/deprecatedtag.js @@ -4,11 +4,11 @@ describe("@deprecated tag", function() { bar = docSet.getByLongname('bar')[0]; it('When a symbol has a @deprecated tag with no value, the doclet has a deprecated property set to true.', function() { - expect(foo.deprecated).toEqual(true); + expect(foo.deprecated).toBe(true); }); it('When a symbol has a @deprecated tag with a value, the doclet has a deprecated property set to that value.', function() { - expect(bar.deprecated).toEqual('since version 2.0'); + expect(bar.deprecated).toBe('since version 2.0'); }); }); \ No newline at end of file diff --git a/test/specs/tags/enumtag.js b/test/specs/tags/enumtag.js index a7c32a28..4f48727e 100644 --- a/test/specs/tags/enumtag.js +++ b/test/specs/tags/enumtag.js @@ -3,24 +3,24 @@ describe("@enum tag", function() { tristate = docSet.getByLongname('TriState')[0]; it('When a symbol has a @enum tag, it has a properties array.', function() { - expect(typeof tristate.properties).toEqual('object'); + expect(typeof tristate.properties).toBe('object'); }); it('If no @type is given for the property it is inherted from the enum.', function() { - expect(tristate.properties[0].type.names.join(', ')).toEqual('number'); + expect(tristate.properties[0].type.names.join(', ')).toBe('number'); }); it('If no no comment is given for the property it is still included in the enum.', function() { - expect(tristate.properties[1].longname).toEqual('TriState.FALSE'); + expect(tristate.properties[1].longname).toBe('TriState.FALSE'); expect(tristate.properties[1].undocumented).toBeUndefined(); }); it('A property of an enum gets its defaultvalue set.', function() { - expect(tristate.properties[1].defaultvalue).toEqual('-1'); + expect(tristate.properties[1].defaultvalue).toBe('-1'); }); it('If a @type is given for the property it is reflected in the property value.', function() { - expect(tristate.properties[2].type.names.join(', ')).toEqual('boolean'); + expect(tristate.properties[2].type.names.join(', ')).toBe('boolean'); }); it('An enum does not contain any circular references.', function() { diff --git a/test/specs/tags/eventfirestag.js b/test/specs/tags/eventfirestag.js index 13b37402..952e9574 100644 --- a/test/specs/tags/eventfirestag.js +++ b/test/specs/tags/eventfirestag.js @@ -5,19 +5,19 @@ describe("@event and @fires tags", function() { // @event tag it('When a symbol has an @event tag, the doclet is of kind "event".', function() { - expect(snowballEvent.kind).toEqual('event'); + expect(snowballEvent.kind).toBe('event'); }); // @fires tag it('When a symbol has a @fires tag, the doclet has an array named "fires".', function() { - expect(typeof snowballMethod.fires).toEqual('object'); + expect(typeof snowballMethod.fires).toBe('object'); }); it('When a symbol has a fires array, the members have the event namespace.', function() { - expect(snowballMethod.fires[0]).toEqual('Hurl#event:snowball'); + expect(snowballMethod.fires[0]).toBe('Hurl#event:snowball'); }); it('When a symbol has a fires array with a name that already has an event: namespace, it doesn\'t have a secong namespace applied.', function() { - expect(snowballMethod.fires[1]).toEqual('Hurl#event:brick'); + expect(snowballMethod.fires[1]).toBe('Hurl#event:brick'); }); }); \ No newline at end of file diff --git a/test/specs/tags/exceptiontag.js b/test/specs/tags/exceptiontag.js index e24405bf..40d3a0c4 100644 --- a/test/specs/tags/exceptiontag.js +++ b/test/specs/tags/exceptiontag.js @@ -5,13 +5,13 @@ describe("@exception tag", function() { pez = docSet.getByLongname('pez')[0]; it('When a symbol has an @exception tag, the doclet has a exception property set to that value.', function() { - expect(typeof foo.exceptions).toEqual('object'); - expect(foo.exceptions.length).toEqual(1); + expect(typeof foo.exceptions).toBe('object'); + expect(foo.exceptions.length).toBe(1); - expect(typeof bar.exceptions).toEqual('object'); - expect(bar.exceptions.length).toEqual(1); + expect(typeof bar.exceptions).toBe('object'); + expect(bar.exceptions.length).toBe(1); - expect(typeof pez.exceptions).toEqual('object'); - expect(pez.exceptions.length).toEqual(1); + expect(typeof pez.exceptions).toBe('object'); + expect(pez.exceptions.length).toBe(1); }); }); \ No newline at end of file diff --git a/test/specs/tags/exportstag.js b/test/specs/tags/exportstag.js index 6d422754..9d11ad91 100644 --- a/test/specs/tags/exportstag.js +++ b/test/specs/tags/exportstag.js @@ -8,24 +8,24 @@ describe("@exports tag", function() { size = docSet.getByLongname('module:my/shirt.Turtleneck#size')[0]; it('When an objlit symbol has an @exports tag, the doclet is aliased to "module:" + the tag value.', function() { - expect(typeof shirt).toEqual('object'); - expect(shirt.alias).toEqual('my/shirt'); + expect(typeof shirt).toBe('object'); + expect(shirt.alias).toBe('my/shirt'); }); it('When an objlit symbol has an @exports tag, the doclet\'s longname includes the "module:" namespace.', function() { - expect(shirt.longname).toEqual('module:my/shirt'); + expect(shirt.longname).toBe('module:my/shirt'); }); it('When an objlit symbol has an @exports tag, the doclet kind is set to module.', function() { - expect(shirt.kind).toEqual('module'); + expect(shirt.kind).toBe('module'); }); it('When an objlit symbol has an @exports tag, the objlit members are documented as members of the module.', function() { - expect(typeof color).toEqual('object'); - expect(color.memberof).toEqual('module:my/shirt'); + expect(typeof color).toBe('object'); + expect(color.memberof).toBe('module:my/shirt'); - expect(typeof tneck).toEqual('object'); - expect(typeof size).toEqual('object'); + expect(typeof tneck).toBe('object'); + expect(typeof size).toBe('object'); }); }); @@ -35,21 +35,21 @@ describe("@exports tag", function() { wool = docSet.getByLongname('module:my/coat#wool')[0]; it('When a function symbol has an @exports tag, the doclet is aliased to "module:" + the tag value.', function() { - expect(typeof coat).toEqual('object'); - expect(coat.alias).toEqual('my/coat'); + expect(typeof coat).toBe('object'); + expect(coat.alias).toBe('my/coat'); }); it('When a function symbol has an @exports tag, the doclet\'s longname includes the "module:" namespace.', function() { - expect(coat.longname).toEqual('module:my/coat'); + expect(coat.longname).toBe('module:my/coat'); }); it('When a function symbol has an @exports tag, the doclet kind is set to module.', function() { - expect(coat.kind).toEqual('module'); + expect(coat.kind).toBe('module'); }); it('When a function symbol has an @exports tag, the this members are documented as instance members of the module.', function() { - expect(typeof wool).toEqual('object'); - expect(wool.memberof).toEqual('module:my/coat'); + expect(typeof wool).toBe('object'); + expect(wool.memberof).toBe('module:my/coat'); }); }); @@ -60,13 +60,13 @@ describe("@exports tag", function() { inhead = docSet.getByLongname('module:html/utils.isInHead')[0]; it('When a function symbol has an @exports tag and there is an objlit named "exports" the members are documented as members of the module.', function() { - expect(typeof getstyle).toEqual('object'); - expect(getstyle.memberof).toEqual('module:html/utils'); + expect(typeof getstyle).toBe('object'); + expect(getstyle.memberof).toBe('module:html/utils'); }); it('When a function symbol has an @exports tag and there are members assinged to an "exports" name, the members are documented as members of the module.', function() { - expect(typeof inhead).toEqual('object'); - expect(inhead.memberof).toEqual('module:html/utils'); + expect(typeof inhead).toBe('object'); + expect(inhead.memberof).toBe('module:html/utils'); }); }); @@ -77,12 +77,12 @@ describe("@exports tag", function() { method = docSet.getByLongname('module:some/module~myClass#myMethod')[0]; it('An inner class declared as a function in a module should be documented.', function() { - expect(typeof innerClass).toEqual('object'); + expect(typeof innerClass).toBe('object'); //expect(getstyle.memberof, 'module:html/utils'); }); it('A method of an inner class declared as a function in a module should be documented.', function() { - expect(typeof method).toEqual('object'); + expect(typeof method).toBe('object'); //expect(inhead.memberof, 'module:html/utils'); }); }); diff --git a/test/specs/tags/globaltag.js b/test/specs/tags/globaltag.js index 4c245c95..3aeb34d8 100644 --- a/test/specs/tags/globaltag.js +++ b/test/specs/tags/globaltag.js @@ -5,10 +5,10 @@ describe("@global tag", function() { var found = docSet.getByLongname('foo').filter(function($) { return ! $.undocumented; }); - expect(found[0].name).toEqual('foo'); - expect(found[0].longname).toEqual('foo'); + expect(found[0].name).toBe('foo'); + expect(found[0].longname).toBe('foo'); expect(found[0].memberof).toBeUndefined(); - expect(found[0].scope).toEqual('global'); + expect(found[0].scope).toBe('global'); }); @@ -16,9 +16,9 @@ describe("@global tag", function() { var found = docSet.getByLongname('Bar').filter(function($) { return ! $.undocumented; }); - expect(found[0].name).toEqual('Bar'); - expect(found[0].longname).toEqual('Bar'); + expect(found[0].name).toBe('Bar'); + expect(found[0].longname).toBe('Bar'); expect(found[0].memberof).toBeUndefined(); - expect(found[0].scope).toEqual('global'); + expect(found[0].scope).toBe('global'); }); }); \ No newline at end of file diff --git a/test/specs/tags/ignoretag.js b/test/specs/tags/ignoretag.js index 73d25468..cc78f416 100644 --- a/test/specs/tags/ignoretag.js +++ b/test/specs/tags/ignoretag.js @@ -3,7 +3,7 @@ describe("@ignore tag", function() { foo = docSet.getByLongname('foo')[0]; it('When a symbol has an @ignore tag, the doclet has a ignore property set to true.', function() { - expect(foo.ignore).toEqual(true); + expect(foo.ignore).toBe(true); }); it('When a symbol has an @ignore tag with a value an error is thrown', function() { @@ -11,7 +11,7 @@ describe("@ignore tag", function() { docSet = jasmine.getDocSetFromFile('test/fixtures/ignoretag2.js'); foo = docSet.getByLongname('foo')[0]; } catch (e) { - expect(e.name).toEqual('TagValueNotPermittedError'); + expect(e.name).toBe('TagValueNotPermittedError'); }; }); }); \ No newline at end of file diff --git a/test/specs/tags/memberoftag.js b/test/specs/tags/memberoftag.js index 15653a11..46d61201 100644 --- a/test/specs/tags/memberoftag.js +++ b/test/specs/tags/memberoftag.js @@ -6,11 +6,11 @@ describe("@memberof tag", function() { Data = docSet.getByLongname('mathlib.Data')[0], point = docSet.getByLongname('mathlib.Data#point')[0]; - expect(typeof Data).toEqual('object'); - expect(typeof point).toEqual('object'); + expect(typeof Data).toBe('object'); + expect(typeof point).toBe('object'); - expect(Data.memberof).toEqual('mathlib'); - expect(Data.name).toEqual('Data'); + expect(Data.memberof).toBe('mathlib'); + expect(Data.name).toBe('Data'); }); it('A symbol within a namespace for which no scope is specified.', function() { @@ -18,7 +18,7 @@ describe("@memberof tag", function() { doOtherStuff = docSet.getByLongname('doStuff.doOtherStuff')[0]; expect(doOtherStuff).toBeDefined(); - expect(doOtherStuff.scope).toEqual('static'); + expect(doOtherStuff.scope).toBe('static'); }); it('A symbol in which name === memberof.', function() { @@ -26,7 +26,7 @@ describe("@memberof tag", function() { doStuff = docSet.getByLongname('doStuff.doStuff')[0]; expect(doStuff).toBeDefined(); - expect(doStuff.scope).toEqual('static'); + expect(doStuff.scope).toBe('static'); }); describe ("static", function() { @@ -36,20 +36,20 @@ describe("@memberof tag", function() { it('A symbol is documented as a static @memberof a class.', function() { //it should appear as a static member of that class - expect(typeof cache).toEqual('object'); - expect(cache.memberof).toEqual('Observable'); - expect(cache.scope).toEqual('static'); - expect(cache.name).toEqual('cache'); - expect(cache.longname).toEqual('Observable.cache'); + expect(typeof cache).toBe('object'); + expect(cache.memberof).toBe('Observable'); + expect(cache.scope).toBe('static'); + expect(cache.name).toBe('cache'); + expect(cache.longname).toBe('Observable.cache'); }); it('A symbol is documented as a static @memberof a class prototype.', function() { //it should appear as an instance member of that class - expect(typeof publish).toEqual('object'); - expect(publish.memberof).toEqual('Observable'); - expect(publish.scope).toEqual('instance'); - expect(publish.name).toEqual('publish'); - expect(publish.longname).toEqual('Observable#publish'); + expect(typeof publish).toBe('object'); + expect(publish.memberof).toBe('Observable'); + expect(publish.scope).toBe('instance'); + expect(publish.name).toBe('publish'); + expect(publish.longname).toBe('Observable#publish'); }); }); diff --git a/test/specs/tags/moduletag.js b/test/specs/tags/moduletag.js index edee26c1..e2b44e30 100644 --- a/test/specs/tags/moduletag.js +++ b/test/specs/tags/moduletag.js @@ -5,13 +5,13 @@ describe("@module tag", function() { title = docSet.getByLongname('module:bookshelf.Book#title')[0]; it('When a global symbol starts with "this" and is in a file with a @module tag, the symbol is documented as a member of that module.', function() { - expect(typeof book).toEqual('object'); - expect(book.memberof).toEqual('module:bookshelf'); + expect(typeof book).toBe('object'); + expect(book.memberof).toBe('module:bookshelf'); }); it('When an inner symbol starts with "this" and is in a file with a @module tag, the symbol is documented as a member of its enclosing constructor.', function() { - expect(typeof title).toEqual('object'); - expect(title.memberof).toEqual('module:bookshelf.Book'); + expect(typeof title).toBe('object'); + expect(title.memberof).toBe('module:bookshelf.Book'); }); }); @@ -24,18 +24,18 @@ describe("@module tag", function() { darken = docSet.getByLongname('module:color/mixer.darken')[0]; it('When a @module tag defines a module module, a symbol of kind "module" is documented', function() { - expect(typeof mixer).toEqual('object'); - expect(mixer.kind).toEqual('module'); + expect(typeof mixer).toBe('object'); + expect(mixer.kind).toBe('module'); }); it('When an object literal is lent to a module with a @lends tag, A member of that object literal is documented as a member of the module', function() { - expect(typeof blend).toEqual('object'); - expect(blend.kind).toEqual('function'); + expect(typeof blend).toBe('object'); + expect(blend.kind).toBe('function'); }); it('When a documented symbol is a member of a namespace "exports", it is documented as a member of the module', function() { - expect(typeof darken).toEqual('object'); - expect(darken.kind).toEqual('function'); + expect(typeof darken).toBe('object'); + expect(darken.kind).toBe('function'); }); }); }); \ No newline at end of file diff --git a/test/specs/tags/overviewtag.js b/test/specs/tags/overviewtag.js index 67f09130..6087be5b 100644 --- a/test/specs/tags/overviewtag.js +++ b/test/specs/tags/overviewtag.js @@ -13,6 +13,6 @@ describe("@overview tag", function() { }); it("The name and longname should be equal", function() { - expect(doclets[0].name).toEqual(doclets[0].longname); + expect(doclets[0].name).toBe(doclets[0].longname); }); -}); \ No newline at end of file +}); diff --git a/test/specs/tags/paramtag.js b/test/specs/tags/paramtag.js index 14d628ad..3e7b2696 100644 --- a/test/specs/tags/paramtag.js +++ b/test/specs/tags/paramtag.js @@ -9,60 +9,60 @@ describe("@param tag", function() { commit = docSet.getByLongname('commit')[0]; it('When a symbol has an @param tag with a type before the name, the doclet has a params property that includes that param.', function() { - expect(typeof find.params).toEqual('object'); - expect(find.params.length).toEqual(1); - expect(find.params[0].type.names.join(', ')).toEqual('String, Array'); - expect(find.params[0].name).toEqual('targetName'); - expect(find.params[0].description).toEqual('The name (or names) of what to find.'); + expect(typeof find.params).toBe('object'); + expect(find.params.length).toBe(1); + expect(find.params[0].type.names.join(', ')).toBe('String, Array'); + expect(find.params[0].name).toBe('targetName'); + expect(find.params[0].description).toBe('The name (or names) of what to find.'); }); it('When a symbol has an @param tag with only a type and name, the doclet has a params property that includes that param.', function() { - expect(typeof bind.params).toEqual('object'); - expect(bind.params.length).toEqual(1); - expect(bind.params[0].type.names.join(', ')).toEqual('function'); - expect(bind.params[0].name).toEqual('callback'); + expect(typeof bind.params).toBe('object'); + expect(bind.params.length).toBe(1); + expect(bind.params[0].type.names.join(', ')).toBe('function'); + expect(bind.params[0].name).toBe('callback'); expect(bind.params[0].description).toBeUndefined(); }); it('When a symbol has an @param tag with only a type, the doclet has a params property that includes that param.', function() { - expect(typeof unbind.params).toEqual('object'); - expect(unbind.params.length).toEqual(1); - expect(unbind.params[0].type.names.join(', ')).toEqual('function'); + expect(typeof unbind.params).toBe('object'); + expect(unbind.params.length).toBe(1); + expect(unbind.params[0].type.names.join(', ')).toBe('function'); expect(unbind.params[0].description).toBeUndefined(); }); it('When a symbol has an @param tag with no type, the doclet has a params property that includes that param.', function() { - expect(typeof getElement.params).toEqual('object'); - expect(getElement.params.length).toEqual(1); + expect(typeof getElement.params).toBe('object'); + expect(getElement.params.length).toBe(1); expect(getElement.params[0].type).toBeUndefined(); - expect(getElement.params[0].name).toEqual('id'); - expect(getElement.params[0].description).toEqual('The id of the element.'); + expect(getElement.params[0].name).toBe('id'); + expect(getElement.params[0].description).toBe('The id of the element.'); }); it('When a symbol has an @param tag with a non-alpha name like "...", the doclet has a params property that includes that param.', function() { - expect(typeof combine.params).toEqual('object'); - expect(combine.params.length).toEqual(1); + expect(typeof combine.params).toBe('object'); + expect(combine.params.length).toBe(1); expect(combine.params[0].type).toBeUndefined(); - expect(combine.params[0].name).toEqual('...'); - expect(combine.params[0].description).toEqual('Two or more elements.'); + expect(combine.params[0].name).toBe('...'); + expect(combine.params[0].description).toBe('Two or more elements.'); }); it('When a symbol has an @param tag with name followed by a dash, the doclet has a params property that includes that param.', function() { - expect(typeof split.params).toEqual('object'); - expect(split.params.length).toEqual(1); + expect(typeof split.params).toBe('object'); + expect(split.params.length).toBe(1); expect(split.params[0].type).toBeUndefined(); - expect(split.params[0].name).toEqual('delimiter'); - expect(split.params[0].description).toEqual('What to split on.'); + expect(split.params[0].name).toBe('delimiter'); + expect(split.params[0].description).toBe('What to split on.'); }); it('When a symbol has an @param tag with no name or type, the doclet has a params property that includes that param.', function() { - expect(typeof commit.params).toEqual('object'); - expect(commit.params.length).toEqual(1); + expect(typeof commit.params).toBe('object'); + expect(commit.params.length).toBe(1); expect(commit.params[0].type).toBeUndefined(); - expect(commit.params[0].description).toEqual('If true make the commit atomic.'); + expect(commit.params[0].description).toBe('If true make the commit atomic.'); }); it('When a symbol has an @param tag with no name and a name is given in the code, the doclet has a params property that includes that param with the name from the code.', function() { - expect(commit.params[0].name).toEqual('atomic'); + expect(commit.params[0].name).toBe('atomic'); }); }); \ No newline at end of file diff --git a/test/specs/tags/privatetag.js b/test/specs/tags/privatetag.js index 6c7f71f2..a4d5aceb 100644 --- a/test/specs/tags/privatetag.js +++ b/test/specs/tags/privatetag.js @@ -4,6 +4,6 @@ describe("@private tag", function() { bar = docSet.getByLongname('Foo#bar')[0]; it('When a symbol has an @private tag, the doclet has an access property that is "private".', function() { - expect(foo.access).toEqual('private'); + expect(foo.access).toBe('private'); }); }); \ No newline at end of file diff --git a/test/specs/tags/propertytag.js b/test/specs/tags/propertytag.js index 374c64ed..5ef94231 100644 --- a/test/specs/tags/propertytag.js +++ b/test/specs/tags/propertytag.js @@ -3,13 +3,13 @@ describe("@property tag", function() { myobject = docSet.getByLongname('myobject')[0]; it('When a symbol has an @property tag with a those properties appear in the parsed object.', function() { - expect(typeof myobject.properties).toEqual('object'); - expect(myobject.properties.length).toEqual(3); - expect(myobject.properties[0].name).toEqual('defaults'); - expect(myobject.properties[1].name).toEqual('defaults.a'); - expect(myobject.properties[2].name).toEqual('defaults.b'); - expect(myobject.properties[0].description).toEqual('The default values.'); - expect(myobject.properties[0].type.names[0]).toEqual('Object'); + expect(typeof myobject.properties).toBe('object'); + expect(myobject.properties.length).toBe(3); + expect(myobject.properties[0].name).toBe('defaults'); + expect(myobject.properties[1].name).toBe('defaults.a'); + expect(myobject.properties[2].name).toBe('defaults.b'); + expect(myobject.properties[0].description).toBe('The default values.'); + expect(myobject.properties[0].type.names[0]).toBe('Object'); }); }); \ No newline at end of file diff --git a/test/specs/tags/readonlytag.js b/test/specs/tags/readonlytag.js index 403c984a..8465cb80 100644 --- a/test/specs/tags/readonlytag.js +++ b/test/specs/tags/readonlytag.js @@ -4,6 +4,6 @@ describe("@readonly tag", function() { length = docSet.getByLongname('Collection#length')[0]; it('When a symbol has an @readonly tag, the doclet has an readonly property that is true.', function() { - expect(length.readonly).toEqual(true); + expect(length.readonly).toBe(true); }); }); \ No newline at end of file diff --git a/test/specs/tags/requirestag.js b/test/specs/tags/requirestag.js index 662a8f8e..40eae164 100644 --- a/test/specs/tags/requirestag.js +++ b/test/specs/tags/requirestag.js @@ -4,11 +4,11 @@ describe("@requires tag", function() { bar = docSet.getByLongname('bar')[0]; it('When a symbol has an @requires tag, the doclet has a requires property that includes that value, with the "module:" namespace added.', function() { - expect(typeof foo.requires).toEqual('object'); - expect(foo.requires[0]).toEqual('module:foo/helper'); + expect(typeof foo.requires).toBe('object'); + expect(foo.requires[0]).toBe('module:foo/helper'); - expect(typeof bar.requires).toEqual('object'); - expect(bar.requires[0]).toEqual('module:foo'); - expect(bar.requires[1]).toEqual('module:Pez#blat'); + expect(typeof bar.requires).toBe('object'); + expect(bar.requires[0]).toBe('module:foo'); + expect(bar.requires[1]).toBe('module:Pez#blat'); }); }); \ No newline at end of file diff --git a/test/specs/tags/returnstag.js b/test/specs/tags/returnstag.js index a401ae48..f459b236 100644 --- a/test/specs/tags/returnstag.js +++ b/test/specs/tags/returnstag.js @@ -4,15 +4,15 @@ describe("@returns tag", function() { bind = docSet.getByLongname('bind')[0]; it('When a symbol has an @returns tag with a type and description, the doclet has a returns array that includes that return.', function() { - expect(typeof find.returns).toEqual('object'); - expect(find.returns.length).toEqual(1); - expect(find.returns[0].type.names.join(', ')).toEqual('String, Array'); - expect(find.returns[0].description).toEqual('The names of the found item(s).'); + expect(typeof find.returns).toBe('object'); + expect(find.returns.length).toBe(1); + expect(find.returns[0].type.names.join(', ')).toBe('String, Array'); + expect(find.returns[0].description).toBe('The names of the found item(s).'); }); it('When a symbol has an @returns tag with only a description, the doclet has a returns array property that includes that return.', function() { - expect(typeof bind.returns).toEqual('object'); - expect(bind.returns.length).toEqual(1); - expect(bind.returns[0].description).toEqual('The binding id.'); + expect(typeof bind.returns).toBe('object'); + expect(bind.returns.length).toBe(1); + expect(bind.returns[0].description).toBe('The binding id.'); }); }); diff --git a/test/specs/tags/seetag.js b/test/specs/tags/seetag.js index 96626a46..d6228a59 100644 --- a/test/specs/tags/seetag.js +++ b/test/specs/tags/seetag.js @@ -4,10 +4,10 @@ describe("@see tag", function() { bar = docSet.getByLongname('bar')[0]; it('When a symbol has an @see tag, the doclet has a see property that includes that value.', function() { - expect(typeof foo.see).toEqual('object'); - expect(foo.see[0]).toEqual('{@link bar}'); + expect(typeof foo.see).toBe('object'); + expect(foo.see[0]).toBe('{@link bar}'); - expect(typeof bar.see).toEqual('object'); - expect(bar.see[0]).toEqual('http://example.com/someref'); + expect(typeof bar.see).toBe('object'); + expect(bar.see[0]).toBe('http://example.com/someref'); }); }); \ No newline at end of file diff --git a/test/specs/tags/sincetag.js b/test/specs/tags/sincetag.js index 4e2228e7..91ab3d83 100644 --- a/test/specs/tags/sincetag.js +++ b/test/specs/tags/sincetag.js @@ -3,6 +3,6 @@ describe("@since tag", function() { foo = docSet.getByLongname('foo')[0]; it('When a symbol has an @since tag, the doclet has a since property set to true.', function() { - expect(foo.since).toEqual('1.2.3'); + expect(foo.since).toBe('1.2.3'); }); }); \ No newline at end of file diff --git a/test/specs/tags/thistag.js b/test/specs/tags/thistag.js index d02c57d4..5fac4ae6 100644 --- a/test/specs/tags/thistag.js +++ b/test/specs/tags/thistag.js @@ -4,13 +4,13 @@ describe("@this tag", function() { fooName = docSet.getByLongname('Foo#name')[0]; it('When a symbol has a @this tag, the doclet has a this property that is set to that value.', function() { - expect(setName['this']).toEqual('Foo'); + expect(setName['this']).toBe('Foo'); }); it('When a this symbol is documented inside a function with a @this tag, the symbol is documented as a member of that tags value.', function() { - expect(typeof fooName).toEqual('object'); - expect(fooName.name).toEqual('name'); - expect(fooName.memberof).toEqual('Foo'); - expect(fooName.scope).toEqual('instance'); + expect(typeof fooName).toBe('object'); + expect(fooName.name).toBe('name'); + expect(fooName.memberof).toBe('Foo'); + expect(fooName.scope).toBe('instance'); }); }); \ No newline at end of file diff --git a/test/specs/tags/typedeftag.js b/test/specs/tags/typedeftag.js index 193e972b..3ace0fa0 100644 --- a/test/specs/tags/typedeftag.js +++ b/test/specs/tags/typedeftag.js @@ -3,19 +3,19 @@ describe("@typedef tag", function() { numberlike = docSet.getByLongname('calc.NumberLike')[0]; it('When a symbol has an @typedef tag, the doclet has a kind property set to "typedef".', function() { - expect(numberlike.kind).toEqual('typedef'); + expect(numberlike.kind).toBe('typedef'); }); it('When a symbol has an @typedef tag with a type, the doclet has a type property set to that type.', function() { - expect(typeof numberlike.type).toEqual('object'); - expect(typeof numberlike.type.names).toEqual('object'); - expect(numberlike.type.names.length).toEqual(2); - expect(numberlike.type.names[0]).toEqual('string'); - expect(numberlike.type.names[1]).toEqual('number'); + expect(typeof numberlike.type).toBe('object'); + expect(typeof numberlike.type.names).toBe('object'); + expect(numberlike.type.names.length).toBe(2); + expect(numberlike.type.names[0]).toBe('string'); + expect(numberlike.type.names[1]).toBe('number'); }); it('When a symbol has an @typedef tag with a name, the doclet has a name property set to that name.', function() { - expect(numberlike.name).toEqual('NumberLike'); - expect(numberlike.longname).toEqual('calc.NumberLike'); + expect(numberlike.name).toBe('NumberLike'); + expect(numberlike.longname).toBe('calc.NumberLike'); }); }); \ No newline at end of file diff --git a/test/specs/tags/typekind.js b/test/specs/tags/typekind.js index 65fd8389..aea60db0 100644 --- a/test/specs/tags/typekind.js +++ b/test/specs/tags/typekind.js @@ -4,12 +4,12 @@ describe("@kind tag with type", function() { port = docSet.getByLongname('module:blog/server.port')[0]; it('When a module symbol has an kind tag, that includes a {type} clause, the doclet has a type property set to that {type} clause', function() { - expect(typeof blog.type).toEqual('object'); - expect(blog.type.names.join(', ')).toEqual('ConnectServer'); + expect(typeof blog.type).toBe('object'); + expect(blog.type.names.join(', ')).toBe('ConnectServer'); }); it('When a property symbol has an kind tag, that includes a {type} clause, the doclet has a type property set to that {type} clause', function() { - expect(typeof port.type).toEqual('object'); - expect(port.type.names.join(', ')).toEqual('number'); + expect(typeof port.type).toBe('object'); + expect(port.type.names.join(', ')).toBe('number'); }); }); \ No newline at end of file diff --git a/test/specs/tags/typetag.js b/test/specs/tags/typetag.js index 1bf7062d..eb48b9c7 100644 --- a/test/specs/tags/typetag.js +++ b/test/specs/tags/typetag.js @@ -4,12 +4,12 @@ describe("@type tag", function() { bar = docSet.getByLongname('bar')[0]; it('When a symbol has an @type tag, the doclet has a type property set to that value\'s type.', function() { - expect(typeof foo.type).toEqual('object'); - expect(typeof foo.type.names).toEqual('object'); - expect(foo.type.names.join(', ')).toEqual('string, Array'); + expect(typeof foo.type).toBe('object'); + expect(typeof foo.type.names).toBe('object'); + expect(foo.type.names.join(', ')).toBe('string, Array'); }); it('When a symbol has an @type tag set to a plain string, the doclet has a type property set to that string as if it were a type.', function() { - expect(bar.type.names.join(', ')).toEqual('integer'); + expect(bar.type.names.join(', ')).toBe('integer'); }); }); \ No newline at end of file diff --git a/test/specs/tags/versiontag.js b/test/specs/tags/versiontag.js index 0db924a2..1b50ada2 100644 --- a/test/specs/tags/versiontag.js +++ b/test/specs/tags/versiontag.js @@ -3,6 +3,6 @@ describe("@version tag", function() { foo = docSet.getByLongname('foo')[0]; it('When a symbol has an @version tag, the doclet has a version property set to that value.', function() { - expect(foo.version).toEqual('1.2.3'); + expect(foo.version).toBe('1.2.3'); }); }); \ No newline at end of file From cd1fb6c96a16ca90e6dff0123e201df9ff3dc0f4 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 12:52:06 +1000 Subject: [PATCH 13/40] @author tests - test that you can have multiple authors --- test/fixtures/authortag.js | 8 ++++++-- test/specs/tags/authortag.js | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/test/fixtures/authortag.js b/test/fixtures/authortag.js index 155bb570..3bba0f0f 100644 --- a/test/fixtures/authortag.js +++ b/test/fixtures/authortag.js @@ -2,5 +2,9 @@ @author Michael Mathews */ function Thingy() { - -} \ No newline at end of file +} + +/** @author John Doe + * @author Jane Doe */ +function Thingy2() { +} diff --git a/test/specs/tags/authortag.js b/test/specs/tags/authortag.js index 42ca0cc6..1a84b336 100644 --- a/test/specs/tags/authortag.js +++ b/test/specs/tags/authortag.js @@ -1,8 +1,18 @@ describe("@author tag", function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/authortag.js'), - Thingy = docSet.getByLongname('Thingy')[0]; + Thingy = docSet.getByLongname('Thingy')[0], + Thingy2 = docSet.getByLongname('Thingy2')[0]; it('When a symbol has a @author tag, the doclet has a author property with that value.', function() { + expect(Thingy.author).toBeDefined(); + expect(Array.isArray(Thingy.author)).toBe(true); expect(Thingy.author[0]).toBe('Michael Mathews '); }); -}); \ No newline at end of file + + it('When a symbol has multiple @author tags, the doclet has a author property, an array with those values.', function() { + expect(Thingy2.author).toBeDefined(); + expect(Array.isArray(Thingy2.author)).toBe(true); + expect(Thingy2.author).toContain('Jane Doe '); + expect(Thingy2.author).toContain('John Doe '); + }); +}); From e4c90b2fee908d4b1b75cc3dcb7809388c8c725a Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 12:52:33 +1000 Subject: [PATCH 14/40] @augments tests - add test that you can @augment multiple doclets --- test/fixtures/augmentstag3.js | 18 ++++++++++++++++++ test/specs/tags/augmentstag.js | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/augmentstag3.js diff --git a/test/fixtures/augmentstag3.js b/test/fixtures/augmentstag3.js new file mode 100644 index 00000000..80851817 --- /dev/null +++ b/test/fixtures/augmentstag3.js @@ -0,0 +1,18 @@ +// test to see that we can @augment multiple things (code allows for it) +/** @class */ +function Foo() { +} +/** A method. */ +Foo.prototype.method1 = function () {}; + +/** @class */ +function Bar() { +} +/** Another method. */ +Bar.prototype.method2 = function () {} + +/** @class + * @augments Foo + * @augments Bar */ +function FooBar() { +} diff --git a/test/specs/tags/augmentstag.js b/test/specs/tags/augmentstag.js index e03aae60..fabc2ee0 100644 --- a/test/specs/tags/augmentstag.js +++ b/test/specs/tags/augmentstag.js @@ -24,7 +24,13 @@ bazMethod3 = docSet.getByLongname('Baz#method3')[0], docSet2 = jasmine.getDocSetFromFile('test/fixtures/augmentstag2.js'), - qux = docSet2.getByLongname('Qux')[0]; + qux = docSet2.getByLongname('Qux')[0], + + docSet3 = jasmine.getDocSetFromFile('test/fixtures/augmentstag3.js'), + FooMethod1 = docSet3.getByLongname('Foo#method1')[0], + BarMethod2 = docSet3.getByLongname('Bar#method2')[0], + FooBarMethod1 = docSet3.getByLongname('FooBar#method1')[0], + FooBarMethod2 = docSet3.getByLongname('FooBar#method2')[0]; it('When a symbol has an @augments tag, the doclet has a augments property that includes that value.', function() { expect(typeof bar.augments).toBe('object'); @@ -82,4 +88,12 @@ expect(typeof qux.augments).toBe('object'); expect(qux.augments[0]).toBe('UndocumentedThing'); }); + + + it('When a symbol @augments multiple parents, it inherits methods from all parents', function() { + expect(FooBarMethod1).toBeDefined(); + expect(FooBarMethod2).toBeDefined(); + expect(FooBarMethod1.description).toBe(FooMethod1.description); + expect(FooBarMethod2.description).toBe(BarMethod2.description); + }); }); From 896f1bd90913a29b45d7fbd44dd26a5ded802d29 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 12:53:05 +1000 Subject: [PATCH 15/40] @alias tag - added test that doc.alias is populated (further tests already in documentation/alias.js) --- test/specs/tags/aliastag.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 test/specs/tags/aliastag.js diff --git a/test/specs/tags/aliastag.js b/test/specs/tags/aliastag.js new file mode 100644 index 00000000..7fea8ac1 --- /dev/null +++ b/test/specs/tags/aliastag.js @@ -0,0 +1,10 @@ +describe("@alias tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @name Foo\n@alias Bar */', {}); + + it("adds an 'alias' property to the doclet with the tag's value", function() { + expect(doc.alias).toBeDefined(); + expect(doc.alias).toBe('Bar'); + }); + // further tests (ensuring alias has the proper effect): documentation/alias.js +}); From 0e8e1664f75aa078b3f34b046913987fdd318a64 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 13:04:57 +1000 Subject: [PATCH 16/40] @mixes and @mixin tests added --- test/fixtures/mixintag.js | 27 +++++++++++++++++++++++++++ test/specs/tags/mixestag.js | 19 +++++++++++++++++++ test/specs/tags/mixintag.js | 13 +++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 test/fixtures/mixintag.js create mode 100644 test/specs/tags/mixestag.js create mode 100644 test/specs/tags/mixintag.js diff --git a/test/fixtures/mixintag.js b/test/fixtures/mixintag.js new file mode 100644 index 00000000..07dc085d --- /dev/null +++ b/test/fixtures/mixintag.js @@ -0,0 +1,27 @@ +/** + * This provides methods used for event handling. It's not meant to + * be used directly, except as a provider of related methods. + * + * @mixin + */ +var Eventful = { + /** fires something. */ + fires: function () {}, + /** handles a signal. */ + on: function () {} +}; + +/** + * @constructor + * @mixes Eventful + */ +var FormButton = function() { +}; + +/** @mixin AnotherMixin*/ + +/** I mix in multiple things + * @constructor MyClass + * @mixes Eventful + * @mixes AnotherMixin */ + diff --git a/test/specs/tags/mixestag.js b/test/specs/tags/mixestag.js new file mode 100644 index 00000000..6bb4f827 --- /dev/null +++ b/test/specs/tags/mixestag.js @@ -0,0 +1,19 @@ +describe("@mixes tag", function() { + var docSet = jasmine.getDocSetFromFile('test/fixtures/mixintag.js'), + FormButton = docSet.getByLongname('FormButton')[0], + MyClass = docSet.getByLongname('MyClass')[0]; + + it("When a symbol has a @mixes tag, it gets an array property 'mixes' with the name of the mixin", function() { + expect(FormButton.mixes).toBeDefined(); + expect(Array.isArray(FormButton.mixes)).toBe(true); + expect(FormButton.mixes.length).toBe(1); + expect(FormButton.mixes[0]).toBe('Eventful'); + }); + + it("A symbol can @mixes multiple mixins and they are all added.", function() { + expect(MyClass.mixes).toBeDefined(); + expect(MyClass.mixes.length).toBe(2); + expect(MyClass.mixes).toContain('Eventful'); + expect(MyClass.mixes).toContain('AnotherMixin'); + }); +}); diff --git a/test/specs/tags/mixintag.js b/test/specs/tags/mixintag.js new file mode 100644 index 00000000..4c928fb2 --- /dev/null +++ b/test/specs/tags/mixintag.js @@ -0,0 +1,13 @@ +describe("@mixin tag", function() { + var docSet = jasmine.getDocSetFromFile('test/fixtures/mixintag.js'), + Eventful = docSet.getByLongname('Eventful')[0], + Mixin = docSet.getByLongname('AnotherMixin')[0]; + + it("When a symbol has a @mixin tag, the doclet's 'kind' property is set to 'mixin'", function() { + expect(Eventful.kind).toBe('mixin'); + }); + + it("When a symbol has a @mixin tag, its name is set to the tag's value (if present)", function() { + expect(Mixin).toBeDefined(); + }); +}); From d869c99c3daf9ed52aabe2f241b2fd12634ef8d9 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 13:07:42 +1000 Subject: [PATCH 17/40] @classdesc: added test --- test/specs/tags/classdesctag.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 test/specs/tags/classdesctag.js diff --git a/test/specs/tags/classdesctag.js b/test/specs/tags/classdesctag.js new file mode 100644 index 00000000..6bac5852 --- /dev/null +++ b/test/specs/tags/classdesctag.js @@ -0,0 +1,7 @@ +describe("@classdesc tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** Asdf. @class Foo\n@classdesc A description of the class. */', {}); + it('adds a classdesc property to the doclet with the description', function() { + expect(doc.classdesc).toBe('A description of the class.'); + }); +}); From 4019e537f0bece72982dde042f92e358eb9265a7 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 13:16:28 +1000 Subject: [PATCH 18/40] @constant: added tests --- test/fixtures/constanttag.js | 6 ++++++ test/specs/tags/constanttag.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 test/fixtures/constanttag.js create mode 100644 test/specs/tags/constanttag.js diff --git a/test/fixtures/constanttag.js b/test/fixtures/constanttag.js new file mode 100644 index 00000000..a9f78058 --- /dev/null +++ b/test/fixtures/constanttag.js @@ -0,0 +1,6 @@ +/** @constant */ +var FOO = 1; + +/** @const BAR */ + +/** @const {string} BAZ */ diff --git a/test/specs/tags/constanttag.js b/test/specs/tags/constanttag.js new file mode 100644 index 00000000..e33ae980 --- /dev/null +++ b/test/specs/tags/constanttag.js @@ -0,0 +1,28 @@ +describe("@constant tag", function() { + var docSet = jasmine.getDocSetFromFile('test/fixtures/constanttag.js'), + FOO = docSet.getByLongname('FOO')[0], + BAR = docSet.getByLongname('BAR')[0], + BAZ = docSet.getByLongname('BAZ')[0]; + + it("sets the doclet's 'kind' property to 'constant'", function() { + expect(FOO.kind).toBe('constant'); + expect(BAR.kind).toBe('constant'); + expect(BAZ.kind).toBe('constant'); + }); + + it("If used as a standalone, takes the name from the code", function() { + expect(FOO.name).toBe('FOO'); + }); + + it("If used with just a name, sets the doclet's name to that", function() { + expect(BAR.name).toBe('BAR'); + }); + + it("If used with a name and a type, sets the doclet's name and type appropriately", function() { + expect(BAZ.name).toBe('BAZ'); + expect(typeof BAZ.type).toBe('object'); + expect(BAZ.type.names).toBeDefined(); + expect(BAZ.type.names.length).toBe(1); + expect(BAZ.type.names[0]).toBe('string'); + }); +}); From dc5e6f093386967d07b8ec5e0064b12ea416ea2c Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 13:21:02 +1000 Subject: [PATCH 19/40] @desc: added tests --- test/specs/tags/descriptiontag.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/specs/tags/descriptiontag.js diff --git a/test/specs/tags/descriptiontag.js b/test/specs/tags/descriptiontag.js new file mode 100644 index 00000000..4c004e75 --- /dev/null +++ b/test/specs/tags/descriptiontag.js @@ -0,0 +1,15 @@ +describe("@description tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** Blah Blah Blah\n @desc halb halb halb */', {}), + doc2 = new doclet.Doclet('/** @description lkjasdf */', {}); + + it("sets the doclet's 'description' property to the description", function() { + expect(doc2.description).toBeDefined(); + expect(doc2.description).toBe('lkjasdf'); + }); + + it("overrides the default description", function() { + expect(doc.description).toBeDefined(); + expect(doc.description).toBe('halb halb halb'); + }); +}); From 0422add48fa76f2bdd7bc7ccfd56be21430399d0 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 14:11:20 +1000 Subject: [PATCH 20/40] @example: added tests --- test/specs/tags/exampletag.js | 22 +++++++++++++++++++ test/specs/tags/exportstag.js | 40 +++++++++++++++++------------------ 2 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 test/specs/tags/exampletag.js diff --git a/test/specs/tags/exampletag.js b/test/specs/tags/exampletag.js new file mode 100644 index 00000000..01ce8214 --- /dev/null +++ b/test/specs/tags/exampletag.js @@ -0,0 +1,22 @@ +describe("@example tag", function() { + var doclet = require('jsdoc/doclet'), + txt = 'console.log("foo");\nconsole.log("bar");', + txt2 = '1 + 2;', + doc = new doclet.Doclet('/** @example\n' + txt + '*/', {}), + doc2 = new doclet.Doclet('/** @example\n' + txt + '\n@example\n' + txt2 + '*/', {}); + + it("creates an 'examples' property on the doclet with the example", function() { + expect(doc.examples).toBeDefined(); + expect(Array.isArray(doc.examples)).toBe(true); + expect(doc.examples.length).toBe(1); + expect(doc.examples).toContain(txt); + }); + + it("can be specified multiple times on one doclet", function() { + expect(doc2.examples).toBeDefined(); + expect(Array.isArray(doc2.examples)).toBe(true); + expect(doc2.examples.length).toBe(2); + expect(doc2.examples).toContain(txt); + expect(doc2.examples).toContain(txt2); + }); +}); diff --git a/test/specs/tags/exportstag.js b/test/specs/tags/exportstag.js index 9d11ad91..6d422754 100644 --- a/test/specs/tags/exportstag.js +++ b/test/specs/tags/exportstag.js @@ -8,24 +8,24 @@ describe("@exports tag", function() { size = docSet.getByLongname('module:my/shirt.Turtleneck#size')[0]; it('When an objlit symbol has an @exports tag, the doclet is aliased to "module:" + the tag value.', function() { - expect(typeof shirt).toBe('object'); - expect(shirt.alias).toBe('my/shirt'); + expect(typeof shirt).toEqual('object'); + expect(shirt.alias).toEqual('my/shirt'); }); it('When an objlit symbol has an @exports tag, the doclet\'s longname includes the "module:" namespace.', function() { - expect(shirt.longname).toBe('module:my/shirt'); + expect(shirt.longname).toEqual('module:my/shirt'); }); it('When an objlit symbol has an @exports tag, the doclet kind is set to module.', function() { - expect(shirt.kind).toBe('module'); + expect(shirt.kind).toEqual('module'); }); it('When an objlit symbol has an @exports tag, the objlit members are documented as members of the module.', function() { - expect(typeof color).toBe('object'); - expect(color.memberof).toBe('module:my/shirt'); + expect(typeof color).toEqual('object'); + expect(color.memberof).toEqual('module:my/shirt'); - expect(typeof tneck).toBe('object'); - expect(typeof size).toBe('object'); + expect(typeof tneck).toEqual('object'); + expect(typeof size).toEqual('object'); }); }); @@ -35,21 +35,21 @@ describe("@exports tag", function() { wool = docSet.getByLongname('module:my/coat#wool')[0]; it('When a function symbol has an @exports tag, the doclet is aliased to "module:" + the tag value.', function() { - expect(typeof coat).toBe('object'); - expect(coat.alias).toBe('my/coat'); + expect(typeof coat).toEqual('object'); + expect(coat.alias).toEqual('my/coat'); }); it('When a function symbol has an @exports tag, the doclet\'s longname includes the "module:" namespace.', function() { - expect(coat.longname).toBe('module:my/coat'); + expect(coat.longname).toEqual('module:my/coat'); }); it('When a function symbol has an @exports tag, the doclet kind is set to module.', function() { - expect(coat.kind).toBe('module'); + expect(coat.kind).toEqual('module'); }); it('When a function symbol has an @exports tag, the this members are documented as instance members of the module.', function() { - expect(typeof wool).toBe('object'); - expect(wool.memberof).toBe('module:my/coat'); + expect(typeof wool).toEqual('object'); + expect(wool.memberof).toEqual('module:my/coat'); }); }); @@ -60,13 +60,13 @@ describe("@exports tag", function() { inhead = docSet.getByLongname('module:html/utils.isInHead')[0]; it('When a function symbol has an @exports tag and there is an objlit named "exports" the members are documented as members of the module.', function() { - expect(typeof getstyle).toBe('object'); - expect(getstyle.memberof).toBe('module:html/utils'); + expect(typeof getstyle).toEqual('object'); + expect(getstyle.memberof).toEqual('module:html/utils'); }); it('When a function symbol has an @exports tag and there are members assinged to an "exports" name, the members are documented as members of the module.', function() { - expect(typeof inhead).toBe('object'); - expect(inhead.memberof).toBe('module:html/utils'); + expect(typeof inhead).toEqual('object'); + expect(inhead.memberof).toEqual('module:html/utils'); }); }); @@ -77,12 +77,12 @@ describe("@exports tag", function() { method = docSet.getByLongname('module:some/module~myClass#myMethod')[0]; it('An inner class declared as a function in a module should be documented.', function() { - expect(typeof innerClass).toBe('object'); + expect(typeof innerClass).toEqual('object'); //expect(getstyle.memberof, 'module:html/utils'); }); it('A method of an inner class declared as a function in a module should be documented.', function() { - expect(typeof method).toBe('object'); + expect(typeof method).toEqual('object'); //expect(inhead.memberof, 'module:html/utils'); }); }); From bdfac98755d84708ebfd8dc40d12e4b6cc1a2c5d Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 14:20:23 +1000 Subject: [PATCH 21/40] @function: added tests --- test/specs/tags/functiontag.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 test/specs/tags/functiontag.js diff --git a/test/specs/tags/functiontag.js b/test/specs/tags/functiontag.js new file mode 100644 index 00000000..ecd8e202 --- /dev/null +++ b/test/specs/tags/functiontag.js @@ -0,0 +1,18 @@ +describe("@function tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @func Foo */', {}), + doc2 = new doclet.Doclet('/** @method */', {}); + + it("sets the doclet's kind to 'function'", function() { + expect(doc.kind).toBe('function'); + expect(doc2.kind).toBe('function'); + }); + + it("sets the doclet's name to the tag value, if provided", function() { + expect(doc.name).toBe('Foo'); + expect(doc2.name).toBeFalsy(); + }); + + // parameter etc tests take place elsewhere: on its own, all @func does is + // set doclet.kind to function and sets the doclet's name. +}); From ff77157eb1192a9f1c6e7a39273fc2fd66c55b56 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 14:34:57 +1000 Subject: [PATCH 22/40] @inner, @instance, @static tests added --- test/specs/tags/scopetags.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/specs/tags/scopetags.js diff --git a/test/specs/tags/scopetags.js b/test/specs/tags/scopetags.js new file mode 100644 index 00000000..c91ba254 --- /dev/null +++ b/test/specs/tags/scopetags.js @@ -0,0 +1,30 @@ +// @inner, @instance, @static (@global has its own file) +describe("@inner tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @name Foo\n@scope inner */', {}); + + it("sets the doclet's 'scope' property to 'inner'", function() { + expect(doc.scope).toBeDefined(); + expect(doc.scope).toBe('inner'); + }); +}); + +describe("@instance tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @name Foo\n@scope instance */', {}); + + it("sets the doclet's 'scope' property to 'instance'", function() { + expect(doc.scope).toBeDefined(); + expect(doc.scope).toBe('instance'); + }); +}); + +describe("@static tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @name Foo\n@scope static */', {}); + + it("sets the doclet's 'scope' property to 'static'", function() { + expect(doc.scope).toBeDefined(); + expect(doc.scope).toBe('static'); + }); +}); From 0911c710fc46f436d784a6005f361c257fd34757 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 15:59:08 +1000 Subject: [PATCH 23/40] @kind: added test --- test/specs/tags/kindtag.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/specs/tags/kindtag.js diff --git a/test/specs/tags/kindtag.js b/test/specs/tags/kindtag.js new file mode 100644 index 00000000..f47cf4fb --- /dev/null +++ b/test/specs/tags/kindtag.js @@ -0,0 +1,8 @@ +describe("@kind tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @kind function */', {}); + it("sets the doclet's 'kind' property to the tag value", function() { + expect(doc.kind).toBeDefined(); + expect(doc.kind).toBe('function'); + }); +}); From b91796b3a49d5281250447101ccae02331c81c3a Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 15:59:21 +1000 Subject: [PATCH 24/40] @lends: added low-level tests --- test/specs/tags/lendstag.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/specs/tags/lendstag.js diff --git a/test/specs/tags/lendstag.js b/test/specs/tags/lendstag.js new file mode 100644 index 00000000..0f4a685d --- /dev/null +++ b/test/specs/tags/lendstag.js @@ -0,0 +1,16 @@ +describe("@lends tag", function() { + // see also specs/documentation/lends.js for tests on @lends behaviour. + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @lends */', {}), + doc2 = new doclet.Doclet('/** @lends MyClass# */', {}); + + it("sets the doclet's 'alias' property to the tag value or ", function() { + expect(doc.alias).toBe(''); + expect(doc2.alias).toBe('MyClass#'); + }); + + it("sets the doclet's 'undocumented' property to 'true'", function() { + expect(doc.undocumented).toBeTruthy(); + expect(doc2.undocumented).toBeTruthy(); + }); +}); From 93a8a591127355d46f1a0f7d4f40f67629d2edc6 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 15:59:28 +1000 Subject: [PATCH 25/40] @license: added tests --- test/specs/tags/licensetag.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/specs/tags/licensetag.js diff --git a/test/specs/tags/licensetag.js b/test/specs/tags/licensetag.js new file mode 100644 index 00000000..0944ae86 --- /dev/null +++ b/test/specs/tags/licensetag.js @@ -0,0 +1,8 @@ +describe("@license tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @license GPL v2 */', {}); + + it("sets the doclet's 'license' property to the tag value", function() { + expect(doc.license).toBe('GPL v2'); + }); +}); From c2707f102ec393bf1a354b627cdd5da97920e245 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 15:59:38 +1000 Subject: [PATCH 26/40] @member: added tests --- test/specs/tags/membertag.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/specs/tags/membertag.js diff --git a/test/specs/tags/membertag.js b/test/specs/tags/membertag.js new file mode 100644 index 00000000..8479d762 --- /dev/null +++ b/test/specs/tags/membertag.js @@ -0,0 +1,25 @@ +describe("@member tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @member */', {}), + doc2 = new doclet.Doclet('/** @var foobar */', {}), + doc3 = new doclet.Doclet('/** @var {string} baz */', {}); + + it("sets the doclet's 'kind' property to 'member'", function() { + expect(doc.kind).toBe('member'); + expect(doc2.kind).toBe('member'); + expect(doc3.kind).toBe('member'); + }); + + it("If specified with a name, sets the doclet's name property", function() { + expect(doc.name).toBeFalsy(); + expect(doc2.name).toBe('foobar'); + expect(doc3.name).toBe('baz'); + }); + + it("If specified with a type and name, sets the doclet's type appropriately", function() { + expect(doc3.type).toBeDefined(); + expect(Array.isArray(doc3.type.names)).toBeTruthy(); + expect(doc3.type.names.length).toBe(1); + expect(doc3.type.names[0]).toBe('string'); + }); +}); From f84e29363b843e1f7d5e721a3922b899d5c03a0d Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 15:59:44 +1000 Subject: [PATCH 27/40] @namespace: added tests --- test/specs/tags/namespacetag.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/specs/tags/namespacetag.js diff --git a/test/specs/tags/namespacetag.js b/test/specs/tags/namespacetag.js new file mode 100644 index 00000000..f8131b3c --- /dev/null +++ b/test/specs/tags/namespacetag.js @@ -0,0 +1,25 @@ +describe("@namespace tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @namespace */', {}), + doc2 = new doclet.Doclet('/** @namespace Foo */', {}), + doc3 = new doclet.Doclet('/** @namespace {function} Bar */', {}); + + it("sets the doclet's kind to 'namespace'", function () { + expect(doc.kind).toBe('namespace'); + expect(doc2.kind).toBe('namespace'); + expect(doc3.kind).toBe('namespace'); + }); + + it("sets the doclet's name to the tag value (if provided)", function() { + expect(doc.name).toBeFalsy(); + expect(doc2.name).toBe('Foo'); + expect(doc3.name).toBe('Bar'); + }); + + it("sets the doclet's type (if provided in @namespace)", function() { + expect(doc3.type).toBeDefined(); + expect(Array.isArray(doc3.type.names)).toBeTruthy(); + expect(doc3.type.names.length).toBe(1); + expect(doc3.type.names[0]).toBe('function'); + }); +}); From af05ac417a40b14c6c1b9c7ea150a05c9e504280 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 15:59:51 +1000 Subject: [PATCH 28/40] @summary: added tests --- test/specs/tags/summarytag.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/specs/tags/summarytag.js diff --git a/test/specs/tags/summarytag.js b/test/specs/tags/summarytag.js new file mode 100644 index 00000000..aa4d4147 --- /dev/null +++ b/test/specs/tags/summarytag.js @@ -0,0 +1,8 @@ +describe("@summary tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @summary I do not like green eggs and ham! */', {}); + it("sets the doclet's 'summary' property to the tag value", function() { + expect(doc.summary).toBe('I do not like green eggs and ham!'); + }); +}); + From 3fb96af55b634cc9f94627de173fe8c4ee16534d Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 16:00:01 +1000 Subject: [PATCH 29/40] @todo: added tests --- test/specs/tags/todotag.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/specs/tags/todotag.js diff --git a/test/specs/tags/todotag.js b/test/specs/tags/todotag.js new file mode 100644 index 00000000..807c76be --- /dev/null +++ b/test/specs/tags/todotag.js @@ -0,0 +1,13 @@ +describe("@todo tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @todo something\n@todo something else */', {}); + + it("adds the entries into a 'todo' array on the doclet", function() { + expect(doc.todo).toBeDefined(); + expect(Array.isArray(doc.todo)).toBeTruthy(); + expect(doc.todo.length).toBe(2); + + expect(doc.todo).toContain('something'); + expect(doc.todo).toContain('something else'); + }); +}); From cdc8a1c2249cdd844d45c7787e0f0f53ea98ae67 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 16:00:08 +1000 Subject: [PATCH 30/40] @tutorial: added low-level tests --- test/specs/tags/tutorialtag.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/specs/tags/tutorialtag.js diff --git a/test/specs/tags/tutorialtag.js b/test/specs/tags/tutorialtag.js new file mode 100644 index 00000000..ea345ccd --- /dev/null +++ b/test/specs/tags/tutorialtag.js @@ -0,0 +1,13 @@ +describe("@tutorial tag", function() { + // these are tests for the block usage, not the inline usage. see util/templateHelper for that. + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** @tutorial tute1\n@tutorial tute2 */', {}); + + it("adds the listed tutorials to a 'tutorials' array on the doclet", function () { + expect(Array.isArray(doc.tutorials)).toBeTruthy(); + expect(doc.tutorials.length).toBe(2); + expect(doc.tutorials).toContain('tute1'); + expect(doc.tutorials).toContain('tute2'); + }); +}); + From e7f3609e54c3c155827288a3bd9084f6304905b2 Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 15 Feb 2013 16:00:18 +1000 Subject: [PATCH 31/40] @undocumented: added tests --- test/specs/tags/undocumentedtag.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/specs/tags/undocumentedtag.js diff --git a/test/specs/tags/undocumentedtag.js b/test/specs/tags/undocumentedtag.js new file mode 100644 index 00000000..5dc85b56 --- /dev/null +++ b/test/specs/tags/undocumentedtag.js @@ -0,0 +1,13 @@ +describe("@undocumented tag", function() { + var doclet = require('jsdoc/doclet'), + doc = new doclet.Doclet('/** Foo bar\n@undocumented */', {}); + + it("sets the doclet's 'undocumented' property to true", function () { + expect(doc.undocumented).toBeTruthy(); + }); + + it("clears the doclet's 'comment' property", function () { + expect(doc.comment).toBe(''); + }); +}); + From f16fa3beb75499b7266946fe3d1ef212ec34f83d Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Fri, 15 Feb 2013 21:17:40 -0800 Subject: [PATCH 32/40] use a 'range' property in parser events rather than 'linelength' and 'absposition' (#346) --- lib/jsdoc/src/parser.js | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/lib/jsdoc/src/parser.js b/lib/jsdoc/src/parser.js index 9e205655..f08821fd 100644 --- a/lib/jsdoc/src/parser.js +++ b/lib/jsdoc/src/parser.js @@ -300,6 +300,20 @@ function getBasename(name) { return name; } +/** @private + * @memberof module:src/parser.Parser + * @param {object} node + * @return {Array.} Start and end lines. + */ +function getRange(node) { + var range = []; + + range[0] = parseInt(String(node.getAbsolutePosition()), 10); + range[1] = range[0] + parseInt(String(node.getLength()), 10); + + return range; +} + /** @private * @memberof module:src/parser.Parser */ @@ -312,17 +326,7 @@ exports.Parser.prototype._makeEvent = function(node, extras) { id: extras.id || 'astnode' + node.hashCode(), comment: extras.comment || String(node.getJsDoc() || '@undocumented'), lineno: extras.lineno || node.left.getLineno(), - range: (function() { - var range = []; - if (extras.range) { - range = extras.range; - } - else { - range[0] = parseInt(String(node.getAbsolutePosition()), 10); - range[1] = range[0] + parseInt(String(node.getLength()), 10); - } - return range; - })(), + range: extras.range || getRange(node), filename: extras.filename || this._currentSourceName, astnode: extras.astnode || node, code: extras.code || aboutNode(node), @@ -388,8 +392,7 @@ exports.Parser.prototype._visitNode = function(node) { comment: commentSrc, lineno: comment.getLineno(), filename: this._currentSourceName, - linelength: comment.getLength(), - absposition: comment.getAbsolutePosition() + range: getRange(comment) }; this.emit('jsdocCommentFound', e, this); @@ -432,9 +435,7 @@ exports.Parser.prototype._visitNode = function(node) { } extras = { - lineno: node.getLineno(), - linelength: node.getLength(), - absposition: node.getAbsolutePosition() + lineno: node.getLineno() }; e = this._makeEvent(node, extras); @@ -442,9 +443,7 @@ exports.Parser.prototype._visitNode = function(node) { } else if (node.type == Token.FUNCTION || node.type == tkn.NAMEDFUNCTIONSTATEMENT) { extras = { - lineno: node.getLineno(), - linelength: node.getLength(), - absposition: node.getAbsolutePosition() + lineno: node.getLineno() }; e = this._makeEvent(node, extras); From e553dad941ec2a6c9986546d9098f10f35799880 Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Fri, 15 Feb 2013 21:32:57 -0800 Subject: [PATCH 33/40] add `@emits` as a synonym for `@fires` (#324) --- lib/jsdoc/tag/dictionary/definitions.js | 3 ++- test/fixtures/eventfirestag.js | 12 +++++++++++ test/specs/tags/eventfirestag.js | 27 ++++++++++++++++--------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/jsdoc/tag/dictionary/definitions.js b/lib/jsdoc/tag/dictionary/definitions.js index db3ca55f..59a66113 100644 --- a/lib/jsdoc/tag/dictionary/definitions.js +++ b/lib/jsdoc/tag/dictionary/definitions.js @@ -349,7 +349,8 @@ exports.defineTags = function(dictionary) { applyNamespace('event', tag); doclet.fires.push(tag.value); } - }); + }) + .synonym('emits'); dictionary.defineTag('function', { onTagged: function(doclet, tag) { diff --git a/test/fixtures/eventfirestag.js b/test/fixtures/eventfirestag.js index 4fe3e746..331eaf8c 100644 --- a/test/fixtures/eventfirestag.js +++ b/test/fixtures/eventfirestag.js @@ -16,3 +16,15 @@ Hurl.prototype.snowball = function () { */ this.emit('snowball', {}); }; + +/** + * Throw a football match. + * + * @emits Hurl#footballMatch + */ +Hurl.prototype.footballMatch = function () { + /** + * @event Hurl#footballMatch + */ + this.emit('footballMatch', {}); +}; diff --git a/test/specs/tags/eventfirestag.js b/test/specs/tags/eventfirestag.js index 13b37402..55d86f4a 100644 --- a/test/specs/tags/eventfirestag.js +++ b/test/specs/tags/eventfirestag.js @@ -1,23 +1,30 @@ -describe("@event and @fires tags", function() { +/*global describe: true, expect: true, it: true, jasmine: true */ +describe('@event and @fires/@emits tags', function() { var docSet = jasmine.getDocSetFromFile('test/fixtures/eventfirestag.js'), snowballMethod = docSet.getByLongname('Hurl#snowball')[0], - snowballEvent = docSet.getByLongname('Hurl#event:snowball')[0]; + snowballEvent = docSet.getByLongname('Hurl#event:snowball')[0], + footballMatchMethod = docSet.getByLongname('Hurl#footballMatch')[0]; // @event tag it('When a symbol has an @event tag, the doclet is of kind "event".', function() { - expect(snowballEvent.kind).toEqual('event'); + expect(snowballEvent.kind).toBe('event'); }); - // @fires tag + // @fires/@emits tag it('When a symbol has a @fires tag, the doclet has an array named "fires".', function() { - expect(typeof snowballMethod.fires).toEqual('object'); + expect(typeof snowballMethod.fires).toBe('object'); }); - it('When a symbol has a fires array, the members have the event namespace.', function() { - expect(snowballMethod.fires[0]).toEqual('Hurl#event:snowball'); + it('When a symbol has an @emits tag, the doclet has an array named "fires".', function() { + expect(typeof footballMatchMethod.fires).toBe('object'); }); - it('When a symbol has a fires array with a name that already has an event: namespace, it doesn\'t have a secong namespace applied.', function() { - expect(snowballMethod.fires[1]).toEqual('Hurl#event:brick'); + it('When a symbol has a "fires" array, the members have the "event:" namespace.', function() { + expect(snowballMethod.fires[0]).toBe('Hurl#event:snowball'); }); -}); \ No newline at end of file + + it('When a symbol has a "fires" array with a name that already has an "event:" namespace, ' + + 'it does not have a second namespace applied.', function() { + expect(snowballMethod.fires[1]).toBe('Hurl#event:brick'); + }); +}); From ef9660119f88695455ed302a333f928e47d39fda Mon Sep 17 00:00:00 2001 From: Gergely Aradszki Date: Sun, 17 Feb 2013 14:54:09 +0100 Subject: [PATCH 34/40] Merge source includes with command line arguments *before* checking for README.md and package.json. Allows to set these in configs source.includes. --- jsdoc.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jsdoc.js b/jsdoc.js index 553297e1..480b3f88 100644 --- a/jsdoc.js +++ b/jsdoc.js @@ -179,6 +179,10 @@ function main() { if (env.conf.plugins) { plugins.installPlugins(env.conf.plugins, app.jsdoc.parser); } + + if (env.conf.source && env.conf.source.include) { + env.opts._ = (env.opts._ || []).concat(env.conf.source.include); + } // any source file named package.json or README.md is treated special for (i = 0, l = env.opts._.length; i < l; i++ ) { @@ -193,10 +197,6 @@ function main() { } } - if (env.conf.source && env.conf.source.include) { - env.opts._ = (env.opts._ || []).concat(env.conf.source.include); - } - if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse? filter = new Filter(env.conf.source); From 9d13a1e6bbf8d583d60ce41fa3a8e7e8658e93ec Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Mon, 18 Feb 2013 21:30:17 -0800 Subject: [PATCH 35/40] allow JSDoc to run from a path containing one or more spaces (#347) --- lib/jsdoc/util/vm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jsdoc/util/vm.js b/lib/jsdoc/util/vm.js index 61279b14..eb7048b1 100644 --- a/lib/jsdoc/util/vm.js +++ b/lib/jsdoc/util/vm.js @@ -58,7 +58,7 @@ var vm = exports.vm = (function() { * @return {object} An object containing VM-specific functions for the requested module. */ exports.getModule = function(modulePath) { - modulePath = [__dirname, vm, modulePath].join('/'); + modulePath = [__dirname, vm, modulePath].join('/').replace(/ /g, '%20'); if (os.platform() === 'win32') { modulePath = pathToUri(modulePath); } From dfe917a35a78e3e7cebdca8e6cae3ae5b59a7c61 Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Tue, 19 Feb 2013 07:02:08 -0800 Subject: [PATCH 36/40] generate human-readable filenames (#339) --- lib/jsdoc/util/templateHelper.js | 25 +++++++++++++++---------- test/specs/jsdoc/util/templateHelper.js | 10 ++++++---- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/jsdoc/util/templateHelper.js b/lib/jsdoc/util/templateHelper.js index 94867bc4..ef036c1a 100644 --- a/lib/jsdoc/util/templateHelper.js +++ b/lib/jsdoc/util/templateHelper.js @@ -3,7 +3,6 @@ * @module jsdoc/util/templateHelper */ -var crypto = require('crypto'); var dictionary = require('jsdoc/tag/dictionary'); var util = require('util'); @@ -14,7 +13,6 @@ var files = {}; // each container gets its own html file var containers = ['class', 'module', 'external', 'namespace', 'mixin']; -/** @external {jsdoc.tutorial.Tutorial} */ var tutorials; /** Sets tutorials map. @@ -68,18 +66,25 @@ var nsprefix = /^(event|module|external):/; * @return {string} The filename to use for the string. */ var getUniqueFilename = exports.getUniqueFilename = function(str) { - var result; - // allow for namespace prefix - var basename = str.replace(nsprefix, '$1-'); + var basename = str.replace(nsprefix, '$1-') + // and use - instead of ~ to denote 'inner' + .replace(/~/g, '-'); - if ( /[^$a-z0-9._\-]/i.test(basename) ) { - result = crypto.createHash('sha1').update(str).digest('hex').substr(0, 10); - } else { - result = makeFilenameUnique(basename, str); + // if the basename includes characters that we can't use in a filepath, remove everything up to + // and including the last bad character + var regexp = /[^$a-z0-9._\-](?=[$a-z0-9._\-]*$)/i; + var result = regexp.exec(basename); + if (result && result.index) { + basename = basename.substr(result.index + 1); } - return result + exports.fileExtension; + // make sure we don't create hidden files on POSIX systems + basename = basename.replace(/^\./, ''); + // and in case we've now stripped the entire basename (uncommon, but possible): + basename = basename.length ? basename : '_'; + + return makeFilenameUnique(basename, str) + exports.fileExtension; }; // two-way lookup diff --git a/test/specs/jsdoc/util/templateHelper.js b/test/specs/jsdoc/util/templateHelper.js index 41ee1c15..54bd9a55 100644 --- a/test/specs/jsdoc/util/templateHelper.js +++ b/test/specs/jsdoc/util/templateHelper.js @@ -140,14 +140,16 @@ describe("jsdoc/util/templateHelper", function() { // disabled because Jasmine appears to execute this code twice, which causes getUniqueFilename // to return an unexpected variation on the name the second time xdescribe("getUniqueFilename", function() { + // TODO: needs more tests for unusual values and things that get special treatment (such as + // inner members) it('should convert a simple string into the string plus the default extension', function() { var filename = helper.getUniqueFilename('BackusNaur'); expect(filename).toEqual('BackusNaur.html'); }); - it('should convert a string with slashes into an alphanumeric hash plus the default extension', function() { + it('should convert a string with slashes into the text following the last slash plus the default extension', function() { var filename = helper.getUniqueFilename('tick/tock'); - expect(filename).toMatch(/^[A-Za-z0-9]+\.html$/); + expect(filename).toMatch(/^tock\.html$/); }); it('should not return the same filename twice', function() { @@ -743,7 +745,7 @@ describe("jsdoc/util/templateHelper", function() { expect(newUrl).toEqual(nestedNamespaceUrl); }); - it('should create a url for a name with invalid characters using a digest.', function() { + it('should create a url for a name with invalid characters.', function() { var mockDoclet = { kind: 'function', longname: 'ns1."!"."*foo"', @@ -752,7 +754,7 @@ describe("jsdoc/util/templateHelper", function() { }, url = helper.createLink(mockDoclet); - expect(url).toEqual('be9d9563a3.html#"*foo"'); + expect(url).toEqual('_.html#"*foo"'); }); }); }); From 32fe768ea7cae5ea34b198e67b4e0acaf8b4d78d Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 22 Feb 2013 12:45:04 +1000 Subject: [PATCH 37/40] 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 38/40] 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 39/40] 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'); From bbf6f51f77955b1692379770adabb9fab1a28c9d Mon Sep 17 00:00:00 2001 From: mathematicalcoffee Date: Fri, 22 Feb 2013 14:47:34 +1000 Subject: [PATCH 40/40] Moved inline doclet definition to external fixtures --- test/fixtures/classdesctag.js | 7 ++++ test/fixtures/descriptiontag.js | 7 ++++ test/fixtures/exampletag.js | 14 ++++++++ test/fixtures/functiontag.js | 7 ++++ test/fixtures/kindtag.js | 2 ++ test/fixtures/licensetag.js | 2 ++ test/fixtures/membertag.js | 5 +++ test/fixtures/namespacetag.js | 5 +++ test/fixtures/scopetags.js | 10 ++++++ test/fixtures/summarytag.js | 3 ++ test/fixtures/todotag.js | 6 ++++ test/fixtures/tutorialtag.js | 5 +++ test/fixtures/undocumentedtag.js | 3 ++ test/specs/tags/aliastag.js | 9 ++--- test/specs/tags/classdesctag.js | 5 +-- test/specs/tags/descriptiontag.js | 6 ++-- test/specs/tags/exampletag.js | 8 ++--- test/specs/tags/functiontag.js | 8 ++--- test/specs/tags/kindtag.js | 4 +-- test/specs/tags/licensetag.js | 4 +-- test/specs/tags/membertag.js | 10 +++--- test/specs/tags/namespacetag.js | 10 +++--- test/specs/tags/scopetags.js | 55 +++++++++++++++--------------- test/specs/tags/summarytag.js | 4 +-- test/specs/tags/todotag.js | 4 +-- test/specs/tags/tutorialtag.js | 4 +-- test/specs/tags/undocumentedtag.js | 4 +-- 27 files changed, 145 insertions(+), 66 deletions(-) create mode 100644 test/fixtures/classdesctag.js create mode 100644 test/fixtures/descriptiontag.js create mode 100644 test/fixtures/exampletag.js create mode 100644 test/fixtures/functiontag.js create mode 100644 test/fixtures/kindtag.js create mode 100644 test/fixtures/licensetag.js create mode 100644 test/fixtures/membertag.js create mode 100644 test/fixtures/namespacetag.js create mode 100644 test/fixtures/scopetags.js create mode 100644 test/fixtures/summarytag.js create mode 100644 test/fixtures/todotag.js create mode 100644 test/fixtures/tutorialtag.js create mode 100644 test/fixtures/undocumentedtag.js diff --git a/test/fixtures/classdesctag.js b/test/fixtures/classdesctag.js new file mode 100644 index 00000000..707a79e6 --- /dev/null +++ b/test/fixtures/classdesctag.js @@ -0,0 +1,7 @@ +/** + * Asdf. + * @class + * @classdesc A description of the class. + */ +function Foo () { +} diff --git a/test/fixtures/descriptiontag.js b/test/fixtures/descriptiontag.js new file mode 100644 index 00000000..78d9d05a --- /dev/null +++ b/test/fixtures/descriptiontag.js @@ -0,0 +1,7 @@ +/** Blah Blah Blah + * @desc halb halb halb + */ +var x; + +/** @description lkjasdf */ +var y; diff --git a/test/fixtures/exampletag.js b/test/fixtures/exampletag.js new file mode 100644 index 00000000..b20f7530 --- /dev/null +++ b/test/fixtures/exampletag.js @@ -0,0 +1,14 @@ +/** @example + * console.log("foo"); + * console.log("bar"); + */ +var x; + +/** @example + * console.log("foo"); + * console.log("bar"); + * @example + * Example 2 + * 1 + 2; + */ +var y; diff --git a/test/fixtures/functiontag.js b/test/fixtures/functiontag.js new file mode 100644 index 00000000..9783268f --- /dev/null +++ b/test/fixtures/functiontag.js @@ -0,0 +1,7 @@ +/** @func Foo */ +function Foo() { +} + +/** @method */ +function Bar() { +} diff --git a/test/fixtures/kindtag.js b/test/fixtures/kindtag.js new file mode 100644 index 00000000..72c5682f --- /dev/null +++ b/test/fixtures/kindtag.js @@ -0,0 +1,2 @@ +/** @kind function */ +var x; diff --git a/test/fixtures/licensetag.js b/test/fixtures/licensetag.js new file mode 100644 index 00000000..e9d852f5 --- /dev/null +++ b/test/fixtures/licensetag.js @@ -0,0 +1,2 @@ +/** @license GPL v2 */ +var x; diff --git a/test/fixtures/membertag.js b/test/fixtures/membertag.js new file mode 100644 index 00000000..66aee08d --- /dev/null +++ b/test/fixtures/membertag.js @@ -0,0 +1,5 @@ +/** @member */ +var x; + +/** @var foobar */ +/** @var {string} baz */ diff --git a/test/fixtures/namespacetag.js b/test/fixtures/namespacetag.js new file mode 100644 index 00000000..82dc1081 --- /dev/null +++ b/test/fixtures/namespacetag.js @@ -0,0 +1,5 @@ +/** @namespace */ +var x = { +}; +/** @namespace Foo */ +/** @namespace {function} Bar */ diff --git a/test/fixtures/scopetags.js b/test/fixtures/scopetags.js new file mode 100644 index 00000000..1eeeb204 --- /dev/null +++ b/test/fixtures/scopetags.js @@ -0,0 +1,10 @@ +/** (scope tags for global objects do not override globalness hence need a container class) + * @module scopetags */ +/** @inner */ +var myInner; + +/** @instance */ +var myInstance; + +/** @static */ +var myStatic; diff --git a/test/fixtures/summarytag.js b/test/fixtures/summarytag.js new file mode 100644 index 00000000..b1f4c496 --- /dev/null +++ b/test/fixtures/summarytag.js @@ -0,0 +1,3 @@ +/** @summary I do not like green eggs and ham! */ +function Sam() { +} diff --git a/test/fixtures/todotag.js b/test/fixtures/todotag.js new file mode 100644 index 00000000..5ecfac4b --- /dev/null +++ b/test/fixtures/todotag.js @@ -0,0 +1,6 @@ +/** A function. + * @todo something + * @todo something else + */ +function x() { +} diff --git a/test/fixtures/tutorialtag.js b/test/fixtures/tutorialtag.js new file mode 100644 index 00000000..b0124dbe --- /dev/null +++ b/test/fixtures/tutorialtag.js @@ -0,0 +1,5 @@ +/** Some documentation. + * @tutorial tute1 + * @tutorial tute2 + */ +var x; diff --git a/test/fixtures/undocumentedtag.js b/test/fixtures/undocumentedtag.js new file mode 100644 index 00000000..01ab4fc3 --- /dev/null +++ b/test/fixtures/undocumentedtag.js @@ -0,0 +1,3 @@ +/** Undocumented doclet. + * @undocumented */ +var x; diff --git a/test/specs/tags/aliastag.js b/test/specs/tags/aliastag.js index 7fea8ac1..4b2396ef 100644 --- a/test/specs/tags/aliastag.js +++ b/test/specs/tags/aliastag.js @@ -1,10 +1,11 @@ describe("@alias tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @name Foo\n@alias Bar */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/alias.js'), + // there are two doclets with longname myObject, we want the second one + myObject = docSet.getByLongname('myObject')[1]; it("adds an 'alias' property to the doclet with the tag's value", function() { - expect(doc.alias).toBeDefined(); - expect(doc.alias).toBe('Bar'); + expect(myObject.alias).toBeDefined(); + expect(myObject.alias).toBe('myObject'); }); // further tests (ensuring alias has the proper effect): documentation/alias.js }); diff --git a/test/specs/tags/classdesctag.js b/test/specs/tags/classdesctag.js index 6bac5852..2a369cf1 100644 --- a/test/specs/tags/classdesctag.js +++ b/test/specs/tags/classdesctag.js @@ -1,6 +1,7 @@ describe("@classdesc tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** Asdf. @class Foo\n@classdesc A description of the class. */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/classdesctag.js'), + doc = docSet.getByLongname('Foo')[0]; + it('adds a classdesc property to the doclet with the description', function() { expect(doc.classdesc).toBe('A description of the class.'); }); diff --git a/test/specs/tags/descriptiontag.js b/test/specs/tags/descriptiontag.js index 4c004e75..855280dc 100644 --- a/test/specs/tags/descriptiontag.js +++ b/test/specs/tags/descriptiontag.js @@ -1,7 +1,7 @@ describe("@description tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** Blah Blah Blah\n @desc halb halb halb */', {}), - doc2 = new doclet.Doclet('/** @description lkjasdf */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/descriptiontag.js'), + doc = docSet.getByLongname('x')[0], + doc2 = docSet.getByLongname('y')[0]; it("sets the doclet's 'description' property to the description", function() { expect(doc2.description).toBeDefined(); diff --git a/test/specs/tags/exampletag.js b/test/specs/tags/exampletag.js index 01ce8214..8d1673c6 100644 --- a/test/specs/tags/exampletag.js +++ b/test/specs/tags/exampletag.js @@ -1,9 +1,9 @@ describe("@example tag", function() { - var doclet = require('jsdoc/doclet'), + var docSet = jasmine.getDocSetFromFile('test/fixtures/exampletag.js'), + doc = docSet.getByLongname('x')[0], + doc2 = docSet.getByLongname('y')[0], txt = 'console.log("foo");\nconsole.log("bar");', - txt2 = '1 + 2;', - doc = new doclet.Doclet('/** @example\n' + txt + '*/', {}), - doc2 = new doclet.Doclet('/** @example\n' + txt + '\n@example\n' + txt2 + '*/', {}); + txt2 = 'Example 2\n1 + 2;'; it("creates an 'examples' property on the doclet with the example", function() { expect(doc.examples).toBeDefined(); diff --git a/test/specs/tags/functiontag.js b/test/specs/tags/functiontag.js index ecd8e202..df63f6b9 100644 --- a/test/specs/tags/functiontag.js +++ b/test/specs/tags/functiontag.js @@ -1,7 +1,7 @@ describe("@function tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @func Foo */', {}), - doc2 = new doclet.Doclet('/** @method */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/functiontag.js'), + doc = docSet.getByLongname('Foo')[0], + doc2 = docSet.getByLongname('Bar')[0]; it("sets the doclet's kind to 'function'", function() { expect(doc.kind).toBe('function'); @@ -10,7 +10,7 @@ describe("@function tag", function() { it("sets the doclet's name to the tag value, if provided", function() { expect(doc.name).toBe('Foo'); - expect(doc2.name).toBeFalsy(); + expect(doc2.name).toBe('Bar'); }); // parameter etc tests take place elsewhere: on its own, all @func does is diff --git a/test/specs/tags/kindtag.js b/test/specs/tags/kindtag.js index f47cf4fb..49d9cd5d 100644 --- a/test/specs/tags/kindtag.js +++ b/test/specs/tags/kindtag.js @@ -1,6 +1,6 @@ describe("@kind tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @kind function */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/kindtag.js'), + doc = docSet.getByLongname('x')[0]; it("sets the doclet's 'kind' property to the tag value", function() { expect(doc.kind).toBeDefined(); expect(doc.kind).toBe('function'); diff --git a/test/specs/tags/licensetag.js b/test/specs/tags/licensetag.js index 0944ae86..e37b1c63 100644 --- a/test/specs/tags/licensetag.js +++ b/test/specs/tags/licensetag.js @@ -1,6 +1,6 @@ describe("@license tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @license GPL v2 */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/licensetag.js'), + doc = docSet.getByLongname('x')[0]; it("sets the doclet's 'license' property to the tag value", function() { expect(doc.license).toBe('GPL v2'); diff --git a/test/specs/tags/membertag.js b/test/specs/tags/membertag.js index 8479d762..cfea6de3 100644 --- a/test/specs/tags/membertag.js +++ b/test/specs/tags/membertag.js @@ -1,8 +1,8 @@ describe("@member tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @member */', {}), - doc2 = new doclet.Doclet('/** @var foobar */', {}), - doc3 = new doclet.Doclet('/** @var {string} baz */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/membertag.js'), + doc = docSet.getByLongname('x')[0], + doc2 = docSet.getByLongname('foobar')[0], + doc3 = docSet.getByLongname('baz')[0]; it("sets the doclet's 'kind' property to 'member'", function() { expect(doc.kind).toBe('member'); @@ -11,7 +11,7 @@ describe("@member tag", function() { }); it("If specified with a name, sets the doclet's name property", function() { - expect(doc.name).toBeFalsy(); + expect(doc.name).toBe('x'); expect(doc2.name).toBe('foobar'); expect(doc3.name).toBe('baz'); }); diff --git a/test/specs/tags/namespacetag.js b/test/specs/tags/namespacetag.js index f8131b3c..182ce0f3 100644 --- a/test/specs/tags/namespacetag.js +++ b/test/specs/tags/namespacetag.js @@ -1,8 +1,8 @@ describe("@namespace tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @namespace */', {}), - doc2 = new doclet.Doclet('/** @namespace Foo */', {}), - doc3 = new doclet.Doclet('/** @namespace {function} Bar */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/namespacetag.js'), + doc = docSet.getByLongname('x')[0], + doc2 = docSet.getByLongname('Foo')[0], + doc3 = docSet.getByLongname('Bar')[0]; it("sets the doclet's kind to 'namespace'", function () { expect(doc.kind).toBe('namespace'); @@ -11,7 +11,7 @@ describe("@namespace tag", function() { }); it("sets the doclet's name to the tag value (if provided)", function() { - expect(doc.name).toBeFalsy(); + expect(doc.name).toBe('x'); expect(doc2.name).toBe('Foo'); expect(doc3.name).toBe('Bar'); }); diff --git a/test/specs/tags/scopetags.js b/test/specs/tags/scopetags.js index c91ba254..0b18a58c 100644 --- a/test/specs/tags/scopetags.js +++ b/test/specs/tags/scopetags.js @@ -1,30 +1,31 @@ -// @inner, @instance, @static (@global has its own file) -describe("@inner tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @name Foo\n@scope inner */', {}); +describe('scope tags', function () { + var docSet = jasmine.getDocSetFromFile('test/fixtures/scopetags.js'); - it("sets the doclet's 'scope' property to 'inner'", function() { - expect(doc.scope).toBeDefined(); - expect(doc.scope).toBe('inner'); - }); -}); - -describe("@instance tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @name Foo\n@scope instance */', {}); - - it("sets the doclet's 'scope' property to 'instance'", function() { - expect(doc.scope).toBeDefined(); - expect(doc.scope).toBe('instance'); - }); -}); - -describe("@static tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @name Foo\n@scope static */', {}); - - it("sets the doclet's 'scope' property to 'static'", function() { - expect(doc.scope).toBeDefined(); - expect(doc.scope).toBe('static'); + // @inner, @instance, @static (@global has its own file) + describe("@inner tag", function() { + var doc = docSet.getByLongname('module:scopetags~myInner')[0]; + + it("sets the doclet's 'scope' property to 'inner'", function() { + expect(doc.scope).toBeDefined(); + expect(doc.scope).toBe('inner'); + }); + }); + + describe("@instance tag", function() { + var doc = docSet.getByLongname('module:scopetags#myInstance')[0]; + + it("sets the doclet's 'scope' property to 'instance'", function() { + expect(doc.scope).toBeDefined(); + expect(doc.scope).toBe('instance'); + }); + }); + + describe("@static tag", function() { + var doc = docSet.getByLongname('module:scopetags.myStatic')[0]; + + it("sets the doclet's 'scope' property to 'static'", function() { + expect(doc.scope).toBeDefined(); + expect(doc.scope).toBe('static'); + }); }); }); diff --git a/test/specs/tags/summarytag.js b/test/specs/tags/summarytag.js index aa4d4147..a4627153 100644 --- a/test/specs/tags/summarytag.js +++ b/test/specs/tags/summarytag.js @@ -1,6 +1,6 @@ describe("@summary tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @summary I do not like green eggs and ham! */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/summarytag.js'), + doc = docSet.getByLongname('Sam')[0]; it("sets the doclet's 'summary' property to the tag value", function() { expect(doc.summary).toBe('I do not like green eggs and ham!'); }); diff --git a/test/specs/tags/todotag.js b/test/specs/tags/todotag.js index 807c76be..410bb55f 100644 --- a/test/specs/tags/todotag.js +++ b/test/specs/tags/todotag.js @@ -1,6 +1,6 @@ describe("@todo tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @todo something\n@todo something else */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/todotag.js'), + doc = docSet.getByLongname('x')[0]; it("adds the entries into a 'todo' array on the doclet", function() { expect(doc.todo).toBeDefined(); diff --git a/test/specs/tags/tutorialtag.js b/test/specs/tags/tutorialtag.js index ea345ccd..b334a266 100644 --- a/test/specs/tags/tutorialtag.js +++ b/test/specs/tags/tutorialtag.js @@ -1,7 +1,7 @@ describe("@tutorial tag", function() { // these are tests for the block usage, not the inline usage. see util/templateHelper for that. - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** @tutorial tute1\n@tutorial tute2 */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/tutorialtag.js'), + doc = docSet.getByLongname('x')[0]; it("adds the listed tutorials to a 'tutorials' array on the doclet", function () { expect(Array.isArray(doc.tutorials)).toBeTruthy(); diff --git a/test/specs/tags/undocumentedtag.js b/test/specs/tags/undocumentedtag.js index 5dc85b56..90052234 100644 --- a/test/specs/tags/undocumentedtag.js +++ b/test/specs/tags/undocumentedtag.js @@ -1,6 +1,6 @@ describe("@undocumented tag", function() { - var doclet = require('jsdoc/doclet'), - doc = new doclet.Doclet('/** Foo bar\n@undocumented */', {}); + var docSet = jasmine.getDocSetFromFile('test/fixtures/undocumentedtag.js'), + doc = docSet.getByLongname('x')[0]; it("sets the doclet's 'undocumented' property to true", function () { expect(doc.undocumented).toBeTruthy();