<commit_before>/*global define */
/*jslint white: true, browser: true, plusplus: true */
define([
    'kb/common/html',
    'kb_sdk_clients/SetAPI/dev/SetAPIClient',
    'kb/service/client/workspace',
    '../utils',
    'text!../../resources/html/reads_set.html',
    'bluebird',
    'jquery',
    'underscore',
    'handlebars',
    'numeral',
    'datatables',
    'datatables_bootstrap'
    ],
    function (html, SetAPI, Workspace, utils, RSTemplate, Promise,
              $, _, handlebars, Numeral, DataTable, DataTable_BS) {
        'use strict';

        //http://localhost:8080/#dataview/11700/set_o_reads/1
        function factory(config) {
            var parent,
                container,
                runtime = config.runtime,
                reads_set_data = {},
                div = html.tag('div'),
                templates = $.parseHTML(RSTemplate),
                outer = templates[0].innerHTML,
                browse_fill = "{{#each readLibraries}}"
                            + "
"
                            + "{{this.name}}	"
                            + "{{this.type}}	"
                            + "{{this.data.read_count}}	"
                            + "{{this.data.read_size}}	"
                            + "{{this.data.insert_size_mean}}	"
                            + "
"
                            + "{{/each}}";

            // VIEW

            function layout() {
                return div(
                    html.makePanel({
                        title: 'Summary',
                        content: outer
                    })
                );
            }

            function setDataElementHTML(element, value) {
                try {
                    container.querySelector("[data-element='" + element + "']").innerHTML = value;
                }
                catch (err) {
                    console.error("While setting data element '" + element + "':", err);
                    throw err;
                }
            }

            function renderSummary(data) {
                var formatValue = function (data, type, row) {
                    var out = Numeral(data).format('0,0');

                    if (out === '0') {
                        return "Missing";
                    } else {
                        return out;
                    }
                };

                setDataElementHTML('reads-set-description', data.set.description);
                setDataElementHTML('reads-set-type', data.set.type);
                setDataElementHTML('reads-set-libraries-count',
                                   Numeral(data.set.item_count).format('0,0'));
                setDataElementHTML('reads-set-total-reads',
                                   Numeral(data.set.stats.read_count).format('0,0'));
                setDataElementHTML('reads-set-total-basepairs',
                                   Numeral(data.set.stats.bp_count).format('0,0'));
                container.querySelector('[id="reads-set-browse-id"] table tbody').innerHTML = handlebars.compile(browse_fill)({'readLibraries': data.row_contents});
                $('[id="reads-set-browse-id"]').removeClass('hidden');
                $('[id="reads-set-browse-table"]').DataTable({
                    "columns": [
                    {data: 'name'},
                    {data: 'type'},
                    {
                        data: 'data.read_count',
                        render: formatValue
                    },
                    {
                        data: 'data.read_size',
                        render: formatValue
                    },
                    {
                        data: 'data.insert_size_mean',
                        render: formatValue
                    }
                    ]
                });
            }

            // utility functions

            function getReadsSetClient() {
                return new SetAPI({
                    url: runtime.getConfig('services.service_wizard.url'),
                    auth: {token: runtime.service('session').getAuthToken() },
                    version: 'release'
                });
            }

            function getWorkspaceClient() {
                return new Workspace(
                    runtime.getConfig('services.workspace.url'),
                    {token: runtime.service('session').getAuthToken()}
                );
            }

            function fetchReadsSet(params) {
                var setAPI = getReadsSetClient(),
                    wsClient = getWorkspaceClient(),
                    readsSetInfo = {};

                return Promise.resolve(setAPI.get_reads_set_v1({
                    'ref': utils.getRef(params),
                    'include_item_info': 1
                    }))
                    .then(function (results) {
                        var refs = [],
                            i = 0,
                            reads_type = results.data.items[0].info[2];
                        readsSetInfo.set = {
                            name: results.info[1],
                            type: results.data.items[0].info[2].split('-')[0].split('.')[1],
                            description: results.data.description,
                            items: results.data.items,
                            item_count: results.data.items.length
                        };

                        // pull all reads objects to calculate summary stats
                        // and individual browse row contents
                        for (i = 0; i < readsSetInfo.set.items.length; i++) {
                            if (reads_type !== readsSetInfo.set.items[i].info[2]) {
                                readsSetInfo.set.type = "Mixed Reads";
                            }
                            refs.push({'ref':readsSetInfo.set.items[i].ref});
                        }

                        return refs;
                    })
                    .then(function (refs) {
                        return Promise.resolve(wsClient.get_objects(refs));
                    })
                    .then(function (data) {
                        var i = 0,
                            results = {};
                        readsSetInfo.row_contents = data;
                        readsSetInfo.set.stats = {
                            read_count: 0,
                            bp_count: 0
                        };
                        // calculate summary stats
                        for (i = 0; i < data.length; i++) {
                            readsSetInfo.row_contents[i].name = data[i].info[1];
                            readsSetInfo.row_contents[i].type = data[i].info[2].split('-')[0].split('.')[1];
                            if (data[i].data.hasOwnProperty('read_count')) {
                                readsSetInfo.set.stats.read_count += data[i].data.read_count;
                                if (data[i].data.hasOwnProperty('read_size')) {
                                    readsSetInfo.set.stats.bp_count += data[i].data.read_count * data[i].data.read_size;
                                }
                            }
                        }
                        return readsSetInfo;
                    })
                    .error(function (err) {
                        console.error(err);
                        container.empty();
                        container.appendChild('Error' + JSON.stringify(err));
                    });
            }

            // WIDGET API
            function attach(node) {
                parent = node;
                container = parent.appendChild(document.createElement('div'));
                container.innerHTML = layout();
            }

            function start(params) {
                Array.from(container.querySelectorAll("[data-element]"))
                .forEach(function (e) {
                    e.innerHTML = html.loading();
                });

                return fetchReadsSet(params).then(function (results) {
                    renderSummary(results);
                });
            }

            function stop() {
                // nothing to do
            }

            function detach() {
                // nothing to do necessarily, since the parent dom node will
                // be removed the controller for this widget removes it,
                // but it is nice to take responsibility for undoing what we
                // changed in the parent node:
                if (parent && container) {
                    container.innerHTML = '';
                    parent.removeChild(container);
                }
            }

            return Object.freeze({
                attach: attach,
                start: start,
                stop: stop,
                detach: detach
            });
        }

        return {
            make: function (config) {
                return factory(config);
            }
        };
    });<commit_msg>removed extra datatables require parameter, switched Array.from to Array.prototype.slice.call<commit_after>/*global define */
