<commit_before>(function($, window, document, undefined){

    var PufferfishImageChangeEvent = function(element, newImageSrc, oldImageSrc){
        this.element = element;
        this.newImageSrc = newImageSrc;
        this.oldImageSrc = oldImageSrc;
    };

    PufferfishImageChangeEvent.prototype.element = null;
    PufferfishImageChangeEvent.prototype.newImageSrc = null;
    PufferfishImageChangeEvent.prototype.oldImageSrc = null;
    PufferfishImageChangeEvent.prototype.isDefaultPrevented = false;

    PufferfishImageChangeEvent.prototype.preventDefault = function(){
        this.isDefaultPrevented = true;
    };

    var defaults = {
        'onChange': function(element, newImageSrc, oldImageSrc){},
        'afterChange': function(element, newImageSrc, oldImageSrc){}
    };

    $.pufferfish = (function(){

        var settings = $.extend({}, defaults);

        var sizeDefinitionRegex =       /\[([^,]+)(\s+)?,(\s+)?\(([^\)]+)\)(\s+)?\]/;
        var sizeDefinitionRegexGlobal = /\[([^,]+)(\s+)?,(\s+)?\(([^\)]+)\)(\s+)?\]/g;
        var constraintRegex =       /([^,\s:]+):(\s+)?([^,]+)/;
        var constraintRegexGlobal = /([^,\s:]+):(\s+)?([^,]+)/g;

        var watchedImages = [];

        function getDataAttrKey(name){
            return 'data-pufferfish' + (typeof name !== 'undefined' ? '-' + name : '');
        }

        function getDataAttrSelector(name){
            return '[' + getDataAttrKey(name) + ']';
        }

        function parseConstraints(constraintString){

            var defaults = {
                'max-width': null,
                'min-width': null
            };

            var constraints = {};

            var constraintStringParts = constraintString.match(constraintRegexGlobal);
            constraintStringParts.forEach(function(constraintStringPart){
                var constraintVars = constraintStringPart.match(constraintRegex);
                constraints[constraintVars[1]] = parseInt(constraintVars[3]);
            });

            return $.extend({}, defaults, constraints);

        }

        function parseSizeDefinitions(sizeDefString){

            var sizeDefStringParts = sizeDefString.match(sizeDefinitionRegexGlobal);
            var sizeDefs = [];

            sizeDefStringParts.forEach(function(sizeDefStringPart){
                var sizeDefVars = sizeDefStringPart.match(sizeDefinitionRegex);

                sizeDefs.push({
                    'src': sizeDefVars[1],
                    'constraints': parseConstraints(sizeDefVars[4])
                });

            });

            return sizeDefs;

        }

        function watchImage(img){

            var sizeDefString = img.attr( getDataAttrKey() );
            var sizeDefinitions = parseSizeDefinitions(sizeDefString);

            var srcAttr = img.attr( getDataAttrKey('src-attr') );
            if(!srcAttr) srcAttr = 'src';

            img.data( getDataAttrKey('watched'), true );

            watchedImages.push({
                'img': img,
                'sizeDefinitions': sizeDefinitions,
                'srcAttr': srcAttr,
                'currentSrc': null
            });

        }

        function reflow(){

            watchedImages.forEach(function(watchedImage){

                var img = watchedImage.img;

                var sizeDefinitions = watchedImage.sizeDefinitions;
                var container = img.parent();
                var availableWidth = container.innerWidth();

                var selectedSizeDefinition = null;

                $.each(sizeDefinitions, function(key, sizeDefinition){

                    if(
                        sizeDefinition.constraints['min-width'] !== null &&
                        availableWidth < sizeDefinition.constraints['min-width']
                    ){
                        return;
                    }

                    if(
                        sizeDefinition.constraints['max-width'] !== null &&
                        availableWidth > sizeDefinition.constraints['max-width']
                    ){
                        return;
                    }

                    selectedSizeDefinition = sizeDefinition;
                    return false;

                });

                if(selectedSizeDefinition !== null && watchedImage.currentSrc !== selectedSizeDefinition.src){

                    var oldImageSrc = watchedImage.currentSrc;
                    var newImageSrc = selectedSizeDefinition.src;

                    watchedImage.currentSrc = newImageSrc;

                    var event = new PufferfishImageChangeEvent(img, newImageSrc, oldImageSrc);
                    settings.onChange(event);

                    if(!event.isDefaultPrevented && elementIsVisible(img)){
                        img.attr(watchedImage.srcAttr, newImageSrc);
                    }

                    settings.afterChange(event);
                }

            });

        }

        function elementIsVisible(element){
            if(element[0] === window || element[0] === document) return true;

            if(element.css('display') === 'none'){
                return false;
            }
            else{
                var parent = element.parent();
                if(parent.length === 0) return false;
                return elementIsVisible(parent);
            }
        }

        function bindUnwatched(context){
            if(typeof context === 'undefined') context = document;
            $(context).find( getDataAttrSelector() ).each(function(){
                var img = $(this);
                if(img.data( getDataAttrKey('watched') )) return;
                watchImage(img);
            });
        }

        function init(context, _settings){
            settings = $.extend({}, defaults, _settings);
            if(typeof context === 'undefined') context = document;
            bindUnwatched(context);
            reflow();
        }

        // Public methods
        return {
            'init': init,
            'reflow': reflow
        };

    })();

    $.fn.pufferfish = function(settings){
        $.pufferfish.init(this, settings);
        $(window).on('resize', function(){
            $.pufferfish.reflow();
        });
    };

})( jQuery, window, window.document);
<commit_msg>Fix for edge case where hidden elements were not being updated on reflow() or init()<commit_after>(function($, window, document, undefined){

    var PufferfishImageChangeEvent = function(element, newImageSrc, oldImageSrc){
        this.element = element;
        this.newImageSrc = newImageSrc;
        this.oldImageSrc = oldImageSrc;
    };

    PufferfishImageChangeEvent.prototype.element = null;
    PufferfishImageChangeEvent.prototype.newImageSrc = null;
    PufferfishImageChangeEvent.prototype.oldImageSrc = null;
    PufferfishImageChangeEvent.prototype.isDefaultPrevented = false;

    PufferfishImageChangeEvent.prototype.preventDefault = function(){
        this.isDefaultPrevented = true;
    };

    var defaults = {
        'onChange': function(element, newImageSrc, oldImageSrc){},
        'afterChange': function(element, newImageSrc, oldImageSrc){}
    };

    $.pufferfish = (function(){

        var settings = $.extend({}, defaults);

        var sizeDefinitionRegex =       /\[([^,]+)(\s+)?,(\s+)?\(([^\)]+)\)(\s+)?\]/;
        var sizeDefinitionRegexGlobal = /\[([^,]+)(\s+)?,(\s+)?\(([^\)]+)\)(\s+)?\]/g;
        var constraintRegex =       /([^,\s:]+):(\s+)?([^,]+)/;
        var constraintRegexGlobal = /([^,\s:]+):(\s+)?([^,]+)/g;

        var watchedImages = [];

        function getDataAttrKey(name){
            return 'data-pufferfish' + (typeof name !== 'undefined' ? '-' + name : '');
        }

        function getDataAttrSelector(name){
            return '[' + getDataAttrKey(name) + ']';
        }

        function parseConstraints(constraintString){

            var defaults = {
                'max-width': null,
                'min-width': null
            };

            var constraints = {};

            var constraintStringParts = constraintString.match(constraintRegexGlobal);
            constraintStringParts.forEach(function(constraintStringPart){
                var constraintVars = constraintStringPart.match(constraintRegex);
                constraints[constraintVars[1]] = parseInt(constraintVars[3]);
            });

            return $.extend({}, defaults, constraints);

        }

        function parseSizeDefinitions(sizeDefString){

            var sizeDefStringParts = sizeDefString.match(sizeDefinitionRegexGlobal);
            var sizeDefs = [];

            sizeDefStringParts.forEach(function(sizeDefStringPart){
                var sizeDefVars = sizeDefStringPart.match(sizeDefinitionRegex);

                sizeDefs.push({
                    'src': sizeDefVars[1],
                    'constraints': parseConstraints(sizeDefVars[4])
                });

            });

            return sizeDefs;

        }

        function watchImage(img){

            var sizeDefString = img.attr( getDataAttrKey() );
            var sizeDefinitions = parseSizeDefinitions(sizeDefString);

            var srcAttr = img.attr( getDataAttrKey('src-attr') );
            if(!srcAttr) srcAttr = 'src';

            img.data( getDataAttrKey('watched'), true );

            watchedImages.push({
                'img': img,
                'sizeDefinitions': sizeDefinitions,
                'srcAttr': srcAttr,
                'currentSrc': null,
                'visible': null
            });

        }

        function reflow(){

            watchedImages.forEach(function(watchedImage){

                var img = watchedImage.img;

                var sizeDefinitions = watchedImage.sizeDefinitions;
                var container = img.parent();
                var availableWidth = container.innerWidth();

                var selectedSizeDefinition = null;

                $.each(sizeDefinitions, function(key, sizeDefinition){

                    if(
                        sizeDefinition.constraints['min-width'] !== null &&
                        availableWidth < sizeDefinition.constraints['min-width']
                    ){
                        return;
                    }

                    if(
                        sizeDefinition.constraints['max-width'] !== null &&
                        availableWidth > sizeDefinition.constraints['max-width']
                    ){
                        return;
                    }

                    selectedSizeDefinition = sizeDefinition;
                    return false;

                });

                var visible = elementIsVisible(img);

                if((selectedSizeDefinition !== null && watchedImage.currentSrc !== selectedSizeDefinition.src) || (visible && watchedImage.visible === null)){

                    var oldImageSrc = watchedImage.currentSrc;
                    var newImageSrc = selectedSizeDefinition.src;

                    watchedImage.currentSrc = newImageSrc;

                    var event = new PufferfishImageChangeEvent(img, newImageSrc, oldImageSrc);
                    settings.onChange(event);

                    if(!event.isDefaultPrevented && visible){
                        img.attr(watchedImage.srcAttr, newImageSrc);
                    }

                    watchedImage.visible = visible;

                    settings.afterChange(event);
                }

            });

        }

        function elementIsVisible(element){
            if(element[0] === window || element[0] === document) return true;

            if(element.css('display') === 'none'){
                return false;
            }
            else{
                var parent = element.parent();
                if(parent.length === 0) return false;
                return elementIsVisible(parent);
            }
        }

        function bindUnwatched(context){
            if(typeof context === 'undefined') context = document;
            $(context).find( getDataAttrSelector() ).each(function(){
                var img = $(this);
                if(img.data( getDataAttrKey('watched') )) return;
                watchImage(img);
            });
        }

        function init(context, _settings){
            settings = $.extend({}, defaults, _settings);
            if(typeof context === 'undefined') context = document;
            bindUnwatched(context);
            reflow();
        }

        // Public methods
        return {
            'init': init,
            'reflow': reflow
        };

    })();

    $.fn.pufferfish = function(settings){
        $.pufferfish.init(this, settings);
        $(window).on('resize', function(){
            $.pufferfish.reflow();
        });
    };

})( jQuery, window, window.document);
<|endoftext|>


