<commit_before>var mercurius = require('../index.js');
var request = require('supertest');
var assert = require('assert');
var nock = require('nock');
var testUtils = require('./testUtils.js');

describe('mercurius clients support', function() {
  var token;

  before(function() {
    return mercurius.ready
    .then(() => testUtils.register(mercurius.app, 'machineXZ', 'https://localhost:50005', ''))
    .then(gotToken => token = gotToken);
  });

  it('sends notifications to a machine from a client', function(done) {
    nock('https://localhost:50005')
    .post('/')
    .reply(201);

    request(mercurius.app)
    .post('/notify')
    .send({
      token: token,
      client: 'clientXZ'
    })
    .expect(200, done);
  });

  it('provides information about the client', function(done) {
    request(mercurius.app)
    .get('/devices/' + token)
    .send()
    .expect(function(res) {
      assert.equal(res.status, 200);
      assert.equal(res.body.clients.length, 1);
      assert.equal(res.body.clients.indexOf('clientXZ'), 0);
      assert.equal(res.body.machines.machineXZ.clients.clientXZ, '1');
    })
    .end(done);
  });

  it('toggle (disable) notifications for a client', function(done) {
    request(mercurius.app)
    .post('/toggleClientNotification')
    .send({
      token: token,
      machineId: 'machineXZ',
      client: 'clientXZ',
    })
    .expect(function(res) {
      assert.equal(res.status, 200);
      assert.equal(res.body.clients.length, 1);
      assert.equal(res.body.clients.indexOf('clientXZ'), 0);
      assert.equal(res.body.machines.machineXZ.clients.clientXZ, '0');
    })
    .end(done);
  });

  it('sends notifications to a machine from a client', function(done) {
    var req = nock('https://localhost:50005')
    .post('/')
    .reply(201);

    request(mercurius.app)
    .post('/notify')
    .send({
      token: token,
      client: 'clientXZ'
    })
    .expect(200, function() {
      assert(!req.isDone(), 'Notification isn\'t sent do a disabled client');
      nock.cleanAll();
      done();
    });
  });

  it('toggle (enable) notifications for a client', function(done) {
    request(mercurius.app)
    .post('/toggleClientNotification')
    .send({
      token: token,
      machineId: 'machineXZ',
      client: 'clientXZ',
    })
    .expect(function(res) {
      assert.equal(res.status, 200);
      assert.equal(res.body.clients.length, 1);
      assert.equal(res.body.clients.indexOf('clientXZ'), 0);
      assert.equal(res.body.machines.machineXZ.clients.clientXZ, '1');
    })
    .end(done);
  });

  it('sends notifications to a machine from a client', function(done) {
    nock('https://localhost:50005')
    .post('/')
    .reply(201);

    request(mercurius.app)
    .post('/notify')
    .send({
      token: token,
      client: 'clientXZ'
    })
    .expect(200, done);
  });
});
<commit_msg>Update test descriptions<commit_after>var mercurius = require('../index.js');
var request = require('supertest');
var assert = require('assert');
var nock = require('nock');
var testUtils = require('./testUtils.js');

describe('mercurius clients support', function() {
  var token;

  before(function() {
    return mercurius.ready
    .then(() => testUtils.register(mercurius.app, 'machineXZ', 'https://localhost:50005', ''))
    .then(gotToken => token = gotToken);
  });

  it('sends notifications to a machine from a client', function(done) {
    nock('https://localhost:50005')
    .post('/')
    .reply(201);

    request(mercurius.app)
    .post('/notify')
    .send({
      token: token,
      client: 'clientXZ'
    })
    .expect(200, done);
  });

  it('provides information about the client', function(done) {
    request(mercurius.app)
    .get('/devices/' + token)
    .send()
    .expect(function(res) {
      assert.equal(res.status, 200);
      assert.equal(res.body.clients.length, 1);
      assert.equal(res.body.clients.indexOf('clientXZ'), 0);
      assert.equal(res.body.machines.machineXZ.clients.clientXZ, '1');
    })
    .end(done);
  });

  it('toggle (disable) notifications for a client', function(done) {
    request(mercurius.app)
    .post('/toggleClientNotification')
    .send({
      token: token,
      machineId: 'machineXZ',
      client: 'clientXZ',
    })
    .expect(function(res) {
      assert.equal(res.status, 200);
      assert.equal(res.body.clients.length, 1);
      assert.equal(res.body.clients.indexOf('clientXZ'), 0);
      assert.equal(res.body.machines.machineXZ.clients.clientXZ, '0');
    })
    .end(done);
  });

  it('doesn\'t send notifications to a machine from a disabled client', function(done) {
    var req = nock('https://localhost:50005')
    .post('/')
    .reply(201);

    request(mercurius.app)
    .post('/notify')
    .send({
      token: token,
      client: 'clientXZ'
    })
    .expect(200, function() {
      assert(!req.isDone(), 'Notification isn\'t sent do a disabled client');
      nock.cleanAll();
      done();
    });
  });

  it('toggle (enable) notifications for a client', function(done) {
    request(mercurius.app)
    .post('/toggleClientNotification')
    .send({
      token: token,
      machineId: 'machineXZ',
      client: 'clientXZ',
    })
    .expect(function(res) {
      assert.equal(res.status, 200);
      assert.equal(res.body.clients.length, 1);
      assert.equal(res.body.clients.indexOf('clientXZ'), 0);
      assert.equal(res.body.machines.machineXZ.clients.clientXZ, '1');
    })
    .end(done);
  });

  it('sends notifications to a machine from a re-enabled client', function(done) {
    nock('https://localhost:50005')
    .post('/')
    .reply(201);

    request(mercurius.app)
    .post('/notify')
    .send({
      token: token,
      client: 'clientXZ'
    })
    .expect(200, done);
  });
});
<|endoftext|>


<commit_before>var Db = require('../src/db');
var config = require('./config.json');
var PgBoss = require('../src/index');

if(process.env.TRAVIS) {
    config.port = 5433;
    config.password = '';
    config.schema = 'pgboss' + process.env.TRAVIS_JOB_ID;
}

module.exports = {
    init: init,
    start: start,
    extend: extend,
    getDb: getDb,
    getJobById: getJobById,
    config: config,
    connectionString: `postgres://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`
};

function getDb() {
    return new Db(config);
}

function init() {
    return getDb().executeSql(`DROP SCHEMA IF EXISTS ${config.schema} CASCADE`);
}

function getJobById(id) {
    return getDb().executeSql(`select * from ${config.schema}.job where id = $1`, [id]);
}

function start(options) {

    return init()
        .then(() => {
            if(options && typeof options == 'object')
                options = extend(config, options);

            return new PgBoss(options || config).start();
        });
}

function extend(dest, source) {
    for(var key in source) {
        if(source.hasOwnProperty(key))
            dest[key] = source[key];
    }
    return dest;
}<commit_msg>have code. will travis<commit_after>var Db = require('../src/db');
var config = require('./config.json');
var PgBoss = require('../src/index');

if(process.env.TRAVIS) {
    config.port = 5432;
    config.password = '';
    config.schema = 'pgboss' + process.env.TRAVIS_JOB_ID;
}

module.exports = {
    init: init,
    start: start,
    extend: extend,
    getDb: getDb,
    getJobById: getJobById,
    config: config,
    connectionString: `postgres://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`
};

function getDb() {
    return new Db(config);
}

function init() {
    return getDb().executeSql(`DROP SCHEMA IF EXISTS ${config.schema} CASCADE`);
}

function getJobById(id) {
    return getDb().executeSql(`select * from ${config.schema}.job where id = $1`, [id]);
}

function start(options) {

    return init()
        .then(() => {
            if(options && typeof options == 'object')
                options = extend(config, options);

            return new PgBoss(options || config).start();
        });
}

function extend(dest, source) {
    for(var key in source) {
        if(source.hasOwnProperty(key))
            dest[key] = source[key];
    }
    return dest;
}<|endoftext|>


