diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/collect.js | 105 | ||||
| -rw-r--r-- | docs/docs.css | 5 | ||||
| -rw-r--r-- | docs/service.template | 37 | ||||
| -rw-r--r-- | docs/spec/collectSpec.js | 141 | ||||
| -rw-r--r-- | docs/specs.js | 2 | 
5 files changed, 270 insertions, 20 deletions
diff --git a/docs/collect.js b/docs/collect.js index 4e845f5b..7ad1630b 100644 --- a/docs/collect.js +++ b/docs/collect.js @@ -7,7 +7,8 @@ var fs       = require('fs'),      Showdown = require('showdown').Showdown;  var documentation = { -    pages:[] +    pages:[], +    byName: {}  };  var keywordPages = []; @@ -23,18 +24,7 @@ var work = callback.chain(function () {        //console.log('reading', file, '...');        findNgDoc(file, work.waitMany(function(doc) {          parseNgDoc(doc); -        if (doc.ngdoc) { -          keywordPages.push({ -            name:doc.name, -            keywords:keywords(doc.raw.text) -            } -          ); -          documentation.pages.push(doc); -          console.log('Found:', doc.ngdoc + ':' + doc.shortName); -          mergeTemplate( -                    doc.ngdoc + '.template', -                    doc.name + '.html', doc, work.waitFor()); -        } +        processNgDoc(documentation, doc);        }));      }));    })); @@ -42,6 +32,7 @@ var work = callback.chain(function () {    console.log('ERROR:', err.stack || err);  }).onDone(function(){    keywordPages.sort(function(a,b){ return a.name == b.name ? 0:(a.name < b.name ? -1 : 1);}); +  writeDoc(documentation.pages);    mergeTemplate('docs-data.js', 'docs-data.js', {JSON:JSON.stringify(keywordPages)}, callback.chain());    mergeTemplate('docs-scenario.js', 'docs-scenario.js', documentation, callback.chain());    copy('docs-scenario.html', callback.chain()); @@ -156,11 +147,17 @@ function markdownTag(doc, name, value) {  }  function markdown(text) { -  text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>'); -  text = text.replace(/(angular\.[\w\._\-:]+)/gm, '<a href="#$1">$1</a>'); -  text = text.replace(/(`(ng:[\w\._\-]+)`)/gm, '<a href="#angular.directive.$2">$1</a>'); -  text = new Showdown.converter().makeHtml(text); -  return text; +  var parts = text.split(/(<pre>[\s\S]*<\/pre>)/); +  parts.forEach(function(text, i){ +    if (!text.match(/^<pre>/)) { +      text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>'); +      text = new Showdown.converter().makeHtml(text); +      text = text.replace(/(angular\.[\$\w\._\-:]+)/gm, '<a href="#!$1">$1</a>'); +      text = text.replace(/(`(ng:[\w\._\-]+)`)/gm, '<a href="#!angular.directive.$2">$1</a>'); +      parts[i] = text; +    } +  }); +  return parts.join('');  }  function markdownNoP(text) { @@ -171,6 +168,43 @@ function markdownNoP(text) {    return lines.join('\n');  } +function requiresTag(doc, name, value) { +  doc.requires = doc.requires || []; +  doc.requires.push({name: value}); +} + +function propertyTag(doc, name, value) { +  doc[name] = doc[name] || []; +  var match = value.match(/^({(\S+)}\s*)?(\S+)(\s+(.*))?/); +   +  if (match) { +    var tag = { +      type: match[2], +      name: match[3], +      description: match[5] || false +    }; +  } else { +    throw "[" + doc.raw.file + ":" + doc.raw.line + +          "]: @" + name + " must be in format '{type} name description' got: " + value; +  } +  return doc[name].push(tag); +} + +function returnsTag(doc, name, value) { +  var match = value.match(/^({(\S+)}\s*)?(.*)?/); +   +  if (match) { +    var tag = { +      type: match[2], +      description: match[3] || false +    }; +  } else { +    throw "[" + doc.raw.file + ":" + doc.raw.line + +          "]: @" + name + " must be in format '{type} description' got: " + value; +  } +  return doc[name] = tag; +} +  var TAG = {    ngdoc: valueTag,    example: escapedHtmlTag, @@ -186,6 +220,7 @@ var TAG = {    paramDescription: markdownTag,    exampleDescription: markdownTag,    element: valueTag, +  methodOf: valueTag,    name: function(doc, name, value) {      doc.name = value;      doc.shortName  = value.split(/\./).pop(); @@ -212,7 +247,10 @@ var TAG = {        throw "[" + doc.raw.file + ":" + doc.raw.line +              "]: @param must be in format '{type} name=value description' got: " + value;      } -  } +  }, +  property: propertyTag, +  requires: requiresTag, +  returns: returnsTag  };  function parseNgDoc(doc){ @@ -291,3 +329,32 @@ function findJsFiles(dir, callback){      callback.done();    }));  } + +function processNgDoc(documentation, doc) { +  if (!doc.ngdoc) return; +  console.log('Found:', doc.ngdoc + ':' + doc.name); +   +  documentation.byName[doc.name] = doc; +   +  if (doc.methodOf) { +    if (parent = documentation.byName[doc.methodOf]) { +      (parent.method = parent.method || []).push(doc); +    } else { +      throw 'Owner "' + doc.methodOf + '" is not defined.'; +    } +  } else { +    documentation.pages.push(doc); +    keywordPages.push({ +      name:doc.name, +      keywords:keywords(doc.raw.text) +    }); +  } +} + +function writeDoc(pages) { +  pages.forEach(function(doc) { +    mergeTemplate( +        doc.ngdoc + '.template', +        doc.name + '.html', doc, callback.chain()); +  }); +} diff --git a/docs/docs.css b/docs/docs.css index 25a8ffea..664328d0 100644 --- a/docs/docs.css +++ b/docs/docs.css @@ -125,3 +125,8 @@ a {    margin-left: 2em;    font-family: monospace;  } + +#sidebar ul li.level-3 { +  margin-left: 3em; +  font-family: monospace; +} diff --git a/docs/service.template b/docs/service.template new file mode 100644 index 00000000..2774cad2 --- /dev/null +++ b/docs/service.template @@ -0,0 +1,37 @@ +<h1><tt>{{name}}</tt></h1> +<h2>Description</h2> +{{{description}}} + +<h2>Dependencies</h2> +<ul> +  {{#requires}} +  <li><tt>{{name}}</tt></li> +  {{/requires}} +</ul> + +<h2>Methods</h2> +<ul> +  {{#method}} +  <li><tt>{{shortName}}</tt>: {{{description}}}</li> +  {{/method}} +</ul> + +<h2>Properties</h2> +<ul> +  {{#property}} +  <li><tt>{{name}}:{{#type}}{{type}}{{/type}}</tt>{{#description}}: {{{description}}}{{/description}}</li> +  {{/property}} +</ul> + +{{#example}} +<h2>Example</h2> +{{{exampleDescription}}} +<doc:example> +  <doc:source> +{{/example}} +    {{{example}}} +{{#example}} +  </doc:source> +  {{#scenario}}<doc:scenario>{{{scenario}}}</doc:scenario>{{/scenario}} +</doc:example> +{{/example}}
\ No newline at end of file diff --git a/docs/spec/collectSpec.js b/docs/spec/collectSpec.js index f20342b1..9de08dc8 100644 --- a/docs/spec/collectSpec.js +++ b/docs/spec/collectSpec.js @@ -11,6 +11,63 @@ describe('collect', function(){        expect(collect.markdown('<angular/>')).          toEqual('<p><tt><angular/></tt></p>');      }); +     +    it('should not replace anything in <pre>', function(){ +      expect(collect.markdown('angular.x\n<pre>\nangular.k\n</pre>\nangular.x')). +        toEqual( +            '<p><a href="#!angular.x">angular.x</a></p>' +  +            '<pre>\nangular.k\n</pre>' +  +            '<p><a href="#!angular.x">angular.x</a></p>'); +    }); +  }); +   +  describe('processNgDoc', function() { +    var processNgDoc = collect.processNgDoc, +        documentation; + +    beforeEach(function() { +      documentation = { +        pages: [], +        byName: {} +      }; +    }); +     +    it('should store references to docs by name', function() { +      var doc = {ngdoc: 'section', name: 'fake', raw: {text:''}}; +      processNgDoc(documentation, doc); +      expect(documentation.byName.fake).toBe(doc); +    }); +     +    it('should connect doc to owner (specified by @methodOf)', function() { +      var parentDoc = {ngdoc: 'section', name: 'parent', raw: {text:''}}; +      var doc = {ngdoc: 'section', name: 'child', methodOf: 'parent', raw: {text:''}}; +      processNgDoc(documentation, parentDoc); +      processNgDoc(documentation, doc); +      expect(documentation.byName.parent.method).toBeDefined(); +      expect(documentation.byName.parent.method[0]).toBe(doc); +    }); +     +    it('should not add doc to sections if @memberOf specified', function() { +      var parentDoc = {ngdoc: 'parent', name: 'parent', raw: {text:''}}; +      var doc = {ngdoc: 'child', name: 'child', methodOf: 'parent', raw: {text:''}}; +      processNgDoc(documentation, parentDoc); +      processNgDoc(documentation, doc); +      expect(documentation.pages.child).not.toBeDefined(); +    }); +     +    it('should throw exception if owner does not exist', function() { +      expect(function() { +        processNgDoc(documentation, {ngdoc: 'section', methodOf: 'not.exist', raw: {text:''}}); +      }).toThrow('Owner "not.exist" is not defined.'); +    }); +     +    it('should ignore non-ng docs', function() { +      var doc = {name: 'anything'}; +      expect(function() { +        processNgDoc(documentation, doc); +      }).not.toThrow(); +      expect(documentation.pages).not.toContain(doc); +    });    });    describe('TAG', function(){ @@ -41,6 +98,90 @@ describe('collect', function(){        });      }); +    describe('@requires', function() { +      it('should parse more @requires tag into array', function() { +        TAG.requires(doc, 'requires', '$service'); +        TAG.requires(doc, 'requires', '$another'); +         +        expect(doc.requires).toEqual([ +          {name: '$service'}, +          {name: '$another'} +        ]); +      }); +    }); + +    describe('@property', function() { +      it('should parse @property tags into array', function() { +        TAG.property(doc, 'property', '{type} name1 desc'); +        TAG.property(doc, 'property', '{type} name2 desc'); +        expect(doc.property.length).toEqual(2); +      }); +       +      it('should parse @property with only name', function() { +        TAG.property(doc, 'property', 'fake'); +        expect(doc.property[0].name).toEqual('fake'); +      }); +       +      it('should parse @property with optional type', function() { +        TAG.property(doc, 'property', '{string} name'); +        expect(doc.property[0].name).toEqual('name'); +        expect(doc.property[0].type).toEqual('string'); +      }); +       +      it('should parse @property with optional description', function() { +        TAG.property(doc, 'property', 'name desc rip tion'); +        expect(doc.property[0].name).toEqual('name'); +        expect(doc.property[0].description).toEqual('desc rip tion'); +      }); +       +      it('should parse @property with type and description both', function() { +        TAG.property(doc, 'property', '{bool} name desc rip tion'); +        expect(doc.property[0].name).toEqual('name'); +        expect(doc.property[0].type).toEqual('bool'); +        expect(doc.property[0].description).toEqual('desc rip tion'); +      }); +       +      /** +       * If property description is undefined, this variable is not set in the template, +       * so the whole @description tag is used instead +       */ +      it('should set undefined description to "false"', function() { +        TAG.property(doc, 'property', 'name'); +        expect(doc.property[0].description).toBe(false); +      }); +    }); +     +    describe('@methodOf', function() { +      it('should parse @methodOf tag', function() { +        expect(function() { +          TAG.methodOf(doc, 'methodOf', 'parentName'); +        }).not.toThrow(); +        expect(doc.methodOf).toEqual('parentName'); +      }); +    }); +     +    describe('@returns', function() { +      it('should parse @returns', function() { +      expect(function() {TAG.returns(doc, 'returns', '');}) +        .not.toThrow(); +      }); +       +      it('should parse @returns with type', function() { +        TAG.returns(doc, 'returns', '{string}'); +        expect(doc.returns.type).toEqual('string'); +      }); +       +      it('should parse @returns with description', function() { +        TAG.returns(doc, 'returns', 'descrip tion'); +        expect(doc.returns.description).toEqual('descrip tion'); +      }); +       +      it('should parse @returns with type and description', function() { +        TAG.returns(doc, 'returns', '{string} description'); +        expect(doc.returns).toEqual({type: 'string', description: 'description'}); +      }); +    }); +          describe('@describe', function(){        it('should support pre blocks', function(){          TAG.description(doc, 'description', '<pre>abc</pre>'); diff --git a/docs/specs.js b/docs/specs.js index 5f1cd153..d564b045 100644 --- a/docs/specs.js +++ b/docs/specs.js @@ -1,6 +1,6 @@  require.paths.push("./lib");  var jasmine = require('jasmine-1.0.1'); -var sys = require('sys'); +var sys = require('util');  for(var key in jasmine) {    global[key] = jasmine[key];  | 
