<commit_before>// ==UserScript==
// @name         Stack Overflow Extras (SOX)
// @namespace    https://github.com/soscripted/sox
// @homepage     https://github.com/soscripted/sox
// @homepageURL  https://github.com/soscripted/sox
// @version      2.7.3 DEV
// @description  Extra optional features for Stack Overflow and Stack Exchange sites
// @contributor  ᴉʞuǝ (https://stackoverflow.com/users/1454538/, https://github.com/mezmi)
// @contributor  ᔕᖺᘎᕊ (https://stackexchange.com/users/4337810/, https://github.com/shu8)
// @contributor  Sir-Cumference (https://stackexchange.com/users/4119142/, https://github.com/Sir-Cumference)
// @contributor  GaurangTandon (https://github.com/GaurangTandon)
// @contributor  double-beep (https://stackexchange.com/users/14688437/double-beep, https://github.com/double-beep)
// @updateURL    https://cdn.jsdelivr.net/gh/soscripted/sox@dev/sox.user.js

// @match        https://*.stackoverflow.com/*
// @match        https://*.stackexchange.com/*
// @match        https://*.superuser.com/*
// @match        https://*.serverfault.com/*
// @match        https://*.askubuntu.com/*
// @match        https://*.stackapps.com/*
// @match        https://*.mathoverflow.net/*
// @match        *://github.com/soscripted/*
// @match        *://soscripted.github.io/sox/*

// @exclude      *://data.stackexchange.com/*
// @exclude      *://api.stackexchange.com/*
// @exclude      *://stackoverflow.com/c/*

// @require      https://code.jquery.com/jquery-3.3.1.min.js
// @require      https://code.jquery.com/ui/1.12.1/jquery-ui.min.js
// @require      https://api.stackexchange.com/js/2.0/all.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.5.3/jquery.timeago.min.js

// @require      sox.common.js
// @require      sox.github.js
// @require      sox.dialog.js
// @require      sox.features.js

// @resource     css sox.css
// @resource     dialog sox.dialog.html
// @resource     featuresJSON sox.features.info.json
// @resource     common sox.common.info.json
// @resource     sprites sox.sprites.svg

// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @grant        GM_info
// @grant        GM_setClipboard
// ==/UserScript==
/*jshint loopfunc: true*/
(function(sox, $) {
  'use strict';

  function init() {
    if (sox.location.on('github.com/soscripted')) {
      try {
        sox.github.init(sox.info.version, sox.info.handler);
      } catch (e) {
        throw ('SOX: There was an error while attempting to initialize the sox.github.js file, please report this on GitHub.\n' + e);
      }
      return;
    }

    if (sox.location.on('soscripted.github.io/sox/#access_token')) { //save access token
      try {
        const access_token = window.location.href.split('=')[1].split('&')[0];
        sox.loginfo('ACCESS TOKEN: ', access_token);
        GM_setValue('SOX-accessToken', access_token);
        alert('Access token successfully saved! You can close this window :)');
      } catch (e) {
        throw ('SOX: There was an error saving your access token');
      }
      return;
    }
    if (sox.info.debugging) {
      sox.debug('DEBUGGING SOX VERSION ' + sox.info.version);
      sox.debug('----------------saved variables---------------------');
      sox.settings.writeToConsole(true); //true => hide access token
      sox.debug('----------------end saved variables---------------------');
    }

    const spritesDiv = $('<div/>', { html: GM_getResourceText('sprites') });
    $('head').append(spritesDiv);

    GM_addStyle(GM_getResourceText('css'));

    const settings = sox.settings.load();
    //returns undefined if not set

    const featureInfo = JSON.parse(GM_getResourceText('featuresJSON'));

    try {
      sox.debug('SOX object', sox);
      sox.dialog.init({
        version: sox.info.version,
        features: featureInfo,
        settings: settings,
        lastVersionInstalled: sox.info.lastVersionInstalled,
      });
    } catch (e) {
      throw ('SOX: There was an error while attempting to initialize the SOX Settings Dialog, please report this on GitHub.\n' + e);
    }

    if (sox.settings.available) {
      // Execute features
      performance.mark('allFeatures-start');
      for (let i = 0; i < settings.length; ++i) {
        const category = settings[i].split('-')[0];
        const featureId = settings[i].split('-')[1];

        if (!(category in featureInfo.categories)) { //if we ever rename a category
          sox.loginfo('Deleting feature "' + settings[i] + '" (category rename?)');
          settings.splice(i, 1);
          sox.settings.save(settings);
          continue;
        }

        const feature = featureInfo.categories[category].filter(obj => {
          return obj.name == featureId;
        })[0];

        let runFeature = true;
        try {
          //NOTE: there is no else if() because it is possible to have both match and exclude patterns..
          //which could have minor exceptions making it neccessary to check both
          if (feature.match !== '') {
            const sites = feature.match.split(',');

            for (let pattern = 0; pattern < sites.length; pattern++) {
              if (!sox.location.matchWithPattern(sites[pattern])) {
                runFeature = false; //none of the patterns match the current site.. yet.
              } else {
                runFeature = true;
                break; //if it does match, then stop looping; we want the feature to run
              }
            }
          }
          if (feature.exclude !== '') {
            const sites = feature.exclude.split(',');

            for (let pattern = 0; pattern < sites.length; pattern++) {
              if (sox.location.matchWithPattern(sites[pattern])) { //if current site is in list, DON'T run feature
                runFeature = false; //don't run feature
                break; //no need to keep on looping
              }
            }
          }
          if (runFeature) {
            sox.debug('running ' + featureId);
            performance.mark(`${featureId}-start`);
            if (feature.settings) {
              const settingsToPass = GM_getValue('SOX-' + featureId + '-settings') ? JSON.parse(GM_getValue('SOX-' + featureId + '-settings')) : {};
              sox.features[featureId](settingsToPass); //run the feature if match and exclude conditions are met, pass on settings object
            } else {
              sox.features[featureId](); //run the feature if match and exclude conditions are met
            }
            performance.mark(`${featureId}-end`);
            performance.measure(featureId, `${featureId}-start`, `${featureId}-end`);
          }
        } catch (err) {
          if (!sox.features[featureId] || !feature) { //remove deprecated/'corrupt' feature IDs from saved settings
            sox.loginfo('Deleting feature "' + settings[i] + '" (feature not found)');
            settings.splice(i, 1);
            sox.settings.save(settings);
            $('#sox-settings-dialog-features').find('#' + settings[i].split('-')[1]).parent().parent().remove();
          } else {
            $('#sox-settings-dialog-features').find('#' + settings[i].split('-')[1]).parent().css('color', 'red').attr('title', 'There was an error loading this feature. Please raise an issue on GitHub.');
            sox.error('There was an error loading the feature "' + settings[i] + '". Please raise an issue on GitHub, and copy the following error log:\n' + err);
          }
        }
      }
      performance.mark('allFeatures-end');
      performance.measure('allFeatures', 'allFeatures-start', 'allFeatures-end');
      sox.debug('Performance Data', performance.getEntriesByType('measure'));
    }

    //custom events....
    sox.helpers.observe([...document.getElementsByClassName('post-layout')], '.new_comment, .comment, .comments, .comment-text', node => {
      sox.debug('sox-new-comment event triggered');
      $(document).trigger('sox-new-comment', [node]);
    });

    sox.helpers.observe(document.body, 'textarea[id^="wmd-input"]', node => {
      sox.debug('sox-edit-window event triggered');
      $(document).trigger('sox-edit-window', [node]);
    });

    sox.helpers.observe(document.body, '.reviewable-post, .review-content', node => {
      sox.debug('sox-new-review-post-appeared event triggered');
      $(document).trigger('sox-new-review-post-appeared', [node]);
    });

    const chatBody = document.getElementById('chat-body');
    if (chatBody) {
      sox.helpers.observe(chatBody, '.user-popup', node => {
        sox.debug('sox-chat-user-popup event triggered');
        $(document).trigger('sox-chat-user-popup', [node]);
      });
    }

    if (GM_getValue('SOX-accessToken', -1) == -1) { //set access token
      //This was originally a series of IIFEs appended to the head which used the SE API JS SDK but
      //it was very uncertain and often caused issues, especially in FF
      //it now uses a Github page to show the access token
      //and detects that page and saves it automatically.
      //this seems to be a much cleaner and easier-to-debug method!
      GM_setValue('SOX-accessToken', -2); //once we ask the user once, don't ask them again: set the value to -2 so this IF never evaluates to true
      const askUserToAuthorise = window.confirm('To get the most out of SOX, you should get an access token! Please press "OK" to continue and follow the instructions in the window that opens. NOTE: this message will not appear again; if you choose not to, you can click the key at the bottom of the settings dialog at anytime to get one.');
      if (askUserToAuthorise) window.open('https://stackexchange.com/oauth/dialog?client_id=7138&scope=no_expiry&redirect_uri=http://soscripted.github.io/sox/');
      sox.warn('Please go to the following URL to get your access token for certain SOX features', 'https://stackexchange.com/oauth/dialog?client_id=7138&scope=no_expiry&redirect_uri=http://soscripted.github.io/sox/');
    }
  }
  sox.ready(init);
})(window.sox = window.sox || {}, jQuery);
<commit_msg>Run the features on focus to avoid being backoffed when opening many tabs<commit_after>// ==UserScript==
// @name         Stack Overflow Extras (SOX)
// @namespace    https://github.com/soscripted/sox
// @homepage     https://github.com/soscripted/sox
// @homepageURL  https://github.com/soscripted/sox
// @version      2.7.3 DEV
// @description  Extra optional features for Stack Overflow and Stack Exchange sites
// @contributor  ᴉʞuǝ (https://stackoverflow.com/users/1454538/, https://github.com/mezmi)
// @contributor  ᔕᖺᘎᕊ (https://stackexchange.com/users/4337810/, https://github.com/shu8)
// @contributor  Sir-Cumference (https://stackexchange.com/users/4119142/, https://github.com/Sir-Cumference)
// @contributor  GaurangTandon (https://github.com/GaurangTandon)
// @contributor  double-beep (https://stackexchange.com/users/14688437/double-beep, https://github.com/double-beep)
// @updateURL    https://cdn.jsdelivr.net/gh/soscripted/sox@dev/sox.user.js

