<commit_before>var assert = require('assert'),
	should = require('should'),
	Module = require('../lib/Module'),
	Injector = require('../lib/Injector');

describe('Injector', function() {
	// Constructor tests
	describe('()', function() {
		it('should start if there are no modules', function() {
			new Injector();
		});

		it('should start if there is one module without dependencies', function() {
			var modA = new Module('mod-a');
			new Injector([modA]);
		});

		it('should start if one of module has missing dependencies', function() {
			var modA = new Module('mod-a', ['mod-b']);
			(function(){
				new Injector([modA]);
			}).should.throw('Module "mod-b" could not be found!');
		});

		it('should start if all depedencies are satisfied', function() {
			var modA = new Module('mod-a', []);
			var modB = new Module('mod-b', ['mod-a']);
			new Injector([modA, modB]);
		});

		it('should start if a dependency is registered on the parent injector', function() {
			var modA = new Module('mod-a', ['mod-b']),
				modB = new Module('mod-b'),
				parent = new Injector([modB]);
			new Injector([modA], parent);
		});

		it('should register the injector into itself', function() {
			var injector = new Injector();
			injector.get('$injector').should.be.exactly(injector);
		});
	});

	// Invoke tests
	describe('invoke(fn, self)', function() {
		var expectedConstant = 'check',
			module = new Module('mod').constant('constant', expectedConstant),
			injector = new Injector([module]),
			invoked,
			actualConstant,
			expectedScope = {scoped: true},
			actualScope,
			retVal = {returned: true};

		it('should invoke unannotated functions', function() {
			var func1 = function(constant) {
					invoked = true;
					actualConstant = constant;
					return retVal;
				};
			injector.invoke(func1).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
		});

		it('should invoke annotated functions', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					return retVal;
				};
			func1.$inject = ['constant'];
			injector.invoke(func1).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
		});

		it('should invoke array annotated functions', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					return retVal;
				};
			injector.invoke(['constant', func1]).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
		});

		it('should invoke unannotated functions with self', function() {
			var func1 = function(constant) {
					invoked = true;
					actualConstant = constant;
					actualScope = this;
					return retVal;
				};
			injector.invoke(func1, expectedScope).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
		});

		it('should invoke annotated functions with self', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					actualScope = this;
					return retVal;
				};
			func1.$inject = ['constant'];
			injector.invoke(func1, expectedScope).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
		});

		it('should invoke array annotated functions with self', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					actualScope = this;
					return retVal;
				};
			injector.invoke(['constant', func1], expectedScope).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
		});

		it('should invoke array annotated functions with locals', function() {
			var expectedLocal = 132456798,
				actualLocal,
				func1 = function(param, local) {
					invoked = true;
					actualConstant = param;
					actualScope = this;
					actualLocal = expectedLocal
					return retVal;
				};
			injector.invoke(['constant', 'local1', func1], expectedScope, {local1: expectedLocal}).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
			expectedLocal.should.be.exactly(actualLocal);
		});
	});

	// Instantiate tests
	describe('annotate(fn)', function() {
		var injector = new Injector();

		it('should no annotate if the function is already annotated', function() {
			var fn = function(injected) {};
			fn.$inject = ['test'];
			injector.annotate(fn).should.be.exactly(fn.$inject);
		});

		it('should annotate the function if not already annotated', function() {
			var fn = function(test) {};
			injector.annotate(fn).should.be.eql(['test']);
		});

		it('should annotate the function if using array syntax', function() {
			var fn = function(injected) {};
			injector.annotate(['test', fn]).should.be.eql(['test']);
		});

		it('should not be able to annotate objects', function() {
			var fn = function(injected) {};
			(function(){
				injector.annotate({});
			}).should.throw('Cannot annotate "[object Object]"');
		});
	});

	// Instantiate tests
	describe('instantiate(Type)', function() {
		var TestType1 = function() {
		};
		var TestType2 = function(injected) {
		};
		TestType2.$inject = ['injected'];
		var TestType3 = function(local) {
		};
		var module = new Module().constant('injected', true).type('TestType3', TestType3),
			injector = new Injector([module]);

		it('should be able to instantiate a parameterless class', function() {
			injector.instantiate(TestType1).should.be.an.instanceOf(TestType1);
		});

		it('should be able to instantiate a class with an injecter parameter', function() {
			injector.instantiate(TestType2).should.be.an.instanceOf(TestType2);
		});

		it('should be able to instantiate a class annotated with array syntax', function() {
			injector.instantiate(['injected', TestType1]).should.be.an.instanceOf(TestType1);
		});

		it('should be able to instantiate a class with a local', function() {
			injector.instantiate(TestType3, {local: 'injected!'}).should.be.an.instanceOf(TestType3);
		});

		it('should be able to instantiate a type by its name', function() {
			injector.instantiate('TestType3', {local: 'injected!'}).should.be.an.instanceOf(TestType3);
		});
	});

	// Get tests
	describe('get(name)', function() {
		var TestType1 = function() {
		};
		var TestType2 = function() {
		};
		var TestType3 = function() {
		};
		TestType3.$inject = ['type3'];
		var constant1 = 'test-1-value',
			modA = new Module('mod-a')
				.constant('constant1', constant1)
				.type('type1', TestType1)
				.type('type3', TestType3)
				.factory('factory1', function() {
					return new TestType1();
				}),
			constant2 = 'test-2-value',
			modB = new Module('mod-b')
				.constant('constant2', constant2)
				.type('type2', TestType2)
				.factory('factory2', function() {
					return new TestType2();
				})
				.constant('decoratedConstant', constant1)
				.decorator('decoratedConstant', ['$delegate', 'constant2', function($delegate, constant2) {
					return $delegate + constant2;
				}])
				.type('decoratedType', TestType2)
				.decorator('decoratedType', ['$delegate', function($delegate) {
					$delegate.decorated = true;
					return $delegate;
				}])
				.factory('decoratedFactory', function() {
					return new TestType2();
				})
				.decorator('decoratedFactory', ['$delegate', function($delegate) {
					$delegate.decorated = true;
					return $delegate;
				}])
				.type('nonReturningMonkeyPatcher', TestType2)
				.decorator('nonReturningMonkeyPatcher', ['$delegate', function($delegate) {
					$delegate.monkeyed = true;
				}])
				.type('doubleDecorated', TestType2)
				.decorator('doubleDecorated', ['$delegate', function($delegate) {
					$delegate.first = true;
					return $delegate;
				}])
				.decorator('doubleDecorated', ['$delegate', function($delegate) {
					$delegate.second = true;
					return $delegate;
				}]),
			parent = new Injector([modB]),
			injector = new Injector([modA], parent);

		it('should not resolve undeclared dependencies', function() {
			(function() {
				return injector.get('not-declared');
			}).should.throw('No provider for "not-declared"!');
		});

		it('should resolve declared constants', function() {
			injector.get('constant1').should.be.exactly(constant1);
		});

		it('should resolve declared constants in parent', function() {
			injector.get('constant2').should.be.exactly(constant2);
		});

		it('should resolve declared types', function() {
			injector.get('type1').should.be.an.instanceOf(TestType1);
		});

		it('should resolve declared types in parent', function() {
			injector.get('type2').should.be.an.instanceOf(TestType2);
		});

		it('should resolve declared factories', function() {
			injector.get('factory1').should.be.an.instanceOf(TestType1);
		});

		it('should resolve declared factories in parent', function() {
			injector.get('factory2').should.be.an.instanceOf(TestType2);
		});

		it('should not resolve circular dependencies', function() {
			(function() {
				return injector.get('type3');
			}).should.throw('Can not resolve circular dependency!');
		});

		it('should resolve decorated constants', function() {
			injector.get('decoratedConstant').should.be.eql(constant1 + constant2);
		});

		it('should resolve decorated types', function() {
			injector.get('decoratedType').decorated.should.be.true;
		});

		it('should resolve decorated factories', function() {
			injector.get('decoratedFactory').decorated.should.be.true;
		});

		it('should resolve decorated decorators, yo dawg', function() {
			var t = injector.get('doubleDecorated');
			t.first.should.be.true;
			t.second.should.be.true;
		});

		it('should resolve if the decorator does not return a new value', function() {
			injector.get('nonReturningMonkeyPatcher').monkeyed.should.be.true;
		});
	});

	// Run callback tests
	describe('run callback', function() {
		it('should run all callback', function() {
			var parameterlessRunInvoked = false,
				parameterizedRunInvoked = false,
				arrayAnnotatedRunInvoked = false,
				module = new Module('module')
					.constant('constant', 'yes')
					.run(function() {parameterlessRunInvoked = true;})
					.run(function(constant) {parameterizedRunInvoked = true;})
					.run(['constant', function(injected) {arrayAnnotatedRunInvoked = true;}]),
				injector = new Injector([module]);
			parameterlessRunInvoked.should.be.true;
			parameterizedRunInvoked.should.be.true;
			arrayAnnotatedRunInvoked.should.be.true;
		});
	});

	// Run module load order tests
	describe('load modules in topological order', function() {
		var actualOrder,
			expectedOrder = ['a', 'b', 'c'],
			modA = new Module('a').run(function() {actualOrder.push('a');}),
			modB = new Module('b', ['a']).run(function() {actualOrder.push('b');}),
			modC = new Module('c', ['b']).run(function() {actualOrder.push('c');}),
			modD = new Module('d', ['missing']),
			modCircular = new Module('b', ['c']);

		it('should throw on missing dependency', function() {
			(function(){
				new Injector([modD]);
			}).should.throw('Module "missing" could not be found!');
		});

		it('should throw on circular dependency', function() {
			(function(){
				new Injector([modC, modCircular]);
			}).should.throw('There is a cycle in the graph. It is not possible to derive a topological sort!');
		});

		it('should load in order if in order', function() {
			actualOrder = [];
			new Injector([modA, modB, modC]);

			actualOrder.should.eql(expectedOrder);
		});

		it('should load in order if in reverse order', function() {
			actualOrder = [];
			new Injector([modC, modB, modA]);

			actualOrder.should.eql(expectedOrder);
		});

		it('should load in order if in mixed order', function() {
			actualOrder = [];
			new Injector([modA, modC, modB]);

			actualOrder.should.eql(expectedOrder);
		});
	});
});
<commit_msg>added tests to check overriding if registered on the same key<commit_after>var assert = require('assert'),
	should = require('should'),
	Module = require('../lib/Module'),
	Injector = require('../lib/Injector');

