<commit_before>function PhraseGrid(selector, indexPath, phrasesPath, tagsByClusters, tags) {
  var thisGrid = this;

  this.selector = selector;
  this.indexPath = indexPath;
  this.phrasesPath = phrasesPath;
  this.tagsByClusters = tagsByClusters;
  this.tags = tags;

  this.index;
  this.clusterId;
  this.seeBeforePhrases = [];
  this.seeAfterPhrases = [];

  this.init = function(clusterId, callback) {
    d3.json(this.indexPath, function(error, index) {
      if(error){
        console.warn(error)
        if(typeof callback != "undefined") callback(null, "Cannot load index");
      } else {
           thisGrid.initTable();
           thisGrid.index = index;
           thisGrid.clusterId = clusterId;
           if(typeof clusterId != "undefined" && clusterId != null) thisGrid.loadPage(clusterId, 0, callback);
           else if(typeof callback != "undefined") callback(context, null);
        }
      })
    };

   this.initTable = function() {
     //Pagination
     var pUpdate = d3.select(this.selector).selectAll("div.phrase-pages").data([1]);
     var pEnter = pUpdate.enter().append("div").classed("phrase-pages", true);
     var pages = pUpdate.merge(pEnter);

     //Table
     var tUpdate = d3.select(this.selector).selectAll("table.phrase-table").data([1]);
     var tEnter = tUpdate.enter().append("table").classed("phrase-table", true);
     var table = tUpdate.merge(tEnter);
     var hRowUpdate = table.selectAll("tr.phrase-header").data([1]);
     var hRowEnter = hRowUpdate.enter().append("tr").classed("phrase-header", true);
     var hRow = hRowUpdate.merge(hRowEnter);
     var hUpdate = hRow.selectAll("td.phrase-header").data(["N°", "Tags",  "Phrase", "%match"]);
     var hEnter = hUpdate.enter().append("th").classed("phrase-header", true).text(d => d);
     var header = hUpdate.merge(hEnter);

   };

   this.loadPage = function(clusterId, page ,callback) {

     if(this.index[clusterId] && this.index[clusterId][page]) {
       this.clusterId = clusterId;
       this.seeBeforePhrases = [];
       this.seeAfterPhrases = [];
       //Pagination
       this.loadPagination(Object.keys(this.index[clusterId]).map(i => (parseInt(i)==page)?true:false));
       //Table
       d3.json(this.phrasesPath + "/" + this.index[clusterId][page] , function(error, phrases) {
         if(error){
           console.warn(error)
           if(typeof callback != "undefined") callback(null, "Cannot load phrases");
         } else {
              thisGrid.tagPhrases(phrases);
              thisGrid.loadPhrases(phrases);
              if(typeof callback != "undefined") callback(phrases, null);
           }
         });
        } else {
          if(typeof callback!="undefined")
            callback(null, "Cluster not found");
          else console.warn("Cannot found cluster to draw phrases")
        }
     };
   this.loadPhrases = function(phrases) {
     var trUpdate = d3.select(this.selector).select("table.phrase-table").selectAll("tr.phrase").data(phrases)
     var trEnter = trUpdate.enter().append("tr").classed("phrase", true);
     var trExit = trUpdate.exit().remove();
     var trs = trUpdate.merge(trEnter);

     trEnter.append("td").classed("phrase-nb phrase-cell", true);
     trEnter.append("td").classed("phrase-tags phrase-cell", true);
     var tdTextEnter = trEnter.append("td").classed("phrase-text phrase-cell", true);
     tdTextEnter.append("span").classed("phrase-text-before", true);
     tdTextEnter.append("span").classed("phrase-text-current", true);
     tdTextEnter.append("span").classed("phrase-text-after", true);
     trEnter.append("td").classed("phrase-match phrase-cell", true);

     trs.select("td.phrase-nb").text((d, i) => i);
     var tagsUpd = trs.select("td.phrase-tags").selectAll("span.tag").data(d => Object.keys(d.tags).map(t => d.tags[t]));
     trs.select("td.phrase-text").select("span.phrase-text-before")
        .text("...").style("display", d => Boolean(d.before)?"inline":"none").on("click", this.toggleBeforePhrase);
     trs.select("td.phrase-text").select("span.phrase-text-current").text(d => d.phrase);
     trs.select("td.phrase-text").select("span.phrase-text-after")
        .text("...").style("display", d => Boolean(d.after)?"inline":"none").on("click", this.toggleAfterPhrase);
     trs.select("td.phrase-match").text(d => (d.similarity*100).toFixed(2)+"%");

     var tagsEnt = tagsUpd.enter().append("span").classed("tag", true).classed("tag fas fa-square", true).style("margin","1px");
     tagsUpd.exit().remove();
     var allTags = tagsUpd.merge(tagsEnt)
               .style("color", d => [d.color].map(c => `rgb(${c[0]},${c[1]},${c[2]})`)[0]);

   };
   this.loadPagination = function(pages) {
     var pUpdate = d3.select(this.selector).select("div.phrase-pages").selectAll("span.phrase-page-container").data(pages, (d,i) => i+":"+d);
     var pEnter = pUpdate.enter().append("span").classed("phrase-page-container", true);
     pEnter.filter((d, i) => i>0).append("span").classed("phrase-page-sep", true).text(",")
     pEnter.append("span").classed("phrase-page", true)
                        .classed("phrase-page-selected", d => d)
                        .on("click", this.changePagination)
                        .html((d, i) => (i<10)?" "+i:i);

     var pExit = pUpdate.exit().remove();

     var containers = pUpdate.merge(pEnter).order();
     var fixed = 1
     var rolling = 10
     var selected = pages.indexOf(true);
     var limit = (selected < rolling)?rolling:((selected+rolling > pages.length -1)?(pages.length-1 - rolling):selected);

     containers.select("span.phrase-page")
                        .style("display", (d, i) => (i<fixed || Math.abs(i - limit)<rolling || i+fixed > pages.length-1)?"inline":"none")
     containers.select("span.phrase-page-sep")
                        .style("display", (d, i) => (i<fixed || Math.abs(i - limit)<rolling || i+fixed > pages.length-1)?"inline":"none")
                        .text((d, i) => (i-1 <fixed || i-1 + fixed > pages.length - 1 || Math.abs(i-1 - limit)<rolling)?",":"...")
   };
   this.changePagination = function(d, i, g) {
     if(!d) {
       thisGrid.loadPage(thisGrid.clusterId, i);
     }
   };
   this.toggleBeforePhrase = function(d, i, g) {
     var target = d3.select(this);
     if(target.text()==="...") target.text(d.before);
     else target.text("...");
   };
   this.toggleAfterPhrase = function(d, i, g) {
     var target = d3.select(this);
     if(target.text()==="...") target.text(d.after);
     else target.text("...");
   };
   this.tagPhrases = function(phrases) {
     var i = 0;
     var tagHierarchy = this.getTagHierarchy();
     phrases.map(phrase => {
       phrase.tags = {};
       var current = tagHierarchy;
       var stop = false;
       var steps = phrase.hierarchyId.split(",");
       var i = 0;
       while(i < steps.length && !stop) {
         if(typeof current[steps[i]] == "undefined") stop = true;
         else {
           if(typeof current["tags"] != "undefined") {
             current["tags"].forEach(tag => phrase.tags[tag] = this.tags[tag]);
           }
           current = current[steps[i]];
           i = i + 1;
         }
       }
     });
   };
/*   this.clusterOrder = function(a, b) {
     var i = 0, aStart = 0, aEnd = a.indexOf(","), bStart = 0, bEnd = b.indexOf(",");
     while(true) {
       if((aEnd = -1 || aEnd - aStart < 1) && (bEnd = -1 || bEnd - bStart < 1)) return 0;
       if(aEnd = -1 || aEnd - aStart < 1) return -1;
       if(bEnd = -1 || bEnd - bStart < 1) return 1;
       var aVal = parseInt(a.substring(aStart, aEnd);
       var bVal = parseInt(b.substring(bStart, bEnd);
       if(aVal<bVal) return -1;
       if(bVal<aVal) return 1;
       aStart = aEnd+1;
       bStart = bStart+1;
       aEnd = a.indexOf(",", aStart);
       bEnd = b.indexOf(",", bStart);
     }
   };*/
   this.getTagHierarchy = function() {
     var ret = {};
     Object.keys(this.tagsByClusters).forEach(taggedCluster => {
       var current = ret;
       path = "";
       taggedCluster.split(",").forEach(p => {
         if(typeof current[p] === "undefined") current[p] = {};
         path = path + (path.length==0?"":",")+p;
         if(path === taggedCluster) current["tags"]=tagsByClusters[taggedCluster];
         current = current[p];
       });
     });
     return ret;
   }

}

