<commit_before>var nodemailer = require('nodemailer')
  , videojs = require(__dirname + '/video');

var transport = nodemailer.createTransport("SMTP", {
            service: "Gmail",
            auth: {
                user: "donateoldspectacles@gmail.com",
                pass: "biplav3403"
            }
        });

var guid = (function() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
               .toString(16)
               .substring(1);
  }
  return function() {
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
           s4() + '-' + s4() + s4() + s4();
  };
})();

function replaceAll(find, replace, str) {
  return str.replace(new RegExp(find, 'g'), replace);
}

function validFormat(n) {
  return (n < 10) ? "0"+n : ""+n;
}

function getTZFormat(d) {
  return d.getUTCFullYear()+
         validFormat(1+d.getUTCMonth())+
         validFormat(d.getUTCDate())+
         "T"+
         validFormat(d.getUTCHours())+
         validFormat(d.getUTCMinutes())+
         validFormat(d.getUTCSeconds())+
         "Z"
}

function createIcal(params,uid) {
  start = new Date(params.start);
  end = new Date(params.end);
  ts = new Date();
  start = getTZFormat(start);
  end = getTZFormat(end);
  ts = getTZFormat(ts);
  uid = replaceAll('-','',guid());
  main_email = params.email;
  part_email = params.main_email;
  org_name = "BakBak Scheduler";
  org_email = "donateoldspectacles@gmail.com";
  subject = params.subject;
  agenda = params.agenda;
  url = 'http://www.bakbak.io/meeting/parts?users='+main_email+','+part_email;
  escaped_url = ' <'+url+'>';
  return 'BEGIN:VCALENDAR\r\n'
          +'PRODID:-//Bakbak//BakBak Scheduler Calendar 1.0//EN\r\n'
          +'VERSION:2.0\r\n'
          +'CALSCALE:GREGORIAN\r\n'
          +'METHOD:REQUEST\r\n'
          +'BEGIN:VEVENT\r\n'
          +'DTSTAMP:'+ts+'\r\n'
          +'DTSTART:'+start+'\r\n'
          +'DTEND:'+end+'\r\n'
          +'SUMMARY:'+subject+escaped_url+'\r\n'
          +'UID:'+ uid +'\r\n'
          +'DESCRIPTION:'+ agenda +' \r\n'
          +'LOCATION: Web Location'+escaped_url+'\r\n'
          +'ORGANIZER;CN='+org_name+':mailto:'+org_email+'\r\n'
          +'ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN='+part_email+';X-NUM-GUESTS=0:mailto:'+part_email+'\r\n'
          +'ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN='+main_email+';X-NUM-GUESTS=0:mailto:'+main_email+'\r\n'
          +'SEQUENCE:0\r\n'
          +'LAST-MODIFIED:'+ts+'\r\n'
          +'CREATED:'+ts+'\r\n'
          +'TRANSP:OPAQUE\r\n'
          +'STATUS:CONFIRMED\r\n'
          +'END:VEVENT\r\n'
          +'END:VCALENDAR\r\n';
}

function createText(params,uid) {
  start = new Date(params.start);
  end = new Date(params.end);
  ts = new Date();
  main_email = params.email;
  part_email = params.main_email;
  org_name = "BakBak Scheduler";
  org_email = "donateoldspectacles@gmail.com";
  subject = params.subject;
  agenda = params.agenda;
  url = 'http://www.bakbak.io/meeting/parts?users='+main_email+','+part_email;
  escaped_url = ' <'+url+'>';
  return 'Start Time: '+start+'\r\n'
          +'End Time: '+end+'\r\n'
          +'Subject: '+subject+escaped_url+'\r\n'
          +'Agenda: '+ agenda +' \r\n'
          +'Location: Web Location'+escaped_url+'\r\n'
          +'Participants: '+part_email+','+main_email+'\r\n'
}

exports.create = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  params = req.body;
  uid = replaceAll('-','',guid());
  console.log(params)
  var ical = createIcal(params,uid);
  var text = createText(params,uid);
  console.log(ical);
  transport.sendMail({
                    from: 'BakBak Scheduler<donateoldspectacles@gmail.com>',
                    to: params.email+","+params.main_email,
                    subject: params.subject,
                    text: text,
                    alternatives: [{
                      contentType: "text/calendar",
                      contents: new Buffer(ical),
                      contentEncoding: "7bit"

                    }]
                    }, function(err, responseStatus) {
                    if (err) {
                        console.log(err);
                        res.render('schedule',{errors: err.message});
                    } else {
                        console.log(responseStatus.message);
                        res.render('schedule',{success_msg: "Successfully Created!"});
                    }
                });
}

exports.index = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  var withEmail='biplav.saraf@gmail.com';
  if(req.query.withEmail) {
    withEmail=req.query.withEmail;
  }
  res.render('schedule',{withEmail:withEmail});
}

exports.meeting = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  console.log(req.body);
  var local;
  var remote;
  if(req.body) {
    local = req.body.local;
    remote = req.body.remote;
  } else {
    local = req.query.local;
    remote = req.query.remote;
  }

  var token = videojs.getToken(local);
  res.render('meeting',{local:local,remote:remote,token:token});
}

exports.meetingSelect = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  var users = req.query.users;
  users = users.split(',');
  res.render('meetingSelect',{user1: users[0],user2:users[1]});
}<commit_msg>with email o form redirection<commit_after>var nodemailer = require('nodemailer')
  , videojs = require(__dirname + '/video');

var transport = nodemailer.createTransport("SMTP", {
            service: "Gmail",
            auth: {
                user: "donateoldspectacles@gmail.com",
                pass: "biplav3403"
            }
        });

var guid = (function() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
               .toString(16)
               .substring(1);
  }
  return function() {
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
           s4() + '-' + s4() + s4() + s4();
  };
})();

function replaceAll(find, replace, str) {
  return str.replace(new RegExp(find, 'g'), replace);
}

function validFormat(n) {
  return (n < 10) ? "0"+n : ""+n;
}

function getTZFormat(d) {
  return d.getUTCFullYear()+
         validFormat(1+d.getUTCMonth())+
         validFormat(d.getUTCDate())+
         "T"+
         validFormat(d.getUTCHours())+
         validFormat(d.getUTCMinutes())+
         validFormat(d.getUTCSeconds())+
         "Z"
}

function createIcal(params,uid) {
  start = new Date(params.start);
  end = new Date(params.end);
  ts = new Date();
  start = getTZFormat(start);
  end = getTZFormat(end);
  ts = getTZFormat(ts);
  uid = replaceAll('-','',guid());
  main_email = params.email;
  part_email = params.main_email;
  org_name = "BakBak Scheduler";
  org_email = "donateoldspectacles@gmail.com";
  subject = params.subject;
  agenda = params.agenda;
  url = 'http://www.bakbak.io/meeting/parts?users='+main_email+','+part_email;
  escaped_url = ' <'+url+'>';
  return 'BEGIN:VCALENDAR\r\n'
          +'PRODID:-//Bakbak//BakBak Scheduler Calendar 1.0//EN\r\n'
          +'VERSION:2.0\r\n'
          +'CALSCALE:GREGORIAN\r\n'
          +'METHOD:REQUEST\r\n'
          +'BEGIN:VEVENT\r\n'
          +'DTSTAMP:'+ts+'\r\n'
          +'DTSTART:'+start+'\r\n'
          +'DTEND:'+end+'\r\n'
          +'SUMMARY:'+subject+escaped_url+'\r\n'
          +'UID:'+ uid +'\r\n'
          +'DESCRIPTION:'+ agenda +' \r\n'
          +'LOCATION: Web Location'+escaped_url+'\r\n'
          +'ORGANIZER;CN='+org_name+':mailto:'+org_email+'\r\n'
          +'ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN='+part_email+';X-NUM-GUESTS=0:mailto:'+part_email+'\r\n'
          +'ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN='+main_email+';X-NUM-GUESTS=0:mailto:'+main_email+'\r\n'
          +'SEQUENCE:0\r\n'
          +'LAST-MODIFIED:'+ts+'\r\n'
          +'CREATED:'+ts+'\r\n'
          +'TRANSP:OPAQUE\r\n'
          +'STATUS:CONFIRMED\r\n'
          +'END:VEVENT\r\n'
          +'END:VCALENDAR\r\n';
}

function createText(params,uid) {
  start = new Date(params.start);
  end = new Date(params.end);
  ts = new Date();
  main_email = params.email;
  part_email = params.main_email;
  org_name = "BakBak Scheduler";
  org_email = "donateoldspectacles@gmail.com";
  subject = params.subject;
  agenda = params.agenda;
  url = 'http://www.bakbak.io/meeting/parts?users='+main_email+','+part_email;
  escaped_url = ' <'+url+'>';
  return 'Start Time: '+start+'\r\n'
          +'End Time: '+end+'\r\n'
          +'Subject: '+subject+escaped_url+'\r\n'
          +'Agenda: '+ agenda +' \r\n'
          +'Location: Web Location'+escaped_url+'\r\n'
          +'Participants: '+part_email+','+main_email+'\r\n'
}

exports.create = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  params = req.body;
  uid = replaceAll('-','',guid());
  console.log(params)
  var ical = createIcal(params,uid);
  var text = createText(params,uid);
  console.log(ical);
  transport.sendMail({
                    from: 'BakBak Scheduler<donateoldspectacles@gmail.com>',
                    to: params.email+","+params.main_email,
                    subject: params.subject,
                    text: text,
                    alternatives: [{
                      contentType: "text/calendar",
                      contents: new Buffer(ical),
                      contentEncoding: "7bit"

                    }]
                    }, function(err, responseStatus) {
                    if (err) {
                        console.log(err);
                        res.render('schedule',{errors: err.message});
                    } else {
                        console.log(responseStatus.message);
                        res.render('schedule',{success_msg: "Successfully Created!", withEmail:params.main_email});
                    }
                });
}

exports.index = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  var withEmail='biplav.saraf@gmail.com';
  if(req.query.withEmail) {
    withEmail=req.query.withEmail;
  }
  res.render('schedule',{withEmail:withEmail});
}

exports.meeting = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  console.log(req.body);
  var local;
  var remote;
  if(req.body) {
    local = req.body.local;
    remote = req.body.remote;
  } else {
    local = req.query.local;
    remote = req.query.remote;
  }

  var token = videojs.getToken(local);
  res.render('meeting',{local:local,remote:remote,token:token});
}

exports.meetingSelect = function(req,res) {
  res.header("Access-Control-Allow-Origin", "*");
  var users = req.query.users;
  users = users.split(',');
  res.render('meetingSelect',{user1: users[0],user2:users[1]});
}<|endoftext|>


<commit_before>// mocha/suites/browser
suite('browser');

var host = document.location.protocol + '//' + document.location.host;

