コード例 #1
0
ファイル: resolver.js プロジェクト: Deeema/jsdoc
        it("logs an error for tutorials defined twice in .json files", function() {
            // can't have a tutorial's metadata defined twice in .json files
            resolver.load(env.dirname + "/test/tutorials/duplicateDefined");
            resolver.resolve();

            expect(logger.error).toHaveBeenCalled();
        });
コード例 #2
0
ファイル: cli.js プロジェクト: SQLGate/jsdoc
JSDoc.resolveTutorials = function() {
    var resolver = require('jsdoc/tutorial/resolver');

    if (env.opts.tutorials) {
        resolver.load(env.opts.tutorials);
        resolver.resolve();
    }
};
コード例 #3
0
ファイル: resolver.js プロジェクト: Anginwei/jsdoc
        it('allows tutorials to be defined in one .json file and redefined in another', function() {
            resolver.load(global.env.dirname + '/test/tutorials/duplicateDefined');
            resolver.resolve();

            expect(logger.error).not.toHaveBeenCalled();
            expect(logger.warn).toHaveBeenCalled();
            // we don't check to see which one wins; it depends on the order in which the JS engine
            // iterates over object keys
            expect(resolver.root.getByName('asdf')).toBeDefined();
        });
コード例 #4
0
ファイル: resolver.js プロジェクト: Anginwei/jsdoc
    function loadTutorials() {
        resetRootTutorial();

        resolver.load(global.env.dirname + '/test/tutorials/tutorials');

        childNames = resolver.root.children.map(function (t) { return t.name; });
        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');
        constr = resolver.root.getByName('constructor');
    }
コード例 #5
0
ファイル: resolver.js プロジェクト: jsdoc3/jsdoc
    function loadTutorials() {
        resetRootTutorial();

        resolver.load(`${env.dirname}/test/tutorials/tutorials`);

        childNames = resolver.root.children.map(({name}) => name);
        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');
        constr = resolver.root.getByName('constructor');
    }
コード例 #6
0
ファイル: templateHelper.js プロジェクト: Billiam/jsdoc
        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;

            // 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');
        });
コード例 #7
0
ファイル: templateHelper.js プロジェクト: Billiam/jsdoc
        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;
            spyOn(console, 'log');

            // 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('<a href="' + helper.tutorialToUrl('constructor') + '">The Constructor tutorial</a>');
        });
コード例 #8
0
ファイル: resolver.js プロジェクト: Anginwei/jsdoc
        it('logs an error for missing tutorials', function() {
            resolver.load(global.env.dirname + '/test/tutorials/incomplete');
            resolver.resolve();

            expect(logger.error).toHaveBeenCalled();
        });
コード例 #9
0
ファイル: resolver.js プロジェクト: Deeema/jsdoc
        it("logs an error for missing tutorials", function() {
            resolver.load(env.dirname + "/test/tutorials/incomplete");
            resolver.resolve();

            expect(logger.error).toHaveBeenCalled();
        });