<commit_msg>bug fix on repeating phrase headers<commit_after>function PhraseGrid(selector, indexPath, phrasesPath, tagsByClusters, tags) {
  var thisGrid = this;

  this.selector = selector;
  this.indexPath = indexPath;
  this.phrasesPath = phrasesPath;
  this.tagsByClusters = tagsByClusters;
  this.tags = tags;

  this.index;
  this.clusterId;
  this.seeBeforePhrases = [];
  this.seeAfterPhrases = [];

  this.init = function(clusterId, callback) {
    d3.json(this.indexPath, function(error, index) {
      if(error){
        console.warn(error)
        if(typeof callback != "undefined") callback(null, "Cannot load index");
      } else {
           thisGrid.initTable();
           thisGrid.index = index;
           thisGrid.clusterId = clusterId;
           if(typeof clusterId != "undefined" && clusterId != null) thisGrid.loadPage(clusterId, 0, callback);
           else if(typeof callback != "undefined") callback(context, null);
        }
      })
    };

   this.initTable = function() {
     //Pagination
     var pUpdate = d3.select(this.selector).selectAll("div.phrase-pages").data([1]);
     var pEnter = pUpdate.enter().append("div").classed("phrase-pages", true);
     var pages = pUpdate.merge(pEnter);

     //Table
     var tUpdate = d3.select(this.selector).selectAll("table.phrase-table").data([1]);
     var tEnter = tUpdate.enter().append("table").classed("phrase-table", true);
     var table = tUpdate.merge(tEnter);
     var hRowUpdate = table.selectAll("tr.phrase-header").data([1]);
     var hRowEnter = hRowUpdate.enter().append("tr").classed("phrase-header", true);
     var hRow = hRowUpdate.merge(hRowEnter);
     var hUpdate = hRow.selectAll("th.phrase-header").data(["N°", "Tags",  "Phrase", "%match"]);
     var hEnter = hUpdate.enter().append("th").classed("phrase-header", true).text(d => d);
     var header = hUpdate.merge(hEnter);

   };

   this.loadPage = function(clusterId, page ,callback) {

     if(this.index[clusterId] && this.index[clusterId][page]) {
       this.clusterId = clusterId;
       this.seeBeforePhrases = [];
       this.seeAfterPhrases = [];
       //Pagination
       this.loadPagination(Object.keys(this.index[clusterId]).map(i => (parseInt(i)==page)?true:false));
       //Table
       d3.json(this.phrasesPath + "/" + this.index[clusterId][page] , function(error, phrases) {
         if(error){
           console.warn(error)
           if(typeof callback != "undefined") callback(null, "Cannot load phrases");
         } else {
              thisGrid.tagPhrases(phrases);
              thisGrid.loadPhrases(phrases);
              if(typeof callback != "undefined") callback(phrases, null);
           }
         });
        } else {
          if(typeof callback!="undefined")
            callback(null, "Cluster not found");
          else console.warn("Cannot found cluster to draw phrases")
        }
     };
   this.loadPhrases = function(phrases) {
     var trUpdate = d3.select(this.selector).select("table.phrase-table").selectAll("tr.phrase").data(phrases)
     var trEnter = trUpdate.enter().append("tr").classed("phrase", true);
     var trExit = trUpdate.exit().remove();
     var trs = trUpdate.merge(trEnter);

     trEnter.append("td").classed("phrase-nb phrase-cell", true);
     trEnter.append("td").classed("phrase-tags phrase-cell", true);
     var tdTextEnter = trEnter.append("td").classed("phrase-text phrase-cell", true);
     tdTextEnter.append("span").classed("phrase-text-before", true);
     tdTextEnter.append("span").classed("phrase-text-current", true);
     tdTextEnter.append("span").classed("phrase-text-after", true);
     trEnter.append("td").classed("phrase-match phrase-cell", true);

     trs.select("td.phrase-nb").text((d, i) => i);
     var tagsUpd = trs.select("td.phrase-tags").selectAll("span.tag").data(d => Object.keys(d.tags).map(t => d.tags[t]));
     trs.select("td.phrase-text").select("span.phrase-text-before")
        .text("...").style("display", d => Boolean(d.before)?"inline":"none").on("click", this.toggleBeforePhrase);
     trs.select("td.phrase-text").select("span.phrase-text-current").text(d => d.phrase);
     trs.select("td.phrase-text").select("span.phrase-text-after")
        .text("...").style("display", d => Boolean(d.after)?"inline":"none").on("click", this.toggleAfterPhrase);
     trs.select("td.phrase-match").text(d => (d.similarity*100).toFixed(2)+"%");

     var tagsEnt = tagsUpd.enter().append("span").classed("tag fas fa-square", true).style("margin","1px");
     tagsUpd.exit().remove();
     var allTags = tagsUpd.merge(tagsEnt)
               .style("color", d => [d.color].map(c => `rgb(${c[0]},${c[1]},${c[2]})`)[0]);

   };
   this.loadPagination = function(pages) {
     var pUpdate = d3.select(this.selector).select("div.phrase-pages").selectAll("span.phrase-page-container").data(pages, (d,i) => i+":"+d);
     var pEnter = pUpdate.enter().append("span").classed("phrase-page-container", true);
     pEnter.filter((d, i) => i>0).append("span").classed("phrase-page-sep", true).text(",")
     pEnter.append("span").classed("phrase-page", true)
                        .classed("phrase-page-selected", d => d)
                        .on("click", this.changePagination)
                        .html((d, i) => (i<10)?" "+i:i);

     var pExit = pUpdate.exit().remove();

     var containers = pUpdate.merge(pEnter).order();
     var fixed = 1
     var rolling = 10
     var selected = pages.indexOf(true);
     var limit = (selected < rolling)?rolling:((selected+rolling > pages.length -1)?(pages.length-1 - rolling):selected);

     containers.select("span.phrase-page")
                        .style("display", (d, i) => (i<fixed || Math.abs(i - limit)<rolling || i+fixed > pages.length-1)?"inline":"none")
     containers.select("span.phrase-page-sep")
                        .style("display", (d, i) => (i<fixed || Math.abs(i - limit)<rolling || i+fixed > pages.length-1)?"inline":"none")
                        .text((d, i) => (i-1 <fixed || i-1 + fixed > pages.length - 1 || Math.abs(i-1 - limit)<rolling)?",":"...")
   };
   this.changePagination = function(d, i, g) {
     if(!d) {
       thisGrid.loadPage(thisGrid.clusterId, i);
     }
   };
   this.toggleBeforePhrase = function(d, i, g) {
     var target = d3.select(this);
     if(target.text()==="...") target.text(d.before);
     else target.text("...");
   };
   this.toggleAfterPhrase = function(d, i, g) {
     var target = d3.select(this);
     if(target.text()==="...") target.text(d.after);
     else target.text("...");
   };
   this.tagPhrases = function(phrases) {
     var i = 0;
     var tagHierarchy = this.getTagHierarchy();
     phrases.map(phrase => {
       phrase.tags = {};
       var current = tagHierarchy;
       var stop = false;
       var steps = phrase.hierarchyId.split(",");
       var i = 0;
       while(i < steps.length && !stop) {
         if(typeof current[steps[i]] == "undefined") stop = true;
         else {
           if(typeof current["tags"] != "undefined") {
             current["tags"].forEach(tag => phrase.tags[tag] = this.tags[tag]);
           }
           current = current[steps[i]];
           i = i + 1;
         }
       }
     });
   };
/*   this.clusterOrder = function(a, b) {
     var i = 0, aStart = 0, aEnd = a.indexOf(","), bStart = 0, bEnd = b.indexOf(",");
     while(true) {
       if((aEnd = -1 || aEnd - aStart < 1) && (bEnd = -1 || bEnd - bStart < 1)) return 0;
       if(aEnd = -1 || aEnd - aStart < 1) return -1;
       if(bEnd = -1 || bEnd - bStart < 1) return 1;
       var aVal = parseInt(a.substring(aStart, aEnd);
       var bVal = parseInt(b.substring(bStart, bEnd);
       if(aVal<bVal) return -1;
       if(bVal<aVal) return 1;
       aStart = aEnd+1;
       bStart = bStart+1;
       aEnd = a.indexOf(",", aStart);
       bEnd = b.indexOf(",", bStart);
     }
   };*/
   this.getTagHierarchy = function() {
     var ret = {};
     Object.keys(this.tagsByClusters).forEach(taggedCluster => {
       var current = ret;
       path = "";
       taggedCluster.split(",").forEach(p => {
         if(typeof current[p] === "undefined") current[p] = {};
         path = path + (path.length==0?"":",")+p;
         if(path === taggedCluster) current["tags"]=tagsByClusters[taggedCluster];
         current = current[p];
       });
     });
     return ret;
   }

}

<|endoftext|>


<commit_before>const frix = require('frix');
const appRoot = require('app-root-path');
const gutil = require('gulp-util');
const shell = require('shelljs');
const optional = require('optional');
const gitconf = optional(`${appRoot}/gitconf.js`);

var pushTimeout;

module.exports = () => {
  frix.api.getOpt().root += 'frix/';
  frix.api.watchReRender((data) => {
    gutil.log(`${data.render.key} rendered`);
    if(gitconf) {
      let file = frix.api.getOpt().root + 'content/' +  frix.api.keys[data.render.key].content;
      shell.exec(`git add ${file} && git commit -m "${gitconf.message}"`);
      gutil.log(`auto commit ${file}`);
      if(pushTimeout) clearTimeout(pushTimeout);
      pushTimeout = setTimeout(() => {
        shell.exec(`git push https://${gitconf.user}:${gitconf.pass}@${gitconf.remote} --all`);
        gutil.log(`auto push to ${gitconf.remote}`);
      }, gitconf.timeout);
    }
  });
  return frix.render().then((requestHandler) => {
    // temporary workaround
    frix.api.requestHandler = requestHandler;
  });
};
<commit_msg>added name and email to gitconf<commit_after>const frix = require('frix');
const appRoot = require('app-root-path');
const gutil = require('gulp-util');
const shell = require('shelljs');
const optional = require('optional');
const gitconf = optional(`${appRoot}/gitconf.js`);