// @match        https://*.stackoverflow.com/*
// @match        https://*.stackexchange.com/*
// @match        https://*.superuser.com/*
// @match        https://*.serverfault.com/*
// @match        https://*.askubuntu.com/*
// @match        https://*.stackapps.com/*
// @match        https://*.mathoverflow.net/*
// @match        *://github.com/soscripted/*
// @match        *://soscripted.github.io/sox/*

// @exclude      *://data.stackexchange.com/*
// @exclude      *://api.stackexchange.com/*
// @exclude      *://stackoverflow.com/c/*

// @require      https://code.jquery.com/jquery-3.3.1.min.js
// @require      https://code.jquery.com/ui/1.12.1/jquery-ui.min.js
// @require      https://api.stackexchange.com/js/2.0/all.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.5.3/jquery.timeago.min.js

// @require      sox.common.js
// @require      sox.github.js
// @require      sox.dialog.js
// @require      sox.features.js

// @resource     css sox.css
// @resource     dialog sox.dialog.html
// @resource     featuresJSON sox.features.info.json
// @resource     common sox.common.info.json
// @resource     sprites sox.sprites.svg

// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @grant        GM_info
// @grant        GM_setClipboard
// ==/UserScript==
/*jshint loopfunc: true*/
(function(sox, $) {
  'use strict';

  function runFeatures(settings, featureInfo) {
    // Execute features
    performance.mark('allFeatures-start');
    for (let i = 0; i < settings.length; ++i) {
      const category = settings[i].split('-')[0];
      const featureId = settings[i].split('-')[1];

      if (!(category in featureInfo.categories)) { //if we ever rename a category
        sox.loginfo('Deleting feature "' + settings[i] + '" (category rename?)');
        settings.splice(i, 1);
        sox.settings.save(settings);
        continue;
      }

      const feature = featureInfo.categories[category].filter(obj => {
        return obj.name == featureId;
      })[0];

      let runFeature = true;
      try {
        //NOTE: there is no else if() because it is possible to have both match and exclude patterns..
        //which could have minor exceptions making it neccessary to check both
        if (feature.match !== '') {
          const sites = feature.match.split(',');

          for (let pattern = 0; pattern < sites.length; pattern++) {
            if (!sox.location.matchWithPattern(sites[pattern])) {
              runFeature = false; //none of the patterns match the current site.. yet.
            } else {
              runFeature = true;
              break; //if it does match, then stop looping; we want the feature to run
            }
          }
        }
        if (feature.exclude !== '') {
          const sites = feature.exclude.split(',');

          for (let pattern = 0; pattern < sites.length; pattern++) {
            if (sox.location.matchWithPattern(sites[pattern])) { //if current site is in list, DON'T run feature
              runFeature = false; //don't run feature
              break; //no need to keep on looping
            }
          }
        }
        if (runFeature) {
          sox.debug('running ' + featureId);
          performance.mark(`${featureId}-start`);
          if (feature.settings) {
            const settingsToPass = GM_getValue('SOX-' + featureId + '-settings') ? JSON.parse(GM_getValue('SOX-' + featureId + '-settings')) : {};
            sox.features[featureId](settingsToPass); //run the feature if match and exclude conditions are met, pass on settings object
          } else {
            sox.features[featureId](); //run the feature if match and exclude conditions are met
          }
          performance.mark(`${featureId}-end`);
          performance.measure(featureId, `${featureId}-start`, `${featureId}-end`);
        }
      } catch (err) {
        if (!sox.features[featureId] || !feature) { //remove deprecated/'corrupt' feature IDs from saved settings
          sox.loginfo('Deleting feature "' + settings[i] + '" (feature not found)');
          settings.splice(i, 1);
          sox.settings.save(settings);
          $('#sox-settings-dialog-features').find('#' + settings[i].split('-')[1]).parent().parent().remove();
        } else {
          $('#sox-settings-dialog-features').find('#' + settings[i].split('-')[1]).parent().css('color', 'red').attr('title', 'There was an error loading this feature. Please raise an issue on GitHub.');
          sox.error('There was an error loading the feature "' + settings[i] + '". Please raise an issue on GitHub, and copy the following error log:\n' + err);
        }
      }
    }
    performance.mark('allFeatures-end');
    performance.measure('allFeatures', 'allFeatures-start', 'allFeatures-end');
    sox.debug('Performance Data', performance.getEntriesByType('measure'));
  }

  function init() {
    if (sox.location.on('github.com/soscripted')) {
      try {
        sox.github.init(sox.info.version, sox.info.handler);
      } catch (e) {
        throw ('SOX: There was an error while attempting to initialize the sox.github.js file, please report this on GitHub.\n' + e);
      }
      return;
    }

    if (sox.location.on('soscripted.github.io/sox/#access_token')) { //save access token
      try {
        const access_token = window.location.href.split('=')[1].split('&')[0];
        sox.loginfo('ACCESS TOKEN: ', access_token);
        GM_setValue('SOX-accessToken', access_token);
        alert('Access token successfully saved! You can close this window :)');
      } catch (e) {
        throw ('SOX: There was an error saving your access token');
      }
      return;
    }
    if (sox.info.debugging) {
      sox.debug('DEBUGGING SOX VERSION ' + sox.info.version);
      sox.debug('----------------saved variables---------------------');
      sox.settings.writeToConsole(true); //true => hide access token
      sox.debug('----------------end saved variables---------------------');
    }

    const spritesDiv = $('<div/>', { html: GM_getResourceText('sprites') });
    $('head').append(spritesDiv);

    GM_addStyle(GM_getResourceText('css'));

    const settings = sox.settings.load();
    //returns undefined if not set

    const featureInfo = JSON.parse(GM_getResourceText('featuresJSON'));

    try {
      sox.debug('SOX object', sox);
      sox.dialog.init({
        version: sox.info.version,
        features: featureInfo,
        settings: settings,
        lastVersionInstalled: sox.info.lastVersionInstalled,
      });
    } catch (e) {
      throw ('SOX: There was an error while attempting to initialize the SOX Settings Dialog, please report this on GitHub.\n' + e);
    }

    if (sox.settings.available) {
       window.addEventListener('focus', () => runFeatures(settings, featureInfo), { once: true });
    }

    //custom events....
    sox.helpers.observe([...document.getElementsByClassName('post-layout')], '.new_comment, .comment, .comments, .comment-text', node => {
      sox.debug('sox-new-comment event triggered');
      $(document).trigger('sox-new-comment', [node]);
    });

    sox.helpers.observe(document.body, 'textarea[id^="wmd-input"]', node => {
      sox.debug('sox-edit-window event triggered');
      $(document).trigger('sox-edit-window', [node]);
    });

    sox.helpers.observe(document.body, '.reviewable-post, .review-content', node => {
      sox.debug('sox-new-review-post-appeared event triggered');
      $(document).trigger('sox-new-review-post-appeared', [node]);
    });

    const chatBody = document.getElementById('chat-body');
    if (chatBody) {
      sox.helpers.observe(chatBody, '.user-popup', node => {
        sox.debug('sox-chat-user-popup event triggered');
        $(document).trigger('sox-chat-user-popup', [node]);
      });
    }

    if (GM_getValue('SOX-accessToken', -1) == -1) { //set access token
      //This was originally a series of IIFEs appended to the head which used the SE API JS SDK but
      //it was very uncertain and often caused issues, especially in FF
      //it now uses a Github page to show the access token
      //and detects that page and saves it automatically.
      //this seems to be a much cleaner and easier-to-debug method!
      GM_setValue('SOX-accessToken', -2); //once we ask the user once, don't ask them again: set the value to -2 so this IF never evaluates to true
      const askUserToAuthorise = window.confirm('To get the most out of SOX, you should get an access token! Please press "OK" to continue and follow the instructions in the window that opens. NOTE: this message will not appear again; if you choose not to, you can click the key at the bottom of the settings dialog at anytime to get one.');
      if (askUserToAuthorise) window.open('https://stackexchange.com/oauth/dialog?client_id=7138&scope=no_expiry&redirect_uri=http://soscripted.github.io/sox/');
      sox.warn('Please go to the following URL to get your access token for certain SOX features', 'https://stackexchange.com/oauth/dialog?client_id=7138&scope=no_expiry&redirect_uri=http://soscripted.github.io/sox/');
    }
  }
  sox.ready(init);
})(window.sox = window.sox || {}, jQuery);
<|endoftext|>


<commit_before>'use strict'
const url = require('url')

const DOMAIN = 'localhost'

exports.addDomain = function (inputUrl) {
  const parsedUrl = url.parse(inputUrl)
  parsedUrl.host = null
  parsedUrl.hostname = DOMAIN
  return url.format(parsedUrl)
}
<commit_msg>Use arrow functions<commit_after>'use strict'
const url = require('url')

const DOMAIN = 'localhost'

exports.addDomain = (inputUrl) => {
  const parsedUrl = url.parse(inputUrl)
  parsedUrl.host = null
  parsedUrl.hostname = DOMAIN
  return url.format(parsedUrl)
}
<|endoftext|>