test('global', function () {
  global.should.be.equal(window);
  global.__filename.should.be.equal(__filename);
  global.__dirname.should.be.equal(__dirname);
});

test('__filename', function () {
  __filename.should.be.equal(host + '/lib/browser/monad.js');
});

test('normalize', function () {
  // normalize(host + '/lib/browser/monad.js').should.be.equal(__filename);
  // normalize(BASEPATH + '../../lib/browser/monad.js').should.be.equal(__filename);
});

test('__dirname', function () {
  __dirname.should.be.equal(host + '/lib/browser');
});

test('BASEPATH is document.location.href', function () {
  var pathname = document.location.pathname;
  BASEPATH.should.be.equal(host + pathname.substring(0, pathname.lastIndexOf('/') + 1));
});

test('require', function () {
  require(__filename).should.be.Function;
});

test('module', function () {
  var name = normalize(__filename);
  delete require._cache[name];

  Module._load(__filename, { id: __filename });

  require._cache[name].id.should.be.equal(name);
  require._cache[name].filename.should.be.equal(name);
  require._cache[name].exports.should.be.equal(require(name));
  require._cache[name].children.should.be.Array;
  require._cache[name].parent.should.be.Object;
  require._cache[name].require.should.be.Function;

});

test('define __filename', function () {
  (define)(__filename).should.be.Function;
  (define)(__filename).id.should.be.equal(__filename);
});

test('define pathnames', function () {
  (define)(__filename)('assert').should.be.Function;

});

test('define callback', function () {
  (define)(__filename)('assert')(function () {
    assert(module.id == 'should fail' /*global.__filename*/);
  }).should.be.Object;
});

<commit_msg>browser:normalize test re-activated<commit_after>// mocha/suites/browser
suite('browser');

var host = document.location.protocol + '//' + document.location.host;

test('global', function () {
  global.should.be.equal(window);
  global.__filename.should.be.equal(__filename);
  global.__dirname.should.be.equal(__dirname);
});

test('__filename', function () {
  __filename.should.be.equal(host + '/lib/browser/monad.js');
});

test('normalize', function () {
  normalize(host + '/lib/browser/monad.js').should.be.equal(__filename);
  normalize(BASEPATH + '../../lib/browser/monad.js').should.be.equal(__filename);
});

test('__dirname', function () {
  __dirname.should.be.equal(host + '/lib/browser');
});

test('BASEPATH is document.location.href', function () {
  var pathname = document.location.pathname;
  BASEPATH.should.be.equal(host + pathname.substring(0, pathname.lastIndexOf('/') + 1));
});

test('require', function () {
  require(__filename).should.be.Function;
});

test('module', function () {
  var name = normalize(__filename);
  delete require._cache[name];

  Module._load(__filename, { id: __filename });

  require._cache[name].id.should.be.equal(name);
  require._cache[name].filename.should.be.equal(name);
  require._cache[name].exports.should.be.equal(require(name));
  require._cache[name].children.should.be.Array;
  require._cache[name].parent.should.be.Object;
  require._cache[name].require.should.be.Function;

});

test('define __filename', function () {
  (define)(__filename).should.be.Function;
  (define)(__filename).id.should.be.equal(__filename);
});

test('define pathnames', function () {
  (define)(__filename)('assert').should.be.Function;

});

test('define callback', function () {
  (define)(__filename)('assert')(function () {
    assert(module.id == 'should fail' /*global.__filename*/);
  }).should.be.Object;
});

<|endoftext|>


<commit_before>/**
 * Author: Vova Zaytsev <zaytsev@usc.edu>
 */

app.controller("NlcdClientController", ["$scope", "$location", "$sce", "NcldApiFactory",
    function ($scope, $location, $sce, NcldApiFactory) {
        /**
        **/

        $scope.central              = null;
        $scope.related              = [];
        $scope.meta                 = null;
        $scope.selection            = [];
        $scope.textSelection        = null;
        $scope.display = {

            // Tab 'ALL'
            relatedTabAllReversed:        false,
            relatedTabAllPredicate:       "inSelection",

            // Tab 'SELECTION'
            relatedTabSelectionReversed:  false,
            relatedTabSelectionPredicate: "pubDate",

            // Tab 'SOURCES'
            relatedTabSourcesReversed:    false,
            relatedTabSourcesPredicate:   "referenceCount",

            // Tab 'AUTHORS'
            relatedTabAuthorsReversed:    false,
            relatedTabAuthorsPredicate:   "referenceCount"

        };

        // Init bootstrap javascript
        $("#relatedTabs a").click(function (e) {
            e.preventDefault();
            $(this).tab("show");
        });
        $("#relatedTabs a:first").tab("show");

        NcldApiFactory.getTestGraph().success(function(data){
            $scope.sg = new StoryGraph(data.data);
            $scope.central = $scope.sg.getCentralNode();
            $scope.related = $scope.sg.getNodes();
            $scope.meta = data.data.meta;

            var distrPlaceId = "storyDistribution";
            var nwPlaceId = "storyNetwork";

            var distrWidth = document.getElementById(distrPlaceId).offsetWidth;
            var nwWidth = document.getElementById(nwPlaceId).offsetWidth;

            console.log(nwWidth);

            var height = 300;

            $scope.sg.drawDistribution(distrPlaceId, distrWidth, height);
            $scope.sg.drawNetwork(nwPlaceId, nwWidth, height);
        });

        //
        $scope.RelatedAllTabOrderBy = function(predicate) {
            if ($scope.display.relatedTabAllPredicate == predicate) {
                $scope.display.relatedTabAllReversed = !$scope.display.relatedTabAllReversed;
            }
            $scope.display.relatedTabAllPredicate = predicate;
        }

        //
        $scope.RelatedSelectionTabOrderBy = function(predicate) {
            if ($scope.display.relatedTabSelectionPredicate == predicate) {
                $scope.display.relatedTabSelectionReversed = !$scope.display.relatedTabSelectionReversed;
            }
            $scope.display.relatedTabSelectionPredicate = predicate;
        }

        //
        $scope.SetSelection = function(referencesList) {
            for (var i in $scope.selection) {
                $scope.selection[i].inSelection = null;
            };
            $scope.selection = [];
            for (var i in referencesList) {
                var refId = referencesList[i];
                var item = $scope.sg.getNode(refId);
                item.inSelection = true;
                $scope.selection.push(item);
            };
            $scope.sg.gfx.SetDistributionSelection(referencesList);
            $scope.sg.gfx.SetNetworkSelection(referencesList);
        };

        //
        $scope.TextSelection = function(chunk, referencesList) {
            if ($scope.textSelection) {
                $scope.textSelection.isSelected = false;
                if ($scope.textSelection.tagId == chunk.tagId) {
                    $scope.textSelection = null;
                    $scope.SetSelection([]);
                    return;
                }
            }
            $scope.textSelection = chunk;
            $scope.textSelection.isSelected = true;
            $scope.SetSelection(referencesList);
        };

}]);<commit_msg>update webapp<commit_after>/**
 * Author: Vova Zaytsev <zaytsev@usc.edu>
 */

app.controller("NlcdClientController", ["$scope", "$location", "$sce", "NcldApiFactory",
    function ($scope, $location, $sce, NcldApiFactory) {
        /**
        **/

        $scope.central              = null;
        $scope.related              = [];
        $scope.meta                 = null;
        $scope.selection            = [];
        $scope.textSelection        = null;
        $scope.display = {

            // Tab 'ALL'
            relatedTabAllReversed:        false,
            relatedTabAllPredicate:       "inSelection",

            // Tab 'SELECTION'
            relatedTabSelectionReversed:  false,
            relatedTabSelectionPredicate: "pubDate",

            // Tab 'SOURCES'
            relatedTabSourcesReversed:    false,
            relatedTabSourcesPredicate:   "referenceCount",

            // Tab 'AUTHORS'
            relatedTabAuthorsReversed:    false,
            relatedTabAuthorsPredicate:   "referenceCount"

        };

        // Init bootstrap javascript
        $("#relatedTabs a").click(function (e) {
            e.preventDefault();
            $(this).tab("show");
        });
        $("#relatedTabs a:first").tab("show");

        NcldApiFactory.getTestGraph().success(function(data){

            console.log(data);

            $scope.sg = new StoryGraph(data.data);
            $scope.central = $scope.sg.getCentralNode();
            $scope.related = $scope.sg.getNodes();
            $scope.meta = data.data.meta;

            var distrPlaceId = "storyDistribution";
            var nwPlaceId = "storyNetwork";

            var distrWidth = document.getElementById(distrPlaceId).offsetWidth;
            var nwWidth = document.getElementById(nwPlaceId).offsetWidth;

            console.log(nwWidth);

            var height = 300;

            $scope.sg.drawDistribution(distrPlaceId, distrWidth, height);
            $scope.sg.drawNetwork(nwPlaceId, nwWidth, height);
        });

        //
        $scope.RelatedAllTabOrderBy = function(predicate) {
            if ($scope.display.relatedTabAllPredicate == predicate) {
                $scope.display.relatedTabAllReversed = !$scope.display.relatedTabAllReversed;
            }
            $scope.display.relatedTabAllPredicate = predicate;
        }

        //
        $scope.RelatedSelectionTabOrderBy = function(predicate) {
            if ($scope.display.relatedTabSelectionPredicate == predicate) {
                $scope.display.relatedTabSelectionReversed = !$scope.display.relatedTabSelectionReversed;
            }
            $scope.display.relatedTabSelectionPredicate = predicate;
        }

        //
        $scope.SetSelection = function(referencesList) {
            for (var i in $scope.selection) {
                $scope.selection[i].inSelection = null;
            };
            $scope.selection = [];
            for (var i in referencesList) {
                var refId = referencesList[i];
                var item = $scope.sg.getNode(refId);
                item.inSelection = true;
                $scope.selection.push(item);
            };
            $scope.sg.gfx.SetDistributionSelection(referencesList);
            $scope.sg.gfx.SetNetworkSelection(referencesList);
        };

        //
        $scope.TextSelection = function(chunk, referencesList) {
            if ($scope.textSelection) {
                $scope.textSelection.isSelected = false;
                if ($scope.textSelection.tagId == chunk.tagId) {
                    $scope.textSelection = null;
                    $scope.SetSelection([]);
                    return;
                }
            }
            $scope.textSelection = chunk;
            $scope.textSelection.isSelected = true;
            $scope.SetSelection(referencesList);
        };

}]);<|endoftext|>


<commit_before>/**
 * Compiles templates in Pattern Lab to templates in backend.
 *
 * Converts Mustache tags into whatever type of tokens are used by the backend
 * webapp based on mappings in a YAML file named similarly to the Mustache
 * template.
 */
'use strict';

const conf = global.conf;
const pref = global.pref;
const workDir = global.workDir;

const fs = require('fs-extra');
const glob = require('glob');
const path = require('path');
const yaml = require('js-yaml');