コード例 #10
0
ファイル: resolver.js プロジェクト: Deeema/jsdoc
describe("jsdoc/tutorial/resolver", function() {
    var logger = require('jsdoc/util/logger');
    var resolver = require('jsdoc/tutorial/resolver');
    var tutorial = require('jsdoc/tutorial');

    it("should exist", function() {
        expect(resolver).toBeDefined();
        expect(typeof resolver).toBe('object');
    });

    it("should export a 'addTutorial' function", function() {
        expect(resolver.addTutorial).toBeDefined();
        expect(typeof resolver.addTutorial).toBe("function");
    });

    it("should export a 'load' function", function() {
        expect(resolver.load).toBeDefined();
        expect(typeof resolver.load).toBe("function");
    });

    it("should export a 'resolve' function", function() {
        expect(resolver.resolve).toBeDefined();
        expect(typeof resolver.resolve).toBe("function");
    });

    it("should export a 'root' tutorial", function() {
        expect(resolver.root).toBeDefined();
        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).toBe("function");
    });

    // note: every time we addTutorial or run the resolver, we are *adding*
    // to the root tutorial.

    // addTutorial
    var tute = new tutorial.Tutorial('myTutorial', '', tutorial.TYPES.HTML);
    resolver.addTutorial(tute);
    describe("addTutorial", function() {

        it("should add a default parent of the root tutorial", function() {
            expect(tute.parent).toBe(resolver.root);
        });

        it("should be added to the root tutorial as a child", function() {
            expect(resolver.root.children).toContain(tute);
        });
    });

    // root.getByName
    describe("root.getByName", function() {
        it("can retrieve tutorials by name", function() {
            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();
        });
    });

    // load
    resolver.load(env.dirname + "/test/tutorials/tutorials");
    var childNames = resolver.root.children.map(function (t) { return t.name; }),
        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'),
        constr = resolver.root.getByName('constructor');

    describe("load", function() {

        it("all tutorials are added, initially as top-level tutorials", function() {
            // check they were added
            expect(test).toBeDefined();
            expect(test2).toBeDefined();
            expect(test3).toBeDefined();
            expect(test4).toBeDefined();
            expect(test6).toBeDefined();
            expect(constr).toBeDefined();
            // check they are top-level in resolver.root
            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('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).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
    //    |- test3
    //       |- test4
    describe("resolve", 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).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).toBe(1);
            expect(test.children).toContain(test2);
            expect(test2.parent).toBe(test);

            // test2 has children test3, test6
            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).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).toBe('test6');
        });

        it("tutorials with configuration files have titles as specified in configuration", function() {
            // test.json had info for just test.json
            expect(test.title).toBe("Test tutorial");
        });

        it("multiple tutorials can appear in a configuration file", function() {
            expect(test2.title).toBe("Test 2");
            expect(test3.title).toBe("Test 3");
            expect(test4.title).toBe("Test 4");
        });
    });

    // error reporting.
    describe("Error reporting", function() {
        beforeEach(function() {
            spyOn(logger, 'error');
            spyOn(logger, 'warn');
        });

        it("logs an error for missing tutorials", function() {
            resolver.load(env.dirname + "/test/tutorials/incomplete");
            resolver.resolve();

            expect(logger.error).toHaveBeenCalled();
        });

        it("logs a warning for duplicate-named tutorials (e.g. test.md, test.html)", function() {
            resolver.addTutorial(tute);

            expect(logger.warn).toHaveBeenCalled();
        });

        it("logs an error for tutorials defined twice in .json files", function() {
            // can't have a tutorial's metadata defined twice in .json files
            resolver.load(env.dirname + "/test/tutorials/duplicateDefined");
            resolver.resolve();

            expect(logger.error).toHaveBeenCalled();
        });
    });

});
コード例 #11
0
ファイル: jsdoc.js プロジェクト: Billiam/jsdoc
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//

/**
 * Run the jsdoc application.
 * @todo Refactor function (and require statements) into smaller functions
 */