<commit_before>//fgnass.github.com/spin.js#v1.1
(function(a,b,c){function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}function m(a,b){for(var d in b)a[d]===c&&(a[d]=b[d]);return a}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1);return g}function h(a,b,c){c&&!c.parentNode&&h(a,c),a.insertBefore(b,c||null);return a}function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}var d=["webkit","Moz","ms","O"],e={},f;h(b.getElementsByTagName("head")[0],g("style"));var i=b.styleSheets[b.styleSheets.length-1],o=function(a){this.opts=m(a||{},{lines:12,length:7,width:5,radius:10,color:"#000",speed:1,trail:100,opacity:.25})},p=o.prototype={spin:function(a){var b=this,c=b.el=l(g(),{position:"relative"}),d,e;a&&(e=n(h(a,c,a.firstChild)),d=n(c),l(c,{left:(a.offsetWidth>>1)-d.x+e.x+"px",top:(a.offsetHeight>>1)-d.y+e.y+"px"})),b.lines(c,b.opts);if(!f){var i=b.opts,j=0,k=20/i.speed,m=(1-i.opacity)/(k*i.trail/100),o=k/i.lines;(function p(){j++;for(var a=i.lines;a;a--){var d=Math.max(1-(j+a*o)%k*m,i.opacity);b.opacity(c,i.lines-a,d,i)}b.timeout=b.el&&setTimeout(p,50)})()}return b},stop:function(){var a=this,b=a.el;clearTimeout(a.timeout),b&&b.parentNode&&b.parentNode.removeChild(b),a.el=c;return a}};p.lines=function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c)+"deg) translate("+b.radius+"px"+",0)",borderRadius:"100em"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:"translate3d(0,0,0)",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},p.opacity=function(a,b,c){a.childNodes[b].style.opacity=c},function(){var a=l(g("group"),{behavior:"url(#default#VML)"}),b;if(!k(a,"transform")&&a.adj){for(b=4;b--;)i.addRule(["group","roundrect","fill","stroke"][b],"behavior:url(#default#VML)");p.lines=function(a,b){function k(a,d,i){h(f,h(l(e(),{rotation:360/b.lines*a+"deg",left:~~d}),h(l(g("roundrect",{arcsize:1}),{width:c,height:b.width,left:b.radius,top:-b.width>>1,filter:i}),g("fill",{color:b.color,opacity:b.opacity}),g("stroke",{opacity:0}))))}function e(){return l(g("group",{coordsize:d+" "+d,coordorigin:-c+" "+ -c}),{width:d,height:d})}var c=b.length+b.width,d=2*c,f=e(),i=~(b.length+b.radius+b.width)+"px",j;if(b.shadow)for(j=1;j<=b.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=b.lines;j++)k(j);return h(l(a,{margin:i+" 0 0 "+i}),f)},p.opacity=function(a,b,c,d){d=d.shadow&&d.lines||0,a.firstChild.childNodes[b+d].firstChild.firstChild.opacity=c}}else f=k(a,"animation")}(),a.Spinner=o})(window,document)<commit_msg>Updated the minified version<commit_after>//fgnass.github.com/spin.js#v1.1
(function(a,b,c){function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}function m(a,b){for(var d in b)a[d]===c&&(a[d]=b[d]);return a}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1);return g}function h(a,b,c){c&&!c.parentNode&&h(a,c),a.insertBefore(b,c||null);return a}function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}var d=["webkit","Moz","ms","O"],e={},f;h(b.getElementsByTagName("head")[0],g("style"));var i=b.styleSheets[b.styleSheets.length-1],o=function(a){this.opts=m(a||{},{lines:12,length:7,width:5,radius:10,color:"#000",speed:1,trail:100,opacity:.25})},p=o.prototype={spin:function(a){var b=this,c=b.el=l(g(),{position:"relative"}),d,e;a&&(e=n(h(a,c,a.firstChild)),d=n(c),l(c,{left:(a.offsetWidth>>1)-d.x+e.x+"px",top:(a.offsetHeight>>1)-d.y+e.y+"px"})),b.lines(c,b.opts);if(!f){var i=b.opts,j=0,k=20/i.speed,m=(1-i.opacity)/(k*i.trail/100),o=k/i.lines;(function p(){j++;for(var a=i.lines;a;a--){var d=Math.max(1-(j+a*o)%k*m,i.opacity);b.opacity(c,i.lines-a,d,i)}b.timeout=b.el&&setTimeout(p,50)})()}return b},stop:function(){var a=this,b=a.el;clearTimeout(a.timeout),b&&b.parentNode&&b.parentNode.removeChild(b),a.el=c;return a}};p.lines=function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:"translate3d(0,0,0)",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},p.opacity=function(a,b,c){a.childNodes[b].style.opacity=c},function(){var a=l(g("group"),{behavior:"url(#default#VML)"}),b;if(!k(a,"transform")&&a.adj){for(b=4;b--;)i.addRule(["group","roundrect","fill","stroke"][b],"behavior:url(#default#VML)");p.lines=function(a,b){function k(a,d,i){h(f,h(l(e(),{rotation:360/b.lines*a+"deg",left:~~d}),h(l(g("roundrect",{arcsize:1}),{width:c,height:b.width,left:b.radius,top:-b.width>>1,filter:i}),g("fill",{color:b.color,opacity:b.opacity}),g("stroke",{opacity:0}))))}function e(){return l(g("group",{coordsize:d+" "+d,coordorigin:-c+" "+ -c}),{width:d,height:d})}var c=b.length+b.width,d=2*c,f=e(),i=~(b.length+b.radius+b.width)+"px",j;if(b.shadow)for(j=1;j<=b.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=b.lines;j++)k(j);return h(l(a,{margin:i+" 0 0 "+i}),f)},p.opacity=function(a,b,c,d){d=d.shadow&&d.lines||0,a.firstChild.childNodes[b+d].firstChild.firstChild.opacity=c}}else f=k(a,"animation")}(),a.Spinner=o})(window,document)<|endoftext|>


<commit_before>'use strict';

var CallbackStore = require('famous-utilities').CallbackStore;

function EventHandler (dispatch, events) {
    this.dispatch = dispatch;
    this._events = new CallbackStore();
    for (var i = 0, len = events.length; i < len; i++) {
        var eventName = events[i].event;
        var callback = events[i].callback;
        this._events.on(eventName, callback);
        dispatch.registerGlobalEvent(eventName, this.trigger.bind(this, eventName));
    }
}

EventHandler.toString = function toString() {
    return 'EventHandler';
};

EventHandler.prototype.on = function on (ev, cb) {
    this._events.on(ev, cb);
    this.dispatch.registerGlobalEvent(ev, this.trigger.bind(this, ev));
};

EventHandler.prototype.off = function off (ev, cb) {
    this._events.off(ev, cb);
    this.dispatch.deregisterGlobalEvent(ev, this.trigger.bind(this, ev))
};

EventHandler.prototype.trigger = function trigger (ev, payload) {
    this._events.trigger(ev, payload);
};

module.exports = EventHandler;
<commit_msg>fix: error with EventHandler if no events were passed<commit_after>'use strict';

var CallbackStore = require('famous-utilities').CallbackStore;

function EventHandler (dispatch, events) {
    this.dispatch = dispatch;
    this._events = new CallbackStore();

    if (events) {
        for (var i = 0, len = events.length; i < len; i++) {
            var eventName = events[i].event;
            var callback = events[i].callback;
            this._events.on(eventName, callback);
            dispatch.registerGlobalEvent(eventName, this.trigger.bind(this, eventName));
        }
    }
}

EventHandler.toString = function toString() {
    return 'EventHandler';
};

EventHandler.prototype.on = function on (ev, cb) {
    this._events.on(ev, cb);
    this.dispatch.registerGlobalEvent(ev, this.trigger.bind(this, ev));
};

EventHandler.prototype.off = function off (ev, cb) {
    this._events.off(ev, cb);
    this.dispatch.deregisterGlobalEvent(ev, this.trigger.bind(this, ev))
};

EventHandler.prototype.trigger = function trigger (ev, payload) {
    this._events.trigger(ev, payload);
};

module.exports = EventHandler;
<|endoftext|>


<commit_before>"use strict";

/**
 * Convert the dataType property to the type property.  Only
 * useful for making schema conversions easier, and avoid conflicts with
 * type types.
 *
 * @param Clazz
 * @param props
 * @param key
 * @param value
 */
export default function dataType(Clazz, key, propTypeKeys) {

    //array of keys to allow for prop type renames.  This should not happen much, but we have dataType->type conversion.
    propTypeKeys.splice(propTypeKeys.indexOf(key), 1, 'type');

    Clazz::this.extendPrototype('componentWillMount', function dataType$willMount() {
        if (!this.injected) this.injected = {};
        this.injected.type = this.props[key] || this.props.type;
    });

    Clazz::this.extendPrototype('componentWillReceiveProps', function dataType$willRecieveProps(newProps) {
        if (!this.injected) this.injected = {};
        if (this.props[key] !== newProps[key]) {
            this.injected.type = this.props[key] || this.props.type;
        }
    });

}<commit_msg>Prevent array shrinking when key does not exist.<commit_after>"use strict";

/**
 * Convert the dataType property to the type property.  Only
 * useful for making schema conversions easier, and avoid conflicts with
 * type types.
 *
 * @param Clazz
 * @param props
 * @param key
 * @param value
 */
export default function dataType(Clazz, key, propTypeKeys) {

    //array of keys to allow for prop type renames.  This should not happen much, but we have dataType->type conversion.
    const idx = propTypeKeys.indexOf(key);
    if (idx > -1){
       propTypeKeys.splice(idx, 1, 'type');
    }

    Clazz::this.extendPrototype('componentWillMount', function dataType$willMount() {
        if (!this.injected) this.injected = {};
        this.injected.type = this.props[key] || this.props.type;
    });

    Clazz::this.extendPrototype('componentWillReceiveProps', function dataType$willRecieveProps(newProps) {
        if (!this.injected) this.injected = {};
        if (this.props[key] !== newProps[key]) {
            this.injected.type = this.props[key] || this.props.type;
        }
    });

}
<|endoftext|>


<commit_before>import { defaultPalette } from '../js/getCustomTheme';
import Snippet from './Snippet';