const utils = require('../lib/utils');

exports.mustacheRecurse = function (file, patternDir) {
  var code;
  var code1 = '';

  try {
    // Read code which will receive token replacement.
    code = fs.readFileSync(file, conf.enc);
    // Split by Mustache tag for parsing.
    let codeSplit = code.split('{{');
    for (let i = 0; i < codeSplit.length; i++) {
      // Signal the OK to recurse by appending partial tags with the .mustache
      // extension. We do NOT want to recurse EVERY included partial because
      // then the outputted file will not contain any partials, which defeats
      // the purpose of recursing templates in the first place.
      if (/^>\s*[\w\-\.\/~]+\.mustache\s*\}\}/.test(codeSplit[i])) {
        let partial = codeSplit[i].split('}}');
        partial[0] = partial[0].replace(/^>\s*/, '').trim();
        let partialCode = exports.mustacheRecurse(patternDir + '/' + partial[0], patternDir);
        code1 += partialCode;
        for (let j = 0; j < partial.length; j++) {
          if (j > 0) {
            code1 += partial[j];
            if (j < partial.length - 1) {
              code1 += '}}';
            }
          }
        }
      }
      else {
        if (i > 0) {
          code1 += '{{' + codeSplit[i];
        }
        else {
          code1 += codeSplit[i];
        }
      }
    }

    return code1;
  }
  catch (err) {
    utils.error(err);
  }
};

exports.mustacheUnescape = function (escaped) {
  var unescaped = escaped.replace(/\{\s*/, '{\\s');
  unescaped = unescaped.replace(/\s*\}/, '\\s}');

  return unescaped;
};

exports.templateProcess = function (file, templatesDirDefault, templatesExtDefault) {
  var code;
  var data = null;
  var dest;
  var mustacheFile;
  var patternDir = utils.pathResolve(conf.ui.paths.source.patterns);
  var sourceDir = patternDir + '/03-templates';
  var sourceDir1 = sourceDir;
  var stats = null;
  var stats1 = null;
  var templatesDir = '';
  var templatesExt = '';
  var yml;
  var ymlFile = '';

  // Exclude files prefixed by __
  if (path.basename(file).slice(0, 2) === '__') {
    return;
  }

  if (path.extname(file) === '.yml') {
    mustacheFile = file.replace(/\.yml$/, '.mustache');
    ymlFile = file;
  }
  else if (path.extname(file) === '.mustache') {
    mustacheFile = file;
    ymlFile = file.replace(/\.mustache$/, '.yml');
  }

  try {
    stats = fs.statSync(mustacheFile);
  }
  catch (err) {
    // Only process templates that actually exist.
    return;
  }

  try {
    stats1 = fs.statSync(ymlFile);
  }
  catch (err) {
    // Fail gracefully.
  }

  // Return on stat fail. Exclude non-files.
  if (!stats || !stats.isFile()) {
    return;
  }

  // Try to read YAML file if it exists.
  if (stats1 && stats1.isFile()) {
    // Read YAML file and store keys/values in tokens object.
    try {
      yml = fs.readFileSync(ymlFile, conf.enc);
      data = yaml.safeLoad(yml);

      if (typeof data.templates_dir === 'string') {
        templatesDir = utils.backendDirCheck(data.templates_dir);
        // Do not maintain nested directory structure in backend if
        // templates_dir is set in exceptional YAML file.
        if (templatesDir) {
          sourceDir1 = path.dirname(mustacheFile);
        }
        // Unset templates_dir in local YAML data.
        delete data.templates_dir;
      }

      if (typeof data.templates_ext === 'string') {
        templatesExt = utils.extCheck(data.templates_ext);
        // Unset templates_dir in local YAML data.
        delete data.templates_ext;
      }
    }
    catch (err) {
      // Fail gracefully.
      data = null;
    }
  }

  if (templatesDirDefault && !templatesDir) {
    templatesDir = templatesDirDefault;
  }

  if (templatesExtDefault && !templatesExt) {
    templatesExt = templatesExtDefault;
  }

  if (templatesDir && templatesExt) {
    // Recurse through Mustache templates (sparingly. See comment above.)
    code = exports.mustacheRecurse(mustacheFile, patternDir);
    // Iterate through tokens and replace keys for values in the code.
    code = exports.tokensReplace(data, code);
    // Write compiled templates.
    dest = exports.templatesWrite(mustacheFile, sourceDir1, templatesDir, templatesExt, code);

    // Log to console.
    utils.log('Template \x1b[36m%s\x1b[0m synced.', dest.replace(workDir, '').replace(/^\//, ''));
  }
};

exports.templatesGlob = function (sourceDir) {
  var globbed = glob.sync(sourceDir + '/*.mustache');
  var globbed1 = glob.sync(sourceDir + '/!(_nosync)/**/*.mustache');

  return globbed.concat(globbed1);
};

exports.templatesWrite = function (file, sourceDir, templatesDir, templatesExt, code) {
  // Determine destination for token-replaced code.
  var dest = file.replace(sourceDir, '');

  // Replace underscore prefixes.
  dest = dest.replace(/\/_([^\/]+)$/, '/$1');
  dest = templatesDir + dest;
  dest = dest.replace(/mustache$/, templatesExt);

  // Write to file system.
  fs.mkdirpSync(path.dirname(dest));
  fs.writeFileSync(dest, code);

  return dest;
};

exports.tokensReplace = function (tokens, code) {
  var regex;
  var token;
  var unescaped;

  for (let i in tokens) {
    if (tokens.hasOwnProperty(i)) {
      unescaped = exports.mustacheUnescape(i);
      regex = new RegExp('\\{\\{\\{?\\s*' + unescaped + '\\s*\\}?\\}\\}', 'g');
      token = tokens[i].replace(/^\n/, '');
      token = token.replace(/\n$/, '');
      code = code.replace(regex, token);
    }
  }

  // Delete remaining Mustache tags if configured to do so.
  if (!pref.templater.retain_mustache) {
    code = code.replace(/\{\{[^\(]*?(\([\S\s]*?\))?\s*\}?\}\}\s*\n?/g, '');
  }
  // Replace escaped curly braces.
  code = code.replace(/\\\{/g, '{');
  code = code.replace(/\\\}/g, '}');

  return code;
};

exports.main = function () {
  var patternDir = utils.pathResolve(conf.ui.paths.source.patterns);
  var sourceDir = patternDir + '/03-templates';
  var files = exports.templatesGlob(sourceDir);
  var templatesDirDefault = utils.backendDirCheck(pref.backend.synced_dirs.templates_dir);
  var templatesExtDefault = utils.extCheck(pref.backend.synced_dirs.templates_ext);

  // Search source directory for Mustache files.
  // Excluding templates in _nosync directory and those prefixed by __.
  // Trying to keep the globbing simple and maintainable.
  for (let i = 0; i < files.length; i++) {
    exports.templateProcess(files[i], templatesDirDefault, templatesExtDefault);
  }
};
<commit_msg>working templater<commit_after>/**
 * Compiles templates in Pattern Lab to templates in backend.
 *
 * Converts Mustache tags into whatever type of tokens are used by the backend
 * webapp based on mappings in a YAML file named similarly to the Mustache
 * template.
 */
'use strict';

const conf = global.conf;
const pref = global.pref;
const workDir = global.workDir;

const fs = require('fs-extra');
const glob = require('glob');
const path = require('path');
const yaml = require('js-yaml');

const utils = require('../lib/utils');

const patternDir = path.normalize(utils.pathResolve(conf.ui.paths.source.patterns));
const sourceDir = patternDir + '/03-templates';

exports.mustacheRecurse = function (file) {
  var code;
  var code1 = '';

  try {
    // Read code which will receive token replacement.
    code = fs.readFileSync(file, conf.enc);
    // Split by Mustache tag for parsing.
    let codeSplit = code.split('{{');
    for (let i = 0; i < codeSplit.length; i++) {
      // Signal the OK to recurse by appending partial tags with the .mustache
      // extension. We do NOT want to recurse EVERY included partial because
      // then the outputted file will not contain any partials, which defeats
      // the purpose of recursing templates in the first place.
      if (/^>\s*[\w\-\.\/~]+\.mustache\s*\}\}/.test(codeSplit[i])) {
        let partial = codeSplit[i].split('}}');
        partial[0] = partial[0].replace(/^>\s*/, '').trim();
        let partialCode = exports.mustacheRecurse(patternDir + '/' + partial[0], patternDir);
        code1 += partialCode;
        for (let j = 0; j < partial.length; j++) {
          if (j > 0) {
            code1 += partial[j];
            if (j < partial.length - 1) {
              code1 += '}}';
            }
          }
        }
      }
      else {
        if (i > 0) {
          code1 += '{{' + codeSplit[i];
        }
        else {
          code1 += codeSplit[i];
        }
      }
    }

    return code1;
  }
  catch (err) {
    utils.error(err);
  }
};

exports.mustacheUnescape = function (escaped) {
  var unescaped = escaped.replace(/\{\s*/, '{\\s');
  unescaped = unescaped.replace(/\s*\}/, '\\s}');

  return unescaped;
};