/*jslint white: true, browser: true, plusplus: true */
define([
    'kb/common/html',
    'kb_sdk_clients/SetAPI/dev/SetAPIClient',
    'kb/service/client/workspace',
    '../utils',
    'text!../../resources/html/reads_set.html',
    'bluebird',
    'jquery',
    'underscore',
    'handlebars',
    'numeral',
    'datatables',
    'datatables_bootstrap'
    ],
    function (html, SetAPI, Workspace, utils, RSTemplate, Promise,
              $, _, handlebars, Numeral, DataTable) {
        'use strict';

        //http://localhost:8080/#dataview/11700/set_o_reads/1
        function factory(config) {
            var parent,
                container,
                runtime = config.runtime,
                reads_set_data = {},
                div = html.tag('div'),
                templates = $.parseHTML(RSTemplate),
                outer = templates[0].innerHTML,
                browse_fill = "{{#each readLibraries}}"
                            + "
"
                            + "{{this.name}}	"
                            + "{{this.type}}	"
                            + "{{this.data.read_count}}	"
                            + "{{this.data.read_size}}	"
                            + "{{this.data.insert_size_mean}}	"
                            + "
"
                            + "{{/each}}";

            // VIEW

            function layout() {
                return div(
                    html.makePanel({
                        title: 'Summary',
                        content: outer
                    })
                );
            }

            function setDataElementHTML(element, value) {
                try {
                    container.querySelector("[data-element='" + element + "']").innerHTML = value;
                }
                catch (err) {
                    console.error("While setting data element '" + element + "':", err);
                    throw err;
                }
            }

            function renderSummary(data) {
                var formatValue = function (data, type, row) {
                    var out = Numeral(data).format('0,0');

                    if (out === '0') {
                        return "Missing";
                    } else {
                        return out;
                    }
                };

                setDataElementHTML('reads-set-description', data.set.description);
                setDataElementHTML('reads-set-type', data.set.type);
                setDataElementHTML('reads-set-libraries-count',
                                   Numeral(data.set.item_count).format('0,0'));
                setDataElementHTML('reads-set-total-reads',
                                   Numeral(data.set.stats.read_count).format('0,0'));
                setDataElementHTML('reads-set-total-basepairs',
                                   Numeral(data.set.stats.bp_count).format('0,0'));
                container.querySelector('[id="reads-set-browse-id"] table tbody').innerHTML = handlebars.compile(browse_fill)({'readLibraries': data.row_contents});
                $('[id="reads-set-browse-id"]').removeClass('hidden');
                $('[id="reads-set-browse-table"]').DataTable({
                    "columns": [
                    {data: 'name'},
                    {data: 'type'},
                    {
                        data: 'data.read_count',
                        render: formatValue
                    },
                    {
                        data: 'data.read_size',
                        render: formatValue
                    },
                    {
                        data: 'data.insert_size_mean',
                        render: formatValue
                    }
                    ]
                });
            }

            // utility functions

            function getReadsSetClient() {
                return new SetAPI({
                    url: runtime.getConfig('services.service_wizard.url'),
                    auth: {token: runtime.service('session').getAuthToken() },
                    version: 'release'
                });
            }

            function getWorkspaceClient() {
                return new Workspace(
                    runtime.getConfig('services.workspace.url'),
                    {token: runtime.service('session').getAuthToken()}
                );
            }

            function fetchReadsSet(params) {
                var setAPI = getReadsSetClient(),
                    wsClient = getWorkspaceClient(),
                    readsSetInfo = {};

                return Promise.resolve(setAPI.get_reads_set_v1({
                    'ref': utils.getRef(params),
                    'include_item_info': 1
                    }))
                    .then(function (results) {
                        var refs = [],
                            i = 0,
                            reads_type = results.data.items[0].info[2];
                        readsSetInfo.set = {
                            name: results.info[1],
                            type: results.data.items[0].info[2].split('-')[0].split('.')[1],
                            description: results.data.description,
                            items: results.data.items,
                            item_count: results.data.items.length
                        };

                        // pull all reads objects to calculate summary stats
                        // and individual browse row contents
                        for (i = 0; i < readsSetInfo.set.items.length; i++) {
                            if (reads_type !== readsSetInfo.set.items[i].info[2]) {
                                readsSetInfo.set.type = "Mixed Reads";
                            }
                            refs.push({'ref':readsSetInfo.set.items[i].ref});
                        }

                        return refs;
                    })
                    .then(function (refs) {
                        return Promise.resolve(wsClient.get_objects(refs));
                    })
                    .then(function (data) {
                        var i = 0,
                            results = {};
                        readsSetInfo.row_contents = data;
                        readsSetInfo.set.stats = {
                            read_count: 0,
                            bp_count: 0
                        };
                        // calculate summary stats
                        for (i = 0; i < data.length; i++) {
                            readsSetInfo.row_contents[i].name = data[i].info[1];
                            readsSetInfo.row_contents[i].type = data[i].info[2].split('-')[0].split('.')[1];
                            if (data[i].data.hasOwnProperty('read_count')) {
                                readsSetInfo.set.stats.read_count += data[i].data.read_count;
                                if (data[i].data.hasOwnProperty('read_size')) {
                                    readsSetInfo.set.stats.bp_count += data[i].data.read_count * data[i].data.read_size;
                                }
                            }
                        }
                        return readsSetInfo;
                    })
                    .error(function (err) {
                        console.error(err);
                        container.empty();
                        container.appendChild('Error' + JSON.stringify(err));
                    });
            }

            // WIDGET API
            function attach(node) {
                parent = node;
                container = parent.appendChild(document.createElement('div'));
                container.innerHTML = layout();
            }

            function start(params) {
                Array.prototype.slice.call(container.querySelectorAll("[data-element]"))
                .forEach(function (e) {
                    e.innerHTML = html.loading();
                });

                return fetchReadsSet(params).then(function (results) {
                    renderSummary(results);
                });
            }

            function stop() {
                // nothing to do
            }

            function detach() {
                // nothing to do necessarily, since the parent dom node will
                // be removed the controller for this widget removes it,
                // but it is nice to take responsibility for undoing what we
                // changed in the parent node:
                if (parent && container) {
                    container.innerHTML = '';
                    parent.removeChild(container);
                }
            }

            return Object.freeze({
                attach: attach,
                start: start,
                stop: stop,
                detach: detach
            });
        }

        return {
            make: function (config) {
                return factory(config);
            }
        };
    });<|endoftext|>


<commit_before>Tools.extend = extend;
Tools.random = random;
Tools.round = round;
Tools.tan = tan;
Tools.sin = sin;
Tools.cos = cos;
Tools.atan = atan;
Tools.asin = asin;
Tools.acos = acos;
module.exports = Tools;

function Tools(base) {
    for(var tool in Tools) {
        if(Tools.hasOwnProperty(tool)) {
            base[tool] = module.exports[tool];
        }
    }
}

function extend(    ) {
    var objs = Array.prototype.slice.call(arguments);
    var newObj = {};
    while(objs[0]) {
        var obj = objs.shift();
        for(var key in obj) {
            if(!obj.hasOwnProperty(key)) { continue; }
            newObj[key] = obj[key];
        }
    }
    return newObj;
}

function random(limit) {
    return Math.floor(Math.random() * (limit || 100)) || 0
}

function round(number, precision) {
    if(number % 1 == 0) { return number; }
    precision = precision || 0;
    m = precision != undefined ? Math.pow(10, precision) : 1;
    return Math.round(number * m) / m;
}

function tan(input) {
    return Math.tan(input * Math.PI / 180);
}

function sin(input) {
    return Math.sin(input * Math.PI / 180);
}

function cos(input) {
    return Math.cos(input * Math.PI / 180);
}

function atan(input) {
    return Math.atan(input) / Math.PI * 180;
}

function asin(input) {
    return Math.asin(input) / Math.PI * 180;
}

function acos(input) {
    return Math.acos(input) / Math.PI * 180;
}
<commit_msg>tools.random should not floor the random number it generates<commit_after>Tools.extend = extend;
Tools.random = random;
Tools.round = round;
Tools.tan = tan;
Tools.sin = sin;
Tools.cos = cos;
Tools.atan = atan;
Tools.asin = asin;
Tools.acos = acos;
module.exports = Tools;

function Tools(base) {
    for(var tool in Tools) {
        if(Tools.hasOwnProperty(tool)) {
            base[tool] = module.exports[tool];
        }
    }
}

function extend(    ) {
    var objs = Array.prototype.slice.call(arguments);
    var newObj = {};
    while(objs[0]) {
        var obj = objs.shift();
        for(var key in obj) {
            if(!obj.hasOwnProperty(key)) { continue; }
            newObj[key] = obj[key];
        }
    }
    return newObj;
}

function random(limit) {
    return Math.random() * (limit || 100) || 0
}

function round(number, precision) {
    if(number % 1 == 0) { return number; }
    precision = precision || 0;
    m = precision != undefined ? Math.pow(10, precision) : 1;
    return Math.round(number * m) / m;
}

