diff --git a/lib/jsdoc/schema.js b/lib/jsdoc/schema.js index 70e4b80f..669ea252 100644 --- a/lib/jsdoc/schema.js +++ b/lib/jsdoc/schema.js @@ -113,59 +113,8 @@ var TYPE_PROPERTY_SCHEMA = exports.TYPE_PROPERTY_SCHEMA = { }, // type parser output parsedType: { - id: '#parsedType', type: OBJECT, - additionalProperties: false, - properties: { - type: { - type: STRING, - enum: [ - 'AllLiteral', - 'FieldType', - 'FunctionType', - 'NameExpression', - 'NullLiteral', - 'RecordType', - 'TypeApplication', - 'TypeUnion', - 'UndefinedLiteral', - 'UnknownLiteral' - ] - }, - expression: { - '$ref': '#parsedType' - }, - applications: { - type : ARRAY, - items: { - '$ref': '#parsedType' - } - }, - name: STRING, - elements: { - type : ARRAY, - items: { - '$ref': '#parsedType' - } - }, - params: ARRAY, - reservedWord: BOOLEAN, - nullable: BOOLEAN, - optional: BOOLEAN, - repeatable: BOOLEAN, - fields: { - type: ARRAY, - items: { - type: OBJECT, - additionalProperties: false, - properties: { - type: STRING, - key: STRING, - value: OBJECT - } - } - } - } + additionalProperties: true } } }; diff --git a/lib/jsdoc/tag.js b/lib/jsdoc/tag.js index d0d267cb..1752fc87 100644 --- a/lib/jsdoc/tag.js +++ b/lib/jsdoc/tag.js @@ -50,6 +50,15 @@ function trim(text, opts) { return text; } +function addHiddenProperty(obj, propName, propValue) { + Object.defineProperty(obj, propName, { + value: propValue, + writable: true, + enumerable: !!global.env.opts.debug, + configurable: true + }); +} + function processTagText(tag, tagDef) { var tagType; @@ -69,9 +78,9 @@ function processTagText(tag, tagDef) { if (tagType.type) { if (tagType.type.length) { tag.value.type = { - names: tagType.type, - parsedType: tagType.parsedType + names: tagType.type }; + addHiddenProperty(tag.value.type, 'parsedType', tagType.parsedType); } tag.value.optional = tagType.optional; tag.value.nullable = tagType.nullable; diff --git a/test/fixtures/type.js b/test/fixtures/type.js deleted file mode 100644 index e82ea86a..00000000 --- a/test/fixtures/type.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @param {number=} Optional - * @param {...number} Variable (repeatable) - * @param {*} All - * @param {?number} Nullable - * @param {!number} Non nullable - * @param {Array.} - * @param {Object.} - * @param {{a: string, b}} Record - * @param {Object.} - */ -function testFunction() { -} diff --git a/test/specs/jsdoc/tag.js b/test/specs/jsdoc/tag.js index 0ed6513e..5eb27ff9 100644 --- a/test/specs/jsdoc/tag.js +++ b/test/specs/jsdoc/tag.js @@ -39,16 +39,29 @@ describe('jsdoc/tag', function() { ]; var textExampleIndented = exampleIndentedRaw.join(''); - // synonym for @param; space in the title - var tagArg = new jsdoc.tag.Tag('arg ', text, meta); - // @param with no type, but with optional and defaultvalue - var tagParam = new jsdoc.tag.Tag('param', '[foo=1]', meta); - // @example that does not need indentation to be removed - var tagExample = new jsdoc.tag.Tag('example', textExample, meta); - // @example that needs indentation to be removed - var tagExampleIndented = new jsdoc.tag.Tag('example', textExampleIndented, meta); - // for testing that onTagText is run when necessary - var tagType = new jsdoc.tag.Tag('type', 'MyType ', meta); + var tagArg; + var tagExample; + var tagExampleIndented; + var tagParam; + var tagType; + + // allow each test to recreate the tags (for example, after enabling debug mode) + function createTags() { + // synonym for @param; space in the title + tagArg = new jsdoc.tag.Tag('arg ', text, meta); + // @param with no type, but with optional and defaultvalue + tagParam = new jsdoc.tag.Tag('param', '[foo=1]', meta); + // @example that does not need indentation to be removed + tagExample = new jsdoc.tag.Tag('example', textExample, meta); + // @example that needs indentation to be removed + tagExampleIndented = new jsdoc.tag.Tag('example', textExampleIndented, meta); + // for testing that onTagText is run when necessary + tagType = new jsdoc.tag.Tag('type', 'MyType ', meta); + } + + beforeEach(function() { + createTags(); + }); it("should have a 'originalTitle' property, a string", function() { expect(tagArg.originalTitle).toBeDefined(); @@ -114,9 +127,14 @@ describe('jsdoc/tag', function() { }); function verifyTagType(tag) { - var def = jsdoc.dictionary.lookUp(tag.title); + var def; + var descriptor; + var info; + + def = jsdoc.dictionary.lookUp(tag.title); expect(def).not.toBe(false); - var info = jsdoc.type.parse(tag.text, def.canHaveName, def.canHaveType); + + info = jsdoc.type.parse(tag.text, def.canHaveName, def.canHaveType); ['optional', 'nullable', 'variable', 'defaultvalue'].forEach(function(prop) { if (hasOwnProp.call(info, prop)) { @@ -129,13 +147,29 @@ describe('jsdoc/tag', function() { expect(typeof tag.value.type).toBe('object'); expect(tag.value.type.names).toBeDefined(); expect(tag.value.type.names).toEqual(info.type); + + expect(tag.value.type.parsedType).toBeDefined(); + expect(typeof tag.value.type.parsedType).toBe('object'); + + descriptor = Object.getOwnPropertyDescriptor(tag.value.type, 'parsedType'); + expect(descriptor.enumerable).toBe(!!global.env.opts.debug); } } + it('if the tag has a type, tag.value should contain the type information', function() { // we assume jsdoc/tag/type.parse works (it has its own tests to verify this); - verifyTagType(tagType); - verifyTagType(tagArg); - verifyTagType(tagParam); + var debug = !!global.env.opts.debug; + + [true, false].forEach(function(bool) { + global.env.opts.debug = bool; + createTags(); + + verifyTagType(tagType); + verifyTagType(tagArg); + verifyTagType(tagParam); + }); + + global.env.opts.debug = debug; }); it('if the tag has a description beyond the name/type, this should be in tag.value.description', function() { diff --git a/test/specs/jsdoc/typeParser.js b/test/specs/jsdoc/typeParser.js deleted file mode 100644 index 17da0b05..00000000 --- a/test/specs/jsdoc/typeParser.js +++ /dev/null @@ -1,4 +0,0 @@ -describe("@param tag", function() { - //To put doclets to jasmine.parseResults for jsdoc/schema test. - var docSet = jasmine.getDocSetFromFile('test/fixtures/type.js'); -}) \ No newline at end of file