<commit_before>angular.module('ram.touchspin', [])

.directive('ramTouchSpin', ['$timeout', '$interval', '$document', '$locale', function ($timeout, $interval, $document, $locale) {
    'use strict';

    var keyCodes = {
        left: 37,
        right: 39,
        up: 38,
        down: 40
    };

    var setScopeValues = function (scope, attrs) {
        if(attrs.min !== undefined){
            scope.min = parseFloat(Number(attrs.min));
        }else{
            scope.min = undefined;
        }
        if(attrs.max !== undefined){
            scope.max = parseFloat(Number(attrs.max));
        }else{
            scope.max = undefined;
        }
        scope.step = attrs.step || 1;
        scope.prefix = attrs.prefix || undefined;
        scope.postfix = attrs.postfix || undefined;
        scope.decimals = attrs.decimals || 0;
        scope.stepInterval = attrs.stepInterval || 100;
        scope.stepIntervalDelay = attrs.stepIntervalDelay || 500;
        scope.emptyStringNull = attrs.nullable || false; //used in toFloat as well, TODO: improve
        var localeDecimalSeparator;
        if($locale.NUMBER_FORMATS.DECIMAL_SEP === undefined){
            //Be prepared for the case that variable name changes, this is not a public api
			//TODO: make sure this is in the public api (feature request: https://github.com/angular/angular.js/issues/13289)
            localeDecimalSeparator = '.';
        }
        else{
            localeDecimalSeparator = $locale.NUMBER_FORMATS.DECIMAL_SEP;
        }
        scope.decimalSep = attrs.decimalSep || localeDecimalSeparator;
        if (attrs.withKey === "false") {
            scope.withKey = false;
        } else {
            scope.withKey = true;
        }
        if (attrs.vertical === "false") {
            scope.verticalButtons = false;
        } else {
            scope.verticalButtons = true;
        }
        if (scope.decimalSep === ".") {
            scope.regex = /^-?(?:\d+|\d*\.(\d+)?)$/i;
        } else if (scope.decimalSep === ",") {
            scope.regex = /^-?(?:\d+|\d*\,(\d+)?)$/i;
        } else {
            //any decimal separator
            scope.regex = new RegExp("^-?(?:\\d+|\\d*" + scope.decimalSep + "(\\d+)?)$");
        }
    };

    var toFloat = function (value, scope) {
        if(value === "" && scope.emptyStringNull){
            return null;
        }
        if (scope.decimalSep !== "." && (typeof value === "string" || value instanceof String)) {
            value = value.replace(scope.decimalSep, ".");
        }
        value = parseFloat(Number(value));
        return value;
    }

    var toString = function (value, decimalSep) {
        if(value === null || value === undefined){
            return "";
        }
        if( typeof value === 'number'){
            value = value.toString();
        }
        value = value.replace('.', decimalSep);
        return value;
    }

    return {
        restrict: 'EA',
        scope: true,
		require: '?ngModel',
        replace: true,
        link: function (scope, element, attrs, ngModelCtrl) {
			if(!ngModelCtrl){
				throw Error("Missing ng-model attribute on ram-touch-spin element");
			}
            var timeout, timer, clickStart;
            scope.focused = false;

            setScopeValues(scope, attrs);

			var orignalRender = ngModelCtrl.$render;
			ngModelCtrl.$render = function () {
				scope.val = toString( ngModelCtrl.$viewValue, scope.decimalSep);
			};

			//TODO: make sure timers are deleted when element is destroyed

			var updateNgviewValue = function(val){
				//consistency check, we should not have a string type value here
				if(typeof value === "string"){
					throw new Error("value was of string type!");
				}
				ngModelCtrl.$setViewValue(val);
				orignalRender();
			}

			//ngModel default value is NaN
			if(isNaN(ngModelCtrl.$viewValue)){
				var initval = attrs.initval || (scope.emptyStringNull ? null : 0);
				if( attrs.initval){
					updateNgviewValue( toFloat(initval, scope));
				}
				scope.val = initval;
			}

			//handle nullable by adding a ngModelController parser
			if(attrs.nullable){
				ngModelCtrl.$parsers.push(function(viewValue) {
					if(viewValue === "") {
						return null;
					}
					return viewValue;
				});
			}

			//This additional parser is a fix for old browsers (Chrome 18) where we have a string value for a strange reason.
			ngModelCtrl.$parsers.push(function(viewValue) {
				if(typeof viewValue === "string"){
					return toFloat(viewValue, scope);
				}
				return viewValue;
			});

            scope.updateValue = function () {
                if (scope.val !== undefined) {
					//check regex first
					//TODO: move regex away from scope object
					if(scope.val === "" || scope.regex.test(scope.val)){
						ngModelCtrl.$setValidity('invalid', true);
					}else{
						ngModelCtrl.$setValidity('invalid', false);
						orignalRender();
						return;
					}
					//parse and update
                    var value = toFloat(scope.val, scope);
                    var adjustVal = false
                    if (scope.max != undefined && value > scope.max){
                         value = scope.max;
                         adjustVal = true;
                    }
                    else if (scope.min != undefined && value < scope.min) {
                        value = scope.min;
                        adjustVal = true;
                    }
                    if(adjustVal){
                        scope.val = toString(value,  scope.decimalSep);
                    }
					updateNgviewValue(value);
                }
            }

            scope.increment = function () {
                var value = parseFloat(parseFloat(Number(ngModelCtrl.$viewValue)) + parseFloat(scope.step)).toFixed(scope.decimals);
                if (scope.max != undefined && value > scope.max) return;
				updateNgviewValue( toFloat(value, scope));
				ngModelCtrl.$render();
            };

            scope.decrement = function () {
                var value = parseFloat(parseFloat(Number(ngModelCtrl.$viewValue)) - parseFloat(scope.step)).toFixed(scope.decimals);
                if (scope.min != undefined && value < scope.min) {
                    value = parseFloat(scope.min).toFixed(scope.decimals);
					updateNgviewValue( toFloat(value, scope));
                    return;
                }
                updateNgviewValue( toFloat(value, scope));
				ngModelCtrl.$render();
            };

           scope.startSpinUp = function () {
				scope.increment();

				clickStart = Date.now();

				timeout = $timeout(function() {
					timer = $interval(function() {
						scope.increment();
					}, scope.stepInterval);
				}, scope.stepIntervalDelay);
			};

			scope.startSpinDown = function () {
				scope.decrement();

				clickStart = Date.now();

				timeout = $timeout(function() {
					timer = $interval(function() {
						scope.decrement();
					}, scope.stepInterval);
				}, scope.stepIntervalDelay);
			};

			scope.stopSpin = function () {
                $timeout.cancel(timeout);
                $interval.cancel(timer);
			};

            scope.focus = function () {
                scope.focused = true;
            }

            scope.blur = function () {
                scope.focused = false;
            }

            var $body = $document.find('body');
            $body.bind('keydown', function (event) {
                if (!scope.withKey || !scope.focused) {
                    return;
                }
                event = event || window.event;
                var which = event.which;
                if (which === keyCodes.up) {
                    scope.increment();
                    event.preventDefault();
                    scope.$apply();
                } else if (which === keyCodes.down) {
                    scope.decrement();
                    event.preventDefault();
                    scope.$apply();
                }
            });
        },

        template:
		'
' +
		'  ' +
		'    <button class="btn btn-default bootstrap-touchspin-down" ng-mousedown="startSpinDown()" ng-mouseup="stopSpin()"></button>' +
		'  ' +
		'  ' +
		'  <input type="text" ng-model="val" class="form-control" ng-change="updateValue()" ng-blur="blur()" ng-focus="focus()">' +
		'  ' +
        '  ' +
		'    <button class="btn btn-default bootstrap-touchspin-down" ng-mousedown="startSpinUp()" ng-mouseup="stopSpin()"></button>' +
		'  ' +
        '  ' +
        '      <button class="btn btn-default bootstrap-touchspin-up" type="button" ng-mousedown="startSpinUp()" ng-mouseup="stopSpin()"></button>' +
        '      <button class="btn btn-default bootstrap-touchspin-down" type="button"ng-mousedown="startSpinDown()" ng-mouseup="stopSpin()"></button>' +
        '  ' +
		'
'

    };

}]);<commit_msg>fix validation: it was not updating on increment/decrement when being false<commit_after>angular.module('ram.touchspin', [])