var pushTimeout;

module.exports = () => {
  frix.api.getOpt().root += 'frix/';
  frix.api.watchReRender((data) => {
    gutil.log(`${data.render.key} rendered`);
    if(gitconf) {
      let file = frix.api.getOpt().root + 'content/' +  frix.api.keys[data.render.key].content;
      shell.exec(`git add ${file} && git commit -c "user.name=${gitconf.name}" -c "user.email=${gitconf.email}" -m "${gitconf.message}"`);
      gutil.log(`auto commit ${file}`);
      if(pushTimeout) clearTimeout(pushTimeout);
      pushTimeout = setTimeout(() => {
        shell.exec(`git push https://${gitconf.user}:${gitconf.pass}@${gitconf.remote} --all`);
        gutil.log(`auto push to ${gitconf.remote}`);
      }, gitconf.timeout);
    }
  });
  return frix.render().then((requestHandler) => {
    // temporary workaround
    frix.api.requestHandler = requestHandler;
  });
};
<|endoftext|>


<commit_before>/*
 * Mapreduce Model
 */

define(['core/lib/date', 'core/models/program'],
  function (Datejs, Program) {

  var METRICS_PATHS = {
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/mappers/process.completion?count=30': 'mappersCompletion',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/reducers/process.completion?count=30': 'reducersCompletion',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/mappers/process.entries.in?aggregate=true': 'mappersEntriesIn',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/mappers/process.entries.out?aggregate=true': 'mappersEntriesOut',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/reducers/process.entries.in?aggregate=true': 'reducersEntriesIn',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/reducers/process.entries.out?aggregate=true': 'reducersEntriesOut'
  };

  var METRIC_TYPES = {
    'mappersCompletion': 'number',
    'reducersCompletion': 'number',
    'mappersEntriesIn': 'number',
    'mappersEntriesOut': 'number',
    'reducersEntriesIn': 'number',
    'reducersEntriesOut': 'number'
  };

  var EXPECTED_FIELDS = [
    'divId',
    'name',
    'description',
    'datasets',
    'inputDataSet',
    'outputDataSet'
  ];

  var Model = Program.extend({

    href: function () {
      return '#/mapreduce/' + this.get('id');
    }.property('id'),
    metricNames: null,
    instances: 0,
    type: 'Mapreduce',
    plural: 'Mapreduce',
    description: 'Mapreduce',
    startTime: null,

    init: function() {
      this._super();

      this.set('metricData', Em.Object.create({
        busyness: 0,
        mappersCompletion: 0,
        reducersCompletion: 0,
        mappersBytesProcessed: 0,
        mappersEntriesIn: 0,
        mappersEntriesOut: 0,
        reducersEntriesIn: 0,
        reducersEntriesOut: 0
      }));
      this.set('metricNames', {});

      this.set('app', this.get('app') || this.get('applicationId') || this.get('appId'));

      this.set('id', this.get('app') + ':' + this.get('name'));
      if (this.get('meta')) {
        this.set('startTime', this.get('meta').startTime);
      }

    },

    trackMetric: function (path, kind, label, interpolate) {

      path = this.interpolate(path);
      this.get(kind).set(C.Util.enc(path), Em.Object.create({
        path: path,
        value: label || [],
        interpolate: 'linear'
      }));
      return path;

    },

    getStartDate: function() {
      var time = parseInt(this.get('startTime'), 10);
      return new Date(time).toString('MMM d, yyyy');
    }.property('startTime'),

    getStartHours: function() {
      var time = parseInt(this.get('startTime'), 10);
      return new Date(time).toString('hh:mm tt');
    }.property('startTime'),

    addMetricName: function (name) {

      this.get('metricNames')[name] = 1;

    },

    setMetricData: function(name, value) {

      this.get('metricData').set(name, value);

    },

    /*
     * Runnable context path, used by user-defined metrics.
     */
    context: function () {

      return this.interpolate('apps/{parent}/mapreduce/{id}');

    }.property('app', 'name'),

    interpolate: function (path) {

      return path.replace(/\{parent\}/, this.get('app'))
        .replace(/\{id\}/, this.get('name'));

    },

    getMetricsRequest: function(http) {

      var appId = this.get('app');
      var jobId = this.get('name');
      var datasetId = this.get('inputDataSet');

      var paths = [];
      var pathMap = {};
      for (var path in METRICS_PATHS) {
        var url = new S(path).template({'appId': appId, 'jobId': jobId}).s;
        paths.push(url);
        pathMap[url] = METRICS_PATHS[path];
      }

      var self = this;

      http.post('metrics', paths, function(response, status) {

        if(!response.result) {
          return;
        }

        var result = response.result;
        var i = result.length, metric;

        while (i--) {

          metric = pathMap[result[i]['path']];

          if (metric) {

            if (result[i]['result']['data'] instanceof Array) {

              result[i]['result']['data'] = result[i]['result']['data'].map(function (entry) {
                return entry.value;
              });

              // Hax for current value of completion.
              if (metric === 'mappersCompletion' ||
                  metric === 'reducersCompletion') {

                var data = result[i]['result']['data'];

                self.setMetricData(metric, data[data.length - 1]);

              } else {

                self.setMetricData(metric, result[i]['result']['data']);

              }

            }
            else if (metric in METRIC_TYPES && METRIC_TYPES[metric] === 'number') {

              self.setMetricData(metric, C.Util.numberArrayToString(result[i]['result']['data']));

            } else {

              self.setMetricData(metric, result[i]['result']['data']);

            }

          }
          metric = null;
        }

      });

    },

    totalCompletion: function () {
      return (this.get('metricData.mappersCompletion') +
       this.get('metricData.reducersCompletion')) / 200;

    }.observes('metricData.mappersCompletion', 'metricData.reducersCompletion').property('metricData.mappersCompletion', 'metricData.reducersCompletion'),

    getMeta: function () {
      var arr = [];
      for (var m in this.meta) {
        arr.push({
          k: m,
          v: this.meta[m]
        });
      }
      return arr;
    }.property('meta'),

    truncatedName: function () {
      return this.get('name').substring(0,6) + '...';
    }.property('name'),

    startStopDisabled: function () {

      if (this.currentState !== 'STOPPED') {
        return true;
      }
      return false;

    }.property('currentState')

  });

  Model.reopenClass({
    type: 'Mapreduce',
    kind: 'Model',
    find: function(model_id, http) {
      var self = this;
      var promise = Ember.Deferred.create();

      var model_id = model_id.split(':');
      var app_id = model_id[0];
      var mapreduce_id = model_id[1];

      http.rest('apps', app_id, 'mapreduce', mapreduce_id, function (model, error) {

        var model = self.transformModel(model);
        model.app = app_id;
        model = C.Mapreduce.create(model);
        model.id = mapreduce_id;
        model.name = mapreduce_id;

        http.rest('apps', app_id, 'mapreduce', mapreduce_id, 'status', function (response) {

          if ($.isEmptyObject(response)) {
            promise.reject('Status could not retrieved.');
          } else {
            model.set('currentState', response.status);
            promise.resolve(model);
          }

        });

      });

      return promise;

    },

    transformModel: function (model) {

      var newModel = {};
      for (var i = EXPECTED_FIELDS.length - 1; i >= 0; i--) {
        newModel[EXPECTED_FIELDS[i]] = model[EXPECTED_FIELDS[i]];
      }
      if ('appId' in model || 'applicationId' in model) {
        newModel.appId = model.appId || model.applicationId;
      }
      return newModel;

    }
  });

  return Model;

});
<commit_msg>add correct interpolation<commit_after>/*
 * Mapreduce Model
 */

