diff options
| author | Igor Minar | 2013-02-06 15:25:28 -0800 | 
|---|---|---|
| committer | Igor Minar | 2013-02-11 14:08:16 -0800 | 
| commit | 42a5033c563fcb3a3f0ddd89ab62ec36d0e73996 (patch) | |
| tree | b9fca17d2b025e18087e9db1906be502e6311a21 /docs | |
| parent | 6b19e7d527dc67113e39bff0060238d78bed9447 (diff) | |
| download | angular.js-42a5033c563fcb3a3f0ddd89ab62ec36d0e73996.tar.bz2 | |
chore(docs): improve docs parser type
previously we barfed on function type definition with optional arguments
like {function(number=)}
this fixes it
I also added a bunch of code that helps to debug incorrectly parsed docs.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/spec/ngdocSpec.js | 28 | ||||
| -rw-r--r-- | docs/src/ngdoc.js | 97 | 
2 files changed, 79 insertions, 46 deletions
diff --git a/docs/spec/ngdocSpec.js b/docs/spec/ngdocSpec.js index 0a7979f2..48db580b 100644 --- a/docs/spec/ngdocSpec.js +++ b/docs/spec/ngdocSpec.js @@ -55,12 +55,15 @@ describe('ngdoc', function() {              '@name a\n' +              '@param {*} a short\n' +              '@param {Type} b med\n' + -            '@param {Class=} [c=2] long\nline'); +            '@param {Class=} [c=2] long\nline\n' + +            '@param {function(number, string=)} d fn with optional arguments');          doc.parse();          expect(doc.param).toEqual([             {name:'a', description:'<p>short</p>', type:'*', optional:false, 'default':undefined},             {name:'b', description:'<p>med</p>', type:'Type', optional:false, 'default':undefined}, -           {name:'c', description:'<p>long\nline</p>', type:'Class', optional:true, 'default':'2'} +           {name:'c', description:'<p>long\nline</p>', type:'Class', optional:true, 'default':'2'}, +           {name:'d', description:'<p>fn with optional arguments</p>', +             type: 'function(number, string=)', optional: false, 'default':undefined}           ]);        }); @@ -318,9 +321,9 @@ describe('ngdoc', function() {        });        it('should not parse @property without a type', function() { -        var doc = new Doc("@property fake"); +        var doc = new Doc("@property fake", 'test.js', '44');          expect(function() { doc.parse(); }). -          toThrow(new Error("Not a valid 'property' format: fake")); +          toThrow(new Error("Not a valid 'property' format: fake (found in: test.js:44)"));        });        it('should parse @property with type', function() { @@ -350,15 +353,30 @@ describe('ngdoc', function() {      describe('@returns', function() {        it('should not parse @returns without type', function() {          var doc = new Doc("@returns lala"); -        expect(doc.parse).toThrow(); +        expect(function() { doc.parse(); }). +            toThrow(); +      }); + + +      it('should not parse @returns with invalid type', function() { +        var doc = new Doc("@returns {xx}x} lala", 'test.js', 34); +        expect(function() { doc.parse(); }). +            toThrow(new Error("Not a valid 'returns' format: {xx}x} lala (found in: test.js:34)"));        }); +        it('should parse @returns with type and description', function() {          var doc = new Doc("@name a\n@returns {string} descrip tion");          doc.parse();          expect(doc.returns).toEqual({type: 'string', description: '<p>descrip tion</p>'});        }); +      it('should parse @returns with complex type and description', function() { +        var doc = new Doc("@name a\n@returns {function(string, number=)} description"); +        doc.parse(); +        expect(doc.returns).toEqual({type: 'function(string, number=)', description: '<p>description</p>'}); +      }); +        it('should transform description of @returns with markdown', function() {          var doc = new Doc("@name a\n@returns {string} descrip *tion*");          doc.parse(); diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js index ae612a55..253f5411 100644 --- a/docs/src/ngdoc.js +++ b/docs/src/ngdoc.js @@ -214,23 +214,25 @@ Doc.prototype = {        if (atName) {          var text = trim(atText.join('\n')), match;          if (atName == 'param') { -          match = text.match(/^\{([^}=]+)(=)?\}\s+(([^\s=]+)|\[(\S+)=([^\]]+)\])\s+(.*)/); -                             //  1      12 2      34       4   5   5 6      6  3   7  7 +          match = text.match(/^\{([^}]+)\}\s+(([^\s=]+)|\[(\S+)=([^\]]+)\])\s+(.*)/); +                             //  1      1    23       3   4   4 5      5  2   6  6            if (!match) { -            throw new Error("Not a valid 'param' format: " + text); +            throw new Error("Not a valid 'param' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');            } + +          var optional = (match[1].slice(-1) === '=');            var param = { -            name: match[5] || match[4], -            description:self.markdown(text.replace(match[0], match[7])), -            type: match[1], -            optional: !!match[2], -            'default':match[6] +            name: match[4] || match[3], +            description:self.markdown(text.replace(match[0], match[6])), +            type: optional ? match[1].substring(0, match[1].length-1) : match[1], +            optional: optional, +            'default':match[5]            };            self.param.push(param);          } else if (atName == 'returns' || atName == 'return') { -          match = text.match(/^\{([^}=]+)\}\s+(.*)/); +          match = text.match(/^\{([^}]+)\}\s+(.*)/);            if (!match) { -            throw new Error("Not a valid 'returns' format: " + text + ' in ' + self.file + ':' + self.line); +            throw new Error("Not a valid 'returns' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');            }            self.returns = {              type: match[1], @@ -245,7 +247,7 @@ Doc.prototype = {          } else if(atName == 'property') {            match = text.match(/^\{(\S+)\}\s+(\S+)(\s+(.*))?/);            if (!match) { -            throw new Error("Not a valid 'property' format: " + text); +            throw new Error("Not a valid 'property' format: " + text + ' (found in: ' + self.file + ':' + self.line + ')');            }            var property = new Doc({              type: match[1], @@ -383,40 +385,53 @@ Doc.prototype = {      var self = this;      dom.h('Usage', function() {        var restrict = self.restrict || 'AC'; +        if (restrict.match(/E/)) { -        dom.text('as element (see '); +        dom.text('This directive can be used as custom element, but we aware of ');          dom.tag('a', {href:'guide/ie'}, 'IE restrictions'); -        dom.text(')'); -        dom.code(function() { -          dom.text('<'); -          dom.text(dashCase(self.shortName)); -          renderParams('\n       ', '="', '"'); -          dom.text('>\n</'); -          dom.text(dashCase(self.shortName)); -          dom.text('>'); -        }); +        dom.text('.');        } -      if (restrict.match(/A/)) { -        var element = self.element || 'ANY'; -        dom.text('as attribute'); -        dom.code(function() { -          dom.text('<' + element + ' '); -          dom.text(dashCase(self.shortName)); -          renderParams('\n     ', '="', '"', true); -          dom.text('>\n   ...\n'); -          dom.text('</' + element + '>'); -        }); -      } -      if (restrict.match(/C/)) { -        dom.text('as class'); -        var element = self.element || 'ANY'; -        dom.code(function() { -          dom.text('<' + element + ' class="'); -          dom.text(dashCase(self.shortName)); -          renderParams(' ', ': ', ';', true); -          dom.text('">\n   ...\n'); -          dom.text('</' + element + '>'); + +      if (self.usage) { +        dom.tag('pre', function() { +          dom.tag('code', function() { +            dom.text(self.usage); +          });          }); +      } else { +        if (restrict.match(/E/)) { +          dom.text('as element:'); +          dom.code(function() { +            dom.text('<'); +            dom.text(dashCase(self.shortName)); +            renderParams('\n       ', '="', '"'); +            dom.text('>\n</'); +            dom.text(dashCase(self.shortName)); +            dom.text('>'); +          }); +        } +        if (restrict.match(/A/)) { +          var element = self.element || 'ANY'; +          dom.text('as attribute'); +          dom.code(function() { +            dom.text('<' + element + ' '); +            dom.text(dashCase(self.shortName)); +            renderParams('\n     ', '="', '"', true); +            dom.text('>\n   ...\n'); +            dom.text('</' + element + '>'); +          }); +        } +        if (restrict.match(/C/)) { +          dom.text('as class'); +          var element = self.element || 'ANY'; +          dom.code(function() { +            dom.text('<' + element + ' class="'); +            dom.text(dashCase(self.shortName)); +            renderParams(' ', ': ', ';', true); +            dom.text('">\n   ...\n'); +            dom.text('</' + element + '>'); +          }); +        }        }        self.html_usage_directiveInfo(dom);        self.html_usage_parameters(dom);  | 