export default new Map([
  ['options', {
    test: /^\.options$/i,
    multiple: false,
    defaultValue: {
      tabVisibility: false,
      darkness: false,
      lineWrapping: false,
      indentUnit4: true,
    },
    defaultName: '.options',
  }],
  ['palette', {
    test: /^\.palette$/i,
    multiple: false,
    defaultValue: defaultPalette,
    defaultName: '.palette',
  }],
  ['env', {
    test: /^\.env$/i,
    multiple: false,
    defaultValue: {
      DEBUG: [true, 'boolean', 'A flag means test mode'],
      TITLE: ['My App', 'string', 'A name of this app'],
    },
    defaultName: '.env',
  }],
  ['babelrc', {
    test: /^\.babelrc$/i,
    multiple: false,
    defaultValue: {
      presets: ['es2015'],
    },
    defaultName: '.babelrc',
  }],
  ['snippets', {
    test: /^snippets\//i,
    multiple: true,
    defaultValue: {},
    defaultName: 'snippets/snippet.json',
    bundle: (files) => {
      const snippets = files
        .reduce((p, file) => {
          const { name, json } = file;
          Object.keys(json).forEach((scope) => {
            p[scope] = (p[scope] || []).concat(
              Object.keys(json[scope])
                .map((key) => new Snippet(
                  Object.assign({
                    name,
                    fileKey: file.key,
                  }, json[scope][key])
                ))
            );
          });
          return p;
        }, Object.create(null));
      const scopes = Object.keys(snippets);
      scopes.forEach((scope) => {
        snippets[scope] = snippets[scope].sort(
          (a, b) =>
            a.prefix.toLowerCase() > b.prefix.toLowerCase() ? 1 : -1
        );
      });
      return (file) =>
        scopes.filter((scope) => file.is(scope))
          .map((scope) => snippets[scope])
          .reduce((p, c) => p.concat(c), []);
    },
  }]
]);
<commit_msg>.provider type<commit_after>import { defaultPalette } from '../js/getCustomTheme';
import Snippet from './Snippet';

export default new Map([
  ['options', {
    test: /^\.options$/i,
    multiple: false,
    defaultValue: {
      tabVisibility: false,
      darkness: false,
      lineWrapping: false,
      indentUnit4: true,
    },
    defaultName: '.options',
  }],
  ['palette', {
    test: /^\.palette$/i,
    multiple: false,
    defaultValue: defaultPalette,
    defaultName: '.palette',
  }],
  ['env', {
    test: /^\.env$/i,
    multiple: false,
    defaultValue: {
      DEBUG: [true, 'boolean', 'A flag means test mode'],
      TITLE: ['My App', 'string', 'A name of this app'],
    },
    defaultName: '.env',
  }],
  ['babelrc', {
    test: /^\.babelrc$/i,
    multiple: false,
    defaultValue: {
      presets: ['es2015'],
    },
    defaultName: '.babelrc',
  }],
  ['provider', {
    test: /^\.provider$/i,
    multiple: false,
    defaultValue: {
      publishUrl: '',
    },
    defaultName: '.provider',
  }],
  ['snippets', {
    test: /^snippets\//i,
    multiple: true,
    defaultValue: {},
    defaultName: 'snippets/snippet.json',
    bundle: (files) => {
      const snippets = files
        .reduce((p, file) => {
          const { name, json } = file;
          Object.keys(json).forEach((scope) => {
            p[scope] = (p[scope] || []).concat(
              Object.keys(json[scope])
                .map((key) => new Snippet(
                  Object.assign({
                    name,
                    fileKey: file.key,
                  }, json[scope][key])
                ))
            );
          });
          return p;
        }, Object.create(null));
      const scopes = Object.keys(snippets);
      scopes.forEach((scope) => {
        snippets[scope] = snippets[scope].sort(
          (a, b) =>
            a.prefix.toLowerCase() > b.prefix.toLowerCase() ? 1 : -1
        );
      });
      return (file) =>
        scopes.filter((scope) => file.is(scope))
          .map((scope) => snippets[scope])
          .reduce((p, c) => p.concat(c), []);
    },
  }]
]);
<|endoftext|>


<commit_before>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, 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
 *
 *         http://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.
 */

(function() {
  'use strict';
  angular.module('bk.core').factory('autocompleteParametersService', function() {

    var markConfig = {
      clearWhenEmpty: false,
      inclusiveLeft: true,
      inclusiveRight: true
    };

    var params = [];
    var cm;
    var scope;
    var currentParam;
    var args = [];

    function startParameterCompletion(codeMirror, documentation, selectionStart, selectionEnd, $scope) {
      cm = codeMirror;
      params = documentation.parameters;
      scope = $scope;
      markParameters(selectionStart, selectionEnd);
      cm.on('cursorActivity', endCompletionIfCursorOutOfRange);
      nextParameter();
    }

    function endCompletionIfCursorOutOfRange(cm) {
      if (!isActive()) {
        return;
      }
      if (!cursorInRange(getCompletionRange())) {
        return endCompletion();
      }

      if (cursorInRange(args[currentParam].find())) {
        return showParameterDocumentation(params[currentParam]);
      }

      var activeArgumentIndex = getArgumentIndexUnderCursor();
      if (activeArgumentIndex === -1 || _.isUndefined(activeArgumentIndex)) {
        return hideParameterDocumentation();
      }
      toParam(activeArgumentIndex);

    }

    function getArgumentIndexUnderCursor() {
      return _.findIndex(args, function(arg) {
        return cursorInRange(arg.find());
      });
    }

    function cursorInRange(range) {
      var cursor = cm.getCursor('anchor');
      return cursor.line >= range.from.line &&
        cursor.line <= range.to.line &&
        cursor.ch >= range.from.ch &&
        cursor.ch <= range.to.ch;
    }

    function getCompletionRange() {
      return {from: args[0].find().from, to: _.last(args).find().to};
    }

    function markParameters(from, to) {
      var paramsString = cm.getRange(from, to);
      args = _(params).map(function(p) {
        var position = paramsString.indexOf(p.name);
        return [position, position + p.name.length - 1];
      }).map(function(p) {
        var start = _.merge({}, from, {ch: from.ch + p[0]});
        var end = _.merge({}, from, {ch: from.ch + p[1] + 1});
        return markWithClass(start, end, 'marked-argument-unchanged');
      }).value();
    }

    function markWithClass(start, end, className) {
      return cm.markText(start, end, _.merge({}, {className: className}, markConfig));
    }

    function nextParameter() {
      if (currentParam === params.length - 1) {
        return endCompletionAndMoveCursor();
      }
      toParam(_.isUndefined(currentParam) ? 0 : currentParam + 1);
    }

    function previousParameter() {
      if (currentParam === 0) {
        return endCompletionAndMoveCursor();
      }

      toParam(_.isUndefined(currentParam) ? params.length - 1 : currentParam - 1);
    }

    function toParam(index) {
      if (! _.isUndefined(currentParam)) {
        params[currentParam].argument = args[currentParam].find();
        markArgumentIfChanged();
      }
      currentParam = index;
      selectArgument(currentParam);
      showParameterDocumentation(params[currentParam]);
    }

    function markArgumentIfChanged() {
      var p = params[currentParam]
      if (cm.getRange(p.argument.from, p.argument.to) !== p.name) {
        args[currentParam].clear();
        args[currentParam] = markWithClass(p.argument.from, p.argument.to, 'marked-argument-changed');
      }
    }

    function isActive() {
      return !(_.isEmpty(params));
    }

    function endCompletion() {
      cm.off('cursorActivity', endCompletionIfCursorOutOfRange);
      hideParameterDocumentation();
      clearMarks()
      cm = void 0;
      currentParam = void 0;
      scope = void 0;
      params = [];
      args = [];
    }

    function endCompletionAndMoveCursor() {
      var lastArg = _.last(args).find();
      cm.setCursor(_.merge({}, lastArg.to, {ch: lastArg.to.ch + 1}));
      endCompletion();
    }

    function selectArgument(i) {
      var arg = args[i].find();
      cm.setSelection(arg.from, arg.to);
    }

    function clearMarks() {
      _.forEach(args, function(arg) {
        arg.clear();
      });
    }

    function showParameterDocumentation(param) {
      scope.$broadcast('showParameterDocumentation', param.description);
    }

    function hideParameterDocumentation() {
      scope.$broadcast('hideParameterDocumentation');
    }

    return {
      startParameterCompletion: startParameterCompletion,
      isActive: isActive,
      nextParameter: nextParameter,
      previousParameter: previousParameter,
      endCompletion: endCompletion,
      endCompletionAndMoveCursor: endCompletionAndMoveCursor
    };

  });
})();
<commit_msg>#2831 - Made tabbing through argument cyclical<commit_after>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, 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
 *
 *         http://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.
 */

