<commit_before>var should = require('should');
var fs = require('fs');
var forecasts = require('../forecasts.js');

describe('aviLevelFromName', function(){
    describe('matching strings', function(){
        it('should return the correct avi Level', function(){
            forecasts.aviLevelFromName('low').should.equal(1);
            forecasts.aviLevelFromName('moderate').should.equal(2);
            forecasts.aviLevelFromName('considerable').should.equal(3);
            forecasts.aviLevelFromName('high').should.equal(4);
            forecasts.aviLevelFromName('extreme').should.equal(5);
            forecasts.aviLevelFromName('Low').should.equal(1);
            forecasts.aviLevelFromName('lOW').should.equal(1);
            forecasts.aviLevelFromName(' low').should.equal(1);
            forecasts.aviLevelFromName('low ').should.equal(1);
            forecasts.aviLevelFromName(' low ').should.equal(1);
            forecasts.aviLevelFromName('   lOw ').should.equal(1);
        })
    })
    describe('non-matching strings', function(){
        it('should return 0', function(){
            forecasts.aviLevelFromName('foo').should.equal(0);
            forecasts.aviLevelFromName('lower').should.equal(0);
            forecasts.aviLevelFromName('').should.equal(0);
            forecasts.aviLevelFromName(null).should.equal(0);
        })
    })
})

describe('findHighestAviLevelInString', function(){
    describe('matching strings', function(){
        it('should return the correct avi Level', function(){
            forecasts.findHighestAviLevelInString('low').should.equal(1);
            forecasts.findHighestAviLevelInString('moderate').should.equal(2);
            forecasts.findHighestAviLevelInString('considerable').should.equal(3);
            forecasts.findHighestAviLevelInString('high').should.equal(4);
            forecasts.findHighestAviLevelInString('extreme').should.equal(5);
            forecasts.findHighestAviLevelInString('Low').should.equal(1);
            forecasts.findHighestAviLevelInString('lOW').should.equal(1);
            forecasts.findHighestAviLevelInString(' low').should.equal(1);
            forecasts.findHighestAviLevelInString('low ').should.equal(1);
            forecasts.findHighestAviLevelInString(' low ').should.equal(1);
            forecasts.findHighestAviLevelInString('   lOw ').should.equal(1);
        })
    })
    describe('non-matching strings', function(){
        it('should return 0', function(){
            forecasts.findHighestAviLevelInString('foo').should.equal(0);
            forecasts.findHighestAviLevelInString('lower').should.equal(0);
            forecasts.findHighestAviLevelInString('lowhigh').should.equal(0);
            forecasts.findHighestAviLevelInString('').should.equal(0);
            forecasts.findHighestAviLevelInString(null).should.equal(0);
        })
    })
    describe('multiple matching strings', function(){
        it('should return the highest level', function(){
            forecasts.findHighestAviLevelInString('low high').should.equal(4);
            forecasts.findHighestAviLevelInString(' low high   ').should.equal(4);
            forecasts.findHighestAviLevelInString('high low').should.equal(4);
            forecasts.findHighestAviLevelInString('low low').should.equal(1);
            forecasts.findHighestAviLevelInString('low high low').should.equal(4);
            forecasts.findHighestAviLevelInString('low highways').should.equal(1);
        })
    })
})

describe('getRegionDetailsForRegionId', function(){
    describe('matching strings', function(){
        it('should return the correct region details', function(){
            forecasts.getRegionDetailsForRegionId('nwac_1').should.have.property('provider','nwac');
            forecasts.getRegionDetailsForRegionId('cac_1').should.have.property('provider','cac');
            forecasts.getRegionDetailsForRegionId('pc_1').should.have.property('provider','pc');
            forecasts.getRegionDetailsForRegionId('caic_1').should.have.property('provider','caic');
        })
    })
    describe('non-matching strings', function(){
        it('should return null', function(){
            should.not.exist(forecasts.getRegionDetailsForRegionId('foo'));
            should.not.exist(forecasts.getRegionDetailsForRegionId('foo_bar'));
            should.not.exist(forecasts.getRegionDetailsForRegionId(''));
            should.not.exist(forecasts.getRegionDetailsForRegionId(null));
            should.not.exist(forecasts.getRegionDetailsForRegionId('caic_0123456'));
        })
    })
})

describe('parseForecast_nwac', function(){
    describe('file000a.html', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_nwac(fs.readFileSync('test/data/nwac/file000a.html','utf8'),
                forecasts.getRegionDetailsForRegionId('nwac_0'));

            should.not.exist(forecast);
        })
    })
    describe('file000b.html', function(){
        it('should fail gracefully on bad input, returning aviLevel 0 for all dates', function(){
            var forecast = forecasts.parseForecast_nwac(fs.readFileSync('test/data/nwac/file000b.html','utf8'),
                forecasts.getRegionDetailsForRegionId('nwac_0'));

            should.exist(forecast);
            forecast.length.should.equal(3);
            forecast[0].date.should.equal('2012-01-16');
            forecast[1].date.should.equal('2012-01-17');
            forecast[2].date.should.equal('2012-01-18');
            forecast[0].aviLevel.should.equal(0);
            forecast[1].aviLevel.should.equal(0);
            forecast[2].aviLevel.should.equal(0);
        })
    })
    describe('file001.html', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_nwac(fs.readFileSync('test/data/nwac/file001.html','utf8'),
                forecasts.getRegionDetailsForRegionId('nwac_1'));

            should.exist(forecast);
            forecast.length.should.equal(3);
            forecast[0].date.should.equal('2012-02-09');
            forecast[1].date.should.equal('2012-02-10');
            forecast[2].date.should.equal('2012-02-11');
            forecast[0].aviLevel.should.equal(2);
            forecast[1].aviLevel.should.equal(2);
            forecast[2].aviLevel.should.equal(2);
        })
    })
})

describe('parseForecast_cac', function(){
    describe('file000.xml', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_cac(fs.readFileSync('test/data/cac/file000.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('cac_0'));

            should.not.exist(forecast);
        })
    })
    describe('file001.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_cac(fs.readFileSync('test/data/cac/file001.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('cac_sea-to-sky'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-09');
            forecast[1].date.should.equal('2012-02-10');
            forecast[2].date.should.equal('2012-02-11');
            forecast[3].date.should.equal('2012-02-12');
            forecast[0].aviLevel.should.equal(3);
            forecast[1].aviLevel.should.equal(3);
            forecast[2].aviLevel.should.equal(2);
            forecast[3].aviLevel.should.equal(2);
        })
    })
    describe('file002.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_cac(fs.readFileSync('test/data/cac/file002.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('cac_kananaskis'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-10');
            forecast[1].date.should.equal('2012-02-11');
            forecast[2].date.should.equal('2012-02-12');
            forecast[3].date.should.equal('2012-02-13');
            forecast[0].aviLevel.should.equal(1);
            forecast[1].aviLevel.should.equal(1);
            forecast[2].aviLevel.should.equal(1);
            forecast[3].aviLevel.should.equal(1);
        })
    })
})

describe('parseForecast_pc', function(){
    describe('file000.xml', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_pc(fs.readFileSync('test/data/pc/file000.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('pc_0'));

            should.not.exist(forecast);
        })
    })
    describe('file001.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_pc(fs.readFileSync('test/data/pc/file001.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('pc_1'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-10');
            forecast[1].date.should.equal('2012-02-11');
            forecast[2].date.should.equal('2012-02-12');
            forecast[3].date.should.equal('2012-02-13');
            forecast[0].aviLevel.should.equal(1);
            forecast[1].aviLevel.should.equal(1);
            forecast[2].aviLevel.should.equal(1);
            forecast[3].aviLevel.should.equal(1);
        })
    })
    describe('file002.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_pc(fs.readFileSync('test/data/pc/file002.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('pc_3'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-09');
            forecast[1].date.should.equal('2012-02-09');
            forecast[2].date.should.equal('2012-02-10');
            forecast[3].date.should.equal('2012-02-11');
            forecast[0].aviLevel.should.equal(2);
            forecast[1].aviLevel.should.equal(2);
            forecast[2].aviLevel.should.equal(2);
            forecast[3].aviLevel.should.equal(2);
        })
    })
})

describe('parseForecast_caic', function(){
    describe('file000.xml', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_caic(fs.readFileSync('test/data/caic/file000.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('caic_0'));

            should.not.exist(forecast);
        })
    })
    describe('file001.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_caic(fs.readFileSync('test/data/caic/file001.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('caic_4'));

            should.exist(forecast);
            forecast.length.should.equal(2);
            forecast[0].date.should.equal('2012-02-13');
            forecast[1].date.should.equal('2012-02-14');
            forecast[0].aviLevel.should.equal(3);
            forecast[1].aviLevel.should.equal(3);
        })
    })
    describe('file002.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_caic(fs.readFileSync('test/data/caic/file002.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('caic_8'));

            should.exist(forecast);
            forecast.length.should.equal(2);
            forecast[0].date.should.equal('2012-02-13');
            forecast[1].date.should.equal('2012-02-14');
            forecast[0].aviLevel.should.equal(4);
            forecast[1].aviLevel.should.equal(4);
        })
    })
})

describe('dateStringFromDateTimeString_caaml', function(){
    describe('valid strings', function(){
        it('should return the correct date', function(){
            forecasts.dateStringFromDateTimeString_caaml('2012-02-02T18:14:00').should.equal('2012-02-02');
            forecasts.dateStringFromDateTimeString_caaml('2012-02-10T00:00:00Z').should.equal('2012-02-10');
            forecasts.dateStringFromDateTimeString_caaml('2012-02-02').should.equal('2012-02-02');
        })
    })
})

<commit_msg>logging control for unit tests<commit_after>var should = require('should');
var fs = require('fs');
var winston = require('winston');
var forecasts = require('../forecasts.js');

// set up the logger
winston.remove(winston.transports.Console);
// verbose, info, warn, error are the log levels i'm using
winston.add(winston.transports.Console, {level: 'error', handleExceptions: true});