function main() {
    var _ = require('underscore');
    var args = require('jsdoc/opts/args');
    var augment = require('jsdoc/augment');
    var borrow = require('jsdoc/borrow');
    var Config = require('jsdoc/config');
    var Filter = require('jsdoc/src/filter').Filter;
    var fs = require('jsdoc/fs');
    var handlers = require('jsdoc/src/handlers');
    var include = require('jsdoc/util/include');
    var Package = require('jsdoc/package').Package;
    var path = require('jsdoc/path');
    var plugins = require('jsdoc/plugins');
    var Readme = require('jsdoc/readme');
    var resolver = require('jsdoc/tutorial/resolver');
    var taffy = require('taffydb').taffy;
    var vm = require('jsdoc/util/vm');

    var defaultOpts;
    var docs;
    var exampleConf;
    var filter;
    var i;
    var info;
    var l;
    var packageDocs;
    var packageJson;
    var sourceFiles;
    var template;


    defaultOpts = {
        destination: './out/',
        encoding: 'utf8'
    };

    // get JSDoc version number
    info = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
    env.version = {
        number: info.version,
        revision: new Date(parseInt(info.revision, 10)).toUTCString()
    };

    env.opts = args.parse(env.args);

    try {
        env.conf = new Config(
            fs.readFileSync( env.opts.configure || path.join(__dirname, 'conf.json'), 'utf8' )
        ).get();
    }
    catch (e) {
        try {
            // Use the example file if possible
            exampleConf = fs.readFileSync(path.join(__dirname, 'conf.json.EXAMPLE'), 'utf8');
            env.conf = JSON.parse(exampleConf);
        }
        catch(e) {
            throw('Configuration file cannot be evaluated. ' + e);
        }
    }

    // look for options on the command line, in the config file, and in the defaults, in that order
    env.opts = _.defaults(env.opts, env.conf.opts, defaultOpts);

    // which version of javascript will be supported? (rhino only)
    if (typeof version === 'function') {
        version(env.conf.jsVersion || 180);
    }

    if (env.opts.help) {
        console.log( args.help() );
        process.exit(0);
    } else if (env.opts.test) {
        include('test/runner.js');
        process.exit(0);
    } else if (env.opts.version) {
        console.log('JSDoc ' + env.version.number + ' (' + env.version.revision + ')');
        process.exit(0);
    }

    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++ ) {
        if (/\bpackage\.json$/i.test(env.opts._[i])) {
            packageJson = fs.readFileSync( env.opts._[i], 'utf8' );
            env.opts._.splice(i--, 1);
        }
        
        if (/(\bREADME|\.md)$/i.test(env.opts._[i])) {
            env.opts.readme = new Readme(env.opts._[i]).html;
            env.opts._.splice(i--, 1);
        }
    }
    
    if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse?
        filter = new Filter(env.conf.source);

        sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), filter);

        handlers.attachTo(app.jsdoc.parser);

        docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding);

        //The files are ALWAYS useful for the templates to have
        //If there is no package.json, just create an empty package
        packageDocs = new Package(packageJson);
        packageDocs.files = sourceFiles || [];
        docs.push(packageDocs);

        borrow.indexAll(docs);

        augment.addInherited(docs);
        borrow.resolveBorrows(docs);

        if (env.opts.explain) {
            console.log(docs);
            process.exit(0);
        }

        if (env.opts.tutorials) {
            resolver.load(env.opts.tutorials);
            resolver.resolve();
        }

        env.opts.template = (function() {
            var publish = env.opts.template || 'templates/default';
            // if we don't find it, keep the user-specified value so the error message is useful
            return path.getResourcePath(publish) || env.opts.template;
        })();

        try {
            template = require(env.opts.template + '/publish');
        }
        catch(e) {
            throw new Error('Unable to load template: ' + e.message || e);
        }

        // templates should include a publish.js file that exports a "publish" function
        if (template.publish && typeof template.publish === 'function') {
            // convert this from a URI back to a path if necessary
            env.opts.template = path._uriToPath(env.opts.template);
            template.publish(
                taffy(docs),
                env.opts,
                resolver.root
            );
        }
        else {
            // old templates define a global "publish" function, which is deprecated
            include(env.opts.template + '/publish.js');
            if (publish && typeof publish === 'function') {
                console.log( env.opts.template + ' uses a global "publish" function, which is ' +
                    'deprecated and may not be supported in future versions. ' +
                    'Please update the template to use "exports.publish" instead.' );
                // convert this from a URI back to a path if necessary
                env.opts.template = path._uriToPath(env.opts.template);
                publish(
                    taffy(docs),
                    env.opts,
                    resolver.root
                );
            }
            else {
                throw new Error( env.opts.template + ' does not export a "publish" function.' );
            }
        }
    }
}
コード例 #12
0
ファイル: resolver.js プロジェクト: garpeer/jsdoc
 function duplicateDefinedTutorials() {
     // can't have a tutorial's metadata defined twice in .json files
     resolver.load(__dirname + "/test/tutorials/duplicateDefined");
     resolver.resolve();
 }
コード例 #13
0
ファイル: resolver.js プロジェクト: garpeer/jsdoc
 // Tests for error reporting.
 function missingTutorial() {
     resolver.load(__dirname + "/test/tutorials/incomplete");
     resolver.resolve();
 }