define(['core/lib/date', 'core/models/program'],
  function (Datejs, Program) {

  var METRICS_PATHS = {
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/mappers/process.completion?count=30': 'mappersCompletion',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/reducers/process.completion?count=30': 'reducersCompletion',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/mappers/process.entries.in?aggregate=true': 'mappersEntriesIn',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/mappers/process.entries.out?aggregate=true': 'mappersEntriesOut',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/reducers/process.entries.in?aggregate=true': 'reducersEntriesIn',
    '/reactor/apps/{{appId}}/mapreduce/{{jobId}}/reducers/process.entries.out?aggregate=true': 'reducersEntriesOut'
  };

  var METRIC_TYPES = {
    'mappersCompletion': 'number',
    'reducersCompletion': 'number',
    'mappersEntriesIn': 'number',
    'mappersEntriesOut': 'number',
    'reducersEntriesIn': 'number',
    'reducersEntriesOut': 'number'
  };

  var EXPECTED_FIELDS = [
    'divId',
    'name',
    'description',
    'datasets',
    'inputDataSet',
    'outputDataSet'
  ];

  var Model = Program.extend({

    href: function () {
      return '#/mapreduce/' + this.get('id');
    }.property('id'),
    metricNames: null,
    instances: 0,
    type: 'Mapreduce',
    plural: 'Mapreduce',
    description: 'Mapreduce',
    startTime: null,

    init: function() {
      this._super();

      this.set('metricData', Em.Object.create({
        busyness: 0,
        mappersCompletion: 0,
        reducersCompletion: 0,
        mappersBytesProcessed: 0,
        mappersEntriesIn: 0,
        mappersEntriesOut: 0,
        reducersEntriesIn: 0,
        reducersEntriesOut: 0
      }));
      this.set('metricNames', {});

      this.set('app', this.get('app') || this.get('applicationId') || this.get('appId'));

      this.set('id', this.get('app') + ':' + this.get('name'));
      if (this.get('meta')) {
        this.set('startTime', this.get('meta').startTime);
      }

    },

    trackMetric: function (path, kind, label, interpolate) {

      path = this.interpolate(path);
      this.get(kind).set(C.Util.enc(path), Em.Object.create({
        path: path,
        value: label || [],
        interpolate: 'linear&maxInterpolateGap=3',
      }));
      return path;

    },

    getStartDate: function() {
      var time = parseInt(this.get('startTime'), 10);
      return new Date(time).toString('MMM d, yyyy');
    }.property('startTime'),

    getStartHours: function() {
      var time = parseInt(this.get('startTime'), 10);
      return new Date(time).toString('hh:mm tt');
    }.property('startTime'),

    addMetricName: function (name) {

      this.get('metricNames')[name] = 1;

    },

    setMetricData: function(name, value) {

      this.get('metricData').set(name, value);

    },

    /*
     * Runnable context path, used by user-defined metrics.
     */
    context: function () {

      return this.interpolate('apps/{parent}/mapreduce/{id}');

    }.property('app', 'name'),

    interpolate: function (path) {

      return path.replace(/\{parent\}/, this.get('app'))
        .replace(/\{id\}/, this.get('name'));

    },

    getMetricsRequest: function(http) {

      var appId = this.get('app');
      var jobId = this.get('name');
      var datasetId = this.get('inputDataSet');

      var paths = [];
      var pathMap = {};
      for (var path in METRICS_PATHS) {
        var url = new S(path).template({'appId': appId, 'jobId': jobId}).s;
        paths.push(url);
        pathMap[url] = METRICS_PATHS[path];
      }

      var self = this;

      http.post('metrics', paths, function(response, status) {

        if(!response.result) {
          return;
        }

        var result = response.result;
        var i = result.length, metric;

        while (i--) {

          metric = pathMap[result[i]['path']];

          if (metric) {

            if (result[i]['result']['data'] instanceof Array) {

              result[i]['result']['data'] = result[i]['result']['data'].map(function (entry) {
                return entry.value;
              });

              // Hax for current value of completion.
              if (metric === 'mappersCompletion' ||
                  metric === 'reducersCompletion') {

                var data = result[i]['result']['data'];

                self.setMetricData(metric, data[data.length - 1]);

              } else {

                self.setMetricData(metric, result[i]['result']['data']);

              }

            }
            else if (metric in METRIC_TYPES && METRIC_TYPES[metric] === 'number') {

              self.setMetricData(metric, C.Util.numberArrayToString(result[i]['result']['data']));

            } else {

              self.setMetricData(metric, result[i]['result']['data']);

            }

          }
          metric = null;
        }

      });

    },

    totalCompletion: function () {
      return (this.get('metricData.mappersCompletion') +
       this.get('metricData.reducersCompletion')) / 200;

    }.observes('metricData.mappersCompletion', 'metricData.reducersCompletion').property('metricData.mappersCompletion', 'metricData.reducersCompletion'),

    getMeta: function () {
      var arr = [];
      for (var m in this.meta) {
        arr.push({
          k: m,
          v: this.meta[m]
        });
      }
      return arr;
    }.property('meta'),

    truncatedName: function () {
      return this.get('name').substring(0,6) + '...';
    }.property('name'),

    startStopDisabled: function () {

      if (this.currentState !== 'STOPPED') {
        return true;
      }
      return false;

    }.property('currentState')

  });

  Model.reopenClass({
    type: 'Mapreduce',
    kind: 'Model',
    find: function(model_id, http) {
      var self = this;
      var promise = Ember.Deferred.create();

      var model_id = model_id.split(':');
      var app_id = model_id[0];
      var mapreduce_id = model_id[1];

      http.rest('apps', app_id, 'mapreduce', mapreduce_id, function (model, error) {

        var model = self.transformModel(model);
        model.app = app_id;
        model = C.Mapreduce.create(model);
        model.id = mapreduce_id;
        model.name = mapreduce_id;

        http.rest('apps', app_id, 'mapreduce', mapreduce_id, 'status', function (response) {

          if ($.isEmptyObject(response)) {
            promise.reject('Status could not retrieved.');
          } else {
            model.set('currentState', response.status);
            promise.resolve(model);
          }

        });

      });

      return promise;

    },

    transformModel: function (model) {

      var newModel = {};
      for (var i = EXPECTED_FIELDS.length - 1; i >= 0; i--) {
        newModel[EXPECTED_FIELDS[i]] = model[EXPECTED_FIELDS[i]];
      }
      if ('appId' in model || 'applicationId' in model) {
        newModel.appId = model.appId || model.applicationId;
      }
      return newModel;

    }
  });

  return Model;

});
<|endoftext|>


<commit_before>const boilerplates = readDirFiles('./boilerplate/')
Object.keys(boilerplates).forEach(key => {
  const val = boilerplates[key]
  boilerplates[key] = o => val.replace(/\$\{(\w+)\}/g, (_, g1) => o[g1])
})

module.exports = {
  boilerplate: {
    // where to place generated components
    dir: 'src/components',
    files: boilerplates,
    // prefix of the tag of a component
    prefix: 'c'
  },

  md2vue: {
    // globs identifying those `.md` files
    // to be transformed into `.vue`
    globs: [
      'src/components/**/index.md',
      'docs/content/**/*.md'
    ],
    // where to write `.vue`
    output: 'docs/pages',
    vueTools (name, uid) {
      return `<input id="${uid}" type="checkbox" /><label for="${uid}"></label>`
    }
  },

  rollup: {
    name: 'Clair',
    input: 'src/js/entry.js',
    output: [
      {
        format: 'umd',
        file: 'dist/clair.js'
      },
      {
        format: 'es',
        file: 'dist/clair.esm.js'
      },
      {
        format: 'cjs',
        file: 'dist/clair.common.js'
      }
    ],

    plugins: [
      installVueComps({
        entry: 'src/js/entry.js',
        vues: 'src/components/**/!(_)*.vue'
      }),
      require('rollup-plugin-node-resolve')({
        jsnext: true,
        main: true
      }),
      require('rollup-plugin-commonjs')(),
      require('rollup-plugin-vue')(),
      require('rollup-plugin-postcss')({
        plugins: [
          require('postcss-import')(),
          require('postcss-for')(),
          require('postcss-cssnext')({
            warnForDuplicates: false
          })
        ],
        extract: 'dist/clair.css'
      }),
      require('rollup-plugin-buble')()
    ]
  },

  nuxt: {
    srcDir: 'docs',
    generate: {
      dir: '.site',
      // avoid error with pre/code
      minify: false
    },
    loading: {
      color: '#56bf8b',
      duration: 3000
    },
    router: {
      linkExactActiveClass: 'is-active'
    },
    head: {
      meta: [
        {
          charset: 'utf-8'
        },
        {
          name: 'viewport',
          content: 'width=device-width, initial-scale=1'
        },
        {
          hid: 'description',
          name: 'description',
          content: 'Clair Design，一套包含设计规范、Vue 组件和配套资源的设计系统。'
        }
      ],
      link: [
        {
          href: 'https://lib.baomitu.com/font-awesome/4.7.0/css/font-awesome.min.css',
          rel: 'stylesheet'
        }
      ]
    },
    plugins: [
      '~plugins/clair.js',
      '~plugins/style.js'
    ],
    modules: ['@nuxtjs/workbox'],
    build: {
      extractCSS: true,
      publicPath: '/static/',
      postcss: [
        require('postcss-import')(),
        require('postcss-for')(),
        require('postcss-cssnext')({
          warnForDuplicates: false
        })
      ]
    }
  }
}

function installVueComps ({ entry, vues }) {
  const path = require('path')
  const mainId = path.resolve(__dirname, entry)

  return { transform }

  function transform (source, id) {
    if (id !== mainId) return

    const components = require('glob')
      .sync(vues)
      .map(file => path.relative('src/js', file))
      .map(file => {
        const { name, dir } = path.parse(file)
        const componentName = name === 'index' ? path.basename(dir) : name
        return {
          path: file.replace(/\\/g, '/'),
          comp: pascalCase(componentName),
          name: componentName
        }
      })

    return `${source}
${components.map(({ path, comp }) => `import ${comp} from '${path}'`).join('\n')}

export default {
  install (Vue) {
    main.install(Vue)
    const comps = [${components.map(c => c.comp).join(', ')}]
    comps.forEach(comp => comp.name && Vue.component(comp.name, comp))
  }
}
`
  }

  function pascalCase (name) {
    return name
      .replace(/-([0-9a-zA-Z])/g, (m, g1) => g1.toUpperCase())
      .replace(/^[a-z]/, m => m.toUpperCase())
  }
}

/* eslint-disable no-param-reassign */
function readDirFiles (dir, encoding, recursive) {
  const fs = require('fs')
  const path = require('path')

  const result = {}

  if (typeof encoding === 'boolean') {
    recursive = encoding
    encoding = null
  }
  typeof recursive === 'undefined' && (recursive = true)
  typeof encoding === 'string' || (encoding = null)

  const entries = fs.readdirSync(dir)

  entries.forEach(function (entry) {
    const entryPath = path.join(dir, entry)
    if (fs.statSync(entryPath).isDirectory()) {
      return recursive && (result[entry] = readDirFiles(entryPath, encoding))
    }

    result[entry] = fs.readFileSync(entryPath, encoding).toString()
  })
  return result
}
<commit_msg>chore(docs): add custom tool for demo blocks<commit_after>const boilerplates = readDirFiles('./boilerplate/')
Object.keys(boilerplates).forEach(key => {
  const val = boilerplates[key]
  boilerplates[key] = o => val.replace(/\$\{(\w+)\}/g, (_, g1) => o[g1])
})