describe('aviLevelFromName', function(){
    describe('matching strings', function(){
        it('should return the correct avi Level', function(){
            forecasts.aviLevelFromName('low').should.equal(1);
            forecasts.aviLevelFromName('moderate').should.equal(2);
            forecasts.aviLevelFromName('considerable').should.equal(3);
            forecasts.aviLevelFromName('high').should.equal(4);
            forecasts.aviLevelFromName('extreme').should.equal(5);
            forecasts.aviLevelFromName('Low').should.equal(1);
            forecasts.aviLevelFromName('lOW').should.equal(1);
            forecasts.aviLevelFromName(' low').should.equal(1);
            forecasts.aviLevelFromName('low ').should.equal(1);
            forecasts.aviLevelFromName(' low ').should.equal(1);
            forecasts.aviLevelFromName('   lOw ').should.equal(1);
        })
    })
    describe('non-matching strings', function(){
        it('should return 0', function(){
            forecasts.aviLevelFromName('foo').should.equal(0);
            forecasts.aviLevelFromName('lower').should.equal(0);
            forecasts.aviLevelFromName('').should.equal(0);
            forecasts.aviLevelFromName(null).should.equal(0);
        })
    })
})

describe('findHighestAviLevelInString', function(){
    describe('matching strings', function(){
        it('should return the correct avi Level', function(){
            forecasts.findHighestAviLevelInString('low').should.equal(1);
            forecasts.findHighestAviLevelInString('moderate').should.equal(2);
            forecasts.findHighestAviLevelInString('considerable').should.equal(3);
            forecasts.findHighestAviLevelInString('high').should.equal(4);
            forecasts.findHighestAviLevelInString('extreme').should.equal(5);
            forecasts.findHighestAviLevelInString('Low').should.equal(1);
            forecasts.findHighestAviLevelInString('lOW').should.equal(1);
            forecasts.findHighestAviLevelInString(' low').should.equal(1);
            forecasts.findHighestAviLevelInString('low ').should.equal(1);
            forecasts.findHighestAviLevelInString(' low ').should.equal(1);
            forecasts.findHighestAviLevelInString('   lOw ').should.equal(1);
        })
    })
    describe('non-matching strings', function(){
        it('should return 0', function(){
            forecasts.findHighestAviLevelInString('foo').should.equal(0);
            forecasts.findHighestAviLevelInString('lower').should.equal(0);
            forecasts.findHighestAviLevelInString('lowhigh').should.equal(0);
            forecasts.findHighestAviLevelInString('').should.equal(0);
            forecasts.findHighestAviLevelInString(null).should.equal(0);
        })
    })
    describe('multiple matching strings', function(){
        it('should return the highest level', function(){
            forecasts.findHighestAviLevelInString('low high').should.equal(4);
            forecasts.findHighestAviLevelInString(' low high   ').should.equal(4);
            forecasts.findHighestAviLevelInString('high low').should.equal(4);
            forecasts.findHighestAviLevelInString('low low').should.equal(1);
            forecasts.findHighestAviLevelInString('low high low').should.equal(4);
            forecasts.findHighestAviLevelInString('low highways').should.equal(1);
        })
    })
})

describe('getRegionDetailsForRegionId', function(){
    describe('matching strings', function(){
        it('should return the correct region details', function(){
            forecasts.getRegionDetailsForRegionId('nwac_1').should.have.property('provider','nwac');
            forecasts.getRegionDetailsForRegionId('cac_1').should.have.property('provider','cac');
            forecasts.getRegionDetailsForRegionId('pc_1').should.have.property('provider','pc');
            forecasts.getRegionDetailsForRegionId('caic_1').should.have.property('provider','caic');
        })
    })
    describe('non-matching strings', function(){
        it('should return null', function(){
            should.not.exist(forecasts.getRegionDetailsForRegionId('foo'));
            should.not.exist(forecasts.getRegionDetailsForRegionId('foo_bar'));
            should.not.exist(forecasts.getRegionDetailsForRegionId(''));
            should.not.exist(forecasts.getRegionDetailsForRegionId(null));
            should.not.exist(forecasts.getRegionDetailsForRegionId('caic_0123456'));
        })
    })
})

describe('parseForecast_nwac', function(){
    describe('file000a.html', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_nwac(fs.readFileSync('test/data/nwac/file000a.html','utf8'),
                forecasts.getRegionDetailsForRegionId('nwac_0'));

            should.not.exist(forecast);
        })
    })
    describe('file000b.html', function(){
        it('should fail gracefully on bad input, returning aviLevel 0 for all dates', function(){
            var forecast = forecasts.parseForecast_nwac(fs.readFileSync('test/data/nwac/file000b.html','utf8'),
                forecasts.getRegionDetailsForRegionId('nwac_0'));

            should.exist(forecast);
            forecast.length.should.equal(3);
            forecast[0].date.should.equal('2012-01-16');
            forecast[1].date.should.equal('2012-01-17');
            forecast[2].date.should.equal('2012-01-18');
            forecast[0].aviLevel.should.equal(0);
            forecast[1].aviLevel.should.equal(0);
            forecast[2].aviLevel.should.equal(0);
        })
    })
    describe('file001.html', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_nwac(fs.readFileSync('test/data/nwac/file001.html','utf8'),
                forecasts.getRegionDetailsForRegionId('nwac_1'));

            should.exist(forecast);
            forecast.length.should.equal(3);
            forecast[0].date.should.equal('2012-02-09');
            forecast[1].date.should.equal('2012-02-10');
            forecast[2].date.should.equal('2012-02-11');
            forecast[0].aviLevel.should.equal(2);
            forecast[1].aviLevel.should.equal(2);
            forecast[2].aviLevel.should.equal(2);
        })
    })
})

describe('parseForecast_cac', function(){
    describe('file000.xml', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_cac(fs.readFileSync('test/data/cac/file000.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('cac_0'));

            should.not.exist(forecast);
        })
    })
    describe('file001.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_cac(fs.readFileSync('test/data/cac/file001.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('cac_sea-to-sky'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-09');
            forecast[1].date.should.equal('2012-02-10');
            forecast[2].date.should.equal('2012-02-11');
            forecast[3].date.should.equal('2012-02-12');
            forecast[0].aviLevel.should.equal(3);
            forecast[1].aviLevel.should.equal(3);
            forecast[2].aviLevel.should.equal(2);
            forecast[3].aviLevel.should.equal(2);
        })
    })
    describe('file002.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_cac(fs.readFileSync('test/data/cac/file002.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('cac_kananaskis'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-10');
            forecast[1].date.should.equal('2012-02-11');
            forecast[2].date.should.equal('2012-02-12');
            forecast[3].date.should.equal('2012-02-13');
            forecast[0].aviLevel.should.equal(1);
            forecast[1].aviLevel.should.equal(1);
            forecast[2].aviLevel.should.equal(1);
            forecast[3].aviLevel.should.equal(1);
        })
    })
})

describe('parseForecast_pc', function(){
    describe('file000.xml', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_pc(fs.readFileSync('test/data/pc/file000.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('pc_0'));

            should.not.exist(forecast);
        })
    })
    describe('file001.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_pc(fs.readFileSync('test/data/pc/file001.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('pc_1'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-10');
            forecast[1].date.should.equal('2012-02-11');
            forecast[2].date.should.equal('2012-02-12');
            forecast[3].date.should.equal('2012-02-13');
            forecast[0].aviLevel.should.equal(1);
            forecast[1].aviLevel.should.equal(1);
            forecast[2].aviLevel.should.equal(1);
            forecast[3].aviLevel.should.equal(1);
        })
    })
    describe('file002.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_pc(fs.readFileSync('test/data/pc/file002.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('pc_3'));

            should.exist(forecast);
            forecast.length.should.equal(4);
            forecast[0].date.should.equal('2012-02-09');
            forecast[1].date.should.equal('2012-02-09');
            forecast[2].date.should.equal('2012-02-10');
            forecast[3].date.should.equal('2012-02-11');
            forecast[0].aviLevel.should.equal(2);
            forecast[1].aviLevel.should.equal(2);
            forecast[2].aviLevel.should.equal(2);
            forecast[3].aviLevel.should.equal(2);
        })
    })
})

describe('parseForecast_caic', function(){
    describe('file000.xml', function(){
        it('should fail gracefully on bad input', function(){
            var forecast = forecasts.parseForecast_caic(fs.readFileSync('test/data/caic/file000.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('caic_0'));

            should.not.exist(forecast);
        })
    })
    describe('file001.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_caic(fs.readFileSync('test/data/caic/file001.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('caic_4'));

            should.exist(forecast);
            forecast.length.should.equal(2);
            forecast[0].date.should.equal('2012-02-13');
            forecast[1].date.should.equal('2012-02-14');
            forecast[0].aviLevel.should.equal(3);
            forecast[1].aviLevel.should.equal(3);
        })
    })
    describe('file002.xml', function(){
        it('should return the correct forecast details', function(){
            var forecast = forecasts.parseForecast_caic(fs.readFileSync('test/data/caic/file002.xml','utf8'),
                forecasts.getRegionDetailsForRegionId('caic_8'));

            should.exist(forecast);
            forecast.length.should.equal(2);
            forecast[0].date.should.equal('2012-02-13');
            forecast[1].date.should.equal('2012-02-14');
            forecast[0].aviLevel.should.equal(4);
            forecast[1].aviLevel.should.equal(4);
        })
    })
})

describe('dateStringFromDateTimeString_caaml', function(){
    describe('valid strings', function(){
        it('should return the correct date', function(){
            forecasts.dateStringFromDateTimeString_caaml('2012-02-02T18:14:00').should.equal('2012-02-02');
            forecasts.dateStringFromDateTimeString_caaml('2012-02-10T00:00:00Z').should.equal('2012-02-10');
            forecasts.dateStringFromDateTimeString_caaml('2012-02-02').should.equal('2012-02-02');
        })
    })
})

<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";
const assert = require('assert')
const vm = require('vm')
const fs = require('fs')
const child_proc = require('child_process')
const { basename, dirname, extname } = require('path')

let logDebug = function(){};
let debugMode = false;
let isInteractive = null; // [stdoutistty:bool, stderristty:bool]