exports.templateProcess = function (file, templatesDirDefault, templatesExtDefault) {
  var code;
  var data = null;
  var dest;
  var mustacheFile;
  var sourceDirParam = sourceDir;
  var stats = null;
  var stats1 = null;
  var templatesDir = '';
  var templatesExt = '';
  var yml;
  var ymlFile = '';

  // Exclude files prefixed by __
  if (path.basename(file).slice(0, 2) === '__') {
    return;
  }

  if (path.extname(file) === '.yml') {
    mustacheFile = file.replace(/\.yml$/, '.mustache');
    ymlFile = file;
  }
  else if (path.extname(file) === '.mustache') {
    mustacheFile = file;
    ymlFile = file.replace(/\.mustache$/, '.yml');
  }

  try {
    stats = fs.statSync(mustacheFile);
  }
  catch (err) {
    // Only process templates that actually exist.
    return;
  }

  try {
    stats1 = fs.statSync(ymlFile);
  }
  catch (err) {
    // Fail gracefully.
  }

  // Return on stat fail. Exclude non-files.
  if (!stats || !stats.isFile()) {
    return;
  }

  // Try to read YAML file if it exists.
  if (stats1 && stats1.isFile()) {
    // Read YAML file and store keys/values in tokens object.
    try {
      yml = fs.readFileSync(ymlFile, conf.enc);
      data = yaml.safeLoad(yml);

      if (typeof data.templates_dir === 'string') {
        templatesDir = utils.backendDirCheck(data.templates_dir);
        // Do not maintain nested directory structure in backend if
        // templates_dir is set in exceptional YAML file.
        if (templatesDir) {
          sourceDirParam = path.dirname(mustacheFile);
        }
        // Unset templates_dir in local YAML data.
        delete data.templates_dir;
      }

      if (typeof data.templates_ext === 'string') {
        templatesExt = utils.extCheck(data.templates_ext);
        // Unset templates_dir in local YAML data.
        delete data.templates_ext;
      }
    }
    catch (err) {
      // Fail gracefully.
      data = null;
    }
  }

  if (templatesDirDefault && !templatesDir) {
    templatesDir = templatesDirDefault;
  }

  if (templatesExtDefault && !templatesExt) {
    templatesExt = templatesExtDefault;
  }

  if (templatesDir && templatesExt) {
    // Recurse through Mustache templates (sparingly. See comment above.)
    code = exports.mustacheRecurse(mustacheFile);
    // Iterate through tokens and replace keys for values in the code.
    code = exports.tokensReplace(data, code);
    // Write compiled templates.
    dest = exports.templatesWrite(mustacheFile, sourceDirParam, templatesDir, templatesExt, code);

    // Log to console.
    utils.log('Template \x1b[36m%s\x1b[0m synced.', dest.replace(workDir, '').replace(/^\//, ''));
  }
};

exports.templatesGlob = function () {
  var globbed = glob.sync(sourceDir + '/*.mustache');
  var globbed1 = glob.sync(sourceDir + '/!(_nosync)/**/*.mustache');

  return globbed.concat(globbed1);
};

exports.templatesWrite = function (file, sourceDirParam, templatesDir, templatesExt, code) {
  // Determine destination for token-replaced code.
  var dest = file.replace(sourceDirParam, '');

  // Replace underscore prefixes.
  dest = dest.replace(/\/_([^\/]+)$/, '/$1');
  dest = templatesDir + dest;
  dest = dest.replace(/mustache$/, templatesExt);

  // Write to file system.
  fs.mkdirpSync(path.dirname(dest));
  fs.writeFileSync(dest, code);

  return dest;
};

exports.tokensReplace = function (tokens, code) {
  var regex;
  var token;
  var unescaped;

  for (let i in tokens) {
    if (tokens.hasOwnProperty(i)) {
      unescaped = exports.mustacheUnescape(i);
      regex = new RegExp('\\{\\{\\{?\\s*' + unescaped + '\\s*\\}?\\}\\}', 'g');
      token = tokens[i].replace(/^\n/, '');
      token = token.replace(/\n$/, '');
      code = code.replace(regex, token);
    }
  }

  // Delete remaining Mustache tags if configured to do so.
  if (!pref.templater.retain_mustache) {
    code = code.replace(/\{\{[^\(]*?(\([\S\s]*?\))?\s*\}?\}\}\s*\n?/g, '');
  }
  // Replace escaped curly braces.
  code = code.replace(/\\\{/g, '{');
  code = code.replace(/\\\}/g, '}');

  return code;
};

exports.main = function () {
  var files = exports.templatesGlob();
  var templatesDirDefault = utils.backendDirCheck(pref.backend.synced_dirs.templates_dir);
  var templatesExtDefault = utils.extCheck(pref.backend.synced_dirs.templates_ext);

  // Search source directory for Mustache files.
  // Excluding templates in _nosync directory and those prefixed by __.
  // Trying to keep the globbing simple and maintainable.
  for (let i = 0; i < files.length; i++) {
    exports.templateProcess(files[i], templatesDirDefault, templatesExtDefault);
  }
};
<|endoftext|>


<commit_before>'use strict';

describe('courseComparator.courses module', function() {

    beforeEach(module('courseComparator.courses'));

    describe('courses controller', function(){
        var scope, ctrl, $httpBackend;

        beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
            $httpBackend = _$httpBackend_;
            $httpBackend
                .expectGET('data/TES.json')
                .respond({
                    "TES1101": {
                        "code": "TES1101",
                        "description": "A test course.",
                        "language": "English",
                        "restriction": "",
                        "title": "Test Course",
                        "year": "1"
                    }
                });

            scope = $rootScope.$new();
            ctrl = $controller('CoursesCtrl', {
                $scope: scope,
                $routeParams: {
                    disciplineId: 'TES'
                }
            });
        }));

        it('should ....', inject(function() {
            expect(ctrl).toBeDefined();
        }));

        it('should set the discipline id', inject(function() {
            expect(scope.disciplineId).toEqual('TES');
        }));

        it('should have data', inject(function() {
            expect(scope.courses).toBeUndefined();

            $httpBackend.flush();

            expect(scope.courses).toEqual({
                "TES1101": {
                    "code": "TES1101",
                    "description": "A test course.",
                    "language": "English",
                    "restriction": "",
                    "title": "Test Course",
                    "year": "1"
                }
            });
        }));

        it('should sort by course code', inject(function() {
            expect(scope.orderProp).toEqual(['code']);
        }));

        it('should have a toggle interest function', inject(function() {
            expect(scope.toggleInterest).toBeDefined();
        }));

    });
});<commit_msg>Revert "rewrite tests for new data structure"<commit_after>'use strict';

describe('courseComparator.courses module', function() {

    beforeEach(module('courseComparator.courses'));

    describe('courses controller', function(){
        var scope, ctrl, $httpBackend;

        beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
            $httpBackend = _$httpBackend_;
            $httpBackend
                .expectGET('data/TES.json')
                .respond([
                    {
                        "code": "TES1101",
                        "description": "A test course.",
                        "language": "English",
                        "restriction": "",
                        "title": "Test Course",
                        "year": "1"
                    }
                ]);

            scope = $rootScope.$new();
            ctrl = $controller('CoursesCtrl', {
                $scope: scope,
                $routeParams: {
                    disciplineId: 'TES'
                }
            });
        }));

        it('should ....', inject(function() {
            expect(ctrl).toBeDefined();
        }));

        it('should set the discipline id', inject(function() {
            expect(scope.disciplineId).toEqual('TES');
        }));

        it('should have data', inject(function() {
            expect(scope.courses).toBeUndefined();

            $httpBackend.flush();

            expect(scope.courses).toEqual([
                {
                    "code": "TES1101",
                    "description": "A test course.",
                    "language": "English",
                    "restriction": "",
                    "title": "Test Course",
                    "year": "1"
                }
            ]);
        }));

        it('should sort by course code', inject(function() {
            expect(scope.orderProp).toEqual(['code']);
        }));

        it('should have a toggle interest function', inject(function() {
            expect(scope.toggleInterest).toBeDefined();
        }));

    });
});<|endoftext|>


<commit_before>import { expect, assert } from 'chai';
import { stub } from 'sinon';
import React from 'react';
import sd from 'skin-deep';
import { isElementOfType } from 'react-addons-test-utils';
import mockery from 'mockery';
import { findWithRef } from 'react-shallow-testutils';
import remoteMock from '../../test-utils/remote-mock';
import shallowRender from '../../test-utils/shallow-render';

const actions = {
  setCurrentTemplate: () => true,
  setCurrentScreenshot: () => true,
  addSize: () => true,
  removeSize: () => true,
  updateSize: () => true
};
const props = {
  templates: {},
  currentTemplate: {},
  currentScreenshot: '/path/to/screenshot',
  sizes: {},
  actions
};

export default describe('Preview', () => {
  let component,
      render,
      errorStub;

  before(done => {
    mockery.enable();
    mockery.warnOnUnregistered(false);
    mockery.registerMock('remote', remoteMock);
    mockery.registerMock('pods/template/components/Preview', {});
    mockery.registerMock('components/ExportPanel', {});
    errorStub = stub(console, 'error');
    component = require('pods/index/component');
    render = shallowRender(component, props);
    done();
  });

  after(done => {
    mockery.disable();
    mockery.deregisterMock('remote');
    mockery.deregisterMock('pods/template/components/Preview');
    mockery.deregisterMock('components/ExportPanel');
    errorStub.restore();
    done();
  });

  it('should pass propTypes check', () => {
    assert(!errorStub.called, `\n${errorStub.args.join('\n')}`);
  });

  it('should render a SideBar component', () => {
    let SideBar = findWithRef(render.output, 'SideBar');

    expect(SideBar).to.be.ok;
  });

  it('should render a PreviewArea component', () => {
    let PreviewArea = findWithRef(render.output, 'PreviewArea');

    expect(PreviewArea).to.be.ok;
  });
});<commit_msg>Fix index component tests<commit_after>import { expect, assert } from 'chai';
import { stub } from 'sinon';
import React from 'react';
import sd from 'skin-deep';
import { isElementOfType } from 'react-addons-test-utils';
import mockery from 'mockery';
import { findWithRef } from 'react-shallow-testutils';
import remoteMock from '../../test-utils/remote-mock';
import shallowRender from '../../test-utils/shallow-render';

const actions = {
  setCurrentTemplate: () => true,
  setCurrentTemplateSet: () => true,
  setCurrentScreenshot: () => true,
  addSize: () => true,
  removeSize: () => true,
  updateSize: () => true
};
const props = {
  templates: {},
  currentTemplate: {},
  currentTemplateSetId: 'default',
  currentScreenshot: '/path/to/screenshot',
  sizes: {},
  actions
};

export default describe('Preview', () => {
  let component,
      render,
      errorStub;

  before(done => {
    mockery.enable();
    mockery.warnOnUnregistered(false);
    mockery.registerMock('remote', remoteMock);
    mockery.registerMock('pods/template/components/Preview', {});
    mockery.registerMock('components/ExportPanel', {});
    errorStub = stub(console, 'error');
    component = require('pods/index/component');
    render = shallowRender(component, props);
    done();
  });

  after(done => {
    mockery.disable();
    mockery.deregisterMock('remote');
    mockery.deregisterMock('pods/template/components/Preview');
    mockery.deregisterMock('components/ExportPanel');
    errorStub.restore();
    done();
  });

  it('should pass propTypes check', () => {
    assert(!errorStub.called, `\n${errorStub.args.join('\n')}`);
  });

  it('should render a SideBar component', () => {
    let SideBar = findWithRef(render.output, 'SideBar');

    expect(SideBar).to.be.ok;
  });

  it('should render a PreviewArea component', () => {
    let PreviewArea = findWithRef(render.output, 'PreviewArea');

    expect(PreviewArea).to.be.ok;
  });
});<|endoftext|>


<commit_before>const expect = require('chai').expect;
const assert = require('assert');
const path = require('path');
const exec = require('child_process').exec;

const runner = path.join(__dirname, '/../../bin/codecept.js');
const codecept_dir = path.join(__dirname, '/../data/sandbox');
const codecept_run = `${runner} run`;
const codecept_run_config = config => `${codecept_run} --config ${codecept_dir}/${config}`;
const config_run_override = config => `${codecept_run} --config ${codecept_dir} --override '${JSON.stringify(config)}'`;