<commit_before>$(function(){
	var canvas = $('.flasher')[0];
	var context = canvas.getContext('2d');
	var color = 1; // Boolean state
	var colorHue = 0; //
	var colorOffset = 120; // between 1 and 360
	var interval;
	var intervalMin = 40; //40 Milliseconds = periode of 25Hz
	var intervalMax = 125; //125 Milliseconds = periode of 8Hz
	var intervalTime = intervalMax; // start with 8Hz wave
	var modifier = 0.5;
	var state = 0;
	var cursorX, cursorY;
	var mouseControl = false;

	function init(){
		canvasToFullscreen();
		beginState();
	}

	/**
	* Click on the canvas to toggle the flashing
	*/
	$(canvas).click(function(){
		state++;
		switchState();
	});

	$( window ).resize(function() {
		canvasToFullscreen();
	});

	/**
	*Set canvas fullscreen
	*/
	function canvasToFullscreen () {
		$(canvas).attr({
			width: window.outerWidth,
			height: window.outerHeight
		});
	}

	/**
	* Get mouse position for manual control
	*/
	document.onmousemove = function(e){
		cursorX = e.pageX;
		cursorY = e.pageY;
	};

	function switchState(){
		switch (state) {
			case 0:
				stopFlashing();
				beginState();
				break;
			case 1:
				startFlashing();
				break;
			case 2:
				mouseControl = true;
				break;
			case 3:
				mouseControl = false;
				state = 0;
				switchState();
				break;
		}
	}

	function beginState() {
		paint('rgb(255,255,255)');
		context.fillStyle = 'black';
		context.font = "bold 30px Verdana";
		context.fillText("PSY-Flasher", 100,70);
		context.font = "17px Verdana";
		context.fillText("First click: auto mode (sweep through frequencies)", 100,100);
		context.fillText("Second click: manual mode (mouse position)", 100,130);
		context.fillText("Third click: back to this page", 100,160);
		context.fillStyle = 'grey';
		context.font = "10px Verdana";
		context.fillText("By Cinezaster", 100,190);
		var gradient = context.createRadialGradient(50,120,1,50,120,80);
		var gradientQuality = 15;
		for (var i = gradientQuality - 1; i > 0; i--) {
			gradient.addColorStop(i*(1/(gradientQuality)),hslToRgbString(i*(360/gradientQuality)));
		}
		context.fillStyle = gradient;
		context.fillRect(10,48,80,143);

	}

	/**
	* Stop the flashing
	*/
	function stopFlashing () {
		clearInterval(interval);
	}

	/**
	 * Start the flashing
	 * by setting interval
	 */
	function startFlashing () {
		interval = setInterval(function () {
			flash();
		},intervalTime/2);
	}

	/**
	 * Flash and alternate between colors using colorOffset
	 */
	function flash() {
		var c;
		if (color) {
			color--;
			//set primary color
			c = colorHue;
			colorHue = (colorHue >= 360)? colorHue-360:colorHue+1;
		} else {
			color++;
			// calculate second color
			c = colorHue + colorOffset;

			if (!mouseControl){
				intervalTime = intervalTime + modifier;

				// takes care of sweeping through 8 and 25Hz
				if (intervalTime > intervalMax || intervalTime < intervalMin) {
					modifier = -modifier;
				}
			} else {
				intervalTime = mapToRange(cursorY, 0, window.outerHeight, intervalMin, intervalMax);
				colorOffset = mapToRange(cursorX, 0, window.outerWidth, 20,180);
			}
			clearInterval(interval);
			interval = setInterval(function () {
				flash();
			},intervalTime/2);
		}
		paint(hslToRgbString(c));
	}

	/**
	 * Assumes c is a color in the set [0,360]
	 * It paints a fullcanvas rect with that color
	 *
	 * @param	Number c 	The hue
	 */
	function paint (c) {
		context.fillStyle = c;
		context.fillRect(0,0,canvas.width,canvas.height);
	}

	/**
	 * Assumes h is contained in the set [0, 360] and
	 * returns r, g, and b in a rgb() String
	 *
	 * @param   Number  h       The hue
	 * @return  String          The rgb(r,g,b) representation
	 */
	function hslToRgbString(h){
		var hue = h/360;
        var r = hue2rgb(hue + 1/3);
        var g = hue2rgb(hue);
        var b = hue2rgb(hue - 1/3);

	    return "rgb(" + Math.round(r * 255)+","+ Math.round(g * 255)+","+ Math.round(b * 255) + ")";
	}

	function hue2rgb(t){
        if(t < 0) t += 1;
        if(t > 1) t -= 1;
        if(t < 1/6) return 6 * t;
        if(t < 1/2) return 1;
        if(t < 2/3) return (2/3 - t) * 6;
        return 0;
    }

    function mapToRange(value, oldMin, oldMax, newMin, newMax) {
    	var oldRange = oldMax - oldMin;
    	var newRange = newMax - newMin;
    	return (((value - oldMin)* newRange)/ oldRange) + newMin;
    }

    init();
});<commit_msg>color offset range update<commit_after>$(function(){
	var canvas = $('.flasher')[0];
	var context = canvas.getContext('2d');
	var color = 1; // Boolean state
	var colorHue = 0; //
	var colorOffset = 120; // between 1 and 360
	var interval;
	var intervalMin = 40; //40 Milliseconds = periode of 25Hz
	var intervalMax = 125; //125 Milliseconds = periode of 8Hz
	var intervalTime = intervalMax; // start with 8Hz wave
	var modifier = 0.5;
	var state = 0;
	var cursorX, cursorY;
	var mouseControl = false;

	function init(){
		canvasToFullscreen();
		beginState();
	}

	/**
	* Click on the canvas to toggle the flashing
	*/
	$(canvas).click(function(){
		state++;
		switchState();
	});

	$( window ).resize(function() {
		canvasToFullscreen();
	});

	/**
	*Set canvas fullscreen
	*/
	function canvasToFullscreen () {
		$(canvas).attr({
			width: window.outerWidth,
			height: window.outerHeight
		});
	}

	/**
	* Get mouse position for manual control
	*/
	document.onmousemove = function(e){
		cursorX = e.pageX;
		cursorY = e.pageY;
	};

	function switchState(){
		switch (state) {
			case 0:
				stopFlashing();
				beginState();
				break;
			case 1:
				startFlashing();
				break;
			case 2:
				mouseControl = true;
				break;
			case 3:
				mouseControl = false;
				state = 0;
				switchState();
				break;
		}
	}

	function beginState() {
		paint('rgb(255,255,255)');
		context.fillStyle = 'black';
		context.font = "bold 30px Verdana";
		context.fillText("PSY-Flasher", 100,70);
		context.font = "17px Verdana";
		context.fillText("First click: auto mode (sweep through frequencies)", 100,100);
		context.fillText("Second click: manual mode (mouse position)", 100,130);
		context.fillText("Third click: back to this page", 100,160);
		context.fillStyle = 'grey';
		context.font = "10px Verdana";
		context.fillText("By Cinezaster", 100,190);
		var gradient = context.createRadialGradient(50,120,1,50,120,80);
		var gradientQuality = 15;
		for (var i = gradientQuality - 1; i > 0; i--) {
			gradient.addColorStop(i*(1/(gradientQuality)),hslToRgbString(i*(360/gradientQuality)));
		}
		context.fillStyle = gradient;
		context.fillRect(10,48,80,143);
	}

	/**
	* Stop the flashing
	*/
	function stopFlashing () {
		clearInterval(interval);
	}

	/**
	 * Start the flashing
	 * by setting interval
	 */
	function startFlashing () {
		interval = setInterval(function () {
			flash();
		},intervalTime/2);
	}

	/**
	 * Flash and alternate between colors using colorOffset
	 */
	function flash() {
		var c;
		if (color) {
			color--;
			//set primary color
			c = colorHue;
			colorHue = (colorHue >= 360)? colorHue-360:colorHue+1;
		} else {
			color++;
			// calculate second color
			c = colorHue + colorOffset;

			if (!mouseControl){
				intervalTime = intervalTime + modifier;

				// takes care of sweeping through 8 and 25Hz
				if (intervalTime > intervalMax || intervalTime < intervalMin) {
					modifier = -modifier;
				}
			} else {
				intervalTime = mapToRange(cursorY, 0, window.outerHeight, intervalMin, intervalMax);
				colorOffset = mapToRange(cursorX, 0, window.outerWidth, 30,330);
			}
			clearInterval(interval);
			interval = setInterval(function () {
				flash();
			},intervalTime/2);
		}
		paint(hslToRgbString(c));
	}

	/**
	 * Assumes c is a color in the set [0,360]
	 * It paints a fullcanvas rect with that color
	 *
	 * @param	Number c 	The hue
	 */
	function paint (c) {
		context.fillStyle = c;
		context.fillRect(0,0,canvas.width,canvas.height);
	}

	/**
	 * Assumes h is contained in the set [0, 360] and
	 * returns r, g, and b in a rgb() String
	 *
	 * @param   Number  h       The hue
	 * @return  String          The rgb(r,g,b) representation
	 */
	function hslToRgbString(h){
		var hue = h/360;
        var r = hue2rgb(hue + 1/3);
        var g = hue2rgb(hue);
        var b = hue2rgb(hue - 1/3);

	    return "rgb(" + Math.round(r * 255)+","+ Math.round(g * 255)+","+ Math.round(b * 255) + ")";
	}

	function hue2rgb(t){
        if(t < 0) t += 1;
        if(t > 1) t -= 1;
        if(t < 1/6) return 6 * t;
        if(t < 1/2) return 1;
        if(t < 2/3) return (2/3 - t) * 6;
        return 0;
    }

    function mapToRange(value, oldMin, oldMax, newMin, newMax) {
    	var oldRange = oldMax - oldMin;
    	var newRange = newMax - newMin;
    	return (((value - oldMin)* newRange)/ oldRange) + newMin;
    }

    init();
});<|endoftext|>


<commit_before>'use strict';

const assert = require('assert');

const render = require('../lib/render');
const prepareContext = require('../lib/prepareContext');

describe('render', function() {
  it('does a render', function(done) {
    const env = {
      herman: {
        customCSS: 'dist/css/main.css',
        minifiedIcons: 'templates/_icons.svg',
        sass: {
          jsonfile: 'dist/css/json.css',
        },
      },
      dir: __dirname,
      renderString() {},
    };
    const tpl = 'templates/base.j2';
    const dest = `${__dirname}/dest`;
    prepareContext({
      data: [],
      groups: {},
      display: {},
    })
      .then(ctx => render(env, tpl, dest, ctx))
      .then(() => {
        // Look for side-effects
        assert.ok(true);
        done();
      })
      .catch(err => {
        assert.fail(err);
        done();
      });
  });
});
<commit_msg>Fix jstest.<commit_after>'use strict';

const assert = require('assert');

const prepareContext = require('../lib/prepareContext');
const render = require('../lib/render');
const { nunjucksEnv } = require('../constants');

describe('render', function() {
  it('does a render', function(done) {
    const tpl = 'templates/base.j2';
    const dest = `${__dirname}/dest/base.html`;
    prepareContext({
      data: [],
      groups: {},
      display: {},
    })
      .then(ctx => render(nunjucksEnv, tpl, dest, ctx))
      .then(() => {
        // Look for side-effects
        assert.ok(true);
        done();
      })
      .catch(err => {
        assert.fail(err);
        done();
      });
  });
});
<|endoftext|>


<commit_before>var functionProxy = require('function-proxy'),
    i18nContext = require('i18n-context')('ember_file_uploader', require.resolve('../locales')),
    t = i18nContext.t,
    config = require('./config');

module.exports = Em.Object.extend(Em.Evented, {
    fileUploader: null,
    file: null,

    isTransferring: false,
    isProcessing: false,
    isCompleted: false,
    isFailed: false,
    progress: 0,
    status: '',

    uploadRequest: null,

    upload: function() {
        var file = this.get('file'),
            url = BD.url(this.get('fileUploader.url')),
            uploadRequest = new FileUploadRequest('POST', url, file),
            additionalHeaders = config.headers;
        this.set('isTransferring', true);
        this.set('uploadRequest', uploadRequest);
        uploadRequest.on('readystatechange', functionProxy(this.onReadyStateChange, this));
        uploadRequest.on('progress', functionProxy(this.onUploadProgress, this));
        uploadRequest.on('load', functionProxy(this.onUploadLoad, this));
        uploadRequest.on('error', functionProxy(this.onUploadError, this));
        uploadRequest.setRequestHeader('X-Filename', file.name);
        uploadRequest.setRequestHeader('X-File-Size', file.size);
        uploadRequest.setRequestHeader('X-Thumbnail-Names', this.get('fileUploader.thumbnailNames'));
        for (var k in additionalHeaders) {
            if (additionalHeaders.hasOwnProperty(k)) {
                uploadRequest.setRequestHeader(k, additionalHeaders[k]);
            }
        }
        uploadRequest.send();
    },
    onReadyStateChange: function() {
        var self = this;
        Em.run(function() {
            var uploadRequest = self.get('uploadRequest'),
                payload,
                file;
            if (uploadRequest.readyState === 4) {
                try {
                    payload = $.parseJSON(uploadRequest.responseText);
                } catch(exception) {
                    //Do nothing, transfer will fail anyway
                }
                if (!payload) {
                    self.handleError();
                } else if (uploadRequest.status === 200) {
                    if (payload.files && payload.files.length) {
                        file = BD.store.load(Billy.File, payload.files[0]);
                    }
                    self.set('isProcessing', false);
                    self.set('isCompleted', true);
                    self.trigger('upload', file, payload);
                    self.trigger('done', self);
                } else if (uploadRequest.status === 422) {
                    self.handleError(payload.errorMessage);
                } else {
                    self.handleError();
                }
            }
        });
    },
    onUploadProgress: function(e) {
        var self = this;
        Em.run(function() {
            if (e.lengthComputable) {
                self.set('progress', Math.round((e.loaded / e.total) * 1000) / 1000);
            }
        });
    },
    onUploadLoad: function() {
        var self = this;
        Em.run(function() {
            self.set('progress', 1);
            self.set('isProcessing', true);
            self.set('isTransferring', false);
        });
    },
    onUploadError: function() {
        var self = this;
        Em.run(function() {
            self.handleError();
        });
    },
    handleError: function(message) {
        this.set('isFailed', true);
        this.set('isTransferring', false);
        this.set('error', message || t('upload_failed'));
        this.trigger('error');
    },

    abort: function() {
        var uploadRequest = this.get('uploadRequest');
        if (uploadRequest) {
            uploadRequest.abort();
        }
        this.trigger('done', this);
    }
});
<commit_msg>Removed BD.url<commit_after>var functionProxy = require('function-proxy'),
    i18nContext = require('i18n-context')('ember_file_uploader', require.resolve('../locales')),
    t = i18nContext.t,
    config = require('./config');