コード例 #14
0
ファイル: resolver.js プロジェクト: garpeer/jsdoc
describe("jsdoc/tutorial/resolver", function() {
    var resolver = require('jsdoc/tutorial/resolver'),
        tutorial = require('jsdoc/tutorial'),
        lenient = !!env.opts.lenient,
        log = eval(console.log);

    /*jshint evil: true */
    it("should exist", function() {
        expect(resolver).toBeDefined();
        expect(typeof resolver).toEqual('object');
    });

    it("should export a 'addTutorial' function", function() {
        expect(resolver.addTutorial).toBeDefined();
        expect(typeof resolver.addTutorial).toEqual("function");
    });

    it("should export a 'load' function", function() {
        expect(resolver.load).toBeDefined();
        expect(typeof resolver.load).toEqual("function");
    });

    it("should export a 'resolve' function", function() {
        expect(resolver.resolve).toBeDefined();
        expect(typeof resolver.resolve).toEqual("function");
    });

    it("should export a 'root' tutorial", function() {
        expect(resolver.root).toBeDefined();
        expect(resolver.root instanceof tutorial.Tutorial).toEqual(true);
    });

    it("exported 'root' tutorial should export a 'getByName' function", function() {
        expect(resolver.root.getByName).toBeDefined();
        expect(typeof resolver.root.getByName).toEqual("function");
    });

    // note: every time we addTutorial or run the resolver, we are *adding*
    // to the root tutorial.

    // addTutorial
    var tute = new tutorial.Tutorial('myTutorial', '', tutorial.TYPES.HTML);
    resolver.addTutorial(tute);
    describe("addTutorial", function() {

        it("should add a default parent of the root tutorial", function() {
            expect(tute.parent).toEqual(resolver.root);
        });

        it("should be added to the root tutorial as a child", function() {
            expect(resolver.root.children[0]).toEqual(tute);
        });
    });

    // root.getByName
    describe("root.getByName", function() {
        it("can retrieve tutorials by name", function() {
            expect(resolver.root.getByName('myTutorial')).toEqual(tute);
        });
    });

    // load
    resolver.load(__dirname + "/test/tutorials/tutorials");
    var childNames = resolver.root.children.map(function (t) { return t.name; }),
        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');

    describe("load", function() {

        it("all tutorials are added, initially as top-level tutorials", function() {
            // check they were added
            expect(test).toBeDefined();
            expect(test2).toBeDefined();
            expect(test3).toBeDefined();
            expect(test4).toBeDefined();
            expect(test6).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);
        });

        it("non-tutorials are skipped", function() {
            expect(resolver.root.getByName('multple')).toBeUndefined();
            expect(resolver.root.getByName('test5')).toBeUndefined();
        }); 


        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);
        });

    });

    // resolve
    // myTutorial
    // test
    // |- test2
    //    |- test6
    //    |- test3
    //       |- test4
    describe("resolve", 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);

            // test has child 'test2'
            expect(test.children.length).toEqual(1);
            expect(test.children[0]).toEqual(test2);
            expect(test2.parent).toEqual(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);

            // test3 has child test4
            expect(test3.children.length).toEqual(1);
            expect(test3.children[0]).toEqual(test4);
            expect(test4.parent).toEqual(test3);
        });

        it("tutorials without configuration files have titles matching filenames", function() {
            // test6.xml didn't have a metadata
            expect(test6.title).toEqual('test6');
        });

        it("tutorials with configuration files have titles matching filenames", function() {
            // test.json had info for just test.json
            expect(test.title).toEqual("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");
        });
    });

    // error reporting.
    describe("Error reporting", function() {
        // Tests for error reporting.
        function missingTutorial() {
            resolver.load(__dirname + "/test/tutorials/incomplete");
            resolver.resolve();
        }
        function duplicateNamedTutorials() {
            // can't add a tutorial if another with its name has already been added
            resolver.addTutorial(tute);
        }
        function duplicateDefinedTutorials() {
            // can't have a tutorial's metadata defined twice in .json files
            resolver.load(__dirname + "/test/tutorials/duplicateDefined");
            resolver.resolve();
        }

        afterEach(function() {
            env.opts.lenient = lenient;
            console.log = log;
        });

        it("throws an exception for missing tutorials if the lenient option is not enabled", function() {
            env.opts.lenient = false;

            expect(missingTutorial).toThrow();
        });

        it("doesn't throw an exception for missing tutorials if the lenient option is enabled", function() {
            console.log = function() {};
            env.opts.lenient = true;

            expect(missingTutorial).not.toThrow();
        });

        it("throws an exception for duplicate-named tutorials (e.g. test.md, test.html) if the lenient option is not enabled", function() {
            env.opts.lenient = false;
            expect(duplicateNamedTutorials).toThrow();
        });

        it("doesn't throw an exception for duplicate-named tutorials (e.g. test.md, test.html) if the lenient option is not enabled", function() {
            console.log = function() {};
            env.opts.lenient = true;
            expect(duplicateNamedTutorials).not.toThrow();
        });

        it("throws an exception for tutorials defined twice in .jsons if the lenient option is not enabled", function() {
            env.opts.lenient = false;
            expect(duplicateDefinedTutorials).toThrow();
        });

        it("doesn't throw an exception for tutorials defined twice in .jsons if the lenient option is not enabled", function() {
            console.log = function() {};
            env.opts.lenient = true;
            expect(duplicateDefinedTutorials).not.toThrow();
        });
    });

});
コード例 #15
0
ファイル: resolver.js プロジェクト: jsdoc3/jsdoc
        it('logs an error for missing tutorials', () => {
            resolver.load(`${env.dirname}/test/tutorials/incomplete`);
            resolver.resolve();

            expect(logger.error).toHaveBeenCalled();
        });
コード例 #16
0
ファイル: resolver.js プロジェクト: jsdoc3/jsdoc
 function loadBomTutorials() {
     resolver.load(`${env.dirname}/test/tutorials/bom`);
 }