describe('CodeceptJS Runner', () => {
  before(() => {
    global.codecept_dir = path.join(__dirname, '/../data/sandbox');
  });

  it('should be executed in current dir', (done) => {
    process.chdir(codecept_dir);
    exec(codecept_run, (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('check current dir'); // test name
      assert(!err);
      done();
    });
  });

  it('should be executed with config path', (done) => {
    exec(`${codecept_run} -c ${codecept_dir}`, (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('check current dir'); // test name
      assert(!err);
      done();
    });
  });

  it('should show failures and exit with 1 on fail', (done) => {
    exec(codecept_run_config('codecept.failed.json'), (err, stdout, stderr) => {
      stdout.should.include('Not-A-Filesystem');
      stdout.should.include('file is not in dir');
      stdout.should.include('FAILURES');
      err.code.should.eql(1);
      done();
    });
  });

  it('should run bootstrap', (done) => {
    exec(codecept_run_config('codecept.bootstrap.sync.json'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      assert(!err);
      done();
    });
  });

  it('should run teardown', (done) => {
    exec(config_run_override({ teardown: 'bootstrap.sync.js' }), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      assert(!err);
      done();
    });
  });

  it('should run async bootstrap', (done) => {
    exec(config_run_override({ bootstrap: 'bootstrap.async.js' }), (err, stdout, stderr) => {
      stdout.should.include('Ready: 0');
      stdout.should.include('Go: 1');
      stdout.should.include('Filesystem'); // feature
      assert(!err);
      done();
    });
  });

  it('should run hooks', (done) => {
    exec(codecept_run_config('codecept.hooks.js'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      stdout.should.include('I am function hook');
      assert(!err);
      done();
    });
  });

  it('should run hooks from suites', (done) => {
    exec(codecept_run_config('codecept.testhooks.json'), (err, stdout) => {
      const lines = stdout.match(/\S.+/g);

      expect(lines).to.include.members([
        'Helper: I\'m simple BeforeSuite hook',
        'Test: I\'m simple BeforeSuite hook',
        'Test: I\'m generator BeforeSuite hook',
        'Test: I\'m async/await BeforeSuite hook',
        'Helper: I\'m simple Before hook',
        'Test: I\'m simple Before hook',
        'Test: I\'m generator Before hook',
        'Test: I\'m async/await Before hook',
        'Test: I\'m generator After hook',
        'Test: I\'m simple After hook',
        'Test: I\'m async/await After hook',
        'Helper: I\'m simple After hook',
        'Test: I\'m generator AfterSuite hook',
        'Test: I\'m simple AfterSuite hook',
        'Test: I\'m async/await AfterSuite hook',
        'Helper: I\'m simple AfterSuite hook',
      ]);
      stdout.should.include('OK  | 1 passed');
      assert(!err);
      done();
    });
  });

  it('should run hooks from suites (in different order)', (done) => {
    exec(codecept_run_config('codecept.testhooks.different.order.json'), (err, stdout) => {
      const lines = stdout.match(/\S.+/g);

      expect(lines).to.include.members([
        'Helper: I\'m simple BeforeSuite hook',
        'Test: I\'m async/await BeforeSuite hook',
        'Helper: I\'m simple Before hook',
        'Test: I\'m async/await Before hook',
        'Test: I\'m async/await After hook',
        'Helper: I\'m simple After hook',
        'Test: I\'m async/await AfterSuite hook',
        'Helper: I\'m simple AfterSuite hook',
      ]);
      stdout.should.include('OK  | 1 passed');
      assert(!err);
      done();
    });
  });

  it('should run different types of scenario', (done) => {
    exec(codecept_run_config('codecept.testscenario.json'), (err, stdout) => {
      const lines = stdout.match(/\S.+/g);
      expect(lines).to.include.members([
        'Test scenario types --',
        'It\'s usual test',
        'I\'m generator test',
        'I\'m async/await test',
      ]);
      stdout.should.include('OK  | 3 passed');
      assert(!err);
      done();
    });
  });

  it('should run bootstrap/teardown as object', (done) => {
    exec(codecept_run_config('codecept.bootstrap.obj.json'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      stdout.should.include('I am teardown');
      assert(!err);
      done();
    });
  });

  it('should run dynamic config', (done) => {
    exec(codecept_run_config('config.js'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      assert(!err);
      done();
    });
  });

  it('should run dynamic config with profile', (done) => {
    exec(`${codecept_run_config('config.js')} --profile failed`, (err, stdout, stderr) => {
      stdout.should.include('FAILURES');
      stdout.should.not.include('I am bootstrap');
      assert(err.code);
      done();
    });
  });

  it('should run dynamic config with profile 2', (done) => {
    exec(`${codecept_run_config('config.js')} --profile bootstrap`, (err, stdout, stderr) => {
      stdout.should.not.include('FAILURES'); // feature
      stdout.should.include('I am bootstrap');
      assert(!err);
      done();
    });
  });
});
<commit_msg>Updated expected text after refactoring the test Helper due to previous commit<commit_after>const expect = require('chai').expect;
const assert = require('assert');
const path = require('path');
const exec = require('child_process').exec;

const runner = path.join(__dirname, '/../../bin/codecept.js');
const codecept_dir = path.join(__dirname, '/../data/sandbox');
const codecept_run = `${runner} run`;
const codecept_run_config = config => `${codecept_run} --config ${codecept_dir}/${config}`;
const config_run_override = config => `${codecept_run} --config ${codecept_dir} --override '${JSON.stringify(config)}'`;

describe('CodeceptJS Runner', () => {
  before(() => {
    global.codecept_dir = path.join(__dirname, '/../data/sandbox');
  });

  it('should be executed in current dir', (done) => {
    process.chdir(codecept_dir);
    exec(codecept_run, (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('check current dir'); // test name
      assert(!err);
      done();
    });
  });

  it('should be executed with config path', (done) => {
    exec(`${codecept_run} -c ${codecept_dir}`, (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('check current dir'); // test name
      assert(!err);
      done();
    });
  });

  it('should show failures and exit with 1 on fail', (done) => {
    exec(codecept_run_config('codecept.failed.json'), (err, stdout, stderr) => {
      stdout.should.include('Not-A-Filesystem');
      stdout.should.include('file is not in dir');
      stdout.should.include('FAILURES');
      err.code.should.eql(1);
      done();
    });
  });

  it('should run bootstrap', (done) => {
    exec(codecept_run_config('codecept.bootstrap.sync.json'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      assert(!err);
      done();
    });
  });

  it('should run teardown', (done) => {
    exec(config_run_override({ teardown: 'bootstrap.sync.js' }), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      assert(!err);
      done();
    });
  });

  it('should run async bootstrap', (done) => {
    exec(config_run_override({ bootstrap: 'bootstrap.async.js' }), (err, stdout, stderr) => {
      stdout.should.include('Ready: 0');
      stdout.should.include('Go: 1');
      stdout.should.include('Filesystem'); // feature
      assert(!err);
      done();
    });
  });

  it('should run hooks', (done) => {
    exec(codecept_run_config('codecept.hooks.js'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      stdout.should.include('I am function hook');
      assert(!err);
      done();
    });
  });

  it('should run hooks from suites', (done) => {
    exec(codecept_run_config('codecept.testhooks.json'), (err, stdout) => {
      const lines = stdout.match(/\S.+/g);

      expect(lines).to.include.members([
        'Helper: I\'m simple BeforeSuite hook',
        'Test: I\'m simple BeforeSuite hook',
        'Test: I\'m generator BeforeSuite hook',
        'Test: I\'m async/await BeforeSuite hook',
        'Helper: I\'m simple Before hook',
        'Test: I\'m simple Before hook',
        'Test: I\'m generator Before hook',
        'Test: I\'m async/await Before hook',
        'Test: I\'m generator After hook',
        'Test: I\'m simple After hook',
        'Test: I\'m async/await After hook',
        'Helper: I\'m simple After hook',
        'Test: I\'m generator AfterSuite hook',
        'Test: I\'m simple AfterSuite hook',
        'Test: I\'m async/await AfterSuite hook',
        'Helper: I\'m simple AfterSuite hook',
      ]);
      stdout.should.include('OK  | 1 passed');
      assert(!err);
      done();
    });
  });

  it('should run hooks from suites (in different order)', (done) => {
    exec(codecept_run_config('codecept.testhooks.different.order.json'), (err, stdout) => {
      const lines = stdout.match(/\S.+/g);

      expect(lines).to.include.members([
        'Helper: I\'m simple BeforeSuite hook',
        'Test: I\'m async/await BeforeSuite hook',
        'Helper: I\'m simple Before hook',
        'Test: I\'m async/await Before hook',
        'Test: I\'m async/await After hook',
        'Helper: I\'m simple After hook',
        'Test: I\'m async/await AfterSuite hook',
        'Helper: I\'m simple AfterSuite hook',
      ]);
      stdout.should.include('OK  | 1 passed');
      assert(!err);
      done();
    });
  });

  it('should run different types of scenario', (done) => {
    exec(codecept_run_config('codecept.testscenario.json'), (err, stdout) => {
      const lines = stdout.match(/\S.+/g);
      expect(lines).to.include.members([
        'Test scenario types --',
        'It\'s usual test',
        'Test: I\'m generator test',
        'Test: I\'m async/await test',
      ]);
      stdout.should.include('OK  | 3 passed');
      assert(!err);
      done();
    });
  });

  it('should run bootstrap/teardown as object', (done) => {
    exec(codecept_run_config('codecept.bootstrap.obj.json'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      stdout.should.include('I am bootstrap');
      stdout.should.include('I am teardown');
      assert(!err);
      done();
    });
  });

  it('should run dynamic config', (done) => {
    exec(codecept_run_config('config.js'), (err, stdout, stderr) => {
      stdout.should.include('Filesystem'); // feature
      assert(!err);
      done();
    });
  });

  it('should run dynamic config with profile', (done) => {
    exec(`${codecept_run_config('config.js')} --profile failed`, (err, stdout, stderr) => {
      stdout.should.include('FAILURES');
      stdout.should.not.include('I am bootstrap');
      assert(err.code);
      done();
    });
  });

  it('should run dynamic config with profile 2', (done) => {
    exec(`${codecept_run_config('config.js')} --profile bootstrap`, (err, stdout, stderr) => {
      stdout.should.not.include('FAILURES'); // feature
      stdout.should.include('I am bootstrap');
      assert(!err);
      done();
    });
  });
});
<|endoftext|>


<commit_before>var nock = require('nock'),
    path = require('path'),
    expect = require('chai').expect,
    helpers = require('../testHelpers'),
    genscrape = require(path.join(__dirname, '..', '..'));

