From e8b692b33463dc99e12cb4b8db1e77a81d09bb0a Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Wed, 13 Aug 2014 17:04:47 -0700 Subject: [PATCH] allow the Closure version of the `protected` tag to specify a type (#731) Also adds tests for the `protected` tag. --- lib/jsdoc/tag/dictionary/definitions.js | 11 +++- test/fixtures/protectedtag.js | 20 +++++++ test/fixtures/protectedtag2.js | 13 +++++ test/specs/tags/protected.js | 75 +++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/protectedtag.js create mode 100644 test/fixtures/protectedtag2.js create mode 100644 test/specs/tags/protected.js diff --git a/lib/jsdoc/tag/dictionary/definitions.js b/lib/jsdoc/tag/dictionary/definitions.js index 151cb280..d2573886 100644 --- a/lib/jsdoc/tag/dictionary/definitions.js +++ b/lib/jsdoc/tag/dictionary/definitions.js @@ -783,7 +783,16 @@ var closureTags = exports.closureTags = { } } }, - protected: cloneTagDef(baseTags.protected), + protected: { + canHaveType: true, + onTagged: function(doclet, tag) { + doclet.access = 'protected'; + + if (tag.value && tag.value.type) { + setDocletTypeToValueType(doclet, tag); + } + } + }, return: cloneTagDef(baseTags.returns), 'this': cloneTagDef(baseTags['this']), throws: cloneTagDef(baseTags.throws), diff --git a/test/fixtures/protectedtag.js b/test/fixtures/protectedtag.js new file mode 100644 index 00000000..68744ba0 --- /dev/null +++ b/test/fixtures/protectedtag.js @@ -0,0 +1,20 @@ +/** @module uid */ + +/** @protected */ +var uidCounter = 1; + +/** @protected */ +var uidObjects = { + /** Root object. */ + root: {} +}; + +/** Obtain a unique ID. */ +exports.getUid = function getUid() { + return uidCounter++; +}; + +/** Associate an object with a unique ID. */ +exports.setObjectForUid = function setObjectForUid(obj, uid) { + uidObjects[uid] = obj; +}; diff --git a/test/fixtures/protectedtag2.js b/test/fixtures/protectedtag2.js new file mode 100644 index 00000000..a67e0a81 --- /dev/null +++ b/test/fixtures/protectedtag2.js @@ -0,0 +1,13 @@ +/** @protected {number} */ +var uidCounter = 1; + +/** + * Unique ID generator. + * @constructor + */ +function UidGenerator() {} + +/** Generate a unique ID. */ +UidGenerator.prototype.generate = function generate() { + return uidCounter++; +}; diff --git a/test/specs/tags/protected.js b/test/specs/tags/protected.js new file mode 100644 index 00000000..b904a97f --- /dev/null +++ b/test/specs/tags/protected.js @@ -0,0 +1,75 @@ +/*global afterEach, describe, expect, it, jasmine, spyOn */ +'use strict'; + +var definitions = require('jsdoc/tag/dictionary/definitions'); +var dictionary = require('jsdoc/tag/dictionary'); +var Dictionary = dictionary.Dictionary; +var doclet = require('jsdoc/doclet'); +var logger = require('jsdoc/util/logger'); + +var originalDictionary = dictionary; + +describe('@protected tag', function() { + var docSet = jasmine.getDocSetFromFile('test/fixtures/protectedtag.js'); + var uidCounter = docSet.getByLongname('module:uid~uidCounter')[0]; + var uidRoot = docSet.getByLongname('module:uid~uidObjects.root')[0]; + + it('When a symbol has a @protected tag, the doclet has an `access` property set to ' + + '`protected`.', function() { + expect(uidCounter.access).toBe('protected'); + }); + + it('When a symbol tagged with @protected has members, the members do not inherit the ' + + '@protected tag.', function() { + expect(uidRoot.access).not.toBeDefined(); + }); + + describe('JSDoc tags', function() { + afterEach(function() { + doclet._replaceDictionary(originalDictionary); + }); + + it('When JSDoc tags are enabled, the @protected tag does not accept a value.', function() { + var dict = new Dictionary(); + var protectedDocs; + + definitions.defineTags(dict, definitions.jsdocTags); + doclet._replaceDictionary(dict); + spyOn(logger, 'warn'); + + protectedDocs = jasmine.getDocSetFromFile('test/fixtures/protectedtag2.js'); + + expect(logger.warn).toHaveBeenCalled(); + }); + }); + + describe('Closure Compiler tags', function() { + afterEach(function() { + doclet._replaceDictionary(originalDictionary); + }); + + it('When Closure Compiler tags are enabled, the @private tag accepts a type expression.', + function() { + var dict = new Dictionary(); + var protectedDocs; + var uidCounter; + + definitions.defineTags(dict, definitions.closureTags); + doclet._replaceDictionary(dict); + spyOn(logger, 'warn'); + + protectedDocs = jasmine.getDocSetFromFile('test/fixtures/protectedtag2.js'); + uidCounter = protectedDocs.getByLongname('uidCounter')[0]; + + expect(logger.warn).not.toHaveBeenCalled(); + + expect(uidCounter).toBeDefined(); + expect(uidCounter.access).toBe('protected'); + + expect(uidCounter.type).toBeDefined(); + expect(uidCounter.type.names).toBeDefined(); + expect(uidCounter.type.names.length).toBe(1); + expect(uidCounter.type.names[0]).toBe('number'); + }); + }); +});