module.exports = Em.Object.extend(Em.Evented, {
    fileUploader: null,
    file: null,

    isTransferring: false,
    isProcessing: false,
    isCompleted: false,
    isFailed: false,
    progress: 0,
    status: '',

    uploadRequest: null,

    upload: function() {
        var file = this.get('file'),
            url = this.get('fileUploader.url'),
            uploadRequest = new FileUploadRequest('POST', url, file),
            additionalHeaders = config.headers;
        this.set('isTransferring', true);
        this.set('uploadRequest', uploadRequest);
        uploadRequest.on('readystatechange', functionProxy(this.onReadyStateChange, this));
        uploadRequest.on('progress', functionProxy(this.onUploadProgress, this));
        uploadRequest.on('load', functionProxy(this.onUploadLoad, this));
        uploadRequest.on('error', functionProxy(this.onUploadError, this));
        uploadRequest.setRequestHeader('X-Filename', file.name);
        uploadRequest.setRequestHeader('X-File-Size', file.size);
        uploadRequest.setRequestHeader('X-Thumbnail-Names', this.get('fileUploader.thumbnailNames'));
        for (var k in additionalHeaders) {
            if (additionalHeaders.hasOwnProperty(k)) {
                uploadRequest.setRequestHeader(k, additionalHeaders[k]);
            }
        }
        uploadRequest.send();
    },
    onReadyStateChange: function() {
        var self = this;
        Em.run(function() {
            var uploadRequest = self.get('uploadRequest'),
                payload,
                file;
            if (uploadRequest.readyState === 4) {
                try {
                    payload = $.parseJSON(uploadRequest.responseText);
                } catch(exception) {
                    //Do nothing, transfer will fail anyway
                }
                if (!payload) {
                    self.handleError();
                } else if (uploadRequest.status === 200) {
                    if (payload.files && payload.files.length) {
                        file = BD.store.load(Billy.File, payload.files[0]);
                    }
                    self.set('isProcessing', false);
                    self.set('isCompleted', true);
                    self.trigger('upload', file, payload);
                    self.trigger('done', self);
                } else if (uploadRequest.status === 422) {
                    self.handleError(payload.errorMessage);
                } else {
                    self.handleError();
                }
            }
        });
    },
    onUploadProgress: function(e) {
        var self = this;
        Em.run(function() {
            if (e.lengthComputable) {
                self.set('progress', Math.round((e.loaded / e.total) * 1000) / 1000);
            }
        });
    },
    onUploadLoad: function() {
        var self = this;
        Em.run(function() {
            self.set('progress', 1);
            self.set('isProcessing', true);
            self.set('isTransferring', false);
        });
    },
    onUploadError: function() {
        var self = this;
        Em.run(function() {
            self.handleError();
        });
    },
    handleError: function(message) {
        this.set('isFailed', true);
        this.set('isTransferring', false);
        this.set('error', message || t('upload_failed'));
        this.trigger('error');
    },

    abort: function() {
        var uploadRequest = this.get('uploadRequest');
        if (uploadRequest) {
            uploadRequest.abort();
        }
        this.trigger('done', this);
    }
});
<|endoftext|>


<commit_before>'use strict';

angular.module('portfolio.userPanel', ['ngRoute', 'ngSanitize'])

.config(['$routeProvider', function($routeProvider) {
	$routeProvider.when('/', {
		templateUrl: 'views/user-panel/user-panel.html',
		controller: 'UserPanelController'
	});
}])