describe('Injector', function() {
	// Constructor tests
	describe('()', function() {
		it('should start if there are no modules', function() {
			new Injector();
		});

		it('should start if there is one module without dependencies', function() {
			var modA = new Module('mod-a');
			new Injector([modA]);
		});

		it('should start if one of module has missing dependencies', function() {
			var modA = new Module('mod-a', ['mod-b']);
			(function(){
				new Injector([modA]);
			}).should.throw('Module "mod-b" could not be found!');
		});

		it('should start if all depedencies are satisfied', function() {
			var modA = new Module('mod-a', []);
			var modB = new Module('mod-b', ['mod-a']);
			new Injector([modA, modB]);
		});

		it('should start if a dependency is registered on the parent injector', function() {
			var modA = new Module('mod-a', ['mod-b']),
				modB = new Module('mod-b'),
				parent = new Injector([modB]);
			new Injector([modA], parent);
		});

		it('should register the injector into itself', function() {
			var injector = new Injector();
			injector.get('$injector').should.be.exactly(injector);
		});
	});

	// Invoke tests
	describe('invoke(fn, self)', function() {
		var expectedConstant = 'check',
			module = new Module('mod').constant('constant', expectedConstant),
			injector = new Injector([module]),
			invoked,
			actualConstant,
			expectedScope = {scoped: true},
			actualScope,
			retVal = {returned: true};

		it('should invoke unannotated functions', function() {
			var func1 = function(constant) {
					invoked = true;
					actualConstant = constant;
					return retVal;
				};
			injector.invoke(func1).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
		});

		it('should invoke annotated functions', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					return retVal;
				};
			func1.$inject = ['constant'];
			injector.invoke(func1).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
		});

		it('should invoke array annotated functions', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					return retVal;
				};
			injector.invoke(['constant', func1]).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
		});

		it('should invoke unannotated functions with self', function() {
			var func1 = function(constant) {
					invoked = true;
					actualConstant = constant;
					actualScope = this;
					return retVal;
				};
			injector.invoke(func1, expectedScope).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
		});

		it('should invoke annotated functions with self', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					actualScope = this;
					return retVal;
				};
			func1.$inject = ['constant'];
			injector.invoke(func1, expectedScope).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
		});

		it('should invoke array annotated functions with self', function() {
			var func1 = function(param) {
					invoked = true;
					actualConstant = param;
					actualScope = this;
					return retVal;
				};
			injector.invoke(['constant', func1], expectedScope).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
		});

		it('should invoke array annotated functions with locals', function() {
			var expectedLocal = 132456798,
				actualLocal,
				func1 = function(param, local) {
					invoked = true;
					actualConstant = param;
					actualScope = this;
					actualLocal = expectedLocal
					return retVal;
				};
			injector.invoke(['constant', 'local1', func1], expectedScope, {local1: expectedLocal}).should.be.exactly(retVal);
			invoked.should.be.true;
			actualConstant.should.be.exactly(expectedConstant);
			actualScope.should.be.exactly(expectedScope);
			expectedLocal.should.be.exactly(actualLocal);
		});
	});

	// Instantiate tests
	describe('annotate(fn)', function() {
		var injector = new Injector();

		it('should no annotate if the function is already annotated', function() {
			var fn = function(injected) {};
			fn.$inject = ['test'];
			injector.annotate(fn).should.be.exactly(fn.$inject);
		});

		it('should annotate the function if not already annotated', function() {
			var fn = function(test) {};
			injector.annotate(fn).should.be.eql(['test']);
		});

		it('should annotate the function if using array syntax', function() {
			var fn = function(injected) {};
			injector.annotate(['test', fn]).should.be.eql(['test']);
		});

		it('should not be able to annotate objects', function() {
			var fn = function(injected) {};
			(function(){
				injector.annotate({});
			}).should.throw('Cannot annotate "[object Object]"');
		});
	});

	// Instantiate tests
	describe('instantiate(Type)', function() {
		var TestType1 = function() {
		};
		var TestType2 = function(injected) {
		};
		TestType2.$inject = ['injected'];
		var TestType3 = function(local) {
		};
		var module = new Module().constant('injected', true).type('TestType3', TestType3),
			injector = new Injector([module]);

		it('should be able to instantiate a parameterless class', function() {
			injector.instantiate(TestType1).should.be.an.instanceOf(TestType1);
		});

		it('should be able to instantiate a class with an injecter parameter', function() {
			injector.instantiate(TestType2).should.be.an.instanceOf(TestType2);
		});

		it('should be able to instantiate a class annotated with array syntax', function() {
			injector.instantiate(['injected', TestType1]).should.be.an.instanceOf(TestType1);
		});

		it('should be able to instantiate a class with a local', function() {
			injector.instantiate(TestType3, {local: 'injected!'}).should.be.an.instanceOf(TestType3);
		});

		it('should be able to instantiate a type by its name', function() {
			injector.instantiate('TestType3', {local: 'injected!'}).should.be.an.instanceOf(TestType3);
		});
	});

	// Get tests
	describe('get(name)', function() {
		var TestType1 = function() {
		};
		var TestType2 = function() {
		};
		var TestType3 = function() {
		};
		TestType3.$inject = ['type3'];
		var constant1 = 'test-1-value',
			modA = new Module('mod-a')
				.constant('constant1', constant1)
				.type('type1', TestType1)
				.type('type3', TestType3)
				.factory('factory1', function() {
					return new TestType1();
				}),
			constant2 = 'test-2-value',
			modB = new Module('mod-b')
				.constant('constant2', constant2)
				.type('type2', TestType2)
				.factory('factory2', function() {
					return new TestType2();
				})
				.constant('decoratedConstant', constant1)
				.decorator('decoratedConstant', ['$delegate', 'constant2', function($delegate, constant2) {
					return $delegate + constant2;
				}])
				.type('decoratedType', TestType2)
				.decorator('decoratedType', ['$delegate', function($delegate) {
					$delegate.decorated = true;
					return $delegate;
				}])
				.factory('decoratedFactory', function() {
					return new TestType2();
				})
				.decorator('decoratedFactory', ['$delegate', function($delegate) {
					$delegate.decorated = true;
					return $delegate;
				}])
				.type('nonReturningMonkeyPatcher', TestType2)
				.decorator('nonReturningMonkeyPatcher', ['$delegate', function($delegate) {
					$delegate.monkeyed = true;
				}])
				.type('doubleDecorated', TestType2)
				.decorator('doubleDecorated', ['$delegate', function($delegate) {
					$delegate.first = true;
					return $delegate;
				}])
				.decorator('doubleDecorated', ['$delegate', function($delegate) {
					$delegate.second = true;
					return $delegate;
				}]),
				constantOverride = 'test-3-value',
				modOverride = new Module('mod-override', ['mod-a'])
					.constant('constant1', constantOverride)
					.type('type1', TestType2)
					.type('type3', TestType2)
					.factory('factory1', function() {
						return new TestType2();
					}),
			parent = new Injector([modB]),
			injector = new Injector([modA], parent);

		it('should not resolve undeclared dependencies', function() {
			(function() {
				return injector.get('not-declared');
			}).should.throw('No provider for "not-declared"!');
		});

		it('should resolve declared constants', function() {
			injector.get('constant1').should.be.exactly(constant1);
		});

		it('should resolve declared constants in parent', function() {
			injector.get('constant2').should.be.exactly(constant2);
		});

		it('should resolve declared types', function() {
			injector.get('type1').should.be.an.instanceOf(TestType1);
		});

		it('should resolve declared types in parent', function() {
			injector.get('type2').should.be.an.instanceOf(TestType2);
		});

		it('should resolve declared factories', function() {
			injector.get('factory1').should.be.an.instanceOf(TestType1);
		});

		it('should resolve declared factories in parent', function() {
			injector.get('factory2').should.be.an.instanceOf(TestType2);
		});

		it('should not resolve circular dependencies', function() {
			(function() {
				return injector.get('type3');
			}).should.throw('Can not resolve circular dependency!');
		});

		it('should resolve decorated constants', function() {
			injector.get('decoratedConstant').should.be.eql(constant1 + constant2);
		});

		it('should resolve decorated types', function() {
			injector.get('decoratedType').decorated.should.be.true;
		});

		it('should resolve decorated factories', function() {
			injector.get('decoratedFactory').decorated.should.be.true;
		});

		it('should resolve decorated decorators, yo dawg', function() {
			var t = injector.get('doubleDecorated');
			t.first.should.be.true;
			t.second.should.be.true;
		});

		it('should resolve if the decorator does not return a new value', function() {
			injector.get('nonReturningMonkeyPatcher').monkeyed.should.be.true;
		});

		it('should resolve overriden types', function() {
			var overridenInjector = new Injector([modA, modOverride]);

			overridenInjector.get('constant1').should.be.exactly(constantOverride);
			overridenInjector.get('type1').should.be.an.instanceOf(TestType2);
			overridenInjector.get('type3').should.be.an.instanceOf(TestType2);
			overridenInjector.get('factory1').should.be.an.instanceOf(TestType2);
		});

		it('should resolve overriden types in parent', function() {
			var overridenInjector = new Injector([modOverride], injector);

			overridenInjector.get('constant1').should.be.exactly(constantOverride);
			overridenInjector.get('type1').should.be.an.instanceOf(TestType2);
			overridenInjector.get('type3').should.be.an.instanceOf(TestType2);
			overridenInjector.get('factory1').should.be.an.instanceOf(TestType2);
		});
	});

	// Run callback tests
	describe('run callback', function() {
		it('should run all callback', function() {
			var parameterlessRunInvoked = false,
				parameterizedRunInvoked = false,
				arrayAnnotatedRunInvoked = false,
				module = new Module('module')
					.constant('constant', 'yes')
					.run(function() {parameterlessRunInvoked = true;})
					.run(function(constant) {parameterizedRunInvoked = true;})
					.run(['constant', function(injected) {arrayAnnotatedRunInvoked = true;}]),
				injector = new Injector([module]);
			parameterlessRunInvoked.should.be.true;
			parameterizedRunInvoked.should.be.true;
			arrayAnnotatedRunInvoked.should.be.true;
		});
	});

	// Run module load order tests
	describe('load modules in topological order', function() {
		var actualOrder,
			expectedOrder = ['a', 'b', 'c'],
			modA = new Module('a').run(function() {actualOrder.push('a');}),
			modB = new Module('b', ['a']).run(function() {actualOrder.push('b');}),
			modC = new Module('c', ['b']).run(function() {actualOrder.push('c');}),
			modD = new Module('d', ['missing']),
			modCircular = new Module('b', ['c']);

		it('should throw on missing dependency', function() {
			(function(){
				new Injector([modD]);
			}).should.throw('Module "missing" could not be found!');
		});

		it('should throw on circular dependency', function() {
			(function(){
				new Injector([modC, modCircular]);
			}).should.throw('There is a cycle in the graph. It is not possible to derive a topological sort!');
		});

		it('should load in order if in order', function() {
			actualOrder = [];
			new Injector([modA, modB, modC]);

			actualOrder.should.eql(expectedOrder);
		});

		it('should load in order if in reverse order', function() {
			actualOrder = [];
			new Injector([modC, modB, modA]);

			actualOrder.should.eql(expectedOrder);
		});

		it('should load in order if in mixed order', function() {
			actualOrder = [];
			new Injector([modA, modC, modB]);

			actualOrder.should.eql(expectedOrder);
		});
	});
});
<|endoftext|>