<commit_before>/**
 * script.js
 * Mich, 2015-03-11
 * Copyright (c) 2015 Datacratic Inc.  All rights reserved.
 **/

$(function () {
    var datasetName = null;
    var kMeansGroups = null;
    var dimensions = null;
    var perplexity = 20;

    logTa = $("textarea");
    function log(msg) {
        logTa.append(msg + "\n").scrollTop(logTa[0].scrollHeight);
    }
    // activate python runner plugin, should it be needed
    $.ajax({
        method : "PUT",
        url : "/v1/plugins/pyrunner?sync=true",
        data : JSON.stringify({"type" : "python_runner"}),
        success : function() { log("Registered python plugin."); },
        error : function() { log("Python plugin likely already registered."); }
    });

    function setFormActiveState(bool) {
        $(this).find("input, button, select").prop("disabled", !bool);
    }

    function getTsneId() {
        return datasetName + "_tsne_" + dimensions + "_" + perplexity;
    }

    function getKmeansId() {
        return datasetName + "_kmeans_" + kMeansGroups;
    }

    function getMergedDatasetId() {
        return datasetName + "_merged_" + kMeansGroups + "_" + dimensions + "_"
            + perplexity;
    }

    function getAjaxOnError(msg) {
        return function ajaxOnError(jqXHR, textStatus, errorThrown) {
            setFormActiveState(true);
            log(msg + " Check console for more info.");
            console.log(jqXHR);
            console.log(textStatus);
            console.log(jqXHR.responseText);
            throw errorThrown;
        }
    }

    function clearDisplayedResult() {
        $("#result").html("");
    }

    function displayResult() {
        if (dimensions == 2) {
            display2dResults();
        }
        else if (dimensions == 3) {
            display3dResults();
        }
        else {
            throw("Unknown dimensions: " + dimensions);
        }
    }

    function getCol(name, cols) {
        for (var i in cols) {
            if (cols[i][0] === name) {
                return cols[i];
            }
        }
    }

    function display3dResults() {
        //data:text/html,
        var url = "/v1/datasets/" + getMergedDatasetId() + "/query";
        $.getJSON(url, function(rawData) {
            var points = [];
            for (var i in rawData) {
                var item = rawData[i].columns;
                points.push({
                    x : getCol("x", item)[1],
                    y : getCol("y", item)[1],
                    z : getCol("z", item)[1],
                    cid : getCol("cluster", item)[1]
                })
            }
            $.get("data_projector.html", function(htmlStr) {
                var index = htmlStr.lastIndexOf("");
                var block2 = htmlStr.substr(index);
                var block1 = htmlStr.substr(0, index);
                index = block2.lastIndexOf("");
                var block3 = block2.substr(index);
                var block2 = block2.substr(0, index);
                var path = location.toString();
                path = path.substr(0, path.lastIndexOf("/") + 1);
                htmlStr = block1
                    + '<link rel="stylesheet" type="text/css" href="' + path + 'DataProjector.css">'
                    + block2
                    + ''
                    + ''
                    + ''
                    + block3;
                $("#result").html('')
            });
        });
    }

    function display2dResults() {
        $("svg").remove();

        function getMinMax(data) {
            var min = 0;
            var max = 0;
            var cols;
            var colX;
            var colY;
            for (var i in data) {
                cols = data[i].columns;
                colX = getCol('x', cols);
                colY = getCol('y', cols);
                min = Math.min(colX[1], colY[1], min);
                max = Math.max(colX[1], colY[1], max);
            }
            return [min, max];
        }

        var color;
        var scale;
        var topOffset = 10;
        var leftOffset = 30;
        label = $("").appendTo("div").css({
            position : "absolute",
            background : "rgba(0, 0, 0, 0.4)",
            color : "white"
        });
        function showLabel(d) {
            label.show();
            label.html(d.rowName);
            label.css({
                left : leftOffset
                    + scale(getCol('x', d.columns)[1])
                    - (label.outerWidth() / 2),
                top  : 10 + topOffset + scale(getCol('y', d.columns)[1])
            });
        }

        function hideLabel() {
            label.hide();
        }

        function doIt(data) {
            color = d3.scale.category20();
            scale = d3.scale
                .linear()
                .domain(getMinMax(data))
                .range([0, 800]);
            $("#result svg").html("");
            var svg = d3.select("#result")
                .append("svg")
                .attr("width", "840px")
                .attr("height", "830px");
            var circles = svg.selectAll("circle")
                .data(data)
                .enter()
                .append("circle")
                .attr("cx", function(d) {
                    return leftOffset + scale(getCol('x', d.columns)[1]);
                })
                .attr("cy", function(d) {
                    return topOffset + scale(getCol('y', d.columns)[1]);
                })
                .attr("r", 5)
                .attr("fill", function (d) {
                    return color(getCol('cluster', d.columns)[1]);
                })
                .on("mouseover", function (d) {
                    showLabel(d);
                })
                .on("mouseout", function (d) {
                    hideLabel();
                });
        }

        var url = "/v1/datasets/" + getMergedDatasetId() + "/query";
        $.getJSON(url, function(data) {
            doIt(data);
        });
    }

    function createMergedDataset() {
        var mergedDatasetId = getMergedDatasetId();
        $.ajax({
            method : "GET",
            url : "/v1/datasets/" + mergedDatasetId,
            success : displayResult,
            error : function() {
                log("Creating merged dataset");
                config = {
                    'type' : "merged",
                    'id' : mergedDatasetId,
                    'params' : {
                        "datasets": [
                            {"id": getTsneId()},
                            {"id": getKmeansId()}
                        ]
                    }
                };
                $.ajax({
                    method : "POST",
                    url : "/v1/datasets?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create merged dataset"),
                    success : function() {
                        log("Created merged dataset");
                        displayResult();
                    }
                });
            }
        });
    }

    function trainTsnePipeline() {
        log("Training tsne pipeline");
        $.ajax({
            method : "PUT",
            url : "/v1/pipelines/" + getTsneId() + "/runs/1?sync=true",
            data : "{}",
            error : getAjaxOnError("Failed to train tsne pipeline"),
            success : function() {
                log("Created tsne pipeline");
                createMergedDataset();
            }
        })
    }

    function createTsnePipeline() {
        var tsneId = getTsneId();
        $.ajax({
            method : "GET",
            url : "/v1/pipelines/" + tsneId,
            success : createMergedDataset,
            error : function () {
                log("Creating tsne pipeline");
                config = {
                    'type' : 'tsne',
                    'params' : {
                        'dataset' : {'id' : datasetName + '_svd_embedding'},
                        'output' : {'id' : tsneId,
                                    'type' : 'mutable',
                                    'address' : datasetName + 'reddit_tsne.beh.gz'},
                        'select' : 'svd*',
                        'where' : 'true',
                        'numOutputDimensions' : dimensions,
                        'perplexity' : perplexity
                    }
                };
                $.ajax({
                    method : "PUT",
                    url : "/v1/pipelines/" + tsneId + "?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create tsne pipeline."),
                    success : function() {
                        log("Created tsne pipeline.");
                        trainTsnePipeline();
                    }
                });
            }
        });
    }

    function trainKmeansPipeline() {
        log("Training kmeans pipeline.");
        $.ajax({
            method : "PUT",
            url : "/v1/pipelines/" + getKmeansId() + "/runs/1?sync=true",
            data : "{}",
            error : getAjaxOnError("Failed to train kmeans pipeline"),
            success : function() {
                log("Trained kmeans pipeline.");
                createTsnePipeline();
            }
        })
    }

    function createKmeansPipeline() {
        var kmeansId = getKmeansId();
        $.ajax({
            method : "GET",
            url : "/v1/pipelines/" + kmeansId,
            success : createTsnePipeline,
            error : function () {
                log("Creating kmeans pipeline");
                config = {
                    'type' : 'kmeans',
                    'params' : {
                        'dataset' : {'id' : datasetName + '_svd_embedding'},
                        'output' : {'id' : kmeansId,
                                    'type' : 'mutable',
                                    'address' : datasetName + '_kmeans.beh.gz'},
                        'select' : 'svd*',
                        'where' : 'true',
                        'numClusters' : kMeansGroups
                    }
                };
                $.ajax({
                    method : "PUT",
                    url : "/v1/pipelines/" + kmeansId + "?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create kmeans pipeline."),
                    success : function() {
                        log("Created kmeans pipeline.");
                        trainKmeansPipeline();
                    }
                });
            }
        });
    }

    function trainSvdPipeline() {
        log("Training svd pipeline.");
        $.ajax({
            method : "PUT",
            url : "/v1/pipelines/" + datasetName + "_svd/runs/1?sync=true",
            data : "{}",
            error : getAjaxOnError("Failed to train svd pipeline."),
            success : function() {
                log("Trained svd pipeline.");
                createKmeansPipeline()
            }
        });
    }

    function createSvdPipeline() {
        var svdId = datasetName + '_svd';
        $.ajax({
            method: "GET",
            url : "/v1/pipelines/" + svdId,
            success: createKmeansPipeline,
            error: function () {
                log("Creating svd pipeline");
                config = {
                    'type' : 'svd',
                    'params' : {
                        'dataset' : {'id' : datasetName},
                        'output' : {'id' : svdId,
                                    'type' : 'mutable',
                                    'address' : datasetName + '_svd.beh.gz'},
                        'rowOutput' : {"id": datasetName + "_svd_embedding",
                                    'type': "embedding",
                                    'address' : datasetName + "_svd.embedding.gz" },
                        'select' : '* EXCLUDING label'
                    }
                };
                $.ajax({
                    method: "PUT",
                    url : "/v1/pipelines/" + svdId + "?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create svd pipeline"),
                    success : function() {
                        log("Created svd pipeline.");
                        trainSvdPipeline();
                    }
                });
            }
        });
    }

    function logCount(data) {
        if (data.count === undefined) {
            log("Unknown data points count.");
        }
        else {
            log("Got " + data.count + " data points.");
        }
    }

    function logQuotaRemaining(data) {
        if (data.quotaRemaining !== undefined) {
            log("Quota remaining: " + data.quotaRemaining);
        }
    }

    function onDataLoaded(data, textStatus, jqXHR) {
        log("Data loaded successfully.");
        datasetName = data.datasetId;
        if (datasetName === undefined) {
            log("ERROR: The data loader failed to return the dataset name.");
            return;
        }
        logQuotaRemaining(data);
        log("Dataset name: " + datasetName);
        logCount(data);
        $.ajax({
            url :"/v1/datasets/" + datasetName,
            success : function() {
                log("Dataset found.");
                createSvdPipeline();
            }, error : getAjaxOnError("Failed to find dataset. Was it named properly?")
        });
    }

    function getDataLoaderConfig() {
        var option = $("select[name=method]").val();
        if (option == "file") {
            return {
                method : "POST",
                url : "/v1/plugins/pyrunner/routes/run?sync=true",
                data : {
                    address : $("input[name=importScriptUri]").val()
                }
            };
        }
        else if (option == "so") {
            return {
                method : "PUT",
                url : '../run/stackexchange',
                data : {
                    site : $("select[name=stackexchangeSite]").val(),
                    key : $("input[name=stackexchangeKey]").val()
                }
            };
        }
        else if (option == "reddit") {
            return {
                method : "PUT",
                url : '../run/reddit'
            };
        }
        throw("Unknown option");
    }

    $("form").submit(function(e) {
        clearDisplayedResult();
        kMeansGroups = parseInt($("input[name=kMeansGroups]").val());
        dimensions = parseInt($("input[name=dimensions]:checked").val());
        perplexity = parseInt($("input[name=perplexity]").val());
        e.preventDefault();
        setFormActiveState(false);
        var params = getDataLoaderConfig();

        log("Loading data.");
        $.ajax({
            method : params.method,
            url : params.url,
            data : JSON.stringify(params.data),
            success : onDataLoaded,
            error : getAjaxOnError("Failed to import data.")
        });
    });

    function onMethodChange() {
        var selection = $("select").val();
        $(".selectOption").each(function() {
            if ($(this).hasClass("selectOption-" + selection)) {
                $(this).show();
            }
            else {
                $(this).hide();
            }
        });
    }
    onMethodChange();
    $("select").change(onMethodChange);

    $.get("stackexchange_options.html", function (data) {
        $("select[name=stackexchangeSite]").html(data);
    });
});
<commit_msg>pyrunner no longer needed<commit_after>/**
 * script.js
 * Mich, 2015-03-11
 * Copyright (c) 2015 Datacratic Inc.  All rights reserved.
 **/