.controller('UserPanelController', ['$scope', '$location', '$timeout', 'usSpinnerService', 'UserConfigService', 'SendEmailService', 'GetGithubProfileService', 'GetCodewarsProfileService', 'GetCodepenProfileService',
	function($scope, $location, $timeout, usSpinnerService, UserConfigService, SendEmailService, GetGithubProfileService, GetCodewarsProfileService, GetCodepenProfileService) {
		$scope.displayError = undefined;
		$scope.loading = false;
		$scope.$watch('loading',function(newValue){
			if (newValue) { usSpinnerService.spin('root-spinner'); }
			if (!newValue) { usSpinnerService.stop('root-spinner'); }
		});

		$scope.userConfig = {};
		$scope.links = {
			codewars: 'https://www.codewars.com/users/',
			github: 'https://github.com/',
			codepen: 'https://codepen.io/'
		};
		$scope.data = {
			github: {},
			codewars: {},
			codepen: {}
		};
		$scope.show = {
			codepen: {
				badge: false
			},
			apps: false,
			email_form: false
		};
		$scope.emailFormData = {
			name: '',
			email: '',
			header: '',
			message: '',
			domain: $location.$$host
		};
		$scope.emailPostBody = '';
		$scope.emailFormSuccessMessage = '';
		$scope.emailFormErrorMessage = '';
		$scope.emailFormDataKeys = Object.keys($scope.emailFormData);
		$scope.emailFormPlaceholders = {
			name: 'You name',
			email: 'your@email.tld',
			header: 'Your message header',
			message: 'Your message text'
		};
		$scope.toggleApps = function() {
			$scope.show.apps = ($scope.show.apps) ? false : true;
			console.log('toggleApps:', $scope.show.apps);
		};
		$scope.toggleEmailForm = function() {
			$scope.show.email_form = ($scope.show.email_form) ? false : true;
			console.log('toggleEmailForm:', $scope.show.email_form);
		};
		$scope.sendMessage = function(isFormValid) {
			$scope.loading = true;
			$scope.emailFormErrorMessage = '';
			$scope.emailFormSuccessMessage = '';
			if (isFormValid) {
				$scope.emailPostBody = '';
				for (var i = 0, max = $scope.emailFormDataKeys.length; i < max; i++) {
					var key = $scope.emailFormDataKeys[i];
					$scope.emailPostBody += key + '=' + $scope.emailFormData[key] + '&';
				}
				$scope.emailPostBody = $scope.emailPostBody.substring(0, $scope.emailPostBody.length - 1);
				SendEmailService.save($scope.emailPostBody).$promise.then(
					function(response) {
						console.log('sendMessage response: ', response);
						if (response.success) {
							$scope.emailFormErrorMessage = '';
							$scope.emailFormSuccessMessage = 'Your message was successfully sent. You will get a reply to the provided email address shortly.';
							$timeout(function() {
								$scope.toggleEmailForm();
								for (var i = 0, max = $scope.emailFormDataKeys.length; i < max; i++) {
									var key = $scope.emailFormDataKeys[i];
									$scope.emailFormData[key] = (key !== 'domain') ? '' : $scope.emailFormData[key];
								}
							}, 3000);
						} else if (response.error) {
							$scope.emailFormErrorMessage = response.error;
							$scope.emailFormSuccessMessage = '';
						} else {
							$scope.emailFormErrorMessage = 'Unknown error';
							$scope.emailFormSuccessMessage = '';
						}
						$scope.loading = false;
					},
					function(error) {
						console.log('sendMessage error: ', error);
						$scope.emailFormSuccessMessage = '';
						$scope.emailFormErrorMessage = error.status + ' : ' + error.statusText;
						$scope.loading = false;
					}
				);
			} else {
				$scope.emailFormErrorMessage = 'The form fields\' values are not valid. Correct mistakes and resubmit your message, please.';
			}
		};

		$scope.getUserConfig = function() {
			$scope.loading = true;
			UserConfigService.query({}).$promise.then(
				function(response) {
					console.log('getUserConfig success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.userConfig = response;
					console.log('use config', $scope.userConfig);
					$scope.links.codewars += $scope.userConfig.username.codewars;
					$scope.links.github += $scope.userConfig.username.github;
					$scope.links.codepen += $scope.userConfig.username.codepen;
					$scope.getGithubProfile();
				},
				function(error) {
					console.log('getUserConfig error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
				}
			);
		};

		$scope.getGithubProfile = function() {
			$scope.loading = true;
			GetGithubProfileService.query({ user: $scope.userConfig.username.github }).$promise.then(
				function(response) {
					console.log('getGithubProfile success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.data.github = response;
					$scope.getCodepenProfile();
				},
				function(error) {
					console.log('getGithubProfile error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
				}
			);
		};
		$scope.getCodepenProfile = function() {
			$scope.loading = true;
			GetCodepenProfileService.query({ user: $scope.userConfig.username.codepen }).$promise.then(
				function(response) {
					console.log('getCodepenProfile success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.data.codepen = response.data;
					$scope.getCodewarsProfile();
					console.log($scope.data);
				},
				function(error) {
					console.log('getCodepenProfile error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
				}
			);
		};
		$scope.getCodewarsProfile = function() {
			$scope.loading = true;
			GetCodewarsProfileService.query({ user: $scope.userConfig.username.codewars }).$promise.then(
				function(response) {
					console.log('getCodewarsProfile success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.data.codewars = response;
				},
				function(error) {
					console.log('getCodewarsProfile error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
					console.log('$scope.data:', $scope.data);
				}
			);
		};

		$scope.$on('$viewContentLoaded', function() {
			console.log('User Panel Controller content loaded');
			$scope.getUserConfig();
			console.log('>> WTF: ',$scope.emailFormData);
		});
		$scope.$on('$destroy', function() {
			console.log('User Panel Controller destroyed');
		});
	}
]);
<commit_msg>(fix) typo<commit_after>'use strict';

angular.module('portfolio.userPanel', ['ngRoute', 'ngSanitize'])

.config(['$routeProvider', function($routeProvider) {
	$routeProvider.when('/', {
		templateUrl: 'views/user-panel/user-panel.html',
		controller: 'UserPanelController'
	});
}])

.controller('UserPanelController', ['$scope', '$location', '$timeout', 'usSpinnerService', 'UserConfigService', 'SendEmailService', 'GetGithubProfileService', 'GetCodewarsProfileService', 'GetCodepenProfileService',
	function($scope, $location, $timeout, usSpinnerService, UserConfigService, SendEmailService, GetGithubProfileService, GetCodewarsProfileService, GetCodepenProfileService) {
		$scope.displayError = undefined;
		$scope.loading = false;
		$scope.$watch('loading',function(newValue){
			if (newValue) { usSpinnerService.spin('root-spinner'); }
			if (!newValue) { usSpinnerService.stop('root-spinner'); }
		});

		$scope.userConfig = {};
		$scope.links = {
			codewars: 'https://www.codewars.com/users/',
			github: 'https://github.com/',
			codepen: 'https://codepen.io/'
		};
		$scope.data = {
			github: {},
			codewars: {},
			codepen: {}
		};
		$scope.show = {
			codepen: {
				badge: false
			},
			apps: false,
			email_form: false
		};
		$scope.emailFormData = {
			name: '',
			email: '',
			header: '',
			message: '',
			domain: $location.$$host
		};
		$scope.emailPostBody = '';
		$scope.emailFormSuccessMessage = '';
		$scope.emailFormErrorMessage = '';
		$scope.emailFormDataKeys = Object.keys($scope.emailFormData);
		$scope.emailFormPlaceholders = {
			name: 'Your name',
			email: 'your@email.tld',
			header: 'Your message header',
			message: 'Your message text'
		};
		$scope.toggleApps = function() {
			$scope.show.apps = ($scope.show.apps) ? false : true;
			console.log('toggleApps:', $scope.show.apps);
		};
		$scope.toggleEmailForm = function() {
			$scope.show.email_form = ($scope.show.email_form) ? false : true;
			console.log('toggleEmailForm:', $scope.show.email_form);
		};
		$scope.sendMessage = function(isFormValid) {
			$scope.loading = true;
			$scope.emailFormErrorMessage = '';
			$scope.emailFormSuccessMessage = '';
			if (isFormValid) {
				$scope.emailPostBody = '';
				for (var i = 0, max = $scope.emailFormDataKeys.length; i < max; i++) {
					var key = $scope.emailFormDataKeys[i];
					$scope.emailPostBody += key + '=' + $scope.emailFormData[key] + '&';
				}
				$scope.emailPostBody = $scope.emailPostBody.substring(0, $scope.emailPostBody.length - 1);
				SendEmailService.save($scope.emailPostBody).$promise.then(
					function(response) {
						console.log('sendMessage response: ', response);
						if (response.success) {
							$scope.emailFormErrorMessage = '';
							$scope.emailFormSuccessMessage = 'Your message was successfully sent. You will get a reply to the provided email address shortly.';
							$timeout(function() {
								$scope.toggleEmailForm();
								for (var i = 0, max = $scope.emailFormDataKeys.length; i < max; i++) {
									var key = $scope.emailFormDataKeys[i];
									$scope.emailFormData[key] = (key !== 'domain') ? '' : $scope.emailFormData[key];
								}
							}, 3000);
						} else if (response.error) {
							$scope.emailFormErrorMessage = response.error;
							$scope.emailFormSuccessMessage = '';
						} else {
							$scope.emailFormErrorMessage = 'Unknown error';
							$scope.emailFormSuccessMessage = '';
						}
						$scope.loading = false;
					},
					function(error) {
						console.log('sendMessage error: ', error);
						$scope.emailFormSuccessMessage = '';
						$scope.emailFormErrorMessage = error.status + ' : ' + error.statusText;
						$scope.loading = false;
					}
				);
			} else {
				$scope.emailFormErrorMessage = 'The form fields\' values are not valid. Correct mistakes and resubmit your message, please.';
			}
		};

		$scope.getUserConfig = function() {
			$scope.loading = true;
			UserConfigService.query({}).$promise.then(
				function(response) {
					console.log('getUserConfig success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.userConfig = response;
					console.log('use config', $scope.userConfig);
					$scope.links.codewars += $scope.userConfig.username.codewars;
					$scope.links.github += $scope.userConfig.username.github;
					$scope.links.codepen += $scope.userConfig.username.codepen;
					$scope.getGithubProfile();
				},
				function(error) {
					console.log('getUserConfig error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
				}
			);
		};

		$scope.getGithubProfile = function() {
			$scope.loading = true;
			GetGithubProfileService.query({ user: $scope.userConfig.username.github }).$promise.then(
				function(response) {
					console.log('getGithubProfile success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.data.github = response;
					$scope.getCodepenProfile();
				},
				function(error) {
					console.log('getGithubProfile error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
				}
			);
		};
		$scope.getCodepenProfile = function() {
			$scope.loading = true;
			GetCodepenProfileService.query({ user: $scope.userConfig.username.codepen }).$promise.then(
				function(response) {
					console.log('getCodepenProfile success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.data.codepen = response.data;
					$scope.getCodewarsProfile();
					console.log($scope.data);
				},
				function(error) {
					console.log('getCodepenProfile error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
				}
			);
		};
		$scope.getCodewarsProfile = function() {
			$scope.loading = true;
			GetCodewarsProfileService.query({ user: $scope.userConfig.username.codewars }).$promise.then(
				function(response) {
					console.log('getCodewarsProfile success: ', response);
					$scope.displayError = undefined;
					$scope.loading = false;
					$scope.data.codewars = response;
				},
				function(error) {
					console.log('getCodewarsProfile error: ', error);
					$scope.displayError = error.status + ' : ' + error.statusText;
					$scope.loading = false;
					console.log('$scope.data:', $scope.data);
				}
			);
		};

		$scope.$on('$viewContentLoaded', function() {
			console.log('User Panel Controller content loaded');
			$scope.getUserConfig();
			console.log('>> WTF: ',$scope.emailFormData);
		});
		$scope.$on('$destroy', function() {
			console.log('User Panel Controller destroyed');
		});
	}
]);
<|endoftext|>


<commit_before>// Copyright (c) 2010-2016 Thomas Fuchs
// http://zeptojs.com/

import $ from 'jquery';
import { ready } from './index';

var touch = {}, touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, longTapDelay = 750, gesture, clicked;

function swipeDirection(x1, x2, y1, y2) {
    return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');
}

function longTap() {
    longTapTimeout = null;
    if (touch.last) {
        if (touch.el !== undefined) touch.el.trigger('longTap');
        touch = {};
    }
}

function cancelLongTap() {
    if (longTapTimeout) clearTimeout(longTapTimeout);
    longTapTimeout = null;
}

function cancelAll() {
    if (touchTimeout)   clearTimeout(touchTimeout);
    if (tapTimeout)     clearTimeout(tapTimeout);
    if (swipeTimeout)   clearTimeout(swipeTimeout);
    if (longTapTimeout) clearTimeout(longTapTimeout);
    touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null;
    touch = {};
}

ready(function () {
    var now, delta, deltaX = 0, deltaY = 0, firstTouch;

    if ('MSGesture' in window) {
        gesture = new MSGesture();
        gesture.target = document.body;
    }

    document.addEventListener('click', () => clicked = true);

    $(document)

        .on('MSGestureEnd gestureend', function (e) {

            var swipeDirectionFromVelocity = e.originalEvent.velocityX > 1 ? 'Right' : e.originalEvent.velocityX < -1 ? 'Left' : e.originalEvent.velocityY > 1 ? 'Down' : e.originalEvent.velocityY < -1 ? 'Up' : null;

            if (swipeDirectionFromVelocity && touch.el !== undefined) {
                touch.el.trigger('swipe');
                touch.el.trigger('swipe' + swipeDirectionFromVelocity);
            }
        })
        .on('touchstart pointerdown', function (e) {

            firstTouch = e.type == 'pointerdown' ? e : e.originalEvent.touches[0];

            now = Date.now();
            delta = now - (touch.last || now);
            touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode);

            if (touchTimeout) clearTimeout(touchTimeout);

            touch.x1 = firstTouch.pageX;
            touch.y1 = firstTouch.pageY;

            if (delta > 0 && delta <= 250) touch.isDoubleTap = true;

            touch.last = now;
            longTapTimeout = setTimeout(longTap, longTapDelay);

            // adds the current touch contact for IE gesture recognition
            if (gesture && ( e.type == 'pointerdown' || e.type == 'touchstart' )) {
                gesture.addPointer(e.originalEvent.pointerId);
            }

            clicked = false;

        })
        .on('touchmove pointermove', function (e) {

            firstTouch = e.type == 'pointermove' ? e : e.originalEvent.touches[0];

            cancelLongTap();
            touch.x2 = firstTouch.pageX;
            touch.y2 = firstTouch.pageY;

            deltaX += Math.abs(touch.x1 - touch.x2);
            deltaY += Math.abs(touch.y1 - touch.y2);
        })
        .on('touchend pointerup', function (e) {

            cancelLongTap();

            // swipe
            if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) {

                swipeTimeout = setTimeout(function () {
                    if (touch.el !== undefined) {
                        touch.el.trigger('swipe');
                        touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)));
                    }
                    touch = {};
                }, 0);

                // normal tap
            } else if ('last' in touch) {

                // don't fire tap when delta position changed by more than 30 pixels,
                // for instance when moving to a point and back to origin
                if (isNaN(deltaX) || (deltaX < 30 && deltaY < 30)) {
                    // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
                    // ('tap' fires before 'scroll')
                    tapTimeout = setTimeout(function () {

                        // trigger universal 'tap' with the option to cancelTouch()
                        // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
                        var event = $.Event('tap');
                        event.cancelTouch = cancelAll;

                        if (touch.el !== undefined) {

                            if (!clicked) {
                                touch.el.trigger('click');
                            }

                            touch.el.trigger(event);
                        }

                        // trigger double tap immediately
                        if (touch.isDoubleTap) {
                            if (touch.el !== undefined) touch.el.trigger('doubleTap');
                            touch = {};
                        }

                        // trigger single tap after 250ms of inactivity
                        else {
                            touchTimeout = setTimeout(function () {
                                touchTimeout = null;
                                if (touch.el !== undefined) touch.el.trigger('singleTap');
                                touch = {};
                            }, 250);
                        }
                    }, 0);
                } else {
                    touch = {};
                }
                deltaX = deltaY = 0;
            }
        })
        // when the browser window loses focus,
        // for example when a modal dialog is shown,
        // cancel all ongoing events
        .on('touchcancel pointercancel', cancelAll);

    // scrolling the window indicates intention of the user
    // to scroll, not tap or swipe, so cancel all ongoing events
    $(window).on('scroll', cancelAll);
});
<commit_msg>updated touch.js<commit_after>// Copyright (c) 2010-2016 Thomas Fuchs
// http://zeptojs.com/

import $ from 'jquery';
import { pointerDown, pointerMove, pointerUp, ready } from './index';

var touch = {}, touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, longTapDelay = 750, gesture, clicked;

function swipeDirection(x1, x2, y1, y2) {
    return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');
}

function longTap() {
    longTapTimeout = null;
    if (touch.last) {
        if (touch.el !== undefined) touch.el.trigger('longTap');
        touch = {};
    }
}

function cancelLongTap() {
    if (longTapTimeout) clearTimeout(longTapTimeout);
    longTapTimeout = null;
}

function cancelAll() {
    if (touchTimeout)   clearTimeout(touchTimeout);
    if (tapTimeout)     clearTimeout(tapTimeout);
    if (swipeTimeout)   clearTimeout(swipeTimeout);
    if (longTapTimeout) clearTimeout(longTapTimeout);
    touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null;
    touch = {};
}

ready(function () {
    var now, delta, deltaX = 0, deltaY = 0, firstTouch;

    if ('MSGesture' in window) {
        gesture = new MSGesture();
        gesture.target = document.body;
    }

    document.addEventListener('click', () => clicked = true);

    $(document)

        .on('MSGestureEnd gestureend', function (e) {

            var swipeDirectionFromVelocity = e.originalEvent.velocityX > 1 ? 'Right' : e.originalEvent.velocityX < -1 ? 'Left' : e.originalEvent.velocityY > 1 ? 'Down' : e.originalEvent.velocityY < -1 ? 'Up' : null;

            if (swipeDirectionFromVelocity && touch.el !== undefined) {
                touch.el.trigger('swipe');
                touch.el.trigger('swipe' + swipeDirectionFromVelocity);
            }
        })
        .on(pointerDown, function (e) {

            firstTouch = e.originalEvent.touches ? e.originalEvent.touches[0] : e;

            now = Date.now();
            delta = now - (touch.last || now);
            touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode);

            if (touchTimeout) clearTimeout(touchTimeout);

            touch.x1 = firstTouch.pageX;
            touch.y1 = firstTouch.pageY;

            if (delta > 0 && delta <= 250) touch.isDoubleTap = true;

            touch.last = now;
            longTapTimeout = setTimeout(longTap, longTapDelay);

            // adds the current touch contact for IE gesture recognition
            if (gesture && ( e.type == 'pointerdown' || e.type == 'touchstart' )) {
                gesture.addPointer(e.originalEvent.pointerId);
            }

            clicked = false;

        })
        .on(pointerMove, function (e) {

            firstTouch = e.originalEvent.touches ? e.originalEvent.touches[0] : e;

            cancelLongTap();
            touch.x2 = firstTouch.pageX;
            touch.y2 = firstTouch.pageY;

            deltaX += Math.abs(touch.x1 - touch.x2);
            deltaY += Math.abs(touch.y1 - touch.y2);
        })
        .on(pointerUp, function () {

            cancelLongTap();

            // swipe
            if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) {

                swipeTimeout = setTimeout(function () {
                    if (touch.el !== undefined) {
                        touch.el.trigger('swipe');
                        touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)));
                    }
                    touch = {};
                }, 0);

                // normal tap
            } else if ('last' in touch) {

                // don't fire tap when delta position changed by more than 30 pixels,
                // for instance when moving to a point and back to origin
                if (isNaN(deltaX) || (deltaX < 30 && deltaY < 30)) {
                    // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
                    // ('tap' fires before 'scroll')
                    tapTimeout = setTimeout(function () {

                        // trigger universal 'tap' with the option to cancelTouch()
                        // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
                        var event = $.Event('tap');
                        event.cancelTouch = cancelAll;

                        if (touch.el !== undefined) {

                            if (!clicked) {
                                touch.el.trigger('click');
                            }

                            touch.el.trigger(event);
                        }

                        // trigger double tap immediately
                        if (touch.isDoubleTap) {
                            if (touch.el !== undefined) touch.el.trigger('doubleTap');
                            touch = {};
                        }

                        // trigger single tap after 250ms of inactivity
                        else {
                            touchTimeout = setTimeout(function () {
                                touchTimeout = null;
                                if (touch.el !== undefined) touch.el.trigger('singleTap');
                                touch = {};
                            }, 250);
                        }
                    }, 0);
                } else {
                    touch = {};
                }
                deltaX = deltaY = 0;
            }
        })
        // when the browser window loses focus,
        // for example when a modal dialog is shown,
        // cancel all ongoing events
        .on('touchcancel pointercancel', cancelAll);

    // scrolling the window indicates intention of the user
    // to scroll, not tap or swipe, so cancel all ongoing events
    $(window).on('scroll', cancelAll);
});
<|endoftext|>


<commit_before>/* eslint no-underscore-dangle: 0 */

import ClientAPI from './client_api';

class StoryStore {
  constructor() {
    this.stories = [];
  }

  addStory(kind, story, fn) {
    this.stories.push({ kind, story, fn });
  }

  getStoryKinds() {
    return this.stories.reduce((kinds, info) => {
      if (kinds.indexOf(info.kind) === -1) {
        kinds.push(info.kind);
      }
      return kinds;
    }, []);
  }

  getStories(kind) {
    return this.stories.reduce((stories, info) => {
      if (info.kind === kind) {
        stories.push(info.story);
      }
      return stories;
    }, []);
  }

  getStory(kind, name) {
    return this.stories.reduce((fn, info) => {
      if (!fn && info.kind === kind && info.story === name) {
        return info.fn;
      }
      return fn;
    }, null);
  }

  hasStory(kind, name) {
    return Boolean(this.getStory(kind, name));
  }
}

describe('preview.client_api', () => {
  describe('setAddon', () => {
    it('should register addons', () => {
      const api = new ClientAPI({});
      let data;

      api.setAddon({
        aa() {
          data = 'foo';
        },
      });

      api.storiesOf('none').aa();
      expect(data).toBe('foo');
    });

    it('should not remove previous addons', () => {
      const api = new ClientAPI({});
      const data = [];

      api.setAddon({
        aa() {
          data.push('foo');
        },
      });

      api.setAddon({
        bb() {
          data.push('bar');
        },
      });

      api.storiesOf('none').aa().bb();
      expect(data).toEqual(['foo', 'bar']);
    });

    it('should call with the api context', () => {
      const api = new ClientAPI({});
      let data;

      api.setAddon({
        aa() {
          data = typeof this.add;
        },
      });

      api.storiesOf('none').aa();
      expect(data).toBe('function');
    });

    it('should be able to access addons added previously', () => {
      const api = new ClientAPI({});
      let data;

      api.setAddon({
        aa() {
          data = 'foo';
        },
      });

      api.setAddon({
        bb() {
          this.aa();
        },
      });

      api.storiesOf('none').bb();
      expect(data).toBe('foo');
    });

    it('should be able to access the current kind', () => {
      const api = new ClientAPI({});
      const kind = 'dfdwf3e3';
      let data;

      api.setAddon({
        aa() {
          data = this.kind;
        },
      });

      api.storiesOf(kind).aa();
      expect(data).toBe(kind);
    });
  });

  describe('addDecorator', () => {
    it('should add local decorators', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');
      localApi.addDecorator(fn => ({ template: `<div>aa${fn().template}</div>` }));

      localApi.add('storyName', () => ({ template: '
hello
' }));
      expect(storyStore.stories[0].fn().template).toBe('
aa
hello

');
    });

    it('should add global decorators', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      api.addDecorator(fn => ({ template: `<div>bb${fn().template}</div>` }));
      const localApi = api.storiesOf('none');

      localApi.add('storyName', () => ({ template: '
hello
' }));
      expect(storyStore.stories[0].fn().template).toBe('
bb
hello

');
    });

    it('should utilize both decorators at once', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');

      api.addDecorator(fn => ({ template: `<div>aa${fn().template}</div>` }));
      localApi.addDecorator(fn => ({ template: `<div>bb${fn().template}</div>` }));

      localApi.add('storyName', () => ({ template: '
hello
' }));
      expect(storyStore.stories[0].fn().template).toBe('
aa
bb
hello

');
    });

    it('should pass the context', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');
      localApi.addDecorator(fn => ({ template: `<div>aa${fn().template}</div>` }));

      localApi.add('storyName', ({ kind, story }) => ({ template: `<p>${kind}-${story}</p>` }));

      const kind = 'dfdfd';
      const story = 'ef349ff';

      const result = storyStore.stories[0].fn({ kind, story });
      expect(result.template).toBe(`<div>aa<p>${kind}-${story}</p>/div>`);
    });

    it('should have access to the context', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');
      localApi.addDecorator((fn, { kind, story }) => ({ template: `<div>${kind}-${story}-${fn().template}</div>` }));

      localApi.add('storyName', () => ({ template: '
hello
' }));

      const kind = 'dfdfd';
      const story = 'ef349ff';

      const result = storyStore.stories[0].fn({ kind, story });
      expect(result.template).toBe(`<div>${kind}-${story}-<p>hello</p></div>`);
    });
  });

  describe('clearDecorators', () => {
    it('should remove all global decorators', () => {
      const api = new ClientAPI({});
      api._globalDecorators = 1234;
      api.clearDecorators();
      expect(api._globalDecorators).toEqual([]);
    });
  });

  describe('getStorybook', () => {
    it('should return storybook when empty', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const book = api.getStorybook();
      expect(book).toEqual([]);
    });

    it('should return storybook with stories', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const functions = {
        'story-1.1': () => 'story-1.1',
        'story-1.2': () => 'story-1.2',
        'story-2.1': () => 'story-2.1',
        'story-2.2': () => 'story-2.2',
      };
      const kind1 = api.storiesOf('kind-1');
      kind1.add('story-1.1', functions['story-1.1']);
      kind1.add('story-1.2', functions['story-1.2']);
      const kind2 = api.storiesOf('kind-2');
      kind2.add('story-2.1', functions['story-2.1']);
      kind2.add('story-2.2', functions['story-2.2']);
      const book = api.getStorybook();
      expect(book).toEqual([
        {
          kind: 'kind-1',
          stories: [
            { name: 'story-1.1', render: functions['story-1.1'] },
            { name: 'story-1.2', render: functions['story-1.2'] },
          ],
        },
        {
          kind: 'kind-2',
          stories: [
            { name: 'story-2.1', render: functions['story-2.1'] },
            { name: 'story-2.2', render: functions['story-2.2'] },
          ],
        },
      ]);
    });
  });
});
<commit_msg>:green_heart: test: fix test failure<commit_after>/* eslint no-underscore-dangle: 0 */

import ClientAPI from './client_api';

class StoryStore {
  constructor() {
    this.stories = [];
  }

  addStory(kind, story, fn) {
    this.stories.push({ kind, story, fn });
  }

  getStoryKinds() {
    return this.stories.reduce((kinds, info) => {
      if (kinds.indexOf(info.kind) === -1) {
        kinds.push(info.kind);
      }
      return kinds;
    }, []);
  }

  getStories(kind) {
    return this.stories.reduce((stories, info) => {
      if (info.kind === kind) {
        stories.push(info.story);
      }
      return stories;
    }, []);
  }

  getStory(kind, name) {
    return this.stories.reduce((fn, info) => {
      if (!fn && info.kind === kind && info.story === name) {
        return info.fn;
      }
      return fn;
    }, null);
  }

  hasStory(kind, name) {
    return Boolean(this.getStory(kind, name));
  }
}

describe('preview.client_api', () => {
  describe('setAddon', () => {
    it('should register addons', () => {
      const api = new ClientAPI({});
      let data;

      api.setAddon({
        aa() {
          data = 'foo';
        },
      });

      api.storiesOf('none').aa();
      expect(data).toBe('foo');
    });

    it('should not remove previous addons', () => {
      const api = new ClientAPI({});
      const data = [];

      api.setAddon({
        aa() {
          data.push('foo');
        },
      });

      api.setAddon({
        bb() {
          data.push('bar');
        },
      });

      api.storiesOf('none').aa().bb();
      expect(data).toEqual(['foo', 'bar']);
    });

    it('should call with the api context', () => {
      const api = new ClientAPI({});
      let data;

      api.setAddon({
        aa() {
          data = typeof this.add;
        },
      });

      api.storiesOf('none').aa();
      expect(data).toBe('function');
    });

    it('should be able to access addons added previously', () => {
      const api = new ClientAPI({});
      let data;

      api.setAddon({
        aa() {
          data = 'foo';
        },
      });

      api.setAddon({
        bb() {
          this.aa();
        },
      });

      api.storiesOf('none').bb();
      expect(data).toBe('foo');
    });

    it('should be able to access the current kind', () => {
      const api = new ClientAPI({});
      const kind = 'dfdwf3e3';
      let data;

      api.setAddon({
        aa() {
          data = this.kind;
        },
      });

      api.storiesOf(kind).aa();
      expect(data).toBe(kind);
    });
  });

  describe('addDecorator', () => {
    it('should add local decorators', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');
      localApi.addDecorator(fn => ({ template: `<div>aa${fn().template}</div>` }));

      localApi.add('storyName', () => ({ template: '
hello
' }));
      expect(storyStore.stories[0].fn().template).toBe('
aa
hello

');
    });

    it('should add global decorators', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      api.addDecorator(fn => ({ template: `<div>bb${fn().template}</div>` }));
      const localApi = api.storiesOf('none');

      localApi.add('storyName', () => ({ template: '
hello
' }));
      expect(storyStore.stories[0].fn().template).toBe('
bb
hello

');
    });

    it('should utilize both decorators at once', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');

      api.addDecorator(fn => ({ template: `<div>aa${fn().template}</div>` }));
      localApi.addDecorator(fn => ({ template: `<div>bb${fn().template}</div>` }));

      localApi.add('storyName', () => ({ template: '
hello
' }));
      expect(storyStore.stories[0].fn().template).toBe('
aa
bb
hello

');
    });

    it('should pass the context', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');
      localApi.addDecorator(fn => ({ template: `<div>aa${fn().template}</div>` }));

      localApi.add('storyName', ({ kind, story }) => ({ template: `<p>${kind}-${story}</p>` }));

      const kind = 'dfdfd';
      const story = 'ef349ff';

      const result = storyStore.stories[0].fn({ kind, story });
      expect(result.template).toBe(`<div>aa<p>${kind}-${story}</p></div>`);
    });

    it('should have access to the context', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const localApi = api.storiesOf('none');
      localApi.addDecorator((fn, { kind, story }) => ({ template: `<div>${kind}-${story}-${fn().template}</div>` }));

      localApi.add('storyName', () => ({ template: '
hello
' }));

      const kind = 'dfdfd';
      const story = 'ef349ff';

      const result = storyStore.stories[0].fn({ kind, story });
      expect(result.template).toBe(`<div>${kind}-${story}-<p>hello</p></div>`);
    });
  });

  describe('clearDecorators', () => {
    it('should remove all global decorators', () => {
      const api = new ClientAPI({});
      api._globalDecorators = 1234;
      api.clearDecorators();
      expect(api._globalDecorators).toEqual([]);
    });
  });

  describe('getStorybook', () => {
    it('should return storybook when empty', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const book = api.getStorybook();
      expect(book).toEqual([]);
    });

    it('should return storybook with stories', () => {
      const storyStore = new StoryStore();
      const api = new ClientAPI({ storyStore });
      const functions = {
        'story-1.1': () => 'story-1.1',
        'story-1.2': () => 'story-1.2',
        'story-2.1': () => 'story-2.1',
        'story-2.2': () => 'story-2.2',
      };
      const kind1 = api.storiesOf('kind-1');
      kind1.add('story-1.1', functions['story-1.1']);
      kind1.add('story-1.2', functions['story-1.2']);
      const kind2 = api.storiesOf('kind-2');
      kind2.add('story-2.1', functions['story-2.1']);
      kind2.add('story-2.2', functions['story-2.2']);
      const book = api.getStorybook();
      expect(book).toEqual([
        {
          kind: 'kind-1',
          stories: [
            { name: 'story-1.1', render: functions['story-1.1'] },
            { name: 'story-1.2', render: functions['story-1.2'] },
          ],
        },
        {
          kind: 'kind-2',
          stories: [
            { name: 'story-2.1', render: functions['story-2.1'] },
            { name: 'story-2.2', render: functions['story-2.2'] },
          ],
        },
      ]);
    });
  });
});
<|endoftext|>


<commit_before>
var Gui = window.require('nw.gui')

var Tray = function()
{
  this._hires = this.hires()

  var icon    = ( this._hires ) ? 'anchor-black-@2x.png' : 'anchor-black.png'
    , alticon = ( this._hires ) ? 'anchor-white-@2x.png' : 'anchor-white.png'

  // Create a tray icon
  this._tray = new Gui.Tray({
      title:   ''
    , icon:    'assets/img/' + icon
    , alticon: 'assets/img/' + alticon
  })

  return this
}

//  test for retina / high resolution / high pixel density.
Tray.prototype.hires = function()
{
  // starts with default value for modern browsers
  var dpr = window.devicePixelRatio ||

  // fallback for IE
      (window.screen.deviceXDPI / window.screen.logicalXDPI) ||

  // default value
      1;

  return !!(dpr > 1);
}

// Get _tray instance
Tray.prototype.get = function()
{
  return this._tray
}

// Set new icon
Tray.prototype.set = function( icon )
{
  if( this._hires )
    icon = icon + '-@2x'

  this._tray.icon = icon + '.png'
}
<commit_msg>Utils/Tray' export method<commit_after>
var Gui = window.require('nw.gui')

module.exports = Tray = function()
{
  this._hires = this.hires()

  var icon    = ( this._hires ) ? 'anchor-black-@2x.png' : 'anchor-black.png'
    , alticon = ( this._hires ) ? 'anchor-white-@2x.png' : 'anchor-white.png'

  // Create a tray icon
  this._tray = new Gui.Tray({
      title:   ''
    , icon:    'assets/img/' + icon
    , alticon: 'assets/img/' + alticon
  })

  return this
}

//  test for retina / high resolution / high pixel density.
Tray.prototype.hires = function()
{
  // starts with default value for modern browsers
  var dpr = window.devicePixelRatio ||

  // fallback for IE
      (window.screen.deviceXDPI / window.screen.logicalXDPI) ||

  // default value
      1;

  return !!(dpr > 1);
}

// Get _tray instance
Tray.prototype.get = function()
{
  return this._tray
}

// Set new icon
Tray.prototype.set = function( icon )
{
  if( this._hires )
    icon = icon + '-@2x'

  this._tray.icon = icon + '.png'
}
<|endoftext|>


<commit_before>
import { omitBy, merge, forEach, reduce } from 'lodash'

import DB from 'jsonmvc-db'

import createControllers from '_controllers/controllers'
import createViews from '_views/views'
import createModels from '_models/models'
import loadModule from '_fns/loadModule'
import update from '_fns/update'
import bundleModules from '_fns/bundleModules'
import start from '_fns/start'
import reloadHMR from '_fns/reloadHMR'
import utils from '_utils'

const jsonmvc = (module, modulesList = {}) => {

  let enabledModules = {
    ajax: modulesList.ajax && loadModule(require.context('_modules/ajax', true, /\.yml|js/)),
    time: modulesList.time && loadModule(require.context('_modules/time', true, /\.yml|js/)),
    ui: modulesList.ui && loadModule(require.context('_modules/ui', true, /\.yml|js/)),
    forms: modulesList.forms && loadModule(require.context('_modules/forms', true, /\.yml|js/)),
    fields: modulesList.fields && loadModule(require.context('_modules/fields', true, /\.yml|js/)),
    firebase: modulesList.firebase && loadModule(require.context('_modules/firebase', true, /\.yml|js/)),
    framework7: modulesList.framework7 && loadModule(require.context('_modules/framework7', true, /\.yml|js/))
  }

  enabledModules = omitBy(enabledModules, x => x === undefined)

  let modules = merge(enabledModules, {
    app: module
  })

  let bundle = bundleModules(modules)

  let db = DB(bundle.data.initial)

  let instance = {
    db: db,
    controllers: createControllers(db, bundle.controllers),
    models: createModels(db, bundle.models),
    views: createViews(db, bundle.views)
  }

  if (typeof window !== 'undefined') {
    window.db = instance.db
    window.instance = instance
  }

  return {
    module,
    update: module => {
      update(instance, {
        app: module
      })
    },
    start: () => {

      if (document.readyState === "complete") {
        start(instance)
      } else {
        document.addEventListener('DOMContentLoaded', function () {
          start(instance)
        })
      }
    }
  }
}

if (typeof window !== 'undefined') {
  window.jsonmvc = jsonmvc
}

export {
  loadModule,
  reloadHMR,
  stream: utils.stream,
  observer: utils.observer
}

export default jsonmvc
<commit_msg>Fix export issue on jsonmvc interface<commit_after>
import { omitBy, merge, forEach, reduce } from 'lodash'

import DB from 'jsonmvc-db'

import createControllers from '_controllers/controllers'
import createViews from '_views/views'
import createModels from '_models/models'
import loadModule from '_fns/loadModule'
import update from '_fns/update'
import bundleModules from '_fns/bundleModules'
import start from '_fns/start'
import reloadHMR from '_fns/reloadHMR'
import utils from '_utils'

const jsonmvc = (module, modulesList = {}) => {

  let enabledModules = {
    ajax: modulesList.ajax && loadModule(require.context('_modules/ajax', true, /\.yml|js/)),
    time: modulesList.time && loadModule(require.context('_modules/time', true, /\.yml|js/)),
    ui: modulesList.ui && loadModule(require.context('_modules/ui', true, /\.yml|js/)),
    forms: modulesList.forms && loadModule(require.context('_modules/forms', true, /\.yml|js/)),
    fields: modulesList.fields && loadModule(require.context('_modules/fields', true, /\.yml|js/)),
    firebase: modulesList.firebase && loadModule(require.context('_modules/firebase', true, /\.yml|js/)),
    framework7: modulesList.framework7 && loadModule(require.context('_modules/framework7', true, /\.yml|js/))
  }

  enabledModules = omitBy(enabledModules, x => x === undefined)

  let modules = merge(enabledModules, {
    app: module
  })

  let bundle = bundleModules(modules)

  let db = DB(bundle.data.initial)

  let instance = {
    db: db,
    controllers: createControllers(db, bundle.controllers),
    models: createModels(db, bundle.models),
    views: createViews(db, bundle.views)
  }

  if (typeof window !== 'undefined') {
    window.db = instance.db
    window.instance = instance
  }

  return {
    module,
    update: module => {
      update(instance, {
        app: module
      })
    },
    start: () => {

      if (document.readyState === "complete") {
        start(instance)
      } else {
        document.addEventListener('DOMContentLoaded', function () {
          start(instance)
        })
      }
    }
  }
}

if (typeof window !== 'undefined') {
  window.jsonmvc = jsonmvc
}

let stream = utils.stream
let observer = utils.observer

export {
  loadModule,
  reloadHMR,
  stream,
  observer
}

export default jsonmvc
<|endoftext|>


<commit_before>/**
 * The test runner will take a properly-formatted page and
 * run accessibility tests against it. To learn more about how to use
 * the test runner, read the wiki at:
 * https://github.com/kevee/quail/wiki/Writing-unit-tests-and-testing-accessibility-tests
 */

(function(global) {

	var testRunner = {

		/**
		 * Accessibility tests loaded from ../dist/tests.json
		 */
		accessibilityTests : {},

		/**
		 * An object to store QUnit callbacks while we scaffold a test for composite.
		 */
		qunitCallbacks : {},

		/**
		 * Run qunit tests against the page. We first capture any
		 * test callbacks into our own object so we can call them later.
		 * This is necessary to keep composite tests with long page
		 * times working.
		 */
		run: function() {
			var that = this;
			if(typeof QUnit === 'undefined') {
				global.QUnit = {
					moduleStart: function(callback) {
						that.qunitCallbacks.moduleStart = callback;
					},
					testStart: function(callback) {
						that.qunitCallbacks.testStart = callback;
					},
					testDone: function(callback) {
						that.qunitCallbacks.testDone = callback;
					},
					log: function(callback) {
						that.qunitCallbacks.log = callback;
					},
					done: function(callback) {
						that.qunitCallbacks.done = callback;
					}
				};
			}
			this.includejQuery();
		},

		/**
		 * Include jQuery on the page using vanilla JS, including differences
		 * in script ready events.
		 */
		includejQuery: function() {
			var em = document.createElement('script');
		  em.type = 'text/javascript';
		  if (em.readyState) {
		      em.onreadystatechange = function () {
		          if (em.readyState == "loaded" || em.readyState == "complete") {
		              em.onreadystatechange = null;
				         testRunner.includeScripts();
		          }
		      };
		  } else {
		      em.onload = function () {
		         testRunner.includeScripts();
		      };
		  }
		  em.src = '../../lib/jquery/jquery.js';
		  var s = document.getElementsByTagName('script')[0];
		  s.parentNode.insertBefore(em, s);
		},

		/**
		 * Once jQuery is available, insert Qunit styles, the placeholder for
		 * the Qunit fixture, and load the rest of the needed JS on the page.
		 * At the end, we request tests.json and set a 250ms timeout to prevent
		 * the parent composite tester from timing out.
		 *
		 * If the page has defined a global.quailTest function, we then run it, if
		 * not, we run the runTests method.
		 */
		includeScripts: function() {
			var that = this;
			$('head').append('<link rel="stylesheet" href="../../lib/qunit/qunit.css" media="screen">');
			$('head').append('<link rel="stylesheet" href="../test.css" media="screen">');
			$('body').prepend('

');
			$.getScript('../quail-testing.jquery.js', function() {
				$.getScript('../../lib/qunit/qunit.js', function() {
					$.ajax({ url: '../../dist/tests.json',
						      dataType: 'json',
						      success: function(data) {
										that.accessibilityTests = data;
										that.buildQUnit();
										QUnit.init();
										setTimeout(function() {
											start();
											var eventObject = document.createEvent('MouseEvents');
											eventObject.initEvent('testsReady', true, true );
											document.dispatchEvent(eventObject);
											if(typeof global.quailTest !== 'undefined') {
												global.quailTest();
											}
											else {
												that.runTests();
											}
										}, 250);
									}
					});
				});
			});
		},

		/**
		 * Assign callbacks for QUnit after the timeout has completed.
		 */
		buildQUnit: function() {
			if(typeof this.qunitCallbacks.moduleStart === 'undefined') {
				return;
			}
			QUnit.moduleStart = this.qunitCallbacks.moduleStart;
			QUnit.testStart = this.qunitCallbacks.testStart;
			QUnit.testDone = this.qunitCallbacks.testDone;
			QUnit.log = this.qunitCallbacks.log;
			QUnit.done = this.qunitCallbacks.done;
		},

		/**
		 * For accessibility tests, we can (for most tests) just use markup on the page
		 * to determine what test to run, where to run it, and whether to expect a failure.
		 * This runs quail against all .quail-test elements, determines pass/fail, and
		 * then runs comparisons into QUnit assertions.
		 */
		runTests: function() {
			var that = this;
			$('.quail-test').each(function(index) {
				if($(this).hasClass('limit-chrome') && navigator.userAgent.search('Chrome') === -1) {
					test('Skipping', function() {
						ok(true, 'Skipping test because browser is not chrome.');
					});
					return;
				}
				if($(this).hasClass('limit-phantom') && navigator.userAgent.search('PhantomJS') === -1) {
					test('Skipping', function() {
						ok(true, 'Skipping test because browser is not phantom.');
					});
					return;
				}
				var thisTest = {
					title : ($(this).attr('title')) ? ': ' + $(this).attr('title') : '',
					accessibilityTest: $(this).data('accessibility-test'),
					expectedPass: ($(this).data('expected') === 'pass'),
				};
				if(typeof thisTest.accessibilityTest === 'undefined' ||
					 !thisTest.accessibilityTest) {
					test('Accessibility test is defined', function() {
						ok(false, 'Accessibility test is not defined.');
					});
				}
				var $that = $(this), expected, label, title;
				testTitle = (typeof that.accessibilityTests[thisTest.accessibilityTest].title !== 'undefined') ?
											that.accessibilityTests[thisTest.accessibilityTest].title.en :
											'No test title defined';
				$that.quail({
					jsonPath: '../../dist',
          guideline: [ thisTest.accessibilityTest ],
          accessibilityTests : that.accessibilityTests,
          reset: true,
          preFilter: function(testName, $element) {
          	if($element.is('#qunit') || $element.parents('#qunit').length) {
          		return false;
          	}
          },
          complete: function(event) {
          	that.quailComplete(event, index, testTitle, thisTest, $that);
          }
        });
			});
		},

		/**
		 * Callback for when quail is done running tests.
		 */
		quailComplete: function(event, index, testTitle, thisTest, $target) {
      test(testTitle +  thisTest.title, function() {
      	label = (thisTest.expectedPass) ? 'pass' : 'fail';
    		$target.addClass(label)
    			   .prepend('#' + (index + 1) + ' (' + label + ')');
    		if(thisTest.expectedPass) {
    			ok(event.results[thisTest.accessibilityTest].elements.length === 0, 'No elements failed test');
    		}
    		else {
    			if($target.hasClass('self-fail')) {
    				ok(event.results[thisTest.accessibilityTest].elements.length > 0, 'Self testing element failed (document-wide test)');
    			}
    			else {
    				$target.find('.quail-failed-element').each(function() {
      				var found = this;
      				expected = false;
      				$.each(event.results[thisTest.accessibilityTest].elements, function(index, $element) {
      					if($element.get(0) === found ||
      						 $element.is('body') && $target.find('body').hasClass('quail-failed-element')) {
      						expected = true;
      						$(found).addClass('found');
      					}
      					if($element.is('svg')) {
      						if($element.attr('class') === 'quail-failed-element') {
      							$element.attr('class', 'quail-failed-element found');
      							expected = true;
      						}
      					}
      				});
      				if(!expected) {
      					ok(false, 'Element not found:' + $('
').append($(found).clone().empty()).html());
      				}
      			});
        		ok($target.find('.quail-failed-element').length === $target.find('.quail-failed-element.found').length, $target.find('.quail-failed-element').length + ' element(s) failed');
    			}
    		}
    	});
  	}
	};

	testRunner.run();

})(this);
<commit_msg>Converted indentation to spaces in testrunner.js<commit_after>/**
 * The test runner will take a properly-formatted page and
 * run accessibility tests against it. To learn more about how to use
 * the test runner, read the wiki at:
 * https://github.com/kevee/quail/wiki/Writing-unit-tests-and-testing-accessibility-tests
 */

(function(global) {

  var testRunner = {

    /**
     * Accessibility tests loaded from ../dist/tests.json
     */
    accessibilityTests : {},

    /**
     * An object to store QUnit callbacks while we scaffold a test for composite.
     */
    qunitCallbacks : {},

    /**
     * Run qunit tests against the page. We first capture any
     * test callbacks into our own object so we can call them later.
     * This is necessary to keep composite tests with long page
     * times working.
     */
    run: function() {
      var that = this;
      if(typeof QUnit === 'undefined') {
        global.QUnit = {
          moduleStart: function(callback) {
            that.qunitCallbacks.moduleStart = callback;
          },
          testStart: function(callback) {
            that.qunitCallbacks.testStart = callback;
          },
          testDone: function(callback) {
            that.qunitCallbacks.testDone = callback;
          },
          log: function(callback) {
            that.qunitCallbacks.log = callback;
          },
          done: function(callback) {
            that.qunitCallbacks.done = callback;
          }
        };
      }
      this.includejQuery();
    },

    /**
     * Include jQuery on the page using vanilla JS, including differences
     * in script ready events.
     */
    includejQuery: function() {
      var em = document.createElement('script');
      em.type = 'text/javascript';
      if (em.readyState) {
        em.onreadystatechange = function () {
          if (em.readyState == "loaded" || em.readyState == "complete") {
            em.onreadystatechange = null;
            testRunner.includeScripts();
          }
        };
      } else {
        em.onload = function () {
          testRunner.includeScripts();
        };
      }
      em.src = '../../lib/jquery/jquery.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(em, s);
    },

    /**
     * Once jQuery is available, insert Qunit styles, the placeholder for
     * the Qunit fixture, and load the rest of the needed JS on the page.
     * At the end, we request tests.json and set a 250ms timeout to prevent
     * the parent composite tester from timing out.
     *
     * If the page has defined a global.quailTest function, we then run it, if
     * not, we run the runTests method.
     */
    includeScripts: function() {
      var that = this;
      $('head').append('<link rel="stylesheet" href="../../lib/qunit/qunit.css" media="screen">');
      $('head').append('<link rel="stylesheet" href="../test.css" media="screen">');
      $('body').prepend('

');
      $.getScript('../quail-testing.jquery.js', function() {
        $.getScript('../../lib/qunit/qunit.js', function() {
          $.ajax({
            url: '../../dist/tests.json',
            dataType: 'json',
            success: function(data) {
              that.accessibilityTests = data;
              that.buildQUnit();
              QUnit.init();
              setTimeout(function() {
                start();
                var eventObject = document.createEvent('MouseEvents');
                eventObject.initEvent('testsReady', true, true );
                document.dispatchEvent(eventObject);
                if(typeof global.quailTest !== 'undefined') {
                  global.quailTest();
                }
                else {
                  that.runTests();
                }
              }, 250);
            }
          });
        });
      });
    },

    /**
     * Assign callbacks for QUnit after the timeout has completed.
     */
    buildQUnit: function() {
      if(typeof this.qunitCallbacks.moduleStart === 'undefined') {
        return;
      }
      QUnit.moduleStart = this.qunitCallbacks.moduleStart;
      QUnit.testStart = this.qunitCallbacks.testStart;
      QUnit.testDone = this.qunitCallbacks.testDone;
      QUnit.log = this.qunitCallbacks.log;
      QUnit.done = this.qunitCallbacks.done;
    },

    /**
     * For accessibility tests, we can (for most tests) just use markup on the page
     * to determine what test to run, where to run it, and whether to expect a failure.
     * This runs quail against all .quail-test elements, determines pass/fail, and
     * then runs comparisons into QUnit assertions.
     */
    runTests: function() {
      var that = this;
      $('.quail-test').each(function(index) {
        if($(this).hasClass('limit-chrome') && navigator.userAgent.search('Chrome') === -1) {
          test('Skipping', function() {
            ok(true, 'Skipping test because browser is not chrome.');
          });
          return;
        }
        if($(this).hasClass('limit-phantom') && navigator.userAgent.search('PhantomJS') === -1) {
          test('Skipping', function() {
            ok(true, 'Skipping test because browser is not phantom.');
          });
          return;
        }
        var thisTest = {
          title : ($(this).attr('title')) ? ': ' + $(this).attr('title') : '',
          accessibilityTest: $(this).data('accessibility-test'),
          expectedPass: ($(this).data('expected') === 'pass'),
        };
        if(typeof thisTest.accessibilityTest === 'undefined' ||
           !thisTest.accessibilityTest) {
          test('Accessibility test is defined', function() {
            ok(false, 'Accessibility test is not defined.');
          });
        }
        var $that = $(this), expected, label, title;
        testTitle = (typeof that.accessibilityTests[thisTest.accessibilityTest].title !== 'undefined') ?
                      that.accessibilityTests[thisTest.accessibilityTest].title.en :
                      'No test title defined';
        $that.quail({
          jsonPath: '../../dist',
          guideline: [ thisTest.accessibilityTest ],
          accessibilityTests : that.accessibilityTests,
          reset: true,
          preFilter: function(testName, $element) {
            if($element.is('#qunit') || $element.parents('#qunit').length) {
              return false;
            }
          },
          complete: function(event) {
            that.quailComplete(event, index, testTitle, thisTest, $that);
          }
        });
      });
    },

    /**
     * Callback for when quail is done running tests.
     */
    quailComplete: function(event, index, testTitle, thisTest, $target) {
      test(testTitle +  thisTest.title, function() {
        label = (thisTest.expectedPass) ? 'pass' : 'fail';
        $target.addClass(label)
             .prepend('#' + (index + 1) + ' (' + label + ')');
        if(thisTest.expectedPass) {
          ok(event.results[thisTest.accessibilityTest].elements.length === 0, 'No elements failed test');
        }
        else {
          if($target.hasClass('self-fail')) {
            ok(event.results[thisTest.accessibilityTest].elements.length > 0, 'Self testing element failed (document-wide test)');
          }
          else {
            $target.find('.quail-failed-element').each(function() {
              var found = this;
              expected = false;
              $.each(event.results[thisTest.accessibilityTest].elements, function(index, $element) {
                if($element.get(0) === found ||
                   $element.is('body') && $target.find('body').hasClass('quail-failed-element')) {
                  expected = true;
                  $(found).addClass('found');
                }
                if($element.is('svg')) {
                  if($element.attr('class') === 'quail-failed-element') {
                    $element.attr('class', 'quail-failed-element found');
                    expected = true;
                  }
                }
              });
              if(!expected) {
                ok(false, 'Element not found:' + $('
').append($(found).clone().empty()).html());
              }
            });
            ok($target.find('.quail-failed-element').length === $target.find('.quail-failed-element.found').length, $target.find('.quail-failed-element').length + ' element(s) failed');
          }
        }
      });
    }
  };

  testRunner.run();

})(this);
<|endoftext|>


<commit_before>module('Path');

test('path.join(path)', function() {
	var doc = new Document();
	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);

	var path2 = new Path();
	path2.add(10, 0);
	path2.add(20, 10);

	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(20, 10))]);
	equals(doc.activeLayer.children.length, 1);

	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);

	var path2 = new Path();
	path2.add(20, 10);
	path2.add(10, 0);
	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(20, 10))]);

	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);

	var path2 = new Path();
	path2.add(30, 10);
	path2.add(40, 0);
	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(30, 10)),
		new Segment(new Point(40, 0))]);

	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);
	path.add(20, 10);

	var path2 = new Path();
	path2.add(0, 0);
	path2.add(10, 5);
	path2.add(20, 10);

	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(20, 10)),
		new Segment(new Point(10, 5))]);
	equals(path.closed, true);
});

test('path.remove()', function() {
	var doc = new Document();
	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);
	path.add(20, 0);
	path.add(30, 0);

	path.remove(0);
	equals(path.segments.length, 3);

	path.remove(path.segments[0]);
	equals(path.segments.length, 2);

	path.remove(0, 1);
	equals(path.segments.length, 0);

	path.remove();

	equals(doc.activeLayer.children.length, 0);
});

test('Is the path deselected after setting a new list of segments?', function() {
	var doc = new Document();
	var path = new Path([0, 0]);
	path.selected = true;
	equals(path.selected, true);
	equals(doc.selectedItems.length, 1);

	path.segments = [[0, 10]];
	equals(path.selected, false);
	equals(doc.selectedItems.length, 0);
});<commit_msg>Add failing test for Path#reverse.<commit_after>module('Path');

test('path.join(path)', function() {
	var doc = new Document();
	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);

	var path2 = new Path();
	path2.add(10, 0);
	path2.add(20, 10);

	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(20, 10))]);
	equals(doc.activeLayer.children.length, 1);

	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);

	var path2 = new Path();
	path2.add(20, 10);
	path2.add(10, 0);
	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(20, 10))]);

	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);

	var path2 = new Path();
	path2.add(30, 10);
	path2.add(40, 0);
	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(30, 10)),
		new Segment(new Point(40, 0))]);

	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);
	path.add(20, 10);

	var path2 = new Path();
	path2.add(0, 0);
	path2.add(10, 5);
	path2.add(20, 10);

	path.join(path2);
	compareSegmentLists(path.segments, [new Segment(new Point(0, 0)),
		new Segment(new Point(10, 0)), new Segment(new Point(20, 10)),
		new Segment(new Point(10, 5))]);
	equals(path.closed, true);
});