function style(streamno, style, what) {
  if (!isInteractive[streamno]) {
    return what;
  }
  const styles = {
    'bold'      : ['1', '22'],
    'italic'    : ['3', '23'],
    'underline' : ['4', '24'],
    'inverse'   : ['7', '27'],

    'white'     : ['37', '39'],
    'grey'      : ['90', '39'],
    'black'     : ['30', '39'],
    'blue'      : ['34', '39'],
    'cyan'      : ['36', '39'],
    'green'     : ['32', '39'],
    'magenta'   : ['35', '39'],
    'red'       : ['31', '39'],
    'yellow'    : ['33', '39'],

    'boldWhite'     : ['1;37', '0;39'],
    'boldGrey'      : ['1;90', '0;39'],
    'boldBlack'     : ['1;30', '0;39'],
    'boldBlue'      : ['1;34', '0;39'],
    'boldCyan'      : ['1;36', '0;39'],
    'boldGreen'     : ['1;32', '0;39'],
    'boldMagenta'   : ['1;35', '0;39'],
    'boldRed'       : ['1;31', '0;39'],
    'boldYellow'    : ['1;33', '0;39'],

    'italicWhite'     : ['3;37', '0;39'],
    'italicGrey'      : ['3;90', '0;39'],
    'italicBlack'     : ['3;30', '0;39'],
    'italicBlue'      : ['3;34', '0;39'],
    'italicCyan'      : ['3;36', '0;39'],
    'italicGreen'     : ['3;32', '0;39'],
    'italicMagenta'   : ['3;35', '0;39'],
    'italicRed'       : ['3;31', '0;39'],
    'italicYellow'    : ['3;33', '0;39'],
  };
  let v = styles[style];
  return `\x1b[${v[0]}m${what}\x1b[${v[1]}m`;
}

function runJSTestInSandbox(filename, name, sandbox) { // :Promise<void>
  logDebug('run', name);
  return new Promise((resolve, reject) => {
    let src = fs.readFileSync(filename, {encoding:'utf8'});
    let expectError = null;
    let m = src.match(/\/\/\!error\s+(.+)\s*(?:\n|$)/);
    if (m) {
      expectError = m[1];
      if (expectError[0] != '/') {
        throw new Error('"//!error" value must be a regex (/.../)');
      }
      expectError = vm.runInNewContext(expectError);
    }

    let script = new vm.Script(src, {
      filename,
      displayErrors: true,
      timeout: 5000,
    });

    let ctx = {
      require,
      console,
      assert,
      setTimeout,
      clearTimeout,
      Buffer,
      isUnitTest: true,
      __dirname: dirname(filename),
      process: {
        stdout: process.stdout,
        stderr: process.stderr,
        isUnitTest: true,
        nextTick: process.nextTick,
        exit(code){ throw new Error('EXIT ' + code) },
      }
    }
    if (sandbox) {
      Object.extend(ctx, sandbox)
    }

    if (expectError) {
      assert.throws(() => {
        script.runInNewContext(ctx);
      }, expectError);
    } else {
      logDebug(`script.runInNewContext("${filename}") ENTER`)
      script.runInNewContext(ctx);
      logDebug(`script.runInNewContext("${filename}") EXIT`)

      if (ctx.Test) {
        let p = ctx.Test();
        if (typeof p == 'object' && typeof p.then == 'function') {
          // Test function returned a promise
          p.then(resolve).catch(reject);
          return;
        }
      }
    }

    resolve();
  });
}

function compileTypescript(infile) { // :Promise<void>
  return new Promise((resolve, reject) => {
    console.log('[ts] compiling', infile)
    const tscfile = __dirname + '/../node_modules/typescript/lib/tsc.js'
    child_proc.execFile(
      process.execPath, [tscfile, '-p', __dirname],
      {
        cwd: __dirname,
        encoding: 'utf8',
        timeout: 30000,
      },
      (error, stdout, stderr) => {
        if (stdout && stdout.length) {
          console.log('[ts]', stdout)
        }
        if (error) {
          if (stderr && stderr.length) {
            console.error('[ts] error:', stderr)
          }
          return reject(error)
        }
        resolve()
      }
    )
  })
}

function compileTypescriptIfNeeded(filename) { // :Promise<string>
  assert.equal(extname(filename), '.ts')
  const outfilename = __dirname + '/build/' + basename(filename, '.ts') + '.js'

  // has input been modified since output was modified?
  const instat = fs.statSync(filename)
  try {
    const outstat = fs.statSync(outfilename)
    if (instat.mtime.getTime() <= outstat.mtime.getTime()) {
      // infile hasn't changed since outfile did
      return Promise.resolve(outfilename)
    }
  } catch (_) {}

  return compileTypescript(filename).then(() => outfilename)
}

function runJSTest(filename, name) {
  const p = (extname(filename) == '.ts') ?
    compileTypescriptIfNeeded(filename) :
    Promise.resolve(filename)

  return p.then(filename =>
    runJSTestInSandbox(filename, name).then(() => {
      process.stdout.write(
        `${style(0,'boldGreen','pass')} ${name}\n`
      )
    }).catch(err => {
      process.stderr.write(
        `${style(1,'boldRed','FAIL')} ${name}:\n${err.stack || String(err)}\n`
      )
      throw err;
    })
  )
}

const suffix = '_test';
const fileexts = ['.js', '.ts']

function runAllTests() {
  return Promise.all(
    fs.readdirSync(__dirname).filter(fn => {
      const ext = extname(fn)
      return ext.includes(ext) && basename(fn, ext).substr(-suffix.length) == suffix
    }).map(fn =>
      runJSTest(__dirname + '/' + fn, fn.substr(0, fn.length - extname(fn).length - suffix.length))
    )
  )
}

function isFileSync(filename) {
  try {
    const st = fs.statSync(filename)
    return st.isFile()
  } catch (_) {}
  return false
}

function testNameToFilename(test) {
  const mkname = s => {
    const b = basename(s, ext)
    return b.substr(0, b.length - suffix.length)
  }

  let ext = extname(test)
  if (test[0] == '/' || isFileSync(test)) {
    return { path: test, name: mkname(test) }
  }

  for (let ext of fileexts) {
    let name = test + suffix + ext
    let path = __dirname + '/' + name
    if (isFileSync(path)) {
      return { path, name: test }
    }
  }

  let path = __dirname + '/' + test;
  if (isFileSync(path)) {
    return {path, name: mkname(test)}
  }

  throw new Error(`test not found: "${test}"`);
}

function runSomeTests(tests) {
  return Promise.all(
    tests.map(testNameToFilename).map(f =>
      runJSTest(f.path, f.name))
  )
}

let args = process.argv.slice(2);
let timeout = 30000;
let timeoutTimer;

let onerr = err => {
  clearTimeout(timeoutTimer);
  console.error(style(1,'boldRed', 'aborted by error'));
  process.exit(1);
};

let onallpass = () => {
  console.log(style(0,'boldGreen','all pass'));
  clearTimeout(timeoutTimer);
}

timeoutTimer = setTimeout(function(){
  console.error(style(1,'boldRed', `timeout after ${(timeout/1000).toFixed(2)}s`));
  onerr();
}, timeout);

function checkflag(flag) {
  let i = args.indexOf(flag);
  if (i != -1) {
    args.splice(i,1);
    return true;
  }
  return false;
}

if (args.indexOf('-h') != -1 || args.indexOf('--help') != -1) {
  console.error([
    'Usage: test [options] [<test> ...]',
    'options:',
    '  --debug              Enable debug mode; prints detailed information.',
    '  --[non-]interactive  Instead of checking if stdout is interactive, be explicit',
    '                       about whether colors and other TTY-related things are output.',
  ].join('\n'));
  process.exit(1);
}

if (checkflag('--non-interactive')) {
  isInteractive = [false,false];
}
if (checkflag('--interactive')) {
  isInteractive = [true,true];
}
if (isInteractive === null) {
  // auto-detect
  isInteractive = [process.stdout.isTTY,process.stderr.isTTY];
}

if (checkflag('--debug')) {
  debugMode = true;
  logDebug = function() {
    let args = Array.prototype.slice.call(arguments);
    args.unshift(style(0,'boldMagenta','[debug]'));
    console.log.apply(console, args);
  };
}

(args.length ? runSomeTests(args) : runAllTests()).catch(onerr).then(onallpass);
<commit_msg>Replace fragile tsc process with typescript library API for tests Fixes #1<commit_after>#!/usr/bin/env node
"use strict";
const assert = require('assert')
const vm = require('vm')
const fs = require('fs')
const { basename, dirname, extname } = require('path')

let logDebug = function(){};
let debugMode = false;
let isInteractive = null; // [stdoutistty:bool, stderristty:bool]

function style(streamno, style, what) {
  if (!isInteractive[streamno]) {
    return what;
  }
  const styles = {
    'bold'      : ['1', '22'],
    'italic'    : ['3', '23'],
    'underline' : ['4', '24'],
    'inverse'   : ['7', '27'],

    'white'     : ['37', '39'],
    'grey'      : ['90', '39'],
    'black'     : ['30', '39'],
    'blue'      : ['34', '39'],
    'cyan'      : ['36', '39'],
    'green'     : ['32', '39'],
    'magenta'   : ['35', '39'],
    'red'       : ['31', '39'],
    'yellow'    : ['33', '39'],

    'boldWhite'     : ['1;37', '0;39'],
    'boldGrey'      : ['1;90', '0;39'],
    'boldBlack'     : ['1;30', '0;39'],
    'boldBlue'      : ['1;34', '0;39'],
    'boldCyan'      : ['1;36', '0;39'],
    'boldGreen'     : ['1;32', '0;39'],
    'boldMagenta'   : ['1;35', '0;39'],
    'boldRed'       : ['1;31', '0;39'],
    'boldYellow'    : ['1;33', '0;39'],

    'italicWhite'     : ['3;37', '0;39'],
    'italicGrey'      : ['3;90', '0;39'],
    'italicBlack'     : ['3;30', '0;39'],
    'italicBlue'      : ['3;34', '0;39'],
    'italicCyan'      : ['3;36', '0;39'],
    'italicGreen'     : ['3;32', '0;39'],
    'italicMagenta'   : ['3;35', '0;39'],
    'italicRed'       : ['3;31', '0;39'],
    'italicYellow'    : ['3;33', '0;39'],
  };
  let v = styles[style];
  return `\x1b[${v[0]}m${what}\x1b[${v[1]}m`;
}