function tan(input) {
    return Math.tan(input * Math.PI / 180);
}

function sin(input) {
    return Math.sin(input * Math.PI / 180);
}

function cos(input) {
    return Math.cos(input * Math.PI / 180);
}

function atan(input) {
    return Math.atan(input) / Math.PI * 180;
}

function asin(input) {
    return Math.asin(input) / Math.PI * 180;
}

function acos(input) {
    return Math.acos(input) / Math.PI * 180;
}
<|endoftext|>


<commit_before>var gulp = require('gulp');
var resemble = require('node-resemble-js');
var paths = require('../util/paths');
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var junitWriter = new (require('junitwriter'))();

gulp.task('compare', function (done) {
    var compareConfig = JSON.parse(fs.readFileSync(paths.compareConfigFileName, 'utf8')).compareConfig,
    testSuite = paths.report && paths.report.indexOf( 'CI' ) > -1 && paths.ciReport.format === 'junit' && junitWriter.addTestsuite(paths.ci.testSuiteName),
    testPairsLength;

    function updateProgress() {
        var results = {};
        _.each(compareConfig.testPairs, function (pair) {
            if (!results[pair.testStatus]) {
                results[pair.testStatus] = 0;
            }
            !results[pair.testStatus]++;
        });
        if (!results.running) {
            console.log ('\nTest completed...');
            console.log ('\x1b[32m', (results.pass || 0) + ' Passed', '\x1b[0m');
            console.log ('\x1b[31m', (results.fail || 0) + ' Failed\n', '\x1b[0m');

            if (results.fail) {
                console.log ('\x1b[31m', '*** Mismatch errors found ***', '\x1b[0m');
                console.log ("For a detailed report run `npm run openReport`\n");
                if (paths.cliExitOnFail) {
                    done(new Error('Mismatch errors found.'));
                }
            }
        }
    }

    _.each(compareConfig.testPairs, function (pair, key) {
        pair.testStatus = "running";
        testPairsLength = !testPairsLength && compareConfig.testPairs.length;

        var referencePath = path.join(paths.backstop, pair.reference);
        var testPath = path.join(paths.backstop, pair.test);

        resemble(referencePath).compareTo(testPath).onComplete(function (data) {
            var imageComparisonFailed = !data.isSameDimensions || data.misMatchPercentage > pair.misMatchThreshold,
            error,
            testCase;

            if (imageComparisonFailed) {
                pair.testStatus = "fail";
                console.log('\x1b[31m', 'ERROR:', pair.label, pair.fileName, '\x1b[0m');
                storeFailedDiffImage(testPath, data);
            } else {
                pair.testStatus = "pass";
                console.log('\x1b[32m', 'OK:', pair.label, pair.fileName, '\x1b[0m');
            }

            // add testcase only when there is a design deviation
            if (testSuite && imageComparisonFailed) {
                testCase = testSuite.addTestcase(' ›› ' + pair.label, pair.selector);
                error = 'Design deviation ›› ' + pair.label + ' (' + pair.selector + ') component';
                testCase.addError(error, 'CSS component');
                testCase.addFailure(error, 'CSS component');
            }

            if (testSuite && testPairsLength === key + 1) {
                junitWriter.save(path.join(paths.ci_report, 'xunit.xml'), function() {
                    console.log('\x1b[32m', 'Regression test report file (xunit.xml) is successfully created.', '\x1b[0m');
                });
            }

            updateProgress();
        });
    });

    function storeFailedDiffImage(testPath, data) {
        var failedDiffFilename = getFailedDiffFilename(testPath);
        console.log('   See:', failedDiffFilename);
        var failedDiffStream = fs.createWriteStream(failedDiffFilename);
        data.getDiffImage().pack().pipe(failedDiffStream)
    }

    function getFailedDiffFilename(testPath) {
        var lastSlash = testPath.lastIndexOf(path.sep);
        return testPath.slice(0, lastSlash + 1) + 'failed_diff_' + testPath.slice(lastSlash + 1, testPath.length);
    }
});
<commit_msg>custom testSuiteName fix<commit_after>var gulp = require('gulp');
var resemble = require('node-resemble-js');
var paths = require('../util/paths');
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var junitWriter = new (require('junitwriter'))();

gulp.task('compare', function (done) {
    var compareConfig = JSON.parse(fs.readFileSync(paths.compareConfigFileName, 'utf8')).compareConfig,
    testSuite = paths.report && paths.report.indexOf( 'CI' ) > -1 && paths.ciReport.format === 'junit' && junitWriter.addTestsuite(paths.ciReport.testSuiteName),
    testPairsLength;

    function updateProgress() {
        var results = {};
        _.each(compareConfig.testPairs, function (pair) {
            if (!results[pair.testStatus]) {
                results[pair.testStatus] = 0;
            }
            !results[pair.testStatus]++;
        });
        if (!results.running) {
            console.log ('\nTest completed...');
            console.log ('\x1b[32m', (results.pass || 0) + ' Passed', '\x1b[0m');
            console.log ('\x1b[31m', (results.fail || 0) + ' Failed\n', '\x1b[0m');

            if (results.fail) {
                console.log ('\x1b[31m', '*** Mismatch errors found ***', '\x1b[0m');
                console.log ("For a detailed report run `npm run openReport`\n");
                if (paths.cliExitOnFail) {
                    done(new Error('Mismatch errors found.'));
                }
            }
        }
    }

    _.each(compareConfig.testPairs, function (pair, key) {
        pair.testStatus = "running";
        testPairsLength = !testPairsLength && compareConfig.testPairs.length;

        var referencePath = path.join(paths.backstop, pair.reference);
        var testPath = path.join(paths.backstop, pair.test);

        resemble(referencePath).compareTo(testPath).onComplete(function (data) {
            var imageComparisonFailed = !data.isSameDimensions || data.misMatchPercentage > pair.misMatchThreshold,
            error,
            testCase;

            if (imageComparisonFailed) {
                pair.testStatus = "fail";
                console.log('\x1b[31m', 'ERROR:', pair.label, pair.fileName, '\x1b[0m');
                storeFailedDiffImage(testPath, data);
            } else {
                pair.testStatus = "pass";
                console.log('\x1b[32m', 'OK:', pair.label, pair.fileName, '\x1b[0m');
            }

            // add testcase only when there is a design deviation
            if (testSuite && imageComparisonFailed) {
                testCase = testSuite.addTestcase(' ›› ' + pair.label, pair.selector);
                error = 'Design deviation ›› ' + pair.label + ' (' + pair.selector + ') component';
                testCase.addError(error, 'CSS component');
                testCase.addFailure(error, 'CSS component');
            }

            if (testSuite && testPairsLength === key + 1) {
                junitWriter.save(path.join(paths.ci_report, 'xunit.xml'), function() {
                    console.log('\x1b[32m', 'Regression test report file (xunit.xml) is successfully created.', '\x1b[0m');
                });
            }

            updateProgress();
        });
    });

    function storeFailedDiffImage(testPath, data) {
        var failedDiffFilename = getFailedDiffFilename(testPath);
        console.log('   See:', failedDiffFilename);
        var failedDiffStream = fs.createWriteStream(failedDiffFilename);
        data.getDiffImage().pack().pipe(failedDiffStream)
    }

    function getFailedDiffFilename(testPath) {
        var lastSlash = testPath.lastIndexOf(path.sep);
        return testPath.slice(0, lastSlash + 1) + 'failed_diff_' + testPath.slice(lastSlash + 1, testPath.length);
    }
});
<|endoftext|>


<commit_before><commit_msg>add default gulp task<commit_after>var gulp = require('gulp');