(function() {
  'use strict';
  angular.module('bk.core').factory('autocompleteParametersService', function() {

    var markConfig = {
      clearWhenEmpty: false,
      inclusiveLeft: true,
      inclusiveRight: true
    };

    var params = [];
    var cm;
    var scope;
    var currentParam;
    var args = [];

    function startParameterCompletion(codeMirror, documentation, selectionStart, selectionEnd, $scope) {
      cm = codeMirror;
      params = documentation.parameters;
      scope = $scope;
      markParameters(selectionStart, selectionEnd);
      cm.on('cursorActivity', endCompletionIfCursorOutOfRange);
      nextParameter();
    }

    function endCompletionIfCursorOutOfRange(cm) {
      if (!isActive()) {
        return;
      }
      if (!cursorInRange(getCompletionRange())) {
        return endCompletion();
      }

      if (cursorInRange(args[currentParam].find())) {
        return showParameterDocumentation(params[currentParam]);
      }

      var activeArgumentIndex = getArgumentIndexUnderCursor();
      if (activeArgumentIndex === -1 || _.isUndefined(activeArgumentIndex)) {
        return hideParameterDocumentation();
      }
      toParam(activeArgumentIndex);

    }

    function getArgumentIndexUnderCursor() {
      return _.findIndex(args, function(arg) {
        return cursorInRange(arg.find());
      });
    }

    function cursorInRange(range) {
      var cursor = cm.getCursor('anchor');
      return cursor.line >= range.from.line &&
        cursor.line <= range.to.line &&
        cursor.ch >= range.from.ch &&
        cursor.ch <= range.to.ch;
    }

    function getCompletionRange() {
      return {from: args[0].find().from, to: _.last(args).find().to};
    }

    function markParameters(from, to) {
      var paramsString = cm.getRange(from, to);
      args = _(params).map(function(p) {
        var position = paramsString.indexOf(p.name);
        return [position, position + p.name.length - 1];
      }).map(function(p) {
        var start = _.merge({}, from, {ch: from.ch + p[0]});
        var end = _.merge({}, from, {ch: from.ch + p[1] + 1});
        return markWithClass(start, end, 'marked-argument-unchanged');
      }).value();
    }

    function markWithClass(start, end, className) {
      return cm.markText(start, end, _.merge({}, {className: className}, markConfig));
    }

    function nextParameter() {
      toParam(_.isUndefined(currentParam) || currentParam === params.length - 1? 0 : currentParam + 1);
    }

    function previousParameter() {
      toParam(_.isUndefined(currentParam) || currentParam === 0 ? params.length - 1 : currentParam - 1);
    }

    function toParam(index) {
      if (! _.isUndefined(currentParam)) {
        params[currentParam].argument = args[currentParam].find();
        markArgumentIfChanged();
      }
      currentParam = index;
      selectArgument(currentParam);
      showParameterDocumentation(params[currentParam]);
    }

    function markArgumentIfChanged() {
      var p = params[currentParam]
      if (cm.getRange(p.argument.from, p.argument.to) !== p.name) {
        args[currentParam].clear();
        args[currentParam] = markWithClass(p.argument.from, p.argument.to, 'marked-argument-changed');
      }
    }

    function isActive() {
      return !(_.isEmpty(params));
    }

    function endCompletion() {
      cm.off('cursorActivity', endCompletionIfCursorOutOfRange);
      hideParameterDocumentation();
      clearMarks()
      cm = void 0;
      currentParam = void 0;
      scope = void 0;
      params = [];
      args = [];
    }

    function endCompletionAndMoveCursor() {
      var lastArg = _.last(args).find();
      cm.setCursor(_.merge({}, lastArg.to, {ch: lastArg.to.ch + 1}));
      endCompletion();
    }

    function selectArgument(i) {
      var arg = args[i].find();
      cm.setSelection(arg.from, arg.to);
    }

    function clearMarks() {
      _.forEach(args, function(arg) {
        arg.clear();
      });
    }

    function showParameterDocumentation(param) {
      scope.$broadcast('showParameterDocumentation', param.description);
    }

    function hideParameterDocumentation() {
      scope.$broadcast('hideParameterDocumentation');
    }

    return {
      startParameterCompletion: startParameterCompletion,
      isActive: isActive,
      nextParameter: nextParameter,
      previousParameter: previousParameter,
      endCompletion: endCompletion,
      endCompletionAndMoveCursor: endCompletionAndMoveCursor
    };

  });
})();
<|endoftext|>


<commit_before>'use strict';

describe('networks', function () {

  var $scope, element, $routeParams, q, deferred, $httpBackend, networkFactory, zoneFactory, $location;

  beforeEach(module('templates'));

  beforeEach(module('myApp', function($provide) {
    networkFactory = {
      query: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      destroy: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      update: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      }
    };
    zoneFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    $provide.value("Zone", zoneFactory);
    $provide.value("Network", networkFactory);
  }));

  beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET('/translations/en_GB.json').respond("");
  }));

  describe('lists the networks for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<list-networks loading="loading"></list-networks>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();

      expect(element.isolateScope().menu.length).toEqual(3);
      expect(element.isolateScope().menu[0].name).toEqual('Edit Settings');
      expect(element.isolateScope().menu[0].type).toEqual('settings');
      expect(element.isolateScope().menu[1].name).toEqual('Change SSID');
      expect(element.isolateScope().menu[1].type).toEqual('ssid');
      expect(element.isolateScope().menu[2].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[2].type).toEqual('delete');

      expect(element.isolateScope().query.page).toEqual('10');
      expect(element.isolateScope().query.limit).toEqual('100');
    });

    it("should get the networks and save to scope", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();
      expect(element.isolateScope().networks[0].id).toEqual(123);
    });

    it("should update the band to 2.4Ghz or 5Ghz", function() {
      element.isolateScope().updateBand('two');
      expect(element.isolateScope().band).toEqual('2.4Ghz');

      element.isolateScope().updateBand('five');
      expect(element.isolateScope().band).toEqual('5Ghz');

      element.isolateScope().updateBand();
      expect(element.isolateScope().band).toEqual('');
    });

    it("should delete a network and remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(0);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should not delete a network and not remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.reject({errors: {data: [{a: 123}]}});
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(1);
    });

    it("should update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should fail to update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.reject();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

  });

  describe('creates new network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<new-network loading="loading"></new-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      // Would prefer to not use a scope //
      element.isolateScope().init();

      var cf = ['Danger', 'Adult', 'Security', 'Family', 'Off'];
      expect(element.isolateScope().content_filters).toEqual(cf);
      var network = element.isolateScope().network
      expect(network.ssid).toEqual('My WiFi Network')
      expect(network.access_type).toEqual('password')
      expect(network.encryption_type).toEqual('psk2')
      expect(network.band_steering).toEqual(true)
      expect(network.active).toEqual(true)
      expect(network.interface_ipaddr === '').toEqual(false)
      expect(network.dhcp_enabled).toEqual(true)
      expect(network.dns_1).toEqual('8.8.8.8')
      expect(network.dns_2).toEqual('8.8.4.4')
      expect(network.interface_netmask).toEqual(24)
      expect(network.use_ps_radius).toEqual(true)
      expect(network.captive_portal_ps).toEqual(true)
      expect(network.content_filter).toEqual('Security')
      expect(network.captive_portal_enabled).toEqual(false)
    });

  });

  describe('displays the network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector, _$location_) {
      $scope = $rootScope;
      q = $q;
      $location = _$location_
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<display-network loading="loading"></display-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default vars for the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var network = { id: '123' };
      deferred.resolve(network);
      $scope.$apply();

      var cf = [{ key: 'Off', value: 'off' }, { key: 'Allow', value: 'allow'}, { key: 'Block', value: 'deny'}];
      expect(element.isolateScope().client_filters).toEqual(cf);
      expect(element.isolateScope().menu.length).toEqual(3);
      expect(element.isolateScope().menu[0].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[0].type).toEqual('delete');
      expect(element.isolateScope().menu[1].name).toEqual('View Zones');
      expect(element.isolateScope().menu[1].type).toEqual('zones');
      expect(element.isolateScope().menu[2].name).toEqual('Test Radius');
      expect(element.isolateScope().menu[2].type).toEqual('radius');
    });

    it("should show the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      deferred.resolve(network);
      $scope.$apply();

      expect(element.isolateScope().network.id).toEqual('123');
      expect(element.isolateScope().network.ssid_hidden).toEqual(false);
      expect(element.isolateScope().short_ip).toEqual('10.168.210.');
    });

    it("should destroy the network", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      element.isolateScope().network = network;
      element.isolateScope().destroy();
      deferred.resolve(network);
      $scope.$apply();
      expect($location.path()).toEqual('/locations/xxx/networks');
    });
  });
});
<commit_msg>fixes networks spec<commit_after>'use strict';