test('path.remove()', function() {
	var doc = new Document();
	var path = new Path();
	path.add(0, 0);
	path.add(10, 0);
	path.add(20, 0);
	path.add(30, 0);

	path.remove(0);
	equals(path.segments.length, 3);

	path.remove(path.segments[0]);
	equals(path.segments.length, 2);

	path.remove(0, 1);
	equals(path.segments.length, 0);

	path.remove();

	equals(doc.activeLayer.children.length, 0);
});

test('Is the path deselected after setting a new list of segments?', function() {
	var doc = new Document();
	var path = new Path([0, 0]);
	path.selected = true;
	equals(path.selected, true);
	equals(doc.selectedItems.length, 1);

	path.segments = [[0, 10]];
	equals(path.selected, false);
	equals(doc.selectedItems.length, 0);
});

test('Path#reverse', function() {
	var doc = new Document();
	var path = new Path.Circle([100, 100], 30);
	path.reverse();
	compareSegmentLists(path.segments, [new Segment(new Point(100, 130),
		new Point(-16.568359375, 0), new Point(16.568359375, 0)),
		new Segment(new Point(130, 100), new Point(0, 16.568359375),
		new Point(0, -16.568359375)), new Segment(new Point(100, 70),
		new Point(16.568359375, 0), new Point(-16.568359375, 0)),
		new Segment(new Point(70, 100), new Point(0, -16.568359375),
		new Point(0, 16.568359375))]);
});