$(function () {
    var datasetName = null;
    var kMeansGroups = null;
    var dimensions = null;
    var perplexity = 20;

    logTa = $("textarea");
    function log(msg) {
        logTa.append(msg + "\n").scrollTop(logTa[0].scrollHeight);
    }

    function setFormActiveState(bool) {
        $(this).find("input, button, select").prop("disabled", !bool);
    }

    function getTsneId() {
        return datasetName + "_tsne_" + dimensions + "_" + perplexity;
    }

    function getKmeansId() {
        return datasetName + "_kmeans_" + kMeansGroups;
    }

    function getMergedDatasetId() {
        return datasetName + "_merged_" + kMeansGroups + "_" + dimensions + "_"
            + perplexity;
    }

    function getAjaxOnError(msg) {
        return function ajaxOnError(jqXHR, textStatus, errorThrown) {
            setFormActiveState(true);
            log(msg + " Check console for more info.");
            console.log(jqXHR);
            console.log(textStatus);
            console.log(jqXHR.responseText);
            throw errorThrown;
        }
    }

    function clearDisplayedResult() {
        $("#result").html("");
    }

    function displayResult() {
        if (dimensions == 2) {
            display2dResults();
        }
        else if (dimensions == 3) {
            display3dResults();
        }
        else {
            throw("Unknown dimensions: " + dimensions);
        }
    }

    function getCol(name, cols) {
        for (var i in cols) {
            if (cols[i][0] === name) {
                return cols[i];
            }
        }
    }

    function display3dResults() {
        //data:text/html,
        var url = "/v1/datasets/" + getMergedDatasetId() + "/query";
        $.getJSON(url, function(rawData) {
            var points = [];
            for (var i in rawData) {
                var item = rawData[i].columns;
                points.push({
                    x : getCol("x", item)[1],
                    y : getCol("y", item)[1],
                    z : getCol("z", item)[1],
                    cid : getCol("cluster", item)[1]
                })
            }
            $.get("data_projector.html", function(htmlStr) {
                var index = htmlStr.lastIndexOf("");
                var block2 = htmlStr.substr(index);
                var block1 = htmlStr.substr(0, index);
                index = block2.lastIndexOf("");
                var block3 = block2.substr(index);
                var block2 = block2.substr(0, index);
                var path = location.toString();
                path = path.substr(0, path.lastIndexOf("/") + 1);
                htmlStr = block1
                    + '<link rel="stylesheet" type="text/css" href="' + path + 'DataProjector.css">'
                    + block2
                    + ''
                    + ''
                    + ''
                    + block3;
                $("#result").html('')
            });
        });
    }

    function display2dResults() {
        $("svg").remove();

        function getMinMax(data) {
            var min = 0;
            var max = 0;
            var cols;
            var colX;
            var colY;
            for (var i in data) {
                cols = data[i].columns;
                colX = getCol('x', cols);
                colY = getCol('y', cols);
                min = Math.min(colX[1], colY[1], min);
                max = Math.max(colX[1], colY[1], max);
            }
            return [min, max];
        }

        var color;
        var scale;
        var topOffset = 10;
        var leftOffset = 30;
        label = $("").appendTo("div").css({
            position : "absolute",
            background : "rgba(0, 0, 0, 0.4)",
            color : "white"
        });
        function showLabel(d) {
            label.show();
            label.html(d.rowName);
            label.css({
                left : leftOffset
                    + scale(getCol('x', d.columns)[1])
                    - (label.outerWidth() / 2),
                top  : 10 + topOffset + scale(getCol('y', d.columns)[1])
            });
        }

        function hideLabel() {
            label.hide();
        }

        function doIt(data) {
            color = d3.scale.category20();
            scale = d3.scale
                .linear()
                .domain(getMinMax(data))
                .range([0, 800]);
            $("#result svg").html("");
            var svg = d3.select("#result")
                .append("svg")
                .attr("width", "840px")
                .attr("height", "830px");
            var circles = svg.selectAll("circle")
                .data(data)
                .enter()
                .append("circle")
                .attr("cx", function(d) {
                    return leftOffset + scale(getCol('x', d.columns)[1]);
                })
                .attr("cy", function(d) {
                    return topOffset + scale(getCol('y', d.columns)[1]);
                })
                .attr("r", 5)
                .attr("fill", function (d) {
                    return color(getCol('cluster', d.columns)[1]);
                })
                .on("mouseover", function (d) {
                    showLabel(d);
                })
                .on("mouseout", function (d) {
                    hideLabel();
                });
        }

        var url = "/v1/datasets/" + getMergedDatasetId() + "/query";
        $.getJSON(url, function(data) {
            doIt(data);
        });
    }

    function createMergedDataset() {
        var mergedDatasetId = getMergedDatasetId();
        $.ajax({
            method : "GET",
            url : "/v1/datasets/" + mergedDatasetId,
            success : displayResult,
            error : function() {
                log("Creating merged dataset");
                config = {
                    'type' : "merged",
                    'id' : mergedDatasetId,
                    'params' : {
                        "datasets": [
                            {"id": getTsneId()},
                            {"id": getKmeansId()}
                        ]
                    }
                };
                $.ajax({
                    method : "POST",
                    url : "/v1/datasets?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create merged dataset"),
                    success : function() {
                        log("Created merged dataset");
                        displayResult();
                    }
                });
            }
        });
    }

    function trainTsnePipeline() {
        log("Training tsne pipeline");
        $.ajax({
            method : "PUT",
            url : "/v1/pipelines/" + getTsneId() + "/runs/1?sync=true",
            data : "{}",
            error : getAjaxOnError("Failed to train tsne pipeline"),
            success : function() {
                log("Created tsne pipeline");
                createMergedDataset();
            }
        })
    }

    function createTsnePipeline() {
        var tsneId = getTsneId();
        $.ajax({
            method : "GET",
            url : "/v1/pipelines/" + tsneId,
            success : createMergedDataset,
            error : function () {
                log("Creating tsne pipeline");
                config = {
                    'type' : 'tsne',
                    'params' : {
                        'dataset' : {'id' : datasetName + '_svd_embedding'},
                        'output' : {'id' : tsneId,
                                    'type' : 'mutable',
                                    'address' : datasetName + 'reddit_tsne.beh.gz'},
                        'select' : 'svd*',
                        'where' : 'true',
                        'numOutputDimensions' : dimensions,
                        'perplexity' : perplexity
                    }
                };
                $.ajax({
                    method : "PUT",
                    url : "/v1/pipelines/" + tsneId + "?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create tsne pipeline."),
                    success : function() {
                        log("Created tsne pipeline.");
                        trainTsnePipeline();
                    }
                });
            }
        });
    }

    function trainKmeansPipeline() {
        log("Training kmeans pipeline.");
        $.ajax({
            method : "PUT",
            url : "/v1/pipelines/" + getKmeansId() + "/runs/1?sync=true",
            data : "{}",
            error : getAjaxOnError("Failed to train kmeans pipeline"),
            success : function() {
                log("Trained kmeans pipeline.");
                createTsnePipeline();
            }
        })
    }

    function createKmeansPipeline() {
        var kmeansId = getKmeansId();
        $.ajax({
            method : "GET",
            url : "/v1/pipelines/" + kmeansId,
            success : createTsnePipeline,
            error : function () {
                log("Creating kmeans pipeline");
                config = {
                    'type' : 'kmeans',
                    'params' : {
                        'dataset' : {'id' : datasetName + '_svd_embedding'},
                        'output' : {'id' : kmeansId,
                                    'type' : 'mutable',
                                    'address' : datasetName + '_kmeans.beh.gz'},
                        'select' : 'svd*',
                        'where' : 'true',
                        'numClusters' : kMeansGroups
                    }
                };
                $.ajax({
                    method : "PUT",
                    url : "/v1/pipelines/" + kmeansId + "?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create kmeans pipeline."),
                    success : function() {
                        log("Created kmeans pipeline.");
                        trainKmeansPipeline();
                    }
                });
            }
        });
    }

    function trainSvdPipeline() {
        log("Training svd pipeline.");
        $.ajax({
            method : "PUT",
            url : "/v1/pipelines/" + datasetName + "_svd/runs/1?sync=true",
            data : "{}",
            error : getAjaxOnError("Failed to train svd pipeline."),
            success : function() {
                log("Trained svd pipeline.");
                createKmeansPipeline()
            }
        });
    }

    function createSvdPipeline() {
        var svdId = datasetName + '_svd';
        $.ajax({
            method: "GET",
            url : "/v1/pipelines/" + svdId,
            success: createKmeansPipeline,
            error: function () {
                log("Creating svd pipeline");
                config = {
                    'type' : 'svd',
                    'params' : {
                        'dataset' : {'id' : datasetName},
                        'output' : {'id' : svdId,
                                    'type' : 'mutable',
                                    'address' : datasetName + '_svd.beh.gz'},
                        'rowOutput' : {"id": datasetName + "_svd_embedding",
                                    'type': "embedding",
                                    'address' : datasetName + "_svd.embedding.gz" },
                        'select' : '* EXCLUDING label'
                    }
                };
                $.ajax({
                    method: "PUT",
                    url : "/v1/pipelines/" + svdId + "?sync=true",
                    data : JSON.stringify(config),
                    error : getAjaxOnError("Failed to create svd pipeline"),
                    success : function() {
                        log("Created svd pipeline.");
                        trainSvdPipeline();
                    }
                });
            }
        });
    }

    function logCount(data) {
        if (data.count === undefined) {
            log("Unknown data points count.");
        }
        else {
            log("Got " + data.count + " data points.");
        }
    }

    function logQuotaRemaining(data) {
        if (data.quotaRemaining !== undefined) {
            log("Quota remaining: " + data.quotaRemaining);
        }
    }

    function onDataLoaded(data, textStatus, jqXHR) {
        log("Data loaded successfully.");
        datasetName = data.datasetId;
        if (datasetName === undefined) {
            log("ERROR: The data loader failed to return the dataset name.");
            return;
        }
        logQuotaRemaining(data);
        log("Dataset name: " + datasetName);
        logCount(data);
        $.ajax({
            url :"/v1/datasets/" + datasetName,
            success : function() {
                log("Dataset found.");
                createSvdPipeline();
            }, error : getAjaxOnError("Failed to find dataset. Was it named properly?")
        });
    }

    function getDataLoaderConfig() {
        var option = $("select[name=method]").val();
        if (option == "file") {
            return {
                method : "POST",
                url : "/v1/plugins/pyrunner/routes/run?sync=true",
                data : {
                    address : $("input[name=importScriptUri]").val()
                }
            };
        }
        else if (option == "so") {
            return {
                method : "PUT",
                url : '../run/stackexchange',
                data : {
                    site : $("select[name=stackexchangeSite]").val(),
                    key : $("input[name=stackexchangeKey]").val()
                }
            };
        }
        else if (option == "reddit") {
            return {
                method : "PUT",
                url : '../run/reddit'
            };
        }
        throw("Unknown option");
    }

    $("form").submit(function(e) {
        clearDisplayedResult();
        kMeansGroups = parseInt($("input[name=kMeansGroups]").val());
        dimensions = parseInt($("input[name=dimensions]:checked").val());
        perplexity = parseInt($("input[name=perplexity]").val());
        e.preventDefault();
        setFormActiveState(false);
        var params = getDataLoaderConfig();

        log("Loading data.");
        $.ajax({
            method : params.method,
            url : params.url,
            data : JSON.stringify(params.data),
            success : onDataLoaded,
            error : getAjaxOnError("Failed to import data.")
        });
    });

    function onMethodChange() {
        var selection = $("select").val();
        $(".selectOption").each(function() {
            if ($(this).hasClass("selectOption-" + selection)) {
                $(this).show();
            }
            else {
                $(this).hide();
            }
        });
    }
    onMethodChange();
    $("select").change(onMethodChange);

    $.get("stackexchange_options.html", function (data) {
        $("select[name=stackexchangeSite]").html(data);
    });
});
<|endoftext|>