<commit_before>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  toString
} = Object.prototype;

function _isBasicObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isBasicObject(val)) ?
    'BasicObject' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (t === 'Object') {
    if (val.constructor && (
      (val.constructor.name && val.constructor.name !== t)
    )) {
      t = val.constructor.name;
    }
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  if (val instanceof Error) {
    if (val.message) {
      t = `${t}("${val.message}")`;
    }
  }

  return t;
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ?
    `${d1} ${d2}` :
    d1;
}

const _compare = (a, b) =>
  String(a).localeCompare(String(b), undefined, {numeric: true});
const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);
const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

const members = val => _symbols(val).concat(_names(val));

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => {
      // Do not attempt to resolve these
      let skip = [
        'arguments',
        'callee',
        'caller'
      ];
      // Only resolve these in the context of leaf
      let leafOnly = [
        '__proto__'
      ];
      let v;
      let sv = '';
      let smax = 101;

      // First resolve k in the context of leaf (like it would be normally)
      try {
        if (!skip.includes(k)) {
          v = leaf[k];
        }
      } catch (err) {
        v = err; // Make the error visible in the dump
      }

      // Then try resolving k in the context of val (reached through
      // following __proto__) to eventually get a shadowed value (some
      // props only make sense when resolved in the context of leaf
      // and an exception will be thrown upon trying to access them through val)
      try {
        if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
          v = val[k];
        }
      } catch (err) {
        // Leave v as set by trying to resolve k in the context of leaf
      }

      // Show select values
      switch (typeof v) {
      case 'boolean':
      case 'number':
        sv = `:${v}`;

        break;
      case 'string':
        sv = `:${JSON.stringify(v)}`;

        break;
      case 'object':
        if (v instanceof Date) {
          sv = `:${JSON.stringify(v)}`;
        } else if (Array.isArray(v)) {
          sv = `:${v.length}`;
        }

        break;
      }

      return `${indent.repeat(level)}${String(k)}{${descStr(val, k)}}: ${typeStr(v, k)}${sv}`;
    }).
    join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  members,
  membersStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {typeStr, descStr, members, membersStr, chain, chainStr, apiStr};
export default apivis;
<commit_msg>Use shadowed value only if not undefined/null<commit_after>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  toString
} = Object.prototype;

function _isBasicObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isBasicObject(val)) ?
    'BasicObject' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (t === 'Object') {
    if (val.constructor && (
      (val.constructor.name && val.constructor.name !== t)
    )) {
      t = val.constructor.name;
    }
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  if (val instanceof Error) {
    if (val.message) {
      t = `${t}("${val.message}")`;
    }
  }

  return t;
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ?
    `${d1} ${d2}` :
    d1;
}

const _compare = (a, b) =>
  String(a).localeCompare(String(b), undefined, {numeric: true});
const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);
const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

const members = val => _symbols(val).concat(_names(val));

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => {
      // Do not attempt to resolve these
      let skip = [
        'arguments',
        'callee',
        'caller'
      ];
      // Only resolve these in the context of leaf
      let leafOnly = [
        '__proto__'
      ];
      let v;
      let sv = '';
      let smax = 101;

      // First resolve k in the context of leaf (like it would be normally)
      try {
        if (!skip.includes(k)) {
          v = leaf[k];
        }
      } catch (err) {
        v = err; // Make the error visible in the dump
      }

      // Then try resolving k in the context of val (reached through
      // following __proto__) to eventually get a shadowed value (some
      // props only make sense when resolved in the context of leaf
      // and an exception will be thrown upon trying to access them through val)
      try {
        if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
          let shv = val[k];

          if (shv !== undefined && shv !== null) {
            v = shv;
          }
        }
      } catch (err) {
        // Leave v as set by trying to resolve k in the context of leaf
      }

      // Show select values
      switch (typeof v) {
      case 'boolean':
      case 'number':
        sv = `:${v}`;

        break;
      case 'string':
        sv = `:${JSON.stringify(v)}`;

        break;
      case 'object':
        if (v instanceof Date) {
          sv = `:${JSON.stringify(v)}`;
        } else if (Array.isArray(v)) {
          sv = `:${v.length}`;
        }

        break;
      }

      return `${indent.repeat(level)}${String(k)}{${descStr(val, k)}}: ${typeStr(v, k)}${sv}`;
    }).
    join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  members,
  membersStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {typeStr, descStr, members, membersStr, chain, chainStr, apiStr};
export default apivis;
<|endoftext|>


<commit_before>pref('extensions.superdrag.version', '0.0.0');

// panel position
pref('extensions.superdrag.panel.show.distance', 120); // the panel will popup after moves such a distance.
pref('extensions.superdrag.panel.pos', 0); // 0: follow the cursor, 1: right top corner.
pref('extensions.superdrag.panel.follow.offset', 5);

// panel settings
pref('extensions.superdrag.panel.show.options', true);

// default action
pref('extensions.superdrag.default.action.link', 'background'); // 'background', 'foreground', 'current'
pref('extensions.superdrag.default.action.text', 'search'); // 'search' only, currently
pref('extensions.superdrag.default.action.search', 'background'); // 'background', 'foreground', 'current'
pref('extensions.superdrag.default.action.image', 'background'); // 'background', 'current', 'save'

// new tab
pref('extensions.superdrag.newtab.pos', 'default'); // 'default', 'right'
pref('extensions.superdrag.newtab.onleft.for.foreground', true);

// popup delay
pref('extensions.superdrag.popup.show.delay', 500); // show the menu after hover such a time interval (in ms)

// other behaviors
pref('extensions.superdrag.behavior.drop.to.input', true); // true so user can drag & drop text to an INPUT or TEXTAREA.

<commit_msg>since foreground tab has owner, the default value of 'open foreground tab on left' is 'false' now<commit_after>pref('extensions.superdrag.version', '0.0.0');

// panel position
pref('extensions.superdrag.panel.show.distance', 120); // the panel will popup after moves such a distance.
pref('extensions.superdrag.panel.pos', 0); // 0: follow the cursor, 1: right top corner.
pref('extensions.superdrag.panel.follow.offset', 5);

// panel settings
pref('extensions.superdrag.panel.show.options', true);

// default action
pref('extensions.superdrag.default.action.link', 'background'); // 'background', 'foreground', 'current'
pref('extensions.superdrag.default.action.text', 'search'); // 'search' only, currently
pref('extensions.superdrag.default.action.search', 'background'); // 'background', 'foreground', 'current'
pref('extensions.superdrag.default.action.image', 'background'); // 'background', 'current', 'save'

// new tab
pref('extensions.superdrag.newtab.pos', 'default'); // 'default', 'right'
pref('extensions.superdrag.newtab.onleft.for.foreground', false);

