<commit_before>/* ************************************************************************

   qooxdoo - the new era of web development

   http://qooxdoo.org

   Copyright:
     2017 Christian Boulanger

   License:
     MIT: https://opensource.org/licenses/MIT
     See the LICENSE file in the project's top-level directory for details.

   Authors:
     * Christian Boulanger (info@bibliograph.org, @cboulanger)

************************************************************************ */

require("../Contrib");

require("qooxdoo");
const process = require("process");
const Search = require("github-api/dist/components/Search");
const Repository = require("github-api/dist/components/Repository");
const fetch = require("node-fetch");
const semver = require("semver");
const inquirer = require("inquirer");

/**
 * Updates the local cache with information of available contrib libraries
 */
qx.Class.define("qx.tool.cli.commands.contrib.Update", {
  extend: qx.tool.cli.commands.Contrib,

  statics: {
    getYargsCommand: function() {
      return {
        command: "update [repository]",
        describe: "updates information on contrib libraries from github. Has to be called before the other commands.",
        builder: {
          "file": {
            alias: "f",
            describe: "Output result to a file"
          },
          "search": {
            alias: "S",
            describe: "Search GitHub for repos (as opposed to using the cached nightly data)"
          },
          "all-versions": {
            alias: "a",
            describe: "Retrieve all releases (as opposed to the latest minor/patch release of each major release)"
          },
          "prereleases": {
            alias: "p",
            describe: "Include prereleases"
          },
          "verbose": {
            alias: "v",
            describe: "Verbose logging"
          },
          "quiet": {
            alias: "q",
            describe: "No output"
          }
        },
        handler: function(argv) {
          return new qx.tool.cli.commands.contrib.Update(argv)
            .process()
            .catch(e => {
              console.error(e.stack || e.message);
              process.exit(1);
            });
        }
      };
    }
  },

  members: {

    /**
     * Updates the cache with information from GitHub.
     */
    process: async function() {
      // init
      let names = [];
      const argv = this.argv;
      const update_repo_only = argv.repository;
      if (!update_repo_only) {
        this.clearCache();
      }

      let cfg = await qx.tool.cli.ConfigDb.getInstance();
      let github = cfg.db("github", {});

      const self = this;
      // Create the cache
      if (!argv.search) {
        // Retrieve the data from the qooxdoo/qx-contrib repository
        await updateFromRepository();
      } else {
        if (!github.token) {
          let response = await inquirer.prompt([
            {
              type: "input",
              name: "token",
              message: "Searching GitHub requires an API token - visit https://github.com/settings/tokens to obtain one " +
                       "(you do not need to assign any permissions, just create a token);\nWhat is your GitHub API Token ? "
            }
          ]
          );
          if (!response.token) {
            console.error("You have not provided a GitHub token.");
            return;
          }
          github.token = response.token;
          cfg.save();
        }

        // Generate data from GitHub API
        await updateFromGitHubAPI();
      }

      let num_libraries = this.getCache().num_libraries;
      if (num_libraries && !argv.quiet) {
        console.info(`Found ${num_libraries} releases of libraries.`);
        console.info(`Run 'qx contrib list' in the root dir of your project to see which versions of these libraries are compatible.`);
      }

      // save cache
      if (argv.file) {
        await this.exportCache(argv.file);
      } else {
        await this.saveCache();
      }

      async function updateFromRepository() {
        if (!argv.quiet) {
          console.log("Downloading cache from GitHub ...");
        }
        let url = self.getRepositoryCacheUrl();
        try {
          let res = await fetch(url);
          let data = await res.json();
          self.setCache(data);
        } catch (e) {
          throw new qx.tool.cli.Utils.UserError(e.message);
        }
      }

      async function updateFromGitHubAPI() {
        const auth = {
          token: github.token
        };
        const search = new Search({}, auth);
        let num_libraries = 0;

        // qooxdoo-contrib repositories
        if (!argv.quiet) {
          console.log("Searching for qooxdoo-contrib repositories on GitHub...");
        }
        let query = "topic:qooxdoo-contrib fork:true";
        if (update_repo_only) {
          query += " " + update_repo_only;
        }
        let result = await search.forRepositories({q: query});
        let repos_data = self.getCache().repos.data;

        // iterate over repositories
        for (let repo of result.data) {
          let name = repo.full_name;

          // if a repository name has been given, only update this repo
          if (update_repo_only && name !== update_repo_only) {
            continue;
          }
          if (argv.verbose) {
            console.info(`### Found ${name} ...`);
          }
          names.push(name);
          let repository = new Repository(name, auth);
          repos_data[name] = {
            description: repo.description,
            url: repo.url,
            releases: {
              list: [],
              data: {}
            }
          };

          // get releases
          try {
            var releases_data = await repository.listReleases();
          } catch (e) {
            console.error("Error retrieving releases: " + e);
            continue;
          }

          // filter releases to speed up updates
          let releases = releases_data.data
            // filter out invalid release names and prereleases unless "--all-versions"
            .filter(r => argv["all-versions"] ? true :
              (semver.valid(r.tag_name, true) && (!semver.prerelease(r.tag_name, true) || argv["prereleases"]))
            )
            // attach a clean version number
            .map(r => {
              r.version = semver.valid(r.tag_name, true);
              return r;
            })
            // sort by version number
            .sort((a, b) => semver.compare(a.version, b.version))
            // use only the latest minor/patch unless "--all-versions"
            .filter((r, i, a) => argv["all-versions"] ? true : (i === a.length-1 || semver.major(a[i+1].version) > semver.major(r.version)));

          let versions = releases.map(r => r.version);
          if (argv.verbose) {
            console.info(`>>> Retrieved ${releases.length} release(s) of ${name}: ${versions.join(", ")}.`);
          }

          // get Manifest.json of each release to determine compatible qooxdoo versions
          for (let release of releases) {
            let tag_name = release.tag_name;
            let releases = repos_data[name].releases;

            // list of paths to manifest files, default is Manifest.json in the root dir
            let manifests = [{path: "Manifest.json"}];

            // can be overridden by a qoxdoo.json in the root dir
            let qooxdoo_data;
            if (argv.verbose) {
              console.log(`>>> Trying to retrieve 'qooxdoo.json' for ${name} ${tag_name}...`);
            }
            try {
              // @todo check if the method can return JSON to save parsing
              qooxdoo_data = await repository.getContents(tag_name, "qooxdoo.json", true);
              if (argv.verbose) {
                console.log(`>>>  File exists, checking for libraries...`);
              }
              let data = qooxdoo_data.data;
              if (typeof data == "string") {
                try {
                  data = qx.tool.compiler.utils.Json.parseJson(data);
                } catch (e) {
                  if (argv.verbose) {
                    console.warn(`!!!  Parse error: ${e.message}`);
                  }
                }
              }
              // we have a list of Manifest.json paths!
              if (data.contribs && data.contribs instanceof Array) {
                manifests = data.contribs;
              } else if (data.libraries && data.libraries instanceof Array) {
                manifests = data.libraries;
              }
            } catch (e) {
              // no qooxdoo.json
              if (e.message.match(/404/)) {
                if (argv.verbose) {
                  console.log(`>>> No qooxdoo.json`);
                }
              } else if (argv.verbose) {
                console.warn(`!!! Error: ${e.message}`);
              }
            }

            // create a list of contribs via their manifests
            for (let [index, {path}] of manifests.entries()) {
              let manifest_data;
              if (path !== "Manifest.json") {
                if (path.substr(0, 2) === "./") {
                  path = path.substr(2);
                }
                path += "/Manifest.json";
              }
              try {
                if (argv.verbose) {
                  console.log(`>>> Retrieving Manifest file '${path}' for ${name} ${tag_name}...`);
                }
                manifest_data = await repository.getContents(tag_name, path, true);
              } catch (e) {
                if (e.message.match(/404/)) {
                  if (argv.verbose) {
                    console.warn(`!!!  File does not exist.`);
                  }
                } else if (argv.verbose) {
                  console.warn(`!!! Error: ${e.message}`);
                }
                continue;
              }
              // retrieve compatible qooxdoo versions
              let data = manifest_data.data;
              // @todo check if the method can return JSON to save parsing
              if (typeof data == "string") {
                try {
                  data = qx.tool.compiler.utils.Json.parseJson(data);
                } catch (e) {
                  if (argv.verbose) {
                    console.warn(`!!! Parse error: ${e.message}`);
                    console.log(data);
                  }
                  continue;
                }
              }

              // qooxdoo version @deprecated
              var qx_versions = data.info["qooxdoo-versions"];
              // @deprecated
              var qx_version_range = (data.requires && data.requires["qooxdoo-sdk"]) || data.info["qooxdoo-range"];
              if (argv.verbose && data.info["qooxdoo-range"]) {
                console.warn(`!!! info.qooxdoo-range is deprecated. Please use the requires.qooxdoo-sdk key instead.`);
              }

              // provide backwards-compatibility for info.qooxdoo-versions containing the semver range
              // (to be removed)
              if (typeof qx_versions == "string" && !qx_version_range) {
                qx_version_range = qx_versions;
                if (argv.verbose) {
                  console.warn(`!!! info.qooxdoo-version is deprecated. Please use the requires.qooxdoo-sdk key instead.`);
                }
              }

              // provide backwards-compatibility for info.qooxdoo-version
              if (qx_versions instanceof Array && qx_versions.length && !qx_version_range) {
                qx_version_range = qx_versions.join(" || ");
                if (argv.verbose) {
                  console.warn(`!!! Manifest key 'info.qooxdoo-version' is deprecated. Please use the requires.qooxdoo-sdk key instead.`);
                }
              }

              if (!qx_version_range) {
                if (argv.verbose) {
                  console.warn(`!!! No compatibility information, skipping...`);
                }
                continue;
              }

              if (!semver.validRange(qx_version_range, {loose: true})) {
                if (argv.verbose) {
                  console.warn(`!!! Invalid compatibility information, skipping...`);
                }
                continue;
              }

              qx_versions = qx_version_range;
              let info = data.info;
              manifests[index] = {path,
                qx_versions,
                info};
              num_libraries++;
              if (argv.verbose) {
                console.log(`>>> ${name} ${tag_name}: Found '${info.name}' contrib (compatible with ${qx_versions})`);
              } else if (!argv.quiet) {
                process.stdout.write("."); // output dots to indicate progress
              }
            } // end iteration over manifests
            // save data in cache
            let zip_url = `https://github.com/${name}/archive/${tag_name}.zip`;
            releases.list.push(tag_name);
            releases.data[tag_name] = {
              title: release.name,
              prerelease: release.prerelease,
              manifests,
              zip_url
            };
          } // end iteration over releases
        } // end iteration over repos

        // wrap-up
        self.getCache().num_libraries = num_libraries;
        if (!update_repo_only) {
          self.getCache().repos.list = names.sort();
        }
        if (!argv.quiet && !argv.verbose) {
          process.stdout.write("\n");
        }
      }
    }
  }
});
<commit_msg>This fixes the broken qx-contrib cronjob<commit_after>/* ************************************************************************

   qooxdoo - the new era of web development

   http://qooxdoo.org

   Copyright:
     2017 Christian Boulanger

   License:
     MIT: https://opensource.org/licenses/MIT
     See the LICENSE file in the project's top-level directory for details.

   Authors:
     * Christian Boulanger (info@bibliograph.org, @cboulanger)

************************************************************************ */