<commit_before>/*
 Copyright (c) 2015 GFT Appverse, S.L., Sociedad Unipersonal.
 This Source Code Form is subject to the terms of the Appverse Public License
 Version 2.0 (“APL v2.0”). If a copy of the APL was not distributed with this
 file, You can obtain one at http://www.appverse.mobi/licenses/apl_v2.0.pdf. [^]
 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the conditions of the AppVerse Public License v2.0
 are met.
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. EXCEPT IN CASE OF WILLFUL MISCONDUCT OR GROSS NEGLIGENCE, IN NO EVENT
 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

/*jshint node:true*/

'use strict';
var yeoman = require('yeoman-generator');
var fs = require('fs');
var esprima = require('esprima');
var estraverse = require('estraverse');
var escodegen = require('escodegen');
var utils = require('../utils.js');

module.exports = yeoman.generators.Base.extend({
    constructor: function () {
        yeoman.generators.Base.apply(this, arguments);
        utils.checkVersion();
    },
    initializing: function () {
        this.log('You called the Appverse Html5 - REST subgenerator.');
        this.conflicter.force = true;
    },
    prompting: function () {
        var done = this.async();
        var prompts = [
            {
                type: "input",
                name: "restBaseUrl",
                message: "Configure your REST backend URL",
                default: "http://127.0.0.1"
             }, {
                type: "input",
                name: "restBaseUrlPort",
                message: "Configure your REST backend URL Port",
                default: "8000"
             }, {
                type: "confirm",
                name: "mockServer",
                message: "Do you want a REST MOCK Server (json-server)?",
                default: true
             }, {
                type: "input",
                name: "mockServerPort",
                message: "Configure your REST MOCK server PORT? ",
                default: "8888",
                when: function (answers) {
                    return answers.mockServer;
                }
            }
        ];
        this.prompt(prompts, function (props) {
            this.restBaseUrl = props.restBaseUrl;
            this.restBaseUrlPort = props.restBaseUrlPort;
            this.mockServer = props.mockServer;
            this.mockServerPort = props.mockServerPort;
            done();
        }.bind(this));
    },
    writing: function () {
        var restJS = '\n  \t<!-- REST MODULE --> \n' +
            '\t<script src="bower_components/lodash/lodash.min.js"></script> \n' +
            '\t<script src="bower_components/angular-resource/angular-resource.min.js"></script> \n' +
            '\t<script src="bower_components/restangular/dist/restangular.min.js"></script> \n' +
            '\t<script src="bower_components/appverse-web-html5-core/dist/appverse-rest/appverse-rest.min.js"></script> \n';

        var indexPath = this.destinationPath('app/index.html');
        var index = this.readFileAsString(indexPath);
        var indexTag = 'app-states.js"></script>';
        var output = index;

        if (index.indexOf("appverse-rest.js") === -1) {
            var pos = index.lastIndexOf(indexTag) + indexTag.length;
            output = [index.slice(0, pos), restJS, index.slice(pos)].join('');
        }
        if (output.length > index.length) {
            fs.writeFileSync(indexPath, output);
            this.log('Writing index.html by the Rest generator');
        }
        //ANGULAR MODULES
        this.log('Writing angular modules (app.js) by the Rest generator');
        var path = this.destinationPath('app/scripts/app.js');
        var file = this.readFileAsString(path);

        //PARSE FILE
        var astCode = esprima.parse(file);

        //ANGULAR REST MODULE
        var appverseRest = {
            type: "Literal",
            value: "appverse.rest",
            raw: "'appverse.rest'"
        };
        //APP NAME
        var appName = utils.getApplicationName(this);

        //REPLACE JS
        var moduleCode = estraverse.replace(astCode, {
            enter: function (node, parent) {
                if (node.type === 'Literal' && node.value === appName) {
                    parent.arguments[1].elements.unshiftIfNotExist(appverseRest, function (e) {
                        return e.type === appverseRest.type && e.value === appverseRest.value;
                    });
                    this.break();
                }
            }
        });

        var config = {
            type: 'Property',
            key: {
                type: 'Literal',
                value: 'REST_CONFIG',
                raw: 'REST_CONFIG'
            },
            computed: false,
            value: {
                type: 'ObjectExpression',
                properties: [{
                    type: 'Property',
                    key: {
                        type: 'Literal',
                        value: 'BaseUrl',
                        raw: 'BaseUrl'
                    },
                    computed: false,
                    value: {
                        type: 'Literal',
                        value: '/api',
                        raw: '/api'
                    },
                    kind: 'init',
                    method: false,
                    shorthand: false
               }, {
                    type: 'Property',
                    key: {
                        type: 'Literal',
                        value: 'RequestSuffix',
                        raw: 'RequestSuffix'
                    },
                    computed: false,
                    value: {
                        type: 'Literal',
                        value: '',
                        raw: ''
                    },
                    kind: 'init',
                    method: false,
                    shorthand: false
               }]
            }
        };

        var configCode = estraverse.replace(moduleCode, {
            enter: function (node, parent) {
                if (node.type === 'Identifier' && node.name === 'environment') {
                    parent.value.properties.pushIfNotExist(config, function (e) {
                        return e.type === config.type && e.key.value === config.key.value;
                    });
                    this.break();
                }
            }
        });
        var finalCode = escodegen.generate(configCode);
        fs.writeFileSync(path, finalCode);

        /*  this.fs.copyTpl(
              this.templatePath('config/connect.js'),
              this.destinationPath('config/connect.js'),
              this
          ); */

        this.template('config/connect.js', 'config/connect.js');

        if (this.mockServer) {
            if (!fs.existsSync("tasks")) {
                fs.mkdirSync("tasks");
            }
            if (!fs.existsSync("api")) {
                fs.mkdirSync("api");
            }
            this.template('tasks/mockserverTask.js', 'tasks/mockserverTask.js');
        }
    },
    installingDeps: function () {
        //TODO - TEMP  APPROACH - PENDING APPVERSE
        /* var bower = require(this.destinationPath('./bower.json'));
         bower.dependencies["lodash"] = "~3.6.0";
         bower.resolutions["lodash"] = "~3.6.0";
         fs.writeFileSync(this.destinationPath('./bower.json'), JSON.stringify(bower)); */

        this.bowerInstall("lodash");
        this.npmInstall(['grunt-connect-proxy'], {
            'saveDev': true
        });

        if (this.mockServer) {
            this.npmInstall(['json-server'], {
                'saveDev': true
            });
        }

    },
    end: function () {

        if (this.mockServer) {
            console.log("\n Execute 'grunt mockserver' to start you application on Mock mode.");
            console.log("Put your .json files into the api folder to serve them automatically with the Mock server");
            console.log("The Mock server will route all your entities using REST URL patterns.");
        }
    }
});
<commit_msg>FATE-52 - Grunt files<commit_after>/*
 Copyright (c) 2015 GFT Appverse, S.L., Sociedad Unipersonal.
 This Source Code Form is subject to the terms of the Appverse Public License
 Version 2.0 (“APL v2.0”). If a copy of the APL was not distributed with this
 file, You can obtain one at http://www.appverse.mobi/licenses/apl_v2.0.pdf. [^]
 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the conditions of the AppVerse Public License v2.0
 are met.
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. EXCEPT IN CASE OF WILLFUL MISCONDUCT OR GROSS NEGLIGENCE, IN NO EVENT
 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 */