function readfile(filename) {
  return new Promise((resolve, reject) => {
    fs.readFile(filename, {encoding:'utf8'}, (e, s) => {
      if (e) { reject(e) } else { resolve(s) }
    })
  })
}

function writefile(filename, data) {
  return new Promise((resolve, reject) => {
    let triedmkdir = false
    function tryw() {
      fs.writeFile(filename, data, e => {
        if (e) {
          if (!triedmkdir && e.code == 'ENOENT') {
            triedmkdir = true
            fs.mkdir(dirname(filename), e2 => {
              if (e2) { reject(e) } else { tryw() }
            })
          } else {
            reject(e)
          }
        } else {
          resolve()
        }
      })
    }
    tryw()
  })
}

function runJSTestInSandbox(src, filename, name, sandbox) { // :Promise<void>
  logDebug('run', name);
  return new Promise((resolve, reject) => {
    let expectError = null;
    let m = src.match(/\/\/\!error\s+(.+)\s*(?:\n|$)/);
    if (m) {
      expectError = m[1];
      if (expectError[0] != '/') {
        throw new Error('"//!error" value must be a regex (/.../)');
      }
      expectError = vm.runInNewContext(expectError);
    }

    let script = new vm.Script(src, {
      filename,
      displayErrors: true,
      timeout: 5000,
    });

    let ctx = {
      require,
      console,
      assert,
      setTimeout,
      clearTimeout,
      Buffer,
      isUnitTest: true,
      __dirname: dirname(filename),
      process: {
        stdout: process.stdout,
        stderr: process.stderr,
        isUnitTest: true,
        nextTick: process.nextTick,
        exit(code){ throw new Error('EXIT ' + code) },
      }
    }
    if (sandbox) {
      Object.extend(ctx, sandbox)
    }

    if (expectError) {
      assert.throws(() => {
        script.runInNewContext(ctx);
      }, expectError);
    } else {
      logDebug(`script.runInNewContext("${filename}") ENTER`)
      script.runInNewContext(ctx);
      logDebug(`script.runInNewContext("${filename}") EXIT`)

      if (ctx.Test) {
        let p = ctx.Test();
        if (typeof p == 'object' && typeof p.then == 'function') {
          // Test function returned a promise
          p.then(resolve).catch(reject);
          return;
        }
      }
    }

    resolve();
  });
}

function tsc(source, filename) { // :Promise<string>
  return new Promise((resolve, reject) => {
    const ts = require(__dirname + '/../node_modules/typescript/lib/typescript.js')
    const compilerOptions = {
      module: ts.ModuleKind.CommonJS,
      target: ts.ScriptTarget.Latest,
      noImplicitAny: false,
      inlineSourceMap: true,
      alwaysStrict: true,
      forceConsistentCasingInFileNames: true,
      noEmitOnError: true,
      lib: [
        "dom",
        "es6",
      ],
      pretty: true
    }

    let r = ts.transpileModule(source, {
      compilerOptions,
      fileName: filename,
      reportDiagnostics: true,
      moduleName: basename(filename, extname(filename)),
    })

    if (r.diagnostics && r.diagnostics.length) {
      const log = {
        [ts.DiagnosticCategory.Warning]: console.warn.bind(console,  '[tsc warning]'),
        [ts.DiagnosticCategory.Error]:   console.error.bind(console, '[tsc error]'),
        [ts.DiagnosticCategory.Message]: console.log.bind(console,   '[tsc]'),
      }
      let firstError = null
      for (let d of r.diagnostics) {
        let prefix = ''
        if (d.file) {
          const pos = d.file.getLineAndCharacterOfPosition(d.start)
          prefix += (d.file.fileName.endsWith(filename) ?
                     basename(filename) : d.file.fileName) +
                    ':' + pos.line + ':' + pos.character + ': '
        }
        prefix += 'TS'+d.code+':'
        log[d.category](prefix, d.messageText)
        if (!firstError && d.category == ts.DiagnosticCategory.Error) {
          firstError = d.messageText
        }
      }
      if (firstError) {
        return reject(new Error(firstError))
      }
    }

    resolve(r.outputText)
  })
}

function getCompiledTypeScript(filename) { // :Promise<string>
  assert.equal(extname(filename), '.ts')

  const outfilename = __dirname + '/build/' + basename(filename, extname(filename)) + '.js'

  // has input been modified since output was modified?
  const instat = fs.statSync(filename)
  try {
    const outstat = fs.statSync(outfilename)
    if (instat.mtime.getTime() <= outstat.mtime.getTime()) {
      // infile hasn't changed since outfile did
      return readfile(outfilename)
    }
  } catch (_) {}

  logDebug('tsc', filename, '->', outfilename)

  return readfile(filename)
         .then(source => tsc(source, filename))
         .then(source => writefile(outfilename, source)
                         .then(() => source))
}

function runJSTest(filename, name) {
  return (
    extname(filename) == '.ts'
    ? getCompiledTypeScript(filename)
    : readfile(filename)
  ).catch(e => {
    console.error(e.stack || String(e))
    throw e
  }).then(source =>
    runJSTestInSandbox(source, filename, name).then(() => {
      process.stdout.write(
        `${style(0,'boldGreen','pass')} ${name}\n`
      )
    }).catch(err => {
      process.stderr.write(
        `${style(1,'boldRed','FAIL')} ${name}:\n${err.stack || String(err)}\n`
      )
      throw err;
    })
  )
}

const suffix = '_test';
const fileexts = ['.js', '.ts']

function runAllTests() {
  return Promise.all(
    fs.readdirSync(__dirname).filter(fn => {
      const ext = extname(fn)
      return ext.includes(ext) && basename(fn, ext).substr(-suffix.length) == suffix
    }).map(fn =>
      runJSTest(__dirname + '/' + fn, fn.substr(0, fn.length - extname(fn).length - suffix.length))
    )
  )
}

function isFileSync(filename) {
  try {
    const st = fs.statSync(filename)
    return st.isFile()
  } catch (_) {}
  return false
}

function testNameToFilename(test) {
  const mkname = s => {
    const b = basename(s, ext)
    return b.substr(0, b.length - suffix.length)
  }

  let ext = extname(test)
  if (test[0] == '/' || isFileSync(test)) {
    return { path: test, name: mkname(test) }
  }

  for (let ext of fileexts) {
    let name = test + suffix + ext
    let path = __dirname + '/' + name
    if (isFileSync(path)) {
      return { path, name: test }
    }
  }

  let path = __dirname + '/' + test;
  if (isFileSync(path)) {
    return {path, name: mkname(test)}
  }

  throw new Error(`test not found: "${test}"`);
}

function runSomeTests(tests) {
  return Promise.all(
    tests.map(testNameToFilename).map(f =>
      runJSTest(f.path, f.name))
  )
}

let args = process.argv.slice(2);
let timeout = 30000;
let timeoutTimer;

let onerr = err => {
  clearTimeout(timeoutTimer);
  console.error(style(1,'boldRed', 'aborted by error'));
  process.exit(1);
};

let onallpass = () => {
  console.log(style(0,'boldGreen','all pass'));
  clearTimeout(timeoutTimer);
}

timeoutTimer = setTimeout(function(){
  console.error(style(1,'boldRed', `timeout after ${(timeout/1000).toFixed(2)}s`));
  onerr();
}, timeout);

function checkflag(flag) {
  let i = args.indexOf('-' + flag)
  if (i == -1) { i = args.indexOf('--' + flag) }
  if (i != -1) {
    args.splice(i,1)
    return true
  }
  return false
}

if (args.indexOf('-h') != -1 || args.indexOf('--help') != -1) {
  console.error([
    'Usage: test [options] [<test> ...]',
    'options:',
    '  --debug              Enable debug mode; prints detailed information.',
    '  --[non-]interactive  Instead of checking if stdout is interactive, be explicit',
    '                       about whether colors and other TTY-related things are output.',
  ].join('\n'));
  process.exit(1);
}

if (checkflag('non-interactive')) {
  isInteractive = [false,false];
}
if (checkflag('interactive')) {
  isInteractive = [true,true];
}
if (isInteractive === null) {
  // auto-detect
  isInteractive = [process.stdout.isTTY,process.stderr.isTTY];
}

if (checkflag('debug')) {
  debugMode = true;
  logDebug = function() {
    let args = Array.prototype.slice.call(arguments);
    args.unshift(style(0,'boldMagenta','D'));
    console.log.apply(console, args);
  };
}

(args.length ? runSomeTests(args) : runAllTests()).catch(onerr).then(onallpass);
<|endoftext|>


<commit_before>var gruntRequireConfig = require('./src/dev/requireConfig').gruntConfig;
var gruntWrapperRequireConfig = require('./src/dev/requireConfig').gruntWrapperConfig;