// popup delay
pref('extensions.superdrag.popup.show.delay', 500); // show the menu after hover such a time interval (in ms)

// other behaviors
pref('extensions.superdrag.behavior.drop.to.input', true); // true so user can drag & drop text to an INPUT or TEXTAREA.

<|endoftext|>


<commit_before>/*jslint browser: true, undef: true*//*global Ext*/

/**
 * @abstract
 * An abstract class for singletons that facilitates communication with backend services
 *
 * TODO:
 * - add events for all lifecycle events: beforerequest, request, beforexception, exception, unauthorized
 * - does the touch version use Ext.Ajax or parent.request?
 * - pass through request options like touch version does
 */
Ext.define('Jarvus.util.AbstractAPI', {
    extend: 'Ext.data.Connection',

    qualifiedUrlRe: /^(https?:)?\/\//,
    jsonMimeTypeRe: /^application\/([^;\s]+\+)?json(;.+)?$/,

    config: {
        /**
         * @cfg {String/null}
         * A host to prefix URLs with, or null to leave paths domain-relative
         */
        host: null,

        /**
         * @cfg {Boolean}
         * True to use HTTPS when prefixing host. Only used if {@link #cfg-host} is set
         */
        useSSL: false,

        /**
         * @cfg {String/null}
         * A path to prefix URLs with
         */
        pathPrefix: null,

        // @inheritdoc
        withCredentials: true,

        // @inheritdoc
        useDefaultXhrHeader: false,

        // @inheritdoc
        disableCaching: false
    },

    //@private
    buildUrl: function(path) {
        var me = this,
            host = me.getHost(),
            pathPrefix = me.getPathPrefix();

        if (me.qualifiedUrlRe.test(path)) {
            return path;
        }

        if (pathPrefix) {
            path = pathPrefix + path;
        }

        if (host) {
            path = (me.getUseSSL() ? 'https://' : 'http://') + host + path;
        }

        return path;
    },

    //@private
    buildHeaders: function(headers) {
        return headers;
    },

    //@private
    buildParams: function(params) {
        return params || null;
    },

    /**
     * Override {@link Ext.data.Connection#method-request} to implement auto-decoding and retry handler
     * @inheritdoc
     */
    request: function(options) {
        var me = this,
            jsonMimeTypeRe = me.jsonMimeTypeRe;

        return me.callParent([Ext.applyIf({
            url: me.buildUrl(options.url),
            params: me.buildParams(options.params),
            headers: me.buildHeaders(options.headers),
            timeout: options.timeout || 30000,
            success: function(response) {

                if (options.autoDecode !== false && jsonMimeTypeRe.test(response.getResponseHeader('Content-Type'))) {
                    response.data = Ext.decode(response.responseText, true);
                }

                //Calling the callback function sending the decoded data
                Ext.callback(options.success, options.scope, [response]);

            },
            failure: function(response) {

                if (options.autoDecode !== false && jsonMimeTypeRe.test(response.getResponseHeader('Content-Type'))) {
                    response.data = Ext.decode(response.responseText, true);
                }

                if (response.aborted === true) {
                    Ext.callback(options.abort, options.scope, [response]);
                } else if (response.status == 401 || response.statusText.indexOf('Unauthorized') !== -1) {

                    /*
                    We seem to always get the same session id, so we can't automatically try again once the user logs in
                    var oldSessionID = Ext.util.Cookies.get('s');
                     */

                    // Send user to callback if login attempt has failed
                    if (options.url == '/login') {
                        Ext.callback(options.success, options.scope, [response]);
                        return;
                    }

                    Ext.override(Ext.Msg, {
                        hide: function () {
                            var me = this,
                                hideManually = me.cfg ? me.cfg.hideManually : false;

                            if (!hideManually) {
                                me.callParent(arguments);
                            }
                        }
                    });

                    var msg = Ext.Msg.show({
                        hideManually: true,
                        title: 'Login Required',
                        msg: "You've either logged out or your has session expired. Please login and try again.",
                        buttonText: {
                            'yes': 'Login',
                            'no': 'Try Again',
                            'cancel': 'Cancel'
                        },
                        scope: msg,
                        fn: function (btn) {
                            if (btn === 'yes') {
                                // login
                                var loginWindow = window.open(me.buildUrl('/login'), 'emergence-login');
                                loginWindow.focus();
                                return;
                            } else if (btn === 'no') {
                                // try again
                                me.request(options);
                            }

                            msg.cfg.hideManually = false;
                            msg.hide();
                        }
                    });

                    /*
                    if (oldSessionID !== null) {
                        var cookieCheckInterval = window.setInterval(function() {
                            console.log(oldSessionID);
                            console.warn(Ext.util.Cookies.get('s'));
                            if (Ext.util.Cookies.get('s') != oldSessionID) {
                                alert('new login');
                                debugger;
                                window.clearInterval(cookieCheckInterval);
                            }
                        }, 100);
                    }
                    */
                } else if(response.status == 0) {
                    Ext.Msg.confirm('An error occurred', 'There was an error trying to reach the server. Do you want to try again?', function (btn) {
                        if (btn === 'yes') {
                            me.request(options);
                        }
                    });
                } else {
                    Ext.callback(options.failure, options.scope, [response]);
                }

            },
            scope: options.scope
        }, options)]);
    },

    // @deprecated
    setHostname: function(hostname) {
        //<debug>
        Ext.Logger.deprecate('hostname config is deprecated, use host instead');
        //</debug>

        this.setHost(hostname);
    },

    // @deprecated
    getHostname: function() {
        //<debug>
        Ext.Logger.deprecate('hostname config is deprecated, use host instead');
        //</debug>

        return this.getHost();
    }
});
<commit_msg>Add unauthenticated callback<commit_after>/*jslint browser: true, undef: true*//*global Ext*/

/**
 * @abstract
 * An abstract class for singletons that facilitates communication with backend services
 *
 * TODO:
 * - add events for all lifecycle events: beforerequest, request, beforexception, exception, unauthorized
 * - does the touch version use Ext.Ajax or parent.request?
 * - pass through request options like touch version does
 */
Ext.define('Jarvus.util.AbstractAPI', {
    extend: 'Ext.data.Connection',

    qualifiedUrlRe: /^(https?:)?\/\//,
    jsonMimeTypeRe: /^application\/([^;\s]+\+)?json(;.+)?$/,

    config: {
        /**
         * @cfg {String/null}
         * A host to prefix URLs with, or null to leave paths domain-relative
         */
        host: null,

        /**
         * @cfg {Boolean}
         * True to use HTTPS when prefixing host. Only used if {@link #cfg-host} is set
         */
        useSSL: false,

        /**
         * @cfg {String/null}
         * A path to prefix URLs with
         */
        pathPrefix: null,

        // @inheritdoc
        withCredentials: true,

        // @inheritdoc
        useDefaultXhrHeader: false,

        // @inheritdoc
        disableCaching: false
    },

    //@private
    buildUrl: function(path) {
        var me = this,
            host = me.getHost(),
            pathPrefix = me.getPathPrefix();

        if (me.qualifiedUrlRe.test(path)) {
            return path;
        }

        if (pathPrefix) {
            path = pathPrefix + path;
        }

        if (host) {
            path = (me.getUseSSL() ? 'https://' : 'http://') + host + path;
        }

        return path;
    },

    //@private
    buildHeaders: function(headers) {
        return headers;
    },

    //@private
    buildParams: function(params) {
        return params || null;
    },

    /**
     * Override {@link Ext.data.Connection#method-request} to implement auto-decoding and retry handler
     * @inheritdoc
     */
    request: function(options) {
        var me = this,
            jsonMimeTypeRe = me.jsonMimeTypeRe;

        return me.callParent([Ext.applyIf({
            url: me.buildUrl(options.url),
            params: me.buildParams(options.params),
            headers: me.buildHeaders(options.headers),
            timeout: options.timeout || 30000,
            success: function(response) {

                if (options.autoDecode !== false && jsonMimeTypeRe.test(response.getResponseHeader('Content-Type'))) {
                    response.data = Ext.decode(response.responseText, true);
                }

                //Calling the callback function sending the decoded data
                Ext.callback(options.success, options.scope, [response]);

            },
            failure: function(response) {

                if (options.autoDecode !== false && jsonMimeTypeRe.test(response.getResponseHeader('Content-Type'))) {
                    response.data = Ext.decode(response.responseText, true);
                }

                if (response.aborted === true) {
                    Ext.callback(options.abort, options.scope, [response]);
                } else if (response.status == 401 || response.statusText.indexOf('Unauthorized') !== -1) {

                    /*
                    We seem to always get the same session id, so we can't automatically try again once the user logs in
                    var oldSessionID = Ext.util.Cookies.get('s');
                     */

                    /*
                    if (oldSessionID !== null) {
                        var cookieCheckInterval = window.setInterval(function() {
                            console.log(oldSessionID);
                            console.warn(Ext.util.Cookies.get('s'));
                            if (Ext.util.Cookies.get('s') != oldSessionID) {
                                alert('new login');
                                debugger;
                                window.clearInterval(cookieCheckInterval);
                            }
                        }, 100);
                    }
                    */

                    Ext.callback(options.unauthenticated, options.scope, [response]);

                } else if(response.status == 0) {
                    Ext.Msg.confirm('An error occurred', 'There was an error trying to reach the server. Do you want to try again?', function (btn) {
                        if (btn === 'yes') {
                            me.request(options);
                        }
                    });
                } else {
                    Ext.callback(options.failure, options.scope, [response]);
                }

            },
            scope: options.scope
        }, options)]);
    },

    // @deprecated
    setHostname: function(hostname) {
        //<debug>
        Ext.Logger.deprecate('hostname config is deprecated, use host instead');
        //</debug>

        this.setHost(hostname);
    },

    // @deprecated
    getHostname: function() {
        //<debug>
        Ext.Logger.deprecate('hostname config is deprecated, use host instead');
        //</debug>

        return this.getHost();
    }
});
<|endoftext|>