gulp.task('default', ['build:dist'], function(){
  console.log('Welcome to the gulp generator of ngcontactmep!');
  console.log('The default tasks build the distribution version');
  console.log('The other tasks are')
  console.log('- gulp serve:dev')
  console.log('    build the development version, serve it and watch the dev files for changes')
  console.log('- gulp serve:dist')
  console.log('    build the distribution version, serve it ')
  console.log('- gulp build:dev')
   console.log('    build the development version')
  console.log('- gulp build:dist')
  console.log('    build the distribution version')
  console.log('-gulp delete')
   console.log('    delete all build files')
   console.log('- gulp delete:dev')
   console.log('    delete all development build files')
   console.log('- gulp delete:dist')
   console.log('    delete all distribution build files')
});<|endoftext|>


<commit_before>var gulp = require('gulp');

gulp.task('default', [
  'less',
  'copy',
  'build',
  'server:sync',
  'watch',
  'server'
]);
<commit_msg>user group server task for default gulp task<commit_after>var gulp = require('gulp');

gulp.task('default', [
  'less',
  'copy',
  'build',
  'server',
  'watch'
]);
<|endoftext|>


<commit_before>var gulp = require('gulp');
var gulpif = require('gulp-if');
var svg2png = require('gulp-svg2png');
var config = require('../config.js');

gulp.task('svg2png', function() {
    return gulp.src(config.src + 'svg/*.svg')
        .pipe(gulpif(config.svgFallback, svg2png()))
        .pipe(gulp.dest(config.build + 'img/svg-fallbacks/'));
});
<commit_msg>Fix svg fallbacks gulp task<commit_after>var gulp = require('gulp');
var gulpif = require('gulp-if');
var svg2png = require('gulp-svg2png');
var config = require('../config.js');

gulp.task('svg2png', function() {
    return gulp.src(config.src + 'svg/*.svg')
        .pipe(gulpif(config.svgFallback, svg2png()))
        .pipe(gulpif(config.svgFallback, gulp.dest(config.build + 'img/svg-fallbacks/')));
});
<|endoftext|>


<commit_before>
	handleEvent: function (e) {
		switch ( e.type ) {
			case 'touchstart':
			case 'pointerdown':
			case 'MSPointerDown':
			case 'mousedown':
				this._start(e);
				break;
			case 'touchmove':
			case 'pointermove':
			case 'MSPointerMove':
			case 'mousemove':
				this._move(e);
				break;
			case 'touchend':
			case 'pointerup':
			case 'MSPointerUp':
			case 'mouseup':
			case 'touchcancel':
			case 'pointercancel':
			case 'MSPointerCancel':
			case 'mousecancel':
				this._end(e);
				break;
			case 'orientationchange':
			case 'resize':
				this._resize();
				break;
			case 'transitionend':
			case 'webkitTransitionEnd':
			case 'oTransitionEnd':
			case 'MSTransitionEnd':
				this._transitionEnd(e);
				break;
			case 'wheel':
			case 'DOMMouseScroll':
			case 'mousewheel':
				this._wheel(e);
				break;
			case 'keydown':
				this._key(e);
				break;
			case 'click':
				if ( !e._constructed ) {
					e.preventDefault();
					e.stopPropagation();
				}
				break;
		}
	}
};<commit_msg>Update handleEvent.js<commit_after>
	handleEvent: function (e) {
		switch ( e.type ) {
			case 'touchstart':
			case 'pointerdown':
			case 'MSPointerDown':
			case 'mousedown':
				this._start(e);
				break;
			case 'touchmove':
			case 'pointermove':
			case 'MSPointerMove':
			case 'mousemove':
				this._move(e);
				break;
			case 'touchend':
			case 'pointerup':
			case 'MSPointerUp':
			case 'mouseup':
			case 'touchcancel':
			case 'pointercancel':
			case 'MSPointerCancel':
			case 'mousecancel':
				this._end(e);
				break;
			case 'orientationchange':
			case 'resize':
				this._resize();
				break;
			case 'transitionend':
			case 'webkitTransitionEnd':
			case 'oTransitionEnd':
			case 'MSTransitionEnd':
				this._transitionEnd(e);
				break;
			case 'wheel':
			case 'DOMMouseScroll':
			case 'mousewheel':
				this._wheel(e);
				break;
			case 'keydown':
				this._key(e);
				break;
			case 'click':
				if ( !e._constructed && !this.options.disableMouse ) {
					e.preventDefault();
					e.stopPropagation();
				}
				break;
		}
	}
};
<|endoftext|>


<commit_before>/** @babel */

import {it, beforeEach, afterEach, promisifySome} from './async-spec-helpers'
import tempCb from 'temp'
import fsCb from 'fs-plus'
import path from 'path'

import {CompositeDisposable} from 'event-kit'
import watchPath, {stopAllWatchers} from '../src/path-watcher'

tempCb.track()

const fs = promisifySome(fsCb, ['writeFile', 'mkdir', 'symlink', 'appendFile', 'realpath'])
const temp = promisifySome(tempCb, ['mkdir'])

describe('PathWatcher', function () {
  let subs

  beforeEach(function () {
    subs = new CompositeDisposable()
  })

  afterEach(async function () {
    subs.dispose()
    await stopAllWatchers()
  })

  function waitForChanges (watcher, ...fileNames) {
    const waiting = new Set(fileNames)
    let fired = false
    const relevantEvents = []

    return new Promise(resolve => {
      const sub = watcher.onDidChange(events => {
        for (const event of events) {
          if (waiting.delete(event.oldPath)) {
            relevantEvents.push(event)
          }
        }

        if (!fired && waiting.size === 0) {
          fired = true
          resolve(relevantEvents)
          sub.dispose()
        }
      })
    })
  }

  describe('watchPath()', function () {
    it('resolves getStartPromise() when the watcher begins listening', async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher = watchPath(rootDir, {}, () => {})
      await watcher.getStartPromise()
    })

    it('reuses an existing native watcher and resolves getStartPromise immediately if attached to a running watcher', async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher0 = watchPath(rootDir, {}, () => {})
      await watcher0.getStartPromise()

      const watcher1 = watchPath(rootDir, {}, () => {})
      await watcher1.getStartPromise()

      expect(watcher0.native).toBe(watcher1.native)
    })

    it("reuses existing native watchers even while they're still starting", async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher0 = watchPath(rootDir, {}, () => {})
      await watcher0.getAttachedPromise()
      expect(watcher0.native.isRunning()).toBe(false)

      const watcher1 = watchPath(rootDir, {}, () => {})
      await watcher1.getAttachedPromise()

      expect(watcher0.native).toBe(watcher1.native)

      await Promise.all([watcher0.getStartPromise(), watcher1.getStartPromise()])
    })

    it("doesn't attach new watchers to a native watcher that's stopping", async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher0 = watchPath(rootDir, {}, () => {})
      await watcher0.getStartPromise()
      const native0 = watcher0.native

      watcher0.dispose()

      const watcher1 = watchPath(rootDir, {}, () => {})

      expect(watcher1.native).not.toBe(native0)
    })

    it('reuses an existing native watcher on a parent directory and filters events', async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-').then(fs.realpath)
      const rootFile = path.join(rootDir, 'rootfile.txt')
      const subDir = path.join(rootDir, 'subdir')
      const subFile = path.join(subDir, 'subfile.txt')

      await fs.mkdir(subDir)

      // Keep the watchers alive with an undisposed subscription
      const rootWatcher = watchPath(rootDir, {}, () => {})
      const childWatcher = watchPath(subDir, {}, () => {})

      await Promise.all([
        rootWatcher.getStartPromise(),
        childWatcher.getStartPromise()
      ])

      expect(rootWatcher.native).toBe(childWatcher.native)
      expect(rootWatcher.native.isRunning()).toBe(true)

      const firstChanges = Promise.all([
        waitForChanges(rootWatcher, subFile),
        waitForChanges(childWatcher, subFile)
      ])

      await fs.writeFile(subFile, 'subfile\n', {encoding: 'utf8'})
      await firstChanges

      const nextRootEvent = waitForChanges(rootWatcher, rootFile)
      await fs.writeFile(rootFile, 'rootfile\n', {encoding: 'utf8'})

      await nextRootEvent
    })

    it('adopts existing child watchers and filters events appropriately to them', async function () {
      const parentDir = await temp.mkdir('atom-fsmanager-test-').then(fs.realpath)

      // Create the directory tree
      const rootFile = path.join(parentDir, 'rootfile.txt')
      const subDir0 = path.join(parentDir, 'subdir0')
      const subFile0 = path.join(subDir0, 'subfile0.txt')
      const subDir1 = path.join(parentDir, 'subdir1')
      const subFile1 = path.join(subDir1, 'subfile1.txt')

      await fs.mkdir(subDir0)
      await fs.mkdir(subDir1)
      await Promise.all([
        fs.writeFile(rootFile, 'rootfile\n', {encoding: 'utf8'}),
        fs.writeFile(subFile0, 'subfile 0\n', {encoding: 'utf8'}),
        fs.writeFile(subFile1, 'subfile 1\n', {encoding: 'utf8'})
      ])

      // Begin the child watchers and keep them alive
      const subWatcher0 = watchPath(subDir0, {}, () => {})
      const subWatcherChanges0 = waitForChanges(subWatcher0, subFile0)

      const subWatcher1 = watchPath(subDir1, {}, () => {})
      const subWatcherChanges1 = waitForChanges(subWatcher1, subFile1)

      await Promise.all(
        [subWatcher0, subWatcher1].map(watcher => watcher.getStartPromise())
      )
      expect(subWatcher0.native).not.toBe(subWatcher1.native)

      // Create the parent watcher
      const parentWatcher = watchPath(parentDir, {}, () => {})
      const parentWatcherChanges = waitForChanges(parentWatcher, rootFile, subFile0, subFile1)

      await parentWatcher.getStartPromise()

      expect(subWatcher0.native).toBe(parentWatcher.native)
      expect(subWatcher1.native).toBe(parentWatcher.native)

      // Ensure events are filtered correctly
      await Promise.all([
        fs.appendFile(rootFile, 'change\n', {encoding: 'utf8'}),
        fs.appendFile(subFile0, 'change\n', {encoding: 'utf8'}),
        fs.appendFile(subFile1, 'change\n', {encoding: 'utf8'})
      ])

      await Promise.all([
        subWatcherChanges0,
        subWatcherChanges1,
        parentWatcherChanges
      ])
    })
  })
})
<commit_msg>Update spec name<commit_after>/** @babel */