module.exports = {
  boilerplate: {
    // where to place generated components
    dir: 'src/components',
    files: boilerplates,
    // prefix of the tag of a component
    prefix: 'c'
  },

  md2vue: {
    // globs identifying those `.md` files
    // to be transformed into `.vue`
    globs: [
      'src/components/**/index.md',
      'docs/content/**/*.md'
    ],
    // where to write `.vue`
    output: 'docs/pages',
    vueTools (name, uid) {
      return `<input id="${uid}" type="checkbox" /><label for="${uid}"></label><c-run-online uid="${uid}"/>`
    }
  },

  rollup: {
    name: 'Clair',
    input: 'src/js/entry.js',
    output: [
      {
        format: 'umd',
        file: 'dist/clair.js'
      },
      {
        format: 'es',
        file: 'dist/clair.esm.js'
      },
      {
        format: 'cjs',
        file: 'dist/clair.common.js'
      }
    ],

    plugins: [
      installVueComps({
        entry: 'src/js/entry.js',
        vues: 'src/components/**/!(_)*.vue'
      }),
      require('rollup-plugin-node-resolve')({
        jsnext: true,
        main: true
      }),
      require('rollup-plugin-commonjs')(),
      require('rollup-plugin-vue')(),
      require('rollup-plugin-postcss')({
        plugins: [
          require('postcss-import')(),
          require('postcss-for')(),
          require('postcss-cssnext')({
            warnForDuplicates: false
          })
        ],
        extract: 'dist/clair.css'
      }),
      require('rollup-plugin-buble')()
    ]
  },

  nuxt: {
    srcDir: 'docs',
    generate: {
      dir: '.site',
      // avoid error with pre/code
      minify: false
    },
    loading: {
      color: '#56bf8b',
      duration: 3000
    },
    router: {
      linkExactActiveClass: 'is-active'
    },
    head: {
      meta: [
        {
          charset: 'utf-8'
        },
        {
          name: 'viewport',
          content: 'width=device-width, initial-scale=1'
        },
        {
          hid: 'description',
          name: 'description',
          content: 'Clair Design，一套包含设计规范、Vue 组件和配套资源的设计系统。'
        }
      ],
      link: [
        {
          href: 'https://lib.baomitu.com/font-awesome/4.7.0/css/font-awesome.min.css',
          rel: 'stylesheet'
        }
      ]
    },
    plugins: [
      '~plugins/clair.js',
      '~plugins/style.js'
    ],
    modules: ['@nuxtjs/workbox'],
    build: {
      extractCSS: true,
      publicPath: '/static/',
      postcss: [
        require('postcss-import')(),
        require('postcss-for')(),
        require('postcss-cssnext')({
          warnForDuplicates: false
        })
      ]
    }
  }
}

function installVueComps ({ entry, vues }) {
  const path = require('path')
  const mainId = path.resolve(__dirname, entry)

  return { transform }

  function transform (source, id) {
    if (id !== mainId) return

    const components = require('glob')
      .sync(vues)
      .map(file => path.relative('src/js', file))
      .map(file => {
        const { name, dir } = path.parse(file)
        const componentName = name === 'index' ? path.basename(dir) : name
        return {
          path: file.replace(/\\/g, '/'),
          comp: pascalCase(componentName),
          name: componentName
        }
      })

    return `${source}
${components.map(({ path, comp }) => `import ${comp} from '${path}'`).join('\n')}

export default {
  install (Vue) {
    main.install(Vue)
    const comps = [${components.map(c => c.comp).join(', ')}]
    comps.forEach(comp => comp.name && Vue.component(comp.name, comp))
  }
}
`
  }

  function pascalCase (name) {
    return name
      .replace(/-([0-9a-zA-Z])/g, (m, g1) => g1.toUpperCase())
      .replace(/^[a-z]/, m => m.toUpperCase())
  }
}

/* eslint-disable no-param-reassign */
function readDirFiles (dir, encoding, recursive) {
  const fs = require('fs')
  const path = require('path')

  const result = {}

  if (typeof encoding === 'boolean') {
    recursive = encoding
    encoding = null
  }
  typeof recursive === 'undefined' && (recursive = true)
  typeof encoding === 'string' || (encoding = null)

  const entries = fs.readdirSync(dir)

  entries.forEach(function (entry) {
    const entryPath = path.join(dir, entry)
    if (fs.statSync(entryPath).isDirectory()) {
      return recursive && (result[entry] = readDirFiles(entryPath, encoding))
    }

    result[entry] = fs.readFileSync(entryPath, encoding).toString()
  })
  return result
}
<|endoftext|>


<commit_before>require("../loader");

var fs = require("fs");
var path = require("path");
var util = require("util");
var parser = require("test262-parser");

Error.stackTraceLimit = 5;

var printed = [];

function print(a) {
    Assert(typeof a === "string");
    printed.push(a);
}

function console_log() {
    var a = Array.prototype.map.call(arguments, e => ToString(e));
    console.log.apply(console, a);
}

function createRealm() {
    var realm = CreateRealm();
    SetRealmGlobalObject(realm);
    var globalObj = SetDefaultGlobalBindings(realm);
    customize_global_object(realm, globalObj);
    return Get(globalObj, "$262");
}

function detachArrayBuffer(a) {
    DetachArrayBuffer(a);
}

function evalScript(sourceText) {
    Assert(typeof sourceText === 'string');
    var hostDefined = undefined;
    var realm = currentRealm;
    var s = ParseScript(sourceText, realm, hostDefined);
    if (Array.isArray(s)) {
        var error = s[0];
        throw Completion({ Type: 'throw', Value: error, Target: empty });
    }
    var status = ScriptEvaluation(s);
    return status;
}