<commit_before>/*jslint browser: true, undef: true*//*global Ext*/

/**
 * @abstract
 * An abstract class for singletons that facilitates communication with backend services on a local or remote emergence server
 */
Ext.define('Emergence.util.AbstractAPI', {
    extend: 'Jarvus.util.AbstractAPI',

    config: {
        sessionData: null
    },

    /**
     * @event
     * Fires after successful login
     * @param {Object} sessionData
     */

    buildHeaders: function(headers) {
        headers = headers || {};

        if (!('Accept' in headers)) {
            headers.Accept = 'application/json';
        }

        return headers;
    },

    /**
     * Attempt to load session data
     * @param {String} hostname
     * @param {String} username
     * @param {String} password
     * @param {Function} callback A function to call and pass the new client data to when it is available
     * @param {Object} scope Scope for the callback function
     */
    getSessionData: function(callback, scope) {
        var me = this;

        me.request({
            url: '/login',
            method: 'GET',
            success: function(response) {
                if(response.data && response.data.success) {
                    me.setSessionData(response.data.data);
                    Ext.callback(callback, scope, [true, response]);
                    me.fireEvent('login', response.data.data);
                }
                else {
                    Ext.callback(callback, scope, [false, response]);
                }
            },
            exception: function(response) {
                Ext.callback(callback, scope, [false, response]);
            }
        });
    },

    /**
     * Login to a remote Slate instance
     * @param {String} hostname
     * @param {String} username
     * @param {String} password
     * @param {Function} callback A function to call and pass the new client data to when it is available
     * @param {Object} scope Scope for the callback function
     */
    login: function(username, password, callback, scope) {
        var me = this;

        me.request({
            url: '/login',
            params: {
                '_LOGIN[username]': username,
                '_LOGIN[password]': password,
                '_LOGIN[returnMethod]': 'POST'
            },
            success: function(response) {
                if (response.data && response.data.success) {
                    me.setSessionData(response.data.data);
                    Ext.callback(callback, scope, [true, response]);
                    me.fireEvent('login', response.data.data);
                } else {
                    Ext.callback(callback, scope, [false, response]);
                }
            },
            exception: function(response) {
                Ext.callback(callback, scope, [false, response]);
            }
        });
    },

    /**
     * Logout from remote Slate instance
     * @param {Function} callback A function to call and pass the new client data to when it is available
     * @param {Object} scope Scope for the callback function
     */
    logout: function(callback, scope) {
        this.request({
            url: '/login/logout',
            success: function(response) {
                Ext.callback(callback, scope, [true, response]);
            },
            exception: function(response) {
                Ext.callback(callback, scope, [false, response]);
            }
        });
    }
});<commit_msg>add uploadMedia method<commit_after>/*jslint browser: true, undef: true*//*global Ext*/

/**
 * @abstract
 * An abstract class for singletons that facilitates communication with backend services on a local or remote emergence server
 */
Ext.define('Emergence.util.AbstractAPI', {
    extend: 'Jarvus.util.AbstractAPI',

    config: {
        sessionData: null
    },

    /**
     * @event
     * Fires after successful login
     * @param {Object} sessionData
     */

    buildHeaders: function(headers) {
        headers = headers || {};

        if (!('Accept' in headers)) {
            headers.Accept = 'application/json';
        }

        return headers;
    },

    /**
     * Attempt to load session data
     * @param {String} hostname
     * @param {String} username
     * @param {String} password
     * @param {Function} callback A function to call and pass the new client data to when it is available
     * @param {Object} scope Scope for the callback function
     */
    getSessionData: function(callback, scope) {
        var me = this;

        me.request({
            url: '/login',
            method: 'GET',
            success: function(response) {
                if(response.data && response.data.success) {
                    me.setSessionData(response.data.data);
                    Ext.callback(callback, scope, [true, response]);
                    me.fireEvent('login', response.data.data);
                }
                else {
                    Ext.callback(callback, scope, [false, response]);
                }
            },
            exception: function(response) {
                Ext.callback(callback, scope, [false, response]);
            }
        });
    },

    /**
     * Login to a remote Slate instance
     * @param {String} hostname
     * @param {String} username
     * @param {String} password
     * @param {Function} callback A function to call and pass the new client data to when it is available
     * @param {Object} scope Scope for the callback function
     */
    login: function(username, password, callback, scope) {
        var me = this;

        me.request({
            url: '/login',
            params: {
                '_LOGIN[username]': username,
                '_LOGIN[password]': password,
                '_LOGIN[returnMethod]': 'POST'
            },
            success: function(response) {
                if (response.data && response.data.success) {
                    me.setSessionData(response.data.data);
                    Ext.callback(callback, scope, [true, response]);
                    me.fireEvent('login', response.data.data);
                } else {
                    Ext.callback(callback, scope, [false, response]);
                }
            },
            exception: function(response) {
                Ext.callback(callback, scope, [false, response]);
            }
        });
    },

    /**
     * Logout from remote Slate instance
     * @param {Function} callback A function to call and pass the new client data to when it is available
     * @param {Object} scope Scope for the callback function
     */
    logout: function(callback, scope) {
        this.request({
            url: '/login/logout',
            success: function(response) {
                Ext.callback(callback, scope, [true, response]);
            },
            exception: function(response) {
                Ext.callback(callback, scope, [false, response]);
            }
        });
    },

    /**
     * Upload an HTML5 file object
     * @param {Object} the html5 file object
     * @param {Function} the function to call after the response
     * @param {Object} the scope for the callback function
     */
    uploadMedia: function(file, callback, scope) {
        var me = this;
        var formData = new FormData();

        formData.append('mediaFile', file);

        me.request({
            method: 'POST',
            url: '/media/upload',
            headers: {
                // Setting Content-Type to null allows the browser to automatically set Content-Type.
                // Must-have for file uploads using the FormData object.
                'Content-Type': null
            },
            rawData: formData,
            success: function(response) {
                var success = response.data && response.data.success,
                    mediaData = success && response.data.data;

                Ext.callback(callback, scope, [success, response, mediaData]);
            }
        });
    }
});<|endoftext|>


<commit_before><commit_msg>extra file removed<commit_after><|endoftext|>


<commit_before>'use strict';

const supertest = require('supertest');
const req = supertest(require('../../').app);

const github = require('../../lib/github');

const owner = process.env.TEST_APP_NAME.split('/')[0];
const repo = process.env.TEST_APP_NAME.split('/')[1];

beforeEach(function beforeEach() {
  github.client().repos = {
    getCommits: function gitHubGetCommitsMock() {
      throw new Error('github.repos.getCommits() is not implemented');
    },
    getCommit: function gitHubGetCommitMock() {
      throw new Error('github.repos.getCommit() is not implemented');
    },
  };

  github.client().statuses = {
    get: function gitHubGetStatusMock(msg, cb) {
      process.nextTick(cb.bind(null, null, []));
    },
  };
});

describe('GET /app', function describe() {
  const url = `/app`;

  it('redirects to login for unauthenticated user', function it(done) {
    req.get(url)
     .expect(302)
     .expect('Location', '/login', done);
  });

  it('returns my applications', function it(done) {
    req.get(url)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200, done);
  });
});

describe('ALL /app/new', function describe() {
  const url = `/app/new`;

  before(function before() {
    github.client().getAllRepos = function getAllReposMock(cb) {
      process.nextTick(cb.bind(null, null, [
        'foo/bar',
        'for/baz',
        'bar/foo',
      ]));
    };
  });

  it('redirects to login for unauthenticated user', function it(done) {
    req.get(url)
     .expect(302)
     .expect('Location', '/login', done);
  });

  it('returns new application form', function it(done) {
    req.get(url)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200, done);
  });
});

describe.skip('GET /app/:owner/:repo', function describe() {
  const url = `/app/${owner}/${repo}`;

  it('redirects to login for unauthenticated user');
  it('redirects to my apps for unautorized user');

  it('returns application', function it(done) {
    github.client().repos.getCommits = function gitHubGetCommitsSpy(msg, cb) {
      cb(null, [{
        sha: '28f497509b8e2f7ff75d48de83303dcc969cd6de',
        commit: {
          author: null,
          commiter: null,
          message: 'Foobar',
          tree: null,
          url: '',
          comment_count: 0,
        },
        parents: [null],
      }]);
    };

    req.get(url)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200, done);
  });
});