import {it, beforeEach, afterEach, promisifySome} from './async-spec-helpers'
import tempCb from 'temp'
import fsCb from 'fs-plus'
import path from 'path'

import {CompositeDisposable} from 'event-kit'
import watchPath, {stopAllWatchers} from '../src/path-watcher'

tempCb.track()

const fs = promisifySome(fsCb, ['writeFile', 'mkdir', 'symlink', 'appendFile', 'realpath'])
const temp = promisifySome(tempCb, ['mkdir'])

describe('watchPath', function () {
  let subs

  beforeEach(function () {
    subs = new CompositeDisposable()
  })

  afterEach(async function () {
    subs.dispose()
    await stopAllWatchers()
  })

  function waitForChanges (watcher, ...fileNames) {
    const waiting = new Set(fileNames)
    let fired = false
    const relevantEvents = []

    return new Promise(resolve => {
      const sub = watcher.onDidChange(events => {
        for (const event of events) {
          if (waiting.delete(event.oldPath)) {
            relevantEvents.push(event)
          }
        }

        if (!fired && waiting.size === 0) {
          fired = true
          resolve(relevantEvents)
          sub.dispose()
        }
      })
    })
  }

  describe('watchPath()', function () {
    it('resolves getStartPromise() when the watcher begins listening', async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher = watchPath(rootDir, {}, () => {})
      await watcher.getStartPromise()
    })

    it('reuses an existing native watcher and resolves getStartPromise immediately if attached to a running watcher', async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher0 = watchPath(rootDir, {}, () => {})
      await watcher0.getStartPromise()

      const watcher1 = watchPath(rootDir, {}, () => {})
      await watcher1.getStartPromise()

      expect(watcher0.native).toBe(watcher1.native)
    })

    it("reuses existing native watchers even while they're still starting", async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher0 = watchPath(rootDir, {}, () => {})
      await watcher0.getAttachedPromise()
      expect(watcher0.native.isRunning()).toBe(false)

      const watcher1 = watchPath(rootDir, {}, () => {})
      await watcher1.getAttachedPromise()

      expect(watcher0.native).toBe(watcher1.native)

      await Promise.all([watcher0.getStartPromise(), watcher1.getStartPromise()])
    })

    it("doesn't attach new watchers to a native watcher that's stopping", async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-')

      const watcher0 = watchPath(rootDir, {}, () => {})
      await watcher0.getStartPromise()
      const native0 = watcher0.native

      watcher0.dispose()

      const watcher1 = watchPath(rootDir, {}, () => {})

      expect(watcher1.native).not.toBe(native0)
    })

    it('reuses an existing native watcher on a parent directory and filters events', async function () {
      const rootDir = await temp.mkdir('atom-fsmanager-test-').then(fs.realpath)
      const rootFile = path.join(rootDir, 'rootfile.txt')
      const subDir = path.join(rootDir, 'subdir')
      const subFile = path.join(subDir, 'subfile.txt')

      await fs.mkdir(subDir)

      // Keep the watchers alive with an undisposed subscription
      const rootWatcher = watchPath(rootDir, {}, () => {})
      const childWatcher = watchPath(subDir, {}, () => {})

      await Promise.all([
        rootWatcher.getStartPromise(),
        childWatcher.getStartPromise()
      ])

      expect(rootWatcher.native).toBe(childWatcher.native)
      expect(rootWatcher.native.isRunning()).toBe(true)

      const firstChanges = Promise.all([
        waitForChanges(rootWatcher, subFile),
        waitForChanges(childWatcher, subFile)
      ])

      await fs.writeFile(subFile, 'subfile\n', {encoding: 'utf8'})
      await firstChanges

      const nextRootEvent = waitForChanges(rootWatcher, rootFile)
      await fs.writeFile(rootFile, 'rootfile\n', {encoding: 'utf8'})

      await nextRootEvent
    })

    it('adopts existing child watchers and filters events appropriately to them', async function () {
      const parentDir = await temp.mkdir('atom-fsmanager-test-').then(fs.realpath)

      // Create the directory tree
      const rootFile = path.join(parentDir, 'rootfile.txt')
      const subDir0 = path.join(parentDir, 'subdir0')
      const subFile0 = path.join(subDir0, 'subfile0.txt')
      const subDir1 = path.join(parentDir, 'subdir1')
      const subFile1 = path.join(subDir1, 'subfile1.txt')

      await fs.mkdir(subDir0)
      await fs.mkdir(subDir1)
      await Promise.all([
        fs.writeFile(rootFile, 'rootfile\n', {encoding: 'utf8'}),
        fs.writeFile(subFile0, 'subfile 0\n', {encoding: 'utf8'}),
        fs.writeFile(subFile1, 'subfile 1\n', {encoding: 'utf8'})
      ])

      // Begin the child watchers and keep them alive
      const subWatcher0 = watchPath(subDir0, {}, () => {})
      const subWatcherChanges0 = waitForChanges(subWatcher0, subFile0)

      const subWatcher1 = watchPath(subDir1, {}, () => {})
      const subWatcherChanges1 = waitForChanges(subWatcher1, subFile1)

      await Promise.all(
        [subWatcher0, subWatcher1].map(watcher => watcher.getStartPromise())
      )
      expect(subWatcher0.native).not.toBe(subWatcher1.native)

      // Create the parent watcher
      const parentWatcher = watchPath(parentDir, {}, () => {})
      const parentWatcherChanges = waitForChanges(parentWatcher, rootFile, subFile0, subFile1)

      await parentWatcher.getStartPromise()

      expect(subWatcher0.native).toBe(parentWatcher.native)
      expect(subWatcher1.native).toBe(parentWatcher.native)

      // Ensure events are filtered correctly
      await Promise.all([
        fs.appendFile(rootFile, 'change\n', {encoding: 'utf8'}),
        fs.appendFile(subFile0, 'change\n', {encoding: 'utf8'}),
        fs.appendFile(subFile1, 'change\n', {encoding: 'utf8'})
      ])

      await Promise.all([
        subWatcherChanges0,
        subWatcherChanges1,
        parentWatcherChanges
      ])
    })
  })
})
<|endoftext|>