describe('networks', function () {

  var $scope, element, $routeParams, q, deferred, $httpBackend, networkFactory, zoneFactory, $location;

  beforeEach(module('templates'));

  beforeEach(module('myApp', function($provide) {
    networkFactory = {
      query: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      destroy: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
      update: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      }
    };
    zoneFactory = {
      get: function () {
        deferred = q.defer();
        return {$promise: deferred.promise};
      },
    };
    $provide.value("Zone", zoneFactory);
    $provide.value("Network", networkFactory);
  }));

  beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET('/translations/en_GB.json').respond("");
  }));

  describe('lists the networks for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<list-networks loading="loading"></list-networks>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();

      expect(element.isolateScope().menu.length).toEqual(3);
      expect(element.isolateScope().menu[0].name).toEqual('Edit Settings');
      expect(element.isolateScope().menu[0].type).toEqual('settings');
      expect(element.isolateScope().menu[1].name).toEqual('Change SSID');
      expect(element.isolateScope().menu[1].type).toEqual('ssid');
      expect(element.isolateScope().menu[2].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[2].type).toEqual('delete');

      expect(element.isolateScope().query.page).toEqual('10');
      expect(element.isolateScope().query.limit).toEqual('100');
    });

    it("should get the networks and save to scope", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      var results = [{ id: 123 }];
      deferred.resolve(results);
      $scope.$apply();
      expect(element.isolateScope().networks[0].id).toEqual(123);
    });

    it("should update the band to 2.4Ghz or 5Ghz", function() {
      element.isolateScope().updateBand('two');
      expect(element.isolateScope().band).toEqual('2.4Ghz');

      element.isolateScope().updateBand('five');
      expect(element.isolateScope().band).toEqual('5Ghz');

      element.isolateScope().updateBand();
      expect(element.isolateScope().band).toEqual('');
    });

    it("should delete a network and remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(0);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should not delete a network and not remove from array", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();
      var network = { id: 123 };
      element.isolateScope().networks = [network];

      element.isolateScope().destroy(network)
      deferred.reject({errors: {data: [{a: 123}]}});
      $scope.$apply();
      expect(element.isolateScope().networks.length).toEqual(1);
    });

    it("should update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.resolve();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

    // To fix - breaks since we need to sort the errors popup
    xit("should fail to update a network", function() {
      spyOn(networkFactory, 'update').and.callThrough();
      var network = { id: 123, state: 'foo' };
      element.isolateScope().networks = [network];

      element.isolateScope().update(network)
      deferred.reject();
      $scope.$apply();
      expect(element.isolateScope().networks[0].state).toEqual(undefined);
    });

  });

  describe('creates new network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector) {
      $scope = $rootScope;
      q = $q;
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<new-network loading="loading"></new-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default scopes vals", function() {
      spyOn(networkFactory, 'get').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      // Would prefer to not use a scope //
      element.isolateScope().init();

      var cf = ['Danger', 'Adult', 'Security', 'Family', 'Off'];
      expect(element.isolateScope().content_filters).toEqual(cf);
      var network = element.isolateScope().network
      expect(network.ssid).toEqual('My WiFi Network')
      expect(network.access_type).toEqual('password')
      expect(network.encryption_type).toEqual('psk2')
      expect(network.band_steering).toEqual(true)
      expect(network.active).toEqual(true)
      expect(network.interface_ipaddr === '').toEqual(false)
      expect(network.dhcp_enabled).toEqual(true)
      expect(network.dns_1).toEqual('8.8.8.8')
      expect(network.dns_2).toEqual('8.8.4.4')
      expect(network.interface_netmask).toEqual(24)
      expect(network.use_ps_radius).toEqual(true)
      expect(network.captive_portal_ps).toEqual(true)
      expect(network.content_filter).toEqual('Security')
      expect(network.captive_portal_enabled).toEqual(false)
    });

  });

  describe('displays the network for a location', function() {
    beforeEach(inject(function($compile, $rootScope, $q, _$routeParams_, $injector, _$location_) {
      $scope = $rootScope;
      q = $q;
      $location = _$location_
      $routeParams = _$routeParams_;
      $routeParams.id = 'xxx';
      $routeParams.q = 'my-filter';
      $routeParams.page = '10';
      $routeParams.per = '100';
      $scope.loading = true;
      var elem = angular.element('<display-network loading="loading"></display-network>');
      element = $compile(elem)($rootScope);
      element.scope().$digest();
    }));

    it("should set the default vars for the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();
      expect(element.isolateScope().location.slug).toEqual('xxx');

      var network = { id: '123' };
      deferred.resolve(network);
      $scope.$apply();

      var cf = [
        { key: 'Off', value: 'off' },
        { key: 'Allow White-listed Clients', value: 'allow'},
        { key: 'Block Banned Clients', value: 'deny'}
      ];

      expect(element.isolateScope().client_filters[0].key).toEqual('Off');
      expect(element.isolateScope().client_filters[0].value).toEqual('off');
      expect(element.isolateScope().client_filters[1].key).toEqual('Allow White-listed Clients');
      expect(element.isolateScope().client_filters[1].value).toEqual('allow');
      expect(element.isolateScope().client_filters[2].key).toEqual('Block Banned Clients');
      expect(element.isolateScope().client_filters[2].value).toEqual('deny');

      expect(element.isolateScope().menu.length).toEqual(3);
      expect(element.isolateScope().menu[0].name).toEqual('Delete Network');
      expect(element.isolateScope().menu[0].type).toEqual('delete');
      expect(element.isolateScope().menu[1].name).toEqual('View Zones');
      expect(element.isolateScope().menu[1].type).toEqual('zones');
      expect(element.isolateScope().menu[2].name).toEqual('Test Radius');
      expect(element.isolateScope().menu[2].type).toEqual('radius');
    });

    it("should show the network", function() {
      spyOn(networkFactory, 'query').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      deferred.resolve(network);
      $scope.$apply();

      expect(element.isolateScope().network.id).toEqual('123');
      expect(element.isolateScope().network.ssid_hidden).toEqual(false);
      expect(element.isolateScope().short_ip).toEqual('10.168.210.');
    });

    it("should destroy the network", function() {
      spyOn(networkFactory, 'destroy').and.callThrough();

      var network = { id: '123', ssid_hidden: '1' };
      element.isolateScope().network = network;
      element.isolateScope().destroy();
      deferred.resolve(network);
      $scope.$apply();
      expect($location.path()).toEqual('/locations/xxx/networks');
    });
  });
});
<|endoftext|>


<commit_before>var assert = require('assert');
var RedisPool = require('redis-mpool');
var TemplateMaps = require('../../../lib/cartodb/template_maps.js');
var test_helper = require('../../support/test_helper');
var _ = require('underscore');

suite('template_maps', function() {

    var redisPool = new RedisPool(global.environment.redis),
        templateMaps = new TemplateMaps(redisPool);

    var owner = 'me';
    var templateName = 'wadus';

    var defaultTemplate = {
        version:'0.0.1',
        name: templateName,
        layergroup: {
            layers: [
                {
                    options: {
                        sql: 'select 1 cartodb_id, null::geometry the_geom_webmercator',
                        cartocss: '#layer { marker-fill:blue; }',
                        cartocss_version: '2.3.0'
                    }
                }
            ]
        }
    };

    function makeTemplate(auth, placeholders) {
        return _.extend({}, defaultTemplate, {
            auth: auth,
            placeholders: placeholders
        });
    }

    var defaultAuth = {
        method: 'open'
    };

    var authTokenSample = {
        method: 'token',
        valid_tokens: ['wadus_token']
    };

    var placeholdersSample = {
        wadus: {
            type: 'number',
            default: 1
        }
    };

    var testScenarios = [
        {
            desc: 'default auth and placeholders values',
            template: defaultTemplate,
            expected: {
                auth: defaultAuth,
                placeholders: {}
            }
        },
        {
            desc: 'default placeholders but specified auth',
            template: makeTemplate(authTokenSample),
            expected: {
                auth: authTokenSample,
                placeholders: {}
            }
        },
        {
            desc: 'default auth but specified placeholders',
            template: makeTemplate(undefined, placeholdersSample),
            expected: {
                auth: defaultAuth,
                placeholders: placeholdersSample
            }
        },
        {
            desc: 'specified auth and placeholders',
            template: makeTemplate(authTokenSample, placeholdersSample),
            expected: {
                auth: authTokenSample,
                placeholders: placeholdersSample
            }
        }
    ];

    testScenarios.forEach(function(testScenario) {
        test('adding template returns a new instance with ' + testScenario.desc, function(done) {

            templateMaps.addTemplate(owner, testScenario.template, function(err, templateId, template) {
                assert.ok(!err, 'Unexpected error adding template: ' + (err && err.message));
                assert.ok(testScenario.template !== template, 'template instances should be different');
                assert.equal(template.name, templateName);
                assert.deepEqual(template.auth, testScenario.expected.auth);
                assert.deepEqual(template.placeholders, testScenario.expected.placeholders);

                templateMaps.delTemplate(owner, templateName, done);
            });

        });
    });

});
<commit_msg>fix jshint<commit_after>require('../../support/test_helper');

var assert = require('assert');
var RedisPool = require('redis-mpool');
var TemplateMaps = require('../../../lib/cartodb/template_maps.js');
var _ = require('underscore');

describe('template_maps', function() {

    var redisPool = new RedisPool(global.environment.redis),
        templateMaps = new TemplateMaps(redisPool);

    var owner = 'me';
    var templateName = 'wadus';

    var defaultTemplate = {
        version:'0.0.1',
        name: templateName,
        layergroup: {
            layers: [
                {
                    options: {
                        sql: 'select 1 cartodb_id, null::geometry the_geom_webmercator',
                        cartocss: '#layer { marker-fill:blue; }',
                        cartocss_version: '2.3.0'
                    }
                }
            ]
        }
    };

    function makeTemplate(auth, placeholders) {
        return _.extend({}, defaultTemplate, {
            auth: auth,
            placeholders: placeholders
        });
    }

    var defaultAuth = {
        method: 'open'
    };

    var authTokenSample = {
        method: 'token',
        valid_tokens: ['wadus_token']
    };

    var placeholdersSample = {
        wadus: {
            type: 'number',
            default: 1
        }
    };

    var testScenarios = [
        {
            desc: 'default auth and placeholders values',
            template: defaultTemplate,
            expected: {
                auth: defaultAuth,
                placeholders: {}
            }
        },
        {
            desc: 'default placeholders but specified auth',
            template: makeTemplate(authTokenSample),
            expected: {
                auth: authTokenSample,
                placeholders: {}
            }
        },
        {
            desc: 'default auth but specified placeholders',
            template: makeTemplate(undefined, placeholdersSample),
            expected: {
                auth: defaultAuth,
                placeholders: placeholdersSample
            }
        },
        {
            desc: 'specified auth and placeholders',
            template: makeTemplate(authTokenSample, placeholdersSample),
            expected: {
                auth: authTokenSample,
                placeholders: placeholdersSample
            }
        }
    ];

    testScenarios.forEach(function(testScenario) {
        it('adding template returns a new instance with ' + testScenario.desc, function(done) {

            templateMaps.addTemplate(owner, testScenario.template, function(err, templateId, template) {
                assert.ok(!err, 'Unexpected error adding template: ' + (err && err.message));
                assert.ok(testScenario.template !== template, 'template instances should be different');
                assert.equal(template.name, templateName);
                assert.deepEqual(template.auth, testScenario.expected.auth);
                assert.deepEqual(template.placeholders, testScenario.expected.placeholders);

                templateMaps.delTemplate(owner, templateName, done);
            });

        });
    });

});
<|endoftext|>


<commit_before>/**
 * Description : This is a test suite that tests an LRS endpoint based on the testing requirements document
 * found at https://github.com/adlnet/xapi-lrs-conformance-requirements
 */