.directive('ramTouchSpin', ['$timeout', '$interval', '$document', '$locale', function ($timeout, $interval, $document, $locale) {
    'use strict';

    var keyCodes = {
        left: 37,
        right: 39,
        up: 38,
        down: 40
    };

    var setScopeValues = function (scope, attrs) {
        if(attrs.min !== undefined){
            scope.min = parseFloat(Number(attrs.min));
        }else{
            scope.min = undefined;
        }
        if(attrs.max !== undefined){
            scope.max = parseFloat(Number(attrs.max));
        }else{
            scope.max = undefined;
        }
        scope.step = attrs.step || 1;
        scope.prefix = attrs.prefix || undefined;
        scope.postfix = attrs.postfix || undefined;
        scope.decimals = attrs.decimals || 0;
        scope.stepInterval = attrs.stepInterval || 100;
        scope.stepIntervalDelay = attrs.stepIntervalDelay || 500;
        scope.emptyStringNull = attrs.nullable || false; //used in toFloat as well, TODO: improve
        var localeDecimalSeparator;
        if($locale.NUMBER_FORMATS.DECIMAL_SEP === undefined){
            //Be prepared for the case that variable name changes, this is not a public api
			//TODO: make sure this is in the public api (feature request: https://github.com/angular/angular.js/issues/13289)
            localeDecimalSeparator = '.';
        }
        else{
            localeDecimalSeparator = $locale.NUMBER_FORMATS.DECIMAL_SEP;
        }
        scope.decimalSep = attrs.decimalSep || localeDecimalSeparator;
        if (attrs.withKey === "false") {
            scope.withKey = false;
        } else {
            scope.withKey = true;
        }
        if (attrs.vertical === "false") {
            scope.verticalButtons = false;
        } else {
            scope.verticalButtons = true;
        }
        if (scope.decimalSep === ".") {
            scope.regex = /^-?(?:\d+|\d*\.(\d+)?)$/i;
        } else if (scope.decimalSep === ",") {
            scope.regex = /^-?(?:\d+|\d*\,(\d+)?)$/i;
        } else {
            //any decimal separator
            scope.regex = new RegExp("^-?(?:\\d+|\\d*" + scope.decimalSep + "(\\d+)?)$");
        }
    };

    var toFloat = function (value, scope) {
        if(value === "" && scope.emptyStringNull){
            return null;
        }
        if (scope.decimalSep !== "." && (typeof value === "string" || value instanceof String)) {
            value = value.replace(scope.decimalSep, ".");
        }
        value = parseFloat(Number(value));
        return value;
    }

    var toString = function (value, decimalSep) {
        if(value === null || value === undefined){
            return "";
        }
        if( typeof value === 'number'){
            value = value.toString();
        }
        value = value.replace('.', decimalSep);
        return value;
    }

    return {
        restrict: 'EA',
        scope: true,
		require: '?ngModel',
        replace: true,
        link: function (scope, element, attrs, ngModelCtrl) {
			if(!ngModelCtrl){
				throw Error("Missing ng-model attribute on ram-touch-spin element");
			}
            var timeout, timer, clickStart;
            scope.focused = false;

            setScopeValues(scope, attrs);

			var orignalRender = ngModelCtrl.$render;
			ngModelCtrl.$render = function () {
				scope.val = toString( ngModelCtrl.$viewValue, scope.decimalSep);
			};

			//TODO: make sure timers are deleted when element is destroyed

			var updateNgviewValue = function(val){
				//consistency check, we should not have a string type value here
				if(typeof value === "string"){
					throw new Error("value was of string type!");
				}
				ngModelCtrl.$setViewValue(val);
				orignalRender();
				ngModelCtrl.$setValidity('invalid', true);
			}

			//ngModel default value is NaN
			if(isNaN(ngModelCtrl.$viewValue)){
				var initval = attrs.initval || (scope.emptyStringNull ? null : 0);
				if( attrs.initval){
					updateNgviewValue( toFloat(initval, scope));
				}
				scope.val = initval;
			}

			//handle nullable by adding a ngModelController parser
			if(attrs.nullable){
				ngModelCtrl.$parsers.push(function(viewValue) {
					if(viewValue === "") {
						return null;
					}
					return viewValue;
				});
			}

			//This additional parser is a fix for old browsers (Chrome 18) where we have a string value for a strange reason.
			ngModelCtrl.$parsers.push(function(viewValue) {
				if(typeof viewValue === "string"){
					return toFloat(viewValue, scope);
				}
				return viewValue;
			});

            scope.updateValue = function () {
                if (scope.val !== undefined) {
					//check regex first
					//TODO: move regex away from scope object
					if(scope.val === "" || scope.regex.test(scope.val)){

					}else{
						ngModelCtrl.$setValidity('invalid', false);
						orignalRender();
						return;
					}
					//parse and update
                    var value = toFloat(scope.val, scope);
                    var adjustVal = false
                    if (scope.max != undefined && value > scope.max){
                         value = scope.max;
                         adjustVal = true;
                    }
                    else if (scope.min != undefined && value < scope.min) {
                        value = scope.min;
                        adjustVal = true;
                    }
                    if(adjustVal){
                        scope.val = toString(value,  scope.decimalSep);
                    }
					updateNgviewValue(value);
                }
            }

            scope.increment = function () {
                var value = parseFloat(parseFloat(Number(ngModelCtrl.$viewValue)) + parseFloat(scope.step)).toFixed(scope.decimals);
                if (scope.max != undefined && value > scope.max) return;
				updateNgviewValue( toFloat(value, scope));
				ngModelCtrl.$render();
            };

            scope.decrement = function () {
                var value = parseFloat(parseFloat(Number(ngModelCtrl.$viewValue)) - parseFloat(scope.step)).toFixed(scope.decimals);
                if (scope.min != undefined && value < scope.min) {
                    value = parseFloat(scope.min).toFixed(scope.decimals);
					updateNgviewValue( toFloat(value, scope));
                    return;
                }
                updateNgviewValue( toFloat(value, scope));
				ngModelCtrl.$render();
            };

           scope.startSpinUp = function () {
				scope.increment();

				clickStart = Date.now();

				timeout = $timeout(function() {
					timer = $interval(function() {
						scope.increment();
					}, scope.stepInterval);
				}, scope.stepIntervalDelay);
			};

			scope.startSpinDown = function () {
				scope.decrement();

				clickStart = Date.now();

				timeout = $timeout(function() {
					timer = $interval(function() {
						scope.decrement();
					}, scope.stepInterval);
				}, scope.stepIntervalDelay);
			};

			scope.stopSpin = function () {
                $timeout.cancel(timeout);
                $interval.cancel(timer);
			};

            scope.focus = function () {
                scope.focused = true;
            }

            scope.blur = function () {
                scope.focused = false;
            }

            var $body = $document.find('body');
            $body.bind('keydown', function (event) {
                if (!scope.withKey || !scope.focused) {
                    return;
                }
                event = event || window.event;
                var which = event.which;
                if (which === keyCodes.up) {
                    scope.increment();
                    event.preventDefault();
                    scope.$apply();
                } else if (which === keyCodes.down) {
                    scope.decrement();
                    event.preventDefault();
                    scope.$apply();
                }
            });
        },

        template:
		'
' +
		'  ' +
		'    <button class="btn btn-default bootstrap-touchspin-down" ng-mousedown="startSpinDown()" ng-mouseup="stopSpin()"></button>' +
		'  ' +
		'  ' +
		'  <input type="text" ng-model="val" class="form-control" ng-change="updateValue()" ng-blur="blur()" ng-focus="focus()">' +
		'  ' +
        '  ' +
		'    <button class="btn btn-default bootstrap-touchspin-down" ng-mousedown="startSpinUp()" ng-mouseup="stopSpin()"></button>' +
		'  ' +
        '  ' +
        '      <button class="btn btn-default bootstrap-touchspin-up" type="button" ng-mousedown="startSpinUp()" ng-mouseup="stopSpin()"></button>' +
        '      <button class="btn btn-default bootstrap-touchspin-down" type="button"ng-mousedown="startSpinDown()" ng-mouseup="stopSpin()"></button>' +
        '  ' +
		'
'

    };

}]);<|endoftext|>