describe('fs ancestor', function(){

  it('process data and respond to hash changes', function(done){

    nockSetup('K2HD-1TC');
    nockSetup('KJZ2-417');

    helpers.mockWindow('https://familysearch.org/tree/#view=ancestor&person=K2HD-1TC', function(){

      var dataEvents = 0,
          noDataEvents = 0;

      genscrape()
      .on('noData', function(){
        noDataEvents++;

        if(noDataEvents === 1){
          window.location.hash = '#view=ancestor&person=KJZ2-417';
          window.onhashchange();
        }

        else {
          expect(true).to.be.false;
        }
      })
      .on('data', function(data){
        dataEvents++;

        if(dataEvents === 1){
          expect(noDataEvents).to.equal(0);
          expect(data).to.deep.equal({ givenName: 'John Augustus',
            familyName: 'Sheets',
            birthPlace: 'Philadelphia, Philadelphia, Pennsylvania, United States',
            birthDate: '14 May 1826',
            deathPlace: 'Salt Lake City, Salt Lake, Utah, United States',
            deathDate: '10 September 1904',
            fatherGivenName: 'Peter',
            fatherFamilyName: 'Sheets',
            motherGivenName: 'Mary Ann',
            motherFamilyName: 'Tridy',
            spouseGivenName: 'Elizabeth',
            spouseFamilyName: 'Tricebaugh',
            marriageDate: '27 December 1862',
            marriagePlace: 'Salt Lake City, Salt Lake, Utah, United States'
          });
          window.location.hash = '#view=pedigree';
          window.onhashchange();
        }

        else if(dataEvents === 2){
          expect(noDataEvents).to.equal(1);
          expect(data).to.deep.equal({
            givenName: 'Lindsay',
            familyName: 'Belding',
            birthPlace: 'Hartford, Hartford, Connecticut, United States',
            birthDate: '1800',
            deathPlace: 'Sinnemahoning, Gibson Township, Cameron, Pennsylvania, United States',
            deathDate: '1875',
            fatherGivenName: 'Amos',
            fatherFamilyName: 'Belding',
            motherGivenName: 'Anna',
            motherFamilyName: 'Day',
            spouseGivenName: 'Jane',
            spouseFamilyName: 'Garrison',
            marriageDate: '15 May 1824',
            marriagePlace: 'Union, Broome, New York'
          });
          done();
        }

        else {
          expect(true).to.be.false;
        }

      })
    });
  })

  it.only('bad http response', function(done){
    nock('https://familysearch.org')
      .defaultReplyHeaders({
        'content-type': 'application/json'
      })
      .get('/platform/tree/persons-with-relationships?persons&person=MMM')
      .reply(500);
    helpers.mockWindow('https://familysearch.org/tree/#view=ancestor&person=MMM', function(){
      genscrape()
      .on('error', function(e){
        expect(e).to.exist;
        done();
      })
    });
  })

  it('ancestor view with no data', function(done){
    helpers.mockWindow('https://familysearch.org/tree/#view=ancestor', function(){
      genscrape()
      .on('noData', function(){
        done();
      })
    });
  })

})

/**
 * Configure nock to respond properly to requests
 * for the given person with test data
 */
function nockSetup(personId){
  nock('https://familysearch.org')
    .defaultReplyHeaders({
      'content-type': 'application/json'
    })
    .get('/platform/tree/persons-with-relationships?persons&person='+personId)
    .replyWithFile(200, path.join(__dirname, '..', 'responses', 'fs', 'platform', personId+'.json'));
}<commit_msg>remove restriction on tests<commit_after>var nock = require('nock'),
    path = require('path'),
    expect = require('chai').expect,
    helpers = require('../testHelpers'),
    genscrape = require(path.join(__dirname, '..', '..'));

describe('fs ancestor', function(){

  it('process data and respond to hash changes', function(done){

    nockSetup('K2HD-1TC');
    nockSetup('KJZ2-417');

    helpers.mockWindow('https://familysearch.org/tree/#view=ancestor&person=K2HD-1TC', function(){

      var dataEvents = 0,
          noDataEvents = 0;

      genscrape()
      .on('noData', function(){
        noDataEvents++;

        if(noDataEvents === 1){
          window.location.hash = '#view=ancestor&person=KJZ2-417';
          window.onhashchange();
        }

        else {
          expect(true).to.be.false;
        }
      })
      .on('data', function(data){
        dataEvents++;

        if(dataEvents === 1){
          expect(noDataEvents).to.equal(0);
          expect(data).to.deep.equal({ givenName: 'John Augustus',
            familyName: 'Sheets',
            birthPlace: 'Philadelphia, Philadelphia, Pennsylvania, United States',
            birthDate: '14 May 1826',
            deathPlace: 'Salt Lake City, Salt Lake, Utah, United States',
            deathDate: '10 September 1904',
            fatherGivenName: 'Peter',
            fatherFamilyName: 'Sheets',
            motherGivenName: 'Mary Ann',
            motherFamilyName: 'Tridy',
            spouseGivenName: 'Elizabeth',
            spouseFamilyName: 'Tricebaugh',
            marriageDate: '27 December 1862',
            marriagePlace: 'Salt Lake City, Salt Lake, Utah, United States'
          });
          window.location.hash = '#view=pedigree';
          window.onhashchange();
        }

        else if(dataEvents === 2){
          expect(noDataEvents).to.equal(1);
          expect(data).to.deep.equal({
            givenName: 'Lindsay',
            familyName: 'Belding',
            birthPlace: 'Hartford, Hartford, Connecticut, United States',
            birthDate: '1800',
            deathPlace: 'Sinnemahoning, Gibson Township, Cameron, Pennsylvania, United States',
            deathDate: '1875',
            fatherGivenName: 'Amos',
            fatherFamilyName: 'Belding',
            motherGivenName: 'Anna',
            motherFamilyName: 'Day',
            spouseGivenName: 'Jane',
            spouseFamilyName: 'Garrison',
            marriageDate: '15 May 1824',
            marriagePlace: 'Union, Broome, New York'
          });
          done();
        }

        else {
          expect(true).to.be.false;
        }

      })
    });
  })

  it('bad http response', function(done){
    nock('https://familysearch.org')
      .defaultReplyHeaders({
        'content-type': 'application/json'
      })
      .get('/platform/tree/persons-with-relationships?persons&person=MMM')
      .reply(500);
    helpers.mockWindow('https://familysearch.org/tree/#view=ancestor&person=MMM', function(){
      genscrape()
      .on('error', function(e){
        expect(e).to.exist;
        done();
      })
    });
  })

  it('ancestor view with no data', function(done){
    helpers.mockWindow('https://familysearch.org/tree/#view=ancestor', function(){
      genscrape()
      .on('noData', function(){
        done();
      })
    });
  })

})

/**
 * Configure nock to respond properly to requests
 * for the given person with test data
 */
function nockSetup(personId){
  nock('https://familysearch.org')
    .defaultReplyHeaders({
      'content-type': 'application/json'
    })
    .get('/platform/tree/persons-with-relationships?persons&person='+personId)
    .replyWithFile(200, path.join(__dirname, '..', 'responses', 'fs', 'platform', personId+'.json'));
}<|endoftext|>


<commit_before>import _ from 'underscore';

import events from 'girder/events';
import Panel from 'girder_plugins/slicer_cli_web/views/Panel';

import StyleCollection from '../collections/StyleCollection';
import StyleModel from '../models/StyleModel';
import editElement from '../dialogs/editElement';
import editStyleGroups from '../dialogs/editStyleGroups';
import drawWidget from '../templates/panels/drawWidget.pug';
import '../stylesheets/panels/drawWidget.styl';

/**
 * Create a panel with controls to draw and edit
 * annotation elements.
 */