/*jshint node:true*/

'use strict';
var yeoman = require('yeoman-generator');
var fs = require('fs');
var esprima = require('esprima');
var estraverse = require('estraverse');
var escodegen = require('escodegen');
var utils = require('../utils.js');

module.exports = yeoman.generators.Base.extend({
    constructor: function () {
        yeoman.generators.Base.apply(this, arguments);
        utils.checkVersion();
    },
    initializing: function () {
        this.log('You called the Appverse Html5 - REST subgenerator.');
        this.conflicter.force = true;
    },
    prompting: function () {
        var done = this.async();
        var prompts = [
            {
                type: "input",
                name: "restBaseUrl",
                message: "Configure your REST backend URL",
                default: "http://127.0.0.1"
             }, {
                type: "input",
                name: "restBaseUrlPort",
                message: "Configure your REST backend URL Port",
                default: "8000"
             }, {
                type: "confirm",
                name: "mockServer",
                message: "Do you want a REST MOCK Server (json-server)?",
                default: true
             }, {
                type: "input",
                name: "mockServerPort",
                message: "Configure your REST MOCK server PORT? ",
                default: "8888",
                when: function (answers) {
                    return answers.mockServer;
                }
            }
        ];
        this.prompt(prompts, function (props) {
            this.restBaseUrl = props.restBaseUrl;
            this.restBaseUrlPort = props.restBaseUrlPort;
            this.mockServer = props.mockServer;
            this.mockServerPort = props.mockServerPort;
            done();
        }.bind(this));
    },
    writing: function () {
        var restJS = '\n  \t<!-- REST MODULE --> \n' +
            '\t<script src="bower_components/lodash/lodash.min.js"></script> \n' +
            '\t<script src="bower_components/angular-resource/angular-resource.min.js"></script> \n' +
            '\t<script src="bower_components/restangular/dist/restangular.min.js"></script> \n' +
            '\t<script src="bower_components/appverse-web-html5-core/dist/appverse-rest/appverse-rest.min.js"></script> \n';

        var indexPath = this.destinationPath('app/index.html');
        var index = this.readFileAsString(indexPath);
        var indexTag = 'app-states.js"></script>';
        var output = index;

        if (index.indexOf("appverse-rest.js") === -1) {
            var pos = index.lastIndexOf(indexTag) + indexTag.length;
            output = [index.slice(0, pos), restJS, index.slice(pos)].join('');
        }
        if (output.length > index.length) {
            fs.writeFileSync(indexPath, output);
            this.log('Writing index.html by the Rest generator');
        }
        //ANGULAR MODULES
        this.log('Writing angular modules (app.js) by the Rest generator');
        var path = this.destinationPath('app/scripts/app.js');
        var file = this.readFileAsString(path);

        //PARSE FILE
        var astCode = esprima.parse(file);

        //ANGULAR REST MODULE
        var appverseRest = {
            type: "Literal",
            value: "appverse.rest",
            raw: "'appverse.rest'"
        };
        //APP NAME
        var appName = utils.getApplicationName(this);

        //REPLACE JS
        var moduleCode = estraverse.replace(astCode, {
            enter: function (node, parent) {
                if (node.type === 'Literal' && node.value === appName) {
                    parent.arguments[1].elements.unshiftIfNotExist(appverseRest, function (e) {
                        return e.type === appverseRest.type && e.value === appverseRest.value;
                    });
                    this.break();
                }
            }
        });

        var config = {
            type: 'Property',
            key: {
                type: 'Literal',
                value: 'REST_CONFIG',
                raw: 'REST_CONFIG'
            },
            computed: false,
            value: {
                type: 'ObjectExpression',
                properties: [{
                    type: 'Property',
                    key: {
                        type: 'Literal',
                        value: 'BaseUrl',
                        raw: 'BaseUrl'
                    },
                    computed: false,
                    value: {
                        type: 'Literal',
                        value: '/api',
                        raw: '/api'
                    },
                    kind: 'init',
                    method: false,
                    shorthand: false
               }, {
                    type: 'Property',
                    key: {
                        type: 'Literal',
                        value: 'RequestSuffix',
                        raw: 'RequestSuffix'
                    },
                    computed: false,
                    value: {
                        type: 'Literal',
                        value: '',
                        raw: ''
                    },
                    kind: 'init',
                    method: false,
                    shorthand: false
               }]
            }
        };

        var configCode = estraverse.replace(moduleCode, {
            enter: function (node, parent) {
                if (node.type === 'Identifier' && node.name === 'environment') {
                    parent.value.properties.pushIfNotExist(config, function (e) {
                        return e.type === config.type && e.key.value === config.key.value;
                    });
                    this.break();
                }
            }
        });
        var finalCode = escodegen.generate(configCode);
        fs.writeFileSync(path, finalCode);

        this.template('config/connect.js', 'config/connect.js');
        this.template('tasks/server.js', 'tasks/server.js');

        if (this.mockServer) {
            if (!fs.existsSync("tasks")) {
                fs.mkdirSync("tasks");
            }
            if (!fs.existsSync("api")) {
                fs.mkdirSync("api");
            }
            this.template('tasks/mockserverTask.js', 'tasks/mockserverTask.js');
        }
    },
    installingDeps: function () {
        //TODO - TEMP  APPROACH - PENDING APPVERSE
        this.bowerInstall("lodash");
        this.npmInstall(['grunt-connect-proxy'], {
            'saveDev': true
        });

        if (this.mockServer) {
            this.npmInstall(['json-server'], {
                'saveDev': true
            });
        }

    },
    end: function () {

        if (this.mockServer) {
            console.log("\n Execute 'grunt mockserver' to start you application on Mock mode.");
            console.log("Put your .json files into the api folder to serve them automatically with the Mock server");
            console.log("The Mock server will route all your entities using REST URL patterns.");
        }
    }
});
<|endoftext|>