<commit_before>class RcdMaterialDialogContentArea extends RcdDivElement {
    constructor(title) {
        super();
        this.title = title ? new RcdTextDivElement(title).init().
            addClass('rcd-material-dialog-title') : undefined;
        this.body = new RcdDivElement().init().
            addClass('rcd-material-dialog-body');
    }

    init() {
        super.init().
            addClass('rcd-material-dialog-content-area');
        if (this.title) {
            this.addChild(this.title);
        }
        return this.addChild(this.body);
    }

    addItem(item) {
        this.body.addChild(item);
        return this;
    }
}

class RcdMaterialDialog extends RcdDivElement {
    constructor(title, text) {
        super();
        this.contentArea = new RcdMaterialDialogContentArea(title).init();
        if (text) {
            const textItem = new RcdTextElement(text).init();
            this.contentArea.addItem(textItem);
        }
        this.actions = new RcdDivElement().init().
            addClass('rcd-material-dialog-actions');
    }

    init() {
        return this.addClass('rcd-material-dialog').
            addChild(this.contentArea).
            addChild(this.actions);
    }

    addItem(item) {
        this.contentArea.addChild(item);
    }

    addAction(label, callback) {
        const action = new RcdMaterialButtonArea(label, callback, RcdMaterialButtonType.FLAT).init().
            addClass('rcd-material-dialog-action');
        this.actions.addChild(action);
        return this;
    }
}

class RcdMaterialModalDialog extends RcdDivElement {
    constructor(title, text, overlay) {
        super();
        this.overlay = overlay;
        this.dialog = new RcdMaterialDialog(title, text).init();
    }

    init() {
        if (this.overlay) {
            this.addClass('rcd-material-overlay');
        }
        return this.addClass('rcd-material-cache').
            addClass('rcd-body'). //Workaround for widget
            addChild(this.dialog);
    }

    addItem(item) {
        this.dialog.addItem(item);
        return this;
    }

    addAction(label, callback) {
        this.dialog.addAction(label, callback);
        return this;
    }

    open(parent) {
        return this.setParent(parent).
            focus();
    }

    close() {
        this.removeParent();
    }
}

class RcdMaterialInfoDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, false);
    }
}

class RcdMaterialDetailsDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
    }

    init() {
        const closeCallback = () => this.close();
        super.init().
            addAction('CLOSE', closeCallback).
            addKeyUpListener('Enter', closeCallback).
            addKeyUpListener('Escape', closeCallback);
        return this;
    }
}

class RcdMaterialConfirmationDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = () => {
            this.close();
            this.callback();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback);
    }
}

class RcdMaterialSelectionDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.dropdownField = new RcdMaterialDropdown(params.label, params.options).init();
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = () => {
            this.close();
            this.callback(this.dropdownField.getValue());
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.dropdownField);
    }

    open(parent) {
        super.open(parent);
        this.dropdownField.focus();
        return this;
    }
}

class RcdMaterialInputDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.inputField = new RcdMaterialTextField(params.label, params.placeholder).init().
            setValue(params.value || '');
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = () => {
            this.close();
            this.callback(this.inputField.getValue());
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.inputField);
    }

    open(parent) {
        super.open(parent);
        this.inputField.focus().select();
        return this;
    }
}<commit_msg>2.0 refactoring<commit_after>class RcdMaterialDialogContentArea extends RcdDivElement {
    constructor(title) {
        super();
        this.title = title ? new RcdTextDivElement(title).init().
            addClass('rcd-material-dialog-title') : undefined;
        this.body = new RcdDivElement().init().
            addClass('rcd-material-dialog-body');
    }

    init() {
        super.init().
            addClass('rcd-material-dialog-content-area');
        if (this.title) {
            this.addChild(this.title);
        }
        return this.addChild(this.body);
    }

    addItem(item) {
        this.body.addChild(item);
        return this;
    }
}

class RcdMaterialDialog extends RcdDivElement {
    constructor(title, text) {
        super();
        this.contentArea = new RcdMaterialDialogContentArea(title).init();
        if (text) {
            const textItem = new RcdTextElement(text).init();
            this.contentArea.addItem(textItem);
        }
        this.actions = new RcdDivElement().init().
            addClass('rcd-material-dialog-actions');
    }

    init() {
        return this.addClass('rcd-material-dialog').
            addChild(this.contentArea).
            addChild(this.actions);
    }

    addItem(item) {
        this.contentArea.addChild(item);
    }

    addAction(label, callback) {
        const action = new RcdMaterialButtonArea(label, callback, RcdMaterialButtonType.FLAT).init().
            addClass('rcd-material-dialog-action');
        this.actions.addChild(action);
        return this;
    }
}

class RcdMaterialModalDialog extends RcdDivElement {
    constructor(title, text, overlay) {
        super();
        this.overlay = overlay;
        this.dialog = new RcdMaterialDialog(title, text).init();
    }

    init() {
        if (this.overlay) {
            this.addClass('rcd-material-overlay');
        }
        return this.addClass('rcd-material-cache').
            addClass('rcd-body'). //Workaround for widget
            addChild(this.dialog);
    }

    addItem(item) {
        this.dialog.addItem(item);
        return this;
    }

    addAction(label, callback) {
        this.dialog.addAction(label, callback);
        return this;
    }

    open(parent) {
        return this.setParent(parent).
            focus();
    }

    close() {
        this.removeParent();
    }
}

class RcdMaterialInfoDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, false);
    }
}

class RcdMaterialDetailsDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
    }

    init() {
        const closeCallback = () => this.close();
        super.init().
            addAction('CLOSE', closeCallback).
            addKeyUpListener('Enter', closeCallback).
            addKeyUpListener('Escape', closeCallback);
        return this;
    }
}

class RcdMaterialConfirmationDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback();
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback);
    }
}

class RcdMaterialSelectionDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.dropdownField = new RcdMaterialDropdown(params.label, params.options).init();
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback(this.dropdownField.getValue());
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.dropdownField);
    }

    open(parent) {
        super.open(parent);
        this.dropdownField.focus();
        return this;
    }
}

class RcdMaterialInputDialog extends RcdMaterialModalDialog {
    constructor(params) {
        super(params.title, params.text, true);
        this.callback = params.callback;
        this.inputField = new RcdMaterialTextField(params.label, params.placeholder).init().
            setValue(params.value || '');
        this.confirmationLabel = params.confirmationLabel || 'OK';
    }

    init() {
        const closeCallback = () => this.close();
        const confirmationCallback = (source, event) => {
            this.close();
            this.callback(this.inputField.getValue());
            event.stopPropagation();
        };
        return super.init().
            addAction('CANCEL', closeCallback).
            addAction(this.confirmationLabel, confirmationCallback).
            addKeyUpListener('Enter', confirmationCallback).
            addKeyUpListener('Escape', closeCallback).
            addItem(this.inputField);
    }