(function(module, fs, extend, moment, request, requestPromise, chai, liburl, Joi, helper, multipartParser, redirect)
{

describe('Authentication Requirements (Communication 4.0)', function() {

/**  XAPI-00334, Communication 2.1.3 GET Statements
 * An LRS rejects a Statement of bad authorization (either authentication needed or failed credentials) with error code 401 Unauthorized
 */
 describe('An LRS rejects a Statement of bad authorization (either authentication needed or failed credentials) with error code 401 Unauthorized (Authentication 4.0 XAPI-00334)',function(){

    it("fails when given a random name pass pair", function(done)
    {
        var templates = [
        {
            statement: '{{statements.default}}'
        }];
        var data = helper.createFromTemplate(templates);
        data = data.statement;
        data.id = helper.generateUUID();
        var headers = helper.addAllHeaders(
        {});

        //warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
        //with oauth already. We get a new verions by appending some other characters to defeat the cache.
        if(global.OAUTH)
            request = require('.\\super-request');
        else
            headers["Authorization"] = 'Basic ' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64');
            request(helper.getEndpointAndAuth())
            .put(helper.getEndpointStatements() + '?statementId=' + data.id)
            .headers(headers)
            .json(data)
            .expect(401, done);
    });

    it('fails with a malformed header', function(done)
    {
        var templates = [
        {
            statement: '{{statements.default}}'
        }];
        var data = helper.createFromTemplate(templates);
        data = data.statement;
        data.id = helper.generateUUID();
        var headers = helper.addAllHeaders(
        {});

        //warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
        //with oauth already. We get a new verions by appending some other characters to defeat the cache.
        if(global.OAUTH)
            request = require('.\\super-request');
        else
            headers["Authorization"] = 'Basic:' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64'); //note bad encoding here.
            request(helper.getEndpointAndAuth())
            .put(helper.getEndpointStatements() + '?statementId=' + data.id)
            .headers(headers)
            .json(data)
            .expect(401, done);
    });
});

/**  XAPI-00335, Communication 2.1.3 GET Statements
 * An LRS must support HTTP Basic Authentication
 */
 //WARNING: This might not be a great test. OAUTH will override it
    it('An LRS must support HTTP Basic Authentication(Authentication 4.0 XAPI-00335)', function(done)
    {
        var templates = [
        {
            statement: '{{statements.default}}'
        }];
        var data = helper.createFromTemplate(templates);
        data = data.statement;
        data.id = helper.generateUUID();
        var headers = helper.addAllHeaders(
        {});

        request(helper.getEndpointAndAuth())
            .put(helper.getEndpointStatements() + '?statementId=' + data.id)
            .headers(headers)
            .json(data)
            .expect(204, done);
    });

});

}(module, require('fs'), require('extend'), require('moment'), require('super-request'), require('supertest-as-promised'), require('chai'), require('url'), require('joi'), require('./../helper'), require('./../multipartParser'), require('./../redirect.js')));
<commit_msg>disable auth tests when using oauth<commit_after>/**
 * Description : This is a test suite that tests an LRS endpoint based on the testing requirements document
 * found at https://github.com/adlnet/xapi-lrs-conformance-requirements
 */

(function(module, fs, extend, moment, request, requestPromise, chai, liburl, Joi, helper, multipartParser, redirect)
{

	describe('Authentication Requirements (Communication 4.0)', function()
	{

		if (!global.OAUTH)
		{
			/**  XAPI-00334, Communication 2.1.3 GET Statements
			 * An LRS rejects a Statement of bad authorization (either authentication needed or failed credentials) with error code 401 Unauthorized
			 */
			describe('An LRS rejects a Statement of bad authorization (either authentication needed or failed credentials) with error code 401 Unauthorized (Authentication 4.0 XAPI-00334)', function()
			{

				it("fails when given a random name pass pair", function(done)
				{
					var templates = [
					{
						statement: '{{statements.default}}'
					}];
					var data = helper.createFromTemplate(templates);
					data = data.statement;
					data.id = helper.generateUUID();
					var headers = helper.addAllHeaders(
					{});

					//warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
					//with oauth already. We get a new verions by appending some other characters to defeat the cache.
					if (global.OAUTH)
						request = require('.\\super-request');
					else
						headers["Authorization"] = 'Basic ' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64');
					request(helper.getEndpointAndAuth())
						.put(helper.getEndpointStatements() + '?statementId=' + data.id)
						.headers(headers)
						.json(data)
						.expect(401, done);
				});

				it('fails with a malformed header', function(done)
				{
					var templates = [
					{
						statement: '{{statements.default}}'
					}];
					var data = helper.createFromTemplate(templates);
					data = data.statement;
					data.id = helper.generateUUID();
					var headers = helper.addAllHeaders(
					{});

					//warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
					//with oauth already. We get a new verions by appending some other characters to defeat the cache.
					if (global.OAUTH)
						request = require('.\\super-request');
					else
						headers["Authorization"] = 'Basic:' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64'); //note bad encoding here.
					request(helper.getEndpointAndAuth())
						.put(helper.getEndpointStatements() + '?statementId=' + data.id)
						.headers(headers)
						.json(data)
						.expect(401, done);
				});
			});

			/**  XAPI-00335, Communication 2.1.3 GET Statements
			 * An LRS must support HTTP Basic Authentication
			 */
			//WARNING: This might not be a great test. OAUTH will override it
			it('An LRS must support HTTP Basic Authentication(Authentication 4.0 XAPI-00335)', function(done)
			{
				var templates = [
				{
					statement: '{{statements.default}}'
				}];
				var data = helper.createFromTemplate(templates);
				data = data.statement;
				data.id = helper.generateUUID();
				var headers = helper.addAllHeaders(
				{});

				request(helper.getEndpointAndAuth())
					.put(helper.getEndpointStatements() + '?statementId=' + data.id)
					.headers(headers)
					.json(data)
					.expect(204, done);
			});

		}
	});

}(module, require('fs'), require('extend'), require('moment'), require('super-request'), require('supertest-as-promised'), require('chai'), require('url'), require('joi'), require('./../helper'), require('./../multipartParser'), require('./../redirect.js')));<|endoftext|>


<commit_before>"use strict";
let vscode = require('vscode');
let linters = require('./lint/lint');
let cp = require('child_process');
let which = require('which');

const severities = {
	refactor: vscode.DiagnosticSeverity.Hint,
	convention: vscode.DiagnosticSeverity.Information,
	info: vscode.DiagnosticSeverity.Information,
	warning: vscode.DiagnosticSeverity.Warning,
	error: vscode.DiagnosticSeverity.Error,
	fatal: vscode.DiagnosticSeverity.Error
};
let timer;

function deferReport(uri, lint, diagnostic) {
	if (lint.error) {
		console.log("Linter error:", lint.source, lint.error);
		return;
	}
	if ((!lint.result || !lint.result.length) && (!lint.lintError || !lint.lintError.length)) return;
	let allOf = lint.result.concat(lint.lintError)
		.map(offense => {
			let tail = offense.location.column + offense.location.length;
			let d = new vscode.Diagnostic(new vscode.Range(
					offense.location.line - 1, offense.location.column - 1,
					offense.location.line - 1, tail - 1),
				offense.message, severities[offense.severity] || vscode.DiagnosticSeverity.Error);
			d.source = offense.cop_name || lint.linter;
			return d;
		});
	diagnostic.set(uri, allOf);
}