describe('GET /app/:owner/:repo/:sha', function describe() {
  const url = `/app/${owner}/${repo}`;
  const urlValid = `${url}/28f497509b8e2f7ff75d48de83303dcc969cd6de`;
  const urlInvalid = `${url}/28f497509b8e2f7ff75d48de83303dcc969cd6dd`;
  const urlUnknown = `${url}/28f497509b8e2f7ff75d48de83303dcc969cd6df`;

  beforeEach(function() {
    github.client().repos.getCommit = function gitHubGetCommitMock(msg, cb) {
      if (msg.sha === '28f497509b8e2f7ff75d48de83303dcc969cd6df') {
        const err = new Error(JSON.stringify({
          message: 'Not Found',
          documentation_url: 'https://developer.github.com/v3',
        }));

        err.code = 404;

        process.nextTick(cb.bind(null, err));
      } else {
        if (msg.sha === '28f497509b8e2f7ff75d48de83303dcc969cd6de') {
          msg.msg = 'feat(scope): some valid message';
        } else {
          msg.msg = 'Some invalid message';
        }

        process.nextTick(cb.bind(null, null, {
          sha: msg.sha,
          commit: {
            author: null,
            commiter: null,
            message: msg.msg,
            tree: null,
            url: '',
            commmet_count: 0,
          },
        }));
      }
    };
  });

  it('redirects from non-existing commit sha', function it(done) {
    req.get(urlUnknown)
      .expect(404)
      .expect('Location', `/app/${owner}/${repo}`, done);
  });

  it('shows valid commit status for unauthenticated user', function it(done) {
    req.get(urlValid)
      .expect(200)
      .expect('X-Commit-Message', 'true', done);
  });

  it('shows invvalid commit status for unauthenticated user', function it(done) {
    req.get(urlInvalid)
      .expect(200)
      .expect('X-Commit-Message', 'false', done);
  });

  it('shows commit status for authenticated user', function it(done) {
    req.get(urlValid)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200)
      .expect('X-Commit-Message', 'true', done);
  });
});
<commit_msg>fix(test): do not skip test section<commit_after>'use strict';

const supertest = require('supertest');
const req = supertest(require('../../').app);

const github = require('../../lib/github');

const owner = process.env.TEST_APP_NAME.split('/')[0];
const repo = process.env.TEST_APP_NAME.split('/')[1];

beforeEach(function beforeEach() {
  github.client().repos = {
    getCommits: function gitHubGetCommitsMock() {
      throw new Error('github.repos.getCommits() is not implemented');
    },
    getCommit: function gitHubGetCommitMock() {
      throw new Error('github.repos.getCommit() is not implemented');
    },
  };

  github.client().statuses = {
    get: function gitHubGetStatusMock(msg, cb) {
      process.nextTick(cb.bind(null, null, []));
    },
  };
});

describe('GET /app', function describe() {
  const url = `/app`;

  it('redirects to login for unauthenticated user', function it(done) {
    req.get(url)
     .expect(302)
     .expect('Location', '/login', done);
  });

  it('returns my applications', function it(done) {
    req.get(url)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200, done);
  });
});

describe('ALL /app/new', function describe() {
  const url = `/app/new`;

  before(function before() {
    github.client().getAllRepos = function getAllReposMock(cb) {
      process.nextTick(cb.bind(null, null, [
        'foo/bar',
        'for/baz',
        'bar/foo',
      ]));
    };
  });

  it('redirects to login for unauthenticated user', function it(done) {
    req.get(url)
     .expect(302)
     .expect('Location', '/login', done);
  });

  it('returns new application form', function it(done) {
    req.get(url)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200, done);
  });
});

describe('GET /app/:owner/:repo', function describe() {
  const url = `/app/${owner}/${repo}`;

  it('redirects to login for unauthenticated user');
  it('redirects to my apps for unautorized user');

  it('returns application', function it(done) {
    github.client().repos.getCommits = function gitHubGetCommitsSpy(msg, cb) {
      cb(null, [{
        sha: '28f497509b8e2f7ff75d48de83303dcc969cd6de',
        commit: {
          author: null,
          commiter: null,
          message: 'Foobar',
          tree: null,
          url: '',
          comment_count: 0,
        },
        parents: [null],
      }]);
    };

    req.get(url)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200, done);
  });
});

describe('GET /app/:owner/:repo/:sha', function describe() {
  const url = `/app/${owner}/${repo}`;
  const urlValid = `${url}/28f497509b8e2f7ff75d48de83303dcc969cd6de`;
  const urlInvalid = `${url}/28f497509b8e2f7ff75d48de83303dcc969cd6dd`;
  const urlUnknown = `${url}/28f497509b8e2f7ff75d48de83303dcc969cd6df`;

  beforeEach(function() {
    github.client().repos.getCommit = function gitHubGetCommitMock(msg, cb) {
      if (msg.sha === '28f497509b8e2f7ff75d48de83303dcc969cd6df') {
        const err = new Error(JSON.stringify({
          message: 'Not Found',
          documentation_url: 'https://developer.github.com/v3',
        }));

        err.code = 404;

        process.nextTick(cb.bind(null, err));
      } else {
        if (msg.sha === '28f497509b8e2f7ff75d48de83303dcc969cd6de') {
          msg.msg = 'feat(scope): some valid message';
        } else {
          msg.msg = 'Some invalid message';
        }

        process.nextTick(cb.bind(null, null, {
          sha: msg.sha,
          commit: {
            author: null,
            commiter: null,
            message: msg.msg,
            tree: null,
            url: '',
            commmet_count: 0,
          },
        }));
      }
    };
  });

  it('redirects from non-existing commit sha', function it(done) {
    req.get(urlUnknown)
      .expect(404)
      .expect('Location', `/app/${owner}/${repo}`, done);
  });

  it('shows valid commit status for unauthenticated user', function it(done) {
    req.get(urlValid)
      .expect(200)
      .expect('X-Commit-Message', 'true', done);
  });

  it('shows invvalid commit status for unauthenticated user', function it(done) {
    req.get(urlInvalid)
      .expect(200)
      .expect('X-Commit-Message', 'false', done);
  });

  it('shows commit status for authenticated user', function it(done) {
    req.get(urlValid)
      .set('Cookie', process.env.SESS_COOKIE)
      .expect(200)
      .expect('X-Commit-Message', 'true', done);
  });
});
<|endoftext|>


<commit_before>'use strict';

const assert = require('chai').assert;
const expect = require('chai').expect;
const should = require('chai').should();

const app = require('../app');
const request = require('supertest').agent(app);

const Task = require('../models/task');