<commit_before>var Fraction = require('../src/fractions');
var Expression = require('../src/expressions');
var Equation = require('../src/equations');

describe("An equation with one variable", function() {
    var x1 = new Expression("x").add(4).divide(5);             // 1/5x + 4/5
    var x2 = new Expression("x").subtract(new Fraction(1, 6)); // x - 1/6
    var eq = new Equation(x1, x2);                             // 1/5x + 4/5 = x - 1/6

    it("should initialize", function() {
        expect(eq).toBeDefined();
    });

    it("should print properly", function() {
        expect(eq.print()).toEqual("1/5x + 4/5 = x - 1/6");
    });

    it("should return a fraction when solving for the one variable", function() {
        var answer = eq.solveFor("x");
        expect(answer instanceof Fraction).toBe(true);
    });

    it("should get the right answer", function() {
        var answer = eq.solveFor("x");
        expect(answer.print()).toEqual("29/24");
    });
});

describe("An equation with multiple variables", function() {
    var a = new Expression("a");
    var b = new Expression("b");
    var c = new Expression("c");
    var d = new Expression("d");

    a = a.add(b); // a + b
    c = c.add(d); // c + d

    var eq = new Equation(a, c); // a + b = c + d

    it("should initialize", function() {
        expect(eq).toBeDefined();
    });

    it("should print properly", function() {
        expect(eq.print()).toEqual("a + b = c + d");
    });

    it("should return an expression when solving for a variable", function() {
        var answer = eq.solveFor("a");
        expect(answer instanceof Expression).toBe(true);
    });

    it("should get the right answer", function() {
        var answer = eq.solveFor("a"); // a = c + d - b
        expect(answer.print()).toEqual("c + d - b");
    });
});

describe("An equation built with an expression and an integer or fraction", function() {
    var x = new Expression("x").add(4).divide(5);
    var eq = new Equation(x, new Fraction(3, 4));
    console.log(eq);

    it("should initialize", function() {
        expect(eq).toBeDefined();
    });

    it("should print properly", function() {
        expect(eq.print()).toEqual("1/5x + 4/5 = 3/4")
    });
});<commit_msg>Remove console.log<commit_after>var Fraction = require('../src/fractions');
var Expression = require('../src/expressions');
var Equation = require('../src/equations');

describe("An equation with one variable", function() {
    var x1 = new Expression("x").add(4).divide(5);             // 1/5x + 4/5
    var x2 = new Expression("x").subtract(new Fraction(1, 6)); // x - 1/6
    var eq = new Equation(x1, x2);                             // 1/5x + 4/5 = x - 1/6

    it("should initialize", function() {
        expect(eq).toBeDefined();
    });

    it("should print properly", function() {
        expect(eq.print()).toEqual("1/5x + 4/5 = x - 1/6");
    });

    it("should return a fraction when solving for the one variable", function() {
        var answer = eq.solveFor("x");
        expect(answer instanceof Fraction).toBe(true);
    });

    it("should get the right answer", function() {
        var answer = eq.solveFor("x");
        expect(answer.print()).toEqual("29/24");
    });
});

describe("An equation with multiple variables", function() {
    var a = new Expression("a");
    var b = new Expression("b");
    var c = new Expression("c");
    var d = new Expression("d");

    a = a.add(b); // a + b
    c = c.add(d); // c + d

    var eq = new Equation(a, c); // a + b = c + d

    it("should initialize", function() {
        expect(eq).toBeDefined();
    });

    it("should print properly", function() {
        expect(eq.print()).toEqual("a + b = c + d");
    });

    it("should return an expression when solving for a variable", function() {
        var answer = eq.solveFor("a");
        expect(answer instanceof Expression).toBe(true);
    });

    it("should get the right answer", function() {
        var answer = eq.solveFor("a"); // a = c + d - b
        expect(answer.print()).toEqual("c + d - b");
    });
});

describe("An equation built with an expression and an integer or fraction", function() {
    var x = new Expression("x").add(4).divide(5);
    var eq = new Equation(x, new Fraction(3, 4));

    it("should initialize", function() {
        expect(eq).toBeDefined();
    });

    it("should print properly", function() {
        expect(eq.print()).toEqual("1/5x + 4/5 = 3/4")
    });
});<|endoftext|>


<commit_before>/**
 * Created by Sanchez
 */
'use strict';

window.game = new Phaser.Game('100', '100', Phaser.AUTO, 'canvas-wrapper', null, true);
window.game.state.add('Boot', require('../states/boot'));
window.game.state.add('Preloader', require('../states/preloader'));
window.game.state.add('State1', require('../states/state1'));
window.game.state.start('Boot');

//Can Use ES6
const use_e6 = true;

window.h5 = {
    isPc: function() {
        var userAgentInfo = navigator.userAgent;
        var Agents = new Array('Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod');
        var flag = true;
        for (var v = 0; v < Agents.length; v++) {
            if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }
        }
        return flag;
    },
    rootResize: function() {
        //orientation portrait width=750px height=1334px / WeChat width=750px height=1206px
        var wFsize;
        //screen.width screen.height  bug !!!
        // var wWidth = (screen.width > 0) ? (window.innerWidth >= screen.width || window.innerWidth == 0) ? screen.width :
        //     window.innerWidth : window.innerWidth;
        // var wHeight = (screen.height > 0) ? (window.innerHeight >= screen.height || window.innerHeight == 0) ?
        //     screen.height : window.innerHeight : window.innerHeight;
        var wWidth = window.innerWidth;
        var wHeight = window.innerHeight;
        if (wWidth > wHeight) {
            wHeight = wWidth;
        }
        wFsize = wHeight / 7.5;
        document.getElementsByTagName('html')[0].style.fontSize = wFsize + 'px';
    },
    eventInit: function() {
        var that = this;
        document.addEventListener('touchstart', function(e) {}, false);
        document.addEventListener('touchmove', function(e) {
            e.preventDefault();
        }, false);
        return that;
    },
    cssInit: function() {
        var that = this;
        var noChangeCountToEnd = 100,
            noEndTimeout = 1000;
        that.rootResize();
        window.addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize', function() {
            var interval,
                timeout,
                end,
                lastInnerWidth,
                lastInnerHeight,
                noChangeCount;
            end = function() {
                // 'orientationchangeend'
                clearInterval(interval);
                clearTimeout(timeout);
                interval = null;
                timeout = null;
                that.rootResize();
            };
            interval = setInterval(function() {
                if (window.innerWidth === lastInnerWidth && window.innerHeight === lastInnerHeight) {
                    noChangeCount++;
                    if (noChangeCount === noChangeCountToEnd) {
                        // The interval resolved the issue first.
                        end();
                    }
                } else {
                    lastInnerWidth = window.innerWidth;
                    lastInnerHeight = window.innerHeight;
                    noChangeCount = 0;
                }
            });
            timeout = setTimeout(function() {
                // The timeout happened first.
                end();
            }, noEndTimeout);
        });

        return that;
    },
    init: function() {
        var that = this;
        that.cssInit().eventInit();
    }
};