<commit_before>define([
  'angular',
  'lodash',
  './query_builder',
],
function (angular, _) {
  'use strict';

  var module = angular.module('grafana.controllers');

  module.controller('DataloopQueryCtrl', function($scope, $timeout, $sce, templateSrv, $q, uiSegmentSrv) {

    var metrics;

    $scope.init = function() {
      if (!$scope.target) { return; }

      var target = $scope.target;
      target.aggrs = target.aggrs || [];
      target.mget = target.mget || 'sum';
      target.mget_enabled = target.mget_enabled || false;

      $scope.oldMetric = $scope.target.metric;
      $scope.$on('typeahead-updated', function() {
        $timeout($scope.get_data);
      });

      $scope.mgets = ['sum', 'avg'];
      $scope.aggrs = [
        {
          name: 'avg',
          vals: ['1s']
        },
        {
          name: 'sum',
          vals: ["1s"]
        },
        {
          name: 'min',
          vals: ["1s"]
        },
        {
          name: 'max',
          vals: ["1s"]
        },
        {
          name: 'percentile',
          vals: [0.99, "1s"]
        },
        {
          name: 'derivate',
          vals: []
        },
        {
          name: 'divide',
          vals: [1]
        },
        {
          name: 'multiply',
          vals: [1]
        }
      ];
    };

    $scope.addAggr = function(aggr) {
      aggr.id = Math.ceil(Math.random() * 10000000000);
      $scope.target.aggrs.push(aggr);
      $scope.get_data();
    };

    $scope.changeAggr = function(newAggr, currentAggrId) {

      //Get the index of the aggr we want to change
      var idx = $scope.target.aggrs.reduce(function(prev, aggr, idx) {
        return aggr.id === currentAggrId ? idx : prev;
      }, 0);

      var old = $scope.target.aggrs[idx];
      newAggr.id = old.id;

      if (!old.vals || old.vals.length !== newAggr.vals.length) {
        $scope.target.aggrs[idx] = newAggr;
      }
      else {
        $scope.target.aggrs[idx].name = newAggr.name;
      }

      $scope.$parent.get_data();
    };

    $scope.deleteAggr = function(id) {
      $scope.target.aggrs = $scope.target.aggrs.filter(function(a) {return a.id !== id;});
      $scope.$parent.get_data();
    };

    //We could replace text input, this with something like graphite segments, and get rid of this kind of things
    $scope.metricChanged = function() {
      if ($scope.oldMetric !== $scope.target.metric) {
        $scope.target.mget_enabled = $scope.target.metric.indexOf('*') > -1;
        $scope.oldMetric = $scope.target.metric;
        return $scope.get_data();
      }
    };

    $scope.getMetrics = function(q, cb) {

      if (metrics) {
        return metrics;
      }

      if (q) {
        return [];
      }

      return $scope.datasource
        .listMetrics()
        .then(function ok(res) {
          metrics = _.map(res, 'name');
          return cb(metrics);
        }, $scope.handleQueryError);
    };

    $scope.toggleQueryMode = function () {
      $scope.target.rawQuery = !$scope.target.rawQuery;
      $scope.get_data();
    };

    $scope.mgetChanged = function(value) {
      $scope.target.mget = value;
      $scope.get_data();
    };

    $scope.buildAggrMenu = function(functionName, idx) {
      //We could have submenus here with submenu:[]
      //Click should not contain "s

      return $scope.aggrs.map(function(aggr) {

        var funArgs = JSON.stringify(aggr).replace(/"/g, "'");
        if (idx) {
          funArgs += ', ' + idx;
        }

        return {
          text: aggr.name,
          click: functionName + "(" + funArgs + ")"
        };
      });
    };

    $scope.buildMgetMenu = function() {

      return $scope.mgets.map(function(mget) {
        return {
          text: mget,
          click: "mgetChanged('" + mget + "')"
        };
      });
    };

    $scope.handleQueryError = function(err) {
      $scope.parserError = err.message || 'Failed to issue metric query';
      return [];
    };

    $scope.init();

  });

});
<commit_msg>Allow for multiple lines with * wildcard<commit_after>define([
  'angular',
  'lodash',
  './query_builder',
],
function (angular, _) {
  'use strict';

  var module = angular.module('grafana.controllers');

  module.controller('DataloopQueryCtrl', function($scope, $timeout, $sce, templateSrv, $q, uiSegmentSrv) {

    var metrics;

    $scope.init = function() {
      if (!$scope.target) { return; }

      var target = $scope.target;
      target.aggrs = target.aggrs || [];
      target.mget = target.mget || 'sum';
      target.mget_enabled = target.mget_enabled || false;

      $scope.oldMetric = $scope.target.metric;
      $scope.$on('typeahead-updated', function() {
        $timeout($scope.get_data);
      });

      $scope.mgets = ['none', 'sum', 'avg'];
      $scope.aggrs = [
        {
          name: 'avg',
          vals: ['1s']
        },
        {
          name: 'sum',
          vals: ["1s"]
        },
        {
          name: 'min',
          vals: ["1s"]
        },
        {
          name: 'max',
          vals: ["1s"]
        },
        {
          name: 'percentile',
          vals: [0.99, "1s"]
        },
        {
          name: 'derivate',
          vals: []
        },
        {
          name: 'divide',
          vals: [1]
        },
        {
          name: 'multiply',
          vals: [1]
        }
      ];
    };

    $scope.addAggr = function(aggr) {
      aggr.id = Math.ceil(Math.random() * 10000000000);
      $scope.target.aggrs.push(aggr);
      $scope.get_data();
    };

    $scope.changeAggr = function(newAggr, currentAggrId) {

      //Get the index of the aggr we want to change
      var idx = $scope.target.aggrs.reduce(function(prev, aggr, idx) {
        return aggr.id === currentAggrId ? idx : prev;
      }, 0);

      var old = $scope.target.aggrs[idx];
      newAggr.id = old.id;

      if (!old.vals || old.vals.length !== newAggr.vals.length) {
        $scope.target.aggrs[idx] = newAggr;
      }
      else {
        $scope.target.aggrs[idx].name = newAggr.name;
      }

      $scope.$parent.get_data();
    };

    $scope.deleteAggr = function(id) {
      $scope.target.aggrs = $scope.target.aggrs.filter(function(a) {return a.id !== id;});
      $scope.$parent.get_data();
    };

    //We could replace text input, this with something like graphite segments, and get rid of this kind of things
    $scope.metricChanged = function() {
      if ($scope.oldMetric !== $scope.target.metric) {
        $scope.target.mget_enabled = $scope.target.metric.indexOf('*') > -1;
        $scope.oldMetric = $scope.target.metric;
        return $scope.get_data();
      }
    };

    $scope.getMetrics = function(q, cb) {

      if (metrics) {
        return metrics;
      }

      if (q) {
        return [];
      }

      return $scope.datasource
        .listMetrics()
        .then(function ok(res) {
          metrics = _.map(res, 'name');
          return cb(metrics);
        }, $scope.handleQueryError);
    };

    $scope.toggleQueryMode = function () {
      $scope.target.rawQuery = !$scope.target.rawQuery;
      $scope.get_data();
    };

    $scope.mgetChanged = function(value) {
      $scope.target.mget = value;
      $scope.get_data();
    };

    $scope.buildAggrMenu = function(functionName, idx) {
      //We could have submenus here with submenu:[]
      //Click should not contain "s

      return $scope.aggrs.map(function(aggr) {

        var funArgs = JSON.stringify(aggr).replace(/"/g, "'");
        if (idx) {
          funArgs += ', ' + idx;
        }

        return {
          text: aggr.name,
          click: functionName + "(" + funArgs + ")"
        };
      });
    };

    $scope.buildMgetMenu = function() {

      return $scope.mgets.map(function(mget) {
        return {
          text: mget,
          click: "mgetChanged('" + mget + "')"
        };
      });
    };

    $scope.handleQueryError = function(err) {
      $scope.parserError = err.message || 'Failed to issue metric query';
      return [];
    };

    $scope.init();

  });

});
<|endoftext|>


<commit_before>'use static'

module.exports = (name, path, ariaLabel) => `<template functional>

    <svg
      fill="currentColor"
      :width="props.width"
      :height="props.height"
      :viewBox="props.viewBox"
      :xmlns="props.xmlns"
    >
      <title>MDI ${name}</title>
      <path d="${path}" />
    </svg>

</template>

`
<commit_msg>Remove svg title<commit_after>'use static'

module.exports = (name, path, ariaLabel) => `<template functional>

    <svg
      fill="currentColor"
      :width="props.width"
      :height="props.height"
      :viewBox="props.viewBox"
      :xmlns="props.xmlns"
    >
      <path d="${path}" />
    </svg>

</template>

`
<|endoftext|>


<commit_before>var test = require('tape');

test('can import rtc module', function(t) {
  t.plan(1);
  t.ok(require('../'), 'imported successfully');
});

require('./generators');
require('./generators-connection-constraints');
require('./peerconnection');
require('./coupling');
// require('./data-channel');

// test the signalling
// require('./signalling/all');<commit_msg>Implement non reactive coupling tests, only invoke reactive tests within chrome<commit_after>var test = require('tape');
var detect = require('rtc-core/detect');

test('can import rtc module', function(t) {
  t.plan(1);
  t.ok(require('../'), 'imported successfully');
});

require('./generators');
require('./generators-connection-constraints');
require('./peerconnection');
require('./coupling');

// only test reactive coupling in chrome
if (! detect.moz) {
  require('./coupling-reactive');
}
// require('./data-channel');

// test the signalling
// require('./signalling/all');<|endoftext|>


<commit_before>var detect = require('rtc/detect');
var isTestling = typeof __testlingConsole != 'undefined';

// if we are running in testling then run the media tests
if (isTestling && (! detect.moz)) {
  require('./media');

  // if (! detect.moz) {
  //   require('./media-reactive');
  // }
}

require('./profile');
require('./datachannel');
// require('./heartbeat-disconnect');
require('./custom-id');

if (! detect.moz) {
  require('./reactive');
}<commit_msg>Include the media test for firefox now given fake media for firefox is possible<commit_after>var detect = require('rtc/detect');
var isTestling = typeof __testlingConsole != 'undefined';

// if we are running in testling then run the media tests
if (isTestling) {
  require('./media');

  if (! detect.moz) {
    require('./media-reactive');
  }
}

require('./profile');
require('./datachannel');
// require('./heartbeat-disconnect');
require('./custom-id');

if (! detect.moz) {
  require('./reactive');
}<|endoftext|>


<commit_before>// NMA_KEY should be set to a valid API-key in the shell before
// running the unit test
var should = require('should');
var NMA = require('../lib/notify-my-android');
var apikey = process.env.NMA_KEY; // be sure to insert your own api key here

if ( !apikey ){
  console.log('API key not set');
}
var p2 = new NMA(apikey); // be sure to insert your own api key here

/*
beforeEach(function(){
  console.log('before every test')
  })
*/

describe('NMA Node.js API', function(){

  /* Empty API-key */
  p = new NMA('');
  it('detects using an empty API-key', function( done ){
    p.notify('node.js', 'Unit testing', 'Empty API-key', function( error, remaining ){
      should.not.exist(remaining);
      error.message.should.be.a('string');
      error.code.should.be.a('string');
      done();
    });
  });

  /* Invalid API-key */
  p = new NMA('1212689455abcd902342aaaaaafffffffffccccccccc0000');
  it('detects using an invalid API-key', function( done ){
    p.notify('node.js', 'Unit testing', 'Using an invalid API-key', function( error, remaining ){
      should.not.exist(remaining);
      error.message.should.be.a('string');
      error.code.should.be.a('string');
      done();
    });
  });

  /* Invalid length of API-key */
  p = new NMA('111111111111');
  it('detects using an API-key with invalid length', function( done ){
    p.notify('node.js', 'Unit testing', 'Using an API-key with invalid length', function( error, remaining ){
      should.not.exist(remaining);
      error.message.should.be.a('string');
      error.code.should.be.a('string');
      done();
    });
  });

  /* Valid key, valid message */
  it('notifies when minimum valid information is added', function(done){
    p2.notify('node.js', 'Unit testing', 'Minimal message', function( error, remaining ){
	remaining.calls.should.be.a('number');
	remaining.resettimer.should.be.a('number');
	should.not.exist(error);
        done();
     });
  });

  /* Valid key, missing parameter */
  /*
  it('detects a missing parameter', function(done){
    p2.notify('node.js', 'Unit testing', function( error, remaining ){
        should.not.exist(remaining);
	err.should.be.a("object");
        done();
     });
  });
  */

  /* Valid key, valid message, high priority */
  it('notifies with high priority notification', function(done){
    p2.notify('node.js', 'Unit testing', 'High priority message', {priority: 2}, function( error, remaining ){
	remaining.calls.should.be.a('number');
	remaining.resettimer.should.be.a('number');
	should.not.exist(error);
        done();
     });
  });

  /* Valid key, valid message in html and with an url, high priority */
  it('notifies in html and with an url (high priority)', function(done){
    p2.notify('node.js', 'Unit testing', '
Notification

in texthtml <tt>with an URL.</tt>
', {priority: 2, url: 'http://www.example.com', contenttype: 'text/html'}, function( error, remaining ){
	remaining.calls.should.be.a('number');
	remaining.resettimer.should.be.a('number');
	should.not.exist(error);
        done();
     });
  });

  /* FIXME: Too many calls, with a valid API-key */
  /* Valid key, valid message, too many messages sent */
  it.skip('too many notifications', function(done){
    p2.notify('node.js', 'Unit testing', 'too many messages sent', function( error, remaining ){
	remaining.calls.should.be.a('number');
	remaining.resettimer.should.be.a('number');
  	console.log('Remaining calls: ' + remaining.calls);
  	console.log('Time before reset: ' + remaining.resettimer);
	should.not.exist(error);
        done();
     });
  });

});
<commit_msg>Fix test suite to comply with changes in should.js.<commit_after>// NMA_KEY should be set to a valid API-key in the shell before
// running the unit test
var should = require('should');
var NMA = require('../lib/notify-my-android');
var apikey = process.env.NMA_KEY; // be sure to insert your own api key here

if ( !apikey ){
  console.log('API key not set');
  return 9;
}

/*
beforeEach(function(){
  console.log('before every test')
  })
*/

describe('NMA Node.js API', function(){

  /* Empty API-key */
  it('detects using an empty API-key', function( done ){
    var p = new NMA('');
    p.notify('node.js', 'Unit testing', 'Empty API-key', function( error, remaining ){
      should.not.exist(remaining);
      error.message.should.be.a.String;
      error.code.should.be.a.String;
      done();
    });
    delete p;
  });

  /* Invalid API-key */
  it('detects using an invalid API-key', function( done ){
    var p = new NMA('1212689455abcd902342aaaaaafffffffffccccccccc0000');
    p.notify('node.js', 'Unit testing', 'Using an invalid API-key', function( error, remaining ){
      should.not.exist(remaining);
      error.message.should.be.a.String;
      error.code.should.be.a.String;
      done();
    });
    delete p;
  });

  /* Invalid length of API-key */
  it('detects using an API-key with invalid length', function( done ){
    var p = new NMA('111111111111');
    p.notify('node.js', 'Unit testing', 'Using an API-key with invalid length', function( error, remaining ){
      should.not.exist(remaining);
      error.message.should.be.a.String;
      error.code.should.be.a.String;
      done();
    });
    delete p;
  });

  /* Valid key, valid message */
  it('notifies when minimum valid information is added', function(done){
    var p = new NMA(apikey);
    p.notify('node.js', 'Unit testing', 'Minimal message', function( error, remaining ){
	remaining.calls.should.be.a.Number;
	remaining.resettimer.should.be.a.Number;
	should.not.exist(error);
        done();
     });
     delete p;
  });

  /* Valid key, missing parameter */
  /*
  it('detects a missing parameter', function(done){
    pvalid.notify('node.js', 'Unit testing', function( error, remaining ){
        should.not.exist(remaining);
	err.should.be.type("object");
        done();
     });
  });
  */

  /* Valid key, valid message, high priority */
  it('notifies with high priority notification', function(done){
    var p = new NMA(apikey);
    p.notify('node.js', 'Unit testing', 'High priority message', {priority: 2}, function( error, remaining ){
	remaining.calls.should.be.a.Number;
	remaining.resettimer.should.be.a.Number;
	should.not.exist(error);
        done();
     });
     delete p;
  });

  /* Valid key, valid message in html and with an url, high priority */
  it('notifies in html and with an url (high priority)', function(done){
    var p = new NMA(apikey);
    p.notify('node.js', 'Unit testing', '
Notification

in texthtml <tt>with an URL.</tt>
', {priority: 2, url: 'http://www.example.com', contenttype: 'text/html'}, function( error, remaining ){
	remaining.calls.should.be.a.Number;
	remaining.resettimer.should.be.a.Number;
	should.not.exist(error);
        done();
     });
     delete p;
  });

  /* FIXME: Too many calls, with a valid API-key */
  /* Valid key, valid message, too many messages sent */
  it.skip('too many notifications', function(done){
    var p = new NMA(apikey);
    p.notify('node.js', 'Unit testing', 'too many messages sent', function( error, remaining ){
	remaining.calls.should.be.a.Number;
	remaining.resettimer.should.be.a.Number;
  	console.log('Remaining calls: ' + remaining.calls);
  	console.log('Time before reset: ' + remaining.resettimer);
	should.not.exist(error);
        done();
     });
     delete p;
  });

});
<|endoftext|>