require("../Contrib");

require("qooxdoo");
const process = require("process");
const Search = require("github-api/dist/components/Search");
const Repository = require("github-api/dist/components/Repository");
const fetch = require("node-fetch");
const semver = require("semver");
const inquirer = require("inquirer");

/**
 * Updates the local cache with information of available contrib libraries
 */
qx.Class.define("qx.tool.cli.commands.contrib.Update", {
  extend: qx.tool.cli.commands.Contrib,

  statics: {
    getYargsCommand: function() {
      return {
        command: "update [repository]",
        describe: "updates information on contrib libraries from github. Has to be called before the other commands.",
        builder: {
          "file": {
            alias: "f",
            describe: "Output result to a file"
          },
          "search": {
            alias: "S",
            describe: "Search GitHub for repos (as opposed to using the cached nightly data)"
          },
          "all-versions": {
            alias: "a",
            describe: "Retrieve all releases (as opposed to the latest minor/patch release of each major release)"
          },
          "prereleases": {
            alias: "p",
            describe: "Include prereleases"
          },
          "verbose": {
            alias: "v",
            describe: "Verbose logging"
          },
          "quiet": {
            alias: "q",
            describe: "No output"
          }
        },
        handler: function(argv) {
          return new qx.tool.cli.commands.contrib.Update(argv)
            .process()
            .catch(e => {
              console.error(e.stack || e.message);
              process.exit(1);
            });
        }
      };
    }
  },

  members: {

    /**
     * Updates the cache with information from GitHub.
     */
    process: async function() {
      // init
      let names = [];
      const argv = this.argv;
      const update_repo_only = argv.repository;
      if (!update_repo_only) {
        this.clearCache();
      }

      let cfg = await qx.tool.cli.ConfigDb.getInstance();
      let github = cfg.db("github", {});

      const self = this;
      // Create the cache
      if (!argv.search) {
        // Retrieve the data from the qooxdoo/qx-contrib repository
        await updateFromRepository();
      } else {
        if (!github.token) {
          let response = await inquirer.prompt([
            {
              type: "input",
              name: "token",
              message: "Searching GitHub requires an API token - visit https://github.com/settings/tokens to obtain one " +
                       "(you do not need to assign any permissions, just create a token);\nWhat is your GitHub API Token ? "
            }
          ]
          );
          if (!response.token) {
            console.error("You have not provided a GitHub token.");
            return;
          }
          github.token = response.token;
          cfg.save();
        }

        // Generate data from GitHub API
        await updateFromGitHubAPI();
      }

      let num_libraries = this.getCache().num_libraries;
      if (num_libraries && !argv.quiet) {
        console.info(`Found ${num_libraries} releases of libraries.`);
        console.info(`Run 'qx contrib list' in the root dir of your project to see which versions of these libraries are compatible.`);
      }

      // save cache
      if (argv.file) {
        await this.exportCache(argv.file);
      } else {
        await this.saveCache();
      }

      async function updateFromRepository() {
        if (!argv.quiet) {
          console.log("Downloading cache from GitHub ...");
        }
        let url = self.getRepositoryCacheUrl();
        try {
          let res = await fetch(url);
          let data = await res.json();
          self.setCache(data);
        } catch (e) {
          throw new qx.tool.cli.Utils.UserError(e.message);
        }
      }

      async function updateFromGitHubAPI() {
        const auth = {
          token: github.token
        };
        const search = new Search({}, auth);
        let num_libraries = 0;

        // qooxdoo-contrib repositories
        if (!argv.quiet) {
          console.log("Searching for qooxdoo-contrib repositories on GitHub...");
        }
        let query = "topic:qooxdoo-contrib fork:true";
        if (update_repo_only) {
          query += " " + update_repo_only;
        }
        let result = await search.forRepositories({q: query});
        let repos_data = self.getCache().repos.data;

        // iterate over repositories
        for (let repo of result.data) {
          let name = repo.full_name;

          // if a repository name has been given, only update this repo
          if (update_repo_only && name !== update_repo_only) {
            continue;
          }
          if (argv.verbose) {
            console.info(`### Found ${name} ...`);
          }
          names.push(name);
          let repository = new Repository(name, auth);
          repos_data[name] = {
            description: repo.description,
            url: repo.url,
            releases: {
              list: [],
              data: {}
            }
          };

          // get releases
          try {
            var releases_data = await repository.listReleases();
          } catch (e) {
            console.error("Error retrieving releases: " + e);
            continue;
          }

          // filter releases to speed up updates
          let releases = releases_data.data
            // filter out invalid release names and prereleases unless "--all-versions"
            .filter(r => argv["all-versions"] ? true :
              (semver.valid(r.tag_name, true) && (!semver.prerelease(r.tag_name, true) || argv["prereleases"]))
            )
            // attach a clean version number
            .map(r => {
              r.version = semver.valid(r.tag_name, true) || "0.0.0";
              return r;
            })
            // sort by version number
            .sort((a, b) => semver.compare(a.version, b.version))
            // use only the latest minor/patch unless "--all-versions"
            .filter((r, i, a) => r.version !== "0.0.0" && (argv["all-versions"] ? true : (i === a.length-1 || semver.major(a[i+1].version) > semver.major(r.version))));

          let versions = releases.map(r => r.version);
          if (argv.verbose) {
            console.info(`>>> Retrieved ${releases.length} release(s) of ${name}: ${versions.join(", ")}.`);
          }

          // get Manifest.json of each release to determine compatible qooxdoo versions
          for (let release of releases) {
            let tag_name = release.tag_name;
            let releases = repos_data[name].releases;

            // list of paths to manifest files, default is Manifest.json in the root dir
            let manifests = [{path: "Manifest.json"}];

            // can be overridden by a qoxdoo.json in the root dir
            let qooxdoo_data;
            if (argv.verbose) {
              console.log(`>>> Trying to retrieve 'qooxdoo.json' for ${name} ${tag_name}...`);
            }
            try {
              // @todo check if the method can return JSON to save parsing
              qooxdoo_data = await repository.getContents(tag_name, "qooxdoo.json", true);
              if (argv.verbose) {
                console.log(`>>>  File exists, checking for libraries...`);
              }
              let data = qooxdoo_data.data;
              if (typeof data == "string") {
                try {
                  data = qx.tool.compiler.utils.Json.parseJson(data);
                } catch (e) {
                  if (argv.verbose) {
                    console.warn(`!!!  Parse error: ${e.message}`);
                  }
                }
              }
              // we have a list of Manifest.json paths!
              if (data.contribs && data.contribs instanceof Array) {
                manifests = data.contribs;
              } else if (data.libraries && data.libraries instanceof Array) {
                manifests = data.libraries;
              }
            } catch (e) {
              // no qooxdoo.json
              if (e.message.match(/404/)) {
                if (argv.verbose) {
                  console.log(`>>> No qooxdoo.json`);
                }
              } else if (argv.verbose) {
                console.warn(`!!! Error: ${e.message}`);
              }
            }

            // create a list of contribs via their manifests
            for (let [index, {path}] of manifests.entries()) {
              let manifest_data;
              if (path !== "Manifest.json") {
                if (path.substr(0, 2) === "./") {
                  path = path.substr(2);
                }
                path += "/Manifest.json";
              }
              try {
                if (argv.verbose) {
                  console.log(`>>> Retrieving Manifest file '${path}' for ${name} ${tag_name}...`);
                }
                manifest_data = await repository.getContents(tag_name, path, true);
              } catch (e) {
                if (e.message.match(/404/)) {
                  if (argv.verbose) {
                    console.warn(`!!!  File does not exist.`);
                  }
                } else if (argv.verbose) {
                  console.warn(`!!! Error: ${e.message}`);
                }
                continue;
              }
              // retrieve compatible qooxdoo versions
              let data = manifest_data.data;
              // @todo check if the method can return JSON to save parsing
              if (typeof data == "string") {
                try {
                  data = qx.tool.compiler.utils.Json.parseJson(data);
                } catch (e) {
                  if (argv.verbose) {
                    console.warn(`!!! Parse error: ${e.message}`);
                    console.log(data);
                  }
                  continue;
                }
              }

              // qooxdoo version @deprecated
              var qx_versions = data.info["qooxdoo-versions"];
              // @deprecated
              var qx_version_range = (data.requires && data.requires["qooxdoo-sdk"]) || data.info["qooxdoo-range"];
              if (argv.verbose && data.info["qooxdoo-range"]) {
                console.warn(`!!! info.qooxdoo-range is deprecated. Please use the requires.qooxdoo-sdk key instead.`);
              }

              // provide backwards-compatibility for info.qooxdoo-versions containing the semver range
              // (to be removed)
              if (typeof qx_versions == "string" && !qx_version_range) {
                qx_version_range = qx_versions;
                if (argv.verbose) {
                  console.warn(`!!! info.qooxdoo-version is deprecated. Please use the requires.qooxdoo-sdk key instead.`);
                }
              }

              // provide backwards-compatibility for info.qooxdoo-version
              if (qx_versions instanceof Array && qx_versions.length && !qx_version_range) {
                qx_version_range = qx_versions.join(" || ");
                if (argv.verbose) {
                  console.warn(`!!! Manifest key 'info.qooxdoo-version' is deprecated. Please use the requires.qooxdoo-sdk key instead.`);
                }
              }

              if (!qx_version_range) {
                if (argv.verbose) {
                  console.warn(`!!! No compatibility information, skipping...`);
                }
                continue;
              }

              if (!semver.validRange(qx_version_range, {loose: true})) {
                if (argv.verbose) {
                  console.warn(`!!! Invalid compatibility information, skipping...`);
                }
                continue;
              }

              qx_versions = qx_version_range;
              let info = data.info;
              manifests[index] = {path,
                qx_versions,
                info};
              num_libraries++;
              if (argv.verbose) {
                console.log(`>>> ${name} ${tag_name}: Found '${info.name}' contrib (compatible with ${qx_versions})`);
              } else if (!argv.quiet) {
                process.stdout.write("."); // output dots to indicate progress
              }
            } // end iteration over manifests
            // save data in cache
            let zip_url = `https://github.com/${name}/archive/${tag_name}.zip`;
            releases.list.push(tag_name);
            releases.data[tag_name] = {
              title: release.name,
              prerelease: release.prerelease,
              manifests,
              zip_url
            };
          } // end iteration over releases
        } // end iteration over repos

        // wrap-up
        self.getCache().num_libraries = num_libraries;
        if (!update_repo_only) {
          self.getCache().repos.list = names.sort();
        }
        if (!argv.quiet && !argv.verbose) {
          process.stdout.write("\n");
        }
      }
    }
  }
});
<|endoftext|>