<|endoftext|>


<commit_before>const chalk = require('chalk')
const testOps = require('../testOps')

module.exports = () => {
  testOps.setupTest()
  testOps.testMu(['start'])

  testOps.newline()
  console.info(chalk.inverse('ADD FILES & SAVE'))
  const fileDataMap = testOps.addFiles(4)
  let newFiles = Object.keys(fileDataMap)
  console.info(chalk.inverse('MU'))
  testOps.testMu(['save'])

  testOps.newline()

  console.info(chalk.inverse('DEL FILES'))
  newFiles.forEach(fp => {
    testOps.removeFile(fp)
  })

  console.info(chalk.inverse('MU UNDO'))
  testOps.testMu(['undo','.'])

  testOps.newline()

  console.info(chalk.inverse('MOD FILES'))
  newFiles.forEach(fp => {
    testOps.modFile(fp)
  })

  console.info(chalk.inverse('MU UNDO'))
  testOps.testMu(['undo','.'])

  testOps.newline()

  console.info(chalk.inverse('RENAME FILES'))
  newFiles.forEach(fp => {
    testOps.rename(fp)
  })

  console.info(chalk.inverse('MU UNDO'))
  testOps.testMu(['undo','.'])

  testOps.newline()

  testOps.verify(fileDataMap)
}
<commit_msg>improves undo test<commit_after>const chalk = require('chalk')
const testOps = require('../testOps')

module.exports = () => {
  testOps.setupTest()
  testOps.testMu(['start'])

  testOps.newline()
  console.info(chalk.inverse('ADD FILES & SAVE'))
  const fileDataMap = testOps.addFiles(4)
  let newFiles = Object.keys(fileDataMap)
  console.info(chalk.inverse('MU'))
  testOps.testMu(['save'])

  testOps.newline()

  console.info(chalk.inverse('DEL FILES'))
  newFiles.forEach(fp => {
    testOps.removeFile(fp)
  })

  console.info(chalk.inverse('MU UNDO'))
  testOps.testMu(['undo','.'])
  testOps.verify(fileDataMap)

  testOps.newline()

  console.info(chalk.inverse('MOD FILES'))
  newFiles.forEach(fp => {
    testOps.modFile(fp)
  })

  console.info(chalk.inverse('MU UNDO'))
  testOps.testMu(['undo','.'])
  testOps.verify(fileDataMap)

  testOps.newline()

  console.info(chalk.inverse('RENAME FILES'))
  newFiles.forEach(fp => {
    testOps.rename(fp)
  })

  console.info(chalk.inverse('MU UNDO'))
  testOps.testMu(['undo','.'])
  testOps.verify(fileDataMap)
}
<|endoftext|>