function customize_global_object(realm, global) {
    var intrinsics = realm.Intrinsics;
    var console, obj262, agent;
    CreateDataProperty(global, `console`, console = ObjectCreate(intrinsics['%ObjectPrototype%']));
    CreateMethodProperty(console, `log`, CreateBuiltinFunction(currentRealm, console_log, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(global, `print`, CreateBuiltinFunction(currentRealm, print, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(global, `$262`, obj262 = ObjectCreate(intrinsics['%ObjectPrototype%']));
    CreateMethodProperty(obj262, `createRealm`, CreateBuiltinFunction(currentRealm, createRealm, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(obj262, `detachArrayBuffer`, CreateBuiltinFunction(currentRealm, detachArrayBuffer, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(obj262, `evalScript`, CreateBuiltinFunction(currentRealm, evalScript, intrinsics['%FunctionPrototype%']));
    CreateDataProperty(obj262, `global`, global);
    CreateDataProperty(obj262, `agent`, agent = ObjectCreate(intrinsics['%ObjectPrototype%']));
    //TODO implement agent
}

var test262_dir = path.join(__dirname, "../../test262");
var assert_src = fs.readFileSync(path.join(test262_dir, "harness/assert.js"), "utf8");
var sta_src = fs.readFileSync(path.join(test262_dir, "harness/sta.js"), "utf8");
var dpH_src = fs.readFileSync(path.join(test262_dir, "harness/doneprintHandle.js"), "utf8");
var current_dirname;
var total = 0;
var heavy = 0;
var failure = 0;
var exception = [];
var failed_tests = [];

function test_do(src, spec) {
    total++;
    var errors;
    HostReportErrors = function(errorList) {
        errors = errorList;
    };
    var module_cache = {};
    HostResolveImportedModule = function(referencingModule, specifier) {
        if (module_cache[specifier]) return module_cache[specifier];
        var sourceText = fs.readFileSync(path.join(current_dirname, specifier), "utf8");
        var realm = referencingModule.Realm;
        var m = ParseModule(sourceText, realm);
        if (Array.isArray(m)) {
            var error = m[0];
            throw Completion({ Type: 'throw', Value: error, Target: empty });
        }
        module_cache[specifier] = m;
        return module_cache[specifier];
    };
    var entries = [
        { sourceText: assert_src },
        { sourceText: sta_src },
    ];
    if (spec.flags.async) {
        printed = [];
        entries.push({ sourceText: dpH_src });
    }
    for (var inc of spec.includes) {
        var inc_src = fs.readFileSync(path.join(test262_dir, "harness", inc), "utf8");
        entries.push({ sourceText: inc_src });
    }
    if (!spec.flags.module) {
        entries.push({ sourceText: src, isModule: false });
    } else {
        entries.push({ sourceText: `import "./${spec.basename}" `, isModule: true });
    }
    InitializeHostDefinedRealm(entries, customize_global_object);
    if (spec.flags.async) {
        var completed = printed.some(p => p === 'Test262:AsyncTestComplete');
        if (!completed) errors = printed;
    }
    if (!spec.negative && !errors) return true;
    if (spec.negative && errors && Type(errors[0]) === 'Object') {
        var c = Get(errors[0], "constructor");
        if (c && Get(c, "name") === spec.negative.type) return true;
    }
    if (errors) {
        if (Type(errors[0]) === 'Object') console.log(Get(errors[0], "name"), Get(errors[0], "message"));
        else console.log(errors[0]);
    }
    failure++;
    return false;
}

function test_file(pathname) {
    if (pathname.endsWith("_FIXTURE.js")) return;
    for (var testname of heavy_tests) {
        if (pathname.endsWith(testname)) return;
    }

    // unspportd new features
    if (pathname.indexOf("/SharedArrayBuffer/") > 0) return;
    if (pathname.indexOf("/Atomics/") > 0) return;
    if (pathname.indexOf("/Object/entries/") > 0) return;
    if (pathname.indexOf("/Object/getOwnPropertyDescriptors/") > 0) return;
    if (pathname.indexOf("/Object/values/") > 0) return;
    if (pathname.indexOf("/String/prototype/padEnd/") > 0) return;
    if (pathname.indexOf("/String/prototype/padStart/") > 0) return;
    if (pathname.match(/[-\/]trailing-comma[-.]/)) return;
    if (pathname.match(/[-\/]await-module[-.]/)) return;
    if (pathname.match(/\/async-/)) return;

    current_dirname = path.dirname(pathname);
    var src = fs.readFileSync(pathname, "utf8");
    var file = { contents: src };
    parser.parseFile(file);
    var spec = file.attrs;
    spec.basename = path.basename(pathname);
    if (!spec.features) spec.features = [];

    if (spec.esid === "pending") return; // unsupported
    if (spec.features.contains("object-spread")) return; // unsupported
    if (spec.features.contains("object-rest")) return; // unsupported
    if (spec.features.contains("caller")) return; // unsupported
    if (spec.features.contains("SharedArrayBuffer")) return; // unsupported
    if (spec.features.contains("async-functions")) return; // unsupported
    if (spec.features.contains("async-iteration")) return; // unsupported

    console.log(pathname);
    if (spec.negative) {
        if (spec.negative.phase === "early" && !spec.flags.raw) {
            src = "throw 'no early error occurred';\n" + src;
        }
    }
    var begin = Date.now();
    var f = true;
    try {
        if (!spec.flags.onlyStrict || spec.flags.module) {
            f &= test_do(src, spec);
        }
        if (!spec.flags.noStrict && !spec.flags.raw && !spec.flags.module) {
            f &= test_do('"use strict";\n' + src, spec);
        }
    } catch (e) {
        exception.push(pathname);
        console.log(e);
        execution_context_stack.length = 0;
    }
    if (!f) failed_tests.push(pathname);
    var elapsed = Date.now() - begin;
    if (elapsed > 10000) {
        heavy++;
        console.log("elapsed", elapsed);
    }
}

function test_dir(pathname) {
    if (pathname[0] !== '/' && pathname[0] !== '.') {
        var org_pathname = pathname;
        pathname = path.join(test262_dir, "test", org_pathname);
        if (!fs.existsSync(pathname)) {
            pathname = path.join(test262_dir, "test", "built-ins", org_pathname);
        }
    }
    if (/\.js$/.test(pathname)) {
        return test_file(pathname);
    }
    try {
        var files = fs.readdirSync(pathname);
    } catch (e) {
        console.log("skip:", pathname);
        return;
    }
    for (var f of files) {
        test_dir(path.join(pathname, f));
    }
}

const heavy_tests = [
    "/S7.4_A5.js",
    "/S7.4_A6.js",
    "/S7.8.5_A1.1_T2.js",
    "/S7.8.5_A1.4_T2.js",
    "/S7.8.5_A2.1_T2.js",
    "/S7.8.5_A2.4_T2.js",
    "/S15.1.2.2_A8.js",
    "/S15.1.2.3_A6.js",
    "/S15.1.3.1_A1.10_T1.js",
    "/S15.1.3.1_A1.11_T1.js",
    "/S15.1.3.1_A1.11_T2.js",
    "/S15.1.3.1_A1.12_T1.js",
    "/S15.1.3.1_A1.12_T2.js",
    "/S15.1.3.1_A1.12_T3.js",
    "/S15.1.3.1_A1.2_T1.js",
    "/S15.1.3.1_A1.2_T2.js",
    "/S15.1.3.1_A2.1_T1.js",
    "/S15.1.3.1_A2.4_T1.js",
    "/S15.1.3.1_A2.5_T1.js",
    "/S15.1.3.2_A1.10_T1.js",
    "/S15.1.3.2_A1.11_T1.js",
    "/S15.1.3.2_A1.11_T2.js",
    "/S15.1.3.2_A1.12_T1.js",
    "/S15.1.3.2_A1.12_T2.js",
    "/S15.1.3.2_A1.12_T3.js",
    "/S15.1.3.2_A1.2_T1.js",
    "/S15.1.3.2_A1.2_T2.js",
    "/S15.1.3.2_A2.1_T1.js",
    "/S15.1.3.2_A2.4_T1.js",
    "/S15.1.3.2_A2.5_T1.js",
    "/S15.1.3.3_A1.3_T1.js",
    "/S15.1.3.3_A2.3_T1.js",
    "/S15.1.3.3_A2.4_T1.js",
    "/S15.1.3.3_A2.4_T2.js",
    "/S15.1.3.3_A2.5_T1.js",
    "/S15.1.3.4_A1.3_T1.js",
    "/S15.1.3.4_A2.3_T1.js",
    "/S15.1.3.4_A2.4_T1.js",
    "/S15.1.3.4_A2.4_T2.js",
    "/S15.1.3.4_A2.5_T1.js",
    "/S15.4.5.2_A3_T4.js",
    "/S15.10.2.12_A3_T1.js",
    "/S15.10.2.12_A4_T1.js",
    "/S15.10.2.12_A5_T1.js",
    "/S15.10.2.12_A6_T1.js",
    "/Array.prototype.concat_large-typed-array.js",
];

for (var i = 2; i < process.argv.length; i++) {
    test_dir(process.argv[i]);
}

if (failed_tests.length) console.log("FAILED TESTS:\n" + failed_tests.join('\n'));
if (exception.length) console.log("EXCEPTION THROWN TESTS:\n" + exception.join('\n'));
if (heavy) console.log("heavy", heavy);
if (failure) console.log("failure", failure);
if (exception.length) console.log("exception", exception.length);
console.log("total", total);

if (failure || exception.length) process.exit(1)
<commit_msg>enhance test262<commit_after>require("../loader");

var fs = require("fs");
var path = require("path");
var util = require("util");
var parser = require("test262-parser");

Error.stackTraceLimit = 5;

var printed = [];

function print(a) {
    Assert(typeof a === "string");
    printed.push(a);
}

function console_log() {
    var a = Array.prototype.map.call(arguments, e => ToString(e));
    console.log.apply(console, a);
}

function createRealm() {
    var realm = CreateRealm();
    SetRealmGlobalObject(realm);
    var globalObj = SetDefaultGlobalBindings(realm);
    customize_global_object(realm, globalObj);
    return Get(globalObj, "$262");
}

function detachArrayBuffer(a) {
    DetachArrayBuffer(a);
}

function evalScript(sourceText) {
    Assert(typeof sourceText === 'string');
    var hostDefined = undefined;
    var realm = currentRealm;
    var s = ParseScript(sourceText, realm, hostDefined);
    if (Array.isArray(s)) {
        var error = s[0];
        throw Completion({ Type: 'throw', Value: error, Target: empty });
    }
    var status = ScriptEvaluation(s);
    return status;
}

function customize_global_object(realm, global) {
    var intrinsics = realm.Intrinsics;
    var console, obj262, agent;
    CreateDataProperty(global, `console`, console = ObjectCreate(intrinsics['%ObjectPrototype%']));
    CreateMethodProperty(console, `log`, CreateBuiltinFunction(currentRealm, console_log, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(global, `print`, CreateBuiltinFunction(currentRealm, print, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(global, `$262`, obj262 = ObjectCreate(intrinsics['%ObjectPrototype%']));
    CreateMethodProperty(obj262, `createRealm`, CreateBuiltinFunction(currentRealm, createRealm, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(obj262, `detachArrayBuffer`, CreateBuiltinFunction(currentRealm, detachArrayBuffer, intrinsics['%FunctionPrototype%']));
    CreateMethodProperty(obj262, `evalScript`, CreateBuiltinFunction(currentRealm, evalScript, intrinsics['%FunctionPrototype%']));
    CreateDataProperty(obj262, `global`, global);
    CreateDataProperty(obj262, `agent`, agent = ObjectCreate(intrinsics['%ObjectPrototype%']));
    //TODO implement agent
}

var test262_dir = path.join(__dirname, "../../test262");
var assert_src = fs.readFileSync(path.join(test262_dir, "harness/assert.js"), "utf8");
var sta_src = fs.readFileSync(path.join(test262_dir, "harness/sta.js"), "utf8");
var dpH_src = fs.readFileSync(path.join(test262_dir, "harness/doneprintHandle.js"), "utf8");
var current_dirname;
var total = 0;
var heavy = 0;
var failure = 0;
var exception = [];
var failed_tests = [];

function test_do(src, spec) {
    total++;
    var errors;
    HostReportErrors = function(errorList) {
        errors = errorList;
    };
    var module_cache = {};
    HostResolveImportedModule = function(referencingModule, specifier) {
        if (module_cache[specifier]) return module_cache[specifier];
        var sourceText = fs.readFileSync(path.join(current_dirname, specifier), "utf8");
        var realm = referencingModule.Realm;
        var m = ParseModule(sourceText, realm);
        if (Array.isArray(m)) {
            var error = m[0];
            throw Completion({ Type: 'throw', Value: error, Target: empty });
        }
        module_cache[specifier] = m;
        return module_cache[specifier];
    };
    var entries = [
        { sourceText: assert_src },
        { sourceText: sta_src },
    ];
    if (spec.flags.async) {
        printed = [];
        entries.push({ sourceText: dpH_src });
    }
    for (var inc of spec.includes) {
        var inc_src = fs.readFileSync(path.join(test262_dir, "harness", inc), "utf8");
        entries.push({ sourceText: inc_src });
    }
    if (!spec.flags.module) {
        entries.push({ sourceText: src, isModule: false });
    } else {
        entries.push({ sourceText: `import "./${spec.basename}" `, isModule: true });
    }
    InitializeHostDefinedRealm(entries, customize_global_object);
    if (spec.flags.async) {
        var completed = printed.some(p => p === 'Test262:AsyncTestComplete');
        if (!completed) errors = printed;
    }
    if (!spec.negative && !errors) return true;
    if (spec.negative && errors && Type(errors[0]) === 'Object') {
        var c = Get(errors[0], "constructor");
        if (c && Get(c, "name") === spec.negative.type) return true;
    }
    if (errors) {
        if (Type(errors[0]) === 'Object') console.log(Get(errors[0], "name"), Get(errors[0], "message"));
        else console.log(errors[0]);
    }
    failure++;
    return false;
}

function test_file(pathname) {
    if (pathname.endsWith("_FIXTURE.js")) return;
    for (var testname of heavy_tests) {
        if (pathname.endsWith(testname)) return;
    }

    // unspportd new features
    if (pathname.indexOf("/SharedArrayBuffer/") > 0) return;
    if (pathname.indexOf("/Atomics/") > 0) return;
    if (pathname.indexOf("/Object/entries/") > 0) return;
    if (pathname.indexOf("/Object/getOwnPropertyDescriptors/") > 0) return;
    if (pathname.indexOf("/Object/values/") > 0) return;
    if (pathname.indexOf("/String/prototype/padEnd/") > 0) return;
    if (pathname.indexOf("/String/prototype/padStart/") > 0) return;
    if (pathname.indexOf("/RegExp/prototype/dotAll/") > 0) return;
    if (pathname.indexOf("/RegExp/property-escapes/") > 0) return;
    if (pathname.indexOf("/RegExp/named-groups/") > 0) return;
    if (pathname.indexOf("/RegExp/lookBehind/") > 0) return;
    if (pathname.indexOf("/RegExp/dotall/") > 0) return;
    if (pathname.match(/[-\/]trailing-comma[-.]/)) return;
    if (pathname.match(/[-\/]await-module[-.]/)) return;
    if (pathname.match(/\/async-/)) return;

    current_dirname = path.dirname(pathname);
    var src = fs.readFileSync(pathname, "utf8");
    var file = { contents: src };
    parser.parseFile(file);
    var spec = file.attrs;
    spec.basename = path.basename(pathname);
    if (!spec.features) spec.features = [];

    // unspportd new features
    if (spec.esid === "pending") return;
    if (spec.features.contains("object-spread")) return;
    if (spec.features.contains("object-rest")) return;
    if (spec.features.contains("caller")) return;
    if (spec.features.contains("SharedArrayBuffer")) return;
    if (spec.features.contains("async-functions")) return;
    if (spec.features.contains("async-iteration")) return;

    console.log(pathname);
    if (spec.negative) {
        if (spec.negative.phase === "early" && !spec.flags.raw) {
            src = "throw 'no early error occurred';\n" + src;
        }
    }
    var begin = Date.now();
    var f = true;
    try {
        if (!spec.flags.onlyStrict || spec.flags.module) {
            f &= test_do(src, spec);
        }
        if (!spec.flags.noStrict && !spec.flags.raw && !spec.flags.module) {
            f &= test_do('"use strict";\n' + src, spec);
        }
    } catch (e) {
        exception.push(pathname);
        console.log(e);
        execution_context_stack.length = 0;
    }
    if (!f) failed_tests.push(pathname);
    var elapsed = Date.now() - begin;
    if (elapsed > 10000) {
        heavy++;
        console.log("elapsed", elapsed);
    }
}

function test_dir(pathname) {
    if (pathname[0] !== '/' && pathname[0] !== '.') {
        var org_pathname = pathname;
        pathname = path.join(test262_dir, "test", org_pathname);
        if (!fs.existsSync(pathname)) {
            pathname = path.join(test262_dir, "test", "built-ins", org_pathname);
        }
    }
    if (/\.js$/.test(pathname)) {
        return test_file(pathname);
    }
    try {
        var files = fs.readdirSync(pathname);
    } catch (e) {
        console.log("skip:", pathname);
        return;
    }
    for (var f of files) {
        test_dir(path.join(pathname, f));
    }
}

const heavy_tests = [
    "/S7.4_A5.js",
    "/S7.4_A6.js",
    "/S7.8.5_A1.1_T2.js",
    "/S7.8.5_A1.4_T2.js",
    "/S7.8.5_A2.1_T2.js",
    "/S7.8.5_A2.4_T2.js",
    "/S15.1.2.2_A8.js",
    "/S15.1.2.3_A6.js",
    "/S15.1.3.1_A1.10_T1.js",
    "/S15.1.3.1_A1.11_T1.js",
    "/S15.1.3.1_A1.11_T2.js",
    "/S15.1.3.1_A1.12_T1.js",
    "/S15.1.3.1_A1.12_T2.js",
    "/S15.1.3.1_A1.12_T3.js",
    "/S15.1.3.1_A1.2_T1.js",
    "/S15.1.3.1_A1.2_T2.js",
    "/S15.1.3.1_A2.1_T1.js",
    "/S15.1.3.1_A2.4_T1.js",
    "/S15.1.3.1_A2.5_T1.js",
    "/S15.1.3.2_A1.10_T1.js",
    "/S15.1.3.2_A1.11_T1.js",
    "/S15.1.3.2_A1.11_T2.js",
    "/S15.1.3.2_A1.12_T1.js",
    "/S15.1.3.2_A1.12_T2.js",
    "/S15.1.3.2_A1.12_T3.js",
    "/S15.1.3.2_A1.2_T1.js",
    "/S15.1.3.2_A1.2_T2.js",
    "/S15.1.3.2_A2.1_T1.js",
    "/S15.1.3.2_A2.4_T1.js",
    "/S15.1.3.2_A2.5_T1.js",
    "/S15.1.3.3_A1.3_T1.js",
    "/S15.1.3.3_A2.3_T1.js",
    "/S15.1.3.3_A2.4_T1.js",
    "/S15.1.3.3_A2.4_T2.js",
    "/S15.1.3.3_A2.5_T1.js",
    "/S15.1.3.4_A1.3_T1.js",
    "/S15.1.3.4_A2.3_T1.js",
    "/S15.1.3.4_A2.4_T1.js",
    "/S15.1.3.4_A2.4_T2.js",
    "/S15.1.3.4_A2.5_T1.js",
    "/S15.4.5.2_A3_T4.js",
    "/S15.10.2.12_A3_T1.js",
    "/S15.10.2.12_A4_T1.js",
    "/S15.10.2.12_A5_T1.js",
    "/S15.10.2.12_A6_T1.js",
    "/Array.prototype.concat_large-typed-array.js",
];

for (var i = 2; i < process.argv.length; i++) {
    test_dir(process.argv[i]);
}

if (failed_tests.length) console.log("FAILED TESTS:\n" + failed_tests.join('\n'));
if (exception.length) console.log("EXCEPTION THROWN TESTS:\n" + exception.join('\n'));
if (heavy) console.log("heavy", heavy);
if (failure) console.log("failure", failure);
if (exception.length) console.log("exception", exception.length);
console.log("total", total);

if (failure || exception.length) process.exit(1)
<|endoftext|>


<commit_before>describe('CacheItem - ', function () {
    beforeEach(function () {
        sessionStorage.clear();
        localStorage.clear();
    });

    describe('simple operation - ', function () {
        beforeEach(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'hehe'});
        });

        it('create', function () {
            expect(cacheItem.storageKey).to.be('hehe');
            expect(cacheItem.level).to.be('session');
        });

        it('simple get set', function () {
            cacheItem.val = 3;
            expect(cacheItem.val).to.be(3);
            expect(sessionStorage.getItem('hehe')).to.be('3');
        });
    });

    describe('object operation - ', function () {
        beforeEach(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'haha', level: 'local'});
        });

        it('object get set from localStorage', function () {
            expect(cacheItem.level).to.be('local');

            var sample = {name: 'zombie'};
            cacheItem.val = sample;
            expect(cacheItem.val.name).to.be('zombie');
            expect(localStorage.getItem('haha')).to.be(JSON.stringify(sample));
        });
    });

    describe('timing - ', function () {
        before(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'hehe', maxAge: -1});
        });

        it('stale', function () {
            expect(cacheItem.isStale()).to.be(true);
        });

        //TODO support timeout expect
        it('lastuse', function () {
            // setTimeout(function () {
            //     cacheItem.val = 3;
            //     expect(cacheItem.lastuse).to.be(Date.now());
            // }, 300);
        });
    });

    describe('valid - ', function () {
        before(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'xixi'});
        });

        it('valid', function () {
            expect(cacheItem.isValid()).to.be(false);
            cacheItem.val = 4;
            expect(cacheItem.isValid()).to.be(true);
        });
    });
    //TODO test fromJson, toJSON
});

describe('lruArray', function () {
    describe('simple operation', function() {
        beforeEach(function () {
            arr = new LruWebStorage.LRUArray('storageKey');
            item1 = new LruWebStorage.CacheItem({key: 'hehe', lastuse: Date.now() - 1000});
            item2 = new LruWebStorage.CacheItem({key: 'haha', lastuse: Date.now() - 2000});
            arr.push(item2);
            arr.push(item1);
        });

        it('', function () {
            expect(arr.length).to.be(2);
        });

        it('sort', function () {
            expect(arr.indexOf(item2.storageKey)).to.be(0);
        });

        it('sortAgain', function () {
            arr.find(item1.storageKey).val = 3;
            expect(arr.indexOf(item1.storageKey)).to.be(0);
        });
    });
});

describe('storage', function () {
    beforeEach(function() {
        sessionStorage.clear();
        localStorage.clear();
    });

    describe('just sessionStorage# ', function () {
        beforeEach(function() {
            lru = LruWebStorage('test');
        });

        it('simple set', function () {
            lru.set('a', 1);
            expect(lru.get('a')).to.eql(1);
        });

        it('set object', function () {
            lru.set('obj', {
                name: 'zombie',
                items: ['head', 'brain'],
                attribute: {
                    intelligence: 40,
                    athletic: 10
                }
            });

            var obj = lru.get('obj');
            expect(obj.name).to.eql('zombie');
            expect(obj.items.length).to.eql(0);
            expect(obj.attribute.intelligence).to.eql(40);
            expect(obj.attribute.athletic).to.eql(10);
        });

        it('get undefined', function() {
            expect(lru.get('b')).to.be(undefined);
        });

        it('check localStorage config', function() {
            var config = JSON.parse(localStorage.getItem('test-lruconfig'));
            expect(config._items.length).to.be(0);
            expect('maxAge' in config).to.be(true);
            expect('limit' in config).to.be(true);
            expect('useSession' in config).to.be(true);
        });
    });

    describe('stale# ', function () {

        it('simple stale', function () {
            lru = LruWebStorage('testStale', {
                maxAge: -1 * 6000,
                onStale: function (item) {
                    expect(item).to.be(1);
                }
            });
            lru.set('a', 1);
            expect(lru.get('a')).to.be(null);
        });
    });

    describe('moveToSession', function () {
        beforeEach(function() {
            lru = LruWebStorage('testMove', {limit: 2});
        });

        it('length', function () {
            lru.set('msa', 1);
            lru.set('msb', 2);
            lru.set('msc', 3);
            expect(Object.keys(localStorage).filter(function(v) {return v.indexOf('testMove') != -1;}).length).to.be(3);//2 + 1, one is the config
            expect(Object.keys(sessionStorage).filter(function(v) {return v.indexOf('testMove') != -1;}).length).to.be(1);
        });
    });

    describe('outOfLimit# ', function () {
        beforeEach(function () {
            lru = LruWebStorage('testLimit', {limit: 2, useSession: false});
        });

        it('simple limit', function () {
            lru.set('limita', 1);
            lru.set('limitb', 2);
            lru.set('limitc', 3);
            expect(lru.get('limitc')).to.be(3);
            expect(lru.get('limitb')).to.be(2);
            expect(lru.get('limita')).to.be(undefined);
        });

        it('lru limit', function () {
            lru.set('a', 1);
            lru.set('b', 2);
            lru.get('a');
            lru.set('c', 3);
            expect(lru.get('c')).to.be(3);
            expect(lru.get('b')).to.be(undefined);
            expect(lru.get('a')).to.be(1);
        });
    });
});
<commit_msg>async<commit_after>describe('CacheItem - ', function () {
    beforeEach(function () {
        sessionStorage.clear();
        localStorage.clear();
    });

    describe('simple operation - ', function () {
        beforeEach(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'hehe'});
        });

        it('create', function () {
            expect(cacheItem.storageKey).to.be('hehe');
            expect(cacheItem.level).to.be('session');
        });

        it('simple get set', function () {
            cacheItem.val = 3;
            expect(cacheItem.val).to.be(3);
            expect(sessionStorage.getItem('hehe')).to.be('3');
        });
    });

    describe('object operation - ', function () {
        var cacheItem;
        beforeEach(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'haha', level: 'local'});
        });

        it('object get set from localStorage', function () {
            expect(cacheItem.level).to.be('local');

            var sample = {name: 'zombie'};
            cacheItem.val = sample;
            expect(cacheItem.val.name).to.be('zombie');
            expect(localStorage.getItem('haha')).to.be(JSON.stringify(sample));
        });
    });

    describe('timing - ', function () {
        var cacheItem;
        before(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'hehe', maxAge: -1});
        });

        it('stale', function () {
            expect(cacheItem.isStale()).to.be(true);
        });

        it('lastuse', function (done) {
            setTimeout(function () {
                cacheItem.val = 3;
                expect(cacheItem.lastuse).to.be(Date.now());
                done();
            }, 300);
        });
    });

    describe('valid - ', function () {
        var cacheItem;
        before(function () {
            cacheItem = new LruWebStorage.CacheItem({key: 'xixi'});
        });

        it('valid', function () {
            expect(cacheItem.isValid()).to.be(false);
            cacheItem.val = 4;
            expect(cacheItem.isValid()).to.be(true);
        });
    });
    //TODO test fromJson, toJSON
});