describe('Teste de API - Rotas', function () {

    var id;
    var task;
    var task_post;

    // É executado ANTES de todos os testes neste bloco
    before(function (done) {
        task = new Task({
            title: 'Task inserida para teste de api',
            completionDate: '2017-05-29',
            labels: ['teste', 'api', 'rotas', 'mocha', 'chai']
        }).save(function (err, res) { // Insere
            if (err) return done(err);

            task = res;
            done();
        });
    });

    // É executado APÓS todos os testes neste bloco
    after(function () {
        removeTask(task._id);
    });

    describe('ROTAS GET', function () {
        it('GET /api/task - Deve retornar status 404 quando rota for inválida.', function (done) {
            request
                .get('/api/task')
                .expect(404)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('GET /api/tasks - Deve retornar lista de tasks.', function (done) {
            request
                .get('/api/tasks')
                .expect("Content-type", /json/)
                .expect(200)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(200);
                    expect(res.charset).to.equal('utf-8');

                    expect(res.error).to.be.false;
                    expect(res.body).to.be.an('array');

                    // Espera pelo menos um registro
                    expect(res.body.length).to.be.at.least(1);

                    done();
                });
        });

        it('GET /api/tasks/12 - Retorna status 404 quando task não for encontrada.', function (done) {
            request
                .get('/api/tasks/12')
                .expect(404)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('GET /api/tasks/:_id - Deve retornar uma task de acordo com o _id.', function (done) {
            request
                .get('/api/tasks/' + task._id)
                .expect("Content-type", /json/)
                .expect(200)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(200);
                    expect(res.body).to.be.an('object');

                    expect(res.body.labels).to.be.an('array').that.include('mocha');

                    expect(res.body.title).to.equal(task.title);

                    expect(res.body).to.have.property('noticeDate');
                    expect(res.body).to.have.property('priority').that.is.a('number');

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

    describe('ROTAS POST', function () {
        it('POST /api/tasks	- Não deve inserir uma task sem title e completionDate', function (done) {
            request
                .post('/api/tasks')
                .send({
                    description: 'Tentando inserir sem os campos obrigatórios: title e completionDate'
                })
                .expect(400)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(400);
                    expect(res.body).to.be.an('object');
                    expect(res.body).to.have.property('errors');
                    done();
                })
        });

        it('POST /api/tasks	- Deve inserir uma nova task e retornar o objeto inserido.', function (done) {
            let t = {
                title: 'Task inserida usando rota POST /api/tasks',
                description: 'Descrição da task',
                priority: 2, // 1 prioridade máxima, 2 média, 3 normal
                completionDate: '2017-05-28',
                labels: 'Test, POST',
                noticeDate: '2017-05-28 09:30:00',
                isFinalized: true
            };

            request
                .post('/api/tasks')
                .send(t)
                .expect("Content-type", /json/)
                .expect(201)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(201);
                    expect(res.body).to.be.an('object');

                    expect(res.body).to.have.property('_id');
                    expect(res.body).to.have.property('title');
                    expect(res.body).to.have.property('description');
                    expect(res.body).to.have.property('priority');
                    expect(res.body).to.have.property('completionDate');
                    expect(res.body).to.have.property('labels');
                    expect(res.body).to.have.property('noticeDate');
                    expect(res.body).to.have.property('isFinalized');
                    expect(res.body).to.have.property('created_at');
                    expect(res.body).to.have.property('updated_at');

                    expect(res.body.title).to.equal(t.title);

                    // remove a task inserida
                    removeTask(res.body._id);
                    done();
                });
        });
    });

    describe('ROTAS PUT', function () {
        it('PUT /api/tasks/:_id - Deve retornar erro 404 quando a task a ser atualizada não existir.', function (done) {
            request
                .put('/api/tasks/12')
                .send({ title: 'Não atualizar!!!' })
                .expect(404)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('PUT /api/tasks/:_id - Deve atualizar uma task de acordo com o _id e retornar o objeto atualizado.', function (done) {
            let t = {
                title: 'Task foi atualizada',
                isFinalized: true
            };

            request
                .put('/api/tasks/' + task._id)
                .send(t)
                .expect("Content-type", /json/)
                .expect(201)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(201);
                    expect(res.body).to.be.an('object');
                    expect(res.body.title).to.equal(t.title);
                    expect(res.body.isFinalized).to.be.true;

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

    describe('ROTAS DELETE', function () {
        it('PUT /api/tasks/:_id - Deve retornar erro 404 quando a task a ser removida não existir.', function (done) {
            request
                .delete('/api/tasks/12')
                .expect(404)
                .end(function (err, res) {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('DELETE /api/tasks/:_id - Deve remover uma task de cordo com o _id e retornar o objeto removido.', function (done) {
            // Insere novamente uma nova task para depois tentar remover pela rota
            task.save(function (err, t) {
                request
                    .delete('/api/tasks/' + t._id)
                    .expect("Content-type", /json/)
                    .expect(200)
                    .end(function (err, res) {
                        // expect(res.body).to.be.an('object');
                        done();
                    });
            });
        });
    });
});

function removeTask(id) {
    Task.findByIdAndRemove(id, function (err, res) {
        if (err) return done(err);
        done();
    });
}<commit_msg>Refatoração, adaptando para arrow functions<commit_after>'use strict';

const assert = require('chai').assert;
const expect = require('chai').expect;
const should = require('chai').should();

const app = require('../app');
const request = require('supertest').agent(app);

const Task = require('../models/task');

describe('Teste de API - Rotas', () => {

    var id;
    var task;
    var task_post;

    // É executado ANTES de todos os testes neste bloco
    before((done) => {
        task = new Task({
            title: 'Task inserida para teste de api',
            completionDate: '2017-05-29',
            labels: ['teste', 'api', 'rotas', 'mocha', 'chai']
        }).save((err, res) => { // Insere
            if (err) return done(err);

            task = res;
            done();
        });
    });

    // É executado APÓS todos os testes neste bloco
    after(() => {
        removeTask(task._id);
    });

    describe('ROTAS GET', () => {
        it('GET /api/task - Deve retornar status 404 quando rota for inválida.', (done) => {
            request
                .get('/api/task')
                .expect(404)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('GET /api/tasks - Deve retornar lista de tasks.', (done) => {
            request
                .get('/api/tasks')
                .expect("Content-type", /json/)
                .expect(200)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(200);
                    expect(res.charset).to.equal('utf-8');

                    expect(res.error).to.be.false;
                    expect(res.body).to.be.an('array');

                    // Espera pelo menos um registro >=
                    expect(res.body.length).to.be.at.least(1);

                    done();
                });
        });

        it('GET /api/tasks/12 - Retorna status 404 quando task não for encontrada.', (done) => {
            request
                .get('/api/tasks/12')
                .expect(404)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('GET /api/tasks/:_id - Deve retornar uma task de acordo com o _id.', (done) => {
            request
                .get('/api/tasks/' + task._id)
                .expect("Content-type", /json/)
                .expect(200)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(200);
                    expect(res.body).to.be.an('object');

                    expect(res.body.labels).to.be.an('array').that.include('mocha');

                    expect(res.body.title).to.equal(task.title);

                    expect(res.body).to.have.property('noticeDate');
                    expect(res.body).to.have.property('priority').that.is.a('number');

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

    describe('ROTAS POST', () => {
        it('POST /api/tasks	- Não deve inserir uma task sem title e completionDate', (done) => {
            request
                .post('/api/tasks')
                .send({
                    description: 'Tentando inserir sem os campos obrigatórios: title e completionDate'
                })
                .expect(400)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(400);
                    expect(res.body).to.be.an('object');
                    expect(res.body).to.have.property('errors');
                    done();
                })
        });

        it('POST /api/tasks	- Deve inserir uma nova task e retornar o objeto inserido.', (done) => {
            let t = {
                title: 'Task inserida usando rota POST /api/tasks',
                description: 'Descrição da task',
                priority: 2, // 1 prioridade máxima, 2 média, 3 normal
                completionDate: '2017-05-28',
                labels: 'Test, POST',
                noticeDate: '2017-05-28 09:30:00',
                isFinalized: true
            };

            request
                .post('/api/tasks')
                .send(t)
                .expect("Content-type", /json/)
                .expect(201)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(201);
                    expect(res.body).to.be.an('object');

                    expect(res.body).to.have.property('_id');
                    expect(res.body).to.have.property('title');
                    expect(res.body).to.have.property('description');
                    expect(res.body).to.have.property('priority');
                    expect(res.body).to.have.property('completionDate');
                    expect(res.body).to.have.property('labels');
                    expect(res.body).to.have.property('noticeDate');
                    expect(res.body).to.have.property('isFinalized');
                    expect(res.body).to.have.property('created_at');
                    expect(res.body).to.have.property('updated_at');

                    expect(res.body.title).to.equal(t.title);

                    // remove a task inserida
                    removeTask(res.body._id);
                    done();
                });
        });
    });

    describe('ROTAS PUT', () => {
        it('PUT /api/tasks/:_id - Deve retornar erro 404 quando a task a ser atualizada não existir.', (done) => {
            request
                .put('/api/tasks/12')
                .send({ title: 'Não atualizar!!!' })
                .expect(404)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('PUT /api/tasks/:_id - Deve atualizar uma task de acordo com o _id e retornar o objeto atualizado.', (done) => {
            let t = {
                title: 'Task foi atualizada',
                isFinalized: true
            };

            request
                .put('/api/tasks/' + task._id)
                .send(t)
                .expect("Content-type", /json/)
                .expect(201)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(201);
                    expect(res.body).to.be.an('object');
                    expect(res.body.title).to.equal(t.title);
                    expect(res.body.isFinalized).to.be.true;

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

    describe('ROTAS DELETE', () => {
        it('PUT /api/tasks/:_id - Deve retornar erro 404 quando a task a ser removida não existir.', (done) => {
            request
                .delete('/api/tasks/12')
                .expect(404)
                .end((err, res) => {
                    expect(res.statusCode).to.equal(404);
                    done();
                });
        });

        it('DELETE /api/tasks/:_id - Deve remover uma task de cordo com o _id e retornar o objeto removido.', (done) => {
            // Insere novamente uma nova task para depois tentar remover pela rota
            task.save(function (err, t) {
                request
                    .delete('/api/tasks/' + t._id)
                    .expect("Content-type", /json/)
                    .expect(200)
                    .end((err, res) => {
                        // expect(res.body).to.be.an('object');
                        done();
                    });
            });
        });
    });
});

function removeTask(id) {
    Task.findByIdAndRemove(id, (err, res) => {
        if (err) return done(err);
        done();
    });
}<|endoftext|>


<commit_before>var assert = require('assert');
var StyleStats = require('../lib/stylestats.js');

describe('Constructor Test', function () {

  describe('Invalid argument', function() {

    it('should throw error', function(done) {
      var invalidArgs = new StyleStats('xxxxxxxxxxxx');
      assert.throws(
        invalidArgs.parse(function(error, invalidArgsResult) {
          if (error) {
            throw error;
          }
        }),
        Error
      );
      done();
    });
  });

  describe('Customize with option', function() {

    it('should return gzipped size if configuration file is specified', function(done) {
      var customStats = new StyleStats('test/fixture/test.css', 'test/fixture/.stylestatsrc');
      customStats.parse(function(error, customResult) {
        if (error) {
          throw error;
        }
        assert.equal(customResult.gzippedSize, 429);
        done();
      });
    });

    it('should throw error if specified configuration file is invalid', function(done) {
      assert.throws(
        function() {
          new StyleStats('test/fixture/test.css', 'test/fixture/.invalidrc');
        },
        Error
      );
      done();
    });

    it('should return gzipped size if option object is given', function(done) {
      var customObjectStats = new StyleStats('test/fixture/test.css', {
        gzippedSize: true
      });
      customObjectStats.parse(function(error, customObjectResult) {
        if (error) {
          throw error;
        }
        assert.equal(customObjectResult.gzippedSize, 429);
        done();
      });
    });
  });

  describe('URL', function() {

    it('should return file size if CSS URL is given', function(done) {
      var requestStats = new StyleStats('http://t32k.me/mol/assets/main.css');
      requestStats.parse(function(error, requestResult) {
        if (error) {
          throw error;
        }
        assert.equal(requestResult.size, 58694);
        done();
      });
    });

    it('should throw error if CSS of specified URL is invalid', function(done) {
      var invalidCSS = new StyleStats('http://t32k.me/static/assets/css/invalid.css');
      assert.throws(
        invalidCSS.parse(function(error, invalidCSSResult) {
          if (error) {
            throw error;
          }
        }),
        Error
      );
      done();
    });

    it('should throw error if invalid JSON URL is given', function(done) {
      var invalidJSON = new StyleStats('http://t32k.me/static/assets/json/foo.json');
      assert.throws(
        invalidJSON.parse(function(error, invalidJSONResult) {
          if (error) {
            throw error;
          }
        }),
        Error
      );
      done();
    });

    it('should return the number of stylesheets if site URL is given', function(done) {
      var htmlStats = new StyleStats('http://t32k.me/');
      htmlStats.parse(function(error, htmlResult) {
        if (error) {
          throw error;
        }
        assert.equal(htmlResult.stylesheets, 1);
        done();
      });
    });
  });

  describe('File path', function() {
    it('should return file size', function(done) {
      var dirStats = new StyleStats('test/fixture/');
      dirStats.parse(function(error, dirResult) {
        if (error) {
          throw error;
        }
        assert.equal(dirResult.size, 20462);
        done();
      });
    });

    it('should return specified files size if glob is specified', function(done) {
      var globStats = new StyleStats('test/**/*.css');
      globStats.parse(function(error, globResult) {
        if (error) {
          throw error;
        }
        assert.equal(globResult.size, 39931);
        done();
      });
    });

    it('should return the number of stylesheets if multiple files are specified', function(done) {
      var multipleStats = new StyleStats(['test/fixture/test.css', 'test/fixture/app.css']);
      multipleStats.parse(function(error, multipleResult) {
        if (error) {
          throw error;
        }
        assert.equal(multipleResult.stylesheets, 2);
        done();
      });
    });
  });

  describe('CSS string', function() {

    it('should return 0 as the number of stylesheets', function(done) {
      var rawStats = new StyleStats('body{color:green}');
      rawStats.parse(function(error, rawResult) {
        if (error) {
          throw error;
        }
        assert.equal(rawResult.stylesheets, 0);
        done();
      });
    });

    it('should return data size', function(done) {
      var rawStats = new StyleStats('body{color:green}');
      rawStats.parse(function(error, rawResult) {
        if (error) {
          throw error;
        }
        assert.equal(rawResult.size, 17);
        done();
      });
    });
  });

  describe('Preprocessor files', function() {

    it('should return file size if LESS files are specified', function(done) {
      var lessStats = new StyleStats('test/fixture/prepros/foo.less');
      lessStats.parse(function(error, lessResult) {
        if (error) {
          throw error;
        }
        assert.equal(lessResult.size, 495);
        done();
      });
    });

    it('should return file size if Stylus files are specified', function(done) {
      var stylStats = new StyleStats('test/fixture/prepros/foo.styl');
      stylStats.parse(function(error, stylResult) {
        if (error) {
          throw error;
        }
        assert.equal(stylResult.size, 259);
        done();
      });
    });
  });
});
<commit_msg>Fix remote tests<commit_after>var assert = require('assert');
var StyleStats = require('../lib/stylestats.js');

describe('Constructor Test', function () {

  describe('Invalid argument', function() {

    it('should throw error', function(done) {
      var invalidArgs = new StyleStats('xxxxxxxxxxxx');
      assert.throws(
        invalidArgs.parse(function(error, invalidArgsResult) {
          if (error) {
            throw error;
          }
        }),
        Error
      );
      done();
    });
  });

  describe('Customize with option', function() {

    it('should return gzipped size if configuration file is specified', function(done) {
      var customStats = new StyleStats('test/fixture/test.css', 'test/fixture/.stylestatsrc');
      customStats.parse(function(error, customResult) {
        if (error) {
          throw error;
        }
        assert.equal(customResult.gzippedSize, 429);
        done();
      });
    });

    it('should throw error if specified configuration file is invalid', function(done) {
      assert.throws(
        function() {
          new StyleStats('test/fixture/test.css', 'test/fixture/.invalidrc');
        },
        Error
      );
      done();
    });

    it('should return gzipped size if option object is given', function(done) {
      var customObjectStats = new StyleStats('test/fixture/test.css', {
        gzippedSize: true
      });
      customObjectStats.parse(function(error, customObjectResult) {
        if (error) {
          throw error;
        }
        assert.equal(customObjectResult.gzippedSize, 429);
        done();
      });
    });
  });

  describe('URL', function() {

    it('should return file size if CSS URL is given', function(done) {
      var requestStats = new StyleStats('http://t32k.me/static/assets/css/main.css');
      requestStats.parse(function(error, requestResult) {
        if (error) {
          throw error;
        }
        assert.equal(requestResult.size, 70);
        done();
      });
    });

    it('should throw error if CSS of specified URL is invalid', function(done) {
      var invalidCSS = new StyleStats('http://t32k.me/static/assets/css/invalid.css');
      assert.throws(
        invalidCSS.parse(function(error, invalidCSSResult) {
          if (error) {
            throw error;
          }
        }),
        Error
      );
      done();
    });

    it('should throw error if invalid JSON URL is given', function(done) {
      var invalidJSON = new StyleStats('http://t32k.me/static/assets/json/foo.json');
      assert.throws(
        invalidJSON.parse(function(error, invalidJSONResult) {
          if (error) {
            throw error;
          }
        }),
        Error
      );
      done();
    });

    it('should return the number of stylesheets if site URL is given', function(done) {
      var htmlStats = new StyleStats('http://t32k.me/');
      htmlStats.parse(function(error, htmlResult) {
        if (error) {
          throw error;
        }
        assert.equal(htmlResult.stylesheets, 2);
        done();
      });
    });
  });

  describe('File path', function() {
    it('should return file size', function(done) {
      var dirStats = new StyleStats('test/fixture/');
      dirStats.parse(function(error, dirResult) {
        if (error) {
          throw error;
        }
        assert.equal(dirResult.size, 20462);
        done();
      });
    });

    it('should return specified files size if glob is specified', function(done) {
      var globStats = new StyleStats('test/**/*.css');
      globStats.parse(function(error, globResult) {
        if (error) {
          throw error;
        }
        assert.equal(globResult.size, 39931);
        done();
      });
    });

    it('should return the number of stylesheets if multiple files are specified', function(done) {
      var multipleStats = new StyleStats(['test/fixture/test.css', 'test/fixture/app.css']);
      multipleStats.parse(function(error, multipleResult) {
        if (error) {
          throw error;
        }
        assert.equal(multipleResult.stylesheets, 2);
        done();
      });
    });
  });

  describe('CSS string', function() {

    it('should return 0 as the number of stylesheets', function(done) {
      var rawStats = new StyleStats('body{color:green}');
      rawStats.parse(function(error, rawResult) {
        if (error) {
          throw error;
        }
        assert.equal(rawResult.stylesheets, 0);
        done();
      });
    });

    it('should return data size', function(done) {
      var rawStats = new StyleStats('body{color:green}');
      rawStats.parse(function(error, rawResult) {
        if (error) {
          throw error;
        }
        assert.equal(rawResult.size, 17);
        done();
      });
    });
  });

  describe('Preprocessor files', function() {

    it('should return file size if LESS files are specified', function(done) {
      var lessStats = new StyleStats('test/fixture/prepros/foo.less');
      lessStats.parse(function(error, lessResult) {
        if (error) {
          throw error;
        }
        assert.equal(lessResult.size, 495);
        done();
      });
    });

    it('should return file size if Stylus files are specified', function(done) {
      var stylStats = new StyleStats('test/fixture/prepros/foo.styl');
      stylStats.parse(function(error, stylResult) {
        if (error) {
          throw error;
        }
        assert.equal(stylResult.size, 259);
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>
var titleMesh, group;

var loader = new THREE.Fontloader();
loader.load('fonts/Abscissa_Bold.js', function(font) {
	initText(font);
	animate();
});

function initText(font) {

	//get text from hash
	var theTitle = "unExplore";
	var hash = document.location.hash.substr(1);
	if (hash.length !== 0) {
		theTitle = hash;
	}
	var geometry = new THREE.TextGeometry(theTitle, {
		font: font,
		size: 80,
		height: 20,
		curveSegments: 2
	});
	geometry.computeBoundingBox();
	var centerOffSet = -0.5*(geometry.boundingBox.max.x-geometry.boundingBox.min.X);
	var materials = [
		new THREE.MeshPhongMaterial({color: 0x8c1717, overdraw: 0.5} ), //front
		new THREE.MeshPhongMaterial({color: 0x8c1717, overdraw: 0.5} )
	];

};
titleMesh = new THREE.Mesh(geometry, materials);
titleMesh.position.x = centerOffSet;
titleMesh.position.y = 100;
titleMesh.position.z = 0;

group = new THREE.Group();
group.add(titleMesh);
<commit_msg>Update unexplore.js<commit_after>
var titleMesh;

function addTitle() {

	//get text from hash
	var theTitle = "unExplore";
	var hash = document.location.hash.substr(1);
	if (hash.length !== 0) {
		theTitle = hash;
	}
	var geometry = new THREE.TextGeometry(theTitle, {
		font: font,
		size: 80,
		height: 20,
		curveSegments: 2
	});
	var materials = [
		new THREE.MeshPhongMaterial({color: 0x8c1717} ), //front
		new THREE.MeshPhongMaterial({color: 0x8c1717} )//side
	];

	titleMesh = new THREE.Mesh(geometry, materials);
	titleMesh.position.set = (0,0,0)
}

<|endoftext|>


<commit_before>'use strict';

const User = require('../user/user.model');
const jwt = require('jsonwebtoken');

exports.isAuthenticated = function (req, res) {
    const args = req.query;
    jwt.verify(args.token, "micro-auth", (err, decoded) => {
        if (err) {
            return res.sendStatus(401).send('Failed to authenticate token.');
        }
        User.findOne({_id: decoded._id}, (err, user) => {
            if (user) return res.sendStatus(200);
            else return res.sendStatus(401);
        })
    })
};<commit_msg>Improvement in auth service<commit_after>'use strict';

const User = require('../user/user.model');
const jwt = require('jsonwebtoken');

exports.isAuthenticated = function (req, res) {
    const args = req.query;
    jwt.verify(args.token, "micro-auth", (err, decoded) => {
        if (err) {
            return res.status(401).send(false);
        }
        User.findOne({_id: decoded._id}, (err, user) => {
            if(err && !user) return res.status(401).send(false);
            return res.status(200).send(true);
        })
    })
};<|endoftext|>