window.onload = function() {
    window.h5.init();
    showStats();
};

function showStats() {
    var stats = new Stats();
    stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
    var fs = document.createElement('div');
    fs.style.position = 'absolute';
    fs.style.left = 0;
    fs.style.top = 0;
    fs.style.zIndex = 999;
    fs.appendChild(stats.domElement);
    document.body.appendChild(fs);

    function animate() {
        stats.begin();
        // monitored code goes here
        stats.end();
        requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
}<commit_msg>:bug: :hankey:  Fix BAD Code  About directory<commit_after>/**
 * Created by Sanchez
 */
'use strict';

window.game = new Phaser.Game('100', '100', Phaser.AUTO, 'canvas-wrapper', null, true);
window.game.state.add('Boot', require('./states/boot'));
window.game.state.add('Preloader', require('./states/preloader'));
window.game.state.add('State1', require('./states/state1'));
window.game.state.start('Boot');

//Can Use ES6
const use_e6 = true;

window.h5 = {
    isPc: function() {
        var userAgentInfo = navigator.userAgent;
        var Agents = new Array('Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod');
        var flag = true;
        for (var v = 0; v < Agents.length; v++) {
            if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }
        }
        return flag;
    },
    rootResize: function() {
        //orientation portrait width=750px height=1334px / WeChat width=750px height=1206px
        var wFsize;
        //screen.width screen.height  bug !!!
        // var wWidth = (screen.width > 0) ? (window.innerWidth >= screen.width || window.innerWidth == 0) ? screen.width :
        //     window.innerWidth : window.innerWidth;
        // var wHeight = (screen.height > 0) ? (window.innerHeight >= screen.height || window.innerHeight == 0) ?
        //     screen.height : window.innerHeight : window.innerHeight;
        var wWidth = window.innerWidth;
        var wHeight = window.innerHeight;
        if (wWidth > wHeight) {
            wHeight = wWidth;
        }
        wFsize = wHeight / 7.5;
        document.getElementsByTagName('html')[0].style.fontSize = wFsize + 'px';
    },
    eventInit: function() {
        var that = this;
        document.addEventListener('touchstart', function(e) {}, false);
        document.addEventListener('touchmove', function(e) {
            e.preventDefault();
        }, false);
        return that;
    },
    cssInit: function() {
        var that = this;
        var noChangeCountToEnd = 100,
            noEndTimeout = 1000;
        that.rootResize();
        window.addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize', function() {
            var interval,
                timeout,
                end,
                lastInnerWidth,
                lastInnerHeight,
                noChangeCount;
            end = function() {
                // 'orientationchangeend'
                clearInterval(interval);
                clearTimeout(timeout);
                interval = null;
                timeout = null;
                that.rootResize();
            };
            interval = setInterval(function() {
                if (window.innerWidth === lastInnerWidth && window.innerHeight === lastInnerHeight) {
                    noChangeCount++;
                    if (noChangeCount === noChangeCountToEnd) {
                        // The interval resolved the issue first.
                        end();
                    }
                } else {
                    lastInnerWidth = window.innerWidth;
                    lastInnerHeight = window.innerHeight;
                    noChangeCount = 0;
                }
            });
            timeout = setTimeout(function() {
                // The timeout happened first.
                end();
            }, noEndTimeout);
        });

        return that;
    },
    init: function() {
        var that = this;
        that.cssInit().eventInit();
    }
};

window.onload = function() {
    window.h5.init();
    showStats();
};