var DrawWidget = Panel.extend({
    events: _.extend(Panel.prototype.events, {
        'click .h-edit-element': 'editElement',
        'click .h-delete-element': 'deleteElement',
        'click .h-draw': 'drawElement',
        'change .h-style-group': '_setStyleGroup',
        'click .h-configure-style-group': '_styleGroupEditor',
        'mouseenter .h-element': '_highlightElement',
        'mouseleave .h-element': '_unhighlightElement'
    }),

    /**
     * Create the panel.
     *
     * @param {object} settings
     * @param {ItemModel} settings.image
     *     The associate large_image "item"
     */
    initialize(settings) {
        this.image = settings.image;
        this.annotation = settings.annotation;
        this.collection = this.annotation.elements();
        this.viewer = settings.viewer;
        this._drawingType = settings.drawingType || null;

        this._highlighted = {};
        this._groups = new StyleCollection();
        this._style = new StyleModel({id: 'default'});
        this.listenTo(this._groups, 'update', this.render);
        this.listenTo(this.collection, 'add remove reset', this._recalculateGroupAggregation);
        this.listenTo(this.collection, 'change update reset', this.render);
        this._groups.fetch().done(() => {
            // ensure the default style exists
            if (this._groups.has('default')) {
                this._style.set(this._groups.get('default').toJSON());
            } else {
                this._groups.add(this._style.toJSON());
                this._groups.get(this._style.id).save();
            }
        });
        this.on('h:mouseon', (model) => {
            if (model && model.id) {
                this._highlighted[model.id] = true;
                this.$(`.h-element[data-id="${model.id}"]`).addClass('h-highlight-element');
            }
        });
        this.on('h:mouseoff', (model) => {
            if (model && model.id) {
                this._highlighted[model.id] = false;
                this.$(`.h-element[data-id="${model.id}"]`).removeClass('h-highlight-element');
            }
        });
    },

    render() {
        this.$('[data-toggle="tooltip"]').tooltip('destroy');
        if (!this.viewer) {
            this.$el.empty();
            return;
        }
        const name = (this.annotation.get('annotation') || {}).name || 'Untitled';
        this.trigger('h:redraw', this.annotation);
        this.$el.html(drawWidget({
            title: 'Draw',
            elements: this.collection.models,
            groups: this._groups,
            style: this._style.id,
            highlighted: this._highlighted,
            name
        }));
        if (this._drawingType) {
            this.$('button.h-draw[data-type="' + this._drawingType + '"]').addClass('active');
            this.drawElement(undefined, this._drawingType);
        }
        this.$('.s-panel-content').collapse({toggle: false});
        this.$('[data-toggle="tooltip"]').tooltip({container: 'body'});
        if (this.viewer.annotationLayer && !this.viewer.annotationLayer._boundHistomicsTKModeChange) {
            this.viewer.annotationLayer._boundHistomicsTKModeChange = true;
            this.viewer.annotationLayer.geoOn(window.geo.event.annotation.mode, (event) => {
                this.$('button.h-draw').removeClass('active');
                if (this._drawingType) {
                    this.$('button.h-draw[data-type="' + this._drawingType + '"]').addClass('active');
                }
                if (event.mode !== this._drawingType && this._drawingType) {
                    /* This makes the draw modes stay on until toggled off.
                     * To turn off drawing after each annotation, add
                     *  this._drawingType = null;
                     */
                    this.drawElement(undefined, this._drawingType);
                }
            });
        }
        return this;
    },

    /**
     * When a region should be drawn that isn't caused by a drawing button,
     * toggle off the drawing mode.
     *
     * @param {event} Girder event that triggered drawing a region.
     */
    _widgetDrawRegion(evt) {
        this._drawingType = null;
        this.$('button.h-draw').removeClass('active');
    },

    /**
     * Set the image "viewer" instance.  This should be a subclass
     * of `large_image/imageViewerWidget` that is capable of rendering
     * annotations.
     */
    setViewer(viewer) {
        this.viewer = viewer;
        // make sure our listeners are in the correct order.
        this.stopListening(events, 's:widgetDrawRegion', this._widgetDrawRegion);
        if (viewer) {
            this.listenTo(events, 's:widgetDrawRegion', this._widgetDrawRegion);
            viewer.stopListening(events, 's:widgetDrawRegion', viewer.drawRegion);
            viewer.listenTo(events, 's:widgetDrawRegion', viewer.drawRegion);
        }
        return this;
    },

    /**
     * Respond to a click on the "edit" button by rendering
     * the EditAnnotation modal dialog.
     */
    editElement(evt) {
        editElement(this.collection.get(this._getId(evt)));
    },

    /**
     * Respond to a click on the "delete" button by removing
     * the element from the element collection.
     */
    deleteElement(evt) {
        this.collection.remove(this._getId(evt));
    },

    /**
     * Respond to clicking an element type by putting the image
     * viewer into "draw" mode.
     *
     * @param {jQuery.Event} [evt] The button click that triggered this event.
     *      `undefined` to use a passed-in type.
     * @param {string|null} [type] If `evt` is `undefined`, switch to this draw
     *      mode.
     */
    drawElement(evt, type) {
        var $el;
        if (evt) {
            $el = this.$(evt.currentTarget);
            $el.tooltip('hide');
            type = $el.hasClass('active') ? null : $el.data('type');
        } else {
            $el = this.$('button.h-draw[data-type="' + type + '"]');
        }
        if (this.viewer.annotationLayer.mode() === type && this._drawingType === type) {
            return;
        }
        if (this.viewer.annotationLayer.mode()) {
            this._drawingType = null;
            this.viewer.annotationLayer.mode(null);
            this.viewer.annotationLayer.geoOff(window.geo.event.annotation.state);
            this.viewer.annotationLayer.removeAllAnnotations();
        }
        if (type) {
            // always show the active annotation when drawing a new element
            this.annotation.set('displayed', true);

            this._drawingType = type;
            this.viewer.startDrawMode(type)
                .then((element) => {
                    this.collection.add(
                        _.map(element, (el) => _.extend(el, _.omit(this._style.toJSON(), 'id')))
                    );
                    return undefined;
                });
        }
    },

    cancelDrawMode() {
        this.drawElement(undefined, null);
        this.viewer.annotationLayer._boundHistomicsTKModeChange = false;
        this.viewer.annotationLayer.geoOff(window.geo.event.annotation.state);
    },

    drawingType() {
        return this._drawingType;
    },

    /**
     * Get the element id from a click event.
     */
    _getId(evt) {
        return this.$(evt.currentTarget).parent('.h-element').data('id');
    },

    _setStyleGroup() {
        this._style.set(
            this._groups.get(this.$('.h-style-group').val()).toJSON()
        );
        if (!this._style.get('group') && this._style.id !== 'default') {
            this._style.set('group', this._style.id);
        }
    },

    _styleGroupEditor() {
        editStyleGroups(this._style, this._groups);
    },

    _highlightElement(evt) {
        const id = $(evt.currentTarget).data('id');
        this.parentView.trigger('h:highlightAnnotation', this.annotation.id, id);
    },

    _unhighlightElement() {
        this.parentView.trigger('h:highlightAnnotation');
    },

    _recalculateGroupAggregation() {
        const groups = _.invoke(
            this.collection.filter((el) => el.get('group')),
            'get', 'group'
        );
        this.annotation.set('groups', groups);
    }
});

export default DrawWidget;
<commit_msg>Fix a bug with selecting an ROI.<commit_after>import _ from 'underscore';

import events from 'girder/events';
import Panel from 'girder_plugins/slicer_cli_web/views/Panel';

import StyleCollection from '../collections/StyleCollection';
import StyleModel from '../models/StyleModel';
import editElement from '../dialogs/editElement';
import editStyleGroups from '../dialogs/editStyleGroups';
import drawWidget from '../templates/panels/drawWidget.pug';
import '../stylesheets/panels/drawWidget.styl';

/**
 * Create a panel with controls to draw and edit
 * annotation elements.
 */
var DrawWidget = Panel.extend({
    events: _.extend(Panel.prototype.events, {
        'click .h-edit-element': 'editElement',
        'click .h-delete-element': 'deleteElement',
        'click .h-draw': 'drawElement',
        'change .h-style-group': '_setStyleGroup',
        'click .h-configure-style-group': '_styleGroupEditor',
        'mouseenter .h-element': '_highlightElement',
        'mouseleave .h-element': '_unhighlightElement'
    }),

    /**
     * Create the panel.
     *
     * @param {object} settings
     * @param {ItemModel} settings.image
     *     The associate large_image "item"
     */
    initialize(settings) {
        this.image = settings.image;
        this.annotation = settings.annotation;
        this.collection = this.annotation.elements();
        this.viewer = settings.viewer;
        this.setViewer(settings.viewer);
        this._drawingType = settings.drawingType || null;

        this._highlighted = {};
        this._groups = new StyleCollection();
        this._style = new StyleModel({id: 'default'});
        this.listenTo(this._groups, 'update', this.render);
        this.listenTo(this.collection, 'add remove reset', this._recalculateGroupAggregation);
        this.listenTo(this.collection, 'change update reset', this.render);
        this._groups.fetch().done(() => {
            // ensure the default style exists
            if (this._groups.has('default')) {
                this._style.set(this._groups.get('default').toJSON());
            } else {
                this._groups.add(this._style.toJSON());
                this._groups.get(this._style.id).save();
            }
        });
        this.on('h:mouseon', (model) => {
            if (model && model.id) {
                this._highlighted[model.id] = true;
                this.$(`.h-element[data-id="${model.id}"]`).addClass('h-highlight-element');
            }
        });
        this.on('h:mouseoff', (model) => {
            if (model && model.id) {
                this._highlighted[model.id] = false;
                this.$(`.h-element[data-id="${model.id}"]`).removeClass('h-highlight-element');
            }
        });
    },

    render() {
        this.$('[data-toggle="tooltip"]').tooltip('destroy');
        if (!this.viewer) {
            this.$el.empty();
            return;
        }
        const name = (this.annotation.get('annotation') || {}).name || 'Untitled';
        this.trigger('h:redraw', this.annotation);
        this.$el.html(drawWidget({
            title: 'Draw',
            elements: this.collection.models,
            groups: this._groups,
            style: this._style.id,
            highlighted: this._highlighted,
            name
        }));
        if (this._drawingType) {
            this.$('button.h-draw[data-type="' + this._drawingType + '"]').addClass('active');
            this.drawElement(undefined, this._drawingType);
        }
        this.$('.s-panel-content').collapse({toggle: false});
        this.$('[data-toggle="tooltip"]').tooltip({container: 'body'});
        if (this.viewer.annotationLayer && !this.viewer.annotationLayer._boundHistomicsTKModeChange) {
            this.viewer.annotationLayer._boundHistomicsTKModeChange = true;
            this.viewer.annotationLayer.geoOn(window.geo.event.annotation.mode, (event) => {
                this.$('button.h-draw').removeClass('active');
                if (this._drawingType) {
                    this.$('button.h-draw[data-type="' + this._drawingType + '"]').addClass('active');
                }
                if (event.mode !== this._drawingType && this._drawingType) {
                    /* This makes the draw modes stay on until toggled off.
                     * To turn off drawing after each annotation, add
                     *  this._drawingType = null;
                     */
                    this.drawElement(undefined, this._drawingType);
                }
            });
        }
        return this;
    },

    /**
     * When a region should be drawn that isn't caused by a drawing button,
     * toggle off the drawing mode.
     *
     * @param {event} Girder event that triggered drawing a region.
     */
    _widgetDrawRegion(evt) {
        this._drawingType = null;
        this.$('button.h-draw').removeClass('active');
    },

    /**
     * Set the image "viewer" instance.  This should be a subclass
     * of `large_image/imageViewerWidget` that is capable of rendering
     * annotations.
     */
    setViewer(viewer) {
        this.viewer = viewer;
        // make sure our listeners are in the correct order.
        this.stopListening(events, 's:widgetDrawRegion', this._widgetDrawRegion);
        if (viewer) {
            this.listenTo(events, 's:widgetDrawRegion', this._widgetDrawRegion);
            viewer.stopListening(events, 's:widgetDrawRegion', viewer.drawRegion);
            viewer.listenTo(events, 's:widgetDrawRegion', viewer.drawRegion);
        }
        return this;
    },

    /**
     * Respond to a click on the "edit" button by rendering
     * the EditAnnotation modal dialog.
     */
    editElement(evt) {
        editElement(this.collection.get(this._getId(evt)));
    },

    /**
     * Respond to a click on the "delete" button by removing
     * the element from the element collection.
     */
    deleteElement(evt) {
        this.collection.remove(this._getId(evt));
    },

    /**
     * Respond to clicking an element type by putting the image
     * viewer into "draw" mode.
     *
     * @param {jQuery.Event} [evt] The button click that triggered this event.
     *      `undefined` to use a passed-in type.
     * @param {string|null} [type] If `evt` is `undefined`, switch to this draw
     *      mode.
     */
    drawElement(evt, type) {
        var $el;
        if (evt) {
            $el = this.$(evt.currentTarget);
            $el.tooltip('hide');
            type = $el.hasClass('active') ? null : $el.data('type');
        } else {
            $el = this.$('button.h-draw[data-type="' + type + '"]');
        }
        if (this.viewer.annotationLayer.mode() === type && this._drawingType === type) {
            return;
        }
        if (this.viewer.annotationLayer.mode()) {
            this._drawingType = null;
            this.viewer.annotationLayer.mode(null);
            this.viewer.annotationLayer.geoOff(window.geo.event.annotation.state);
            this.viewer.annotationLayer.removeAllAnnotations();
        }
        if (type) {
            // always show the active annotation when drawing a new element
            this.annotation.set('displayed', true);

            this._drawingType = type;
            this.viewer.startDrawMode(type)
                .then((element) => {
                    this.collection.add(
                        _.map(element, (el) => _.extend(el, _.omit(this._style.toJSON(), 'id')))
                    );
                    return undefined;
                });
        }
    },

    cancelDrawMode() {
        this.drawElement(undefined, null);
        this.viewer.annotationLayer._boundHistomicsTKModeChange = false;
        this.viewer.annotationLayer.geoOff(window.geo.event.annotation.state);
    },

    drawingType() {
        return this._drawingType;
    },

    /**
     * Get the element id from a click event.
     */
    _getId(evt) {
        return this.$(evt.currentTarget).parent('.h-element').data('id');
    },

    _setStyleGroup() {
        this._style.set(
            this._groups.get(this.$('.h-style-group').val()).toJSON()
        );
        if (!this._style.get('group') && this._style.id !== 'default') {
            this._style.set('group', this._style.id);
        }
    },

    _styleGroupEditor() {
        editStyleGroups(this._style, this._groups);
    },

    _highlightElement(evt) {
        const id = $(evt.currentTarget).data('id');
        this.parentView.trigger('h:highlightAnnotation', this.annotation.id, id);
    },

    _unhighlightElement() {
        this.parentView.trigger('h:highlightAnnotation');
    },

    _recalculateGroupAggregation() {
        const groups = _.invoke(
            this.collection.filter((el) => el.get('group')),
            'get', 'group'
        );
        this.annotation.set('groups', groups);
    }
});