<commit_before>var vows = require('vows');
var assert = require('assert');

var BlockIo = require('../lib/block_io');
var API_KEY = process.env.API_KEY;
var ADDRESS = process.env.ADDRESS;

var client = new BlockIo(API_KEY);

vows.describe("block.io node.js api wrapper").addBatch({
  "get_balance": makeMethodCase('get_balance', {}),
  "get_new_address": makeMethodCase('get_new_address', {})
}).addBatch({
  "get_my_addresses": makeMethodCase('get_my_addresses', {}, {
    "must return an address": function (err, res) {
      assert.isObject(res);
      assert.isObject(res.data);
      assert.isArray(res.data.addresses);
      assert.isString(res.data.addresses[0].address);
      assert.isString(res.data.addresses[0].label);
    }
  })
}).addBatch({
  "get_address_received (by address)": makeMethodCase('get_address_received', {address: ADDRESS}, {
    "must return balance data": function (err, res) {
      assert.isObject(res);
      assert.isObject(res.data);
      assert.isString(res.data.confirmed_received);
      assert.isString(res.data.unconfirmed_received);
    }
  })
}).export(module);

function makeMethodCase (method, args, customChecks) {
  var testCase = {
    topic: function () {
      client[method](args, this.callback);
    },
    "must not return an error": function (err, data) {
      assert.isNull(err);
    },
    "must return status 'success'": function (err, data) {
      assert.isObject(data);
      assert.equal(data.status, 'success');
    }
  };

  if (customChecks) Object.keys(customChecks).forEach(function (k) {
    testCase[k] = customChecks[k];
  });

  return testCase;
}
<commit_msg>Add basic label tests<commit_after>var vows = require('vows');
var assert = require('assert');

var BlockIo = require('../lib/block_io');
var API_KEY = process.env.API_KEY;
var ADDRESS = process.env.ADDRESS;
var LABEL = (new Date).getTime().toString(36);

var client = new BlockIo(API_KEY);

vows.describe("block.io node.js api wrapper").addBatch({
  "get_balance": makeMethodCase('get_balance', {}),
  "get_new_address": makeMethodCase('get_new_address', {}),
  "get_new_address (with label)": makeMethodCase('get_new_address', {label: LABEL}, {
    "must return the label": function (err, res) {
      assert.isObject(res);
      assert.isObject(res.data);
      assert.isString(res.data.address);
      assert.strictEqual(res.data.label, LABEL);
    }
  })
}).addBatch({
  "get_my_addresses": makeMethodCase('get_my_addresses', {}, {
    "must return an address": function (err, res) {
      assert.isObject(res);
      assert.isObject(res.data);
      assert.isArray(res.data.addresses);
      assert.isString(res.data.addresses[0].address);
      assert.isString(res.data.addresses[0].label);
    }
  })
}).addBatch({
  "get_address_received (by address)": makeMethodCase('get_address_received', {address: ADDRESS}, {
    "must return balance data": function (err, res) {
      assert.isObject(res);
      assert.isObject(res.data);
      assert.isString(res.data.confirmed_received);
      assert.isString(res.data.unconfirmed_received);
    }
  }),
  "get_address_received (by label)": makeMethodCase('get_address_received', {label: LABEL}, {
    "must return balance data": function (err, res) {
      assert.isObject(res);
      assert.isObject(res.data);
      assert.isString(res.data.confirmed_received);
      assert.isString(res.data.unconfirmed_received);
    }
  }),
}).export(module);

function makeMethodCase (method, args, customChecks) {
  var testCase = {
    topic: function () {
      client[method](args, this.callback);
    },
    "must not return an error": function (err, data) {
      assert.isNull(err);
    },
    "must return status 'success'": function (err, data) {
      assert.isObject(data);
      assert.equal(data.status, 'success');
    }
  };

  if (customChecks) Object.keys(customChecks).forEach(function (k) {
    testCase[k] = customChecks[k];
  });

  return testCase;
}
<|endoftext|>


<commit_before>/* jshint -W030 */
'use strict';

var request = require('request');
var chai = require('chai');
var expect = chai.expect;
var e = require('./setup/test-environment');
var C = require('./setup/test-constants');

