<commit_before>// RENDERING TESTS
// ===============
//
// This loads in the render.json sample file and checks that each compiled
// template, in combination with the sample data, produces the expected
// HTML.
//
// TODO: add moar samples

QUnit.config.reorder = false;

var fixture = document.getElementById( 'qunit-fixture' ), tests;

tests = [
	{
		name: "Empty model",
		template: "",
		result: ""
	},
	{
		name: "Plain text",
		template: "a string",
		result: "a string"
	},
	{
		name: "Single interpolator",
		template: "{{mustache}}",
		data: { mustache: "hello world" },
		result: "hello world"
	},
	{
		name: "Element containing single interpolator",
		template: "
{{mustache}}
",
		data: { mustache: "hello world" },
		result: "
hello world
"
	},
	{
		name: "Element containing interpolator surrounded by text",
		template: "
Hello {{mustache}}!
",
		data: { mustache: "world" },
		result: "
Hello world!
"
	},
	{
		name: "Section with index refs",
		template: "
{{#items:i}}
{{i}}: {{name}}
{{/items}}
",
		data: {
			items: [{name:"zero"},{name:"one"},{name:"two"}]
		},
		result: "

0: zero

1: one

2: two

"
	},
	{
		name: "Section with index refs in attributes",
		template: "
{{#items:i}}
{{name}}
{{/items}}
",
		data: {
			items: [{name:"zero"},{name:"one"},{name:"two"}]
		},
		result: "

zero

one

two

"
	},
	{
		name: "Element with attributes",
		template: "
text
",
		data: {
			"class_name": "it_works"
		},
		result: "
text
"
	},
	{
		name: "Section with descendant attributes",
		template: "{{#todos}}
{{todo}}<input value='{{todo}}'>
{{/todos}}",
		data: {
			todos: [{todo:"debug Ractive"},{todo:"release Ractive"}]
		},
		result: "
debug Ractive<input value=\"debug Ractive\">

release Ractive<input value=\"release Ractive\">
"
	},
	{
		name: "Partials",
		template: "{{#items}}{{>item}}{{/items}}",
		data: {
			items: [{description:"Item the first"},{description:"Item the second"},{description:"Item the third"}]
		},
		partials: {
			item: "
{{description}}
"
		},
		result: "
Item the first

Item the second

Item the third
"
	},
	{
		name: "Empty string attributes",
		template: "
test
",
		result: "
test
"
	},
	{
		name: 'Function values',
		template: '
{{message}}
',
		data: { message: function () { return 'functions work'; } },
		result: '
functions work
'
	},
	{
		name: 'Attribute with sections',
		template: '
{{#todos:i}}
{{desc}}
{{/todos}}
',
		data: { todos: [{ desc: 'debug Ractive', completed: false }, { desc: 'release Ractive', completed: false }, { desc: 'make cup of tea', completed: true }]},
		result: '

debug Ractive

release Ractive

make cup of tea

'
	},
	{
		name: 'Conditional section with true condition',
		template: '{{#condition}}The condition is truthy{{/condition}}',
		data: { condition: true },
		result: 'The condition is truthy'
	},
	{
		name: 'Conditional section with false condition',
		template: '{{#condition}}The condition is truthy{{/condition}}',
		data: { condition: false },
		result: ''
	},
	{
		name: 'Inverted section with true condition',
		template: '{{^condition}}The condition is falsy{{/condition}}',
		data: { condition: true },
		result: ''
	},
	{
		name: 'Inverted section with false condition',
		template: '{{^condition}}The condition is falsy{{/condition}}',
		data: { condition: false },
		result: 'The condition is falsy'
	},
	{
		name: 'Table',
		template: "
Click headers to sort:

#	Superhero name	Real name	Superpower
{{#superheroes:i}}
{{i | plus_one}}	{{name}}	{{realname}}	{{power}}
{{/superheroes}}
",
		data: { superheroes: [{ name: 'Nightcrawler', realname: 'Wagner, Kurt',     power: 'Teleportation', info: 'http://www.superherodb.com/Nightcrawler/10-107/' }, { name: 'Cyclops',      realname: 'Summers, Scott',   power: 'Optic blast',   info: 'http://www.superherodb.com/Cyclops/10-50/' }, { name: 'Mystique',     realname: 'Darkholme, Raven', power: 'Shapeshifting', info: 'http://www.superherodb.com/Mystique/10-817/' }, { name: 'Wolverine',    realname: 'Howlett, James',   power: 'Regeneration',  info: 'http://www.superherodb.com/Wolverine/10-161/' } ]},
		result: '
Click headers to sort:

#	Superhero name	Real name	Superpower

1	Nightcrawler	Wagner, Kurt	Teleportation

2	Cyclops	Summers, Scott	Optic blast

3	Mystique	Darkholme, Raven	Shapeshifting

4	Wolverine	Howlett, James	Regeneration

',
		formatters: {
			plus_one: function ( n ) { return n + 1; }
		}
	},
	{
		name: 'Triple',
		template: '
before {{{triple}}} after
',
		data: { triple: 'bold italic' },
		result: '
before bold italic after
',
		new_data: { triple: 'italic bold' },
		new_result: '
before italic bold after
'
	}
];

_.each( tests, function ( t, i ) {
	test( t.name, function () {
		console.group(i+1);

		var ractive = new Ractive({
			el: fixture,
			data: t.data,
			template: t.template,
			partials: t.partials,
			formatters: t.formatters
		});

		equal( fixture.innerHTML, t.result );

		if ( t.new_data ) {
			ractive.set( t.new_data );
			equal( fixture.innerHTML, t.new_result );
		}

		console.groupEnd();
	});
});<commit_msg>updated test<commit_after>// RENDERING TESTS
// ===============
//
// This loads in the render.json sample file and checks that each compiled
// template, in combination with the sample data, produces the expected
// HTML.
//
// TODO: add moar samples

QUnit.config.reorder = false;

var fixture = document.getElementById( 'qunit-fixture' ), tests;

tests = [
	{
		name: "Empty model",
		template: "",
		result: ""
	},
	{
		name: "Plain text",
		template: "a string",
		result: "a string"
	},
	{
		name: "Single interpolator",
		template: "{{mustache}}",
		data: { mustache: "hello world" },
		result: "hello world"
	},
	{
		name: "Element containing single interpolator",
		template: "
{{mustache}}
",
		data: { mustache: "hello world" },
		result: "
hello world
"
	},
	{
		name: "Element containing interpolator surrounded by text",
		template: "
Hello {{mustache}}!
",
		data: { mustache: "world" },
		result: "
Hello world!
"
	},
	{
		name: "Section with index refs",
		template: "
{{#items:i}}
{{i}}: {{name}}
{{/items}}
",
		data: {
			items: [{name:"zero"},{name:"one"},{name:"two"}]
		},
		result: "

0: zero

1: one

2: two

"
	},
	{
		name: "Section with index refs in attributes",
		template: "
{{#items:i}}
{{name}}
{{/items}}
",
		data: {
			items: [{name:"zero"},{name:"one"},{name:"two"}]
		},
		result: "

zero

one

two

"
	},
	{
		name: "Element with attributes",
		template: "
text
",
		data: {
			"class_name": "it_works"
		},
		result: "
text
"
	},
	{
		name: "Section with descendant attributes",
		template: "{{#todos}}
{{todo}}{{todo}}
{{/todos}}",
		data: {
			todos: [{todo:"debug Ractive",status:"complete"},{todo:"release Ractive",status:"incomplete"}]
		},
		result: "
debug Ractivedebug Ractive

release Ractiverelease Ractive
"
	},
	{
		name: "Section with descendant value attributes",
		template: "{{#todos}}
{{todo}}<input value='{{todo}}'>
{{/todos}}",
		data: {
			todos: [{todo:"debug Ractive"},{todo:"release Ractive"}]
		},
		result: "
debug Ractive<input>

release Ractive<input>
"
	},
	{
		name: "Partials",
		template: "{{#items}}{{>item}}{{/items}}",
		data: {
			items: [{description:"Item the first"},{description:"Item the second"},{description:"Item the third"}]
		},
		partials: {
			item: "
{{description}}
"
		},
		result: "
Item the first

Item the second

Item the third
"
	},
	{
		name: "Empty string attributes",
		template: "
test
",
		result: "
test
"
	},
	{
		name: 'Function values',
		template: '
{{message}}
',
		data: { message: function () { return 'functions work'; } },
		result: '
functions work
'
	},
	{
		name: 'Attribute with sections',
		template: '
{{#todos:i}}
{{desc}}
{{/todos}}
',
		data: { todos: [{ desc: 'debug Ractive', completed: false }, { desc: 'release Ractive', completed: false }, { desc: 'make cup of tea', completed: true }]},
		result: '

debug Ractive

release Ractive

make cup of tea

'
	},
	{
		name: 'Conditional section with true condition',
		template: '{{#condition}}The condition is truthy{{/condition}}',
		data: { condition: true },
		result: 'The condition is truthy'
	},
	{
		name: 'Conditional section with false condition',
		template: '{{#condition}}The condition is truthy{{/condition}}',
		data: { condition: false },
		result: ''
	},
	{
		name: 'Inverted section with true condition',
		template: '{{^condition}}The condition is falsy{{/condition}}',
		data: { condition: true },
		result: ''
	},
	{
		name: 'Inverted section with false condition',
		template: '{{^condition}}The condition is falsy{{/condition}}',
		data: { condition: false },
		result: 'The condition is falsy'
	},
	{
		name: 'Table',
		template: "
Click headers to sort:

#	Superhero name	Real name	Superpower
{{#superheroes:i}}
{{i | plus_one}}	{{name}}	{{realname}}	{{power}}
{{/superheroes}}
",
		data: { superheroes: [{ name: 'Nightcrawler', realname: 'Wagner, Kurt',     power: 'Teleportation', info: 'http://www.superherodb.com/Nightcrawler/10-107/' }, { name: 'Cyclops',      realname: 'Summers, Scott',   power: 'Optic blast',   info: 'http://www.superherodb.com/Cyclops/10-50/' }, { name: 'Mystique',     realname: 'Darkholme, Raven', power: 'Shapeshifting', info: 'http://www.superherodb.com/Mystique/10-817/' }, { name: 'Wolverine',    realname: 'Howlett, James',   power: 'Regeneration',  info: 'http://www.superherodb.com/Wolverine/10-161/' } ]},
		result: '
Click headers to sort:

#	Superhero name	Real name	Superpower

1	Nightcrawler	Wagner, Kurt	Teleportation

2	Cyclops	Summers, Scott	Optic blast

3	Mystique	Darkholme, Raven	Shapeshifting

4	Wolverine	Howlett, James	Regeneration

',
		formatters: {
			plus_one: function ( n ) { return n + 1; }
		}
	},
	{
		name: 'Triple',
		template: '
before {{{triple}}} after
',
		data: { triple: 'bold italic' },
		result: '
before bold italic after
',
		new_data: { triple: 'italic bold' },
		new_result: '
before italic bold after
'
	}
];

_.each( tests, function ( t, i ) {
	test( t.name, function () {
		console.group(i+1);

		var ractive = new Ractive({
			el: fixture,
			data: t.data,
			template: t.template,
			partials: t.partials,
			formatters: t.formatters
		});

		equal( fixture.innerHTML, t.result );

		if ( t.new_data ) {
			ractive.set( t.new_data );
			equal( fixture.innerHTML, t.new_result );
		}

		console.groupEnd();
	});
});<|endoftext|>


<commit_before>/* Copyright (c) 2017 e-soa Jacques Desodt, MIT License */
'use strict'

/* Default plugin options */
const role = 'entity-crud-test'

/* Prerequisites */
const Seneca = require('seneca') // eslint-disable-line no-unused-vars
const testFunctions = require('./functions')

/* Test prerequisites */
const Code = require('code')
const Lab = require('lab', {timeout: testFunctions.timeout})
var lab = (exports.lab = Lab.script())
var describe = lab.describe
var it = lab.it
var expect = Code.expect

describe('update', function () {
  //
  // Simple update
  it('simple', function (fin) {
    // Initializes the data
    var content = 'Listen to this song written by David Bowie.'
    var updateTitle = 'Life on Mars'
    var updateTag = 'A tag'
    var entity = {title: 'Life on Venus', content: content}
    var updateEntity = null
    // Gets the Seneca instance
    var seneca = testFunctions.setSeneca(Seneca, role, fin) // Add 'print' for debug
    // Creates before read
    seneca.act({role: role, cmd: 'create', entity: entity}, function (ignore, result) {
      // Checks result
      expect(result.entity.id).to.not.equal(null)
      entity = result.entity
      updateEntity = {id: result.entity.id, title: updateTitle, tag: updateTag}
      // Update
      seneca.act({role: role, cmd: 'update', entity: updateEntity}, function (ignore, updateResult) {
        // Checks result
        expect(updateResult.success).to.equal(true)
        // Read
        seneca.act({role: role, cmd: 'read', id: entity.id}, function (ignore, readResult) {
          expect(readResult.success).to.equal(true)
          expect(readResult.entity.title).to.equal(updateTitle)
          expect(readResult.entity.content).to.equal(content)
          expect(readResult.entity.tag).to.equal(updateTag)
          fin()
        })
      })
    })
  })

  // Update returns no namespace
  it('no namespace', function (fin) {
    // Initializes the data
    var content = 'Listen to this song written by David Bowie.'
    var updateTitle = 'Life on Mars'
    var updateTag = 'A tag'
    var entity = {title: 'Life on Venus', content: content}
    var updateEntity = null
    // Gets the Seneca instance
    var seneca = testFunctions.setSeneca(Seneca, role, fin) // Add 'print' for debug
    // Creates before read
    seneca.act({role: role, cmd: 'create', entity: entity}, function (ignore, result) {
      // Checks result
      expect(result.entity.id).to.not.equal(null)
      entity = result.entity
      updateEntity = {id: result.entity.id, title: updateTitle, tag: updateTag}
      // Update
      seneca.act({role: role, cmd: 'update', entity: updateEntity, nonamespace: true}, function (ignore, updateResult) {
        // Checks result
        expect(updateResult.success).to.equal(true)
        expect(updateResult.entity.entity$).to.not.exist()
      // Read
        seneca.act({role: role, cmd: 'read', id: entity.id}, function (ignore, readResult) {
          expect(readResult.success).to.equal(true)
          expect(readResult.entity.title).to.equal(updateTitle)
          expect(readResult.entity.content).to.equal(content)
          expect(readResult.entity.tag).to.equal(updateTag)
          fin()
        })
      })
    })
  })
  //
})
<commit_msg>This project has been moved to GitLab<commit_after><|endoftext|>


<commit_before>var supertest = require('supertest');
var chai = require('chai');
var expect = chai.expect;
var api = supertest('https://' + process.env.SYSTEMAPIC_DOMAIN);
var helpers = require('../helpers');
var token = helpers.token;
var httpStatus = require('http-status');
var Layer = require('../../models/layer');
var expected = require('../../shared/errors');

module.exports = function () {

    describe('/api/user/unique', function () {

        it('should respond with status code 401 when not authenticated', function (done) {
            api.post('/api/user/unique')
                .send({})
                .expect(httpStatus.UNAUTHORIZED)
                .end(done);
        });

        it('should respond with status code 400 and error if email doesn\'t exist in request body', function (done) {
            token(function (err, access_token) {
                if (err) {
                    return done(err);
                }

				api.post('/api/user/unique')
	                .send({
                        access_token: access_token
                    })
	                .expect(httpStatus.BAD_REQUEST)
	                .end(function (err, res) {
	                	if (err) {
	                		return done(err);
	                	}

                        var result = helpers.parse(res.text);

                        expect(result.error.code).to.be.equal(httpStatus.BAD_REQUEST);
                        expect(result.error.errors.missingRequiredFields).to.include('email');

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

        it('should respond with status code 200 and unique true if user with such email doesn\'t exist', function (done) {
            token(function (err, access_token) {
                if (err) {
                    return done(err);
                }

				api.post('/api/user/unique')
	                .send({
                        access_token: access_token,
                        email: "unique12345678901233@gmail.com"
                    })
	                .expect(httpStatus.OK)
	                .end(function (err, res) {
	                	if (err) {
	                		return done(err);
	                	}

                        var result = helpers.parse(res.text);

                        expect(result.unique).to.be.true;

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

        it('should respond with status code 200 and unique false if user with such email alredy exist', function (done) {
            token(function (err, access_token) {
                if (err) {
                    return done(err);
                }

				api.post('/api/user/unique')
	                .send({
                        access_token: access_token,
                        email: helpers.test_user.email
                    })
	                .expect(httpStatus.OK)
	                .end(function (err, res) {
	                	if (err) {
	                		return done(err);
	                	}

                        var result = helpers.parse(res.text);

                        expect(result.unique).to.be.false;

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

    });

};<commit_msg>updated tests<commit_after>var supertest = require('supertest');
var chai = require('chai');
var expect = chai.expect;
var api = supertest('https://' + process.env.SYSTEMAPIC_DOMAIN);
var helpers = require('../helpers');
var token = helpers.token;
var httpStatus = require('http-status');
var Layer = require('../../models/layer');
var expected = require('../../shared/errors');

module.exports = function () {

    describe('/api/user/unique', function () {

        it('should respond with status code 401 when not authenticated', function (done) {
            api.post('/api/user/unique')
                .send({})
                .expect(httpStatus.UNAUTHORIZED)
                .end(done);
        });

        it('should respond with status code 401 and error if email doesn\'t exist in request body', function (done) {
            token(function (err, access_token) {
                if (err) {
                    return done(err);
                }

				api.post('/api/user/unique')
	                .send({
                        access_token: access_token
                    })
	                .expect(httpStatus.UNAUTHORIZED)
	                .end(function (err, res) {
	                	if (err) {
	                		return done(err);
	                	}

                        var result = helpers.parse(res.text);

                        expect(result.error.code).to.be.equal(httpStatus.UNAUTHORIZED);
                        expect(result.error.errors.missingRequiredFields).to.include('email');

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

        it('should respond with status code 200 and unique true if user with such email doesn\'t exist', function (done) {
            token(function (err, access_token) {
                if (err) {
                    return done(err);
                }

				api.post('/api/user/unique')
	                .send({
                        access_token: access_token,
                        email: "unique12345678901233@gmail.com"
                    })
	                .expect(httpStatus.OK)
	                .end(function (err, res) {
	                	if (err) {
	                		return done(err);
	                	}

                        var result = helpers.parse(res.text);

                        expect(result.unique).to.be.true;

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

        it('should respond with status code 200 and unique false if user with such email alredy exist', function (done) {
            token(function (err, access_token) {
                if (err) {
                    return done(err);
                }

				api.post('/api/user/unique')
	                .send({
                        access_token: access_token,
                        email: helpers.test_user.email
                    })
	                .expect(httpStatus.OK)
	                .end(function (err, res) {
	                	if (err) {
	                		return done(err);
	                	}

                        var result = helpers.parse(res.text);

                        expect(result.unique).to.be.false;

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

    });

};<|endoftext|>


<commit_before>import { expect } from 'chai';
import { defaultTo, toString, toNumber, toInteger, toFloat, toBoolean, mapFrom } from '../../src/utils';

describe('UTILS', function () {
  describe('defaultTo(defaultValue)', function () {
    it('should return a function', function () {
      expect(defaultTo('')).to.be.a('function');
    });
    describe('the returned function', function () {
      it('should default to the specified value when null is received as first argument', function () {
        expect(defaultTo('default')(undefined)).to.equal('default');
        expect(defaultTo(0)(undefined)).to.equal(0);
        expect(defaultTo(false)(undefined)).to.equal(false);
      });
      it('shuld return the value received as first argument if it\'s not null', function () {
        expect(defaultTo('default')('not null')).to.equal('not null');
      });
    });
  });
  describe('toString(value)', function () {
    it('should tranform the value into a string', function () {
      expect(toString(121)).to.equal('121');
      expect(toString(true)).to.equal('true');
      expect(toString({})).to.equal('[object Object]');
    });
  });
  describe('toNumber(value)', function () {
    it('should tranform the value into a number', function () {
      expect(toNumber('121')).to.equal(121);
      expect(toNumber('121.12')).to.equal(121.12);
      expect(toNumber(121)).to.equal(121);
      expect(toNumber(121.12)).to.equal(121.12);
    });
    it('should throw an error when the value cannot be transform into a number', function () {
      expect(() => toNumber('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('toFloat(value)', function () {
    it('should tranform the value into a float', function () {
      expect(toFloat('121')).to.equal(121.0);
      expect(toFloat('121.12')).to.equal(121.12);
      expect(toFloat(121)).to.equal(121.0);
      expect(toFloat(121.12)).to.equal(121.12);
    });
    it('should throw an error when the value cannot be transform into a float', function () {
      expect(() => toFloat('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('toInteger(value)', function () {
    it('should tranform the value into an integer', function () {
      expect(toInteger('121')).to.equal(121);
      expect(toInteger('121.12')).to.equal(121);
      expect(toInteger(121)).to.equal(121);
      expect(toInteger(121.12)).to.equal(121);
    });
    it('should throw an error when the value cannot be transform into an integer', function () {
      expect(() => toInteger('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('toBoolean(value)', function () {
    it('should tranform the value into a boolean', function () {
      expect(toBoolean('true')).to.equal(true);
      expect(toBoolean('false')).to.equal(false);
      expect(toBoolean(true)).to.equal(true);
      expect(toBoolean(false)).to.equal(false);
    });
    it('should throw an error when the value cannot be transform into a boolean', function () {
      expect(() => toBoolean('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('mapFrom(mapping)', function () {
    it('should return a function', function () {
      expect(mapFrom({})).to.be.a('function');
    });
    describe('the returned function', function () {
      it('should map the value received as first argument using the mapping', function () {
        expect(mapFrom({ test: 'mapped value' })('test')).to.equal('mapped value');
        expect(mapFrom({ 1: 'mapped value' })(1)).to.equal('mapped value');
        expect(mapFrom({ [false]: 'mapped value' })(false)).to.equal('mapped value');
      });
    });
  });
});
<commit_msg>Add tests to 'using' utility function<commit_after>import { expect } from 'chai';
import { defaultTo, toString, toNumber, toInteger, toFloat, toBoolean, mapFrom, using } from '../../src/utils';

describe('UTILS', function () {
  describe('defaultTo(defaultValue)', function () {
    it('should return a function', function () {
      expect(defaultTo('')).to.be.a('function');
    });
    describe('the returned function', function () {
      it('should default to the specified value when null is received as first argument', function () {
        expect(defaultTo('default')(undefined)).to.equal('default');
        expect(defaultTo(0)(undefined)).to.equal(0);
        expect(defaultTo(false)(undefined)).to.equal(false);
      });
      it('shuld return the value received as first argument if it\'s not null', function () {
        expect(defaultTo('default')('not null')).to.equal('not null');
      });
    });
  });
  describe('toString(value)', function () {
    it('should tranform the value into a string', function () {
      expect(toString(121)).to.equal('121');
      expect(toString(true)).to.equal('true');
      expect(toString({})).to.equal('[object Object]');
    });
  });
  describe('toNumber(value)', function () {
    it('should tranform the value into a number', function () {
      expect(toNumber('121')).to.equal(121);
      expect(toNumber('121.12')).to.equal(121.12);
      expect(toNumber(121)).to.equal(121);
      expect(toNumber(121.12)).to.equal(121.12);
    });
    it('should throw an error when the value cannot be transform into a number', function () {
      expect(() => toNumber('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('toFloat(value)', function () {
    it('should tranform the value into a float', function () {
      expect(toFloat('121')).to.equal(121.0);
      expect(toFloat('121.12')).to.equal(121.12);
      expect(toFloat(121)).to.equal(121.0);
      expect(toFloat(121.12)).to.equal(121.12);
    });
    it('should throw an error when the value cannot be transform into a float', function () {
      expect(() => toFloat('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('toInteger(value)', function () {
    it('should tranform the value into an integer', function () {
      expect(toInteger('121')).to.equal(121);
      expect(toInteger('121.12')).to.equal(121);
      expect(toInteger(121)).to.equal(121);
      expect(toInteger(121.12)).to.equal(121);
    });
    it('should throw an error when the value cannot be transform into an integer', function () {
      expect(() => toInteger('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('toBoolean(value)', function () {
    it('should tranform the value into a boolean', function () {
      expect(toBoolean('true')).to.equal(true);
      expect(toBoolean('false')).to.equal(false);
      expect(toBoolean(true)).to.equal(true);
      expect(toBoolean(false)).to.equal(false);
    });
    it('should throw an error when the value cannot be transform into a boolean', function () {
      expect(() => toBoolean('asdfad')).to.throw(/Cannot transform/);
    });
  });
  describe('mapFrom(mapping)', function () {
    it('should return a function', function () {
      expect(mapFrom({})).to.be.a('function');
    });
    describe('the returned function', function () {
      it('should map the value received as first argument using the mapping', function () {
        expect(mapFrom({ test: 'mapped value' })('test')).to.equal('mapped value');
        expect(mapFrom({ 1: 'mapped value' })(1)).to.equal('mapped value');
        expect(mapFrom({ [false]: 'mapped value' })(false)).to.equal('mapped value');
      });
    });
  });
  describe('using(fn)', function () {
    it('should return a function', function () {
      expect(using(() => ({}))).to.be.a('function');
    });
    it('should apply the function `fn` to the value', function () {
      expect(using((v) => v * 2)(2)).to.equal(4);
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var browserSingleton;
/**
 * @workInProgress
 * @ngdoc service
 * @name angular.service.$browser
 * @requires $log
 *
 * @description
 * Represents the browser.
 */
angularService('$browser', function($log){
  if (!browserSingleton) {
    browserSingleton = new Browser(window, jqLite(window.document), jqLite(window.document.body),
                                   XHR, $log);
    browserSingleton.bind();
  }
  return browserSingleton;
}, {$inject:['$log']});

extend(angular, {
  // disabled for now until we agree on public name
  //'annotate': annotate,
  'element': jqLite,
  'compile': compile,
  'scope': createScope,
  'copy': copy,
  'extend': extend,
  'equals': equals,
  'forEach': forEach,
  'injector': createInjector,
  'noop':noop,
  'bind':bind,
  'toJson': toJson,
  'fromJson': fromJson,
  'identity':identity,
  'isUndefined': isUndefined,
  'isDefined': isDefined,
  'isString': isString,
  'isFunction': isFunction,
  'isObject': isObject,
  'isNumber': isNumber,
  'isArray': isArray,
  'version': version
});

//try to bind to jquery now so that one can write angular.element().read()
//but we will rebind on bootstrap again.
bindJQuery();

<commit_msg>doc($browser): remove duplication of $browser to docs<commit_after>'use strict';

var browserSingleton;

angularService('$browser', function($log){
  if (!browserSingleton) {
    browserSingleton = new Browser(window, jqLite(window.document), jqLite(window.document.body),
                                   XHR, $log);
    browserSingleton.bind();
  }
  return browserSingleton;
}, {$inject:['$log']});

extend(angular, {
  // disabled for now until we agree on public name
  //'annotate': annotate,
  'element': jqLite,
  'compile': compile,
  'scope': createScope,
  'copy': copy,
  'extend': extend,
  'equals': equals,
  'forEach': forEach,
  'injector': createInjector,
  'noop':noop,
  'bind':bind,
  'toJson': toJson,
  'fromJson': fromJson,
  'identity':identity,
  'isUndefined': isUndefined,
  'isDefined': isDefined,
  'isString': isString,
  'isFunction': isFunction,
  'isObject': isObject,
  'isNumber': isNumber,
  'isArray': isArray,
  'version': version
});

//try to bind to jquery now so that one can write angular.element().read()
//but we will rebind on bootstrap again.
bindJQuery();

<|endoftext|>


<commit_before>/*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/
/*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/

define(function(require){
	var $ = require('jquery');
	var html = require('text!test/markup/wizard-markup.html');

	require('bootstrap');
	require('fuelux/wizard');

	function testWizardStepStates($wizard, activeStep) {
		var $steps = $wizard.find('li');

		for(var i = 0; i < $steps.length; i++) {
			if(i === (activeStep - 1)){
				equal($steps.eq(i).hasClass('active'), true, 'step ' + activeStep + ' is active');
			}
			else if (i < (activeStep - 1)) {
				equal($steps.eq(i).hasClass('complete'), true, 'step ' + (i + 1) + ' is complete');
			}
			else {
				equal($steps.eq(i).hasClass('complete'), false, 'step ' + (i + 1) + ' is not complete');
			}
		}
	}

	module("Fuel UX Wizard");

	test("should be defined on jquery object", function () {
		ok($().wizard, 'wizard method is defined');
	});

	test("should return element", function () {
		var $wizard = $(html).find('#MyWizard');
		ok($wizard.wizard() === $wizard, 'wizard should be initialized');
	});

	test("should set step index", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var index   = $wizard.wizard('selectedItem').step;

		// check default state
		equal(index, 1, 'default step is set');

		// move to next step
		$wizard.wizard('next');
		index = $wizard.wizard('selectedItem').step;
		equal(index, 2, 'next step is set');

		// move to previous step
		$wizard.wizard('previous');
		index = $wizard.wizard('selectedItem').step;
		equal(index, 1, 'previous step is set');
	});

	test("should fire change event", function () {
		var $wizard    = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('changed.fu.wizard', function (evt, data) {
			eventFired = true;
		});

		// move to next step
		$wizard.wizard('next');

		equal(eventFired, true, 'change event fired');
	});

	test("should fire changed event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('changed.fu.wizard', function (evt, data) {
			eventFired = true;
		});

		// move to next step
		$wizard.wizard('next');
		var index = $wizard.wizard('selectedItem').step;

		equal(eventFired, true, 'changed event fired');
		equal(index, 2, 'step changed');
	});

	test("should suppress changed event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('change.fu.wizard', function (evt, data) {
			eventFired = true;
			return evt.preventDefault(); // prevent action
		});

		// move to next step
		$wizard.wizard('next');
		var index = $wizard.wizard('selectedItem').step;

		equal(eventFired, true, 'change event fired');
		equal(index, 1, 'step not changed');
	});

	test("should suppress stepclick event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('stepclick.fu.wizard', function (evt, data) {
			eventFired = true;
			return evt.preventDefault(); // prevent action
		});

		// move to second step
		$wizard.wizard('next');

		// click first step
		$wizard.find('.steps li:first').click();

		var index = $wizard.wizard('selectedItem').step;

		equal(eventFired, true, 'stepclick event fired');
		equal(index, 2, 'step not changed');
	});

	test("should fire finished event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('finished.fu.wizard', function (evt, data) {
			eventFired = true;
		});

		// move to next step
		$wizard.wizard('next'); // move to step2
		$wizard.wizard('next'); // move to step3
		$wizard.wizard('next'); // move to step4
		$wizard.wizard('next'); // move to step5
		$wizard.wizard('next'); // calling next method on last step triggers event

		equal(eventFired, true, 'finish event fired');
	});

	test("should change nextBtn text as appropriate", function () {
		var $wizard = $(html).find('#MyWizardWithSpaces').wizard();
		var $nextClone;

		$nextClone = $wizard.find('.btn-next').clone();
		$nextClone.children().remove();
		equal($.trim($nextClone.text()), 'Next', 'nextBtn text equal to "Next"');

		$wizard.wizard('next');
		$wizard.wizard('next');
		$wizard.wizard('next');
		$wizard.wizard('next');
		$wizard.wizard('next');
		$nextClone = $wizard.find('.btn-next').clone();
		$nextClone.children().remove();
		equal($.trim($nextClone.text()), 'Finish', 'nextBtn text equal to "Finish"');

		$wizard.wizard('previous');
		$nextClone = $wizard.find('.btn-next').clone();
		$nextClone.children().remove();
		equal($.trim($nextClone.text()), 'Next', 'nextBtn text equal to "Next"');
	});

	test("pass no init parameter to set current step", function () {
		var step    = 1;
		var $wizard = $(html).find('#MyWizard').wizard();

		testWizardStepStates($wizard, step);
	});

	test("pass init parameter to set current step > 1", function () {
		var step    = 3;
		var $wizard = $(html).find('#MyWizard').wizard({selectedItem:{step:step}});

		testWizardStepStates($wizard, step);
	});

	test("use selectedItem to set current step > 1", function () {
		var step = 3;
		var $wizard = $(html).find('#MyWizard').wizard();

		testWizardStepStates($wizard, 1);

		$wizard.wizard('selectedItem', {step:step});

		testWizardStepStates($wizard, step);
	});

	test( "should disabled previous steps when data attribute is present", function() {
		var step       = 3;
		var secondStep = 2;
		var $wizard = $(html).find('#MyWizardPreviousStepDisabled').wizard();

		// checking disabled property of previous button and making sure CSS class is present that removes hovers and changes cursor on previous steps
		var prevBtnDisabled   = !!$wizard.find( '.btn-prev' ).prop( 'disabled' );
		var stepsListCssClass = !!$wizard.find( '.steps' ).hasClass( 'previous-disabled' );

		testWizardStepStates( $wizard, 1 );

		// testing to see if step changes when previous step clicked on
		$wizard.wizard( 'selectedItem', { step: step } );
		$wizard.find( '.steps > li:first-child' ).click();
		var activeStepIndex = $wizard.find( '.steps > li' ).index( $wizard.find( '.steps > li.active' ) ) + 1;

		// making sure wizard can still programatically set it's own step
		$wizard.wizard( 'selectedItem', { step: secondStep } );
		var wizardSetActiveStep = $wizard.find( '.steps > li' ).index( $wizard.find( '.steps > li.active' ) ) + 1;

		// tests
		equal( prevBtnDisabled, true, 'previous step button is disabled' );
		equal( stepsListCssClass, true, 'step list has correct CSS class for disabling hovers and changing cursor' );
		equal( activeStepIndex, step, 'did not go to step when previous step clicked' );
		equal( wizardSetActiveStep, secondStep, 'can still programatically set previous step' );
	});

	/*
	test("should manage step panes", function() {
		var $wizard = $(html).wizard();
		var $step = $wizard.find('#step1');

		equal($wizard.find('#step1').hasClass('active'), true, 'active class set');
		$wizard.wizard('next');
		equal($wizard.find('#step1').hasClass('active'), false, 'active class removed');
	});
	*/

});
<commit_msg>Update wizard test events<commit_after>/*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/
/*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/
/*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/

define(function(require){
	var $ = require('jquery');
	var html = require('text!test/markup/wizard-markup.html');

	require('bootstrap');
	require('fuelux/wizard');

	function testWizardStepStates($wizard, activeStep) {
		var $steps = $wizard.find('li');

		for(var i = 0; i < $steps.length; i++) {
			if(i === (activeStep - 1)){
				equal($steps.eq(i).hasClass('active'), true, 'step ' + activeStep + ' is active');
			}
			else if (i < (activeStep - 1)) {
				equal($steps.eq(i).hasClass('complete'), true, 'step ' + (i + 1) + ' is complete');
			}
			else {
				equal($steps.eq(i).hasClass('complete'), false, 'step ' + (i + 1) + ' is not complete');
			}
		}
	}

	module("Fuel UX Wizard");

	test("should be defined on jquery object", function () {
		ok($().wizard, 'wizard method is defined');
	});

	test("should return element", function () {
		var $wizard = $(html).find('#MyWizard');
		ok($wizard.wizard() === $wizard, 'wizard should be initialized');
	});

	test("should set step index", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var index   = $wizard.wizard('selectedItem').step;

		// check default state
		equal(index, 1, 'default step is set');

		// move to next step
		$wizard.wizard('next');
		index = $wizard.wizard('selectedItem').step;
		equal(index, 2, 'next step is set');

		// move to previous step
		$wizard.wizard('previous');
		index = $wizard.wizard('selectedItem').step;
		equal(index, 1, 'previous step is set');
	});

	test("should fire clicked event", function () {
		var $wizard    = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('clicked.fu.wizard.action', function (evt, data) {
			eventFired = true;
		});

		// move to next step
		$wizard.wizard('next');

		equal(eventFired, true, 'clicked event fired');
	});

	test("should fire changed event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('changed.fu.wizard', function (evt, data) {
			eventFired = true;
		});

		// move to next step
		$wizard.wizard('next');
		var index = $wizard.wizard('selectedItem').step;

		equal(eventFired, true, 'changed event fired');
		equal(index, 2, 'step changed');
	});

	test("should suppress changed event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('clicked.fu.wizard.action', function (evt, data) {
			eventFired = true;
			return evt.preventDefault(); // prevent action
		});

		// move to next step
		$wizard.wizard('next');
		var index = $wizard.wizard('selectedItem').step;

		equal(eventFired, true, 'clicked event fired');
		equal(index, 1, 'step not changed');
	});

	test("should suppress stepclick event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('stepclick.fu.wizard', function (evt, data) {
			eventFired = true;
			return evt.preventDefault(); // prevent action
		});

		// move to second step
		$wizard.wizard('next');

		// click first step
		$wizard.find('.steps li:first').click();

		var index = $wizard.wizard('selectedItem').step;

		equal(eventFired, true, 'stepclick event fired');
		equal(index, 2, 'step not changed');
	});

	test("should fire finished event", function () {
		var $wizard = $(html).find('#MyWizard').wizard();
		var eventFired = false;

		$wizard.on('finished.fu.wizard', function (evt, data) {
			eventFired = true;
		});

		// move to next step
		$wizard.wizard('next'); // move to step2
		$wizard.wizard('next'); // move to step3
		$wizard.wizard('next'); // move to step4
		$wizard.wizard('next'); // move to step5
		$wizard.wizard('next'); // calling next method on last step triggers event

		equal(eventFired, true, 'finish event fired');
	});

	test("should change nextBtn text as appropriate", function () {
		var $wizard = $(html).find('#MyWizardWithSpaces').wizard();
		var $nextClone;

		$nextClone = $wizard.find('.btn-next').clone();
		$nextClone.children().remove();
		equal($.trim($nextClone.text()), 'Next', 'nextBtn text equal to "Next"');

		$wizard.wizard('next');
		$wizard.wizard('next');
		$wizard.wizard('next');
		$wizard.wizard('next');
		$wizard.wizard('next');
		$nextClone = $wizard.find('.btn-next').clone();
		$nextClone.children().remove();
		equal($.trim($nextClone.text()), 'Finish', 'nextBtn text equal to "Finish"');

		$wizard.wizard('previous');
		$nextClone = $wizard.find('.btn-next').clone();
		$nextClone.children().remove();
		equal($.trim($nextClone.text()), 'Next', 'nextBtn text equal to "Next"');
	});

	test("pass no init parameter to set current step", function () {
		var step    = 1;
		var $wizard = $(html).find('#MyWizard').wizard();

		testWizardStepStates($wizard, step);
	});

	test("pass init parameter to set current step > 1", function () {
		var step    = 3;
		var $wizard = $(html).find('#MyWizard').wizard({selectedItem:{step:step}});

		testWizardStepStates($wizard, step);
	});

	test("use selectedItem to set current step > 1", function () {
		var step = 3;
		var $wizard = $(html).find('#MyWizard').wizard();

		testWizardStepStates($wizard, 1);

		$wizard.wizard('selectedItem', {step:step});

		testWizardStepStates($wizard, step);
	});

	test( "should disabled previous steps when data attribute is present", function() {
		var step       = 3;
		var secondStep = 2;
		var $wizard = $(html).find('#MyWizardPreviousStepDisabled').wizard();

		// checking disabled property of previous button and making sure CSS class is present that removes hovers and changes cursor on previous steps
		var prevBtnDisabled   = !!$wizard.find( '.btn-prev' ).prop( 'disabled' );
		var stepsListCssClass = !!$wizard.find( '.steps' ).hasClass( 'previous-disabled' );

		testWizardStepStates( $wizard, 1 );

		// testing to see if step changes when previous step clicked on
		$wizard.wizard( 'selectedItem', { step: step } );
		$wizard.find( '.steps > li:first-child' ).click();
		var activeStepIndex = $wizard.find( '.steps > li' ).index( $wizard.find( '.steps > li.active' ) ) + 1;

		// making sure wizard can still programatically set it's own step
		$wizard.wizard( 'selectedItem', { step: secondStep } );
		var wizardSetActiveStep = $wizard.find( '.steps > li' ).index( $wizard.find( '.steps > li.active' ) ) + 1;

		// tests
		equal( prevBtnDisabled, true, 'previous step button is disabled' );
		equal( stepsListCssClass, true, 'step list has correct CSS class for disabling hovers and changing cursor' );
		equal( activeStepIndex, step, 'did not go to step when previous step clicked' );
		equal( wizardSetActiveStep, secondStep, 'can still programatically set previous step' );
	});

	/*
	test("should manage step panes", function() {
		var $wizard = $(html).wizard();
		var $step = $wizard.find('#step1');

		equal($wizard.find('#step1').hasClass('active'), true, 'active class set');
		$wizard.wizard('next');
		equal($wizard.find('#step1').hasClass('active'), false, 'active class removed');
	});
	*/

});
<|endoftext|>


<commit_before>/*
	AppController.js
	Copyright (c) 2014-2020 dangered wolf, et al
	Released under the MIT licence
*/

import { make, exists, getIpc } from "./Utils.js";
import { UIAlert } from "./UIAlert.js";
import { UIUpdateNotify } from "./UIUpdateNotify.js";
import { AutoUpdateController } from "./AutoUpdateController.js";
import { openSettings } from "./UISettings.js";
import { buildContextMenu } from "./UIContextMenu.js";
import { parseActions, loadPreferences } from "./PrefHandler.js";
import { parseConfig } from "./EnterpriseConfigParser.js";
import { I18n } from "./I18n.js";

let offlineNotification;

/*
	Notifies users of an app update
*/

function notifyUpdate() {
	if (isDev || enterpriseConfig.disableUpdateNotification) {
		return;
	}
	UIUpdateNotify();
}

/*
	Create offline notification (probably because we're offline)
*/

function notifyOffline() {

	if (exists(offlineNotification)) {
		return;
	}

	let notifRoot = mR.findFunction("showErrorNotification")[0].showNotification({title:I18n("Internet Disconnected"),timeoutDelayMs:9999999999});
	let notifId = notifRoot._id;
	offlineNotification = $("li.Notification[data-id=\""+notifId+"\"]");
	let notifContent = $("li.Notification[data-id=\""+notifId+"\"] .Notification-content");
	let notifIcon = $("li.Notification[data-id=\""+notifId+"\"] .Notification-icon .Icon");

	if (offlineNotification.length > 0) {
		notifIcon.removeClass("Icon--notifications").addClass("mtd-icon-disconnected");

		notifContent.append(
			make("p").attr("style","max-width:initial!important").html(I18n("We detected that you are disconnected from the internet. Many actions are unavailable without an internet connection."))
		)
	}
}

/*
	Dismiss offline notification (probably because we're online again)
*/

function dismissOfflineNotification() {
	if (!exists(window.offlineNotification)) {return;}
	mR.findFunction("showErrorNotification")[0].removeNotification({notification:offlineNotification});
}

/*
	mtdAppFunctions() consists of functions to help interface
	from here (the renderer process) to the main process
*/

export function mtdAppFunctions() {

	if (typeof require === "undefined") {return;}

	const { remote, ipcRenderer } = require("electron");

	const Store = require("electron-store");
	store = new Store({name:"mtdsettings"});

	// Enable high contrast if system is set to high contrast

	$(document).on("uiDrawerHideDrawer",(e) => {
		getIpc().send("drawerClose");
	});

	$(document).on("uiDrawerActive",(e) => {
		if (!$(".application").hasClass("hide-detail-view-inline"))
			getIpc().send("drawerOpen");
	});

	ipcRenderer.on("enterpriseConfig", (e, config) => {
		window.enterpriseConfig = config;
		parseConfig(config);
		loadPreferences();
	});

	ipcRenderer.on("inverted-color-scheme-changed", (e, enabled) => {
		if (enabled && getPref("mtd_highcontrast") !== true) {
			try {
				settingsData.accessibility.options.highcont.activate.func();
			} catch(e){}
		}
	});

	ipcRenderer.on("color-scheme-changed", (e, theme) => {
		parseActions(settingsData.themes.options.coretheme.activate, theme);

	});

	ipcRenderer.on("disable-high-contrast", (e) => {
		console.info("DISABLING HIGH CONTRAST ");
		try {
			settingsData.accessibility.options.highcont.deactivate.func();
		} catch(e){}
	});

	ipcRenderer.on("aboutMenu", (e,args) => {
		if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0 && $("#settings-modal").attr("style") === "display: block;"){
			$(".mtd-settings-tab[data-action=\"about\"]").click();
		} else {
			openSettings();
			if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0){
				$(".mtd-settings-tab[data-action=\"about\"]").click();
			}
		}
	});

	ipcRenderer.on("checkForUpdatesMenu", (e,args) => {
		if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0 && $("#settings-modal").attr("style") === "display: block;"){
			$(".mtd-settings-tab[data-action=\"about\"]").click();
		} else {
			openSettings();
			if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0){
				$(".mtd-settings-tab[data-action=\"about\"]").click();
			}
		}

		if (!AutoUpdateController.isCheckingForUpdates) {
			ipcRenderer.send("checkForUpdates");
		}
	});

	ipcRenderer.on("update-downloaded", (e,args) => {
		if ($("#settings-modal[style='display: block;']>.mtd-settings-panel").length <= 0 && !html.hasClass("mtd-winstore") && !html.hasClass("mtd-macappstore")) {
			notifyUpdate()
		}
	});

	ipcRenderer.on("openSettings", (e,args) => {
		openSettings();
	});

	ipcRenderer.on("accountsMan", (e,args) => {
		$(".js-show-drawer.js-header-action").click();
	});

	ipcRenderer.on("sendFeedback", (e,args) => {
		window.open("https://github.com/dangeredwolf/ModernDeck/issues");
	});

	ipcRenderer.on("msgModernDeck", (e,args) => {
		$(document).trigger("uiComposeTweet", {
			type: "message",
			messageRecipients: [{
				screenName: "ModernDeck"
			}]
		})
	});

	ipcRenderer.on("newTweet", (e,args) => {
		mtdPrepareWindows();
		$(document).trigger("uiComposeTweet");
	});

	ipcRenderer.on("newDM", (e,args) => {
		mtdPrepareWindows();
		$(document).trigger("uiComposeTweet");
		$(".js-dm-button").click();
	});

	let minimise, maximise, closeButton;

	if (html.hasClass("mtd-js-app")) {
		if ($(".windowcontrols").length <= 0) {
			minimise = make("button")
			.addClass("windowcontrol min")
			.html("&#xE15B")

			maximise = make("button")
			.addClass("windowcontrol max")
			.html("&#xE3C6")

			if (html.hasClass("mtd-maximized")) {
				maximise.html("&#xE3E0")
			}

			closeButton = make("button")
			.addClass("windowcontrol close")
			.html("&#xE5CD")

			let windowcontrols = make("div")
			.addClass("windowcontrols")
			.append(minimise)
			.append(maximise)
			.append(closeButton);

			body.append(windowcontrols,
				make("div").addClass("mtd-app-drag-handle")
			);
		} else {
			minimise = $(".windowcontrol.min");
			maximise = $(".windowcontrol.max");
			closeButton = $(".windowcontrol.close");

			if (html.hasClass("mtd-maximized")) {
				maximise.html("&#xE3E0")
			}
		}

		minimise.click((data,handler) => {
			ipcRenderer.send("minimize");
		});

		maximise.click((data,handler) => {
			ipcRenderer.send("maximizeButton");
		});

		closeButton.click(() => {
			window.close();
		});

	}

	ipcRenderer.on("context-menu", (event, p) => {
		const electron = require("electron")
		let theMenu = buildContextMenu(p);
		let menu = electron.remote.menu;
		let Menu = electron.remote.Menu;

		if (useNativeContextMenus || useSafeMode) {
			Menu.buildFromTemplate(theMenu).popup();
			return;
		} else {
			if (exists(theMenu))
				body.append(theMenu);
		}

	})

	ipcRenderer.on("failedOpenUrl", (event, p) => {
		new UIAlert({
			title:I18n("Failed to open link in browser"),
			message:I18n("ModernDeck failed to open a link you clicked in the default browser.\n\n(Sometimes, this can be caused if you have the Twitter for Windows app installed)"),
			buttonText:I18n("OK")
		})
	})

	const updateOnlineStatus = () => {

		if (!navigator.onLine) {
			// notifyOffline();
		} else {
			dismissOfflineNotification();
		}

	}

	window.addEventListener("online", updateOnlineStatus);
	window.addEventListener("offline", updateOnlineStatus);

	updateOnlineStatus();
}
<commit_msg>Update AppController.js<commit_after>/*
	AppController.js
	Copyright (c) 2014-2020 dangered wolf, et al
	Released under the MIT licence
*/

import { make, exists, getIpc } from "./Utils.js";
import { UIAlert } from "./UIAlert.js";
import { UIUpdateNotify } from "./UIUpdateNotify.js";
import { AutoUpdateController } from "./AutoUpdateController.js";
import { openSettings } from "./UISettings.js";
import { buildContextMenu } from "./UIContextMenu.js";
import { parseActions, loadPreferences } from "./PrefHandler.js";
import { parseConfig } from "./EnterpriseConfigParser.js";
import { I18n } from "./I18n.js";

let offlineNotification;

/*
	Notifies users of an app update
*/

function notifyUpdate() {
	if (isDev || enterpriseConfig.disableUpdateNotification) {
		return;
	}
	UIUpdateNotify();
}

/*
	Create offline notification (probably because we're offline)
*/

function notifyOffline() {

	if (exists(offlineNotification)) {
		return;
	}

	let notifRoot = mR.findFunction("showErrorNotification")[0].showNotification({title:I18n("Internet Disconnected"),timeoutDelayMs:9999999999});
	let notifId = notifRoot._id;
	offlineNotification = $("li.Notification[data-id=\""+notifId+"\"]");
	let notifContent = $("li.Notification[data-id=\""+notifId+"\"] .Notification-content");
	let notifIcon = $("li.Notification[data-id=\""+notifId+"\"] .Notification-icon .Icon");

	if (offlineNotification.length > 0) {
		notifIcon.removeClass("Icon--notifications").addClass("mtd-icon-disconnected");

		notifContent.append(
			make("p").attr("style","max-width:initial!important").html(I18n("We detected that you are disconnected from the internet. Many actions are unavailable without an internet connection."))
		)
	}
}

/*
	Dismiss offline notification (probably because we're online again)
*/

function dismissOfflineNotification() {
	if (!exists(window.offlineNotification)) {return;}
	mR.findFunction("showErrorNotification")[0].removeNotification({notification:offlineNotification});
}

/*
	mtdAppFunctions() consists of functions to help interface
	from here (the renderer process) to the main process
*/

export function mtdAppFunctions() {

	if (typeof require === "undefined") {return;}

	const { remote, ipcRenderer } = require("electron");

	const Store = require("electron-store");
	store = new Store({name:"mtdsettings"});

	// Enable high contrast if system is set to high contrast

	$(document).on("uiDrawerHideDrawer",(e) => {
		getIpc().send("drawerClose");
	});

	$(document).on("uiDrawerActive",(e) => {
		if (!$(".application").hasClass("hide-detail-view-inline"))
			getIpc().send("drawerOpen");
	});

	ipcRenderer.on("enterpriseConfig", (e, config) => {
		window.enterpriseConfig = config;
		parseConfig(config);
	});

	ipcRenderer.on("inverted-color-scheme-changed", (e, enabled) => {
		if (enabled && getPref("mtd_highcontrast") !== true) {
			try {
				settingsData.accessibility.options.highcont.activate.func();
			} catch(e){}
		}
	});

	ipcRenderer.on("color-scheme-changed", (e, theme) => {
		parseActions(settingsData.themes.options.coretheme.activate, theme);

	});

	ipcRenderer.on("disable-high-contrast", (e) => {
		console.info("DISABLING HIGH CONTRAST ");
		try {
			settingsData.accessibility.options.highcont.deactivate.func();
		} catch(e){}
	});

	ipcRenderer.on("aboutMenu", (e,args) => {
		if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0 && $("#settings-modal").attr("style") === "display: block;"){
			$(".mtd-settings-tab[data-action=\"about\"]").click();
		} else {
			openSettings();
			if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0){
				$(".mtd-settings-tab[data-action=\"about\"]").click();
			}
		}
	});

	ipcRenderer.on("checkForUpdatesMenu", (e,args) => {
		if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0 && $("#settings-modal").attr("style") === "display: block;"){
			$(".mtd-settings-tab[data-action=\"about\"]").click();
		} else {
			openSettings();
			if ($(".mtd-settings-tab[data-action=\"about\"]").length > 0){
				$(".mtd-settings-tab[data-action=\"about\"]").click();
			}
		}

		if (!AutoUpdateController.isCheckingForUpdates && window.enterpriseConfig.updatePolicy !== "disabled") {
			ipcRenderer.send("checkForUpdates");
		}
	});

	ipcRenderer.on("update-downloaded", (e,args) => {
		if ($("#settings-modal[style='display: block;']>.mtd-settings-panel").length <= 0 && !html.hasClass("mtd-winstore") && !html.hasClass("mtd-macappstore")) {
			notifyUpdate()
		}
	});

	ipcRenderer.on("openSettings", (e,args) => {
		openSettings();
	});

	ipcRenderer.on("accountsMan", (e,args) => {
		$(".js-show-drawer.js-header-action").click();
	});

	ipcRenderer.on("sendFeedback", (e,args) => {
		window.open("https://github.com/dangeredwolf/ModernDeck/issues");
	});

	ipcRenderer.on("msgModernDeck", (e,args) => {
		$(document).trigger("uiComposeTweet", {
			type: "message",
			messageRecipients: [{
				screenName: "ModernDeck"
			}]
		})
	});

	ipcRenderer.on("newTweet", (e,args) => {
		mtdPrepareWindows();
		$(document).trigger("uiComposeTweet");
	});

	ipcRenderer.on("newDM", (e,args) => {
		mtdPrepareWindows();
		$(document).trigger("uiComposeTweet");
		$(".js-dm-button").click();
	});

	let minimise, maximise, closeButton;

	if (html.hasClass("mtd-js-app")) {
		if ($(".windowcontrols").length <= 0) {
			minimise = make("button")
			.addClass("windowcontrol min")
			.html("&#xE15B")

			maximise = make("button")
			.addClass("windowcontrol max")
			.html("&#xE3C6")

			if (html.hasClass("mtd-maximized")) {
				maximise.html("&#xE3E0")
			}

			closeButton = make("button")
			.addClass("windowcontrol close")
			.html("&#xE5CD")

			let windowcontrols = make("div")
			.addClass("windowcontrols")
			.append(minimise)
			.append(maximise)
			.append(closeButton);

			body.append(windowcontrols,
				make("div").addClass("mtd-app-drag-handle")
			);
		} else {
			minimise = $(".windowcontrol.min");
			maximise = $(".windowcontrol.max");
			closeButton = $(".windowcontrol.close");

			if (html.hasClass("mtd-maximized")) {
				maximise.html("&#xE3E0")
			}
		}

		minimise.click((data,handler) => {
			ipcRenderer.send("minimize");
		});

		maximise.click((data,handler) => {
			ipcRenderer.send("maximizeButton");
		});

		closeButton.click(() => {
			window.close();
		});

	}

	ipcRenderer.on("context-menu", (event, p) => {
		const electron = require("electron")
		let theMenu = buildContextMenu(p);
		let menu = electron.remote.menu;
		let Menu = electron.remote.Menu;

		if (useNativeContextMenus || useSafeMode) {
			Menu.buildFromTemplate(theMenu).popup();
			return;
		} else {
			if (exists(theMenu))
				body.append(theMenu);
		}

	})

	ipcRenderer.on("failedOpenUrl", (event, p) => {
		new UIAlert({
			title:I18n("Failed to open link in browser"),
			message:I18n("ModernDeck failed to open a link you clicked in the default browser.\n\n(Sometimes, this can be caused if you have the Twitter for Windows app installed)"),
			buttonText:I18n("OK")
		})
	})

	const updateOnlineStatus = () => {

		if (!navigator.onLine) {
			// notifyOffline();
		} else {
			dismissOfflineNotification();
		}

	}

	window.addEventListener("online", updateOnlineStatus);
	window.addEventListener("offline", updateOnlineStatus);

	updateOnlineStatus();
}
<|endoftext|>


<commit_before>import escodegen from 'escodegen';

function literal(val, raw) {
    let node = {type: 'Literal', value: val};
    if (raw) {
        node.raw = raw;
    }
    return node;
}

function id(name) {
    return {type: 'Identifier', name: name};
}

function block(body) {
    return {type: 'BlockStatement', body: body};
}

function statement(type, node) {
    return {type: type + 'Statement', argument: node};
}

function argsOf(node, $convert=true) {
    let args = node.slice(Array.isArray(node[1]) ? 1 : 2);
    return $convert ? args.map(convert) : args;
}

function fun(name, node) {
    let body = node.slice(-1)[0];
    body = body[0] == 'do' ? argsOf(body) : [convert(body)];
    body[body.length - 1] = statement('Return', body[body.length - 1]);
    return {
        type: 'Function' + (name ? 'Declaration' : 'Expression'),
        name: name && convert(name),
        params: node.slice(2, -1).map(convert),
        body: block(body)
    };
}

function member(node, computed=false) {
    let [obj, prop] = argsOf(node);
    return {
        type: 'MemberExpression',
        object: obj,
        property: prop,
        computed: computed
    };
}

function call(callee, args) {
    return {type: 'CallExpression', callee: callee, arguments: args};
}

function object(node) {
    return {
        type: 'ObjectExpression',
        properties: argsOf(node, false).map(n => {
            let [k, v] = argsOf(n);
            return {
                type: 'Property',
                key: k,
                value: v,
                kind: 'init'
            };
        })
    };
}

function variable(id, init) {
    return {
        type: 'VariableDeclaration',
        declarations: [{
            type: 'VariableDeclarator',
            id: id,
            init: init
        }],
        kind: 'let'
    };
}

function expression(type) {
    return (n, op) => {
        let [left, right] = argsOf(n);
        return {
            type: type,
            operator: op || n[0],
            left: left,
            right: right
        };
    };
}

let assignment = expression('AssignmentExpression');
let binary = expression('BinaryExpression');

let nodes = {
    boolean: n => literal(null),
    name: n => id(n[2]),
    number: n => literal(parseFloat(n[2])),
    string: n => literal(null, {
          content: n[2],
          precedence: escodegen.Precedence.Primary
    }),
    regex: n => literal(RegExp.apply(null, argsOf(n, false))),
    function: n => fun(null, n),
    return: n => statement('Return', convert(n[2])),
    throw: n => statement('Throw', convert(n[2])),
    '?': n => {
        let [test, con, alt] = argsOf(n);
        let statements = [con, alt].filter(n => n && n.type.endsWith('Statement')).length > 0;
        return {
            type: statements ? 'IfStatement' :  'ConditionalExpression',
            test: test,
            consequent: con,
            alternate: alt || (statements ? null : literal(null))
        }
    },
    for: n => {
        let body = n.slice(-1)[0];
        body = body[0] == 'do' ? argsOf(body) : [convert(body)];
        return {
            type: 'WhileStatement',
            test: convert(n[2]),
            body: block(body.map($n => $n.type.endsWith('Expression')
                ? {type: 'ExpressionStatement', expression: $n} : $n
            ))
        };
    },
    '|': n => {
        let [left, right] = n.args.map(convert);
        return {
            type: 'LogicalExpression',
            operator: n.node,
            left: left,
            right: right
        }
    },
    at: n => member(n, true),
    import: n => {
        return {
            type: 'VariableDeclaration',
            declarations: n.args.map($n => {
                let [left, right] = $n.args.map(convert);
                return variable(left, call(id('require'), [right]));
            }),
            kind: 'let'
        };
    },
    '+': binary,
    '-': binary,
    '==': n => binary(n, '==='),
    '!=': n => binary(n, '!=='),
    object: n => {
        let args = argsOf(n, false);
        if (args.length == 1) {
            let arg = args[0];
            return Array.isArray(arg) ? arg : convert(arg);
        }
        return object(n);
    },
    Array: n => ({type: 'ArrayExpression', elements: argsOf(n)}),
    HashMap: n => call(id('Immutable.HashMap'), [object(n)]),
    OrderedMap: n => call(id('Immutable.OrderedMap'), [object(n)]),
    '.': n => member(n),
    '=': n => variable.apply(null, argsOf(n)),
    ':=': n => assignment(n, '='),
    '+=': assignment,
    ':': n => {
        return {type: 'ExportDefaultDeclaration', declaration: fun.apply(null, argsOf(n[3], false))};
    }
}

function convert(node) {
    let head = node[0];
    let parser = nodes[head] || nodes[head[2]];
    return parser ? parser(node) : call(
        Array.isArray(head) ? convert(head) : id(head),
        argsOf(node)
    );
}

export default function compile(ast) {
    return escodegen.generate({
        type: 'Program',
        body: [{
            type: 'ImportDeclaration',
            specifiers: [{type: 'ImportDefaultSpecifier', id: id('Immutable') }],
            source: literal('immutable')
        }].concat(ast.map(convert))
    }, {verbatim: 'raw'});
}
<commit_msg>lifted vars<commit_after>import escodegen from 'escodegen';

function literal(val, raw) {
    let node = {type: 'Literal', value: val};
    if (raw) {
        node.raw = raw;
    }
    return node;
}

function id(name) {
    return {type: 'Identifier', name: name};
}

function block(body) {
    return {type: 'BlockStatement', body: body};
}

function statement(type, node) {
    return {type: type + 'Statement', argument: node};
}

function argsOf(node, $convert=true) {
    let args = node.slice(Array.isArray(node[1]) ? 1 : 2);
    return $convert ? args.map(convert) : args;
}

function fun(name, node) {
    let body = node.slice(-1)[0];
    body = body[0] == 'do' ? argsOf(body) : [convert(body)];
    body[body.length - 1] = statement('Return', body[body.length - 1]);
    return {
        type: 'Function' + (name ? 'Declaration' : 'Expression'),
        name: name && convert(name),
        params: node.slice(2, -1).map(convert),
        body: block(body)
    };
}

function member(node, computed=false) {
    let [obj, prop] = argsOf(node);
    return {
        type: 'MemberExpression',
        object: obj,
        property: prop,
        computed: computed
    };
}

function call(callee, args) {
    return {type: 'CallExpression', callee: callee, arguments: args};
}

function object(node) {
    return {
        type: 'ObjectExpression',
        properties: argsOf(node, false).map(n => {
            let [k, v] = argsOf(n);
            return {
                type: 'Property',
                key: k,
                value: v,
                kind: 'init'
            };
        })
    };
}

function variable(id, init) {
    return {
        type: 'VariableDeclaration',
        declarations: [{
            type: 'VariableDeclarator',
            id: id,
            init: init
        }],
        kind: 'let'
    };
}

function expression(type) {
    return (n, op) => {
        let [left, right] = argsOf(n);
        return {
            type: type,
            operator: op || n[0],
            left: left,
            right: right
        };
    };
}

let vars = [];
function lift(node, block=false) {
    if (Array.isArray(node)) {
        return node.map(lift);
    } else if (node && typeof node == 'object' && !(node instanceof RegExp)) {
        if (!block && node.type == 'VariableDeclaration') {
            vars.push(node);
            return node.declarations[0].id;
        }
        Object.getOwnPropertyNames(node).forEach(n => {
            node[n] = lift(node[n]);
        });
    }
    return node;
}

let assignment = expression('AssignmentExpression');
let binary = expression('BinaryExpression');

let nodes = {
    boolean: n => literal(null),
    name: n => id(n[2]),
    number: n => literal(parseFloat(n[2])),
    string: n => literal(null, {
          content: n[2],
          precedence: escodegen.Precedence.Primary
    }),
    regex: n => literal(RegExp.apply(null, argsOf(n, false))),
    function: n => fun(null, n),
    return: n => statement('Return', convert(n[2])),
    throw: n => statement('Throw', convert(n[2])),
    '?': n => {
        let [test, con, alt] = argsOf(n);
        let statement = [con, alt].filter(n => n && n.type.endsWith('Statement')).length > 0;
        return {
            type: statement ? 'IfStatement' :  'ConditionalExpression',
            test: test,
            consequent: con,
            alternate: alt || (statement ? null : literal(null))
        }
    },
    for: n => {
        let body = n.slice(-1)[0], $body = [];
        body = body[0] == 'do' ? argsOf(body) : [convert(body)];
        for (let node of body) {
            node = lift(node, true);
            $body = $body.concat(vars);
            $body.push(node.type.endsWith('Expression') ? {type: 'ExpressionStatement', expression: node} : node);
            vars = [];
        }
        return {
            type: 'WhileStatement',
            test: convert(n[2]),
            body: block($body)
        };
    },
    '|': n => {
        let [left, right] = n.args.map(convert);
        return {
            type: 'LogicalExpression',
            operator: n.node,
            left: left,
            right: right
        }
    },
    at: n => member(n, true),
    import: n => {
        return {
            type: 'VariableDeclaration',
            declarations: n.args.map($n => {
                let [left, right] = $n.args.map(convert);
                return variable(left, call(id('require'), [right]));
            }),
            kind: 'let'
        };
    },
    '+': binary,
    '-': binary,
    '==': n => binary(n, '==='),
    '!=': n => binary(n, '!=='),
    object: n => {
        let args = argsOf(n, false);
        if (args.length == 1) {
            let arg = args[0];
            return Array.isArray(arg) ? arg : convert(arg);
        }
        return object(n);
    },
    Array: n => ({type: 'ArrayExpression', elements: argsOf(n)}),
    HashMap: n => call(id('Immutable.HashMap'), [object(n)]),
    OrderedMap: n => call(id('Immutable.OrderedMap'), [object(n)]),
    '.': n => member(n),
    '=': n => variable.apply(null, argsOf(n)),
    ':=': n => assignment(n, '='),
    '+=': assignment,
    ':': n => {
        return {type: 'ExportDefaultDeclaration', declaration: fun.apply(null, argsOf(n[3], false))};
    }
}

function convert(node) {
    let head = node[0];
    let parser = nodes[head] || nodes[head[2]];
    return parser ? parser(node) : call(
        Array.isArray(head) ? convert(head) : id(head),
        argsOf(node)
    );
}

export default function compile(ast) {
    return escodegen.generate({
        type: 'Program',
        body: [{
            type: 'ImportDeclaration',
            specifiers: [{type: 'ImportDefaultSpecifier', id: id('Immutable') }],
            source: literal('immutable')
        }].concat(ast.map(convert))
    }, {verbatim: 'raw'});
}
<|endoftext|>


<commit_before>define(['pex/geom'], function(geom) {
  var Vec2 = geom.Vec2;
  var Vec3 = geom.Vec4;
  var Mat4 = geom.Mat4;

  function Camera(fov, aspectRatio, near, far, position, target, up) {

    this.fov = fov || 60;
    this.aspectRatio = aspectRatio || 4/3;
    this.near = near || 0.1;
    this.far = far || 100;
    this.position = position || Vec3.fromValues(0, 0, 5);

    this.target = target || Vec3.fromValues(0, 0, 0);
    this.up = up || Vec3.fromValues(0, 1, 0);
    this.projectionMatrix = Mat4.create();
    this.viewMatrix = Mat4.create();
    this.updateMatrices();
  }

  Camera.prototype.setPosition = function(position) {
    this.position = position;
    this.updateMatrices();
  }

  Camera.prototype.getPosition = function() {
    return this.position;
  }

  Camera.prototype.setTarget = function(target) {
    this.target = target;
    this.updateMatrices();
  }

  Camera.prototype.getTarget = function() {
    return this.target;
  }

  Camera.prototype.setUp = function(up) {
    this.up = up;
    this.updateMatrices();
  }

  Camera.prototype.getUp = function() {
    return this.up;
  }

  Camera.prototype.lookAt = function(target, eyePosition, up) {
    if (target) this.target = target;
    if (eyePosition) this.position = eyePosition;
    if (up) this.up = up;
    this.updateMatrices();
  }

  Camera.prototype.setNear = function(near) {
    this.near = near;
    this.updateMatrices();
  }

  Camera.prototype.getNear = function() {
    return this.near;
  }

  Camera.prototype.setFar = function(far) {
    this.far = far;
    this.updateMatrices();
  }

  Camera.prototype.getFar = function() {
    return this.far;
  }

  Camera.prototype.setFov = function(fov) {
    this.fov = fov;
    this.updateMatrices();
  }

  Camera.prototype.getFov = function() {
    return this.fov;
  }

  Camera.prototype.setAspectRatio = function(ratio) {
    this.aspectRatio = ratio;
    this.updateMatrices();
  }

  Camera.prototype.getAspectRatio = function() {
    return this.aspectRatio;
  }

  Camera.prototype.getViewMatrix = function() {
    return this.viewMatrix;
  }

  Camera.prototype.getProjectionMatrix = function() {
    return this.projectionMatrix;
  }

  Camera.prototype.updateMatrices = function() {
    Mat4.perspective(this.projectionMatrix, this.fov / 180 * Math.PI, this.aspectRatio, this.near, this.far);
    Mat4.lookAt(this.viewMatrix, this.position, this.target, this.up);
  }

  return Camera;
});<commit_msg>Added 3d to 2d camera projection<commit_after>define(['pex/geom'], function(geom) {
  var Vec2 = geom.Vec2;
  var Vec3 = geom.Vec3;
  var Vec4 = geom.Vec4;
  var Mat4 = geom.Mat4;

  function Camera(fov, aspectRatio, near, far, position, target, up) {

    this.fov = fov || 60;
    this.aspectRatio = aspectRatio || 4/3;
    this.near = near || 0.1;
    this.far = far || 100;
    this.position = position || Vec3.fromValues(0, 0, 5);

    this.target = target || Vec3.fromValues(0, 0, 0);
    this.up = up || Vec3.fromValues(0, 1, 0);
    this.projectionMatrix = Mat4.create();
    this.viewMatrix = Mat4.create();
    this.updateMatrices();
  }

  Camera.prototype.setPosition = function(position) {
    this.position = position;
    this.updateMatrices();
  }

  Camera.prototype.getPosition = function() {
    return this.position;
  }

  Camera.prototype.setTarget = function(target) {
    this.target = target;
    this.updateMatrices();
  }

  Camera.prototype.getTarget = function() {
    return this.target;
  }

  Camera.prototype.setUp = function(up) {
    this.up = up;
    this.updateMatrices();
  }

  Camera.prototype.getUp = function() {
    return this.up;
  }

  Camera.prototype.lookAt = function(target, eyePosition, up) {
    if (target) this.target = target;
    if (eyePosition) this.position = eyePosition;
    if (up) this.up = up;
    this.updateMatrices();
  }

  Camera.prototype.setNear = function(near) {
    this.near = near;
    this.updateMatrices();
  }

  Camera.prototype.getNear = function() {
    return this.near;
  }

  Camera.prototype.setFar = function(far) {
    this.far = far;
    this.updateMatrices();
  }

  Camera.prototype.getFar = function() {
    return this.far;
  }

  Camera.prototype.setFov = function(fov) {
    this.fov = fov;
    this.updateMatrices();
  }

  Camera.prototype.getFov = function() {
    return this.fov;
  }

  Camera.prototype.setAspectRatio = function(ratio) {
    this.aspectRatio = ratio;
    this.updateMatrices();
  }

  Camera.prototype.getAspectRatio = function() {
    return this.aspectRatio;
  }

  Camera.prototype.getViewMatrix = function() {
    return this.viewMatrix;
  }

  Camera.prototype.getProjectionMatrix = function() {
    return this.projectionMatrix;
  }

  Camera.prototype.updateMatrices = function() {
    Mat4.perspective(this.projectionMatrix, this.fov / 180 * Math.PI, this.aspectRatio, this.near, this.far);
    Mat4.lookAt(this.viewMatrix, this.position, this.target, this.up);
  }

  var tmpPoint = Vec4.create();
  var projected = Vec4.create();

  Camera.prototype.getScreenPos = function(out, point, windowWidth, windowHeight) {
    Vec4.set(tmpPoint, point[0], point[1], point[2], 1.0);

    Vec4.transformMat4(projected, tmpPoint, this.viewMatrix);
    Vec4.transformMat4(projected, projected, this.projectionMatrix);
    Vec2.set(out, projected[0], projected[1]);

    out[0] /= projected[3];
    out[1] /= projected[3];
    out[0] = out[0] * 0.5 + 0.5;
    out[1] = out[1] * 0.5 + 0.5;
    out[0] *= windowWidth;
    out[1] *= windowHeight;
  }

  return Camera;
});<|endoftext|>


<commit_before>import { reduce, isFinite, isString } from "lodash"

class ValidatorAssertions {
  invalid(fields, error)
  {
    return {
      valid: false,
      fields,
      error
    }
  }

  isNumber(value)
  {
    return isFinite(value)
  }

  isString(value)
  {
    return isString(value) && value !== ""
  }

  hasValue(value)
  {
    if (value === undefined)
      return false

    if (value === null)
      return false

    if (typeof (value) === "number" && isNaN(value))
      return false

    return true
  }
}

const validatorAssertions = new ValidatorAssertions()

export default class BaseValidator {

  constructor(module = null)
  {
    this._ruleMap = []
    this.module = module
  }

  injectStore(store)
  {
    this._store = store
  }

  /*
   * Add rule to validator. name {string} is the rule's name to find it in debugging mode.
   * validatorFunction {function(state)} is the validator function given global state as
   * first parameter.
   *
   * The return value should be either null if the rule don't apply or everything is valid.
   * Otherwise it should call this.valid(fields, error) as return value where fields is
   * an array of strings with the fields validated and error is a string describing technical
   * what was validated and failed.
   *
   * The idea behind this technical error string is that it should be a key in i18n to translate
   * to a good user readable error message.
   *
   * The validatorFunction is called in context of ValidatorAssertions, so every function in there
   * is callable via this.functionName().
   */
  rule(name, validatorFunction)
  {
    this._ruleMap.push({
      name,
      validatorFunction
    })
  }

  isValid()
  {
    const state = this._store.state

    return reduce(
      this._ruleMap.map(
        (rule) =>
        {
          const valid = rule.validatorFunction.call(validatorAssertions, state)

          if (valid && valid.valid === false)
            return {
              name: rule.name,
              fields: valid.fields,
              error: valid.error
            }

          return true
        }
      ),
      (all, thisRule) =>
      {
        if (thisRule === true)
          return all

        if (all === true)
          return [ thisRule ]

        return all.concat(thisRule)
      }
    )
  }

}
<commit_msg>Fix initial value for reducing validator results<commit_after>import { reduce, isFinite, isString } from "lodash"

class ValidatorAssertions {
  invalid(fields, error)
  {
    return {
      valid: false,
      fields,
      error
    }
  }

  isNumber(value)
  {
    return isFinite(value)
  }

  isString(value)
  {
    return isString(value) && value !== ""
  }

  hasValue(value)
  {
    if (value === undefined)
      return false

    if (value === null)
      return false

    if (typeof (value) === "number" && isNaN(value))
      return false

    return true
  }
}

const validatorAssertions = new ValidatorAssertions()

export default class BaseValidator {

  constructor(module = null)
  {
    this._ruleMap = []
    this.module = module
  }

  injectStore(store)
  {
    this._store = store
  }

  /*
   * Add rule to validator. name {string} is the rule's name to find it in debugging mode.
   * validatorFunction {function(state)} is the validator function given global state as
   * first parameter.
   *
   * The return value should be either null if the rule don't apply or everything is valid.
   * Otherwise it should call this.valid(fields, error) as return value where fields is
   * an array of strings with the fields validated and error is a string describing technical
   * what was validated and failed.
   *
   * The idea behind this technical error string is that it should be a key in i18n to translate
   * to a good user readable error message.
   *
   * The validatorFunction is called in context of ValidatorAssertions, so every function in there
   * is callable via this.functionName().
   */
  rule(name, validatorFunction)
  {
    this._ruleMap.push({
      name,
      validatorFunction
    })
  }

  isValid()
  {
    const state = this._store.state

    return reduce(
      this._ruleMap.map(
        (rule) =>
        {
          const valid = rule.validatorFunction.call(validatorAssertions, state)

          if (valid && valid.valid === false)
            return {
              name: rule.name,
              fields: valid.fields,
              error: valid.error
            }

          return true
        }
      ),
      (all, thisRule) =>
      {
        if (thisRule === true)
          return all

        if (all === true)
          return [ thisRule ]

        return all.concat(thisRule)
      },
      []
    )
  }

}
<|endoftext|>


<commit_before>/* @flow */
/**
 * @jsx React.DOM

 */
"use strict";

var shallowCloneObject            = require('./shallowCloneObject');
var isValidElement = require('react').isValidElement;
var sameColumn = require('./ColumnComparer');
var ColumnUtils = require('./ColumnUtils');

type ColumnMetricsType = {
    columns: Array<Column>;
    totalWidth: number;
    minColumnWidth: number;
};

type Column = {
  key: string;
  left: number;
  width: number;
};

/**
 * Update column metrics calculation.
 *
 * @param {ColumnMetricsType} metrics
 */
function recalculate(metrics: ColumnMetricsType): ColumnMetricsType {
    // compute width for columns which specify width
    var columns = setColumnWidths(metrics.columns, metrics.totalWidth);

    var unallocatedWidth = columns.filter(c => c.width).reduce((w, column) => {
      return w - column.width;
    }, metrics.totalWidth);

    var width = columns.filter(c => c.width).reduce((w, column) => {
      return w + column.width;
    }, 0);

    // compute width for columns which doesn't specify width
    columns = setDefferedColumnWidths(columns, unallocatedWidth, metrics.minColumnWidth);

    // compute left offset
    columns = setColumnOffsets(columns);

    return {
      columns,
      width,
      totalWidth: metrics.totalWidth,
      minColumnWidth: metrics.minColumnWidth
    };
}

function setColumnOffsets(columns) {
  var left = 0;
  return columns.map(column => {
    column.left = left;
    left += column.width;
    return column;
  });
}

function setColumnWidths(columns, totalWidth) {
  return columns.map(column => {
    var colInfo = Object.assign({}, column);
    if(column.width){
      if (/^([0-9]+)%$/.exec(column.width.toString())) {
        colInfo.width = Math.floor(
          column.width / 100 * totalWidth);
      }
    }
    return colInfo;
  });
}

function setDefferedColumnWidths(columns, unallocatedWidth, minColumnWidth) {
  var defferedColumns = columns.filter(c => !c.width);
  return columns.map((column, i, arr) => {
    if(!column.width){
      if (unallocatedWidth <= 0) {
        column.width = minColumnWidth;
      } else {
        column.width = Math.floor(unallocatedWidth / (ColumnUtils.getSize(defferedColumns)));
      }
    }
    return column;
  });
}

/**
 * Update column metrics calculation by resizing a column.
 *
 * @param {ColumnMetricsType} metrics
 * @param {Column} column
 * @param {number} width
 */
function resizeColumn(metrics: ColumnMetricsType, index: number, width: number): ColumnMetricsType {
  var column = metrics.columns[index];
  metrics = shallowCloneObject(metrics);
  metrics.columns = metrics.columns.slice(0);

  var updatedColumn = shallowCloneObject(column);
  updatedColumn.width = Math.max(width, metrics.minColumnWidth);

  metrics.columns.splice(index, 1, updatedColumn);

  return recalculate(metrics);
}

function areColumnsImmutable(prevColumns: Array<Column>, nextColumns: Array<Column>) {
  return (typeof Immutable !== 'undefined' && (prevColumns instanceof Immutable.List) && (nextColumns instanceof Immutable.List));
}

function compareEachColumn(prevColumns: Array<Column>, nextColumns: Array<Column>, sameColumn: (a: Column, b: Column) => boolean) {
  var i, len, column;
  var prevColumnsByKey: { [key:string]: Column } = {};
  var nextColumnsByKey: { [key:string]: Column } = {};

  if(ColumnUtils.getSize(prevColumns) !== ColumnUtils.getSize(nextColumns)){
    return false;
  }

  for (i = 0, len = ColumnUtils.getSize(prevColumns); i < len; i++) {
    column = prevColumns[i];
    prevColumnsByKey[column.key] = column;
  }

  for (i = 0, len = ColumnUtils.getSize(nextColumns); i < len; i++) {
    column = nextColumns[i];
    nextColumnsByKey[column.key] = column;
    var prevColumn = prevColumnsByKey[column.key];
    if (prevColumn === undefined || !sameColumn(prevColumn, column)) {
      return false;
    }
  }

  for (i = 0, len = ColumnUtils.getSize(prevColumns); i < len; i++) {
    column = prevColumns[i];
    var nextColumn = nextColumnsByKey[column.key];
    if (nextColumn === undefined) {
      return false;
    }
  }
  return true;
}

function sameColumns(prevColumns: Array<Column>, nextColumns: Array<Column>, sameColumn: (a: Column, b: Column) => boolean): boolean {
  if(areColumnsImmutable(prevColumns, nextColumns)) {
    return prevColumns === nextColumns;
  }else{
    return compareEachColumn(prevColumns, nextColumns, sameColumn);
  }
}

module.exports = { recalculate, resizeColumn, sameColumn, sameColumns };
<commit_msg>use ColumnUtils.getColumn before performing updates<commit_after>/* @flow */
/**
 * @jsx React.DOM

 */
"use strict";

var shallowCloneObject            = require('./shallowCloneObject');
var isValidElement = require('react').isValidElement;
var sameColumn = require('./ColumnComparer');
var ColumnUtils = require('./ColumnUtils');

type ColumnMetricsType = {
    columns: Array<Column>;
    totalWidth: number;
    minColumnWidth: number;
};

type Column = {
  key: string;
  left: number;
  width: number;
};

/**
 * Update column metrics calculation.
 *
 * @param {ColumnMetricsType} metrics
 */
function recalculate(metrics: ColumnMetricsType): ColumnMetricsType {
    // compute width for columns which specify width
    var columns = setColumnWidths(metrics.columns, metrics.totalWidth);

    var unallocatedWidth = columns.filter(c => c.width).reduce((w, column) => {
      return w - column.width;
    }, metrics.totalWidth);

    var width = columns.filter(c => c.width).reduce((w, column) => {
      return w + column.width;
    }, 0);

    // compute width for columns which doesn't specify width
    columns = setDefferedColumnWidths(columns, unallocatedWidth, metrics.minColumnWidth);

    // compute left offset
    columns = setColumnOffsets(columns);

    return {
      columns,
      width,
      totalWidth: metrics.totalWidth,
      minColumnWidth: metrics.minColumnWidth
    };
}

function setColumnOffsets(columns) {
  var left = 0;
  return columns.map(column => {
    column.left = left;
    left += column.width;
    return column;
  });
}

function setColumnWidths(columns, totalWidth) {
  return columns.map(column => {
    var colInfo = Object.assign({}, column);
    if(column.width){
      if (/^([0-9]+)%$/.exec(column.width.toString())) {
        colInfo.width = Math.floor(
          column.width / 100 * totalWidth);
      }
    }
    return colInfo;
  });
}

function setDefferedColumnWidths(columns, unallocatedWidth, minColumnWidth) {
  var defferedColumns = columns.filter(c => !c.width);
  return columns.map((column, i, arr) => {
    if(!column.width){
      if (unallocatedWidth <= 0) {
        column.width = minColumnWidth;
      } else {
        column.width = Math.floor(unallocatedWidth / (ColumnUtils.getSize(defferedColumns)));
      }
    }
    return column;
  });
}

/**
 * Update column metrics calculation by resizing a column.
 *
 * @param {ColumnMetricsType} metrics
 * @param {Column} column
 * @param {number} width
 */
function resizeColumn(metrics: ColumnMetricsType, index: number, width: number): ColumnMetricsType {
  var column = ColumnUtils.getColumn(metrics.columns, index);
  metrics = shallowCloneObject(metrics);
  metrics.columns = metrics.columns.slice(0);

  var updatedColumn = shallowCloneObject(column);
  updatedColumn.width = Math.max(width, metrics.minColumnWidth);

  metrics.columns.splice(index, 1, updatedColumn);

  return recalculate(metrics);
}

function areColumnsImmutable(prevColumns: Array<Column>, nextColumns: Array<Column>) {
  return (typeof Immutable !== 'undefined' && (prevColumns instanceof Immutable.List) && (nextColumns instanceof Immutable.List));
}

function compareEachColumn(prevColumns: Array<Column>, nextColumns: Array<Column>, sameColumn: (a: Column, b: Column) => boolean) {
  var i, len, column;
  var prevColumnsByKey: { [key:string]: Column } = {};
  var nextColumnsByKey: { [key:string]: Column } = {};

  if(ColumnUtils.getSize(prevColumns) !== ColumnUtils.getSize(nextColumns)){
    return false;
  }

  for (i = 0, len = ColumnUtils.getSize(prevColumns); i < len; i++) {
    column = prevColumns[i];
    prevColumnsByKey[column.key] = column;
  }

  for (i = 0, len = ColumnUtils.getSize(nextColumns); i < len; i++) {
    column = nextColumns[i];
    nextColumnsByKey[column.key] = column;
    var prevColumn = prevColumnsByKey[column.key];
    if (prevColumn === undefined || !sameColumn(prevColumn, column)) {
      return false;
    }
  }

  for (i = 0, len = ColumnUtils.getSize(prevColumns); i < len; i++) {
    column = prevColumns[i];
    var nextColumn = nextColumnsByKey[column.key];
    if (nextColumn === undefined) {
      return false;
    }
  }
  return true;
}

function sameColumns(prevColumns: Array<Column>, nextColumns: Array<Column>, sameColumn: (a: Column, b: Column) => boolean): boolean {
  if(areColumnsImmutable(prevColumns, nextColumns)) {
    return prevColumns === nextColumns;
  }else{
    return compareEachColumn(prevColumns, nextColumns, sameColumn);
  }
}

module.exports = { recalculate, resizeColumn, sameColumn, sameColumns };
<|endoftext|>


<commit_before>'use strict'

const ExecInfo = require('./ExecInfo')
const Promise = require('bluebird')
const _ = require('lodash')
const { execHook, logError, possiblyCallback, resultsTransform } =
        require('./utils')

// Implements command implementation functions binding and wrapping.
class CommandBinder {

  constructor (server, transport, userName) {
    this.server = server
    this.transport = transport
    this.userName = userName
  }

  commandWatcher (id, name) {
    this.server.runningCommands++
    return Promise.resolve().disposer(() => {
      this.server.runningCommands--
      if (this.transport.closed && this.server.runningCommands <= 0) {
        this.server.emit('commandsFinished')
      }
    })
  }

  makeCommand (name, fn) {
    let { validator } = this.server
    let beforeHook = this.server.hooks[`${name}Before`]
    let afterHook = this.server.hooks[`${name}After`]
    return (args, info) => {
      let execInfo = new ExecInfo()
      _.assign(execInfo, { server: this.server, userName: this.userName })
      _.assign(execInfo, info)
      _.assign(execInfo, validator.splitArguments(name, args))
      return Promise.using(
        this.commandWatcher(info.id, name),
        () => validator.checkArguments(name, ...execInfo.args)
          .then(() => {
            if (beforeHook && !execInfo.bypassHooks) {
              return execHook(beforeHook, execInfo)
            } else {
              return Promise.resolve()
            } })
          .then(results => {
            if (results && results.length) { return results }
            return fn(...execInfo.args, execInfo)
              .then(result => { execInfo.results = [result] },
                    error => { execInfo.error = error })
              .then(() => {
                if (afterHook && !execInfo.bypassHooks) {
                  return execHook(afterHook, execInfo)
                } else {
                  return Promise.resolve()
                } })
              .then(results => {
                if (results && results.length) {
                  return results
                } else if (execInfo.error) {
                  return Promise.reject(execInfo.error)
                } else {
                  return execInfo.results
                }
              })
          }))
        .catch(error => logError(error))
    }
  }

  bindDisconnect (id, fn) {
    let server = this.server
    let hook = this.server.hooks.onDisconnect
    this.transport.bindHandler(id, 'disconnect', () => {
      return Promise.using(
        this.commandWatcher(id, 'disconnect'),
        () => fn(id).then(() => execHook(hook, server, id)).catchReturn())
    })
  }

  bindCommand (id, name, fn) {
    let cmd = this.makeCommand(name, fn)
    let useErrorObjects = this.server.useRawErrorObjects
    let info = {id}
    return this.transport.bindHandler(id, name, function () {
      let [args, cb] = possiblyCallback(arguments)
      let ack = resultsTransform(useErrorObjects, cb)
      return cmd(args, info).asCallback(ack, { spread: true })
    })
  }

}

module.exports = CommandBinder
<commit_msg>fix: add disconnection errors logging<commit_after>'use strict'

const ExecInfo = require('./ExecInfo')
const Promise = require('bluebird')
const _ = require('lodash')
const { execHook, logError, possiblyCallback, resultsTransform } =
        require('./utils')

// Implements command functions binding and wrapping.
class CommandBinder {

  constructor (server, transport, userName) {
    this.server = server
    this.transport = transport
    this.userName = userName
  }

  commandWatcher (id, name) {
    this.server.runningCommands++
    return Promise.resolve().disposer(() => {
      this.server.runningCommands--
      if (this.transport.closed && this.server.runningCommands <= 0) {
        this.server.emit('commandsFinished')
      }
    })
  }

  makeCommand (name, fn) {
    let { validator } = this.server
    let beforeHook = this.server.hooks[`${name}Before`]
    let afterHook = this.server.hooks[`${name}After`]
    return (args, info) => {
      let execInfo = new ExecInfo()
      _.assign(execInfo, { server: this.server, userName: this.userName })
      _.assign(execInfo, info)
      _.assign(execInfo, validator.splitArguments(name, args))
      return Promise.using(
        this.commandWatcher(info.id, name),
        () => validator.checkArguments(name, ...execInfo.args)
          .then(() => {
            if (beforeHook && !execInfo.bypassHooks) {
              return execHook(beforeHook, execInfo)
            } else {
              return Promise.resolve()
            } })
          .then(results => {
            if (results && results.length) { return results }
            return fn(...execInfo.args, execInfo)
              .then(result => { execInfo.results = [result] },
                    error => { execInfo.error = error })
              .then(() => {
                if (afterHook && !execInfo.bypassHooks) {
                  return execHook(afterHook, execInfo)
                } else {
                  return Promise.resolve()
                } })
              .then(results => {
                if (results && results.length) {
                  return results
                } else if (execInfo.error) {
                  return Promise.reject(execInfo.error)
                } else {
                  return execInfo.results
                }
              })
          }))
        .catch(error => logError(error))
    }
  }

  bindDisconnect (id, fn) {
    let server = this.server
    let hook = this.server.hooks.onDisconnect
    this.transport.bindHandler(id, 'disconnect', () => {
      return Promise.using(
        this.commandWatcher(id, 'disconnect'),
        () => fn(id)
          .catch(error => logError(error))
          .catchReturn()
          .then(() => execHook(hook, server, id))
          .catch(error => logError(error))
          .catchReturn())
    })
  }

  bindCommand (id, name, fn) {
    let cmd = this.makeCommand(name, fn)
    let useErrorObjects = this.server.useRawErrorObjects
    let info = {id}
    return this.transport.bindHandler(id, name, function () {
      let [args, cb] = possiblyCallback(arguments)
      let ack = resultsTransform(useErrorObjects, cb)
      return cmd(args, info).asCallback(ack, { spread: true })
    })
  }

}

module.exports = CommandBinder
<|endoftext|>