describe('lruArray', function () {
    describe('simple operation', function() {
        var arr, item1, item2;
        beforeEach(function () {
            arr = new LruWebStorage.LRUArray('storageKey');
            item1 = new LruWebStorage.CacheItem({key: 'hehe', lastuse: Date.now() - 1000});
            item2 = new LruWebStorage.CacheItem({key: 'haha', lastuse: Date.now() - 2000});
            arr.push(item2);
            arr.push(item1);
        });

        it('', function (done) {
            expect(arr.length).to.be(2);
            done();
        });

        it('sort', function (done) {
            expect(arr.indexOf(item2.storageKey)).to.be(0);
            done();
        });

        it('sortAgain', function (done) {
            arr.find(item1.storageKey).val = 3;
            setTimeout(function () {
                expect(arr.indexOf(item1.storageKey)).to.be(0);
                done();
            }, 1);

        });
    });
});

describe('storage', function () {
    beforeEach(function() {
        sessionStorage.clear();
        localStorage.clear();
    });

    describe('just sessionStorage# ', function () {
        var lru;
        beforeEach(function() {
            lru = LruWebStorage('test');
        });

        it('simple set', function () {
            lru.set('a', 1);
            expect(lru.get('a')).to.eql(1);
        });

        it('set object', function () {
            lru.set('obj', {
                name: 'zombie',
                items: ['head', 'brain'],
                attribute: {
                    intelligence: 40,
                    athletic: 10
                }
            });

            var obj = lru.get('obj');
            expect(obj.name).to.eql('zombie');
            expect(obj.items.length).to.eql(2);
            expect(obj.attribute.intelligence).to.eql(40);
            expect(obj.attribute.athletic).to.eql(10);
        });

        it('get undefined', function() {
            expect(lru.get('b')).to.be(undefined);
        });

        it('check localStorage config', function() {
            lru.set('a', 1);
            lru.set('obj', {
                name: 'zombie',
                items: ['head', 'brain'],
                attribute: {
                    intelligence: 40,
                    athletic: 10
                }
            });

            var config = JSON.parse(localStorage.getItem('test-lruconfig'));
            expect(config._items.length).to.be(2);
            expect('maxAge' in config).to.be(true);
            expect('limit' in config).to.be(true);
            expect('useSession' in config).to.be(true);
        });
    });

    describe('stale# ', function () {
        var lru;

        it('simple stale', function () {
            lru = LruWebStorage('testStale', {
                maxAge: -1 * 6000,
                onStale: function (item) {
                    expect(item).to.be(1);
                }
            });
            lru.set('a', 1);
            expect(lru.get('a')).to.be(null);
        });
    });

    describe('moveToSession', function () {
        var lru;
        beforeEach(function() {
            lru = LruWebStorage('testMove', {limit: 2});
        });

        it('length', function () {
            lru.set('msa', 1);
            lru.set('msb', 2);
            lru.set('msc', 3);
            expect(Object.keys(localStorage).filter(function(v) {return v.indexOf('testMove') != -1;}).length).to.be(3);//2 + 1, one is the config
            expect(Object.keys(sessionStorage).filter(function(v) {return v.indexOf('testMove') != -1;}).length).to.be(1);
        });
    });

    describe('outOfLimit# ', function () {
        var lru;
        beforeEach(function () {
            lru = LruWebStorage('testLimit', {limit: 2, useSession: false});
        });

        it('simple limit', function () {
            lru.set('limita', 1);
            lru.set('limitb', 2);
            lru.set('limitc', 3);
            expect(lru.get('limitc')).to.be(3);
            expect(lru.get('limitb')).to.be(2);
            expect(lru.get('limita')).to.be(undefined);
        });

        it('lru limit', function () {
            lru.set('a', 1);
            lru.set('b', 2);
            lru.get('a');
            lru.set('c', 3);
            expect(lru.get('c')).to.be(3);
            expect(lru.get('b')).to.be(undefined);
            expect(lru.get('a')).to.be(1);
        });
    });
});
<|endoftext|>