describe('client-side api', function() {
    this.timeout(10000);

    context('on the dashboard', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.dashboard)
                .call(done);
        });

        // Check for basic connectivity. The rest of the test are run from the dashboard as well.
        it('should receive messages', function(done) {
            e.browser.client
                .execute(function() {
                    window.serverToDashboardReceived = false;
                    window.dashboardApi.listenFor('serverToDashboard', function() {
                        window.serverToDashboardReceived = true;
                    });
                });

            var sendMessage = setInterval(function() {
                e.apis.extension.sendMessage('serverToDashboard');
            }, 500);

            e.browser.client
                .executeAsync(function(done) {
                    var checkMessageReceived;
                    checkMessageReceived = setInterval(function() {
                        if (window.serverToDashboardReceived) {
                            clearInterval(checkMessageReceived);
                            done();
                        }
                    }, 50);
                })
                .then(function() {
                    clearInterval(sendMessage);

                    done();
                });
        });

        it('should send messages', function(done) {
            e.apis.extension.listenFor('dashboardToServer', done);
            e.browser.client
                .execute(function() {
                    window.dashboardApi.sendMessage('dashboardToServer');
                });
        });
    });

    context('in a graphic', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.graphic)
                .call(done);
        });

        // The graphic and dashboard APIs use the same file
        // If dashboard API passes all its tests, we just need to make sure that the socket works
        it('should receive messages', function(done) {
            e.browser.client
                .execute(function() {
                    window.serverToGraphicReceived = false;
                    window.graphicApi.listenFor('serverToGraphic', function() {
                        window.serverToGraphicReceived = true;
                    });
                });

            var sendMessage = setInterval(function() {
                e.apis.extension.sendMessage('serverToGraphic');
            }, 500);

            e.browser.client
                .executeAsync(function(done) {
                    var checkMessageReceived;
                    checkMessageReceived = setInterval(function() {
                        if (window.serverToGraphicReceived) {
                            clearInterval(checkMessageReceived);
                            done();
                        }
                    }, 50);
                })
                .then(function() {
                    clearInterval(sendMessage);

                    done();
                });
        });

        it('should send messages', function(done) {
            e.apis.extension.listenFor('graphicToServer', done);
            e.browser.client
                .execute(function() {
                    window.graphicApi.sendMessage('graphicToServer');
                });
        });
    });

    describe('#config', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.dashboard)
                .call(done);
        });

        it('should exist and have length', function(done) {
            e.browser.client
                .execute(function() {
                    return window.dashboardApi.config;
                })
                .then(function(ret) {
                    expect(ret.value).to.not.be.empty();

                    done();
                });
        });

        it('shouldn\'t reveal sensitive information', function(done) {
            e.browser.client
                .execute(function() {
                    return window.dashboardApi.config;
                })
                .then(function(ret) {
                    expect(ret.value.login).to.not.have.property('sessionSecret');

                    done();
                });
        });

        it('shouldn\'t be writable', function(done) {
            e.browser.client
                .execute(function() {
                    return Object.isFrozen(window.dashboardApi.config);
                })
                .then(function(ret) {
                    expect(ret.value).to.be.true;

                    done();
                });
        });
    });

    describe('#bundleConfig', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.dashboard)
                .call(done);
        });

        it('should exist and have length', function(done) {
            e.browser.client
                .execute(function() {
                    return window.dashboardApi.bundleConfig;
                })
                .then(function(ret) {
                    expect(ret.value).to.not.be.empty();

                    done();
                });
        });
    });
});

describe('server-side api', function() {
    it('should receive messages and fire acknowledgements', function(done) {
        this.timeout(10000);

        e.apis.extension.listenFor('clientToServer', function(data, cb) {
            cb();
        });

        e.browser.client
            .switchTab(e.browser.tabs.dashboard)
            .executeAsync(function(done) {
                window.dashboardApi.sendMessage('clientToServer', null, done);
            })
            .call(done);
    });

    it('should send messages', function(done) {
        this.timeout(10000);

        e.browser.client
            .switchTab(e.browser.tabs.dashboard)
            .execute(function() {
                window.serverToClientReceived = false;
                window.dashboardApi.listenFor('serverToClient', function() {
                    window.serverToClientReceived = true;
                });
            });

        var sendMessage = setInterval(function() {
            e.apis.extension.sendMessage('serverToClient');
        }, 500);

        e.browser.client
            .switchTab(e.browser.tabs.dashboard)
            .executeAsync(function(done) {
                var checkMessageReceived;
                checkMessageReceived = setInterval(function() {
                    if (window.serverToClientReceived) {
                        clearInterval(checkMessageReceived);
                        done();
                    }
                }, 50);
            })
            .then(function() {
                clearInterval(sendMessage);

                done();
            });
    });

    it('should mount express middleware', function(done) {
        request(C.DASHBOARD_URL + 'test-bundle/test-route', function (error, response) {
            expect(error).to.be.null();
            expect(response.statusCode).to.equal(200);
            done();
        });
    });

    describe('#config', function() {
        it('should exist and have length', function() {
            expect(e.apis.extension.config).to.not.be.empty();
        });

        it('shouldn\'t reveal sensitive information', function() {
            expect(e.apis.extension.config.login).to.not.have.property('sessionSecret');
        });

        it('shouldn\'t be writable', function() {
            expect(Object.isFrozen(e.apis.extension.config)).to.be.true;
        });
    });

    describe('#bundleConfig', function() {
        it('should exist and has length', function() {
            expect(e.apis.extension.bundleConfig).to.not.be.empty();
        });
    });
});
<commit_msg>Fix tests<commit_after>/* jshint -W030 */
'use strict';

var request = require('request');
var chai = require('chai');
var expect = chai.expect;
var e = require('./setup/test-environment');
var C = require('./setup/test-constants');

describe('client-side api', function() {
    this.timeout(10000);

    context('on the dashboard', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.dashboard)
                .call(done);
        });

        // Check for basic connectivity. The rest of the test are run from the dashboard as well.
        it('should receive messages', function(done) {
            var sendMessage;
            e.browser.client
                .execute(function() {
                    window.serverToDashboardReceived = false;
                    window.dashboardApi.listenFor('serverToDashboard', function() {
                        window.serverToDashboardReceived = true;
                    });
                })
                .then(function() {
                    sendMessage = setInterval(function() {
                        e.apis.extension.sendMessage('serverToDashboard');
                    }, 500);
                })
                .executeAsync(function(done) {
                    var checkMessageReceived;
                    checkMessageReceived = setInterval(function() {
                        if (window.serverToDashboardReceived) {
                            clearInterval(checkMessageReceived);
                            done();
                        }
                    }, 50);
                })
                .then(function() {
                    clearInterval(sendMessage);
                    done();
                });
        });

        it('should send messages', function(done) {
            e.apis.extension.listenFor('dashboardToServer', done);
            e.browser.client
                .execute(function() {
                    window.dashboardApi.sendMessage('dashboardToServer');
                });
        });
    });

    context('in a graphic', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.graphic)
                .call(done);
        });

        // The graphic and dashboard APIs use the same file
        // If dashboard API passes all its tests, we just need to make sure that the socket works
        it('should receive messages', function(done) {
            var sendMessage;
            e.browser.client
                .execute(function() {
                    window.serverToGraphicReceived = false;
                    window.graphicApi.listenFor('serverToGraphic', function() {
                        window.serverToGraphicReceived = true;
                    });
                })
                .then(function() {
                    sendMessage = setInterval(function() {
                        e.apis.extension.sendMessage('serverToGraphic');
                    }, 500);
                })
                .executeAsync(function(done) {
                    var checkMessageReceived;
                    checkMessageReceived = setInterval(function() {
                        if (window.serverToGraphicReceived) {
                            clearInterval(checkMessageReceived);
                            done();
                        }
                    }, 50);
                })
                .then(function() {
                    clearInterval(sendMessage);
                    done();
                });
        });

        it('should send messages', function(done) {
            e.apis.extension.listenFor('graphicToServer', done);
            e.browser.client
                .execute(function() {
                    window.graphicApi.sendMessage('graphicToServer');
                });
        });
    });

    describe('#config', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.dashboard)
                .call(done);
        });

        it('should exist and have length', function(done) {
            e.browser.client
                .execute(function() {
                    return window.dashboardApi.config;
                })
                .then(function(ret) {
                    expect(ret.value).to.not.be.empty();

                    done();
                });
        });

        it('shouldn\'t reveal sensitive information', function(done) {
            e.browser.client
                .execute(function() {
                    return window.dashboardApi.config;
                })
                .then(function(ret) {
                    expect(ret.value.login).to.not.have.property('sessionSecret');

                    done();
                });
        });

        it('shouldn\'t be writable', function(done) {
            e.browser.client
                .execute(function() {
                    return Object.isFrozen(window.dashboardApi.config);
                })
                .then(function(ret) {
                    expect(ret.value).to.be.true;

                    done();
                });
        });
    });

    describe('#bundleConfig', function() {
        before(function(done) {
            e.browser.client
                .switchTab(e.browser.tabs.dashboard)
                .call(done);
        });

        it('should exist and have length', function(done) {
            e.browser.client
                .execute(function() {
                    return window.dashboardApi.bundleConfig;
                })
                .then(function(ret) {
                    expect(ret.value).to.not.be.empty();

                    done();
                });
        });
    });
});

describe('server-side api', function() {
    it('should receive messages and fire acknowledgements', function(done) {
        this.timeout(10000);

        e.apis.extension.listenFor('clientToServer', function(data, cb) {
            cb();
        });

        e.browser.client
            .switchTab(e.browser.tabs.dashboard)
            .executeAsync(function(done) {
                window.dashboardApi.sendMessage('clientToServer', null, done);
            })
            .call(done);
    });

    it('should send messages', function(done) {
        this.timeout(10000);

        e.browser.client
            .switchTab(e.browser.tabs.dashboard)
            .execute(function() {
                window.serverToClientReceived = false;
                window.dashboardApi.listenFor('serverToClient', function() {
                    window.serverToClientReceived = true;
                });
            });

        var sendMessage = setInterval(function() {
            e.apis.extension.sendMessage('serverToClient');
        }, 500);

        e.browser.client
            .switchTab(e.browser.tabs.dashboard)
            .executeAsync(function(done) {
                var checkMessageReceived;
                checkMessageReceived = setInterval(function() {
                    if (window.serverToClientReceived) {
                        clearInterval(checkMessageReceived);
                        done();
                    }
                }, 50);
            })
            .then(function() {
                clearInterval(sendMessage);

                done();
            });
    });

    it('should mount express middleware', function(done) {
        request(C.DASHBOARD_URL + 'test-bundle/test-route', function (error, response) {
            expect(error).to.be.null();
            expect(response.statusCode).to.equal(200);
            done();
        });
    });

    describe('#config', function() {
        it('should exist and have length', function() {
            expect(e.apis.extension.config).to.not.be.empty();
        });

        it('shouldn\'t reveal sensitive information', function() {
            expect(e.apis.extension.config.login).to.not.have.property('sessionSecret');
        });

        it('shouldn\'t be writable', function() {
            expect(Object.isFrozen(e.apis.extension.config)).to.be.true;
        });
    });

    describe('#bundleConfig', function() {
        it('should exist and has length', function() {
            expect(e.apis.extension.bundleConfig).to.not.be.empty();
        });
    });
});
<|endoftext|>