    open(parent) {
        super.open(parent);
        this.inputField.focus().select();
        return this;
    }
}<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const fs = require('fs');
const log = require('./lib/log.js');

function loadPage(driver, gatherers, options) {
  const loadPage = options.flags.loadPage;
  const url = options.url;

  if (loadPage) {
    return driver.gotoURL(url, {waitForLoad: true});
  }

  return Promise.resolve();
}

function reloadPage(driver, options) {
  // Since a Page.reload command does not let a service worker take over, we
  // navigate away and then come back to reload. We do not `waitForLoad` on
  // about:blank since a page load event is never fired on it.
  return driver.gotoURL('about:blank')
    .then(_ => driver.gotoURL(options.url, {waitForLoad: true}));
}

function setupDriver(driver, gatherers, options) {
  return new Promise((resolve, reject) => {
    // Enable emulation.
    if (options.flags.mobile) {
      return resolve(driver.beginEmulation());
    }

    // noop if no mobile emulation
    resolve();
  }).then(_ => {
    return driver.cleanAndDisableBrowserCaches();
  }).then(_ => {
    // Force SWs to update on load.
    return driver.forceUpdateServiceWorkers();
  });
}

// Enable tracing and network record collection.
function beginPassiveCollection(driver) {
  return driver.beginTrace()
    .then(_ => driver.beginNetworkCollect());
}

function endPassiveCollection(options, tracingData) {
  const driver = options.driver;
  const saveTrace = options.flags.saveTrace;
  return driver.endNetworkCollect().then(networkRecords => {
    tracingData.networkRecords = networkRecords;
  }).then(_ => {
    return driver.endTrace();
  }).then(traceContents => {
    tracingData.traceContents = traceContents;
  }).then(_ => {
    return saveTrace && saveAssets(tracingData, options.url);
  });
}

function phaseRunner(gatherers) {
  return function runPhase(gatherFun) {
    return gatherers.reduce((chain, gatherer) => {
      return chain.then(_ => gatherFun(gatherer));
    }, Promise.resolve());
  };
}

function saveArtifacts(artifacts) {
  const artifactsFilename = 'artifacts.log';
  // The _target property of NetworkRequest is circular.
  // We skip it when stringifying.
  const replacer = (key, value) => key === '_target' ? undefined : value;
  fs.writeFileSync(artifactsFilename, JSON.stringify(artifacts, replacer));
  log.log('info', 'artifacts file saved to disk', artifactsFilename);
}