export default DrawWidget;
<|endoftext|>


<commit_before>angular.module('lampost_editor').controller('SocialEditorCtrl', ['$scope', 'lpRemote', 'lpEditor', 'lpEvent',
  function ($scope, lpRemote, lpEditor, lpEvent) {

    var preview;

    $scope.editMode = true;
    $scope.source = 'Player';
    $scope.target = 'Target';
    $scope.sourceSelf = false;
    $scope.displayMap = {};

    $scope.startEditMode = function() {
      $scope.editMode = true;
      updateDisplayMap();
    }

    $scope.previewSocial = function () {
      lpRemote.request('editor/social/preview', {target: $scope.target, self_source: $scope.sourceSelf,
        source: $scope.source, b_map: $scope.model.b_map})
        .then(function (data) {
          preview = data;
          $scope.editMode = false;
          updateDisplayMap();
        });
    };

    $scope.updateSocial = function(bType) {
      $scope.model.b_map[bType] = $scope.displayMap[bType];
    }

    function updateDisplayMap() {
      if ($scope.model.b_map) {
        angular.forEach(lpEditor.constants.broadcast_types, function(bType) {
          var key = bType.id;
          $scope.displayMap[key] = $scope.editMode ? $scope.model.b_map[key] : preview[key];
        });
      }
    }

    lpEvent.register('editReady', updateDisplayMap, $scope);

    updateDisplayMap();

  }]);

<commit_msg>Social editor tweaking.<commit_after>angular.module('lampost_editor').controller('SocialEditorCtrl', ['$scope', 'lpRemote', 'lpEditor', 'lpEvent',
  function ($scope, lpRemote, lpEditor, lpEvent) {

    var preview = {};

    $scope.editMode = true;
    $scope.source = 'Player';
    $scope.target = 'Target';
    $scope.sourceSelf = false;
    $scope.displayMap = {};

    $scope.startEditMode = function() {
      $scope.editMode = true;
      updateDisplayMap();
    }

    $scope.previewSocial = function () {
      lpRemote.request('editor/social/preview', {target: $scope.target, self_source: $scope.sourceSelf,
        source: $scope.source, b_map: $scope.model.b_map})
        .then(function (data) {
          preview = data;
          preview.dbo_id = $scope.model.dbo_id
          $scope.editMode = false;
          updateDisplayMap();
        });
    };

    $scope.updateSocial = function(bType) {
      $scope.model.b_map[bType] = $scope.displayMap[bType];
    }

    function updateDisplayMap() {
      if ($scope.model.b_map) {
        angular.forEach(lpEditor.constants.broadcast_types, function(bType) {
          var key = bType.id;
          $scope.displayMap[key] = $scope.editMode ? $scope.model.b_map[key] : preview[key];
        });
      }
    }

    lpEvent.register('editReady', function() {
      if (!$scope.editMode &&  $scope.model.dbo_id != preview.dbo_id) {
        $scope.previewSocial()
      } else {
        updateDisplayMap()
      }
    }, $scope);

    updateDisplayMap();

  }]);

<|endoftext|>


<commit_before>; (function (root, factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define([
			'jasmine'
			, 'sinon'
			, 'pubsub'
		], factory);
	} else {
		// Browser globals
		root.specsUnsubscription = factory(root.jasmine, root.sinon, root.pubsub);
	}
}(this, function(jasmine, sinon, pubsub) {
	describe('pubsub should handle unsubscription', function() {

		var testSubscriber

		beforeEach(function() {
			testSubscriber = jasmine.createSpy()
		})

		it('should not throw an exception', function() {
			expect(function() {
				pubsub.sub('test-event-delete-1', testSubscriber)
				pubsub.unsub('test-event-delete-1', testSubscriber)

				pubsub.pub('test-event-delete-1')
			}).not.toThrow()
		})

		it('should not call a subscriber after unsubscription', function() {
			pubsub.sub('test-event-delete-2', testSubscriber)
			pubsub.unsub('test-event-delete-2', testSubscriber)

			pubsub.pub('test-event-delete-2')

			expect(testSubscriber).not.toHaveBeenCalled()
		})
	})
}));
<commit_msg>Unsubscription is idempotent<commit_after>; (function (root, factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define([
			'jasmine'
			, 'sinon'
			, 'pubsub'
		], factory);
	} else {
		// Browser globals
		root.specsUnsubscription = factory(root.jasmine, root.sinon, root.pubsub);
	}
}(this, function(jasmine, sinon, pubsub) {
	describe('unsubscription from events', function() {

		var testSubscriber

		beforeEach(function() {
			testSubscriber = jasmine.createSpy()
		})

		it('should not throw an exception', function() {
			expect(function() {
				pubsub.sub('test-event-delete-1', testSubscriber)
				pubsub.unsub('test-event-delete-1', testSubscriber)

				pubsub.pub('test-event-delete-1')
			}).not.toThrow()
		})

		it('should not call a subscriber after unsubscription', function() {
			pubsub.sub('test-event-delete-2', testSubscriber)
			pubsub.unsub('test-event-delete-2', testSubscriber)

			pubsub.pub('test-event-delete-2')

			expect(testSubscriber).not.toHaveBeenCalled()
		})

		it('should be idempotent', function() {
			expect(function() {
				pubsub.sub('test-event-delete-3', testSubscriber)
				pubsub.unsub('test-event-delete-3', testSubscriber)
				pubsub.unsub('test-event-delete-3', testSubscriber)
			}).not.toThrow()
		})

		it('should be safe when you\'re not yet subscribed', function() {
			expect(function() {
				pubsub.unsub('test-event-delete-3', testSubscriber)
			}).not.toThrow()
		})
	})
}));
<|endoftext|>


<commit_before>var expect = require('chai').expect;
var Q = require('q');

module.exports = function (browser) {
    describe("The Window example", function () {
        beforeEach(function (done) {
            browser.url('http://localhost:8080/window.html', done);
        });

        // Don't test alerts etc. under Safari, because Selenium can't
        // manage alerts with Safari.
        var describeAlert =
            (browser.desiredCapabilities.browserName == 'safari')
                ? describe.skip
                : describe;

        var truthy = function () {
            return Q.when(true);
        };

        var falsy = function () {
            return Q.when(false);
        };

        describeAlert("alert", function () {
            it("should open", function () {
                return browser
                    .click("#alert-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 24000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("Hello world!");
                    })

                    .alertAccept();
            });
        });

        describeAlert("confirm", function () {
            it("should recognize acceptance", function () {
                return browser
                    .click("#confirm-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 24000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("Do you agree?");
                    })

                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Pressed OK") >= 0;
                        });
                    }, 24000, 500);
            });

            it("should recognize rejection", function () {
                return browser
                    .click("#confirm-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 24000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("Do you agree?");
                    })

                    .alertDismiss()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Pressed cancel") >= 0;
                        });
                    }, 24000, 500);
            });
        });

        describeAlert("prompt", function () {
            it("should recognize dismissal", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 24000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("What is your favourite colour?");
                    })

                    .alertDismiss()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("User canceled.") >= 0;
                        });
                    }, 24000, 500);
            });

            it("should return default when accepted", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 24000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("What is your favourite colour?");
                    })

                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Got response: Blue") >= 0;
                        });
                    }, 24000, 500);
            });

            it("should interpret empty string as dismissal", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 24000, 500)

                    .alertText("")
                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("User canceled.") >= 0;
                        });
                    }, 24000, 500);
            });

            it("should return entered text if entered", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 24000, 500)

                    .alertText("Red")
                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Got response: Red") >= 0;
                        });
                    }, 24000, 500);
            });
        });
    });
};
<commit_msg>And yet more absurd values for the timeouts ...<commit_after>var expect = require('chai').expect;
var Q = require('q');

module.exports = function (browser) {
    describe("The Window example", function () {
        beforeEach(function (done) {
            browser.url('http://localhost:8080/window.html', done);
        });

        // Don't test alerts etc. under Safari, because Selenium can't
        // manage alerts with Safari.
        var describeAlert =
            (browser.desiredCapabilities.browserName == 'safari')
                ? describe.skip
                : describe;

        var truthy = function () {
            return Q.when(true);
        };

        var falsy = function () {
            return Q.when(false);
        };

        describeAlert("alert", function () {
            it("should open", function () {
                return browser
                    .click("#alert-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 30000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("Hello world!");
                    })

                    .alertAccept();
            });
        });

        describeAlert("confirm", function () {
            it("should recognize acceptance", function () {
                return browser
                    .click("#confirm-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 30000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("Do you agree?");
                    })

                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Pressed OK") >= 0;
                        });
                    }, 30000, 500);
            });

            it("should recognize rejection", function () {
                return browser
                    .click("#confirm-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 30000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("Do you agree?");
                    })

                    .alertDismiss()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Pressed cancel") >= 0;
                        });
                    }, 30000, 500);
            });
        });

        describeAlert("prompt", function () {
            it("should recognize dismissal", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 30000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("What is your favourite colour?");
                    })

                    .alertDismiss()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("User canceled.") >= 0;
                        });
                    }, 30000, 500);
            });

            it("should return default when accepted", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 30000, 500)

                    .alertText().then(function (text) {
                        expect(text).to.equal("What is your favourite colour?");
                    })

                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Got response: Blue") >= 0;
                        });
                    }, 30000, 500);
            });

            it("should interpret empty string as dismissal", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 30000, 500)

                    .alertText("")
                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("User canceled.") >= 0;
                        });
                    }, 30000, 500);
            });

            it("should return entered text if entered", function () {
                return browser
                    .click("#prompt-button")

                    .waitUntil(function () {
                        return this.alertText().then(truthy, falsy);
                    }, 30000, 500)

                    .alertText("Red")
                    .alertAccept()

                    .waitUntil(function () {
                        return this.getText("#message").then(function (text) {
                            return text.indexOf("Got response: Red") >= 0;
                        });
                    }, 30000, 500);
            });
        });
    });
};
<|endoftext|>