module.exports = function (grunt) {
    grunt.initConfig({
        requirejs: {
            core: {
                options: gruntRequireConfig
            },
            wrapper: {
                options: gruntWrapperRequireConfig
            }
        },
        concat: {

        },
        jst: {
            compile: {
                options: {
                    prettify: true,
                    processName: function (filePath) {
                        var parts = filePath.split('/');
                        var fileName = parts[parts.length - 1];
                        return fileName.split('.')[0];
                    },
                    amd: true
                },
                files: {
                    "src/js/generated/templates.js": ["src/templates/*.html"]
                }
            }
        },
        less: {
            development: {
                options: {
                    paths: ['src/less']
                },
                files: {
                    "build/tmp/razorflow.css": "src/less/razorflow.less"
                }
            },
            newdesign: {
                options: {
                    paths: ['src/dev/newdesign/less']
                },
                files: {
                    "src/dev/newdesign/css/razorflow.css":  "src/dev/newdesign/less/razorflow.less"
                }
            }
        },
        jshint: {
            options: {
                jshintrc: 'src/js/.jshintrc'
            },
            files: [
                "src/js/**/*.js"
            ]
        },
        karma: {
            dev: {
                configFile: './karma.conf.js',
                singleRun: true
            }
        },
        lodash: {
            build: {
                dest: 'src/vendor/js/lodash.rf.js',
                options: {
                    include: ['extend', 'pluck', 'map', 'each', 'isNumber', 'isString', 'isNaN', 'isArray', 'isObject', 'find', 'defer', 'delay', 'max', 'min', 'sortBy', 'flatten', 'clone', 'cloneDeep', 'values', 'pick', 'reduce', 'filter', 'indexOf', 'keys', 'debounce'],
                }
            }
        },
        cssmin: {
            minify: {
                expand: true,
                cwd: 'build/tmp/',
                src: ['razorflow.css'],
                dest: 'build/assets/css',
                ext: '.min.css'
            }
        },
        // Need to copy products.json
        copy: {
            localToWebRF: {
                files: [
                    {src: ["build/js/razorflow.min.js"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/css/razorflow.min.css"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/js/templates.js"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/js/rfDemos.js"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/img/exampleImgs/*.png"], dest: '../webrf/backend/static/transfer/',flatten: true },
                ]
            }
        },
        copyto: {
            srcToBuild: {
                files: [
                    {cwd: 'src/vendor/js/', src: ['jquery.min.js'], dest: 'build/assets/js/'},
                ]
            },
            packageToBuild: {
                files: [
                    {cwd: 'src/package/', src: ['**/*'], dest: 'build/package/'},
                ],
            },
            assetsToPackage: {
                files: [
                    {cwd: 'build/assets/', src: ["js/**", "css/**"], dest: 'build/package/files/'},
                    {cwd: 'build/assets/', src: ["js/**", "css/**"], dest: 'build/package/dashboard_quickstart/'},
                ],
            },
            packageToRelease: {
                files: [
                    {cwd: 'src/package/', src: ['**'], dest: '../package/rf/javascript/'}
                ]
            }
        },
        replace: {
            removeAMD: {
                src: "build/assets/js/razorflow.min.js",
                overwrite: true,
                replacements: [
                    {from: /\bdefine\b/g, to: "_dfn"},
                    {from: /\brequire\b/g, to: "_rqr"}
                ]
            }
        },
        clean: {
            build: ["build"]
        }
    });

    grunt.loadNpmTasks('grunt-contrib-requirejs');
    grunt.loadNpmTasks('grunt-contrib-jst');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-lodash');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-text-replace');
    grunt.loadNpmTasks('grunt-copy-to');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadTasks("./tools/src/grunt-tasks");

    grunt.registerTask('compile', ['less', 'jst:compile']);
    grunt.registerTask('test', ['compile', 'karma:dev', 'shell:coverageReport']);

    grunt.registerTask('build', ["clean:build", "less", "jst:compile", 'requirejs:core', 'requirejs:wrapper', "replace:removeAMD", 'cssmin:minify', "copyto:srcToBuild"])
    grunt.registerTask('package', ['build', 'copyto:packageToBuild', 'copyto:assetsToPackage'])
    // grunt.registerTask('websiteRelease', ['build', 'cssmin:minify', 'squashdemos', "screenshotGen:examples", 'copy:localToWebRF'])
}<commit_msg>Added a grunt task to copy razorcharts<commit_after>var gruntRequireConfig = require('./src/dev/requireConfig').gruntConfig;
var gruntWrapperRequireConfig = require('./src/dev/requireConfig').gruntWrapperConfig;