const langConfig = {
	comments: {
		lineComment: "#",
		blockComment: ["=begin", "=end"]
	},
	brackets: [
		["{", "}"],
		["[", "]"],
		["(", ")"]
	],
	indentationRules: {
		increaseIndentPattern: /^\s*((begin|class|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while)|(.*\sdo\b))\b[^\{;]*$/
	},
	wordPattern: /(-?\d+(?:\.\d+))|(:?[A-Za-z][^-`~@#%^&()=+[{}|;:'",<>/.*\]\s\\!?]*[!?]?)/
};

let pairedEnds = [];

const highligher = {
	provideDocumentHighlights: (doc, pos) => {
		let result = pairedEnds.find(pair => (
			pair.entry.start.line === pos.line ||
			pair.end.start.line === pos.line));
		if (result) {
			return [new vscode.DocumentHighlight(result.entry, 2), new vscode.DocumentHighlight(result.end, 2)];
		}
	}
};

function getEnd(line) {
	//end must be on a line by itself, or followed directly by a dot
	let match = line.text.match(/^(\s*)end\b[\.\s#]?\s*$/);
	if (match) {
		return new vscode.Range(line.lineNumber, match[1].length, line.lineNumber, match[1].length + 3);
	}
}

function getEntry(line) {
	//only lines that start with the entry
	let match = line.text.match(/^(\s*)(begin|class|def|for|if|module|unless|until|case|while)\b[^\{;]*$/);
	if (match) {
		return new vscode.Range(line.lineNumber, match[1].length, line.lineNumber, match[1].length + match[2].length);
	} else {
		//check for do
		match = line.text.match(/\b(do)\b\s*(\|.*\|[^;]*)?$/);
		if (match) {
			return new vscode.Range(line.lineNumber, match.index, line.lineNumber, match.index + 2);
		}
	}
}

function balancePairs(doc) {
	pairedEnds = [];
	if (doc.languageId !== 'ruby') return;

	let waitingEntries = [];
	let entry, end;
	for (let i = 0; i < doc.lineCount; i++) {
		if ((entry = getEntry(doc.lineAt(i)))) {
			waitingEntries.push(entry);
		} else if (waitingEntries.length && (end = getEnd(doc.lineAt(i)))) {
			pairedEnds.push({
				entry: waitingEntries.pop(),
				end: end
			});
		}
	}
}

function balanceEvent(event) {
	pairedEnds = [];
	if (event && event.document) balancePairs(event.document);
}

var completeCmd;

function completionProvider(document, position, token) {
	return new Promise((resolve, reject) => {
		const line = position.line + 1;
		const column = position.character;

		var child = cp.spawn(completeCmd, [
			'--completion-class-info',
			'--dev',
			'--fork',
			'--line='+line,
			'--column='+column], { detached: false });
		child.stderr.on('data', (data) => {
			console.log("stderr:", data.toString());
			reject(data);
		});
		child.stdout.on('data', (data) => {
			var completionItems = [];
			data.toString().split('\n').forEach(function(elem) {
				var items = elem.split('\t');
				if (/^[^\w]/.test(items[0])) return;
				var completionItem = new vscode.CompletionItem(items[0]);
				completionItem.detail = items[1];
				completionItem.documentation = items[1];
				completionItem.filterText = items[0];
				completionItem.insertText = items[0];
				completionItem.label = items[0];
				completionItem.kind = vscode.CompletionItemKind.Method;
				completionItems.push(completionItem);
			}, this);
			if (completionItems.length == 0)
				return reject([]);
			return resolve(completionItems);
		});
		child.stdin.write(document.getText());
		child.stdin.end();
	});
}

function activate(context) {
	//add language config
	vscode.languages.setLanguageConfiguration('ruby', langConfig);

	let activeLinters = {};
	let linterTimers = {};
	let activeDiagnostics = {};

	function changeTrigger(changed) {
		timer = process.hrtime();
		if (!changed || !changed.document) return;
		if (changed.document.languageId !== 'ruby') return;

		const doc = changed.document;
		let lintConfig = vscode.workspace.getConfiguration("ruby.lint");

		if (lintConfig) {
			clearTimeout(linterTimers[doc.fileName]);

			if (activeLinters[doc.fileName]) {
				try {
					activeLinters[doc.fileName].send('stop');
				} catch (e) {}
				delete activeLinters[doc.fileName];
			}
			linterTimers[doc.fileName] = setTimeout(() => {
				activeLinters[doc.fileName] = linters.runCollection(lintConfig, doc.fileName, doc.getText(), result => {
					if (!activeDiagnostics[result.linter]) {
						activeDiagnostics[result.linter] = vscode.languages.createDiagnosticCollection(result.linter);
						context.subscriptions.push(activeDiagnostics[result.linter]);
					}
					activeDiagnostics[result.linter].delete(doc.uri);
					deferReport(doc.uri, result, activeDiagnostics[result.linter]);
				});
			}, 200);
		}
	}
	context.subscriptions.push(vscode.languages.registerDocumentHighlightProvider('ruby', highligher));

	context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(changeTrigger));
	context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(changeTrigger));
	context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(
		() => vscode.window.visibleTextEditors.forEach(changeTrigger)));

	vscode.window.visibleTextEditors.forEach(changeTrigger);

	context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(balanceEvent));
	context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(balanceEvent));
	context.subscriptions.push(vscode.workspace.onDidOpenTextDocument(balancePairs));
	if (vscode.window && vscode.window.activeTextEditor) {
		balancePairs(vscode.window.activeTextEditor.document);
	}

	which("rct-complete", function(err, found) {
		if (!err && found) {
			completeCmd = found;
			vscode.languages.registerCompletionItemProvider('ruby', {
				provideCompletionItems: completionProvider
			});
		}
	});
}

exports.activate = activate;
<commit_msg>Collect stdout/stderr<commit_after>"use strict";
let vscode = require('vscode');
let linters = require('./lint/lint');
let cp = require('child_process');
let which = require('which');

const severities = {
	refactor: vscode.DiagnosticSeverity.Hint,
	convention: vscode.DiagnosticSeverity.Information,
	info: vscode.DiagnosticSeverity.Information,
	warning: vscode.DiagnosticSeverity.Warning,
	error: vscode.DiagnosticSeverity.Error,
	fatal: vscode.DiagnosticSeverity.Error
};
let timer;

function deferReport(uri, lint, diagnostic) {
	if (lint.error) {
		console.log("Linter error:", lint.source, lint.error);
		return;
	}
	if ((!lint.result || !lint.result.length) && (!lint.lintError || !lint.lintError.length)) return;
	let allOf = lint.result.concat(lint.lintError)
		.map(offense => {
			let tail = offense.location.column + offense.location.length;
			let d = new vscode.Diagnostic(new vscode.Range(
					offense.location.line - 1, offense.location.column - 1,
					offense.location.line - 1, tail - 1),
				offense.message, severities[offense.severity] || vscode.DiagnosticSeverity.Error);
			d.source = offense.cop_name || lint.linter;
			return d;
		});
	diagnostic.set(uri, allOf);
}

const langConfig = {
	comments: {
		lineComment: "#",
		blockComment: ["=begin", "=end"]
	},
	brackets: [
		["{", "}"],
		["[", "]"],
		["(", ")"]
	],
	indentationRules: {
		increaseIndentPattern: /^\s*((begin|class|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while)|(.*\sdo\b))\b[^\{;]*$/
	},
	wordPattern: /(-?\d+(?:\.\d+))|(:?[A-Za-z][^-`~@#%^&()=+[{}|;:'",<>/.*\]\s\\!?]*[!?]?)/
};

let pairedEnds = [];

const highligher = {
	provideDocumentHighlights: (doc, pos) => {
		let result = pairedEnds.find(pair => (
			pair.entry.start.line === pos.line ||
			pair.end.start.line === pos.line));
		if (result) {
			return [new vscode.DocumentHighlight(result.entry, 2), new vscode.DocumentHighlight(result.end, 2)];
		}
	}
};

function getEnd(line) {
	//end must be on a line by itself, or followed directly by a dot
	let match = line.text.match(/^(\s*)end\b[\.\s#]?\s*$/);
	if (match) {
		return new vscode.Range(line.lineNumber, match[1].length, line.lineNumber, match[1].length + 3);
	}
}

function getEntry(line) {
	//only lines that start with the entry
	let match = line.text.match(/^(\s*)(begin|class|def|for|if|module|unless|until|case|while)\b[^\{;]*$/);
	if (match) {
		return new vscode.Range(line.lineNumber, match[1].length, line.lineNumber, match[1].length + match[2].length);
	} else {
		//check for do
		match = line.text.match(/\b(do)\b\s*(\|.*\|[^;]*)?$/);
		if (match) {
			return new vscode.Range(line.lineNumber, match.index, line.lineNumber, match.index + 2);
		}
	}
}

function balancePairs(doc) {
	pairedEnds = [];
	if (doc.languageId !== 'ruby') return;

	let waitingEntries = [];
	let entry, end;
	for (let i = 0; i < doc.lineCount; i++) {
		if ((entry = getEntry(doc.lineAt(i)))) {
			waitingEntries.push(entry);
		} else if (waitingEntries.length && (end = getEnd(doc.lineAt(i)))) {
			pairedEnds.push({
				entry: waitingEntries.pop(),
				end: end
			});
		}
	}
}

function balanceEvent(event) {
	pairedEnds = [];
	if (event && event.document) balancePairs(event.document);
}

var completeCmd;

function completionProvider(document, position, token) {
	return new Promise((resolve, reject) => {
		const line = position.line + 1;
		const column = position.character;

		var child = cp.spawn(completeCmd, [
			'--completion-class-info',
			'--dev',
			'--fork',
			'--line='+line,
			'--column='+column]);

		var outbuf = [], errbuf = [];
		child.stderr.on('data', (data) => errbuf.push(data.toString()));
		child.stdout.on('data', (data) => outbuf.push(data.toString()));
		child.stdout.on('end', () => {
			if (errbuf.length > 0) reject(errbuf.join(''));

			var completionItems = [];
			outbuf.join('').split('\n').forEach(function(elem) {
				var items = elem.split('\t');
				if (/^[^\w]/.test(items[0])) return;
				var completionItem = new vscode.CompletionItem(items[0]);
				completionItem.detail = items[1];
				completionItem.documentation = items[1];
				completionItem.filterText = items[0];
				completionItem.insertText = items[0];
				completionItem.label = items[0];
				completionItem.kind = vscode.CompletionItemKind.Method;
				completionItems.push(completionItem);
			}, this);
			if (completionItems.length == 0)
				return reject([]);
			return resolve(completionItems);
		});
		child.stdin.end(document.getText());
	});
}

function activate(context) {
	//add language config
	vscode.languages.setLanguageConfiguration('ruby', langConfig);

	let activeLinters = {};
	let linterTimers = {};
	let activeDiagnostics = {};

	function changeTrigger(changed) {
		timer = process.hrtime();
		if (!changed || !changed.document) return;
		if (changed.document.languageId !== 'ruby') return;

		const doc = changed.document;
		let lintConfig = vscode.workspace.getConfiguration("ruby.lint");

		if (lintConfig) {
			clearTimeout(linterTimers[doc.fileName]);

			if (activeLinters[doc.fileName]) {
				try {
					activeLinters[doc.fileName].send('stop');
				} catch (e) {}
				delete activeLinters[doc.fileName];
			}
			linterTimers[doc.fileName] = setTimeout(() => {
				activeLinters[doc.fileName] = linters.runCollection(lintConfig, doc.fileName, doc.getText(), result => {
					if (!activeDiagnostics[result.linter]) {
						activeDiagnostics[result.linter] = vscode.languages.createDiagnosticCollection(result.linter);
						context.subscriptions.push(activeDiagnostics[result.linter]);
					}
					activeDiagnostics[result.linter].delete(doc.uri);
					deferReport(doc.uri, result, activeDiagnostics[result.linter]);
				});
			}, 200);
		}
	}
	context.subscriptions.push(vscode.languages.registerDocumentHighlightProvider('ruby', highligher));

	context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(changeTrigger));
	context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(changeTrigger));
	context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(
		() => vscode.window.visibleTextEditors.forEach(changeTrigger)));

	vscode.window.visibleTextEditors.forEach(changeTrigger);

	context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(balanceEvent));
	context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(balanceEvent));
	context.subscriptions.push(vscode.workspace.onDidOpenTextDocument(balancePairs));
	if (vscode.window && vscode.window.activeTextEditor) {
		balancePairs(vscode.window.activeTextEditor.document);
	}

	which("rct-complete", function(err, found) {
		if (!err && found) {
			completeCmd = found;
			vscode.languages.registerCompletionItemProvider('ruby', {
				provideCompletionItems: completionProvider
			});
		}
	});
}

exports.activate = activate;
<|endoftext|>