<commit_before>var chai   = require('chai'),
    expect = chai.expect,
    specConverter = require('../../index'),
    fs = require('fs'),
    YAML = require('js-yaml'),
		_ = require('lodash');

chai.use(require('chai-string'));

describe('Converter', function() {
  var converterInstance, fullPath = __dirname + '/../data/raml-import/raml/raml08.yaml';
  beforeEach(function(){
    converterInstance = new specConverter.Converter(specConverter.Formats.RAML08, specConverter.Formats.SWAGGER);
  });
  afterEach(function(){
    converterInstance = null;
  });
  describe('constructor', function(){
    it('should successfully create new converter instance', function(){
      expect(converterInstance).to.be.an.instanceof(specConverter.Converter);
    });
    it('should validate from format, throw error otherwise', function(done){
      try{
        //set up a fake format
        specConverter.Formats.ABCD = {
          name: 'ABCD',
          className: 'ABCD'
        };

        //doesn't support export/convert from abcd format
        var newConverterInstance = new specConverter.Converter(specConverter.Formats.ABCD, specConverter.Formats.POSTMAN);
        expect(newConverterInstance).to.be.an.instanceof(specConverter.Converter);
      } catch(e) {
        expect(e.message).to.equal('from format ABCD not supported');
        done();
      }
    });
    it('should validate to format, throw error otherwise', function(done){
      try{
        //doesn't support export/convert to postman format
        var newConverterInstance = new specConverter.Converter(specConverter.Formats.RAML08, specConverter.Formats.POSTMAN);
        expect(newConverterInstance).to.be.an.instanceof(specConverter.Converter);
      } catch(e) {
        expect(e.message).to.equal('to format Postman not supported');
        done();
      }
    });
  });
  describe('loadFile', function(){
    it('should successfully load "from"/"importer" comaptible file', function(done){
      converterInstance.loadFile(fullPath, function(){
        done();
      });
    });
    it('should throw error for format incompatible file', function(done){
      converterInstance.loadFile(__dirname + '/../data/postman.json', function(err) {
        expect(err).to.not.be.undefined;
        expect(err).to.be.instanceof(Error);
        done();
      });
    });
  });

  describe('loadData', function(){
    //current function will work for only stoplight data and postman json data
    it('should successfully load raw data');
    it('should throw error for format incompatible data');
  });

  describe('convert', function(){
    it('should successfully convert and return converted data', function(done){
      converterInstance.loadFile(fullPath, function(err){
        if(err)return done(err);
        converterInstance.convert('json')
        .then(function(returnedData){
          expect(returnedData).to.be.an('object');
          expect(returnedData).to.include.keys('swagger');
          expect(returnedData.swagger).to.be.equal('2.0');
          done();
        })
        .catch(done);
      });
    });
    it('converting from stoplightx to stoplightx format should be identical', function(done) {
      var path = __dirname + '/../data/stoplightx.json';
      var originalData = require(path);
      var newConverterInstance = new specConverter.Converter(specConverter.Formats.STOPLIGHTX, specConverter.Formats.STOPLIGHTX);

      newConverterInstance.loadFile(path, function(err) {
        if (err) {
          return done(err);
        }

        try {
          newConverterInstance.convert('json', function(err, convertedData) {
            if (err) {
              done(err);
            }

            expect(JSON.parse(JSON.stringify(convertedData))).to.deep.equal(originalData);
            done();
          });
        } catch (err) {
          done(err);
        }
      });
    });

    // This test has an issue because RAML does not support operationIds
    // It performs importing from raml to stoplight and exporting from stoplight to raml
    // and thus verifies in both ways
    // it('converting from raml to raml format should be identical', function(done){

    //   //This test include swagger file that is fully compatible with sl spec.
    //   //Of course, for some specific properties, librart usually skips and won't import, these
    //   //will be documented/listed on library docs

    //   var path = __dirname + '/../data/raml.yaml';
    //   var originalData = fs.readFileSync(path, 'utf8');
    //   var newConverterInstance = new specConverter.Converter(specConverter.Formats.RAML, specConverter.Formats.RAML);
    //   newConverterInstance.loadData(originalData)
    //   .then(function(){
    //     try {
    //       newConverterInstance.convert('yaml', function(err, convertedData){
    //         if(err)return done(err);
    //         expect(YAML.safeLoad(originalData)).to.deep.equal(YAML.safeLoad(convertedData));
    //         done();
    //       });
    //     }
    //     catch(err) {
    //       done(err);
    //     }
    //   })
    //   .catch(done);
    // });

    // This test has an issue because RAML does not support operationIds
    // it('should convert reversly from raml to swagger without loss', function(done){
    //   var converter = new specConverter.Converter(specConverter.Formats.RAML, specConverter.Formats.SWAGGER);
    //   var ramlPath = __dirname + '/../data/swagger-compatible-raml.yaml';
    //   converter.loadFile(ramlPath, function(){
    //     try{
    //       converter.convert('yaml', function(err, covertedSwagger){
    //         if(err)return done(err);
    //         var converter2 = new specConverter.Converter(specConverter.Formats.SWAGGER, specConverter.Formats.RAML);
    //         converter2.loadData(covertedSwagger)
    //         .then(function(){
    //           try{
    //             converter2.convert('yaml', function(err, resultRAML){
    //               if(err)return done(err);
    //               expect(YAML.safeLoad(resultRAML)).to.deep.equal(YAML.safeLoad(fs.readFileSync(ramlPath, 'utf8')));
    //               done();
    //             });
    //           }
    //           catch(err) {
    //             done(err);
    //           }
    //         })
    //         .catch(done);
    //       });
    //     }
    //     catch(err) {
    //       done(err);
    //     }
    //   });
    // });
  });
});