module.exports = function (grunt) {
    grunt.initConfig({
        requirejs: {
            core: {
                options: gruntRequireConfig
            },
            wrapper: {
                options: gruntWrapperRequireConfig
            }
        },
        concat: {

        },
        jst: {
            compile: {
                options: {
                    prettify: true,
                    processName: function (filePath) {
                        var parts = filePath.split('/');
                        var fileName = parts[parts.length - 1];
                        return fileName.split('.')[0];
                    },
                    amd: true
                },
                files: {
                    "src/js/generated/templates.js": ["src/templates/*.html"]
                }
            }
        },
        less: {
            development: {
                options: {
                    paths: ['src/less']
                },
                files: {
                    "build/tmp/razorflow.css": "src/less/razorflow.less"
                }
            },
            newdesign: {
                options: {
                    paths: ['src/dev/newdesign/less']
                },
                files: {
                    "src/dev/newdesign/css/razorflow.css":  "src/dev/newdesign/less/razorflow.less"
                }
            }
        },
        jshint: {
            options: {
                jshintrc: 'src/js/.jshintrc'
            },
            files: [
                "src/js/**/*.js"
            ]
        },
        karma: {
            dev: {
                configFile: './karma.conf.js',
                singleRun: true
            }
        },
        lodash: {
            build: {
                dest: 'src/vendor/js/lodash.rf.js',
                options: {
                    include: ['extend', 'pluck', 'map', 'each', 'isNumber', 'isString', 'isNaN', 'isArray', 'isObject', 'find', 'defer', 'delay', 'max', 'min', 'sortBy', 'flatten', 'clone', 'cloneDeep', 'values', 'pick', 'reduce', 'filter', 'indexOf', 'keys', 'debounce'],
                }
            }
        },
        cssmin: {
            minify: {
                expand: true,
                cwd: 'build/tmp/',
                src: ['razorflow.css'],
                dest: 'build/assets/css',
                ext: '.min.css'
            }
        },
        // Need to copy products.json
        copy: {
            localToWebRF: {
                files: [
                    {src: ["build/js/razorflow.min.js"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/css/razorflow.min.css"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/js/templates.js"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/js/rfDemos.js"], dest: '../webrf/backend/static/transfer/', flatten:true},
                    {src: ["build/img/exampleImgs/*.png"], dest: '../webrf/backend/static/transfer/',flatten: true },
                ]
            }
        },
        copyto: {
            srcToBuild: {
                files: [
                    {cwd: 'src/vendor/js/', src: ['jquery.min.js'], dest: 'build/assets/js/'},
                ]
            },
            packageToBuild: {
                files: [
                    {cwd: 'src/package/', src: ['**/*'], dest: 'build/package/'},
                ],
            },
            assetsToPackage: {
                files: [
                    {cwd: 'build/assets/', src: ["js/**", "css/**"], dest: 'build/package/files/'},
                    {cwd: 'build/assets/', src: ["js/**", "css/**"], dest: 'build/package/dashboard_quickstart/'},
                ],
            },
            packageToRelease: {
                files: [
                    {cwd: 'src/package/', src: ['**'], dest: '../package/rf/javascript/'}
                ]
            },
            razorcharts: {
                files: [
                    {cwd: '../razorcharts/src/js', src:['**'], dest: 'src/js/'}
                ]
            }
        },
        replace: {
            removeAMD: {
                src: "build/assets/js/razorflow.min.js",
                overwrite: true,
                replacements: [
                    {from: /\bdefine\b/g, to: "_dfn"},
                    {from: /\brequire\b/g, to: "_rqr"}
                ]
            }
        },
        clean: {
            build: ["build"]
        }
    });

    grunt.loadNpmTasks('grunt-contrib-requirejs');
    grunt.loadNpmTasks('grunt-contrib-jst');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-lodash');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-text-replace');
    grunt.loadNpmTasks('grunt-copy-to');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadTasks("./tools/src/grunt-tasks");

    grunt.registerTask('compile', ['less', 'jst:compile']);
    grunt.registerTask('test', ['compile', 'karma:dev', 'shell:coverageReport']);

    grunt.registerTask('build', ["clean:build", "less", "jst:compile", 'requirejs:core', 'requirejs:wrapper', "replace:removeAMD", 'cssmin:minify', "copyto:srcToBuild"])
    grunt.registerTask('package', ['build', 'copyto:packageToBuild', 'copyto:assetsToPackage'])
    // grunt.registerTask('websiteRelease', ['build', 'cssmin:minify', 'squashdemos', "screenshotGen:examples", 'copy:localToWebRF'])
}<|endoftext|>


<commit_before>// http://stackoverflow.com/questions/13567312/working-project-structure-that-uses-grunt-js-to-combine-javascript-files-using-r

/*global module:false*/
module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        pkg: '<json:package.json>',
        localConfig: (function(){
                        try {
                            return grunt.file.readJSON('localConfig.json')
                        } catch(e) {
                            return {}
                        }
                    })() ,
        meta: {
          banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
            '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
            '<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
            '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
            ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
        },
        lint: {
            files: ['grunt.js', 'src/**/*.js', 'tests/**/*.js']
        },
        qunit: {
            all: {
              options: {
                urls: [
                  'http://localhost:3000/tests/capture.html',
                ]
              }
            }
        },
        connect: {
            server: {
                options: {
                    port: 3000,
                    base: '.'
                }
            }
        },
        requirejs: {
            // Building capturing only
            capture: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-capture",
                    out: "./build/mobify-capture.js",
                }
            },
            // Build resizeImages only
            resizeImages: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-resizeImages",
                    out: "./build/mobify-resizeImages.js",
                }
            },
            // Build enhance only - TODO: Rename!!!
            enhance: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-enhance",
                    out: "./build/mobify-enhance.js",
                }
            },
            // Building full Mobify.js library
            full: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-full",
                    out: "./build/mobify.js",
                }
            },
            // Building full Mobify.js library
            fullOptimized: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    keepBuildDir: true,
                    name: "mobify-full",
                    out: "./build/mobify.min.js",
                }
            }
        },
        watch: {
          files: 'src/**/*.js',
          tasks: ['requirejs'],
        },
        'saucelabs-qunit': {
            all: {
                username: '<%= localConfig.saucelabs.username %>', // if not provided it'll default to ENV SAUCE_USERNAME (if applicable)
                key: '<%= localConfig.saucelabs.key %>', // if not provided it'll default to ENV SAUCE_ACCESS_KEY (if applicable)
                urls: ['http://localhost:3000/tests/capture.html'],
                concurrency: 2,
                tunneled: true,
                browsers: [/*{
                    browserName: 'internet explorer',
                    version: '9'
                },*/{
                    browserName: 'chrome',
                },{
                    browserName: 'firefox',
                    version: '13.0'
                }], // https://saucelabs.com/docs/browsers
                onTestComplete: function(){
                    // Called after a qunit unit is done, per page, per browser
                    // Return true or false, passes or fails the test
                    // Returning undefined does not alter the test result

                    // For async return, call
                    var done = this.async();
                    setTimeout(function(){
                        // Return to this test after 1000 milliseconds
                        done(/*true or false changes the test result, undefined does not alter the result*/);
                    }, 1000);
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-requirejs');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-qunit');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-saucelabs');

    // Default task.
    // grunt.registerTask('default', 'lint qunit requirejs');
    //grunt.registerTask('skiptests', 'concat');
    grunt.registerTask('default', ['requirejs:resizeImages',
                                   'requirejs:capture',
                                   'requirejs:enhance',
                                   'requirejs:full',
                                   'requirejs:fullOptimized']);
    grunt.registerTask('capture', 'requirejs:capture');
    grunt.registerTask('full', 'requirejs:full');
    grunt.registerTask('test', ['connect', 'qunit']);
    grunt.registerTask('saucelabs', ['test', 'saucelabs-qunit']);
    grunt.registerTask('serve', 'connect');
};
<commit_msg>Adding browsers we want to test on Saucelabs<commit_after>// http://stackoverflow.com/questions/13567312/working-project-structure-that-uses-grunt-js-to-combine-javascript-files-using-r

/*global module:false*/
module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        pkg: '<json:package.json>',
        localConfig: (function(){
                        try {
                            return grunt.file.readJSON('localConfig.json')
                        } catch(e) {
                            return {}
                        }
                    })() ,
        meta: {
          banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
            '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
            '<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' +
            '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
            ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
        },
        lint: {
            files: ['grunt.js', 'src/**/*.js', 'tests/**/*.js']
        },
        qunit: {
            all: {
              options: {
                urls: [
                  'http://localhost:3000/tests/capture.html',
                ]
              }
            }
        },
        connect: {
            server: {
                options: {
                    port: 3000,
                    base: '.'
                }
            }
        },
        requirejs: {
            // Building capturing only
            capture: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-capture",
                    out: "./build/mobify-capture.js",
                }
            },
            // Build resizeImages only
            resizeImages: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-resizeImages",
                    out: "./build/mobify-resizeImages.js",
                }
            },
            // Build enhance only - TODO: Rename!!!
            enhance: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-enhance",
                    out: "./build/mobify-enhance.js",
                }
            },
            // Building full Mobify.js library
            full: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    optimize: "none",
                    keepBuildDir: true,
                    name: "mobify-full",
                    out: "./build/mobify.js",
                }
            },
            // Building full Mobify.js library
            fullOptimized: {
                options: {
                    almond: true,
                    mainConfigFile: "./src/config.js",
                    keepBuildDir: true,
                    name: "mobify-full",
                    out: "./build/mobify.min.js",
                }
            }
        },
        watch: {
          files: 'src/**/*.js',
          tasks: ['requirejs'],
        },
        'saucelabs-qunit': {
            all: {
                username: '<%= localConfig.saucelabs.username %>', // if not provided it'll default to ENV SAUCE_USERNAME (if applicable)
                key: '<%= localConfig.saucelabs.key %>', // if not provided it'll default to ENV SAUCE_ACCESS_KEY (if applicable)
                urls: ['http://localhost:3000/tests/capture.html'],
                concurrency: 1,
                tunneled: true,
                browsers: [
                { // Only working version of IE compatable
                    browserName: 'internet explorer',
                    version: '10'
                },
                { // Always tests latest Chrome (on Windows)
                    browserName: 'chrome',
                },
                { // Lowest known working version of FF
                    browserName: 'firefox',
                    version: '4.0'
                },
                { // Highest known working version of FF
                    browserName: 'firefox',
                    version: '18.0'
                }], // https://saucelabs.com/docs/browsers
                onTestComplete: function(){
                    // Called after a qunit unit is done, per page, per browser
                    // Return true or false, passes or fails the test
                    // Returning undefined does not alter the test result

                    // For async return, call
                    var done = this.async();
                    setTimeout(function(){
                        // Return to this test after 1000 milliseconds
                        done(/*true or false changes the test result, undefined does not alter the result*/);
                    }, 1000);
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-requirejs');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-qunit');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-saucelabs');

    // Default task.
    // grunt.registerTask('default', 'lint qunit requirejs');
    //grunt.registerTask('skiptests', 'concat');
    grunt.registerTask('default', ['requirejs:resizeImages',
                                   'requirejs:capture',
                                   'requirejs:enhance',
                                   'requirejs:full',
                                   'requirejs:fullOptimized']);
    grunt.registerTask('capture', 'requirejs:capture');
    grunt.registerTask('full', 'requirejs:full');
    grunt.registerTask('test', ['connect', 'qunit']);
    grunt.registerTask('saucelabs', ['test', 'saucelabs-qunit']);
    grunt.registerTask('serve', 'connect');
};
<|endoftext|>


<commit_before>var fixedWithLiResult=false;
//判断元素position属性值为fixed的元素中是否包含li元素
function isIncludeLiInFixedEle(node){
	var childLen=node.childNodes.length;
	if(childLen==0){

	}else{
		for(var i=0;i<childLen;i++){
			var childTmp=node.childNodes[i];
			if(childTmp.nodeType==1){
				if(childTmp.nodeName=="LI"){
					fixedWithLiResult=true;
					return;
				}
			}
			isIncludeLiInFixedEle(childTmp);
		}
	}
}

function traverseDOM(node){
  var childLen=node.childNodes.length;
  if(childLen==0){
  }else{
    for(var i=0;i<childLen;i++){
      var childTmp=node.childNodes[i];
      if(childTmp.nodeType==1){
        if(childTmp.nodeName=="DIV"){
          var str="hello world!"
        }
        var obj=window.getComputedStyle(childTmp);
        if(obj.hasOwnProperty("position")){
          if(obj.position=="fixed" && (obj.bottom=="0px" || obj.left=='0px' || obj.right=='0px')){
            var widthTmp=parseInt(obj.width.replace(/[^0-9]/ig,""));
            if(widthTmp>=1000){
		    return;
	    }
            isIncludeLiInFixedEle(childTmp);
            if(fixedWithLiResult){
              fixedWithLiResult=false;
              continue;
            }
            console.log('......Github......');
	    console.log(childTmp);
	    console.log(obj.bottom);
	    console.log(obj.left);
	    console.log(obj.right);
	    console.log('......Github......');
            childTmp.style.display="none";
          }
        }
      }
      traverseDOM(childTmp);
    }
  }
}

setTimeout(function(){
 traverseDOM(document.body);
},1000);

window.addEventListener('scroll',function(e){
	traverseDOM(document.body);
});

<commit_msg>Update test.js<commit_after>var fixedWithLiResult=false;
//判断元素position属性值为fixed的元素中是否包含li元素
function isIncludeLiInFixedEle(node){
	var childLen=node.childNodes.length;
	if(childLen==0){

	}else{
		for(var i=0;i<childLen;i++){
			var childTmp=node.childNodes[i];
			if(childTmp.nodeType==1){
				if(childTmp.nodeName=="LI"){
					fixedWithLiResult=true;
					return;
				}
			}
			isIncludeLiInFixedEle(childTmp);
		}
	}
}

function traverseDOM(node){
  var childLen=node.childNodes.length;
  if(childLen==0){
  }else{
    for(var i=0;i<childLen;i++){
      var childTmp=node.childNodes[i];
      if(childTmp.nodeType==1){
        if(childTmp.nodeName=="DIV"){
          var str="hello world!"
        }
        var obj=window.getComputedStyle(childTmp);
        if(obj.hasOwnProperty("position")){
          if(obj.position=="fixed" && (obj.bottom=="0px" || obj.left=='0px' || obj.right=='0px')){
            var widthTmp=parseInt(obj.width.replace(/[^0-9]/ig,""));
            if(widthTmp>=1000){
		    continue;
	    }
            isIncludeLiInFixedEle(childTmp);
            if(fixedWithLiResult){
              fixedWithLiResult=false;
              continue;
            }
            console.log('......Github......');
	    console.log(childTmp);
	    console.log(obj.bottom);
	    console.log(obj.left);
	    console.log(obj.right);
	    console.log('......Github......');
            childTmp.style.display="none";
          }
        }
      }
      traverseDOM(childTmp);
    }
  }
}

setTimeout(function(){
 traverseDOM(document.body);
},1000);

window.addEventListener('scroll',function(e){
	traverseDOM(document.body);
});

<|endoftext|>


<commit_before>'use strict'

const Scheduler = require('qos_scheduler')
const Performance = require('qos_performance')
const Process = require('qos_process')

global.BUCKET_EMERGENCY = 1000
global.BUCKET_FLOOR = 2000
global.BUCKET_CEILING = 9500
const CPU_BUFFER = 130
const CPU_MINIMUM = 0.50
const CPU_ADJUST = 0.05
const CPU_GLOBAL_BOOST = 60
const MINIMUM_PROGRAMS = 0.3
const PROGRAM_NORMALIZING_BURST = 2
const GLOBAL_LAST_RESET = Game.time

class QosKernel {
  constructor () {
    global.kernel = this

    if (!Memory.qos) {
      Memory.qos = {}
    }
    this.newglobal = GLOBAL_LAST_RESET === Game.time
    this.simulation = !!Game.rooms['sim']
    this.scheduler = new Scheduler()
    this.performance = new Performance()
    this.process = Process
  }

  start () {
    // Announce new uploads
    Logger.log(`Initializing Kernel for tick ${Game.time}`, LOG_TRACE, 'kernel')
    if (!Memory.qos.script_version || Memory.qos.script_version !== SCRIPT_VERSION) {
      Logger.log(`New script upload detected: ${SCRIPT_VERSION}`, LOG_WARN)
      Memory.qos.script_version = SCRIPT_VERSION
      Memory.qos.script_upload = Game.time
    }

    sos.lib.segments.moveToGlobalCache()
    sos.lib.stormtracker.track()

    if (Game.time % 7 === 0) {
      this.cleanMemory()
    }

    this.scheduler.shift()

    if (this.scheduler.getProcessCount() <= 0) {
      this.scheduler.launchProcess('player')
    }
  }

  cleanMemory () {
    Logger.log('Cleaning memory', LOG_TRACE, 'kernel')
    let i
    for (i in Memory.creeps) { // jshint ignore:line
      if (!Game.creeps[i]) {
        delete Memory.creeps[i]
      }
    }

    sos.lib.cache.clean()
    qlib.notify.clean()
  }

  run () {
    while (this.shouldContinue()) {
      const runningProcess = this.scheduler.getNextProcess()
      if (!runningProcess) {
        return
      }
      Logger.defaultLogGroup = runningProcess.name
      try {
        let processName = runningProcess.name
        const descriptor = runningProcess.getDescriptor()
        if (descriptor) {
          processName += ' ' + descriptor
        }

        Logger.log(`Running ${processName} (pid ${runningProcess.pid})`, LOG_TRACE, 'kernel')
        const startCpu = Game.cpu.getUsed()
        runningProcess.run()
        let performanceName = runningProcess.name
        const performanceDescriptor = runningProcess.getPerformanceDescriptor()
        if (performanceDescriptor) {
          performanceName += ' ' + performanceDescriptor
        }
        this.performance.addProgramStats(performanceName, Game.cpu.getUsed() - startCpu)
      } catch (err) {
        let message = 'program error occurred\n'
        message += `process ${runningProcess.pid}: ${runningProcess.name}\n`
        message += !!err && !!err.stack ? err.stack : err.toString()
        Logger.log(message, LOG_ERROR)
      }
      Logger.defaultLogGroup = 'default'
    }
  }

  sigmoid (x) {
    return 1.0 / (1.0 + Math.exp(-x))
  }

  sigmoidSkewed (x) {
    return this.sigmoid((x * 12.0) - 6.0)
  }

  shouldContinue () {
    if (this.simulation) {
      return true
    }

    // Make sure to stop if cpuUsed has hit the maximum allowed cpu.
    const cpuUsed = Game.cpu.getUsed()
    if (cpuUsed >= Game.cpu.tickLimit - CPU_BUFFER) {
      return false
    }

    // Allow if the cpu used is less than this tick's limit.
    const cpuLimit = this.getCpuLimit()
    if (cpuUsed < cpuLimit) {
      return true
    }

    // Ensure that a minumum number of processes runs each tick.
    // This is primarily useful for garbage collection cycles.
    if (Game.cpu.bucket > BUCKET_FLOOR) {
      const total = this.scheduler.getProcessCount()
      const completed = this.scheduler.getCompletedProcessCount()
      if (completed / total < MINIMUM_PROGRAMS) {
        if (cpuUsed < cpuLimit * PROGRAM_NORMALIZING_BURST) {
          return true
        }
      }
    }

    return false
  }

  getCpuLimit () {
    if (Game.cpu.bucket > BUCKET_CEILING) {
      return Game.cpu.tickLimit - CPU_BUFFER
    }

    if (Game.cpu.bucket < BUCKET_EMERGENCY) {
      return 0
    }

    if (Game.cpu.bucket < BUCKET_FLOOR) {
      return Game.cpu.limit * CPU_MINIMUM
    }

    if (!this._cpuLimit) {
      const bucketRange = BUCKET_CEILING - BUCKET_FLOOR
      const depthInRange = (Game.cpu.bucket - BUCKET_FLOOR) / bucketRange
      const minToAllocate = Game.cpu.limit * CPU_MINIMUM
      const maxToAllocate = Game.cpu.limit
      this._cpuLimit = (minToAllocate + this.sigmoidSkewed(depthInRange) * (maxToAllocate - minToAllocate)) * (1 - CPU_ADJUST)
      if (this.newglobal) {
        this._cpuLimit += CPU_GLOBAL_BOOST
      }
    }

    return this._cpuLimit
  }

  shutdown () {
    sos.lib.vram.saveDirty()
    sos.lib.segments.process()

    const processCount = this.scheduler.getProcessCount()
    const completedCount = this.scheduler.memory.processes.completed.length

    Logger.log(`Processes Run: ${completedCount}/${processCount}`, LOG_INFO, 'kernel')
    Logger.log(`Tick Limit: ${Game.cpu.tickLimit}`, LOG_INFO, 'kernel')
    Logger.log(`Kernel Limit: ${this.getCpuLimit()}`, LOG_INFO, 'kernel')
    Logger.log(`CPU Used: ${Game.cpu.getUsed()}`, LOG_INFO, 'kernel')
    Logger.log(`Bucket: ${Game.cpu.bucket}`, LOG_INFO, 'kernel')

    if (Game.time % 50 === 0) {
      this.performance.reportHtml()
    }
    if (Game.time % 3000 === 0) {
      this.performance.clear()
    }
  }
}

module.exports = QosKernel
<commit_msg>When bucket > BUCKET_CEILING don't use more than 5% of bucket<commit_after>'use strict'

const Scheduler = require('qos_scheduler')
const Performance = require('qos_performance')
const Process = require('qos_process')

global.BUCKET_EMERGENCY = 1000
global.BUCKET_FLOOR = 2000
global.BUCKET_CEILING = 9500
const CPU_BUFFER = 130
const CPU_MINIMUM = 0.50
const CPU_ADJUST = 0.05
const CPU_GLOBAL_BOOST = 60
const MINIMUM_PROGRAMS = 0.3
const PROGRAM_NORMALIZING_BURST = 2
const GLOBAL_LAST_RESET = Game.time

class QosKernel {
  constructor () {
    global.kernel = this

    if (!Memory.qos) {
      Memory.qos = {}
    }
    this.newglobal = GLOBAL_LAST_RESET === Game.time
    this.simulation = !!Game.rooms['sim']
    this.scheduler = new Scheduler()
    this.performance = new Performance()
    this.process = Process
  }

  start () {
    // Announce new uploads
    Logger.log(`Initializing Kernel for tick ${Game.time}`, LOG_TRACE, 'kernel')
    if (!Memory.qos.script_version || Memory.qos.script_version !== SCRIPT_VERSION) {
      Logger.log(`New script upload detected: ${SCRIPT_VERSION}`, LOG_WARN)
      Memory.qos.script_version = SCRIPT_VERSION
      Memory.qos.script_upload = Game.time
    }

    sos.lib.segments.moveToGlobalCache()
    sos.lib.stormtracker.track()

    if (Game.time % 7 === 0) {
      this.cleanMemory()
    }

    this.scheduler.shift()

    if (this.scheduler.getProcessCount() <= 0) {
      this.scheduler.launchProcess('player')
    }
  }

  cleanMemory () {
    Logger.log('Cleaning memory', LOG_TRACE, 'kernel')
    let i
    for (i in Memory.creeps) { // jshint ignore:line
      if (!Game.creeps[i]) {
        delete Memory.creeps[i]
      }
    }

    sos.lib.cache.clean()
    qlib.notify.clean()
  }

  run () {
    while (this.shouldContinue()) {
      const runningProcess = this.scheduler.getNextProcess()
      if (!runningProcess) {
        return
      }
      Logger.defaultLogGroup = runningProcess.name
      try {
        let processName = runningProcess.name
        const descriptor = runningProcess.getDescriptor()
        if (descriptor) {
          processName += ' ' + descriptor
        }

        Logger.log(`Running ${processName} (pid ${runningProcess.pid})`, LOG_TRACE, 'kernel')
        const startCpu = Game.cpu.getUsed()
        runningProcess.run()
        let performanceName = runningProcess.name
        const performanceDescriptor = runningProcess.getPerformanceDescriptor()
        if (performanceDescriptor) {
          performanceName += ' ' + performanceDescriptor
        }
        this.performance.addProgramStats(performanceName, Game.cpu.getUsed() - startCpu)
      } catch (err) {
        let message = 'program error occurred\n'
        message += `process ${runningProcess.pid}: ${runningProcess.name}\n`
        message += !!err && !!err.stack ? err.stack : err.toString()
        Logger.log(message, LOG_ERROR)
      }
      Logger.defaultLogGroup = 'default'
    }
  }

  sigmoid (x) {
    return 1.0 / (1.0 + Math.exp(-x))
  }

  sigmoidSkewed (x) {
    return this.sigmoid((x * 12.0) - 6.0)
  }

  shouldContinue () {
    if (this.simulation) {
      return true
    }

    // Make sure to stop if cpuUsed has hit the maximum allowed cpu.
    const cpuUsed = Game.cpu.getUsed()
    if (cpuUsed >= Game.cpu.tickLimit - CPU_BUFFER) {
      return false
    }

    // Allow if the cpu used is less than this tick's limit.
    const cpuLimit = this.getCpuLimit()
    if (cpuUsed < cpuLimit) {
      return true
    }

    // Ensure that a minumum number of processes runs each tick.
    // This is primarily useful for garbage collection cycles.
    if (Game.cpu.bucket > BUCKET_FLOOR) {
      const total = this.scheduler.getProcessCount()
      const completed = this.scheduler.getCompletedProcessCount()
      if (completed / total < MINIMUM_PROGRAMS) {
        if (cpuUsed < cpuLimit * PROGRAM_NORMALIZING_BURST) {
          return true
        }
      }
    }

    return false
  }

  getCpuLimit () {
    if (Game.cpu.bucket > BUCKET_CEILING) {
      return Math.min(Game.cpu.tickLimit - CPU_BUFFER, Game.cpu.bucket * 0.05)
    }

    if (Game.cpu.bucket < BUCKET_EMERGENCY) {
      return 0
    }

    if (Game.cpu.bucket < BUCKET_FLOOR) {
      return Game.cpu.limit * CPU_MINIMUM
    }

    if (!this._cpuLimit) {
      const bucketRange = BUCKET_CEILING - BUCKET_FLOOR
      const depthInRange = (Game.cpu.bucket - BUCKET_FLOOR) / bucketRange
      const minToAllocate = Game.cpu.limit * CPU_MINIMUM
      const maxToAllocate = Game.cpu.limit
      this._cpuLimit = (minToAllocate + this.sigmoidSkewed(depthInRange) * (maxToAllocate - minToAllocate)) * (1 - CPU_ADJUST)
      if (this.newglobal) {
        this._cpuLimit += CPU_GLOBAL_BOOST
      }
    }

    return this._cpuLimit
  }

  shutdown () {
    sos.lib.vram.saveDirty()
    sos.lib.segments.process()

    const processCount = this.scheduler.getProcessCount()
    const completedCount = this.scheduler.memory.processes.completed.length

    Logger.log(`Processes Run: ${completedCount}/${processCount}`, LOG_INFO, 'kernel')
    Logger.log(`Tick Limit: ${Game.cpu.tickLimit}`, LOG_INFO, 'kernel')
    Logger.log(`Kernel Limit: ${this.getCpuLimit()}`, LOG_INFO, 'kernel')
    Logger.log(`CPU Used: ${Game.cpu.getUsed()}`, LOG_INFO, 'kernel')
    Logger.log(`Bucket: ${Game.cpu.bucket}`, LOG_INFO, 'kernel')

    if (Game.time % 50 === 0) {
      this.performance.reportHtml()
    }
    if (Game.time % 3000 === 0) {
      this.performance.clear()
    }
  }
}

module.exports = QosKernel
<|endoftext|>


<commit_before>'use strict';

var Download = require('../');
var fs = require('fs');
var path = require('path');
var fixture = path.join.bind(path, __dirname, 'fixtures');
var nock = require('nock');
var rm = require('rimraf');
var test = require('ava');

test('expose a constructor', function (t) {
	t.plan(1);
	t.assert(typeof Download === 'function');
});

test('return an instance if it called without `new`', function (t) {
	t.plan(1);
	t.assert(Download() instanceof Download);
});

test('set a file to get', function (t) {
	t.plan(1);

	var download = new Download()
		.get('http://example.com/test.jpg');

	t.assert(download._get[0].url === 'http://example.com/test.jpg');
});

test('download a file', function (t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'test-file.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
		});
});