function saveAssets(tracingData, url) {
  const date = new Date();
  const hostname = url.match(/^.*?\/\/(.*?)(:?\/|$)/)[1];
  const filename = (hostname + '_' + date.toISOString() + '.trace.json')
      .replace(/[\/\?<>\\:\*\|":]/g, '-');
  fs.writeFileSync(filename, JSON.stringify(tracingData.traceContents, null, 2));
  log.log('info', 'trace file saved to disk', filename);
}

function run(gatherers, options) {
  const driver = options.driver;
  const tracingData = {};

  if (typeof options.url !== 'string' || options.url.length === 0) {
    return Promise.reject(new Error('You must provide a url to scheduler'));
  }

  const runPhase = phaseRunner(gatherers);

  return driver.connect()
    // Initial prep before the page load.
    .then(_ => setupDriver(driver, gatherers, options))
    .then(_ => runPhase(gatherer => gatherer.setup(options)))
    .then(_ => beginPassiveCollection(driver))
    .then(_ => runPhase(gatherer => gatherer.beforePageLoad(options)))

    // Load page, gather from browser, stop profilers.
    .then(_ => loadPage(driver, gatherers, options))
    .then(_ => runPhase(gatherer => gatherer.profiledPostPageLoad(options)))
    .then(_ => endPassiveCollection(options, tracingData))
    .then(_ => runPhase(gatherer => gatherer.postProfiling(options, tracingData)))

    // Reload page for SW, etc.
    .then(_ => runPhase(gatherer => gatherer.reloadSetup(options)))
    .then(_ => runPhase(gatherer => gatherer.beforeReloadPageLoad(options)))
    .then(_ => reloadPage(driver, options))
    .then(_ => runPhase(gatherer => gatherer.afterReloadPageLoad(options)))

    // Reload page again for HTTPS redirect
    .then(_ => {
      options.url = options.url.replace(/^https/, 'http');
    })
    .then(_ => reloadPage(driver, options))
    .then(_ => runPhase(gatherer => gatherer.afterSecondReloadPageLoad(options)))

    // Finish and teardown.
    .then(_ => driver.disconnect())
    .then(_ => runPhase(gatherer => gatherer.tearDown(options)))
    .then(_ => {
      // Collate all the gatherer results.
      const artifacts = gatherers.reduce((artifacts, gatherer) => {
        artifacts[gatherer.name] = gatherer.artifact;
        return artifacts;
      }, {
        networkRecords: tracingData.networkRecords,
        rawNetworkEvents: tracingData.rawNetworkEvents,
        traceContents: tracingData.traceContents,
        frameLoadEvents: tracingData.frameLoadEvents
      });

      if (options.flags.saveArtifacts) {
        saveArtifacts(artifacts);
      }

      return artifacts;
    });
}

module.exports = {
  loadPage,
  reloadPage,
  setupDriver,
  beginPassiveCollection,
  endPassiveCollection,
  phaseRunner,
  run,
  saveAssets
};
<commit_msg>Fixes (or appears to) the occasional hang<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const fs = require('fs');
const log = require('./lib/log.js');

function loadPage(driver, gatherers, options) {
  const loadPage = options.flags.loadPage;
  const url = options.url;

  if (loadPage) {
    return driver.gotoURL(url, {waitForLoad: true});
  }

  return Promise.resolve();
}

function reloadPage(driver, options) {
  // Since a Page.reload command does not let a service worker take over, we
  // navigate away and then come back to reload. We do not `waitForLoad` on
  // about:blank since a page load event is never fired on it.
  return driver.gotoURL('about:blank')
    // Wait one second for about:blank to "take hold" before switching back to the page.
    .then(_ => new Promise((resolve, reject) => setTimeout(resolve, 300)))
    .then(_ => driver.gotoURL(options.url, {waitForLoad: true}));
}

function setupDriver(driver, gatherers, options) {
  return new Promise((resolve, reject) => {
    // Enable emulation.
    if (options.flags.mobile) {
      return resolve(driver.beginEmulation());
    }

    // noop if no mobile emulation
    resolve();
  }).then(_ => {
    return driver.cleanAndDisableBrowserCaches();
  }).then(_ => {
    // Force SWs to update on load.
    return driver.forceUpdateServiceWorkers();
  });
}

// Enable tracing and network record collection.
function beginPassiveCollection(driver) {
  return driver.beginTrace()
    .then(_ => driver.beginNetworkCollect());
}

function endPassiveCollection(options, tracingData) {
  const driver = options.driver;
  const saveTrace = options.flags.saveTrace;
  return driver.endNetworkCollect().then(networkRecords => {
    tracingData.networkRecords = networkRecords;
  }).then(_ => {
    return driver.endTrace();
  }).then(traceContents => {
    tracingData.traceContents = traceContents;
  }).then(_ => {
    return saveTrace && saveAssets(tracingData, options.url);
  });
}

function phaseRunner(gatherers) {
  return function runPhase(gatherFun) {
    return gatherers.reduce((chain, gatherer) => {
      return chain.then(_ => gatherFun(gatherer));
    }, Promise.resolve());
  };
}

function saveArtifacts(artifacts) {
  const artifactsFilename = 'artifacts.log';
  // The _target property of NetworkRequest is circular.
  // We skip it when stringifying.
  const replacer = (key, value) => key === '_target' ? undefined : value;
  fs.writeFileSync(artifactsFilename, JSON.stringify(artifacts, replacer));
  log.log('info', 'artifacts file saved to disk', artifactsFilename);
}

function saveAssets(tracingData, url) {
  const date = new Date();
  const hostname = url.match(/^.*?\/\/(.*?)(:?\/|$)/)[1];
  const filename = (hostname + '_' + date.toISOString() + '.trace.json')
      .replace(/[\/\?<>\\:\*\|":]/g, '-');
  fs.writeFileSync(filename, JSON.stringify(tracingData.traceContents, null, 2));
  log.log('info', 'trace file saved to disk', filename);
}

function run(gatherers, options) {
  const driver = options.driver;
  const tracingData = {};

  if (typeof options.url !== 'string' || options.url.length === 0) {
    return Promise.reject(new Error('You must provide a url to scheduler'));
  }

  const runPhase = phaseRunner(gatherers);

  return driver.connect()
    // Initial prep before the page load.
    .then(_ => setupDriver(driver, gatherers, options))
    .then(_ => runPhase(gatherer => gatherer.setup(options)))
    .then(_ => beginPassiveCollection(driver))
    .then(_ => runPhase(gatherer => gatherer.beforePageLoad(options)))

    // Load page, gather from browser, stop profilers.
    .then(_ => loadPage(driver, gatherers, options))
    .then(_ => runPhase(gatherer => gatherer.profiledPostPageLoad(options)))
    .then(_ => endPassiveCollection(options, tracingData))
    .then(_ => runPhase(gatherer => gatherer.postProfiling(options, tracingData)))

    // Reload page for SW, etc.
    .then(_ => runPhase(gatherer => gatherer.reloadSetup(options)))
    .then(_ => runPhase(gatherer => gatherer.beforeReloadPageLoad(options)))
    .then(_ => reloadPage(driver, options))
    .then(_ => runPhase(gatherer => gatherer.afterReloadPageLoad(options)))

    // Reload page again for HTTPS redirect
    .then(_ => {
      options.url = options.url.replace(/^https/, 'http');
    })
    .then(_ => reloadPage(driver, options))
    .then(_ => runPhase(gatherer => gatherer.afterSecondReloadPageLoad(options)))

    // Finish and teardown.
    .then(_ => driver.disconnect())
    .then(_ => runPhase(gatherer => gatherer.tearDown(options)))
    .then(_ => {
      // Collate all the gatherer results.
      const artifacts = gatherers.reduce((artifacts, gatherer) => {
        artifacts[gatherer.name] = gatherer.artifact;
        return artifacts;
      }, {
        networkRecords: tracingData.networkRecords,
        rawNetworkEvents: tracingData.rawNetworkEvents,
        traceContents: tracingData.traceContents,
        frameLoadEvents: tracingData.frameLoadEvents
      });

      if (options.flags.saveArtifacts) {
        saveArtifacts(artifacts);
      }

      return artifacts;
    });
}

module.exports = {
  loadPage,
  reloadPage,
  setupDriver,
  beginPassiveCollection,
  endPassiveCollection,
  phaseRunner,
  run,
  saveAssets
};
<|endoftext|>


<commit_before>var chai = require('chai');
var assert = require('assert');
var expect = chai.expect
var RequestHash = require('../src/request_hash');

describe('RequestHash with Empty Body', function() {
  var exampleRequestA = {
    headers: {'authorization': '12345', 'content-type': 'application/json'},
    body: ''
  }

  var exampleRequestB = {
    headers: {'authorization': '98745', 'content-type': 'application/json'},
    body: ''
  }

  describe('toString()', function() {
    it('should NOT be equal when headers are considered', function () {
      var cacheHeadersAuthorization = ['authorization']
      var hashA = new RequestHash(exampleRequestA, cacheHeadersAuthorization);
      var hashB = new RequestHash(exampleRequestB, cacheHeadersAuthorization);

      expect(hashA.toString()).to.not.equal(hashB.toString());
    });

    it('should be equal when headers are NOT considered', function () {
      var cacheHeaders = []
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);
      var hashB = new RequestHash(exampleRequestB, cacheHeaders);

      expect(hashA.toString()).to.equal(hashB.toString());
    });
  });

  describe('_filteredAttributes()', function() {
    it('should NOT be equal when headers are considered', function () {
      var cacheHeadersAuthorization = ['authorization']
      var hashA = new RequestHash(exampleRequestA, cacheHeadersAuthorization);
      var hashB = new RequestHash(exampleRequestB, cacheHeadersAuthorization);

      expect(hashA._filteredAttributes()).to.not.deep.equal(hashB._filteredAttributes());
    });

    it('should be equal when headers are NOT considered', function () {
      var cacheHeaders = []
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);
      var hashB = new RequestHash(exampleRequestB, cacheHeaders);

      expect(hashA._filteredAttributes()).to.deep.equal(hashB._filteredAttributes());
    });

    it('should be filter all headers out', function () {
      var cacheHeaders = []
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);

      expect(hashA._filteredAttributes()).to.deep.equal({body: '', headers: {}});
    });

    it('should be keep defined headers headers', function () {
      var cacheHeaders = ['content-type']
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);
      expect(hashA._filteredAttributes()).to.deep.equal({body: '', headers: {'content-type': 'application/json'}});
    });
  });
});
<commit_msg>Remove Extra Requires<commit_after>var expect = require('chai').expect;
var RequestHash = require('../src/request_hash');

describe('RequestHash with Empty Body', function() {
  var exampleRequestA = {
    headers: {'authorization': '12345', 'content-type': 'application/json'},
    body: ''
  }

  var exampleRequestB = {
    headers: {'authorization': '98745', 'content-type': 'application/json'},
    body: ''
  }

  describe('toString()', function() {
    it('should NOT be equal when headers are considered', function () {
      var cacheHeadersAuthorization = ['authorization']
      var hashA = new RequestHash(exampleRequestA, cacheHeadersAuthorization);
      var hashB = new RequestHash(exampleRequestB, cacheHeadersAuthorization);

      expect(hashA.toString()).to.not.equal(hashB.toString());
    });

    it('should be equal when headers are NOT considered', function () {
      var cacheHeaders = []
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);
      var hashB = new RequestHash(exampleRequestB, cacheHeaders);

      expect(hashA.toString()).to.equal(hashB.toString());
    });
  });

  describe('_filteredAttributes()', function() {
    it('should NOT be equal when headers are considered', function () {
      var cacheHeadersAuthorization = ['authorization']
      var hashA = new RequestHash(exampleRequestA, cacheHeadersAuthorization);
      var hashB = new RequestHash(exampleRequestB, cacheHeadersAuthorization);

      expect(hashA._filteredAttributes()).to.not.deep.equal(hashB._filteredAttributes());
    });

    it('should be equal when headers are NOT considered', function () {
      var cacheHeaders = []
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);
      var hashB = new RequestHash(exampleRequestB, cacheHeaders);

      expect(hashA._filteredAttributes()).to.deep.equal(hashB._filteredAttributes());
    });

    it('should be filter all headers out', function () {
      var cacheHeaders = []
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);

      expect(hashA._filteredAttributes()).to.deep.equal({body: '', headers: {}});
    });

    it('should be keep defined headers headers', function () {
      var cacheHeaders = ['content-type']
      var hashA = new RequestHash(exampleRequestA, cacheHeaders);
      expect(hashA._filteredAttributes()).to.deep.equal({body: '', headers: {'content-type': 'application/json'}});
    });
  });
});
<|endoftext|>


<commit_before><commit_msg>server node file<commit_after><|endoftext|>