describe('reversable - from swagger 2 raml 2 swagger', function () {
	var baseDir = __dirname + '/../data/reversable/swagger';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (testFile) {
		return function (done) {
			var testFilePath = baseDir + '/' + testFile;

			var ramlVersion = _.startsWith(testFile, 'raml08') ? specConverter.Formats.RAML08 : specConverter.Formats.RAML10;
			var swaggerToRamlConverter = new specConverter.Converter(specConverter.Formats.SWAGGER, ramlVersion);
			var ramlToSwaggerConverter = new specConverter.Converter(ramlVersion,  specConverter.Formats.SWAGGER);

			swaggerToRamlConverter.loadFile(testFilePath, function(){
				try{
					swaggerToRamlConverter.convert('yaml', function(err, covertedRAML){
						if (err)return done(err);
						ramlToSwaggerConverter.loadData(covertedRAML)
							.then(function(){
								try{
									ramlToSwaggerConverter.convert('json', function(err, resultSwagger){
										if(err)return done(err);
										expect(resultSwagger).to.deep.equal(require(testFilePath));
										done();
									});
								} catch(err) {
									done(err);
								}
							})
							.catch(done);
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
		it('test: ' + testFile, testWithData(testFile));
	});
});

describe('reversable - from raml 2 swagger 2 raml', function () {
	var baseDir = __dirname + '/../data/reversable/raml';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (testFile) {
		return function (done) {
			var testFilePath = baseDir + '/' + testFile;

			var ramlVersion = _.startsWith(testFile, 'raml08') ? specConverter.Formats.RAML08 : specConverter.Formats.RAML10;
			var ramlToSwaggerConverter = new specConverter.Converter(ramlVersion,  specConverter.Formats.SWAGGER);
			var swaggerToRamlConverter = new specConverter.Converter(specConverter.Formats.SWAGGER, ramlVersion);

			ramlToSwaggerConverter.loadFile(testFilePath, function(){
				try{
					ramlToSwaggerConverter.convert('json', function(err, resultSwagger){
						if (err)return done(err);
						swaggerToRamlConverter.loadData(JSON.stringify(resultSwagger))
							.then(function(){
								try{
									swaggerToRamlConverter.convert('yaml', function(err, covertedRAML){
										if(err)return done(err);
										expect(YAML.safeLoad(covertedRAML)).to.deep.equal(YAML.safeLoad(fs.readFileSync(testFilePath, 'utf8')));
										done();
									});
								} catch(err) {
									done(err);
								}
							})
							.catch(done);
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
		it('test: ' + testFile, testWithData(testFile));
	});
});

describe('from swagger to raml', function () {
	var baseDir = __dirname + '/../data/swagger-import/swagger';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (sourceFile, targetFile, stringCompare) {
		return function (done) {
			var converter = new specConverter.Converter(specConverter.Formats.SWAGGER, specConverter.Formats.RAML10);
			converter.loadFile(sourceFile, function(){
				try{
					converter.convert('yaml', function(err, covertedRAML){
						if (err)return done(err);

						var existsTarget = fs.existsSync(targetFile);

						if (!existsTarget) {
							console.log('Content for non existing target file ' + targetFile + '\n.');
							console.log('********** Begin file **********\n');
							console.log(covertedRAML);
							console.log('********** Finish file **********\n');

							done(err);
						}

						if (stringCompare == true) {
							expect(covertedRAML).to.deep.equal(fs.readFileSync(targetFile, 'utf8'));
						} else {
							expect(YAML.safeLoad(covertedRAML)).to.deep.equal(YAML.safeLoad(fs.readFileSync(targetFile, 'utf8')));
						}

						done();
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
		var sourceFile = baseDir + '/' + testFile;
		var targetFile = baseDir + '/../raml/' + _.replace(testFile, 'json', 'yaml');

		it('test: ' + testFile, testWithData(sourceFile, targetFile, false));
	});

	it('should convert from swagger petstore with external refs to raml 1.0',
		testWithData(__dirname + '/../data/petstore-separate/spec/swagger.json', __dirname + '/../data/petstore-separate/raml10.yaml', true));
});

describe('from raml to swagger', function () {
	var baseDir = __dirname + '/../data/raml-import/raml';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (testFile) {
		return function (done) {
			var testFilePath = baseDir + '/' + testFile;
			var ramlVersion = _.startsWith(testFile, 'raml08') ? specConverter.Formats.RAML08 : specConverter.Formats.RAML10;
			var converter = new specConverter.Converter(ramlVersion, specConverter.Formats.SWAGGER);
			converter.loadFile(testFilePath, function() {
				try{
					converter.convert('json', function(err, resultSwagger){
						if (err)return done(err);
						expect(resultSwagger).to.deep.equal(require(baseDir + '/../swagger/' + _.replace(testFile, 'yaml', 'json')));
						done();
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
		it('test: ' + testFile, testWithData(testFile));
	});
});
<commit_msg>skip files that start w period in tests<commit_after>var chai   = require('chai'),
    expect = chai.expect,
    specConverter = require('../../index'),
    fs = require('fs'),
    YAML = require('js-yaml'),
		_ = require('lodash');

chai.use(require('chai-string'));

describe('Converter', function() {
  var converterInstance, fullPath = __dirname + '/../data/raml-import/raml/raml08.yaml';
  beforeEach(function(){
    converterInstance = new specConverter.Converter(specConverter.Formats.RAML08, specConverter.Formats.SWAGGER);
  });
  afterEach(function(){
    converterInstance = null;
  });
  describe('constructor', function(){
    it('should successfully create new converter instance', function(){
      expect(converterInstance).to.be.an.instanceof(specConverter.Converter);
    });
    it('should validate from format, throw error otherwise', function(done){
      try{
        //set up a fake format
        specConverter.Formats.ABCD = {
          name: 'ABCD',
          className: 'ABCD'
        };

        //doesn't support export/convert from abcd format
        var newConverterInstance = new specConverter.Converter(specConverter.Formats.ABCD, specConverter.Formats.POSTMAN);
        expect(newConverterInstance).to.be.an.instanceof(specConverter.Converter);
      } catch(e) {
        expect(e.message).to.equal('from format ABCD not supported');
        done();
      }
    });
    it('should validate to format, throw error otherwise', function(done){
      try{
        //doesn't support export/convert to postman format
        var newConverterInstance = new specConverter.Converter(specConverter.Formats.RAML08, specConverter.Formats.POSTMAN);
        expect(newConverterInstance).to.be.an.instanceof(specConverter.Converter);
      } catch(e) {
        expect(e.message).to.equal('to format Postman not supported');
        done();
      }
    });
  });
  describe('loadFile', function(){
    it('should successfully load "from"/"importer" comaptible file', function(done){
      converterInstance.loadFile(fullPath, function(){
        done();
      });
    });
    it('should throw error for format incompatible file', function(done){
      converterInstance.loadFile(__dirname + '/../data/postman.json', function(err) {
        expect(err).to.not.be.undefined;
        expect(err).to.be.instanceof(Error);
        done();
      });
    });
  });

  describe('loadData', function(){
    //current function will work for only stoplight data and postman json data
    it('should successfully load raw data');
    it('should throw error for format incompatible data');
  });

  describe('convert', function(){
    it('should successfully convert and return converted data', function(done){
      converterInstance.loadFile(fullPath, function(err){
        if(err)return done(err);
        converterInstance.convert('json')
        .then(function(returnedData){
          expect(returnedData).to.be.an('object');
          expect(returnedData).to.include.keys('swagger');
          expect(returnedData.swagger).to.be.equal('2.0');
          done();
        })
        .catch(done);
      });
    });
    it('converting from stoplightx to stoplightx format should be identical', function(done) {
      var path = __dirname + '/../data/stoplightx.json';
      var originalData = require(path);
      var newConverterInstance = new specConverter.Converter(specConverter.Formats.STOPLIGHTX, specConverter.Formats.STOPLIGHTX);

      newConverterInstance.loadFile(path, function(err) {
        if (err) {
          return done(err);
        }

        try {
          newConverterInstance.convert('json', function(err, convertedData) {
            if (err) {
              done(err);
            }

            expect(JSON.parse(JSON.stringify(convertedData))).to.deep.equal(originalData);
            done();
          });
        } catch (err) {
          done(err);
        }
      });
    });

    // This test has an issue because RAML does not support operationIds
    // It performs importing from raml to stoplight and exporting from stoplight to raml
    // and thus verifies in both ways
    // it('converting from raml to raml format should be identical', function(done){

    //   //This test include swagger file that is fully compatible with sl spec.
    //   //Of course, for some specific properties, librart usually skips and won't import, these
    //   //will be documented/listed on library docs

    //   var path = __dirname + '/../data/raml.yaml';
    //   var originalData = fs.readFileSync(path, 'utf8');
    //   var newConverterInstance = new specConverter.Converter(specConverter.Formats.RAML, specConverter.Formats.RAML);
    //   newConverterInstance.loadData(originalData)
    //   .then(function(){
    //     try {
    //       newConverterInstance.convert('yaml', function(err, convertedData){
    //         if(err)return done(err);
    //         expect(YAML.safeLoad(originalData)).to.deep.equal(YAML.safeLoad(convertedData));
    //         done();
    //       });
    //     }
    //     catch(err) {
    //       done(err);
    //     }
    //   })
    //   .catch(done);
    // });

    // This test has an issue because RAML does not support operationIds
    // it('should convert reversly from raml to swagger without loss', function(done){
    //   var converter = new specConverter.Converter(specConverter.Formats.RAML, specConverter.Formats.SWAGGER);
    //   var ramlPath = __dirname + '/../data/swagger-compatible-raml.yaml';
    //   converter.loadFile(ramlPath, function(){
    //     try{
    //       converter.convert('yaml', function(err, covertedSwagger){
    //         if(err)return done(err);
    //         var converter2 = new specConverter.Converter(specConverter.Formats.SWAGGER, specConverter.Formats.RAML);
    //         converter2.loadData(covertedSwagger)
    //         .then(function(){
    //           try{
    //             converter2.convert('yaml', function(err, resultRAML){
    //               if(err)return done(err);
    //               expect(YAML.safeLoad(resultRAML)).to.deep.equal(YAML.safeLoad(fs.readFileSync(ramlPath, 'utf8')));
    //               done();
    //             });
    //           }
    //           catch(err) {
    //             done(err);
    //           }
    //         })
    //         .catch(done);
    //       });
    //     }
    //     catch(err) {
    //       done(err);
    //     }
    //   });
    // });
  });
});

describe('reversable - from swagger 2 raml 2 swagger', function () {
	var baseDir = __dirname + '/../data/reversable/swagger';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (testFile) {
    return function (done) {
			var testFilePath = baseDir + '/' + testFile;

			var ramlVersion = _.startsWith(testFile, 'raml08') ? specConverter.Formats.RAML08 : specConverter.Formats.RAML10;
			var swaggerToRamlConverter = new specConverter.Converter(specConverter.Formats.SWAGGER, ramlVersion);
			var ramlToSwaggerConverter = new specConverter.Converter(ramlVersion,  specConverter.Formats.SWAGGER);

			swaggerToRamlConverter.loadFile(testFilePath, function(){
				try{
					swaggerToRamlConverter.convert('yaml', function(err, covertedRAML){
						if (err)return done(err);
						ramlToSwaggerConverter.loadData(covertedRAML)
							.then(function(){
								try{
									ramlToSwaggerConverter.convert('json', function(err, resultSwagger){
										if(err)return done(err);
										expect(resultSwagger).to.deep.equal(require(testFilePath));
										done();
									});
								} catch(err) {
									done(err);
								}
							})
							.catch(done);
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
    if (!_.startsWith(testFile, '.')) {
      it('test: ' + testFile, testWithData(testFile));
    }
	});
});

describe('reversable - from raml 2 swagger 2 raml', function () {
	var baseDir = __dirname + '/../data/reversable/raml';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (testFile) {
		return function (done) {
			var testFilePath = baseDir + '/' + testFile;

			var ramlVersion = _.startsWith(testFile, 'raml08') ? specConverter.Formats.RAML08 : specConverter.Formats.RAML10;
			var ramlToSwaggerConverter = new specConverter.Converter(ramlVersion,  specConverter.Formats.SWAGGER);
			var swaggerToRamlConverter = new specConverter.Converter(specConverter.Formats.SWAGGER, ramlVersion);

			ramlToSwaggerConverter.loadFile(testFilePath, function(){
				try{
					ramlToSwaggerConverter.convert('json', function(err, resultSwagger){
						if (err)return done(err);
						swaggerToRamlConverter.loadData(JSON.stringify(resultSwagger))
							.then(function(){
								try{
									swaggerToRamlConverter.convert('yaml', function(err, covertedRAML){
										if(err)return done(err);
										expect(YAML.safeLoad(covertedRAML)).to.deep.equal(YAML.safeLoad(fs.readFileSync(testFilePath, 'utf8')));
										done();
									});
								} catch(err) {
									done(err);
								}
							})
							.catch(done);
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
		if (!_.startsWith(testFile, '.')) {
      it('test: ' + testFile, testWithData(testFile));
    }
	});
});

describe('from swagger to raml', function () {
	var baseDir = __dirname + '/../data/swagger-import/swagger';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (sourceFile, targetFile, stringCompare) {
		return function (done) {
			var converter = new specConverter.Converter(specConverter.Formats.SWAGGER, specConverter.Formats.RAML10);
			converter.loadFile(sourceFile, function(){
				try{
					converter.convert('yaml', function(err, covertedRAML){
						if (err)return done(err);

						var existsTarget = fs.existsSync(targetFile);

						if (!existsTarget) {
							console.log('Content for non existing target file ' + targetFile + '\n.');
							console.log('********** Begin file **********\n');
							console.log(covertedRAML);
							console.log('********** Finish file **********\n');

							done(err);
						}

						if (stringCompare == true) {
							expect(covertedRAML).to.deep.equal(fs.readFileSync(targetFile, 'utf8'));
						} else {
							expect(YAML.safeLoad(covertedRAML)).to.deep.equal(YAML.safeLoad(fs.readFileSync(targetFile, 'utf8')));
						}

						done();
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
    if (!_.startsWith(testFile, '.')) {
      var sourceFile = baseDir + '/' + testFile;
      var targetFile = baseDir + '/../raml/' + _.replace(testFile, 'json', 'yaml');

      it('test: ' + testFile, testWithData(sourceFile, targetFile, false));
    }
	});

	it('should convert from swagger petstore with external refs to raml 1.0',
		testWithData(__dirname + '/../data/petstore-separate/spec/swagger.json', __dirname + '/../data/petstore-separate/raml10.yaml', true));
});

describe('from raml to swagger', function () {
	var baseDir = __dirname + '/../data/raml-import/raml';
	var testFiles = fs.readdirSync(baseDir);

	var testWithData = function (testFile) {
		return function (done) {
			var testFilePath = baseDir + '/' + testFile;
			var ramlVersion = _.startsWith(testFile, 'raml08') ? specConverter.Formats.RAML08 : specConverter.Formats.RAML10;
			var converter = new specConverter.Converter(ramlVersion, specConverter.Formats.SWAGGER);
			converter.loadFile(testFilePath, function() {
				try{
					converter.convert('json', function(err, resultSwagger){
						if (err)return done(err);
						expect(resultSwagger).to.deep.equal(require(baseDir + '/../swagger/' + _.replace(testFile, 'yaml', 'json')));
						done();
					});
				} catch(err) {
					done(err);
				}
			});
		};
	};

	testFiles.forEach(function (testFile) {
    if (!_.startsWith(testFile, '.')) {
		  it('test: ' + testFile, testWithData(testFile));
    }
	});
});
<|endoftext|>


<commit_before>define(["angular-ui-router"], function() {

	// Declare app level module which depends on filters, and services
	angular.module('isaac.router', [
        'ui.router',
	])

	.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

        $urlRouterProvider.when("", "/");
        $urlRouterProvider.otherwise(function($injector, $location) {
            var $state = $injector.get("$state");
            $state.go("404", {target: $location.url()});
        });

        var genericPageState = function(url, id) {
            return {
                url: url,
                resolve: {
                    "page": ["api", function(api) {
                        return api.pages.get({id: id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/generic_page.html",
                        controller: "GenericPageController",
                    }
                }
            };
        }

        var staticPageState = function(url, state) {
            return {
                url: url,
                views: {
                    "body": {
                        templateUrl: "/partials/states/" + state + ".html"
                    },
                },
            }
        }

        $stateProvider
            .state('home', staticPageState("/", "home"))
            .state('about', genericPageState("/about", "about_us_index"))
            .state('events', genericPageState("/events", "events_index"))
            .state('apply_uni', genericPageState("/apply_uni", "apply_uni"))
            .state('featured_problems', genericPageState("/featured_problems", "featured_problems_index"))
            .state('bios', genericPageState("/bios", "bios"))
            .state('why_physics', genericPageState("/why_physics", "why_physics"))
            .state('contact', staticPageState("/contact", "contact"))

            .state('conceptIndex', {
                url: "/concepts?page",
                resolve: {
                    "conceptList" : ['api', function(api){
                        return api.getConceptList().$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/concept_index.html",
                        controller: "ConceptIndexController",
                    }
                }
            })
            .state('questionIndex', {
                url: "/questions?page",
                resolve: {
                    "pageIndex" :['$stateParams', function($stateParams){
                        return parseInt($stateParams.page || "1") - 1;
                    }],
                    "list" : ['api', 'pageIndex', function(api, pageIndex){
                        return api.getQuestionList(pageIndex).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/question_index.html",
                        controller: "QuestionIndexController",
                    }
                }
            })

            .state('concept', {
                url: "/concepts/:id",
                resolve: {
                    "page": ["api", "$stateParams", function(api, $stateParams) {
                        return api.conceptPages.get({id: $stateParams.id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/concept.html",
                        controller: "ConceptPageController",
                    }
                }
            })

            .state('question', {
                url: "/questions/:id",
                resolve: {
                    "page": ["api", "$stateParams", function(api, $stateParams) {
                        return api.questionPages.get({id: $stateParams.id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/question.html",
                        controller: "QuestionPageController",
                    }
                }
            })

            .state('random_content', {
                url: "/content/:id",
                resolve: {
                    "page": ["api", "$stateParams", function(api, $stateParams) {
                        return api.content.get({id: $stateParams.id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/generic_page.html",
                        controller: ["$scope", "page", function($scope, page) {
                            $scope.title = "Content object: " + page.contentObject.id;
                            $scope.doc = page.contentObject;
                        }],
                    }
                }
            })
            .state('404', {
                params: ["target"],
                views: {
                    "body": {
                        templateUrl: "/partials/states/404.html",
                        controller: function($scope, $stateParams) {
                            $scope.target = $stateParams.target;
                        }
                    },
                },
            })

	}])

})<commit_msg>Add 404 state for missing content.<commit_after>define(["angular-ui-router"], function() {

	// Declare app level module which depends on filters, and services
	angular.module('isaac.router', [
        'ui.router',
	])

	.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

        $urlRouterProvider.when("", "/");
        $urlRouterProvider.otherwise(function($injector, $location) {
            var $state = $injector.get("$state");
            $state.go("404", {target: $location.url()});
        });

        var genericPageState = function(url, id) {
            return {
                url: url,
                resolve: {
                    "page": ["api", function(api) {
                        return api.pages.get({id: id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/generic_page.html",
                        controller: "GenericPageController",
                    }
                }
            };
        }

        var staticPageState = function(url, state) {
            return {
                url: url,
                views: {
                    "body": {
                        templateUrl: "/partials/states/" + state + ".html"
                    },
                },
            }
        }

        $stateProvider
            .state('home', staticPageState("/", "home"))
            .state('about', genericPageState("/about", "about_us_index"))
            .state('events', genericPageState("/events", "events_index"))
            .state('apply_uni', genericPageState("/apply_uni", "apply_uni"))
            .state('featured_problems', genericPageState("/featured_problems", "featured_problems_index"))
            .state('bios', genericPageState("/bios", "bios"))
            .state('why_physics', genericPageState("/why_physics", "why_physics"))
            .state('contact', staticPageState("/contact", "contact"))

            .state('conceptIndex', {
                url: "/concepts?page",
                resolve: {
                    "conceptList" : ['api', function(api){
                        return api.getConceptList().$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/concept_index.html",
                        controller: "ConceptIndexController",
                    }
                }
            })
            .state('questionIndex', {
                url: "/questions?page",
                resolve: {
                    "pageIndex" :['$stateParams', function($stateParams){
                        return parseInt($stateParams.page || "1") - 1;
                    }],
                    "list" : ['api', 'pageIndex', function(api, pageIndex){
                        return api.getQuestionList(pageIndex).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/question_index.html",
                        controller: "QuestionIndexController",
                    }
                }
            })

            .state('concept', {
                url: "/concepts/:id",
                resolve: {
                    "page": ["api", "$stateParams", function(api, $stateParams) {
                        return api.conceptPages.get({id: $stateParams.id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/concept.html",
                        controller: "ConceptPageController",
                    }
                }
            })

            .state('question', {
                url: "/questions/:id",
                resolve: {
                    "page": ["api", "$stateParams", function(api, $stateParams) {
                        return api.questionPages.get({id: $stateParams.id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/question.html",
                        controller: "QuestionPageController",
                    }
                }
            })

            .state('random_content', {
                url: "/content/:id",
                resolve: {
                    "page": ["api", "$stateParams", function(api, $stateParams) {
                        return api.content.get({id: $stateParams.id}).$promise;
                    }]
                },
                views: {
                    "body": {
                        templateUrl: "/partials/states/generic_page.html",
                        controller: ["$scope", "page", function($scope, page) {
                            $scope.title = "Content object: " + page.contentObject.id;
                            $scope.doc = page.contentObject;
                        }],
                    }
                }
            })
            .state('404', {
                params: ["target"],
                views: {
                    "body": {
                        templateUrl: "/partials/states/404.html",
                        controller: function($scope, $stateParams) {
                            $scope.target = $stateParams.target;
                        }
                    },
                },
            })

	}])

    .run(['$rootScope', '$state', function($rootScope, $state) {
        $rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
            console.warn("State change error:", error);

            if (error.status == 404)
                $state.go('404', {target: $state.href(toState, toParams)});
        });

    }])

})<|endoftext|>


<commit_before>jQuery.entwine("workflow", function($) {
	$(".workflow-field").entwine({
		Loading: null,
		Dialog:  null,
		onmatch: function() {
			var self = this;

			this.setLoading(this.find(".workflow-field-loading"));
			this.setDialog(this.find(".workflow-field-dialog"));

			this.getDialog().data("workflow-field", this).dialog({
				autoOpen: false,
				width:    800,
				height:   600,
				modal:    true
			});

			this.getDialog().on("click", "button", function() {
				$(this).addClass("loading ui-state-disabled");
			});

			this.getDialog().on("submit", "form", function() {
				$(this).ajaxSubmit(function(response) {
					if($(response).is(".workflow-field")) {
						self.getDialog().empty().dialog("close");
						self.replaceWith(response);
					} else {
						self.getDialog().html(response);
					}
				});

				return false;
			});
		},
		showDialog: function(url) {
			var dlg = this.getDialog();

			dlg.empty().dialog("open");
			dlg.parent().addClass("loading");

			$.get(url).done(function(body) {
				dlg.html(body).parent().removeClass("loading");
			});
		},
		loading: function(toggle) {
			this.getLoading().toggle(typeof(toggle) == "undefined" || toggle);
		}
	});

	function helper() {
		return $("<div />").addClass("ui-state-highlight").appendTo("body");
	}

	$(".workflow-field .workflow-field-actions").entwine({
		onmatch: function() {
			this.sortable({
				axis:        "y",
				containment: this,
				placeholder: "ui-state-highlight workflow-placeholder",
				handle:      ".workflow-field-action-drag",
				tolerance:   "pointer",
				update: function() {
					var actions = $(this).find(".workflow-field-action");
					var field   = $(this).closest(".workflow-field");
					var link    = field.data("sort-link");
					var ids     = actions.map(function() { return $(this).data("id"); });

					var data = {
						"id[]":  ids.get(),
						"class": "WorkflowAction"
					};

					field.loading();
					$.post(link, data).done(function() { field.loading(false); });
				}
			});
		}
	});

	$(".workflow-field .workflow-field-action-transitions").entwine({
		onmatch: function() {
			this.sortable({
				axis:        "y",
				containment: this,
				handle:      ".workflow-field-action-drag",
				tolerance:   "pointer",
				update: function() {
					var trans = $(this).find("li");
					var field = $(this).closest(".workflow-field");
					var link  = field.data("sort-link");
					var ids   = trans.map(function() { return $(this).data("id"); });

					var data = {
						"id[]":   ids.get(),
						"class":  "WorkflowTransition",
						"parent": $(this).closest(".workflow-field-action").data("id")
					};

					field.loading();
					$.post(link, data).done(function() { field.loading(false); });
				}
			});
		}
	});

	$(".workflow-field .workflow-field-create-class").entwine({
		onmatch: function() {
			this.chosen().addClass("has-chnz");
		},
		onchange: function() {
			this.siblings(".workflow-field-do-create").toggleClass("ui-state-disabled", !this.val());
		}
	});

	$(".workflow-field .workflow-field-do-create").entwine({
		onclick: function() {
			var sel   = this.siblings(".workflow-field-create-class");
			var field = this.closest(".workflow-field");

			if(sel.val()) {
				field.showDialog(sel.val());
			}

			return false;
		}
	});

	$(".workflow-field .workflow-field-open-dialog").entwine({
		onclick: function() {
			this.closest(".workflow-field").showDialog(this.prop("href"));
			return false;
		}
	});

	$(".workflow-field .workflow-field-delete").entwine({
		onclick: function() {
			if(confirm("Are you sure you want to permanently delete this?")) {

			}

			return false;
		}
	});
});<commit_msg>BUGFIX Implementation of the javascript ajax request for workflow action deletion<commit_after>jQuery.entwine("workflow", function($) {
	$(".workflow-field").entwine({
		Loading: null,
		Dialog:  null,
		onmatch: function() {
			var self = this;

			this.setLoading(this.find(".workflow-field-loading"));
			this.setDialog(this.find(".workflow-field-dialog"));

			this.getDialog().data("workflow-field", this).dialog({
				autoOpen: false,
				width:    800,
				height:   600,
				modal:    true
			});

			this.getDialog().on("click", "button", function() {
				$(this).addClass("loading ui-state-disabled");
			});

			this.getDialog().on("submit", "form", function() {
				$(this).ajaxSubmit(function(response) {
					if($(response).is(".workflow-field")) {
						self.getDialog().empty().dialog("close");
						self.replaceWith(response);
					} else {
						self.getDialog().html(response);
					}
				});

				return false;
			});
		},
		showDialog: function(url) {
			var dlg = this.getDialog();

			dlg.empty().dialog("open");
			dlg.parent().addClass("loading");

			$.get(url).done(function(body) {
				dlg.html(body).parent().removeClass("loading");
			});
		},
		loading: function(toggle) {
			this.getLoading().toggle(typeof(toggle) == "undefined" || toggle);
		}
	});

	function helper() {
		return $("<div />").addClass("ui-state-highlight").appendTo("body");
	}

	$(".workflow-field .workflow-field-actions").entwine({
		onmatch: function() {
			this.sortable({
				axis:        "y",
				containment: this,
				placeholder: "ui-state-highlight workflow-placeholder",
				handle:      ".workflow-field-action-drag",
				tolerance:   "pointer",
				update: function() {
					var actions = $(this).find(".workflow-field-action");
					var field   = $(this).closest(".workflow-field");
					var link    = field.data("sort-link");
					var ids     = actions.map(function() { return $(this).data("id"); });

					var data = {
						"id[]":  ids.get(),
						"class": "WorkflowAction"
					};

					field.loading();
					$.post(link, data).done(function() { field.loading(false); });
				}
			});
		}
	});

	$(".workflow-field .workflow-field-action-transitions").entwine({
		onmatch: function() {
			this.sortable({
				axis:        "y",
				containment: this,
				handle:      ".workflow-field-action-drag",
				tolerance:   "pointer",
				update: function() {
					var trans = $(this).find("li");
					var field = $(this).closest(".workflow-field");
					var link  = field.data("sort-link");
					var ids   = trans.map(function() { return $(this).data("id"); });

					var data = {
						"id[]":   ids.get(),
						"class":  "WorkflowTransition",
						"parent": $(this).closest(".workflow-field-action").data("id")
					};

					field.loading();
					$.post(link, data).done(function() { field.loading(false); });
				}
			});
		}
	});

	$(".workflow-field .workflow-field-create-class").entwine({
		onmatch: function() {
			this.chosen().addClass("has-chnz");
		},
		onchange: function() {
			this.siblings(".workflow-field-do-create").toggleClass("ui-state-disabled", !this.val());
		}
	});

	$(".workflow-field .workflow-field-do-create").entwine({
		onclick: function() {
			var sel   = this.siblings(".workflow-field-create-class");
			var field = this.closest(".workflow-field");

			if(sel.val()) {
				field.showDialog(sel.val());
			}

			return false;
		}
	});

	$(".workflow-field .workflow-field-open-dialog").entwine({
		onclick: function() {
			this.closest(".workflow-field").showDialog(this.prop("href"));
			return false;
		}
	});

	$(".workflow-field .workflow-field-delete").entwine({
		onclick: function() {
			if(confirm("Are you sure you want to permanently delete this?")) {
				$.post(this.prop('href')).done(function(body) {
					$(".workflow-field").replaceWith(body);
				});
			}

			return false;
		}
	});
});<|endoftext|>


<commit_before>import parseEncode from '../encode';
import {FrameRole, MarkRole} from '../marks/roles';
import {array, extend, hasOwnProperty, isArray, isObject} from 'vega-util';

export function encoder(_) {
  return isObject(_) ? extend({}, _) : {value: _};
}

export function addEncode(object, name, value, set) {
  if (value != null) {
    if (isObject(value) && !isArray(value)) {
      object.update[name] = value;
    } else {
      object[set || 'enter'][name] = {value: value};
    }
    return 1;
  } else {
    return 0;
  }
}

export function addEncoders(object, enter, update) {
  for (let name in enter) {
    addEncode(object, name, enter[name]);
  }
  for (let name in update) {
    addEncode(object, name, update[name], 'update');
  }
}

export function extendEncode(encode, extra, skip) {
  for (var name in extra) {
    if (skip && hasOwnProperty(skip, name)) continue;
    encode[name] = extend(encode[name] || {}, extra[name]);
  }
  return encode;
}

export function encoders(encode, type, role, style, scope, params) {
  var enc, key;
  params = params || {};
  params.encoders = {$encode: (enc = {})};

  encode = applyDefaults(encode, type, role, style, scope.config);

  for (key in encode) {
    enc[key] = parseEncode(encode[key], type, params, scope);
  }

  return params;
}

function applyDefaults(encode, type, role, style, config) {
  var enter = {}, key, skip, props;

  // ignore legend and axis
  if (role == 'legend' || String(role).indexOf('axis') === 0) {
    role = null;
  }

  // resolve mark config
  props = role === FrameRole ? config.group
    : (role === MarkRole) ? extend({}, config.mark, config[type])
    : null;

  for (key in props) {
    // do not apply defaults if relevant fields are defined
    skip = has(key, encode)
      || (key === 'fill' || key === 'stroke')
      && (has('fill', encode) || has('stroke', encode));

    if (!skip) enter[key] = defaultEncode(props[key]);
  }

  // resolve styles, apply with increasing precedence
  array(style).forEach(function(name) {
    var props = config.style && config.style[name];
    for (var key in props) {
      if (!has(key, encode)) {
        enter[key] = defaultEncode(props[key]);
      }
    }
  });

  encode = extend({}, encode); // defensive copy
  encode.enter = extend(enter, encode.enter);

  return encode;
}

function defaultEncode(value) {
  return value && value.signal
    ? {signal: value.signal}
    : {value: value};
}

export function has(key, encode) {
  return encode && (
    (encode.enter && encode.enter[key]) ||
    (encode.update && encode.update[key])
  );
}
<commit_msg>Assign signal-valued defaults to update set.<commit_after>import parseEncode from '../encode';
import {FrameRole, MarkRole} from '../marks/roles';
import {array, extend, hasOwnProperty, isArray, isObject} from 'vega-util';

export function encoder(_) {
  return isObject(_) ? extend({}, _) : {value: _};
}

export function addEncode(object, name, value, set) {
  if (value != null) {
    if (isObject(value) && !isArray(value)) {
      object.update[name] = value;
    } else {
      object[set || 'enter'][name] = {value: value};
    }
    return 1;
  } else {
    return 0;
  }
}

export function addEncoders(object, enter, update) {
  for (let name in enter) {
    addEncode(object, name, enter[name]);
  }
  for (let name in update) {
    addEncode(object, name, update[name], 'update');
  }
}

export function extendEncode(encode, extra, skip) {
  for (var name in extra) {
    if (skip && hasOwnProperty(skip, name)) continue;
    encode[name] = extend(encode[name] || {}, extra[name]);
  }
  return encode;
}

export function encoders(encode, type, role, style, scope, params) {
  var enc, key;
  params = params || {};
  params.encoders = {$encode: (enc = {})};

  encode = applyDefaults(encode, type, role, style, scope.config);

  for (key in encode) {
    enc[key] = parseEncode(encode[key], type, params, scope);
  }

  return params;
}

function applyDefaults(encode, type, role, style, config) {
  var defaults = {}, enter = {}, update, key, skip, props;

  // ignore legend and axis
  if (role == 'legend' || String(role).indexOf('axis') === 0) {
    role = null;
  }

  // resolve mark config
  props = role === FrameRole ? config.group
    : (role === MarkRole) ? extend({}, config.mark, config[type])
    : null;

  for (key in props) {
    // do not apply defaults if relevant fields are defined
    skip = has(key, encode)
      || (key === 'fill' || key === 'stroke')
      && (has('fill', encode) || has('stroke', encode));

    if (!skip) applyDefault(defaults, key, props[key]);
  }

  // resolve styles, apply with increasing precedence
  array(style).forEach(function(name) {
    var props = config.style && config.style[name];
    for (var key in props) {
      if (!has(key, encode)) {
        applyDefault(defaults, key, props[key]);
      }
    }
  });

  encode = extend({}, encode); // defensive copy
  for (key in defaults) {
    props = defaults[key];
    if (props.signal) {
      (update = update || {})[key] = props;
    } else {
      enter[key] = props;
    }
  }

  encode.enter = extend(enter, encode.enter);
  if (update) encode.update = extend(update, encode.update);

  return encode;
}

function applyDefault(defaults, key, value) {
  defaults[key] = value && value.signal
    ? {signal: value.signal}
    : {value: value}
}

export function has(key, encode) {
  return encode && (
    (encode.enter && encode.enter[key]) ||
    (encode.update && encode.update[key])
  );
}
<|endoftext|>