function showStats() {
    var stats = new Stats();
    stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
    var fs = document.createElement('div');
    fs.style.position = 'absolute';
    fs.style.left = 0;
    fs.style.top = 0;
    fs.style.zIndex = 999;
    fs.appendChild(stats.domElement);
    document.body.appendChild(fs);

    function animate() {
        stats.begin();
        // monitored code goes here
        stats.end();
        requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Jari Saukkonen
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var COMPORT = '/dev/ttyUSB1';

var logger = require('logops');
logger.setLevel('DEBUG');
var SerialPort = require('serialport');
var nmea0183 = require('./nmea0183');
var request = require('request');
var parser = nmea0183();

var port = new SerialPort(COMPORT, {
  baudRate: 57600
});

port.on('open', function() {
    logger.info('serial port opened');
});

port.on('data', function (data) {
    data = data.toString();
    for (var i = 0; i < data.length; i++) {
        var result = parser.consume(data.charAt(i));
        if (result.complete && result.success) {
            var data = result.message
                .split(',')
                .map(p => p.split('='))
                .reduce((o, p) => (o[p[0]] = p[1], o), {});

            var raindata = { 'Type': 'RainTrigger', 'Data': {}};
            raindata.Rain = parseInt(data.RAIN);
            raindata.Intensity = parseInt(data.INTENSITY);

            var interiordata = { 'Type': 'Interior', 'Data': {}};
            interiordata.EnclosureTemp = [ parseFloat(data.ENCLOSURETEMP), 'C' ];
            interiordata.InteriorTemp = [ parseFloat(data.INTERIORTEMP), 'C' ];
            interiordata.InteriorHumidity = [ parseFloat(data.INTERIORHUMIDITY), '%' ];
            interiordata.InteriorPressure = [ parseInt(data.INTERIORPRESSURE)/100.0, 'hPa' ];

            console.log(JSON.stringify(raindata));
            request.post({
                url: 'http://localhost:9001/api',
                body: raindata,
                json: true
            });

            console.log(JSON.stringify(interiordata));
            request.post({
                url: 'http://localhost:9001/api',
                body: interiordata,
                json: true
            });
        }
    }
});
<commit_msg>Fix data format<commit_after>/*
 * Copyright (c) 2016 Jari Saukkonen
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var COMPORT = '/dev/ttyUSB1';

var logger = require('logops');
logger.setLevel('DEBUG');
var SerialPort = require('serialport');
var nmea0183 = require('./nmea0183');
var request = require('request');
var parser = nmea0183();

var port = new SerialPort(COMPORT, {
  baudRate: 57600
});

port.on('open', function() {
    logger.info('serial port opened');
});

port.on('data', function (data) {
    data = data.toString();
    for (var i = 0; i < data.length; i++) {
        var result = parser.consume(data.charAt(i));
        if (result.complete && result.success) {
            var data = result.message
                .split(',')
                .map(p => p.split('='))
                .reduce((o, p) => (o[p[0]] = p[1], o), {});

            var raindata = { 'Type': 'RainTrigger', 'Data': {}};
            raindata.Data.Rain = parseInt(data.RAIN);
            raindata.Data.Intensity = parseInt(data.INTENSITY);

            var interiordata = { 'Type': 'Interior', 'Data': {}};
            interiordata.Data.EnclosureTemp = [ parseFloat(data.ENCLOSURETEMP), 'C' ];
            interiordata.Data.InteriorTemp = [ parseFloat(data.INTERIORTEMP), 'C' ];
            interiordata.Data.InteriorHumidity = [ parseFloat(data.INTERIORHUMIDITY), '%' ];
            interiordata.Data.InteriorPressure = [ parseInt(data.INTERIORPRESSURE)/100.0, 'hPa' ];

            console.log(JSON.stringify(raindata));
            request.post({
                url: 'http://localhost:9001/api',
                body: raindata,
                json: true
            });

            console.log(JSON.stringify(interiordata));
            request.post({
                url: 'http://localhost:9001/api',
                body: interiordata,
                json: true
            });
        }
    }
});
<|endoftext|>


<commit_before>'use strict';

var ngModule = angular.module('woServices');
ngModule.service('auth', Auth);
module.exports = Auth;

var APP_CONFIG_DB_NAME = 'app-config';
var EMAIL_ADDR_DB_KEY = 'emailaddress';
var REALNAME_DB_KEY = 'realname';
var OAUTH_TOKEN_DB_KEY = 'oauthtoken';

/**
 * The Auth BO handles the rough edges and gaps between user/password authentication
 * and OAuth via Chrome Identity API.
 * Typical usage:
 * var auth = new Auth(...);
 * auth.setCredentials(...); // during the account setup
 * auth.getCredentials(...); // called to gather all the information to connect to IMAP/SMTP,
 *                              username, password / oauth token, IMAP/SMTP server host names, ...
 */
function Auth(appConfigStore, oauth) {
    this._appConfigStore = appConfigStore;
    this._oauth = oauth;

    this._initialized = false;
}

/**
 * Initialize the service
 */
Auth.prototype.init = function() {
    var self = this;

    if (self._initialized) {
        return new Promise(function(resolve) {
            resolve();
        });
    }

    // init app config database
    return self._appConfigStore.init(APP_CONFIG_DB_NAME).then(function() {
        // load credentials from disk
        return self._loadCredentials();
    }).then(function() {
        // set login hint if email address was already set previously
        if (self.emailAddress) {
            self._oauth._loginHint = self.emailAddress;
        }

        self._initialized = true;
    });
};

/**
 * Check if the service has been initialized.
 */
Auth.prototype.isInitialized = function() {
    return this._initialized;
};

Auth.prototype.storeCredentials = function() {
    var self = this;

    if (!self.credentialsDirty) {
        // nothing to store if credentials not dirty
        return new Promise(function(resolve) {
            resolve();
        });
    }

    // persist the config
    var storeEmailAddress = self._appConfigStore.storeList([self.emailAddress], EMAIL_ADDR_DB_KEY);
    var storeRealname = self._appConfigStore.storeList([self.realname], REALNAME_DB_KEY);
    var storeOAuthToken = self._appConfigStore.storeList([self.oauthToken], OAUTH_TOKEN_DB_KEY);

    return Promise.all([
        storeEmailAddress,
        storeRealname,
        storeOAuthToken
    ]).then(function() {
        self.credentialsDirty = false;
    });
};

/**
 * Delete the locally cached oauth token.
 */
Auth.prototype.flushOAuthToken = function() {
    this.oauthToken = undefined;
    this._oauth.flushToken();

    // remove cached token from local storage
    return self._appConfigStore.removeList(OAUTH_TOKEN_DB_KEY);
};

/**
 * READ FIRST b/c usage of the oauth api is weird.
 * the chrome identity api will let you query an oauth token for an email account without knowing
 * the corresponding email address. also, android has multiple accounts whereas desktop chrome only
 * has one user logged in.
 * 1) try to read the email address from the configuration (see above)
 * 2) fetch the oauth token. if we already HAVE an email address at this point, we can spare
 *    popping up the account picker on android! if not, the account picker will pop up. this
 *    is android only, since the desktop chrome will query the user that is logged into chrome
 * 3) fetch the email address for the oauth token from the chrome identity api
 */
Auth.prototype.getOAuthCredentials = function() {
    var self = this;

    return new Promise(function(resolve) {
        resolve();
    }).then(function() {
        // make sure we've loaded cached credentials from disk
        return self._loadCredentials();

    }).then(function() {
        // if a stored token exists, check if it's still valid
        if (self.oauthToken) {
            return queryEmailAddress();
        }

        // if no oauth token exists fetch a fresh one
        return self._oauth.getOAuthToken(self.emailAddress).then(function(oauthToken) {
            self.oauthToken = oauthToken;
        });

    }).then(function() {
        // at this point we can be fairly certain that we have a valid oauth token

        // shortcut if the email address is already known
        if (self.emailAddress) {
            return;
        }

        // query the email address
        return queryEmailAddress();

    }).then(function() {
        self.credentialsDirty = true;

        return {
            emailAddress: self.emailAddress,
            realname: self.realname,
            oauthToken: self.oauthToken
        };
    });

    function queryEmailAddress() {
        return self._oauth.queryEmailAddress(self.oauthToken).then(function(info) {
            self.emailAddress = info.emailAddress;
            self.realname = info.realname;

        }).catch(function(err) {
            if (err.code === 401) {
                // oauth token has probably expired
                return self.flushOAuthToken().then(function() {
                    throw err;
                });
            }
            throw err;
        });
    }
};

/**
 * Loads email address, password, ... from disk and sets them on `this`
 */
Auth.prototype._loadCredentials = function() {
    var self = this;

    if (self.loaded) {
        return new Promise(function(resolve) {
            resolve();
        });
    }

    return loadFromDB(REALNAME_DB_KEY).then(function(realname) {
        self.realname = realname;
        return loadFromDB(EMAIL_ADDR_DB_KEY);

    }).then(function(emailAddress) {
        self.emailAddress = emailAddress;
        return loadFromDB(OAUTH_TOKEN_DB_KEY);

    }).then(function(oauthToken) {
        self.oauthToken = oauthToken;
        self.loaded = true;
    });

    function loadFromDB(key) {
        return self._appConfigStore.listItems(key).then(function(cachedItems) {
            return cachedItems && cachedItems[0];
        });
    }
};

/**
 * Logout of the app by clearing the app config store and in memory credentials
 */
Auth.prototype.logout = function() {
    var self = this;

    // clear app config db
    return self._appConfigStore.clear().then(function() {
        // clear in memory cache
        self.emailAddress = undefined;
        self.realname = undefined;
        self.oauthToken = undefined;
        self._oauth.flushToken();
        self.loaded = undefined;
        self._initialized = undefined;
        self.credentialsDirty = undefined;
    });
};<commit_msg>Fix bug in auth.flushOAuthToken<commit_after>'use strict';

var ngModule = angular.module('woServices');
ngModule.service('auth', Auth);
module.exports = Auth;

var APP_CONFIG_DB_NAME = 'app-config';
var EMAIL_ADDR_DB_KEY = 'emailaddress';
var REALNAME_DB_KEY = 'realname';
var OAUTH_TOKEN_DB_KEY = 'oauthtoken';

/**
 * The Auth BO handles the rough edges and gaps between user/password authentication
 * and OAuth via Chrome Identity API.
 * Typical usage:
 * var auth = new Auth(...);
 * auth.setCredentials(...); // during the account setup
 * auth.getCredentials(...); // called to gather all the information to connect to IMAP/SMTP,
 *                              username, password / oauth token, IMAP/SMTP server host names, ...
 */
function Auth(appConfigStore, oauth) {
    this._appConfigStore = appConfigStore;
    this._oauth = oauth;

    this._initialized = false;
}

/**
 * Initialize the service
 */
Auth.prototype.init = function() {
    var self = this;

    if (self._initialized) {
        return new Promise(function(resolve) {
            resolve();
        });
    }

    // init app config database
    return self._appConfigStore.init(APP_CONFIG_DB_NAME).then(function() {
        // load credentials from disk
        return self._loadCredentials();
    }).then(function() {
        // set login hint if email address was already set previously
        if (self.emailAddress) {
            self._oauth._loginHint = self.emailAddress;
        }

        self._initialized = true;
    });
};

/**
 * Check if the service has been initialized.
 */
Auth.prototype.isInitialized = function() {
    return this._initialized;
};

Auth.prototype.storeCredentials = function() {
    var self = this;

    if (!self.credentialsDirty) {
        // nothing to store if credentials not dirty
        return new Promise(function(resolve) {
            resolve();
        });
    }

    // persist the config
    var storeEmailAddress = self._appConfigStore.storeList([self.emailAddress], EMAIL_ADDR_DB_KEY);
    var storeRealname = self._appConfigStore.storeList([self.realname], REALNAME_DB_KEY);
    var storeOAuthToken = self._appConfigStore.storeList([self.oauthToken], OAUTH_TOKEN_DB_KEY);

    return Promise.all([
        storeEmailAddress,
        storeRealname,
        storeOAuthToken
    ]).then(function() {
        self.credentialsDirty = false;
    });
};

/**
 * Delete the locally cached oauth token.
 */
Auth.prototype.flushOAuthToken = function() {
    this.oauthToken = undefined;
    this._oauth.flushToken();

    // remove cached token from local storage
    return this._appConfigStore.removeList(OAUTH_TOKEN_DB_KEY);
};

/**
 * READ FIRST b/c usage of the oauth api is weird.
 * the chrome identity api will let you query an oauth token for an email account without knowing
 * the corresponding email address. also, android has multiple accounts whereas desktop chrome only
 * has one user logged in.
 * 1) try to read the email address from the configuration (see above)
 * 2) fetch the oauth token. if we already HAVE an email address at this point, we can spare
 *    popping up the account picker on android! if not, the account picker will pop up. this
 *    is android only, since the desktop chrome will query the user that is logged into chrome
 * 3) fetch the email address for the oauth token from the chrome identity api
 */
Auth.prototype.getOAuthCredentials = function() {
    var self = this;

    return new Promise(function(resolve) {
        resolve();
    }).then(function() {
        // make sure we've loaded cached credentials from disk
        return self._loadCredentials();

    }).then(function() {
        // if a stored token exists, check if it's still valid
        if (self.oauthToken) {
            return queryEmailAddress();
        }

        // if no oauth token exists fetch a fresh one
        return self._oauth.getOAuthToken(self.emailAddress).then(function(oauthToken) {
            self.oauthToken = oauthToken;
        });

    }).then(function() {
        // at this point we can be fairly certain that we have a valid oauth token

        // shortcut if the email address is already known
        if (self.emailAddress) {
            return;
        }

        // query the email address
        return queryEmailAddress();

    }).then(function() {
        self.credentialsDirty = true;

        return {
            emailAddress: self.emailAddress,
            realname: self.realname,
            oauthToken: self.oauthToken
        };
    });

    function queryEmailAddress() {
        return self._oauth.queryEmailAddress(self.oauthToken).then(function(info) {
            self.emailAddress = info.emailAddress;
            self.realname = info.realname;

        }).catch(function(err) {
            if (err.code === 401) {
                // oauth token has probably expired
                return self.flushOAuthToken().then(function() {
                    throw err;
                });
            }
            throw err;
        });
    }
};

/**
 * Loads email address, password, ... from disk and sets them on `this`
 */
Auth.prototype._loadCredentials = function() {
    var self = this;

    if (self.loaded) {
        return new Promise(function(resolve) {
            resolve();
        });
    }

    return loadFromDB(REALNAME_DB_KEY).then(function(realname) {
        self.realname = realname;
        return loadFromDB(EMAIL_ADDR_DB_KEY);

    }).then(function(emailAddress) {
        self.emailAddress = emailAddress;
        return loadFromDB(OAUTH_TOKEN_DB_KEY);

    }).then(function(oauthToken) {
        self.oauthToken = oauthToken;
        self.loaded = true;
    });

    function loadFromDB(key) {
        return self._appConfigStore.listItems(key).then(function(cachedItems) {
            return cachedItems && cachedItems[0];
        });
    }
};

/**
 * Logout of the app by clearing the app config store and in memory credentials
 */
Auth.prototype.logout = function() {
    var self = this;

    // clear app config db
    return self._appConfigStore.clear().then(function() {
        // clear in memory cache
        self.emailAddress = undefined;
        self.realname = undefined;
        self.oauthToken = undefined;
        self._oauth.flushToken();
        self.loaded = undefined;
        self._initialized = undefined;
        self.credentialsDirty = undefined;
    });
};<|endoftext|>


<commit_before>/*
 Copyright 2017 Bitnami.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

'use strict';

const exec = require('child_process').exec;
const expect = require('chai').expect;
const fs = require('fs-extra');
const helpers = require('../lib/helpers');
const moment = require('moment');
const os = require('os');
const path = require('path');
const request = require('request');

function deployExample(cwd, example, callback) {
  fs.copy(`${__dirname}/../examples/${example}`, `${cwd}/${example}`, (err) => {
    if (err) throw err;
    fs.remove(`${cwd}/${example}/node_modules`, rmErr => {
      if (rmErr) throw rmErr;
      fs.mkdir(`${cwd}/${example}/node_modules`, mkdirErr => {
        if (mkdirErr) throw mkdirErr;
        fs.symlink(
          `${__dirname}/..`,
          `${cwd}/${example}/node_modules/serverless-kubeless`,
          (linkErr) => {
            if (linkErr) throw linkErr;
            exec('serverless deploy', { cwd: `${cwd}/${example}` }, (deployErr, stdout) => {
              if (deployErr) {
                console.error(`ERROR: ${example} failed to be deployed:\n${stdout}\n${deployErr}`);
              }
              callback();
            });
          }
        );
      });
    });
  });
}
function removeExample(cwd, example, callback) {
  exec('serverless remove', { cwd: `${cwd}/${example}` }, (removeErr) => {
    if (removeErr) throw removeErr;
    fs.remove(cwd, (rmErr) => {
      if (rmErr) throw rmErr;
      callback();
    });
  });
}

function getURL(info, regexp) {
  let URL = info.match(regexp || /URL:\s+(.*)/)[1];
  if (URL.match('API_URL')) {
    URL = URL.replace(
      'API_URL',
      helpers.getKubernetesAPIURL(helpers.loadKubeConfig()).replace(/:[0-9]+$/, ''));
  }
  return URL;
}

function postWithRedirect(url, body, callback) {
  request.post({ url, body, strictSSL: false }, (err, res) => {
    if (res.statusCode === 301) {
      request.post({ url: res.headers.location, body, strictSSL: false }, (errR, resR) => {
        callback(errR, resR);
      });
    } else {
      callback(err, res);
    }
  });
}

describe('Examples', () => {
  let cwd = null;

  describe('event-trigger-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'event-trigger-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'event-trigger-python', done);
    });
    it('should get a submmited message "hello world"', (done) => {
      exec('kubectl get all --all-namespaces', (err, stdout) => {
        console.log('RESOURCES: ', stdout);
      });
      exec('kubeless topic publish --topic hello_topic --data "hello world"', (err, stdout) => {
        if (err) {
          console.error(stdout);
          throw err;
        }
        exec(
          'serverless logs -f events',
          { cwd: `${cwd}/event-trigger-python` },
          (eerr, logs) => {
            if (eerr) throw eerr;
            expect(logs).to.contain('hello world');
            done();
          }
        );
      });
    });
  });
  describe('get-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'get-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'get-python', done);
    });
    it('should return a "hello world"', (done) => {
      exec('serverless invoke -f hello -l', { cwd: `${cwd}/get-python` }, (err, stdout) => {
        if (err) throw err;
        expect(stdout).to.contain('hello world');
        done();
      });
    });
  });
  xdescribe('get-ruby', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'get-ruby', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'get-ruby', done);
    });
    it('should return the latest kubeless version', (done) => {
      exec('serverless invoke -f version -l', { cwd: `${cwd}/get-ruby` }, (err, stdout) => {
        if (err) throw err;
        expect(stdout).to.match(/[0-9]+\.[0-9]+\.[0-9]+/);
        done();
      });
    });
  });
  describe('http-custom-path', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'http-custom-path', () => {
        setTimeout(done, 15000);
      });
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'http-custom-path', done);
    });
    it('should return a "hello world" in a subpath', (done) => {
      exec('serverless info', { cwd: `${cwd}/http-custom-path` }, (err, stdout) => {
        if (err) throw err;
        const URL = getURL(stdout);
        expect(URL).to.match(/.*\/hello/);
        request.get({ url: URL, strictSSL: false }, (gerr, res) => {
          if (gerr) throw gerr;
          expect(res.body).to.contain('hello world');
          done();
        });
      });
    });
  });
  describe('multi-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'multi-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'multi-python', done);
    });
    it('should return "foo"', (done) => {
      exec(
        'serverless invoke -f foo -l --data \'{"hello": "world"}\'',
        { cwd: `${cwd}/multi-python` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('foo');
          done();
        }
      );
    });
    it('should return "bar"', (done) => {
      exec(
        'serverless invoke -f bar -l --data \'{"hello": "world"}\'',
        { cwd: `${cwd}/multi-python` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('bar');
          done();
        }
      );
    });
  });
  describe('post-nodejs', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'post-nodejs', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'post-nodejs', done);
    });
    it('should return "Hello world"', (done) => {
      exec(
        'serverless invoke -f capitalize --data "hello world" -l',
        { cwd: `${cwd}/post-nodejs` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('Hello world');
          done();
        }
      );
    });
  });
  describe('post-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'post-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'post-python', done);
    });
    it('should return a the request', (done) => {
      exec(
        'serverless invoke -f echo --data \'{"hello": "world"}\' -l',
        { cwd: `${cwd}/post-python` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('{ hello: \'world\' }');
          done();
        }
      );
    });
  });
  xdescribe('post-ruby', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'post-ruby', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'post-ruby', done);
    });
    it('should play ping-pong"', (done) => {
      exec(
        'serverless invoke -f ping --data "ping" -l',
        { cwd: `${cwd}/post-ruby` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('pong');
          done();
        }
      );
    });
  });
  describe('todo-app', function () {
    this.timeout(10000);
    let info = '';
    let id = null;

    before(function (done) {
      this.timeout(300000);
      cwd = path.join(os.tmpdir(), moment().valueOf().toString());
      fs.mkdirSync(cwd);
      // We need to deploy a MongoDB for the todo-app example
      exec(
        'curl -sL https://raw.githubusercontent.com/bitnami/bitnami-docker-mongodb/3.4.7-r0/kubernetes.yml',
        (err, manifest) => {
          if (err) {
            console.error('ERROR: Unable to download mongodb manifest');
          } else {
            fs.writeFile(`${cwd}/mongodb.yaml`, manifest, (werr) => {
              if (werr) throw werr;
              exec(`kubectl create -f ${cwd}/mongodb.yaml`, (kerr) => {
                if (kerr) {
                  console.error(`ERROR: Unable to deploy the mongoDB manifest: ${kerr.message}`);
                }
                const wait = setInterval(() => {
                  exec('kubectl get pods', (gerr, stdout) => {
                    if (gerr) throw gerr;
                    if (stdout.match(/mongodb-.*Running/)) {
                      clearInterval(wait);
                      deployExample(cwd, 'todo-app/backend', () => {
                        exec(
                          'serverless info',
                          { cwd: `${cwd}/todo-app/backend` },
                          (infoerr, output) => {
                            if (err) throw err;
                            info = output;
                            setTimeout(done, 15000);
                          }
                        );
                      });
                    }
                  });
                }, 2000);
              });
            });
          }
        }
      );
    });

    after(function (done) {
      this.timeout(300000);
      exec(`kubectl delete -f ${cwd}/mongodb.yaml`, (kerr) => {
        if (kerr) {
          console.error(`ERROR: Unable to remove the mongoDB manifest: ${kerr.message}`);
        }
        removeExample(cwd, 'todo-app/backend', done);
      });
      done();
    });
    it('should create a TODO', (done) => {
      const URL = getURL(info, /Service Information "create"\n(?:.*\n)*?URL:\s+(.*)/);
      expect(URL).to.match(/.*\/create/);
      postWithRedirect(URL, '{"body": "test"}', (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('test');
        id = response.id;
        done();
      });
    });
    it('should read all the TODOs', (done) => {
      const URL = getURL(info, /Service Information "read-all"\n(?:.*\n)*?URL:\s+(.*)/);
      expect(URL).to.match(/.*\/read-all/);
      request.get({ url: URL, strictSSL: false }, (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.be.an('array').with.length(1);
        expect(response[0]).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response[0].body).to.be.eql('test');
        done();
      });
    });
    it('should read one TODO', (done) => {
      const URL = getURL(info, /Service Information "read-one"\n(?:.*\n)*?URL:\s+(.*)/m);
      expect(URL).to.match(/.*\/read/);
      request.get({ url: `${URL}?id=${id}`, strictSSL: false }, (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('test');
        done();
      });
    });
    it('should update one TODO', (done) => {
      const URL = getURL(info, /Service Information "update"\n(?:.*\n)*?URL:\s+(.*)/m);
      expect(URL).to.match(/.*\/update/);
      postWithRedirect(`${URL}?id=${id}`, '{"body": "new-test"}', (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('new-test');
        id = response.id;
        done();
      });
    });
    it('should delete one TODO', (done) => {
      const URL = getURL(info, /Service Information "delete"\n(?:.*\n)*?URL:\s+(.*)/m);
      expect(URL).to.match(/.*\/delete/);
      request.get({ url: `${URL}?id=${id}`, strictSSL: false }, (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('new-test');
        done();
      });
    });
  });
});
<commit_msg>Force to use /tmp dir<commit_after>/*
 Copyright 2017 Bitnami.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

'use strict';

const exec = require('child_process').exec;
const expect = require('chai').expect;
const fs = require('fs-extra');
const helpers = require('../lib/helpers');
const moment = require('moment');
const os = require('os');
const path = require('path');
const request = require('request');

function deployExample(cwd, example, callback) {
  fs.copy(`${__dirname}/../examples/${example}`, `${cwd}/${example}`, (err) => {
    if (err) throw err;
    fs.remove(`${cwd}/${example}/node_modules`, rmErr => {
      if (rmErr) throw rmErr;
      fs.mkdir(`${cwd}/${example}/node_modules`, mkdirErr => {
        if (mkdirErr) throw mkdirErr;
        fs.symlink(
          `${__dirname}/..`,
          `${cwd}/${example}/node_modules/serverless-kubeless`,
          (linkErr) => {
            if (linkErr) throw linkErr;
            exec('serverless deploy', { cwd: `${cwd}/${example}` }, (deployErr, stdout) => {
              if (deployErr) {
                console.error(`ERROR: ${example} failed to be deployed:\n${stdout}\n${deployErr}`);
              }
              callback();
            });
          }
        );
      });
    });
  });
}
function removeExample(cwd, example, callback) {
  exec('serverless remove', { cwd: `${cwd}/${example}` }, (removeErr) => {
    if (removeErr) throw removeErr;
    fs.remove(cwd, (rmErr) => {
      if (rmErr) throw rmErr;
      callback();
    });
  });
}

function getURL(info, regexp) {
  let URL = info.match(regexp || /URL:\s+(.*)/)[1];
  if (URL.match('API_URL')) {
    URL = URL.replace(
      'API_URL',
      helpers.getKubernetesAPIURL(helpers.loadKubeConfig()).replace(/:[0-9]+$/, ''));
  }
  return URL;
}

function postWithRedirect(url, body, callback) {
  request.post({ url, body, strictSSL: false }, (err, res) => {
    if (res.statusCode === 301) {
      request.post({ url: res.headers.location, body, strictSSL: false }, (errR, resR) => {
        callback(errR, resR);
      });
    } else {
      callback(err, res);
    }
  });
}

describe('Examples', () => {
  let cwd = null;

  describe('event-trigger-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'event-trigger-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'event-trigger-python', done);
    });
    it('should get a submmited message "hello world"', (done) => {
      exec('kubectl get all --all-namespaces', (err, stdout) => {
        console.log('RESOURCES: ', stdout);
      });
      exec('kubeless topic publish --topic hello_topic --data "hello world"', (err, stdout) => {
        if (err) {
          console.error(stdout);
          throw err;
        }
        exec(
          'serverless logs -f events',
          { cwd: `${cwd}/event-trigger-python` },
          (eerr, logs) => {
            if (eerr) throw eerr;
            expect(logs).to.contain('hello world');
            done();
          }
        );
      });
    });
  });
  describe('get-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'get-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'get-python', done);
    });
    it('should return a "hello world"', (done) => {
      exec('serverless invoke -f hello -l', { cwd: `${cwd}/get-python` }, (err, stdout) => {
        if (err) throw err;
        expect(stdout).to.contain('hello world');
        done();
      });
    });
  });
  xdescribe('get-ruby', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'get-ruby', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'get-ruby', done);
    });
    it('should return the latest kubeless version', (done) => {
      exec('serverless invoke -f version -l', { cwd: `${cwd}/get-ruby` }, (err, stdout) => {
        if (err) throw err;
        expect(stdout).to.match(/[0-9]+\.[0-9]+\.[0-9]+/);
        done();
      });
    });
  });
  describe('http-custom-path', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'http-custom-path', () => {
        setTimeout(done, 15000);
      });
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'http-custom-path', done);
    });
    it('should return a "hello world" in a subpath', (done) => {
      exec('serverless info', { cwd: `${cwd}/http-custom-path` }, (err, stdout) => {
        if (err) throw err;
        const URL = getURL(stdout);
        expect(URL).to.match(/.*\/hello/);
        request.get({ url: URL, strictSSL: false }, (gerr, res) => {
          if (gerr) throw gerr;
          expect(res.body).to.contain('hello world');
          done();
        });
      });
    });
  });
  describe('multi-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'multi-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'multi-python', done);
    });
    it('should return "foo"', (done) => {
      exec(
        'serverless invoke -f foo -l --data \'{"hello": "world"}\'',
        { cwd: `${cwd}/multi-python` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('foo');
          done();
        }
      );
    });
    it('should return "bar"', (done) => {
      exec(
        'serverless invoke -f bar -l --data \'{"hello": "world"}\'',
        { cwd: `${cwd}/multi-python` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('bar');
          done();
        }
      );
    });
  });
  describe('post-nodejs', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'post-nodejs', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'post-nodejs', done);
    });
    it('should return "Hello world"', (done) => {
      exec(
        'serverless invoke -f capitalize --data "hello world" -l',
        { cwd: `${cwd}/post-nodejs` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('Hello world');
          done();
        }
      );
    });
  });
  describe('post-python', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'post-python', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'post-python', done);
    });
    it('should return a the request', (done) => {
      exec(
        'serverless invoke -f echo --data \'{"hello": "world"}\' -l',
        { cwd: `${cwd}/post-python` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('{ hello: \'world\' }');
          done();
        }
      );
    });
  });
  xdescribe('post-ruby', function () {
    this.timeout(10000);
    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      deployExample(cwd, 'post-ruby', done);
    });
    after(function (done) {
      this.timeout(300000);
      removeExample(cwd, 'post-ruby', done);
    });
    it('should play ping-pong"', (done) => {
      exec(
        'serverless invoke -f ping --data "ping" -l',
        { cwd: `${cwd}/post-ruby` },
        (err, stdout) => {
          if (err) throw err;
          expect(stdout).to.contain('pong');
          done();
        }
      );
    });
  });
  describe('todo-app', function () {
    this.timeout(10000);
    let info = '';
    let id = null;

    before(function (done) {
      this.timeout(300000);
      cwd = path.join('/tmp', moment().valueOf().toString());
      fs.mkdirSync(cwd);
      // We need to deploy a MongoDB for the todo-app example
      exec(
        'curl -sL https://raw.githubusercontent.com/bitnami/bitnami-docker-mongodb/3.4.7-r0/kubernetes.yml',
        (err, manifest) => {
          if (err) {
            console.error('ERROR: Unable to download mongodb manifest');
          } else {
            fs.writeFile(`${cwd}/mongodb.yaml`, manifest, (werr) => {
              if (werr) throw werr;
              exec(`kubectl create -f ${cwd}/mongodb.yaml`, (kerr) => {
                if (kerr) {
                  console.error(`ERROR: Unable to deploy the mongoDB manifest: ${kerr.message}`);
                }
                const wait = setInterval(() => {
                  exec('kubectl get pods', (gerr, stdout) => {
                    if (gerr) throw gerr;
                    if (stdout.match(/mongodb-.*Running/)) {
                      clearInterval(wait);
                      deployExample(cwd, 'todo-app/backend', () => {
                        exec(
                          'serverless info',
                          { cwd: `${cwd}/todo-app/backend` },
                          (infoerr, output) => {
                            if (err) throw err;
                            info = output;
                            setTimeout(done, 15000);
                          }
                        );
                      });
                    }
                  });
                }, 2000);
              });
            });
          }
        }
      );
    });

    after(function (done) {
      this.timeout(300000);
      exec(`kubectl delete -f ${cwd}/mongodb.yaml`, (kerr) => {
        if (kerr) {
          console.error(`ERROR: Unable to remove the mongoDB manifest: ${kerr.message}`);
        }
        removeExample(cwd, 'todo-app/backend', done);
      });
      done();
    });
    it('should create a TODO', (done) => {
      const URL = getURL(info, /Service Information "create"\n(?:.*\n)*?URL:\s+(.*)/);
      expect(URL).to.match(/.*\/create/);
      postWithRedirect(URL, '{"body": "test"}', (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('test');
        id = response.id;
        done();
      });
    });
    it('should read all the TODOs', (done) => {
      const URL = getURL(info, /Service Information "read-all"\n(?:.*\n)*?URL:\s+(.*)/);
      expect(URL).to.match(/.*\/read-all/);
      request.get({ url: URL, strictSSL: false }, (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.be.an('array').with.length(1);
        expect(response[0]).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response[0].body).to.be.eql('test');
        done();
      });
    });
    it('should read one TODO', (done) => {
      const URL = getURL(info, /Service Information "read-one"\n(?:.*\n)*?URL:\s+(.*)/m);
      expect(URL).to.match(/.*\/read/);
      request.get({ url: `${URL}?id=${id}`, strictSSL: false }, (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('test');
        done();
      });
    });
    it('should update one TODO', (done) => {
      const URL = getURL(info, /Service Information "update"\n(?:.*\n)*?URL:\s+(.*)/m);
      expect(URL).to.match(/.*\/update/);
      postWithRedirect(`${URL}?id=${id}`, '{"body": "new-test"}', (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('new-test');
        id = response.id;
        done();
      });
    });
    it('should delete one TODO', (done) => {
      const URL = getURL(info, /Service Information "delete"\n(?:.*\n)*?URL:\s+(.*)/m);
      expect(URL).to.match(/.*\/delete/);
      request.get({ url: `${URL}?id=${id}`, strictSSL: false }, (err, res) => {
        if (err) throw err;
        const response = JSON.parse(res.body);
        expect(response).to.contain.keys(['body', 'id', 'updatedAt']);
        expect(response.body).to.be.eql('new-test');
        done();
      });
    });
  });
});
<|endoftext|>