<commit_before>'use strict';
/* Draws a dependencyTree
 *
 * Can be used in isolation and awaits tokens passed into it, which have
 * a head.id property.
 *
 * The directive needs to be set on an svg element as attribute.
 *
 * Styling of the tree can be customized by passing a styles object as
 * attribute.
 * This object should be a dictionary of token ids with style information
 * in three categories: edge, label and token.
 * These properties should hold regular css style information. Example
 *
 *   {
 *     '0001' : {
 *       edge: { stroke: 'blue' },
 *       token: { color: 'white' }
 *     }
 *   }
 *
 * This would draw the edge of the token 0001 one blue and the textual
 * representation of the token itself in white.
 *
 * Tokens are rendered by the token directive. If no styles object has
 * been passed to the dependencyTree directive, the token itself will
 * decide its styling.
 * Hover and click events for tokens are activated. An option to customize
 * this will follow.
 *
 * Watches are in effect for changes of a tokens head.id value, changes
 * in the styles object, as well as in the tokens object.
 *
 * Example, given a tokens and a styles object in the current scope:
 *
 *   <svg dependency-tree tokens="tokens" styles="styles/>
 *
 */
/* global dagreD3 */
angular.module('arethusa.depTree').directive('dependencyTree', [
  '$compile',
  'languageSettings',
  'keyCapture',
  'idHandler',
  function ($compile, languageSettings, keyCapture, idHandler) {
    return {
      restrict: 'A',
      scope: {
        tokens: '=',
        styles: '='
      },
      link: function (scope, element, attrs) {
        var rootText = "[ROOT]";
        var rootId = idHandler.getId('0');

        function rootPlaceholder() {
          return '
' + rootText + '
';
        }

        function tokenPlaceholder(token) {
          return '
' + token.string + '
';
        }
        function labelPlaceholder(token) {
          //var label = generateLabel(token);
          var label = 'xxxxxxxxxxx';
          var id = token.id;
          var classes = 'text-center tree-label';
          return '
' + label + '
';
        }
        function generateLabel(token) {
          return (token.relation || {}).label;
        }
        function tokenHasCustomStyling(token) {
          var t = scope.styles[token.id] || {};
          return t.token;
        }
        function applyTokenStyling(childScope, token) {
          childScope.style = scope.styles[token.id].token;
        }
        // Right now this function is responsible for managing the label and
        // edge colors when a custom styling is available.
        //
        // Once the relation plugin is ready, the label will be handled by
        // a directive that is coming from there.
        //
        // The directive will only stay responsible for the edges.
        //
        // If an edge style is overridden, we safe the old value in the
        // styleResets object. the resetEdgeStyling() function will now
        // how to operate with this then.
        var styleResets = {};
        function applyCustomStyling() {
          var edges = vis.selectAll('g.edgePath path');
          angular.forEach(scope.styles, function (style, id) {
            var labelStyle = style.label;
            var edgeStyle = style.edge;
            if (labelStyle) {
              label(id).style(labelStyle);
            }
            if (edgeStyle) {
              saveOldEdgeStyles(id, edgeStyle);
              edge(id).style(edgeStyle);
            }
          });
        }
        function saveOldEdgeStyles(id, properties) {
          if (properties) {
            var e = edge(id);
            var style = {};
            angular.forEach(properties, function (_, property) {
              style[property] = e.style(property);
            });
            styleResets[id] = style;
          }
        }
        function compiledEdgeLabel(token) {
          var template = '';
          var childScope = scope.$new();
          childScope.obj = token.relation;
          return $compile(template)(childScope)[0];
        }
        function compiledToken(token) {
          var childScope = scope.$new();
          childScope.token = token;
          // Ugly but working...
          // We replace the colorize value in our token template string.
          // If custom styles are given, we check if one is available for
          // this token. If yes, we use it, otherwise we just pass one
          // undefined which leaves the token unstyled.
          //
          // Without custom styles we let the token itself decide what color
          // it has.
          var style;
          if (scope.styles) {
            if (tokenHasCustomStyling(token)) {
              applyTokenStyling(childScope, token);
            }
            // else we just stay undefined
            style = 'style';
          } else {
            style = 'true';
          }
          return $compile(tokenHtml.replace('STYLE', style))(childScope)[0];
        }
        var tokenHtml ='';
        var rootTokenHtml = '' + rootText + '';

        // Creating the node set
        // g will hold the graph and be set when new tokens are loaded,
        // vis will be it's d3 representation
        var g;
        var vis;
        function createRootNode() {
          g.addNode(rootId, { label: rootPlaceholder() });
        }
        function createNode(token) {
          g.addNode(token.id, { label: tokenPlaceholder(token) });
        }
        function nodePresent(id) {
          return g._nodes[id];
        }
        function hasHead(token) {
          return (token.head || {}).id;
        }
        function createEdges() {
          angular.forEach(scope.tokens, function (token, index) {
            if (hasHead(token)) {
              drawEdge(token);
            }
          });
        }
        function edges() {
          return vis.selectAll('g.edgePath path');
        }
        function edge(id) {
          return vis.select('#' + edgeId(id));
        }
        function edgePresent(id) {
          return edge(id)[0][0];  // yes, that's valid d3 syntax
        }
        function edgeId(id) {
          return 'tep' + id;
        }
        function label(id) {
          return vis.select('#' + labelId(id));
        }
        function labelId(id) {
          return 'tel' + id;
        }
        function nodeId(id) {
          return 'tph' + id;
        }
        function node(id) {
          return vis.select('#' + nodeId(id));
        }
        function nodes() {
          return vis.selectAll('div.node');
        }
        function drawEdge(token) {
          if (!nodePresent(token.id)) {
            createNode(token);
          }
          if (!nodePresent(token.head.id)) {
            createNode(scope.tokens[token.head.id]);
          }
          g.addEdge(token.id, token.id, token.head.id, { label: labelPlaceholder(token) });
        }
        function updateEdge(token) {
          if (edgePresent(token.id)) {
            g.delEdge(token.id);
          }
          drawEdge(token);
        }
        function resetEdgeStyling() {
          angular.forEach(styleResets, function (style, id) {
            edge(id).style(style);
          });
          styleResets = {};  // clean up, to avoid constant resetting
        }
        function createGraph(subtrees) {
          g = new dagreD3.Digraph();
          createRootNode();
          createEdges();
          render();
        }
        // Initialize the graph
        scope.compactTree = function() {
          scope.nodeSep = 30;
          scope.edgeSep = 10;
          scope.rankSep = 30;
        };

        scope.wideTree = function() {
          scope.nodeSep = 80;
          scope.edgeSep = 5;
          scope.rankSep = 40;
        };
        scope.changeDir = function() {
          var horDir;
          if (sortRankByIdAscending()) {
            horDir = "RL";
          } else {
            horDir = "LR";
            scope.textDirection = !scope.textDirection;
          }
          scope.rankDir = scope.rankDir === "BT" ? horDir : "BT";
        };

        function sortRankByIdAscending() {
          var langSettings = languageSettings.getFor('treebank');
          return langSettings ? langSettings.leftToRight : true;
        }

        scope.textDirection = sortRankByIdAscending();

        scope.rankDir = 'BT';
        scope.compactTree();

        scope.layout = dagreD3.layout()
          .sortRankByIdAscending(scope.textDirection)
          .rankDir(scope.rankDir)
          .nodeSep(scope.nodeSep)
          .edgeSep(scope.edgeSep)
          .rankSep(scope.rankSep);

        var svg = d3.select(element[0]);
        svg.call(d3.behavior.zoom().on('zoom', function () {
          var ev = d3.event;
          svg.select('g').attr('transform', 'translate(' + ev.translate + ') scale(' + ev.scale + ')');
        }).scaleExtent([0.3, 2.5]));
        var renderer = new dagreD3.Renderer();

        function transition(selection) {
          return selection.transition().duration(700);
        }
        renderer.transition(transition);

        // Prepend Tree settings panel
        scope.settingOn = false;
        element.wrap('

');
        var wrapper = element.parent();
        var panel = '\

\

\
             \
             \
             \
            compact \
            wide \
            change direction\

\
        ';
        wrapper.prepend($compile(panel)(scope));

        function insertRootDirective() {
          node(rootId).append(function() {
            this.textContent = '';
            return $compile(rootTokenHtml)(scope)[0];
          });
        }
        function insertTokenDirectives() {
          nodes().append(function () {
            // This is the element we append to and we created as a placeholder
            // We clear out its text content so that we can display the content
            // of our compiled token directive.
            // The placholder has an id in the format of tphXXXX where XXXX is the id.
            this.textContent = '';
            return compiledToken(scope.tokens[this.id.slice(3)]);
          });
        }
        function insertEdgeDirectives() {
          angular.forEach(scope.tokens, function (token, id) {
            label(id).append(function () {
              this.textContent = '';
              return compiledEdgeLabel(token);
            });
          });
        }
        function render() {
          vis = svg.select('g');
          renderer.layout(scope.layout).run(g, vis);
          // Customize the graph so that it holds our directives
          insertRootDirective();
          insertTokenDirectives();
          insertEdgeDirectives();

          // Not very elegant, but we don't want marker-end arrowheads right now
          // We also place an token edge path (tep) id on these elements, so that
          // we can access them more easily later on.
          edges().each(function (id) {
            angular.element(this).attr('id', edgeId(id));
          }).attr('marker-end', '');

          // A bug in webkit makes it impossible to select camelCase tags...
          // We work around by using a function.
          // http://stackoverflow.com/questions/11742812/cannot-select-svg-foreignobject-element-in-d3
          vis.selectAll(function () {
            return this.getElementsByTagName('foreignObject');
          }).each(function () {
            angular.element(this.children[0]).attr('style', 'float: center;');
          });
        }

        function createHeadWatches() {
          angular.forEach(scope.tokens, function (token, id) {
            var childScope = scope.$new();
            childScope.token = token.id;
            childScope.head = token.head;
            childScope.$watch('head.id', function (newVal, oldVal) { // Very important to do here, otherwise the tree will
              // be render a little often on startup...
              if (newVal !== oldVal) {
                // If a disconnection has been requested, we just
                // have to delete the edge and do nothing else
                if (newVal === "") {
                  g.delEdge(token.id);
                } else {
                  updateEdge(token);
                }
                render();
              }
            });
          });
        }

        scope.$watch('tokens', function (newVal, oldVal) {
          createGraph();
          createHeadWatches();
        });
        scope.$watch('styles', function (newVal, oldVal) {
          if (newVal !== oldVal) {
            render();
            if (newVal) {
              applyCustomStyling();
            } else {
              resetEdgeStyling();
            }
          }
        });

        // Settings watches
        var watches = {
          'nodeSep': function(newVal) { scope.layout.nodeSep(newVal); },
          'edgeSep': function(newVal) { scope.layout.edgeSep(newVal); },
          'edgeDir': function(newVal) { scope.layout.edgeDir(newVal); },
          'nodeDir': function(newVal) { scope.layout.nodeDir(newVal); },
          'rankDir': function(newVal) { scope.layout.rankDir(newVal); },
          'textDirection': function(newVal) { scope.layout.sortRankByIdAscending(newVal); }
        };

        angular.forEach(watches, function(fn, attr) {
          scope.$watch(attr, function(newVal, oldVal) {
            if (newVal !== oldVal) {
              fn(newVal);
              render();
            }
          });
        });

        keyCapture.initCaptures(function(kC) {
          return {
            tree: [
              kC.create('directionChange', function() { scope.changeDir(); })
            ]
          };
        });
      },
      template: '<svg class="full-height full-width"><g/></svg>'
    };
  }
]);
<commit_msg>Restructure tree settings panel<commit_after>'use strict';
/* Draws a dependencyTree
 *
 * Can be used in isolation and awaits tokens passed into it, which have
 * a head.id property.
 *
 * The directive needs to be set on an svg element as attribute.
 *
 * Styling of the tree can be customized by passing a styles object as
 * attribute.
 * This object should be a dictionary of token ids with style information
 * in three categories: edge, label and token.
 * These properties should hold regular css style information. Example
 *
 *   {
 *     '0001' : {
 *       edge: { stroke: 'blue' },
 *       token: { color: 'white' }
 *     }
 *   }
 *
 * This would draw the edge of the token 0001 one blue and the textual
 * representation of the token itself in white.
 *
 * Tokens are rendered by the token directive. If no styles object has
 * been passed to the dependencyTree directive, the token itself will
 * decide its styling.
 * Hover and click events for tokens are activated. An option to customize
 * this will follow.
 *
 * Watches are in effect for changes of a tokens head.id value, changes
 * in the styles object, as well as in the tokens object.
 *
 * Example, given a tokens and a styles object in the current scope:
 *
 *   <svg dependency-tree tokens="tokens" styles="styles/>
 *
 */
/* global dagreD3 */
angular.module('arethusa.depTree').directive('dependencyTree', [
  '$compile',
  'languageSettings',
  'keyCapture',
  'idHandler',
  function ($compile, languageSettings, keyCapture, idHandler) {
    return {
      restrict: 'A',
      scope: {
        tokens: '=',
        styles: '='
      },
      link: function (scope, element, attrs) {
        var rootText = "[ROOT]";
        var rootId = idHandler.getId('0');

        function rootPlaceholder() {
          return '
' + rootText + '
';
        }

        function tokenPlaceholder(token) {
          return '
' + token.string + '
';
        }
        function labelPlaceholder(token) {
          //var label = generateLabel(token);
          var label = 'xxxxxxxxxxx';
          var id = token.id;
          var classes = 'text-center tree-label';
          return '
' + label + '
';
        }
        function generateLabel(token) {
          return (token.relation || {}).label;
        }
        function tokenHasCustomStyling(token) {
          var t = scope.styles[token.id] || {};
          return t.token;
        }
        function applyTokenStyling(childScope, token) {
          childScope.style = scope.styles[token.id].token;
        }
        // Right now this function is responsible for managing the label and
        // edge colors when a custom styling is available.
        //
        // Once the relation plugin is ready, the label will be handled by
        // a directive that is coming from there.
        //
        // The directive will only stay responsible for the edges.
        //
        // If an edge style is overridden, we safe the old value in the
        // styleResets object. the resetEdgeStyling() function will now
        // how to operate with this then.
        var styleResets = {};
        function applyCustomStyling() {
          var edges = vis.selectAll('g.edgePath path');
          angular.forEach(scope.styles, function (style, id) {
            var labelStyle = style.label;
            var edgeStyle = style.edge;
            if (labelStyle) {
              label(id).style(labelStyle);
            }
            if (edgeStyle) {
              saveOldEdgeStyles(id, edgeStyle);
              edge(id).style(edgeStyle);
            }
          });
        }
        function saveOldEdgeStyles(id, properties) {
          if (properties) {
            var e = edge(id);
            var style = {};
            angular.forEach(properties, function (_, property) {
              style[property] = e.style(property);
            });
            styleResets[id] = style;
          }
        }
        function compiledEdgeLabel(token) {
          var template = '';
          var childScope = scope.$new();
          childScope.obj = token.relation;
          return $compile(template)(childScope)[0];
        }
        function compiledToken(token) {
          var childScope = scope.$new();
          childScope.token = token;
          // Ugly but working...
          // We replace the colorize value in our token template string.
          // If custom styles are given, we check if one is available for
          // this token. If yes, we use it, otherwise we just pass one
          // undefined which leaves the token unstyled.
          //
          // Without custom styles we let the token itself decide what color
          // it has.
          var style;
          if (scope.styles) {
            if (tokenHasCustomStyling(token)) {
              applyTokenStyling(childScope, token);
            }
            // else we just stay undefined
            style = 'style';
          } else {
            style = 'true';
          }
          return $compile(tokenHtml.replace('STYLE', style))(childScope)[0];
        }
        var tokenHtml ='';
        var rootTokenHtml = '' + rootText + '';

        // Creating the node set
        // g will hold the graph and be set when new tokens are loaded,
        // vis will be it's d3 representation
        var g;
        var vis;
        function createRootNode() {
          g.addNode(rootId, { label: rootPlaceholder() });
        }
        function createNode(token) {
          g.addNode(token.id, { label: tokenPlaceholder(token) });
        }
        function nodePresent(id) {
          return g._nodes[id];
        }
        function hasHead(token) {
          return (token.head || {}).id;
        }
        function createEdges() {
          angular.forEach(scope.tokens, function (token, index) {
            if (hasHead(token)) {
              drawEdge(token);
            }
          });
        }
        function edges() {
          return vis.selectAll('g.edgePath path');
        }
        function edge(id) {
          return vis.select('#' + edgeId(id));
        }
        function edgePresent(id) {
          return edge(id)[0][0];  // yes, that's valid d3 syntax
        }
        function edgeId(id) {
          return 'tep' + id;
        }
        function label(id) {
          return vis.select('#' + labelId(id));
        }
        function labelId(id) {
          return 'tel' + id;
        }
        function nodeId(id) {
          return 'tph' + id;
        }
        function node(id) {
          return vis.select('#' + nodeId(id));
        }
        function nodes() {
          return vis.selectAll('div.node');
        }
        function drawEdge(token) {
          if (!nodePresent(token.id)) {
            createNode(token);
          }
          if (!nodePresent(token.head.id)) {
            createNode(scope.tokens[token.head.id]);
          }
          g.addEdge(token.id, token.id, token.head.id, { label: labelPlaceholder(token) });
        }
        function updateEdge(token) {
          if (edgePresent(token.id)) {
            g.delEdge(token.id);
          }
          drawEdge(token);
        }
        function resetEdgeStyling() {
          angular.forEach(styleResets, function (style, id) {
            edge(id).style(style);
          });
          styleResets = {};  // clean up, to avoid constant resetting
        }
        function createGraph(subtrees) {
          g = new dagreD3.Digraph();
          createRootNode();
          createEdges();
          render();
        }
        // Initialize the graph
        scope.compactTree = function() {
          scope.nodeSep = 30;
          scope.edgeSep = 10;
          scope.rankSep = 30;
        };

        scope.wideTree = function() {
          scope.nodeSep = 80;
          scope.edgeSep = 5;
          scope.rankSep = 40;
        };
        scope.changeDir = function() {
          var horDir;
          if (sortRankByIdAscending()) {
            horDir = "RL";
          } else {
            horDir = "LR";
            scope.textDirection = !scope.textDirection;
          }
          scope.rankDir = scope.rankDir === "BT" ? horDir : "BT";
        };

        function sortRankByIdAscending() {
          var langSettings = languageSettings.getFor('treebank');
          return langSettings ? langSettings.leftToRight : true;
        }

        scope.textDirection = sortRankByIdAscending();

        scope.rankDir = 'BT';
        scope.compactTree();

        scope.layout = dagreD3.layout()
          .sortRankByIdAscending(scope.textDirection)
          .rankDir(scope.rankDir)
          .nodeSep(scope.nodeSep)
          .edgeSep(scope.edgeSep)
          .rankSep(scope.rankSep);

        var svg = d3.select(element[0]);
        svg.call(d3.behavior.zoom().on('zoom', function () {
          var ev = d3.event;
          svg.select('g').attr('transform', 'translate(' + ev.translate + ') scale(' + ev.scale + ')');
        }).scaleExtent([0.3, 2.5]));
        var renderer = new dagreD3.Renderer();

        function transition(selection) {
          return selection.transition().duration(700);
        }
        renderer.transition(transition);

        // Prepend Tree settings panel
        scope.settingsOn = false;
        element.wrap('

');
        var wrapper = element.parent();

        // We temporarily disable the fine-grained tree settings - they are a
        // little buggy.
            // \
            // \
            // \
        var panel = '\

\
            \

\
          \

\

\
                \
                  \
                \

\

\
                \
                  \
                \

\

\
                \
                  \
                \

\

\
         \
        ';
        wrapper.prepend($compile(panel)(scope));

        function insertRootDirective() {
          node(rootId).append(function() {
            this.textContent = '';
            return $compile(rootTokenHtml)(scope)[0];
          });
        }
        function insertTokenDirectives() {
          nodes().append(function () {
            // This is the element we append to and we created as a placeholder
            // We clear out its text content so that we can display the content
            // of our compiled token directive.
            // The placholder has an id in the format of tphXXXX where XXXX is the id.
            this.textContent = '';
            return compiledToken(scope.tokens[this.id.slice(3)]);
          });
        }
        function insertEdgeDirectives() {
          angular.forEach(scope.tokens, function (token, id) {
            label(id).append(function () {
              this.textContent = '';
              return compiledEdgeLabel(token);
            });
          });
        }
        function render() {
          vis = svg.select('g');
          renderer.layout(scope.layout).run(g, vis);
          // Customize the graph so that it holds our directives
          insertRootDirective();
          insertTokenDirectives();
          insertEdgeDirectives();

          // Not very elegant, but we don't want marker-end arrowheads right now
          // We also place an token edge path (tep) id on these elements, so that
          // we can access them more easily later on.
          edges().each(function (id) {
            angular.element(this).attr('id', edgeId(id));
          }).attr('marker-end', '');

          // A bug in webkit makes it impossible to select camelCase tags...
          // We work around by using a function.
          // http://stackoverflow.com/questions/11742812/cannot-select-svg-foreignobject-element-in-d3
          vis.selectAll(function () {
            return this.getElementsByTagName('foreignObject');
          }).each(function () {
            angular.element(this.children[0]).attr('style', 'float: center;');
          });
        }

        function createHeadWatches() {
          angular.forEach(scope.tokens, function (token, id) {
            var childScope = scope.$new();
            childScope.token = token.id;
            childScope.head = token.head;
            childScope.$watch('head.id', function (newVal, oldVal) { // Very important to do here, otherwise the tree will
              // be render a little often on startup...
              if (newVal !== oldVal) {
                // If a disconnection has been requested, we just
                // have to delete the edge and do nothing else
                if (newVal === "") {
                  g.delEdge(token.id);
                } else {
                  updateEdge(token);
                }
                render();
              }
            });
          });
        }

        scope.$watch('tokens', function (newVal, oldVal) {
          createGraph();
          createHeadWatches();
        });
        scope.$watch('styles', function (newVal, oldVal) {
          if (newVal !== oldVal) {
            render();
            if (newVal) {
              applyCustomStyling();
            } else {
              resetEdgeStyling();
            }
          }
        });

        // Settings watches
        var watches = {
          'nodeSep': function(newVal) { scope.layout.nodeSep(newVal); },
          'edgeSep': function(newVal) { scope.layout.edgeSep(newVal); },
          'edgeDir': function(newVal) { scope.layout.edgeDir(newVal); },
          'nodeDir': function(newVal) { scope.layout.nodeDir(newVal); },
          'rankDir': function(newVal) { scope.layout.rankDir(newVal); },
          'textDirection': function(newVal) { scope.layout.sortRankByIdAscending(newVal); }
        };

        angular.forEach(watches, function(fn, attr) {
          scope.$watch(attr, function(newVal, oldVal) {
            if (newVal !== oldVal) {
              fn(newVal);
              render();
            }
          });
        });

        keyCapture.initCaptures(function(kC) {
          return {
            tree: [
              kC.create('directionChange', function() { scope.changeDir(); })
            ]
          };
        });
      },
      template: '<svg class="full-height full-width"><g/></svg>'
    };
  }
]);
<|endoftext|>


<commit_before>var fs = require('fs')
var test = require('tape')
var path = require('path')
var rimraf = require('rimraf')
var yaml = require('yamljs')
var tmp = require('tmp')
var frontmatter = require('yaml-front-matter')

var fetchDocs = require('../lib/fetch-docs.js')

var settings = {
  configFile: path.join(__dirname, 'fixtures/test_config.yml'),
  tmpDir: tmp.dirSync().name,
  targetDir: tmp.dirSync().name
}

test('Fetch and write documentation', function (t) {

  t.plan(7)

  fetchDocs(settings, function callback (error, message) {
    if (error) return t.fail(error)
    if (message) console.log(message)

    t.ok(fs.existsSync(settings.targetDir), 'Docs folder created.')

    var config = yaml.load(settings.configFile)

    t.equal(config.latest_version, settings.version, 'Config: Latest version set.')

    var sampleDoc = fs.readFileSync(path.join(settings.targetDir, 'api', 'accelerator.md'))
    var sampleFM = frontmatter.loadFront(sampleDoc)

    t.equal(sampleFM.title, 'Accelerator', 'Frontmatter: Adds permalink to README.')

    var expectedSourceUrl = 'https://github.com/electron/electron/blob/master/docs/api/accelerator.md'
    t.equal(sampleFM.source_url, expectedSourceUrl, 'Frontmatter: Adds file source url')

    t.equal(sampleFM.version, settings.version, 'Frontmatter: Adds version.')
    t.equal(sampleFM.category, 'API', 'Frontmatter: Adds category.')

    t.ok(sampleFM.redirect_from.indexOf('/docs/v0.25.0/api/accelerator/') > -1, 'Frontmatter: Adds redirects.')

    tearDown(settings, config)
  })
})

function tearDown (settings, config) {
  config.latest_version = '0.0.0'
  config.available_versions = ['v0.27.0', 'v0.26.0', 'v0.25.0']
  fs.writeFileSync(settings.configFile, yaml.stringify(config))
}
<commit_msg>Remove v from version<commit_after>var fs = require('fs')
var test = require('tape')
var path = require('path')
var rimraf = require('rimraf')
var yaml = require('yamljs')
var tmp = require('tmp')
var frontmatter = require('yaml-front-matter')

var fetchDocs = require('../lib/fetch-docs.js')

var settings = {
  configFile: path.join(__dirname, 'fixtures/test_config.yml'),
  tmpDir: tmp.dirSync().name,
  targetDir: tmp.dirSync().name
}

test('Fetch and write documentation', function (t) {

  t.plan(7)

  fetchDocs(settings, function callback (error, message) {
    if (error) return t.fail(error)
    if (message) console.log(message)

    t.ok(fs.existsSync(settings.targetDir), 'Docs folder created.')

    var config = yaml.load(settings.configFile)

    t.equal(config.latest_version, settings.version.substring(1), 'Config: Latest version set.')

    var sampleDoc = fs.readFileSync(path.join(settings.targetDir, 'api', 'accelerator.md'))
    var sampleFM = frontmatter.loadFront(sampleDoc)

    t.equal(sampleFM.title, 'Accelerator', 'Frontmatter: Adds permalink to README.')

    var expectedSourceUrl = 'https://github.com/electron/electron/blob/master/docs/api/accelerator.md'
    t.equal(sampleFM.source_url, expectedSourceUrl, 'Frontmatter: Adds file source url')

    t.equal(sampleFM.version, settings.version, 'Frontmatter: Adds version.')
    t.equal(sampleFM.category, 'API', 'Frontmatter: Adds category.')

    t.ok(sampleFM.redirect_from.indexOf('/docs/v0.25.0/api/accelerator/') > -1, 'Frontmatter: Adds redirects.')

    tearDown(settings, config)
  })
})

function tearDown (settings, config) {
  config.latest_version = '0.0.0'
  config.available_versions = ['v0.27.0', 'v0.26.0', 'v0.25.0']
  fs.writeFileSync(settings.configFile, yaml.stringify(config))
}
<|endoftext|>


<commit_before>/**
    ServiceProfessional Service activity
**/
'use strict';

var ko = require('knockout'),
    Activity = require('../components/Activity'),
    ServiceProfessionalServiceViewModel = require('../viewmodels/ServiceProfessionalService'),
    $ = require('jquery'),
    RouteMatcher = require('../utils/Router').RouteMatcher,
    Route = require('../utils/Router').Route;

var A = Activity.extend(function ServiceProfessionalServiceActivity() {

    Activity.apply(this, arguments);

    this.accessLevel = this.app.UserType.serviceProfessional;
    this.viewModel = new ViewModel(this.app);
    // Defaults settings for navBar.
    this.navBar = Activity.createSubsectionNavBar('Job Title', {
        backLink: '/scheduling', helpLink: this.viewModel.helpLink
    });
    // Save defaults to restore on updateNavBarState when needed:
    this.defaultLeftAction = this.navBar.leftAction().model.toPlainObject(true);
    // Make navBar available at viewModel, needed for dekstop navigation
    this.viewModel.navBar = this.navBar;

    // On changing jobTitleID:
    this.registerHandler({
        target: this.viewModel.jobTitle,
        handler: function(/*jobTitle*/) {
            // Update navbar (may indicate the jobTitle name)
            this.updateNavBarState();

            // May depend on current URL, will change with job title
            this.viewModel.serviceEditorCancelLink(this.serviceEditorCancelLink(this.viewModel.isAdditionMode()));
        }.bind(this)
    });

    // On changing jobTitleID:
    this.registerHandler({
        target: this.viewModel.jobTitleID,
        handler: function(jobTitleID) {

            if (jobTitleID) {

                var params = this.parseRoute(this.requestData.route.path),
                    urlJobTitleID = +params.jobTitleID,
                    clientID = +params.clientID;

                if (urlJobTitleID !== jobTitleID) {
                    var url = this.buildRoute(jobTitleID, clientID, params.isNew);

                    this.app.shell.replaceState(this.requestData, null, url);
                }
            }
        }.bind(this)
    });

    this.registerHandler({
        target: this.viewModel.clientID,
        handler: function(clientID) {
            var viewModel = this.viewModel,
                app = this.app;

            viewModel.client(null);

            if(clientID) {
                app.model.clients.getItem(clientID)
                .then(function(client) {
                    viewModel.client(client);
                })
                .catch(function(error) {
                    app.modals.showError({ title: 'Unable to load client.', error: error });
                });
            }
        }.bind(this)
    });

    // Go back with the selected pricing when triggered in the form/view
    this.viewModel.returnSelected = function(pricing, jobTitleID) {
        // Pass the selected client in the info
        this.requestData.selectedServices = pricing;
        this.requestData.selectedJobTitleID = jobTitleID;
        // And go back
        this.app.shell.goBack(this.requestData);
    }.bind(this);

    this.returnRequest = function returnRequest() {
        this.app.shell.goBack(this.requestData);
    }.bind(this);
});

exports.init = A.init;

A.prototype.applyOwnNavbarRules = function() {
    this.navBar.title(this.requestData.title || '');

    if (this.requestData.cancelLink) {
        this.convertToCancelAction(this.navBar.leftAction(), this.requestData.cancelLink, this.requestData);
    }
    else {
        // Reset to defaults, or given title:
        this.navBar.leftAction().model.updateWith(this.defaultLeftAction, true);

        var jid = this.viewModel.jobTitleID(),
            jname = this.viewModel.jobTitle() && this.viewModel.jobTitle().singularName() || 'Scheduler',
            url = this.mustReturnTo || (jid && '/jobtitles/' + jid || '/scheduling'),
            handler = this.viewModel.isSelectionMode() ? this.returnRequest : null;

        this.navBar.leftAction().link(url);
        this.navBar.leftAction().text(this.requestData.navTitle || jname);
        this.navBar.leftAction().handler(handler);
    }
};

A.prototype.updateNavBarState = function updateNavBarState() {
    // Perform updates that apply this request:
    this.app.model.onboarding.updateNavBar(this.navBar) ||
    //this.app.applyNavbarMustReturn(this.requestData) ||
    this.applyOwnNavbarRules();
};

A.prototype.referrerURL = function() {
    return (this.app.shell.referrerRoute && this.app.shell.referrerRoute.url) || '/';
};

A.prototype.serviceEditorCancelLink = function(isAdditionMode) {
    if (isAdditionMode) {
        // Sets referrer as cancel link
        return this.referrerURL();
    }
    else {
        return '/serviceProfessionalService' + this.requestData.route.path;
    }
};

A.prototype.buildRoute = function(jobTitleID, clientID, isAdditionMode) {
    var base = '/serviceProfessionalService',
        jobTitle = '/' + jobTitleID,
        client = clientID > 0 ? ('/client/' + clientID) : '',
        newParam = isAdditionMode ? '/new' : '';

    return base + jobTitle + client + newParam;
};

A.prototype.parseRoute = function(url) {
    var paramsDefaults = { jobTitleID: 0, isNew: false, clientID: null },
        matcher = new RouteMatcher([
            new Route('/:jobTitleID/new', { isNew: true }),
            new Route('/:jobTitleID/client/:clientID/new', { isNew: true }),
            new Route('/:jobTitleID/client/:clientID'),
            new Route('/new', { isNew: true }),
            new Route('/:jobTitleID')
        ], paramsDefaults);

    return matcher.match(url) || paramsDefaults;
};

A.prototype.show = function show(options) {
    //jshint maxcomplexity:8
    Activity.prototype.show.call(this, options);

    // Remember route to go back, from a request of 'mustReturn' or last requested
    this.mustReturnTo = this.requestData.route.query.mustReturn || this.mustReturnTo;

    // Reset: avoiding errors because persisted data for different ID on loading
    // or outdated info forcing update
    this.viewModel.reset();
    this.viewModel.requestData(this.requestData);
    this.viewModel.preSelectedServices(this.requestData.selectedServices || []);

    this.viewModel.isSelectionMode(this.requestData.selectPricing === true);

    var params = this.parseRoute(options.route.path);

    var jobTitleID = +params.jobTitleID;
    if (jobTitleID === 0 && options.selectedJobTitleID > 0)
        jobTitleID = options.selectedJobTitleID |0;

    this.viewModel.clientID(+params.clientID);

    var isAdditionMode = params.isNew;

    this.viewModel.serviceEditorCancelLink(this.serviceEditorCancelLink(isAdditionMode));

    if (isAdditionMode) {
        this.requestData.cancelLink = this.referrerURL();
    }

    this.viewModel.isAdditionMode(isAdditionMode);

    this.updateNavBarState();

    this.viewModel.jobTitleID(jobTitleID);

    if (jobTitleID === 0) {
        this.viewModel.clearData();
        this.viewModel.jobTitles.sync();
    }
    else {
        this.viewModel.loadServicesData();
    }
};

var UserJobProfile = require('../viewmodels/UserJobProfile');

function ViewModel(app) {
    // ViewModel has all of the properties of a ServiceProfessionalServiceViewModel
    ServiceProfessionalServiceViewModel.call(this, app);

    // Always load empty pricing types, regardless of view model mode
    this.loadEmptyPricingTypes(true);

    this.clientID = ko.observable(null);
    this.client = ko.observable(null);

    this.requestData = ko.observable(null);
    this.serviceEditorCancelLink = ko.observable(null);

    this.helpLink = '/help/relatedArticles/201967166-listing-and-pricing-your-services';
    this.isInOnboarding = app.model.onboarding.inProgress;

    this.isLocked = this.isLoading;

    this.jobTitles = new UserJobProfile(app);
    this.jobTitles.baseUrl('/serviceProfessionalService');
    this.jobTitles.selectJobTitle = function(jobTitle) {
        this.jobTitleID(jobTitle.jobTitleID());
        this.loadServicesData();
        return false;
    }.bind(this);

    this.loadServicesData = function() {
        var clientID = this.clientID(),
            jobTitleID = this.jobTitleID(),
            model = app.model.serviceProfessionalServices,
            services = clientID ? model.getClientSpecificServicesForJobTitle(clientID, jobTitleID) :
                                  model.getList(jobTitleID);

        return this.loadData(null, jobTitleID, services);
    }.bind(this);

    this.clientName = ko.pureComputed(function() {
        return (this.client() && this.client().firstName()) || '';
    }, this);

    this.jobTitleName = ko.pureComputed(function() {
        return (this.jobTitle() && this.jobTitle().singularName()) || '';
    }, this);

    this.submitText = ko.pureComputed(function() {
        return (
            this.isLoading() ?
                'loading...' :
                'Save and continue'
        );
    }, this);

    this.onboardingNextReady = ko.computed(function() {
        var isin = app.model.onboarding.inProgress(),
            hasPricing = this.list().length > 0;

        return isin && hasPricing;
    }, this);

    this.editServiceRequest = function() {
        return $.extend({ cancelLink: this.serviceEditorCancelLink() }, this.requestData());
    }.bind(this);

    this.newServiceRequest = function() {
        return $.extend({ cancelLink: this.serviceEditorCancelLink() }, this.requestData());
    }.bind(this);

    var baseNewServiceURL = this.newServiceURL;

    this.newServiceURL = function(jobTitleID, pricingTypeID) {
        if(this.client()) {
            return '#!serviceProfessionalServiceEditor/' + jobTitleID + '/pricing_type/' + pricingTypeID + '/client/' + this.clientID() + '/new';
        }
        else {
            return baseNewServiceURL(jobTitleID, pricingTypeID);
        }
    }.bind(this);

    /**
        Ends the selection process, ready to collect selection
        and passing it to the requester activity.
        Works too to pass to the next onboarding step
    **/
    this.endSelection = function(data, event) {

        if (app.model.onboarding.inProgress()) {
            // Ensure we keep the same jobTitleID in next steps as here:
            app.model.onboarding.selectedJobTitleID(this.jobTitleID());
            app.model.onboarding.goNext();
        }
        else {
            // Run method injected by the activity to return a
            // selected address:
            this.returnSelected(
                this.selectedServices().map(function(pricing) {
                    return pricing.model.toPlainObject(true);
                }),
                this.jobTitleID()
            );
        }

        event.preventDefault();
        event.stopImmediatePropagation();
    }.bind(this);

    this.selectedServiceRequest = function(pricing) {
        return pricing.model.toPlainObject(true);
    };
}

ViewModel._inherits(ServiceProfessionalServiceViewModel);
<commit_msg>further refactoring of  serviceProfesionalServices activity applyOwnNavbarRules for readability #302<commit_after>/**
    ServiceProfessional Service activity
**/
'use strict';

var ko = require('knockout'),
    Activity = require('../components/Activity'),
    ServiceProfessionalServiceViewModel = require('../viewmodels/ServiceProfessionalService'),
    $ = require('jquery'),
    RouteMatcher = require('../utils/Router').RouteMatcher,
    Route = require('../utils/Router').Route;

var A = Activity.extend(function ServiceProfessionalServiceActivity() {

    Activity.apply(this, arguments);

    this.accessLevel = this.app.UserType.serviceProfessional;
    this.viewModel = new ViewModel(this.app);
    // Defaults settings for navBar.
    this.navBar = Activity.createSubsectionNavBar('Job Title', {
        backLink: '/scheduling', helpLink: this.viewModel.helpLink
    });
    // Save defaults to restore on updateNavBarState when needed:
    this.defaultLeftAction = this.navBar.leftAction().model.toPlainObject(true);
    // Make navBar available at viewModel, needed for dekstop navigation
    this.viewModel.navBar = this.navBar;

    // On changing jobTitleID:
    this.registerHandler({
        target: this.viewModel.jobTitle,
        handler: function(/*jobTitle*/) {
            // Update navbar (may indicate the jobTitle name)
            this.updateNavBarState();

            // May depend on current URL, will change with job title
            this.viewModel.serviceEditorCancelLink(this.serviceEditorCancelLink(this.viewModel.isAdditionMode()));
        }.bind(this)
    });

    // On changing jobTitleID:
    this.registerHandler({
        target: this.viewModel.jobTitleID,
        handler: function(jobTitleID) {

            if (jobTitleID) {

                var params = this.parseRoute(this.requestData.route.path),
                    urlJobTitleID = +params.jobTitleID,
                    clientID = +params.clientID;

                if (urlJobTitleID !== jobTitleID) {
                    var url = this.buildRoute(jobTitleID, clientID, params.isNew);

                    this.app.shell.replaceState(this.requestData, null, url);
                }
            }
        }.bind(this)
    });

    this.registerHandler({
        target: this.viewModel.clientID,
        handler: function(clientID) {
            var viewModel = this.viewModel,
                app = this.app;

            viewModel.client(null);

            if(clientID) {
                app.model.clients.getItem(clientID)
                .then(function(client) {
                    viewModel.client(client);
                })
                .catch(function(error) {
                    app.modals.showError({ title: 'Unable to load client.', error: error });
                });
            }
        }.bind(this)
    });

    // Go back with the selected pricing when triggered in the form/view
    this.viewModel.returnSelected = function(pricing, jobTitleID) {
        // Pass the selected client in the info
        this.requestData.selectedServices = pricing;
        this.requestData.selectedJobTitleID = jobTitleID;
        // And go back
        this.app.shell.goBack(this.requestData);
    }.bind(this);

    this.returnRequest = function returnRequest() {
        this.app.shell.goBack(this.requestData);
    }.bind(this);
});

exports.init = A.init;

A.prototype.applyOwnNavbarRules = function() {
    this.navBar.title(this.requestData.title || '');

    if (this.requestData.cancelLink) {
        this.convertToCancelAction(this.navBar.leftAction(), this.requestData.cancelLink, this.requestData);
    }
    else {
        this.navBar.leftAction().model.updateWith(this.defaultLeftAction, true);
        this.navBar.leftAction().model.updateWith(this.newLeftAction(), true);
    }
};

A.prototype.newLeftAction = function() {
    var leftAction = {},
        jid = this.viewModel.jobTitleID(),
        jname = this.viewModel.jobTitle() && this.viewModel.jobTitle().singularName() || 'Scheduler',
        url = this.mustReturnTo || (jid && '/jobtitles/' + jid || '/scheduling'),
        handler = this.viewModel.isSelectionMode() ? this.returnRequest : null;

    leftAction.link = url;
    leftAction.text = this.requestData.navTitle || jname;
    leftAction.handler = handler;

    return leftAction;
};

A.prototype.updateNavBarState = function updateNavBarState() {
    // Perform updates that apply this request:
    this.app.model.onboarding.updateNavBar(this.navBar) ||
    //this.app.applyNavbarMustReturn(this.requestData) ||
    this.applyOwnNavbarRules();
};

A.prototype.referrerURL = function() {
    return (this.app.shell.referrerRoute && this.app.shell.referrerRoute.url) || '/';
};

A.prototype.serviceEditorCancelLink = function(isAdditionMode) {
    if (isAdditionMode) {
        // Sets referrer as cancel link
        return this.referrerURL();
    }
    else {
        return '/serviceProfessionalService' + this.requestData.route.path;
    }
};

A.prototype.buildRoute = function(jobTitleID, clientID, isAdditionMode) {
    var base = '/serviceProfessionalService',
        jobTitle = '/' + jobTitleID,
        client = clientID > 0 ? ('/client/' + clientID) : '',
        newParam = isAdditionMode ? '/new' : '';

    return base + jobTitle + client + newParam;
};

A.prototype.parseRoute = function(url) {
    var paramsDefaults = { jobTitleID: 0, isNew: false, clientID: null },
        matcher = new RouteMatcher([
            new Route('/:jobTitleID/new', { isNew: true }),
            new Route('/:jobTitleID/client/:clientID/new', { isNew: true }),
            new Route('/:jobTitleID/client/:clientID'),
            new Route('/new', { isNew: true }),
            new Route('/:jobTitleID')
        ], paramsDefaults);

    return matcher.match(url) || paramsDefaults;
};

A.prototype.show = function show(options) {
    //jshint maxcomplexity:8
    Activity.prototype.show.call(this, options);

    // Remember route to go back, from a request of 'mustReturn' or last requested
    this.mustReturnTo = this.requestData.route.query.mustReturn || this.mustReturnTo;

    // Reset: avoiding errors because persisted data for different ID on loading
    // or outdated info forcing update
    this.viewModel.reset();
    this.viewModel.requestData(this.requestData);
    this.viewModel.preSelectedServices(this.requestData.selectedServices || []);

    this.viewModel.isSelectionMode(this.requestData.selectPricing === true);

    var params = this.parseRoute(options.route.path);

    var jobTitleID = +params.jobTitleID;
    if (jobTitleID === 0 && options.selectedJobTitleID > 0)
        jobTitleID = options.selectedJobTitleID |0;

    this.viewModel.clientID(+params.clientID);

    var isAdditionMode = params.isNew;

    this.viewModel.serviceEditorCancelLink(this.serviceEditorCancelLink(isAdditionMode));

    if (isAdditionMode) {
        this.requestData.cancelLink = this.referrerURL();
    }

    this.viewModel.isAdditionMode(isAdditionMode);

    this.updateNavBarState();

    this.viewModel.jobTitleID(jobTitleID);

    if (jobTitleID === 0) {
        this.viewModel.clearData();
        this.viewModel.jobTitles.sync();
    }
    else {
        this.viewModel.loadServicesData();
    }
};

var UserJobProfile = require('../viewmodels/UserJobProfile');

function ViewModel(app) {
    // ViewModel has all of the properties of a ServiceProfessionalServiceViewModel
    ServiceProfessionalServiceViewModel.call(this, app);

    // Always load empty pricing types, regardless of view model mode
    this.loadEmptyPricingTypes(true);

    this.clientID = ko.observable(null);
    this.client = ko.observable(null);

    this.requestData = ko.observable(null);
    this.serviceEditorCancelLink = ko.observable(null);

    this.helpLink = '/help/relatedArticles/201967166-listing-and-pricing-your-services';
    this.isInOnboarding = app.model.onboarding.inProgress;

    this.isLocked = this.isLoading;

    this.jobTitles = new UserJobProfile(app);
    this.jobTitles.baseUrl('/serviceProfessionalService');
    this.jobTitles.selectJobTitle = function(jobTitle) {
        this.jobTitleID(jobTitle.jobTitleID());
        this.loadServicesData();
        return false;
    }.bind(this);

    this.loadServicesData = function() {
        var clientID = this.clientID(),
            jobTitleID = this.jobTitleID(),
            model = app.model.serviceProfessionalServices,
            services = clientID ? model.getClientSpecificServicesForJobTitle(clientID, jobTitleID) :
                                  model.getList(jobTitleID);

        return this.loadData(null, jobTitleID, services);
    }.bind(this);

    this.clientName = ko.pureComputed(function() {
        return (this.client() && this.client().firstName()) || '';
    }, this);

    this.jobTitleName = ko.pureComputed(function() {
        return (this.jobTitle() && this.jobTitle().singularName()) || '';
    }, this);

    this.submitText = ko.pureComputed(function() {
        return (
            this.isLoading() ?
                'loading...' :
                'Save and continue'
        );
    }, this);

    this.onboardingNextReady = ko.computed(function() {
        var isin = app.model.onboarding.inProgress(),
            hasPricing = this.list().length > 0;

        return isin && hasPricing;
    }, this);

    this.editServiceRequest = function() {
        return $.extend({ cancelLink: this.serviceEditorCancelLink() }, this.requestData());
    }.bind(this);

    this.newServiceRequest = function() {
        return $.extend({ cancelLink: this.serviceEditorCancelLink() }, this.requestData());
    }.bind(this);

    var baseNewServiceURL = this.newServiceURL;

    this.newServiceURL = function(jobTitleID, pricingTypeID) {
        if(this.client()) {
            return '#!serviceProfessionalServiceEditor/' + jobTitleID + '/pricing_type/' + pricingTypeID + '/client/' + this.clientID() + '/new';
        }
        else {
            return baseNewServiceURL(jobTitleID, pricingTypeID);
        }
    }.bind(this);

    /**
        Ends the selection process, ready to collect selection
        and passing it to the requester activity.
        Works too to pass to the next onboarding step
    **/
    this.endSelection = function(data, event) {

        if (app.model.onboarding.inProgress()) {
            // Ensure we keep the same jobTitleID in next steps as here:
            app.model.onboarding.selectedJobTitleID(this.jobTitleID());
            app.model.onboarding.goNext();
        }
        else {
            // Run method injected by the activity to return a
            // selected address:
            this.returnSelected(
                this.selectedServices().map(function(pricing) {
                    return pricing.model.toPlainObject(true);
                }),
                this.jobTitleID()
            );
        }

        event.preventDefault();
        event.stopImmediatePropagation();
    }.bind(this);

    this.selectedServiceRequest = function(pricing) {
        return pricing.model.toPlainObject(true);
    };
}

ViewModel._inherits(ServiceProfessionalServiceViewModel);
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2016 SAP and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * Contributors:
 * SAP - initial API and implementation
 *******************************************************************************/

/* globals $ java org */
/* eslint-env node, dirigible */

exports.generate = function(template, parameters) {
	var temlatingService = $.getTemplatingService();
	var internalParameters = $.getTemplatingService().createParameters();
	for (var parameter in parameters) {
		internalParameters.put(parameter, parameters[parameter]);
		var generated = temlatingService.generate(template, internalParameters, "generation_service_api");
		return generated;
	}
};

exports.getWorker = function(category) {
	var internalWorker = $.getGenerationService().getGenerationWorker(category, $.getRequest());
	return new Worker(internalWorker);
};

/**
 * Worker object
 */
function Worker(internalWorker) {
	this.internalWorker = internalWorker;

	this.getInternalObject = function() {
		return this.internalWorker;
	};

	this.generate = function(parameters) {
		return this.internalWorker.generate(parameters, $.getRequest());
	};

	this.getTemplates = function() {
		return this.internalWorker.getTemplates($.getRequest());
	};
}

// CONSTANTS

// ---- Worker Types ----
exports.WORKER_CATEGORY_DATA_STRUCTURES = "DataStructures";
exports.WORKER_CATEGORY_SCRIPTING_SERVICES = "ScriptingServices";
exports.WORKER_CATEGORY_WEB_CONTENT = "WebContent";
exports.WORKER_CATEGORY_WEB_CONTENT_FOR_ENTITY = "WebContentForEntity";<commit_msg>Fixes Generator API<commit_after>/*******************************************************************************
 * Copyright (c) 2016 SAP and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * Contributors:
 * SAP - initial API and implementation
 *******************************************************************************/

/* globals $ java org */
/* eslint-env node, dirigible */

exports.generate = function(template, parameters) {
	var temlatingService = $.getTemplatingService();
	var internalParameters = $.getTemplatingService().createParameters();
	for (var parameter in parameters) {
		internalParameters.put(parameter, parameters[parameter]);
	}
	var generated = temlatingService.generate(template, internalParameters, "generation_service_api");
	return generated;
};

exports.getWorker = function(category) {
	var internalWorker = $.getGenerationService().getGenerationWorker(category, $.getRequest());
	return new Worker(internalWorker);
};

/**
 * Worker object
 */
function Worker(internalWorker) {
	this.internalWorker = internalWorker;

	this.getInternalObject = function() {
		return this.internalWorker;
	};

	this.generate = function(parameters) {
		return this.internalWorker.generate(parameters, $.getRequest());
	};

	this.getTemplates = function() {
		return this.internalWorker.getTemplates($.getRequest());
	};
}

// CONSTANTS

// ---- Worker Types ----
exports.WORKER_CATEGORY_DATA_STRUCTURES = "DataStructures";
exports.WORKER_CATEGORY_SCRIPTING_SERVICES = "ScriptingServices";
exports.WORKER_CATEGORY_WEB_CONTENT = "WebContent";
exports.WORKER_CATEGORY_WEB_CONTENT_FOR_ENTITY = "WebContentForEntity";
<|endoftext|>


<commit_before>define(['app','underscore','/app/js/common.js',
    'introjs','scbd-angularjs-services', 'scbd-angularjs-filters', 'scbd-angularjs-controls',
    '/app/views/forms/view/record-loader.directive.html.js',
    '/app/views/search/find_schemas.partial.html.js',
    '/app/views/search/find_countries.partial.html.js',
    '/app/views/search/search-filter-regions.js',
    '/app/views/search/find_facets.partial.html.js',
    '/app/views/search/find_themes.partial.html.js',
    '/app/views/directives/search-filter-dates.partial.html.js',
    '/app/views/directives/document-list.partial.html.js', 'bootstrap-datepicker','moment',
    '/app/views/directives/help-directive.html.js',
    '/app/views/search/search-directives/search-directive.html.js',
    '/app/views/search/search-directives/national-records-filter-directive.html.js',
    '/app/views/countries/country-map-list-directive.html.js', '/app/services/search-service.js'],
     function (app,_) {

    app.controller('FindController', ['$scope', '$rootScope','showHelp' ,'$http', '$timeout', '$q','realm', '$routeParams',
        '$location','$element','commonjs','$mdSidenav', '$mdUtil', '$mdMedia', 'searchService',
        function ($scope, $rootScope,showHelp, $http, $timeout, $q, realm, $routeParams,$location,
            $element, commonjs, $mdSidenav, $mdUtil, $mdMedia, searchService) {

        var self = this;
        var queryCanceler = null;
        var refreshTimeout = null;

        $scope.orderReferenceBy = 'createdDate_dt desc';
        $scope.itemsPerPage    = 25;
        $scope.documentCount   = 0;
        $scope.currentPage     = 0;

        $scope.querySchema     = '*:*';
        $scope.queryGovernment = '*:*';
        $scope.queryTheme      = '*:*';
        $scope.queryRegion      = '*:*';
        $scope.queryKeywords   = '*:*';
        $scope.displayDetails = false;
        $scope.countryResultFilter = [];
        $scope.queryPartyStatus = '';

        $scope.previewType = 'group';
        $scope.sortBy = '';
        $scope.rawDocs = [];
        $scope.helpSchema = 'search'
        //============================================================
        //
        //
        //============================================================
        $scope.clearFilter = function(){

            $scope.keyword = "";
            $scope.queryPartyStatus = "";
            $scope.partyStatusString = undefined;
            $scope.queryGovernment = undefined;
            $scope.queryRegion = undefined;
            $scope.queryThem = undefined;
            $scope.$broadcast("clearFilter",{});
        }

        $scope.$watch('currentPage',     function() {
            refresh();
        });
        $scope.$watch('querySchema',     function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryGovernment', function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryTargets',    function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryTheme',      function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryRegion',     function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryDate',       function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('keyword',         function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('orderReferenceBy',function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('previewType',     function(newValue, oldValue) {
            if(newValue && oldValue && $scope.rawDocs){
                $scope.rawDocs = undefined;
                $scope.documentCount = 0;

                if($scope.currentPage>0){
                    $scope.clearFilter();
                    $scope.currentPage=0;
                }
                else
                    refresh();
            }
        });

        $scope.updatePreviewType = function(type){
            $scope.previewType=type;
            $scope.rawDocs = undefined;
            $scope.clearFilter();
        }

        $scope.removeFilter = function(filter){
            $scope.$broadcast('removeFilter',{data:filter});
        }
        $scope.removeCountryFilter = function(filter){
            $scope.countryApi.unSelectItem(filter.code);
        }
        $scope.removeRegionFilter = function(filter){
            $scope.regionsApi.unSelectItem(filter.identifier);
        }
        $scope.removeThematicAreaFilter = function(filter){
            $scope.thematicAreaApi.unSelectItem(filter.identifier);
        }

        $scope.toggleSideBar = function(e){
            e.preventDefault();
            $element.find("#wrapper").toggleClass("toggled");
        }

        function query () {
            if($scope.recordType =='country')
                return;

            if(!$scope.recordType)
                $scope.recordType = 'national';

            if (queryCanceler) {
                console.log('trying to abort pending request...');
                queryCanceler.resolve(true);
            }

            var q = '(realm_ss:' + realm.value.toLowerCase() + ') AND NOT version_s:*';
            q += '(' + $scope.querySchema + ')';

            if($scope.queryGovernment){
                // if($scope.queryGovernment.indexOf("government_s:eur") < 0)
                $scope.queryGovernment = $scope.queryGovernment.replace("government_s:eu", "government_s:eur");
                q += ' AND (' + $scope.queryGovernment + ')';
            }
            if($scope.queryTheme)      q += ' AND (' + $scope.queryTheme + ')';
            if($scope.queryRegion)      q += ' AND (' + $scope.queryRegion + ')';
            if($scope.queryPartyStatus) q += ' AND (' + $scope.queryPartyStatus + ')';

            var orderByFields='createdDate_dt desc';

            if($scope.recordType == 'reference'){
                orderByFields = $scope.orderReferenceBy;
            }

            var searchOperation;
            queryCanceler = $q.defer();

            if($scope.previewType == 'list' || $scope.recordType == 'reference'){
                $scope.rawDocs = undefined;
                var listQuery = {
                    query: q,
                    sort: orderByFields,
                    fields      : 'id,identifier_s,title_t,createdDate_dt,description_t,url_ss,schema_EN_t,date_dt,government_EN_t,schema_s,number_d,aichiTarget_ss,reference_s,sender_s,meeting_ss,recipient_ss,symbol_s,eventCity_EN_t,eventCountry_EN_t,startDate_s,endDate_s,body_s,code_s,meeting_s,group_s,function_t,department_t,organization_t,summary_EN_t,reportType_EN_t,completion_EN_t,jurisdiction_EN_t,development_EN_t,' +
                                  'government_s,publicationYear_is,resourceTypes_CEN_ss,regions_CEN_ss,languages_CEN_ss,absResposibleForAll_b,absJurisdiction_EN_t,jurisdiction_CEN_s,geneticResourceTypes_CEN_ss,thematicAreas_CEN_ss,usage_CEN_ss,keywords_CEN_ss,informAllAuthorities_b,originCountries_CEN_ss,orgperson_s,status_EN_t,type_EN_t,endDate_dt,startDate_dt,amendmentIntent_i,' +
                                  'resourceLinksLanguage_ss,type_ss,ownerGovernment_s',
                    currentPage : $scope.currentPage,
                    itemsPerPage: $scope.itemsPerPage
                };
                searchOperation = searchService.list(listQuery, queryCanceler);
            }
            else if($scope.previewType == 'group'){
                if($scope.currentPage==0)
                    $scope.rawDocs = undefined;
                var groupQuery = {
                    query       : q + ' AND government_s:*',
                    sort        : 'government_EN_s asc, createdDate_dt desc, title_t asc',
                    fields      : 'id,identifier_s,title_t,description_t,url_ss,schema_EN_t,date_dt,government_s,government_EN_t,schema_s,summary_EN_t,jurisdiction_EN_t,type_ss,uniqueIdentifier_s,ownerGovernment_s,type_EN_t,status_EN_t',
                    groupField  : 'government_s',
                    groupSort   : 'government_EN_s asc',
                    currentPage : $scope.currentPage,
                    itemsPerPage: $scope.itemsPerPage
                };
                searchOperation = searchService.group(groupQuery, queryCanceler);
            }

            $q.when(searchOperation)
              .then(function (data) {
                queryCanceler = null;
                 if($scope.previewType=='list'|| $scope.recordType == 'reference'){
                    $scope.rawDocs = data.data.response.docs;
                    $scope.documentCount   = data.data.response.numFound;
                 }
                 else {
                     var lRawDocs = [];
                     if($scope.rawDocs && $scope.currentPage!=0)
                        lRawDocs = _.clone($scope.rawDocs);

                    _.map(lRawDocs, function(doc){doc.newRecord = false;});

                    data.data.grouped.government_s.groups.forEach(function(doc){
                                doc.newRecord = true;
                                lRawDocs.push(doc);
                    });
                    $scope.rawDocs = lRawDocs;
                    $scope.documentCount = data.data.grouped.government_s.matches;
                    $scope.groupCount = data.data.grouped.government_s.ngroups;

                 }

                if(!$scope.schemas) {
                    var schemas = [ "absPermit", "absCheckpoint", "absCheckpointCommunique", "authority", "measure", "database","focalPoint",
                                    "resource", "meeting", "notification","pressRelease","statement" , "news", "modelContractualClause", "communityProtocol"];

                    var facetQuery = {
                        query  : '(realm_ss:' + realm.value.toLowerCase() + ') AND NOT version_s:* AND (schema_s:(' +
                                 schemas.join(' ') + '))',
                        fields : ['schema_s', 'government_s', 'thematicAreas_ss', 'government_REL_ss', 'regions_REL_ss']
                    };
                    searchService.facets(facetQuery)
                        .then(function(data){
                                $scope.schemas = data.schema_s;
                                $scope.thematicAreas = data.thematicAreas_ss;

                                self.governments = data.government_s;
                                self.regionFacets = data.government_REL_ss;
                                self.referenceRegionFacets = data.regions_REL_ss;

                                updateRegionsFilter($scope.recordType);
                        });
                }
            }).catch(function (error) {
                    console.log('onerror'); console.log(error);
            });
        };

        function refresh() {

            if(refreshTimeout)
                $timeout.cancel(refreshTimeout);

            refreshTimeout = $timeout(function () { query(); }, 200);
        }

        function updateRegionsFilter(recordType){
            if(recordType=='national'){
                    $scope.governmentsQueryField    = 'government_s';
                    $scope.governments              = self.governments;
                    $scope.regionQueryField         = 'government_REL_ss';
                    $scope.regionFacets             = self.regionFacets;
                    $scope.helpSchema = '/search/national-records';
            }else
            if(recordType=='reference'){
                    $scope.governmentsQueryField    = 'regions_REL_ss';
                    $scope.governments              = self.referenceRegionFacets;
                    $scope.regionQueryField         = 'regions_REL_ss';
                    $scope.regionFacets             = self.referenceRegionFacets;
                    $scope.helpSchema = '/search/reference-records';
            }
            else if(recordType=='countryProfile'){
                    $scope.helpSchema = '/search/countries';
            }
        }

        $scope.$watch('recordType', function(newVal){
            updateRegionsFilter(newVal);
        });

    }]);

});
<commit_msg>fix problem selecting country EU<commit_after>define(['app','underscore','/app/js/common.js',
    'introjs','scbd-angularjs-services', 'scbd-angularjs-filters', 'scbd-angularjs-controls',
    '/app/views/forms/view/record-loader.directive.html.js',
    '/app/views/search/find_schemas.partial.html.js',
    '/app/views/search/find_countries.partial.html.js',
    '/app/views/search/search-filter-regions.js',
    '/app/views/search/find_facets.partial.html.js',
    '/app/views/search/find_themes.partial.html.js',
    '/app/views/directives/search-filter-dates.partial.html.js',
    '/app/views/directives/document-list.partial.html.js', 'bootstrap-datepicker','moment',
    '/app/views/directives/help-directive.html.js',
    '/app/views/search/search-directives/search-directive.html.js',
    '/app/views/search/search-directives/national-records-filter-directive.html.js',
    '/app/views/countries/country-map-list-directive.html.js', '/app/services/search-service.js'],
     function (app,_) {

    app.controller('FindController', ['$scope', '$rootScope','showHelp' ,'$http', '$timeout', '$q','realm', '$routeParams',
        '$location','$element','commonjs','$mdSidenav', '$mdUtil', '$mdMedia', 'searchService',
        function ($scope, $rootScope,showHelp, $http, $timeout, $q, realm, $routeParams,$location,
            $element, commonjs, $mdSidenav, $mdUtil, $mdMedia, searchService) {

        var self = this;
        var queryCanceler = null;
        var refreshTimeout = null;

        $scope.orderReferenceBy = 'createdDate_dt desc';
        $scope.itemsPerPage    = 25;
        $scope.documentCount   = 0;
        $scope.currentPage     = 0;

        $scope.querySchema     = '*:*';
        $scope.queryGovernment = '*:*';
        $scope.queryTheme      = '*:*';
        $scope.queryRegion      = '*:*';
        $scope.queryKeywords   = '*:*';
        $scope.displayDetails = false;
        $scope.countryResultFilter = [];
        $scope.queryPartyStatus = '';

        $scope.previewType = 'group';
        $scope.sortBy = '';
        $scope.rawDocs = [];
        $scope.helpSchema = 'search';
        //============================================================
        //
        //
        //============================================================
        $scope.clearFilter = function(){

            $scope.keyword = "";
            $scope.queryPartyStatus = "";
            $scope.partyStatusString = undefined;
            $scope.queryGovernment = undefined;
            $scope.queryRegion = undefined;
            $scope.queryThem = undefined;
            $scope.$broadcast("clearFilter",{});
        };

        $scope.$watch('currentPage',     function() {
            refresh();
        });
        $scope.$watch('querySchema',     function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryGovernment', function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryTargets',    function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryTheme',      function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryRegion',     function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('queryDate',       function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('keyword',         function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('orderReferenceBy',function() { $scope.currentPage=0; refresh(); });
        $scope.$watch('previewType',     function(newValue, oldValue) {
            if(newValue && oldValue && $scope.rawDocs){
                $scope.rawDocs = undefined;
                $scope.documentCount = 0;

                if($scope.currentPage>0){
                    $scope.clearFilter();
                    $scope.currentPage=0;
                }
                else
                    refresh();
            }
        });

        $scope.updatePreviewType = function(type){
            $scope.previewType=type;
            $scope.rawDocs = undefined;
            $scope.clearFilter();
        };

        $scope.removeFilter = function(filter){
            $scope.$broadcast('removeFilter',{data:filter});
        };

        $scope.removeCountryFilter = function(filter){
            $scope.countryApi.unSelectItem(filter.code);
        };

        $scope.removeRegionFilter = function(filter){
            $scope.regionsApi.unSelectItem(filter.identifier);
        };

        $scope.removeThematicAreaFilter = function(filter){
            $scope.thematicAreaApi.unSelectItem(filter.identifier);
        };

        $scope.toggleSideBar = function(e){
            e.preventDefault();
            $element.find("#wrapper").toggleClass("toggled");
        };

        function query () {
            if($scope.recordType =='country')
                return;

            if(!$scope.recordType)
                $scope.recordType = 'national';

            if (queryCanceler) {
                console.log('trying to abort pending request...');
                queryCanceler.resolve(true);
            }

            var q = '(realm_ss:' + realm.value.toLowerCase() + ') AND NOT version_s:*';
            q += '(' + $scope.querySchema + ')';

            if($scope.queryGovernment){
                if($scope.queryGovernment.indexOf("government_s:eur") < 0)
                    $scope.queryGovernment = $scope.queryGovernment.replace("government_s:eu", "government_s:eur");
                q += ' AND (' + $scope.queryGovernment + ')';
            }
            if($scope.queryTheme)      q += ' AND (' + $scope.queryTheme + ')';
            if($scope.queryRegion)      q += ' AND (' + $scope.queryRegion + ')';
            if($scope.queryPartyStatus) q += ' AND (' + $scope.queryPartyStatus + ')';

            var orderByFields='createdDate_dt desc';

            if($scope.recordType == 'reference'){
                orderByFields = $scope.orderReferenceBy;
            }

            var searchOperation;
            queryCanceler = $q.defer();

            if($scope.previewType == 'list' || $scope.recordType == 'reference'){
                $scope.rawDocs = undefined;
                var listQuery = {
                    query: q,
                    sort: orderByFields,
                    fields      : 'id,identifier_s,title_t,createdDate_dt,description_t,url_ss,schema_EN_t,date_dt,government_EN_t,schema_s,number_d,aichiTarget_ss,reference_s,sender_s,meeting_ss,recipient_ss,symbol_s,eventCity_EN_t,eventCountry_EN_t,startDate_s,endDate_s,body_s,code_s,meeting_s,group_s,function_t,department_t,organization_t,summary_EN_t,reportType_EN_t,completion_EN_t,jurisdiction_EN_t,development_EN_t,' +
                                  'government_s,publicationYear_is,resourceTypes_CEN_ss,regions_CEN_ss,languages_CEN_ss,absResposibleForAll_b,absJurisdiction_EN_t,jurisdiction_CEN_s,geneticResourceTypes_CEN_ss,thematicAreas_CEN_ss,usage_CEN_ss,keywords_CEN_ss,informAllAuthorities_b,originCountries_CEN_ss,orgperson_s,status_EN_t,type_EN_t,endDate_dt,startDate_dt,amendmentIntent_i,' +
                                  'resourceLinksLanguage_ss,type_ss,ownerGovernment_s',
                    currentPage : $scope.currentPage,
                    itemsPerPage: $scope.itemsPerPage
                };
                searchOperation = searchService.list(listQuery, queryCanceler);
            }
            else if($scope.previewType == 'group'){
                if($scope.currentPage===0){
                    $scope.rawDocs = undefined;
                }
                var groupQuery = {
                    query       : q + ' AND government_s:*',
                    sort        : 'government_EN_s asc, createdDate_dt desc, title_t asc',
                    fields      : 'id,identifier_s,title_t,description_t,url_ss,schema_EN_t,date_dt,government_s,government_EN_t,schema_s,summary_EN_t,jurisdiction_EN_t,type_ss,uniqueIdentifier_s,ownerGovernment_s,type_EN_t,status_EN_t',
                    groupField  : 'government_s',
                    groupSort   : 'government_EN_s asc',
                    currentPage : $scope.currentPage,
                    itemsPerPage: $scope.itemsPerPage
                };
                searchOperation = searchService.group(groupQuery, queryCanceler);
            }

            $q.when(searchOperation)
              .then(function (data) {
                queryCanceler = null;
                 if($scope.previewType=='list'|| $scope.recordType == 'reference'){
                    $scope.rawDocs = data.data.response.docs;
                    $scope.documentCount   = data.data.response.numFound;
                 }
                 else {
                     var lRawDocs = [];
                     if($scope.rawDocs && $scope.currentPage!==0)
                        lRawDocs = _.clone($scope.rawDocs);

                    _.map(lRawDocs, function(doc){doc.newRecord = false;});

                    data.data.grouped.government_s.groups.forEach(function(doc){
                                doc.newRecord = true;
                                lRawDocs.push(doc);
                    });
                    $scope.rawDocs = lRawDocs;
                    $scope.documentCount = data.data.grouped.government_s.matches;
                    $scope.groupCount = data.data.grouped.government_s.ngroups;

                 }

                if(!$scope.schemas) {
                    var schemas = [ "absPermit", "absCheckpoint", "absCheckpointCommunique", "authority", "measure", "database","focalPoint",
                                    "resource", "meeting", "notification","pressRelease","statement" , "news", "modelContractualClause", "communityProtocol"];

                    var facetQuery = {
                        query  : '(realm_ss:' + realm.value.toLowerCase() + ') AND NOT version_s:* AND (schema_s:(' +
                                 schemas.join(' ') + '))',
                        fields : ['schema_s', 'government_s', 'thematicAreas_ss', 'government_REL_ss', 'regions_REL_ss']
                    };
                    searchService.facets(facetQuery)
                        .then(function(data){
                                $scope.schemas = data.schema_s;
                                $scope.thematicAreas = data.thematicAreas_ss;

                                self.governments = data.government_s;
                                self.regionFacets = data.government_REL_ss;
                                self.referenceRegionFacets = data.regions_REL_ss;

                                updateRegionsFilter($scope.recordType);
                        });
                }
            }).catch(function (error) {
                    console.log('onerror'); console.log(error);
            });
        }

        function refresh() {

            if(refreshTimeout)
                $timeout.cancel(refreshTimeout);

            refreshTimeout = $timeout(function () { query(); }, 200);
        }

        function updateRegionsFilter(recordType){
            if(recordType=='national'){
                    $scope.governmentsQueryField    = 'government_s';
                    $scope.governments              = self.governments;
                    $scope.regionQueryField         = 'government_REL_ss';
                    $scope.regionFacets             = self.regionFacets;
                    $scope.helpSchema = '/search/national-records';
            }else
            if(recordType=='reference'){
                    $scope.governmentsQueryField    = 'regions_REL_ss';
                    $scope.governments              = self.referenceRegionFacets;
                    $scope.regionQueryField         = 'regions_REL_ss';
                    $scope.regionFacets             = self.referenceRegionFacets;
                    $scope.helpSchema = '/search/reference-records';
            }
            else if(recordType=='countryProfile'){
                    $scope.helpSchema = '/search/countries';
            }
        }

        $scope.$watch('recordType', function(newVal){
            updateRegionsFilter(newVal);
        });

    }]);

});
<|endoftext|>


<commit_before>const expect = require('chai').expect;

const version = process.env.QB_VERSION;

describe('check compiler version inside docker', function () {
    it('should have the same version', async () => {
        const exec = require('child_process').exec;
        let options = {
            timeout: 60000,
            killSignal: 'SIGKILL'
        };
        const result = await new Promise(resolve => exec(`docker run --rm -v ${__dirname}/env/version.cpp:/home/builder/bench-file.cpp -t fredtingaud/quick-bench:${version} /bin/bash -c "./build && ./run"`, options, (error, stdout, stderr) => {
            resolve(stdout + stderr);
        }));
        expect(result).to.eql(version);
    }).timeout(60000);
});
<commit_msg>Add a test for std-versions script<commit_after>const expect = require('chai').expect;

const version = process.env.QB_VERSION;

describe('check compiler version inside docker', function () {
    it('should have the same version', async () => {
        const exec = require('child_process').exec;
        let options = {
            timeout: 60000,
            killSignal: 'SIGKILL'
        };
        const result = await new Promise(resolve => exec(`docker run --rm -v ${__dirname}/env/version.cpp:/home/builder/bench-file.cpp -t fredtingaud/quick-bench:${version} /bin/bash -c "./build && ./run"`, options, (error, stdout, stderr) => {
            resolve(stdout + stderr);
        }));
        expect(result).to.eql(version);
    }).timeout(60000);
});

describe('check available standards', function() {
    it('should contain multiple standards', async() =>{
        const exec = require('child_process').exec;
        let options = {
            timeout: 60000,
            killSignal: 'SIGKILL'
        };
        const result = await new Promise(resolve => exec(`docker run --rm -t fredtingaud/quick-bench:${version} /bin/bash -c "./std-versions"`, options, (error, stdout, stderr) => {
            resolve(stdout + stderr);
        }));
        expect(result).to.not.be.empty();
        expect(result).to.contain('c++11');
    })
})<|endoftext|>


<commit_before>define(['jquery', 'backbone', 'bootstrap', 'dropzone'], function ($, Backbone) {
    return Backbone.View.extend({
        initialize: function(options) {
            this.$el.find('.dropzone').dropzone({
                //url: "/file/post",
                addRemoveLinks : true,
                maxFilesize: 0.5,
                dictResponseError: 'Error uploading file!'
            });
            this.$el.find('.modal').modal('show');
        }
    });
});<commit_msg>detecting when dropzone is not already attached to add image form for initial setup<commit_after>define(['jquery', 'backbone', 'dropzone', 'bootstrap'], function ($, Backbone, dropzone) {
    return Backbone.View.extend({
        initialize: function(options) {
            var dropzoneEl = this.$el.find('.dropzone');
            // detect if dropzone is attached, and if not init
            if (!dropzoneEl.hasClass('dz-clickable')) {
                dropzoneEl.dropzone({
                    addRemoveLinks : true,
                    maxFilesize: 0.5,
                    dictResponseError: 'Error uploading file!'
                });
            }

            this.$el.find('.modal').modal('show');
        }
    });
});<|endoftext|>


<commit_before>/**
 * `core/user` data store: Surveys tests.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import {
	createTestRegistry,
	muteFetch,
} from '../../../../../tests/js/utils';
import { STORE_NAME } from './constants';

describe( 'core/user surveys', () => {
	let registry;

	beforeEach( () => {
		registry = createTestRegistry();
	} );

	const survey = {
		survey_payload: 'foo',
		session: 'bar',
	};
	const surveyTriggerEndpoint = /^\/google-site-kit\/v1\/core\/user\/data\/survey-trigger/;
	const surveyEventEndpoint = /^\/google-site-kit\/v1\/core\/user\/data\/survey-event/;

	describe( 'actions', () => {
		describe( 'triggerSurvey', () => {
			it( 'throws an error when parameters are missing or incorrect', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey();
				} ).toThrow( 'triggerID is required and must be a string' );

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'coolSurvey', false );
				} ).toThrow( 'options must be an object' );

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'warmSurvey', { ttl: 'a' } );
				} ).toThrow( 'options.ttl must be a number' );
			} );

			it( 'does not throw an error when parameters are correct', () => {
				muteFetch( surveyTriggerEndpoint );

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'adSenseSurvey' );
				} ).not.toThrow();

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'analyticsSurvey', { ttl: 1 } );
				} ).not.toThrow();
			} );

			it( 'makes network requests to endpoints', async () => {
				muteFetch( surveyTriggerEndpoint );

				await registry.dispatch( STORE_NAME ).triggerSurvey( 'optimizeSurvey', { ttl: 1 } );

				expect( fetchMock ).toHaveFetched( surveyTriggerEndpoint, {
					body: {
						data: { triggerID: 'optimizeSurvey' },
					},
				} );
			} );
		} );

		describe( 'sendSurveyEvent', () => {
			it( 'throws an error when parameters are missing or incorrect', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent();
				} ).toThrow( 'eventID is required and must be a string' );

				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent( 'dismiss_survey', 'answer_question' );
				} ).toThrow( 'eventData must be an object' );
			} );

			it( 'does not throw an error when parameters are correct', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent( 'dismiss_survey' );
				} ).not.toThrow();

				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent( 'answer_question', { foo: 'bar' } );
				} ).not.toThrow();
			} );

			it( 'makes network requests to endpoints', async () => {
				muteFetch( surveyEventEndpoint );

				// Survey events are only sent if there is a current survey.
				registry.dispatch( STORE_NAME ).receiveTriggerSurvey( survey, { triggerID: 'optimizeSurvey' } );
				// Send a survey event.
				await registry.dispatch( STORE_NAME ).sendSurveyEvent( 'answer_question', { foo: 'bar' } );

				expect( fetchMock ).toHaveFetched( surveyEventEndpoint, {
					body: {
						data: {
							event: { answer_question: { foo: 'bar' } },
							session: survey.session,
						},
					},
				} );
			} );
		} );
	} );

	describe( 'selectors', () => {
		describe( 'getCurrentSurvey', () => {
			it( 'returns null when no current survey is set', async () => {
				expect( registry.select( STORE_NAME ).getCurrentSurvey() ).toEqual( null );
			} );

			it( 'returns the current survey when it is set', () => {
				registry.dispatch( STORE_NAME ).receiveTriggerSurvey( survey, { triggerID: 'optimizeSurvey' } );

				expect(
					registry.select( STORE_NAME ).getCurrentSurvey()
				).toEqual( survey.survey_payload );
			} );
		} );

		describe( 'getCurrentSurveySession', () => {
			it( 'returns null when no current survey session is set', async () => {
				expect(
					registry.select( STORE_NAME ).getCurrentSurveySession()
				).toEqual( null );
			} );

			it( 'returns the current survey session when set', () => {
				registry.dispatch( STORE_NAME ).receiveTriggerSurvey( survey, { triggerID: 'optimizeSurvey' } );

				expect(
					registry.select( STORE_NAME ).getCurrentSurveySession()
				).toEqual( survey.session );
			} );
		} );
	} );
} );
<commit_msg>Update assertions to use semantic.<commit_after>/**
 * `core/user` data store: Surveys tests.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import {
	createTestRegistry,
	muteFetch,
} from '../../../../../tests/js/utils';
import { STORE_NAME } from './constants';

describe( 'core/user surveys', () => {
	let registry;

	beforeEach( () => {
		registry = createTestRegistry();
	} );

	const survey = {
		survey_payload: 'foo',
		session: 'bar',
	};
	const surveyTriggerEndpoint = /^\/google-site-kit\/v1\/core\/user\/data\/survey-trigger/;
	const surveyEventEndpoint = /^\/google-site-kit\/v1\/core\/user\/data\/survey-event/;

	describe( 'actions', () => {
		describe( 'triggerSurvey', () => {
			it( 'throws an error when parameters are missing or incorrect', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey();
				} ).toThrow( 'triggerID is required and must be a string' );

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'coolSurvey', false );
				} ).toThrow( 'options must be an object' );

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'warmSurvey', { ttl: 'a' } );
				} ).toThrow( 'options.ttl must be a number' );
			} );

			it( 'does not throw an error when parameters are correct', () => {
				muteFetch( surveyTriggerEndpoint );

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'adSenseSurvey' );
				} ).not.toThrow();

				expect( () => {
					registry.dispatch( STORE_NAME ).triggerSurvey( 'analyticsSurvey', { ttl: 1 } );
				} ).not.toThrow();
			} );

			it( 'makes network requests to endpoints', async () => {
				muteFetch( surveyTriggerEndpoint );

				await registry.dispatch( STORE_NAME ).triggerSurvey( 'optimizeSurvey', { ttl: 1 } );

				expect( fetchMock ).toHaveFetched( surveyTriggerEndpoint, {
					body: {
						data: { triggerID: 'optimizeSurvey' },
					},
				} );
			} );
		} );

		describe( 'sendSurveyEvent', () => {
			it( 'throws an error when parameters are missing or incorrect', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent();
				} ).toThrow( 'eventID is required and must be a string' );

				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent( 'dismiss_survey', 'answer_question' );
				} ).toThrow( 'eventData must be an object' );
			} );

			it( 'does not throw an error when parameters are correct', () => {
				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent( 'dismiss_survey' );
				} ).not.toThrow();

				expect( () => {
					registry.dispatch( STORE_NAME ).sendSurveyEvent( 'answer_question', { foo: 'bar' } );
				} ).not.toThrow();
			} );

			it( 'makes network requests to endpoints', async () => {
				muteFetch( surveyEventEndpoint );

				// Survey events are only sent if there is a current survey.
				registry.dispatch( STORE_NAME ).receiveTriggerSurvey( survey, { triggerID: 'optimizeSurvey' } );
				// Send a survey event.
				await registry.dispatch( STORE_NAME ).sendSurveyEvent( 'answer_question', { foo: 'bar' } );

				expect( fetchMock ).toHaveFetched( surveyEventEndpoint, {
					body: {
						data: {
							event: { answer_question: { foo: 'bar' } },
							session: survey.session,
						},
					},
				} );
			} );
		} );
	} );

	describe( 'selectors', () => {
		describe( 'getCurrentSurvey', () => {
			it( 'returns null when no current survey is set', async () => {
				expect( registry.select( STORE_NAME ).getCurrentSurvey() ).toBeNull();
			} );

			it( 'returns the current survey when it is set', () => {
				registry.dispatch( STORE_NAME ).receiveTriggerSurvey( survey, { triggerID: 'optimizeSurvey' } );

				expect(
					registry.select( STORE_NAME ).getCurrentSurvey()
				).toEqual( survey.survey_payload );
			} );
		} );

		describe( 'getCurrentSurveySession', () => {
			it( 'returns null when no current survey session is set', async () => {
				expect(
					registry.select( STORE_NAME ).getCurrentSurveySession()
				).toBeNull();
			} );

			it( 'returns the current survey session when set', () => {
				registry.dispatch( STORE_NAME ).receiveTriggerSurvey( survey, { triggerID: 'optimizeSurvey' } );

				expect(
					registry.select( STORE_NAME ).getCurrentSurveySession()
				).toEqual( survey.session );
			} );
		} );
	} );
} );
<|endoftext|>