test('download multiple files', function (t) {
	t.plan(7);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'))
		.get('/nested/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test-file.zip')
		.get('http://foo.com/nested/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files.length === 2);
			t.assert(files[0].path === 'test-file.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
			t.assert(files[1].path === 'test-file.zip');
			t.assert(files[1].url === 'http://foo.com/nested/test-file.zip');
		});
});

test('download a file and rename it', function (t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test-file.zip')
		.rename('foobar.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(path.basename(files[0].path) === 'foobar.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
		});
});

test('download and extract a file', function (t) {
	t.plan(3);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download({extract: true})
		.get('http://foo.com/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'file.txt');
		});
});

test('specify destination folder', function (t) {
	t.plan(4);

	var d0 = path.join(__dirname, 'tmp');
	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'))
		.get('/test.js')
		.replyWithFile(200, __filename);

	new Download({extract: true})
		.get('http://foo.com/test-file.zip')
		.get('http://foo.com/test.js')
		.dest(d0)
		.run(function (err, files) {
			var r0 = fs.readdirSync(d0);
			t.assert(!err, err);
			t.assert(scope.isDone());
			rm.sync(d0);
			t.assert(r0[0] === 'file.txt');
			t.assert(r0[1] === 'test.js');
		});
});

test('specify multiple destination folders', function (t) {
	t.plan(4);

	var d1 = path.join(__dirname, 't1');
	var d2 = path.join(__dirname, 't2');
	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'))
		.get('/test.js')
		.replyWithFile(200, __filename);

	new Download({extract: true})
		.get('http://foo.com/test-file.zip', d1)
		.get('http://foo.com/test.js')
		.dest(d2)
		.run(function (err, files) {
			var r1 = fs.readdirSync(d1);
			var r2 = fs.readdirSync(d2);
			t.assert(!err, err);
			t.assert(scope.isDone());
			rm.sync(d1);
			rm.sync(d2);
			t.assert(r1[0] === 'file.txt');
			t.assert(r2[0] === 'test.js');
		});
});

test('rename file to a valid filename', function (t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.get('/test?file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test?file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'test!file.zip');
			t.assert(files[0].url === 'http://foo.com/test?file.zip');
		});
});

test('error on invalid URL', function (t) {
	t.plan(1);

	new Download()
		.get('foobar')
		.run(function (err) {
			t.assert(err.message === 'Specify a valid URL');
		});
});

test('request options', function(t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.matchHeader('authorization', 'Basic dXNlcjpwYXNzd29yZA==')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download({auth: 'user:password'})
		.get('http://foo.com/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'test-file.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
		});
});
<commit_msg>Minor tweaks<commit_after>'use strict';

var Download = require('../');
var fs = require('fs');
var path = require('path');
var fixture = path.join.bind(path, __dirname, 'fixtures');
var nock = require('nock');
var rm = require('rimraf');
var test = require('ava');

test('expose a constructor', function (t) {
	t.plan(1);
	t.assert(typeof Download === 'function');
});

test('return an instance if it called without `new`', function (t) {
	t.plan(1);
	t.assert(Download() instanceof Download);
});

test('set a file to get', function (t) {
	t.plan(1);

	var download = new Download()
		.get('http://example.com/test.jpg');

	t.assert(download._get[0].url === 'http://example.com/test.jpg');
});

test('download a file', function (t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'test-file.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
		});
});

test('download multiple files', function (t) {
	t.plan(7);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'))
		.get('/nested/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test-file.zip')
		.get('http://foo.com/nested/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files.length === 2);
			t.assert(files[0].path === 'test-file.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
			t.assert(files[1].path === 'test-file.zip');
			t.assert(files[1].url === 'http://foo.com/nested/test-file.zip');
		});
});

test('download a file and rename it', function (t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test-file.zip')
		.rename('foobar.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(path.basename(files[0].path) === 'foobar.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
		});
});

test('download and extract a file', function (t) {
	t.plan(3);

	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download({extract: true})
		.get('http://foo.com/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'file.txt');
		});
});

test('specify destination folder', function (t) {
	t.plan(4);

	var d0 = path.join(__dirname, 'tmp');
	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'))
		.get('/test.js')
		.replyWithFile(200, __filename);

	new Download({extract: true})
		.get('http://foo.com/test-file.zip')
		.get('http://foo.com/test.js')
		.dest(d0)
		.run(function (err, files) {
			var r0 = fs.readdirSync(d0);
			t.assert(!err, err);
			t.assert(scope.isDone());
			rm.sync(d0);
			t.assert(r0[0] === 'file.txt');
			t.assert(r0[1] === 'test.js');
		});
});

test('specify multiple destination folders', function (t) {
	t.plan(4);

	var d1 = path.join(__dirname, 't1');
	var d2 = path.join(__dirname, 't2');
	var scope = nock('http://foo.com')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'))
		.get('/test.js')
		.replyWithFile(200, __filename);

	new Download({extract: true})
		.get('http://foo.com/test-file.zip', d1)
		.get('http://foo.com/test.js')
		.dest(d2)
		.run(function (err, files) {
			var r1 = fs.readdirSync(d1);
			var r2 = fs.readdirSync(d2);
			t.assert(!err, err);
			t.assert(scope.isDone());
			rm.sync(d1);
			rm.sync(d2);
			t.assert(r1[0] === 'file.txt');
			t.assert(r2[0] === 'test.js');
		});
});

test('rename file to a valid filename', function (t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.get('/test?file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download()
		.get('http://foo.com/test?file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'test!file.zip');
			t.assert(files[0].url === 'http://foo.com/test?file.zip');
		});
});

test('error on invalid URL', function (t) {
	t.plan(1);

	new Download()
		.get('foobar')
		.run(function (err) {
			t.assert(err.message === 'Specify a valid URL');
		});
});

test('request options', function (t) {
	t.plan(4);

	var scope = nock('http://foo.com')
		.matchHeader('authorization', 'Basic dXNlcjpwYXNzd29yZA==')
		.get('/test-file.zip')
		.replyWithFile(200, fixture('test-file.zip'));

	new Download({auth: 'user:password'})
		.get('http://foo.com/test-file.zip')
		.run(function (err, files) {
			t.assert(!err, err);
			t.assert(scope.isDone());
			t.assert(files[0].path === 'test-file.zip');
			t.assert(files[0].url === 'http://foo.com/test-file.zip');
		});
});
<|endoftext|>


<commit_before>'use strict'

const assert = require('assert')

describe('Array', () => {
    describe('#indexOf()', () => {
        it('should return -1 when the value is not present', () => {
            assert.equal(-1, [1, 2, 3].indexOf(4))
        })
    })
})
<commit_msg>testing Scrapers.find<commit_after>'use strict'

const assert = require('assert')

const Scrapers = require('../scrapers')

describe('Scrapers', () => {
    const stubFunction = () => undefined
    const appObjectsMock = {
        config: {
            scrapers: ['scraperA', 'scraperB'],
        },
        logger: {
            debug: stubFunction,
            info: stubFunction,
        },
    }

    function onCreatePageEmptyMock(query, phantomObjects) {
        return new Promise(resolve => {
            phantomObjects
                .instancePromise
                .then(instance => instance.exit())
            resolve(new Map())
        })
    }

    describe('#find()', () => {
        it('should merge empty maps', done => {
            const createPageCallbacks = {
                scraperA: onCreatePageEmptyMock,
                scraperB: onCreatePageEmptyMock,
            }

            const scrapers = new Scrapers(appObjectsMock, createPageCallbacks)
            scrapers
                .find('hello')
                .then(results => assert.equal(results, ''))
                .then(done)
        })

        it('should sort by bot names', () => {})

        it('should ignore bots names case-sensitivity', () => {})

        it('should override previous descriptions', () => {})

        it('should trim description whitespace', () => {})

        it('should remove URLs from description', () => {})

        it('should remove @ from description', () => {})

        it('should remove new lines from description', () => {})
    })
})
<|endoftext|>