<commit_before>"use strict";
var Fiber = require('./fibers');
var util = require('util');
module.exports = Future;
Function.prototype.future = function() {
	var fn = this;
	var ret = function() {
		return new FiberFuture(fn, this, arguments);
	};
	ret.toString = function() {
		return '<<Future '+ fn+ '.future()>>';
	};
	return ret;
};

Future.activeFutures = [];
var activeFutureCtorStack = [];

function addActiveFuture(future) {
	Future.activeFutures.push(future);
	activeFutureCtorStack.push(new Error().stack);
}

function deleteActiveFuture(future) {
	var index = Future.activeFutures.indexOf(future);
	if (index !== -1) {
		Future.activeFutures.splice(index, 1);
		activeFutureCtorStack.splice(index, 1);
	}
}

function Future() {
	addActiveFuture(this);
}

/**
 * Wrap a node-style async function to return a future in place of using a callback.
 */
Future.wrap = function(fn, idx) {
	idx = idx === undefined ? fn.length - 1 : idx;
	return function() {
		var args = Array.prototype.slice.call(arguments);
		if (args.length > idx) {
			throw new Error('function expects no more than '+ idx+ ' arguments');
		}
		var future = new Future;
		args[idx] = future.resolver();
		fn.apply(this, args);
		return future;
	};
};

/**
 * Creates a future returning the given result value.
 */
Future.fromResult = function(value) {
	var future = new Future();
	future.return(value);
	return future;
}

Future.assertNoFutureLeftBehind = function() {
	if (Future.activeFutures.length > 0) {
		var message = ["There are outstanding futures. Construction call stacks:"];
		for (var i = 0; i < Future.activeFutures.length; ++i) {
			message.push("#" + (i+1).toString());
			var stack = activeFutureCtorStack[i].split("\n");
			stack.shift();
			while (stack[0] && stack[0].indexOf("future.js") !== -1)
				stack.shift();
			message.push(stack.join("\n"));
		}
		throw new Error(message.join("\n"));
	}
}

function getFutures(args, removeResolved) {
	var futures = [];
	for (var ii = 0; ii < args.length; ++ii) {
		var arg = args[ii];
		if (arg instanceof Future) {
			// Ignore already resolved fibers
			if (removeResolved && arg.isResolved()) {
				continue;
			}
			futures.push(arg);
		} else if (arg instanceof Array) {
			for (var jj = 0; jj < arg.length; ++jj) {
				var aarg = arg[jj];
				if (aarg instanceof Future) {
					// Ignore already resolved fibers
					if (removeResolved && aarg.isResolved()) {
						continue;
					}
					futures.push(aarg);
				} else {
					throw new Error(aarg+ ' is not a future');
				}
			}
		} else {
			throw new Error(arg+ ' is not a future');
		}
	}
	return futures;
}

/**
 * Wait on a series of futures and then return. If the futures throw an exception this function
 * /won't/ throw it back. You can get the value of the future by calling get() on it directly. If
 * you want to wait on a single future you're better off calling future.wait() on the instance.
 */
Future.settle = function settle(/* ... */) {
	var futures = getFutures(arguments, true);

	// pull out a FiberFuture for reuse if possible
	var singleFiberFuture;
	for (var i = 0; i < futures.length; ++i) {
		var candidateFuture = futures[i];
		if (candidateFuture instanceof FiberFuture && !candidateFuture.started) {
			singleFiberFuture = candidateFuture;
			futures.splice(i, 1);
			break;
		}
	}

	// Resumes current fiber
	var fiber = Fiber.current;
	if (!fiber) {
		throw new Error('Can\'t wait without a fiber');
	}

	// Resolve all futures
	var pending = futures.length + (singleFiberFuture ? 1 : 0);
	function cb() {
		if (!--pending) {
			fiber.run();
		}
	}
	for (var ii = 0; ii < futures.length; ++ii) {
		futures[ii].resolve(cb, undefined, true);
	}

	// Reusing a fiber?
	if (singleFiberFuture) {
		singleFiberFuture.started = true;
		try {
			singleFiberFuture.return(
				singleFiberFuture.fn.apply(singleFiberFuture.context, singleFiberFuture.args));
		} catch(e) {
			singleFiberFuture.throw(e);
		}
		--pending;
	}

	// Yield this fiber
	if (pending) {
		Fiber.yield();
	}

	if (singleFiberFuture) {
		futures.push(singleFiberFuture);
	}
	return futures;
};

Future.wait = function wait() {
	Future.settle.apply(null, arguments)
	var futures = getFutures(arguments, false);
	var errors;

	for (var i = 0; i < futures.length; ++i) {
		var settled = futures[i];
		deleteActiveFuture(settled);
		if (settled.resolved && settled.error) {
			(errors || (errors = [])).push(settled.error);
		}
	}

	if (errors) {
		if (errors.length === 1) {
			throw errors[0];
		} else {
			var error = new Error();
			var message = ["Multiple exceptions were thrown:"];
			var stack = ["Multiple exceptions were thrown:"];
			for (var ei = 0; ei < errors.length; ++ei) {
				var err = errors[ei];
				message.push(err.message);
				stack.push(err.stack ? err.stack : err);
			}

			error.innerErrors = errors;
			error.message = message.join("\n");
			error.stack = stack.join("\n\n");

			throw error;
		}
	}
};

Future.prototype = {
	/**
	 * Return the value of this future. If the future hasn't resolved yet this will throw an error.
	 */
	get: function() {
		deleteActiveFuture(this);
		if (!this.resolved) {
			throw new Error('Future must resolve before value is ready');
		} else if (this.error) {
			// Link the stack traces up
			var stack = {}, error = this.error instanceof Object ? this.error : new Error(this.error);
			var longError = Object.create(error);
			Error.captureStackTrace(stack, Future.prototype.get);
			Object.defineProperty(longError, 'stack', {
				get: function() {
					var baseStack = error.stack;
					if (baseStack) {
						baseStack = baseStack.split('\n');
						return [baseStack[0]]
							.concat(stack.stack.split('\n').slice(1))
							.concat('    - - - - -')
							.concat(baseStack.slice(1))
							.join('\n');
					} else {
						return stack.stack;
					}
				},
				enumerable: true,
			});
			throw longError;
		} else {
			return this.value;
		}
	},

	/**
	 * Mark this future as returned. All pending callbacks will be invoked immediately.
	 */
	"return": function(value) {
		if (this.resolved) {
			throw new Error('Future resolved more than once');
		}
		this.value = value;
		this.resolved = true;

		var callbacks = this.callbacks;
		if (callbacks) {
			delete this.callbacks;
			for (var ii = 0; ii < callbacks.length; ++ii) {
				try {
					var ref = callbacks[ii];
					if (ref[1]) {
						ref[1](value);
					} else {
						ref[0](undefined, value);
					}
				} catch(ex) {
					// console.log('Resolve cb threw', String(ex.stack || ex.message || ex));
					process.nextTick(function() {
						throw(ex);
					});
				}
			}
		}
	},

	/**
	 * Throw from this future as returned. All pending callbacks will be invoked immediately.
	 */
	"throw": function(error) {
		if (this.resolved) {
			throw new Error('Future resolved more than once');
		} else if (!error) {
			throw new Error('Must throw non-empty error');
		}
		this.error = error;
		this.resolved = true;

		var callbacks = this.callbacks;
		if (callbacks) {
			delete this.callbacks;
			for (var ii = 0; ii < callbacks.length; ++ii) {
				try {
					var ref = callbacks[ii];
					if (ref[1]) {
						ref[0].throw(error);
					} else {
						ref[0](error);
					}
				} catch(ex) {
					// console.log('Resolve cb threw', String(ex.stack || ex.message || ex));
					process.nextTick(function() {
						throw(ex);
					});
				}
			}
		}
	},

	/**
	 * "detach" this future. Basically this is useful if you want to run a task in a future, you
	 * aren't interested in its return value, but if it throws you don't want the exception to be
	 * lost. If this fiber throws, an exception will be thrown to the event loop and node will
	 * probably fall down.
	 */
	detach: function() {
		this.resolve(function(err) {
			if (err) {
				throw err;
			}
		});
	},

	/**
	 * Returns whether or not this future has resolved yet.
	 */
	isResolved: function() {
		return this.resolved === true;
	},

	/**
	 * Returns a node-style function which will mark this future as resolved when called.
	 */
	resolver: function() {
		return function(err, val) {
			if (err) {
				this.throw(err);
			} else {
				this.return(val);
			}
		}.bind(this);
	},

	/**
	 * Waits for this future to resolve and then invokes a callback.
	 *
	 * If two arguments are passed, the first argument is a future which will be thrown to in the case
	 * of error, and the second is a function(val){} callback.
	 *
	 * If only one argument is passed it is a standard function(err, val){} callback.
	 */
	resolve: function(arg1, arg2, noDeactivate) {
		if (!noDeactivate) {
			deleteActiveFuture(this);
		}

		if (this.resolved) {
			if (arg2) {
				if (this.error) {
					arg1.throw(this.error);
				} else {
					arg2(this.value);
				}
			} else {
				arg1(this.error, this.value);
			}
		} else {
			(this.callbacks = this.callbacks || []).push([arg1, arg2]);
		}
		return this;
	},

	/**
	 * Resolve only in the case of success
	 */
	resolveSuccess: function(cb) {
		this.resolve(function(err, val) {
			if (err) {
				return;
			}
			cb(val);
		});
		return this;
	},

	/**
	 * Propogate results to another future.
	 */
	proxy: function(future) {
		this.resolve(function(err, val) {
			if (err) {
				future.throw(err);
			} else {
				future.return(val);
			}
		});
	},

	/**
	 * Propogate only errors to an another future or array of futures.
	 */
	proxyErrors: function(futures) {
		this.resolve(function(err) {
			if (!err) {
				return;
			}
			if (futures instanceof Array) {
				for (var ii = 0; ii < futures.length; ++ii) {
					futures[ii].throw(err);
				}
			} else {
				futures.throw(err);
			}
		});
		return this;
	},

	/**
	 * Waits for the future to settle. If the future throws an error, then wait() will rethrow that error.
	 */
	wait: function() {
		if (this.isResolved()) {
			return this.get();
		}
		Future.settle(this);
		return this.get();
	},
};

/**
 * A function call which loads inside a fiber automatically and returns a future.
 */
function FiberFuture(fn, context, args) {
	this.fn = fn;
	this.context = context;
	this.args = args;
	this.started = false;
	addActiveFuture(this);
	var that = this;
	process.nextTick(function() {
		if (!that.started) {
			that.started = true;
			Fiber(function() {
				try {
					that.return(fn.apply(context, args));
				} catch(e) {
					that.throw(e);
				}
			}).run();
		}
	});
}
util.inherits(FiberFuture, Future);
<commit_msg>assert no FiberFuture's created<commit_after>"use strict";
var Fiber = require('./fibers');
var util = require('util');
module.exports = Future;
Function.prototype.future = function() {
	var fn = this;
	var ret = function() {
		return new FiberFuture(fn, this, arguments);
	};
	ret.toString = function() {
		return '<<Future '+ fn+ '.future()>>';
	};
	return ret;
};

Future.activeFutures = [];
var activeFutureCtorStack = [];

function addActiveFuture(future) {
	Future.activeFutures.push(future);
	activeFutureCtorStack.push(new Error().stack);
}

function deleteActiveFuture(future) {
	var index = Future.activeFutures.indexOf(future);
	if (index !== -1) {
		Future.activeFutures.splice(index, 1);
		activeFutureCtorStack.splice(index, 1);
	}
}

function Future() {
	addActiveFuture(this);
}

/**
 * Wrap a node-style async function to return a future in place of using a callback.
 */
Future.wrap = function(fn, idx) {
	idx = idx === undefined ? fn.length - 1 : idx;
	return function() {
		var args = Array.prototype.slice.call(arguments);
		if (args.length > idx) {
			throw new Error('function expects no more than '+ idx+ ' arguments');
		}
		var future = new Future;
		args[idx] = future.resolver();
		fn.apply(this, args);
		return future;
	};
};

/**
 * Creates a future returning the given result value.
 */
Future.fromResult = function(value) {
	var future = new Future();
	future.return(value);
	return future;
}

Future.assertNoFutureLeftBehind = function() {
	if (Future.activeFutures.length > 0) {
		var message = ["There are outstanding futures. Construction call stacks:"];
		for (var i = 0; i < Future.activeFutures.length; ++i) {
			message.push("#" + (i+1).toString());
			var stack = activeFutureCtorStack[i].split("\n");
			stack.shift();
			while (stack[0] && stack[0].indexOf("future.js") !== -1)
				stack.shift();
			message.push(stack.join("\n"));
		}
		throw new Error(message.join("\n"));
	}
}

function getFutures(args, removeResolved) {
	var futures = [];
	for (var ii = 0; ii < args.length; ++ii) {
		var arg = args[ii];
		if (arg instanceof Future) {
			// Ignore already resolved fibers
			if (removeResolved && arg.isResolved()) {
				continue;
			}
			futures.push(arg);
		} else if (arg instanceof Array) {
			for (var jj = 0; jj < arg.length; ++jj) {
				var aarg = arg[jj];
				if (aarg instanceof Future) {
					// Ignore already resolved fibers
					if (removeResolved && aarg.isResolved()) {
						continue;
					}
					futures.push(aarg);
				} else {
					throw new Error(aarg+ ' is not a future');
				}
			}
		} else {
			throw new Error(arg+ ' is not a future');
		}
	}
	return futures;
}

/**
 * Wait on a series of futures and then return. If the futures throw an exception this function
 * /won't/ throw it back. You can get the value of the future by calling get() on it directly. If
 * you want to wait on a single future you're better off calling future.wait() on the instance.
 */
Future.settle = function settle(/* ... */) {
	var futures = getFutures(arguments, true);

	// pull out a FiberFuture for reuse if possible
	var singleFiberFuture;
	for (var i = 0; i < futures.length; ++i) {
		var candidateFuture = futures[i];
		if (candidateFuture instanceof FiberFuture && !candidateFuture.started) {
			singleFiberFuture = candidateFuture;
			futures.splice(i, 1);
			break;
		}
	}

	// Resumes current fiber
	var fiber = Fiber.current;
	if (!fiber) {
		throw new Error('Can\'t wait without a fiber');
	}

	// Resolve all futures
	var pending = futures.length + (singleFiberFuture ? 1 : 0);
	function cb() {
		if (!--pending) {
			fiber.run();
		}
	}
	for (var ii = 0; ii < futures.length; ++ii) {
		futures[ii].resolve(cb, undefined, true);
	}

	// Reusing a fiber?
	if (singleFiberFuture) {
		singleFiberFuture.started = true;
		try {
			singleFiberFuture.return(
				singleFiberFuture.fn.apply(singleFiberFuture.context, singleFiberFuture.args));
		} catch(e) {
			singleFiberFuture.throw(e);
		}
		--pending;
	}

	// Yield this fiber
	if (pending) {
		Fiber.yield();
	}

	if (singleFiberFuture) {
		futures.push(singleFiberFuture);
	}
	return futures;
};

Future.wait = function wait() {
	Future.settle.apply(null, arguments)
	var futures = getFutures(arguments, false);
	var errors;

	for (var i = 0; i < futures.length; ++i) {
		var settled = futures[i];
		deleteActiveFuture(settled);
		if (settled.resolved && settled.error) {
			(errors || (errors = [])).push(settled.error);
		}
	}

	if (errors) {
		if (errors.length === 1) {
			throw errors[0];
		} else {
			var error = new Error();
			var message = ["Multiple exceptions were thrown:"];
			var stack = ["Multiple exceptions were thrown:"];
			for (var ei = 0; ei < errors.length; ++ei) {
				var err = errors[ei];
				message.push(err.message);
				stack.push(err.stack ? err.stack : err);
			}

			error.innerErrors = errors;
			error.message = message.join("\n");
			error.stack = stack.join("\n\n");

			throw error;
		}
	}
};

Future.prototype = {
	/**
	 * Return the value of this future. If the future hasn't resolved yet this will throw an error.
	 */
	get: function() {
		deleteActiveFuture(this);
		if (!this.resolved) {
			throw new Error('Future must resolve before value is ready');
		} else if (this.error) {
			// Link the stack traces up
			var stack = {}, error = this.error instanceof Object ? this.error : new Error(this.error);
			var longError = Object.create(error);
			Error.captureStackTrace(stack, Future.prototype.get);
			Object.defineProperty(longError, 'stack', {
				get: function() {
					var baseStack = error.stack;
					if (baseStack) {
						baseStack = baseStack.split('\n');
						return [baseStack[0]]
							.concat(stack.stack.split('\n').slice(1))
							.concat('    - - - - -')
							.concat(baseStack.slice(1))
							.join('\n');
					} else {
						return stack.stack;
					}
				},
				enumerable: true,
			});
			throw longError;
		} else {
			return this.value;
		}
	},

	/**
	 * Mark this future as returned. All pending callbacks will be invoked immediately.
	 */
	"return": function(value) {
		if (this.resolved) {
			throw new Error('Future resolved more than once');
		}
		this.value = value;
		this.resolved = true;

		var callbacks = this.callbacks;
		if (callbacks) {
			delete this.callbacks;
			for (var ii = 0; ii < callbacks.length; ++ii) {
				try {
					var ref = callbacks[ii];
					if (ref[1]) {
						ref[1](value);
					} else {
						ref[0](undefined, value);
					}
				} catch(ex) {
					// console.log('Resolve cb threw', String(ex.stack || ex.message || ex));
					process.nextTick(function() {
						throw(ex);
					});
				}
			}
		}
	},

	/**
	 * Throw from this future as returned. All pending callbacks will be invoked immediately.
	 */
	"throw": function(error) {
		if (this.resolved) {
			throw new Error('Future resolved more than once');
		} else if (!error) {
			throw new Error('Must throw non-empty error');
		}
		this.error = error;
		this.resolved = true;

		var callbacks = this.callbacks;
		if (callbacks) {
			delete this.callbacks;
			for (var ii = 0; ii < callbacks.length; ++ii) {
				try {
					var ref = callbacks[ii];
					if (ref[1]) {
						ref[0].throw(error);
					} else {
						ref[0](error);
					}
				} catch(ex) {
					// console.log('Resolve cb threw', String(ex.stack || ex.message || ex));
					process.nextTick(function() {
						throw(ex);
					});
				}
			}
		}
	},

	/**
	 * "detach" this future. Basically this is useful if you want to run a task in a future, you
	 * aren't interested in its return value, but if it throws you don't want the exception to be
	 * lost. If this fiber throws, an exception will be thrown to the event loop and node will
	 * probably fall down.
	 */
	detach: function() {
		this.resolve(function(err) {
			if (err) {
				throw err;
			}
		});
	},

	/**
	 * Returns whether or not this future has resolved yet.
	 */
	isResolved: function() {
		return this.resolved === true;
	},

	/**
	 * Returns a node-style function which will mark this future as resolved when called.
	 */
	resolver: function() {
		return function(err, val) {
			if (err) {
				this.throw(err);
			} else {
				this.return(val);
			}
		}.bind(this);
	},

	/**
	 * Waits for this future to resolve and then invokes a callback.
	 *
	 * If two arguments are passed, the first argument is a future which will be thrown to in the case
	 * of error, and the second is a function(val){} callback.
	 *
	 * If only one argument is passed it is a standard function(err, val){} callback.
	 */
	resolve: function(arg1, arg2, noDeactivate) {
		if (!noDeactivate) {
			deleteActiveFuture(this);
		}

		if (this.resolved) {
			if (arg2) {
				if (this.error) {
					arg1.throw(this.error);
				} else {
					arg2(this.value);
				}
			} else {
				arg1(this.error, this.value);
			}
		} else {
			(this.callbacks = this.callbacks || []).push([arg1, arg2]);
		}
		return this;
	},

	/**
	 * Resolve only in the case of success
	 */
	resolveSuccess: function(cb) {
		this.resolve(function(err, val) {
			if (err) {
				return;
			}
			cb(val);
		});
		return this;
	},

	/**
	 * Propogate results to another future.
	 */
	proxy: function(future) {
		this.resolve(function(err, val) {
			if (err) {
				future.throw(err);
			} else {
				future.return(val);
			}
		});
	},

	/**
	 * Propogate only errors to an another future or array of futures.
	 */
	proxyErrors: function(futures) {
		this.resolve(function(err) {
			if (!err) {
				return;
			}
			if (futures instanceof Array) {
				for (var ii = 0; ii < futures.length; ++ii) {
					futures[ii].throw(err);
				}
			} else {
				futures.throw(err);
			}
		});
		return this;
	},

	/**
	 * Waits for the future to settle. If the future throws an error, then wait() will rethrow that error.
	 */
	wait: function() {
		if (this.isResolved()) {
			return this.get();
		}
		Future.settle(this);
		return this.get();
	},
};

/**
 * A function call which loads inside a fiber automatically and returns a future.
 */
function FiberFuture(fn, context, args) {
	this.fn = fn;
	this.context = context;
	this.args = args;
	this.started = false;
	addActiveFuture(this);
	var that = this;
	process.nextTick(function() {
		if (!that.started) {
			that.started = true;
			console.log("WARNING: Non-primary fiber starting. Function: %s", fn.toString());
			Fiber(function() {
				try {
					that.return(fn.apply(context, args));
				} catch(e) {
					that.throw(e);
				}
			}).run();
		}
	});
}
util.inherits(FiberFuture, Future);
<|endoftext|>


<commit_before>import { Inject, Parameter } from '../../decorators';
const AbstractRecursivePass = Jymfony.Component.DependencyInjection.Compiler.AbstractRecursivePass;
const Definition = Jymfony.Component.DependencyInjection.Definition;
const DIParameter = Jymfony.Component.DependencyInjection.Parameter;
const Reference = Jymfony.Component.DependencyInjection.Reference;

/**
 * @memberOf Jymfony.Component.DependencyInjection.Compiler
 */
export default class ResolveInjectDecoratorPass extends AbstractRecursivePass {
    /**
     * @inheritdoc
     */
    _processValue(value, isRoot = false) {
        if (! (value instanceof Definition)) {
            return super._processValue(value, isRoot);
        }

        const class_ = value.getClass();
        if (! ReflectionClass.exists(class_)) {
            return;
        }

        const reflClass = new ReflectionClass(class_);
        for (const field of reflClass.fields) {
            const reflField = reflClass.getField(field);
            for (const [ , annotation ] of reflField.metadata) {
                if (annotation instanceof Inject) {
                    value.addProperty(field, new Reference(annotation.serviceId));
                } else if (annotation instanceof Parameter) {
                    value.addProperty(field, new DIParameter(annotation.parameterName));
                }
            }
        }
    }
}
<commit_msg>[Autoloader] add support for optional imports (proprietary extension)<commit_after>import { Inject, Parameter } from '../../decorators' optional;
const AbstractRecursivePass = Jymfony.Component.DependencyInjection.Compiler.AbstractRecursivePass;
const Definition = Jymfony.Component.DependencyInjection.Definition;
const DIParameter = Jymfony.Component.DependencyInjection.Parameter;
const Reference = Jymfony.Component.DependencyInjection.Reference;

/**
 * @memberOf Jymfony.Component.DependencyInjection.Compiler
 */
export default class ResolveInjectDecoratorPass extends AbstractRecursivePass {
    process(container) {
        if (undefined === Inject || undefined === Parameter) {
            // @jymfony/decorators is not installed.
            return;
        }

        super.process(container);
    }

    /**
     * @inheritdoc
     */
    _processValue(value, isRoot = false) {
        if (! (value instanceof Definition)) {
            return super._processValue(value, isRoot);
        }

        const class_ = value.getClass();
        if (! ReflectionClass.exists(class_)) {
            return;
        }

        const reflClass = new ReflectionClass(class_);
        for (const field of reflClass.fields) {
            const reflField = reflClass.getField(field);
            for (const [ , annotation ] of reflField.metadata) {
                if (annotation instanceof Inject) {
                    value.addProperty(field, new Reference(annotation.serviceId));
                } else if (annotation instanceof Parameter) {
                    value.addProperty(field, new DIParameter(annotation.parameterName));
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>gng with nback<commit_after><|endoftext|>


<commit_before>/* Directives */
angular.module('myApp.directives')
        .directive('ngVisible', function() {
            return function(scope, elem, attr) {
                scope.$watch(attr.ngVisible, function(value) {
                    elem.css('visibility', value ? 'visible' : 'hidden');
                });
            };
        })
        .directive('ngKeyup', function() {
            return function(scope, elem, attrs) {
                elem.bind('keyup', function() {
                    scope.$apply(attrs.ngKeyup);
                });
            };
        })
        .directive('gimsLinkNew', function($routeParams) {
            return {
                restrict: "E",
                replace: true,
                scope: {
                    content: '='
                },
                link: function(element, attrs) {

                    var returnUrl = '';
                    if (attrs.origin) {
                        returnUrl = sprintf('?returnUrl=/admin/%s/edit/%s&%s=%s',
                                attrs.origin,
                                $routeParams.id,
                                attrs.origin,
                                $routeParams.id
                                );
                    }

                    var html = sprintf(' new %s',
                            attrs.target,
                            returnUrl,
                            attrs.target
                            );

                    element.html(html).show();
                }
            };
        })
        .directive('gimsFocus', function($timeout) {
            return {
                link: function(element) {
                    $timeout(function() {
                        element.focus();
                    });
                }
            };
        });
<commit_msg>Correct gimsLinkNew directive<commit_after>/* Directives */
angular.module('myApp.directives')
        .directive('ngVisible', function() {
            return function(scope, elem, attr) {
                scope.$watch(attr.ngVisible, function(value) {
                    elem.css('visibility', value ? 'visible' : 'hidden');
                });
            };
        })
        .directive('ngKeyup', function() {
            return function(scope, elem, attrs) {
                elem.bind('keyup', function() {
                    scope.$apply(attrs.ngKeyup);
                });
            };
        })
        .directive('gimsLinkNew', function($routeParams) {
            return {
                restrict: "E",
                replace: true,
                scope: {
                    content: '='
                },
                link: function(scope, element, attrs) {

                    var returnUrl = '';
                    if (attrs.origin) {
                        returnUrl = sprintf('?returnUrl=/admin/%s/edit/%s&%s=%s',
                                attrs.origin,
                                $routeParams.id,
                                attrs.origin,
                                $routeParams.id
                                );
                    }

                    var html = sprintf(' new %s',
                            attrs.target,
                            returnUrl,
                            attrs.target
                            );

                    element.html(html).show();
                }
            };
        })
        .directive('gimsFocus', function($timeout) {
            return {
                link: function(element) {
                    $timeout(function() {
                        element.focus();
                    });
                }
            };
        });
<|endoftext|>


<commit_before>'use strict';

/**
 * Controller for the BreakOut-Member-Page.
 */

const co = require('co');
const _ = require('lodash');
const fs = require('fs');
const logger = require('../../services/logger');

const api = require('../../services/api-proxy');

let team = {};

/**
 * Sends the occurred error back to the client, and logs it to the bunyan global logger.
 * @param res
 * @param errMsg
 * @param err
 * @returns {*}
 */
const sendErr = (res, errMsg, err) => {

  if (err) logger.error(errMsg, err);
  else logger.error(errMsg);

  res.status(500).send({ error: errMsg });
};

team.getTeamByUrl = (teamId, token) => co(function*() {
  let tempTeam = yield api.team.get(teamId);

  let events = yield api.event.all();
  tempTeam.event = events.filter((event) => event.id === tempTeam.event).pop();

  tempTeam.max = {};
  tempTeam.max.distance = 0;
  tempTeam.max.donations = 0;

  //ONLY VIEW FULLY PAID TEAMS
  if (!tempTeam.hasFullyPaid) return tempTeam;

  let allSponsors = yield api.sponsoring.getByTeam(tempTeam.event.id, tempTeam.id);
  allSponsors = allSponsors.filter(s => (s.status === 'ACCEPTED' || s.status === 'PAYED') && !s.sponsorIsHidden);
  tempTeam.sponsors = yield allSponsors.map(sponsor => {
    if (sponsor.userId) return api.user.get(sponsor.userId);
    return sponsor.unregisteredSponsor;
  });

  let allChallenges = yield api.challenge.getByTeam(tempTeam.event.id, tempTeam.id);
  tempTeam.challenges = allChallenges.filter(s => s.status === 'ACCEPTED' || s.status === 'WITH_PROOF' || s.status === 'PROOF_ACCEPTED');
  tempTeam.openChallenges = allChallenges.filter(s => s.status === 'ACCEPTED');

  tempTeam.postings = yield api.team.getPostings(token,teamId, 0);

  let locations = _.map(
    _.sortBy(
      _.filter(tempTeam.postings, p => p.postingLocation && p.postingLocation.duringEvent),
      p => p.date),
    p => _.pick(p.postingLocation, ['latitude', 'longitude'])
  );

  const distances = yield [
    api.team.getDistance(teamId),
    api.team.getDonations(teamId)
  ];

  tempTeam.max.distance = distances[0].distance;
  tempTeam.max.donations = distances[1].fullSum;

  tempTeam.mapData = [{
    id: teamId,
    name: tempTeam.name,
    event: tempTeam.event,
    locations: locations,
    members: []
  }];

  tempTeam.members.forEach((m, i) => {
    tempTeam.mapData[0].members[i] = {
      firstname: m.firstname
    };
  });

  return tempTeam;
}).catch((ex) => {
  throw ex;
});

team.getAll = (sort) => co(function*() {

  const events = yield api.event.all();

  let teamsByEvent = yield events.map((e) => api.team.getAllByEvent(e.id));

  let allTeams = teamsByEvent.map((teams, index) => {
    return teams.map(team => {
      team.city = events[index].city;
      team.event = events[index].id;
      return team;
    });
  });

  allTeams = _.flatten(allTeams);
  allTeams = allTeams.filter(t => t.hasFullyPaid && t.id !== 1);
  if (sort) {
    allTeams = _.sortBy(allTeams, t => t[sort]);
  } else {
    allTeams = _.shuffle(allTeams);
  }

  return allTeams;

}).catch((ex) => {
  throw ex;
});

team.createPost = (req, res, next) => co(function*() {

  let mediaType = req.body.mediaType === '' ? null : [req.body.mediaType];

  let post = yield api.posting.createPosting(
    req.user,
    req.body.postText,
    mediaType,
    req.body.latitude,
    req.body.longitude);

  if (req.body.mediaType !== '' && req.file) {
    yield post.media.map(m => api.uploadPicture(req.file, m));
  }

  if (req.body.challenge) {
    yield api.challenge.proof(req.user, req.body.challenge, post.id);
  }
  res.sendStatus(200);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.createLike = (req, res, next) => co(function*() {

  yield api.posting.createLike(req.user, req.body.postingId);
  res.sendStatus(200);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.getLikes = (req, res, next) => co(function*() {

  let likes = yield api.posting.getLikesForPosting(req.params.postingId);

  res.send(likes);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.createComment = (req, res, next) => co(function*() {
  if (req.body.text && req.body.text !== '') {
    yield api.posting.createComment(req.user, req.body.id, req.body.text);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.deletePosting = (req, res, next) => co(function*() {
  if (req.params.postingId && req.params.postingId !== '') {
    yield api.admin.deletePosting(req.user, req.params.postingId);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  throw ex;
});

team.deleteMedia = (req, res, next) => co(function*() {
  if (req.params.mediaId && req.params.mediaId !== '') {
    yield api.admin.deleteMedia(req.user, req.params.mediaId);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  throw ex;
});

team.deleteComment = (req, res, next) => co(function*() {
  if (req.params.commentId && req.params.commentId !== '') {
    yield api.admin.deleteComment(req.user, req.params.commentId);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  throw ex;
});

team.isAuth = (req, res) => {
  if (req.isAuthenticated()) return res.sendStatus(200);
  return res.sendStatus(401);
};

module.exports = team;<commit_msg>team page fix, show fixed values for donation & distance<commit_after>'use strict';

/**
 * Controller for the BreakOut-Member-Page.
 */

const co = require('co');
const _ = require('lodash');
const fs = require('fs');
const logger = require('../../services/logger');

const api = require('../../services/api-proxy');

let team = {};

/**
 * Sends the occurred error back to the client, and logs it to the bunyan global logger.
 * @param res
 * @param errMsg
 * @param err
 * @returns {*}
 */
const sendErr = (res, errMsg, err) => {

  if (err) logger.error(errMsg, err);
  else logger.error(errMsg);

  res.status(500).send({ error: errMsg });
};

team.getTeamByUrl = (teamId, token) => co(function*() {
  let tempTeam = yield api.team.get(teamId);

  let events = yield api.event.all();
  tempTeam.event = events.filter((event) => event.id === tempTeam.event).pop();

  tempTeam.max = {};
  tempTeam.max.distance = 0;
  tempTeam.max.donations = 0;

  //ONLY VIEW FULLY PAID TEAMS
  if (!tempTeam.hasFullyPaid) return tempTeam;

  let allSponsors = yield api.sponsoring.getByTeam(tempTeam.event.id, tempTeam.id);
  allSponsors = allSponsors.filter(s => (s.status === 'ACCEPTED' || s.status === 'PAYED') && !s.sponsorIsHidden);
  tempTeam.sponsors = yield allSponsors.map(sponsor => {
    if (sponsor.userId) return api.user.get(sponsor.userId);
    return sponsor.unregisteredSponsor;
  });

  let allChallenges = yield api.challenge.getByTeam(tempTeam.event.id, tempTeam.id);
  tempTeam.challenges = allChallenges.filter(s => s.status === 'ACCEPTED' || s.status === 'WITH_PROOF' || s.status === 'PROOF_ACCEPTED');
  tempTeam.openChallenges = allChallenges.filter(s => s.status === 'ACCEPTED');

  tempTeam.postings = yield api.team.getPostings(token,teamId, 0);

  let locations = _.map(
    _.sortBy(
      _.filter(tempTeam.postings, p => p.postingLocation && p.postingLocation.duringEvent),
      p => p.date),
    p => _.pick(p.postingLocation, ['latitude', 'longitude'])
  );

  const distances = yield [
    api.team.getDistance(teamId),
    api.team.getDonations(teamId)
  ];

  tempTeam.max.distance = distances[0].distance.toFixed(0);
  tempTeam.max.donations = distances[1].fullSum.toFixed(2);

  tempTeam.mapData = [{
    id: teamId,
    name: tempTeam.name,
    event: tempTeam.event,
    locations: locations,
    members: []
  }];

  tempTeam.members.forEach((m, i) => {
    tempTeam.mapData[0].members[i] = {
      firstname: m.firstname
    };
  });

  return tempTeam;
}).catch((ex) => {
  throw ex;
});

team.getAll = (sort) => co(function*() {

  const events = yield api.event.all();

  let teamsByEvent = yield events.map((e) => api.team.getAllByEvent(e.id));

  let allTeams = teamsByEvent.map((teams, index) => {
    return teams.map(team => {
      team.city = events[index].city;
      team.event = events[index].id;
      return team;
    });
  });

  allTeams = _.flatten(allTeams);
  allTeams = allTeams.filter(t => t.hasFullyPaid && t.id !== 1);
  if (sort) {
    allTeams = _.sortBy(allTeams, t => t[sort]);
  } else {
    allTeams = _.shuffle(allTeams);
  }

  return allTeams;

}).catch((ex) => {
  throw ex;
});

team.createPost = (req, res, next) => co(function*() {

  let mediaType = req.body.mediaType === '' ? null : [req.body.mediaType];

  let post = yield api.posting.createPosting(
    req.user,
    req.body.postText,
    mediaType,
    req.body.latitude,
    req.body.longitude);

  if (req.body.mediaType !== '' && req.file) {
    yield post.media.map(m => api.uploadPicture(req.file, m));
  }

  if (req.body.challenge) {
    yield api.challenge.proof(req.user, req.body.challenge, post.id);
  }
  res.sendStatus(200);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.createLike = (req, res, next) => co(function*() {

  yield api.posting.createLike(req.user, req.body.postingId);
  res.sendStatus(200);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.getLikes = (req, res, next) => co(function*() {

  let likes = yield api.posting.getLikesForPosting(req.params.postingId);

  res.send(likes);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.createComment = (req, res, next) => co(function*() {
  if (req.body.text && req.body.text !== '') {
    yield api.posting.createComment(req.user, req.body.id, req.body.text);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  sendErr(res, ex.message, ex);
});

team.deletePosting = (req, res, next) => co(function*() {
  if (req.params.postingId && req.params.postingId !== '') {
    yield api.admin.deletePosting(req.user, req.params.postingId);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  throw ex;
});

team.deleteMedia = (req, res, next) => co(function*() {
  if (req.params.mediaId && req.params.mediaId !== '') {
    yield api.admin.deleteMedia(req.user, req.params.mediaId);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  throw ex;
});

team.deleteComment = (req, res, next) => co(function*() {
  if (req.params.commentId && req.params.commentId !== '') {
    yield api.admin.deleteComment(req.user, req.params.commentId);
    return res.sendStatus(200);
  }
  return res.sendStatus(500);

}).catch((ex) => {
  throw ex;
});

team.isAuth = (req, res) => {
  if (req.isAuthenticated()) return res.sendStatus(200);
  return res.sendStatus(401);
};

module.exports = team;<|endoftext|>


<commit_before>describe('SpiesController using Bard', function () {

});<commit_msg>Testing a controller using bard.js<commit_after>describe('SpiesController using Bard', function () {

	var controller;

	beforeEach(function () {

		bard.appModule('testingAngular.controllers')
		bard.inject('$controller');

		controller = $controller("SpiesController");
	});

	describe('isStaff', function () {

		beforeEach(function () {

			bard.inject('user');
		});

		it('should return true if staff', function () {

			spyOn(user, 'getUserType').and.returnValue('Staff');

			var result = controller.isStaff();

			expect(result).toBeTruthy();
		});

		it('should return false if not staff', function () {

			spyOn(user, 'getUserType').and.returnValue('Not staff');

			var result = controller.isStaff();

			expect(result).toBeFalsy();
		});
	});
});<|endoftext|>


<commit_before><commit_msg>Delete messages_controller.js<commit_after><|endoftext|>


<commit_before>/* eslint-disable no-loop-func */
const path = require('path');
const liveServer = require('live-server');
const stringSimilarity = require('string-similarity');

const spinner = require('ora')();

const clientPath = path.resolve(__dirname, '../../client');
require('@babel/polyfill');
require('@babel/register')({
  root: clientPath,
  babelrc: false,
  presets: ['@babel/preset-env'],
  plugins: ['dynamic-import-node'],
  ignore: [/node_modules/],
  only: [clientPath]
});

const createPseudoWorker = require('./utils/pseudo-worker');
const {
  default: createWorker
} = require('../../client/src/templates/Challenges/utils/worker-executor');

const { assert, AssertionError } = require('chai');
const Mocha = require('mocha');
const { flatten } = require('lodash');

const jsdom = require('jsdom');

const dom = new jsdom.JSDOM('');
global.document = dom.window.document;

const vm = require('vm');

const puppeteer = require('puppeteer');

const { getChallengesForLang, getMetaForBlock } = require('../getChallenges');

const MongoIds = require('./utils/mongoIds');
const ChallengeTitles = require('./utils/challengeTitles');
const { challengeSchemaValidator } = require('../schema/challengeSchema');
const {
  challengeTypes,
  helpCategory
} = require('../../client/utils/challengeTypes');

const { dasherize } = require('../../utils/slugs');

const { testedLang } = require('../utils');

const {
  buildDOMChallenge,
  buildJSChallenge
} = require('../../client/src/templates/Challenges/utils/build');

const { createPoly } = require('../../utils/polyvinyl');

const testEvaluator = require('../../client/config/test-evaluator').filename;

const oldRunnerFail = Mocha.Runner.prototype.fail;
Mocha.Runner.prototype.fail = function(test, err) {
  if (err instanceof AssertionError) {
    const errMessage = String(err.message || '');
    const assertIndex = errMessage.indexOf(': expected');
    if (assertIndex !== -1) {
      err.message = errMessage.slice(0, assertIndex);
    }
    // Don't show stacktrace for assertion errors.
    if (err.stack) {
      delete err.stack;
    }
  }
  return oldRunnerFail.call(this, test, err);
};

async function newPageContext(browser) {
  const page = await browser.newPage();
  // it's needed for workers as context.
  await page.goto('http://127.0.0.1:8080/index.html');
  return page;
}

spinner.start();
spinner.text = 'Populate tests.';

let browser;
let page;

setup()
  .then(runTests)
  .catch(err => {
    cleanup();
    // setting the error code because node does not (yet) exit with a non-zero
    // code on unhandled exceptions.
    process.exitCode = 1;
    throw err;
  });

async function setup() {
  if (process.env.npm_config_superblock && process.env.npm_config_block) {
    throw new Error(`Please do not use both a block and superblock as input.`);
  }

  // liveServer starts synchronously
  liveServer.start({
    host: '127.0.0.1',
    port: '8080',
    root: path.resolve(__dirname, 'stubs'),
    mount: [['/js', path.join(clientPath, 'static/js')]],
    open: false,
    logLevel: 0
  });
  browser = await puppeteer.launch({
    args: [
      // Required for Docker version of Puppeteer
      '--no-sandbox',
      '--disable-setuid-sandbox',
      // This will write shared memory files into /tmp instead of /dev/shm,
      // because Docker’s default for /dev/shm is 64MB
      '--disable-dev-shm-usage'
      // dumpio: true
    ]
  });
  global.Worker = createPseudoWorker(await newPageContext(browser));
  page = await newPageContext(browser);
  await page.setViewport({ width: 300, height: 150 });

  const lang = testedLang();

  let challenges = await getChallenges(lang);

  // the next few statements create a list of all blocks and superblocks
  // as they appear in the list of challenges
  const blocks = challenges.map(({ block }) => block);
  const superBlocks = challenges.map(({ superBlock }) => superBlock);
  const targetBlockStrings = [...new Set(blocks)];
  const targetSuperBlockStrings = [...new Set(superBlocks)];

  // the next few statements will filter challenges based on command variables
  if (process.env.npm_config_superblock) {
    const filter = stringSimilarity.findBestMatch(
      process.env.npm_config_superblock,
      targetSuperBlockStrings
    ).bestMatch.target;

    console.log(`\nsuperBlock being tested: ${filter}`);
    challenges = challenges.filter(
      challenge => challenge.superBlock === filter
    );

    if (!challenges.length) {
      throw new Error(`No challenges found with superBlock "${filter}"`);
    }
  }

  if (process.env.npm_config_block) {
    const filter = stringSimilarity.findBestMatch(
      process.env.npm_config_block,
      targetBlockStrings
    ).bestMatch.target;

    console.log(`\nblock being tested: ${filter}`);
    challenges = challenges.filter(challenge => challenge.block === filter);

    if (!challenges.length) {
      throw new Error(`No challenges found with block "${filter}"`);
    }
  }

  const meta = {};
  for (const challenge of challenges) {
    const dashedBlockName = dasherize(challenge.block);
    if (!meta[dashedBlockName]) {
      meta[dashedBlockName] = (await getMetaForBlock(
        dashedBlockName
      )).challengeOrder;
    }
  }
  return {
    meta,
    challenges,
    lang
  };
}

// cleanup calls some async functions, but it's the last thing that happens, so
// no need to await anything.
function cleanup() {
  if (browser) {
    browser.close();
  }
  liveServer.shutdown();
  spinner.stop();
}

function runTests(challengeData) {
  // rethrow unhandled rejections to make sure the tests exit with -1
  process.on('unhandledRejection', err => {
    throw err;
  });

  describe('Check challenges', function() {
    after(function() {
      cleanup();
    });
    populateTestsForLang(challengeData);
  });
  spinner.text = 'Testing';
  run();
}

async function getChallenges(lang) {
  const challenges = await getChallengesForLang(lang).then(curriculum =>
    Object.keys(curriculum)
      .map(key => curriculum[key].blocks)
      .reduce((challengeArray, superBlock) => {
        const challengesForBlock = Object.keys(superBlock).map(
          key => superBlock[key].challenges
        );
        return [...challengeArray, ...flatten(challengesForBlock)];
      }, [])
  );
  return challenges;
}

function validateBlock(challenge) {
  const dashedBlock = dasherize(challenge.block);
  if (!helpCategory.hasOwnProperty(dashedBlock)) {
    return `'${dashedBlock}' block not found as a helpCategory in client/utils/challengeTypes.js file for the '${challenge.title}' challenge`;
  } else {
    return null;
  }
}

function populateTestsForLang({ lang, challenges, meta }) {
  const mongoIds = new MongoIds();
  const challengeTitles = new ChallengeTitles();
  const validateChallenge = challengeSchemaValidator(lang);

  describe(`Check challenges (${lang})`, function() {
    this.timeout(5000);
    challenges.forEach(challenge => {
      const dashedBlockName = dasherize(challenge.block);
      describe(challenge.block || 'No block', function() {
        describe(challenge.title || 'No title', function() {
          it('Matches a title in meta.json', function() {
            const index = meta[dashedBlockName].findIndex(
              arr => arr[1] === challenge.title
            );

            if (index < 0) {
              throw new AssertionError(
                `Cannot find title "${challenge.title}" in meta.json file`
              );
            }
          });

          it('Matches an ID in meta.json', function() {
            const index = meta[dashedBlockName].findIndex(
              arr => arr[0] === challenge.id
            );

            if (index < 0) {
              throw new AssertionError(
                `Cannot find ID "${challenge.id}" in meta.json file`
              );
            }
          });

          it('Common checks', function() {
            const result = validateChallenge(challenge);
            const invalidBlock = validateBlock(challenge);

            if (result.error) {
              throw new AssertionError(result.error);
            }
            if (challenge.challengeType !== 7 && invalidBlock) {
              throw new Error(invalidBlock);
            }
            const { id, title } = challenge;
            mongoIds.check(id, title);
            challengeTitles.check(title);
          });

          const { challengeType } = challenge;
          if (
            challengeType !== challengeTypes.html &&
            challengeType !== challengeTypes.js &&
            challengeType !== challengeTypes.bonfire &&
            challengeType !== challengeTypes.modern &&
            challengeType !== challengeTypes.backend
          ) {
            return;
          }

          let { tests = [] } = challenge;
          tests = tests.filter(test => !!test.testString);
          if (tests.length === 0) {
            it('Check tests. No tests.');
            return;
          }

          describe('Check tests syntax', function() {
            tests.forEach(test => {
              it(`Check for: ${test.text}`, function() {
                assert.doesNotThrow(() => new vm.Script(test.testString));
              });
            });
          });

          let { files = [] } = challenge;
          if (challengeType === challengeTypes.backend) {
            it('Check tests is not implemented.');
            return;
          }

          if (files.length > 1) {
            it('Check tests.', () => {
              throw new Error('Seed file should be only the one.');
            });
            return;
          }

          const buildChallenge =
            challengeType === challengeTypes.js ||
            challengeType === challengeTypes.bonfire
              ? buildJSChallenge
              : buildDOMChallenge;

          files = files.map(createPoly);
          it('Test suite must fail on the initial contents', async function() {
            this.timeout(5000 * tests.length + 1000);
            // suppress errors in the console.
            const oldConsoleError = console.error;
            console.error = () => {};
            let fails = false;
            let testRunner;
            try {
              testRunner = await createTestRunner(
                { ...challenge, files },
                '',
                buildChallenge
              );
            } catch {
              fails = true;
            }
            if (!fails) {
              for (const test of tests) {
                try {
                  await testRunner(test);
                } catch (e) {
                  fails = true;
                  break;
                }
              }
            }
            console.error = oldConsoleError;
            assert(fails, 'Test suit does not fail on the initial contents');
          });

          let { solutions = [] } = challenge;
          const noSolution = new RegExp('// solution required');
          solutions = solutions.filter(
            solution => !!solution && !noSolution.test(solution)
          );

          if (solutions.length === 0) {
            it('Check tests. No solutions');
            return;
          }

          describe('Check tests against solutions', function() {
            solutions.forEach((solution, index) => {
              it(`Solution ${index + 1} must pass the tests`, async function() {
                this.timeout(5000 * tests.length + 1000);
                const testRunner = await createTestRunner(
                  { ...challenge, files },
                  solution,
                  buildChallenge
                );
                for (const test of tests) {
                  await testRunner(test);
                }
              });
            });
          });
        });
      });
    });
  });
}

async function createTestRunner(
  { required = [], template, files },
  solution,
  buildChallenge
) {
  if (solution) {
    files[0].contents = solution;
  }

  const { build, sources, loadEnzyme } = await buildChallenge({
    files,
    required,
    template
  });
  const code = sources && 'index' in sources ? sources['index'] : '';

  const evaluator = await (buildChallenge === buildDOMChallenge
    ? getContextEvaluator(build, sources, code, loadEnzyme)
    : getWorkerEvaluator(build, sources, code));

  return async ({ text, testString }) => {
    try {
      const { pass, err } = await evaluator.evaluate(testString, 5000);
      if (!pass) {
        throw new AssertionError(err.message);
      }
    } catch (err) {
      reThrow(err, text);
    }
  };
}

async function getContextEvaluator(build, sources, code, loadEnzyme) {
  await initializeTestRunner(build, sources, code, loadEnzyme);

  return {
    evaluate: async (testString, timeout) =>
      Promise.race([
        new Promise((_, reject) =>
          setTimeout(() => reject('timeout'), timeout)
        ),
        await page.evaluate(async testString => {
          return await document.__runTest(testString);
        }, testString)
      ])
  };
}

async function getWorkerEvaluator(build, sources, code) {
  const testWorker = createWorker(testEvaluator, { terminateWorker: true });
  return {
    evaluate: async (testString, timeout) =>
      await testWorker.execute({ testString, build, code, sources }, timeout)
        .done
  };
}

async function initializeTestRunner(build, sources, code, loadEnzyme) {
  await page.reload();
  await page.setContent(build);
  await page.evaluate(
    async (code, sources, loadEnzyme) => {
      const getUserInput = fileName => sources[fileName];
      await document.__initTestFrame({ code, getUserInput, loadEnzyme });
    },
    code,
    sources,
    loadEnzyme
  );
}

function reThrow(err, text) {
  if (typeof err === 'string') {
    throw new AssertionError(
      `${text}
         ${err}`
    );
  } else {
    err.message = `${text}
       ${err.message}`;
    throw err;
  }
}
<commit_msg>fix: make all unhandled errors fail tests<commit_after>/* eslint-disable no-loop-func */
const path = require('path');
const liveServer = require('live-server');
const stringSimilarity = require('string-similarity');

const spinner = require('ora')();

const clientPath = path.resolve(__dirname, '../../client');
require('@babel/polyfill');
require('@babel/register')({
  root: clientPath,
  babelrc: false,
  presets: ['@babel/preset-env'],
  plugins: ['dynamic-import-node'],
  ignore: [/node_modules/],
  only: [clientPath]
});

const createPseudoWorker = require('./utils/pseudo-worker');
const {
  default: createWorker
} = require('../../client/src/templates/Challenges/utils/worker-executor');

const { assert, AssertionError } = require('chai');
const Mocha = require('mocha');
const { flatten } = require('lodash');

const jsdom = require('jsdom');

const vm = require('vm');

const puppeteer = require('puppeteer');

const { getChallengesForLang, getMetaForBlock } = require('../getChallenges');

const MongoIds = require('./utils/mongoIds');
const ChallengeTitles = require('./utils/challengeTitles');
const { challengeSchemaValidator } = require('../schema/challengeSchema');
const {
  challengeTypes,
  helpCategory
} = require('../../client/utils/challengeTypes');

const { dasherize } = require('../../utils/slugs');

const { testedLang } = require('../utils');

const {
  buildDOMChallenge,
  buildJSChallenge
} = require('../../client/src/templates/Challenges/utils/build');

const { createPoly } = require('../../utils/polyvinyl');

const testEvaluator = require('../../client/config/test-evaluator').filename;

// rethrow unhandled rejections to make sure the tests exit with -1
process.on('unhandledRejection', err => {
  cleanup();
  // setting the error code because node does not (yet) exit with a non-zero
  // code on unhandled exceptions.
  process.exitCode = 1;
  throw err;
});

const dom = new jsdom.JSDOM('');
global.document = dom.window.document;

const oldRunnerFail = Mocha.Runner.prototype.fail;
Mocha.Runner.prototype.fail = function(test, err) {
  if (err instanceof AssertionError) {
    const errMessage = String(err.message || '');
    const assertIndex = errMessage.indexOf(': expected');
    if (assertIndex !== -1) {
      err.message = errMessage.slice(0, assertIndex);
    }
    // Don't show stacktrace for assertion errors.
    if (err.stack) {
      delete err.stack;
    }
  }
  return oldRunnerFail.call(this, test, err);
};

async function newPageContext(browser) {
  const page = await browser.newPage();
  // it's needed for workers as context.
  await page.goto('http://127.0.0.1:8080/index.html');
  return page;
}

spinner.start();
spinner.text = 'Populate tests.';

let browser;
let page;

setup()
  .then(runTests)
  .catch(err => {
    cleanup();
    // setting the error code because node does not (yet) exit with a non-zero
    // code on unhandled exceptions.
    process.exitCode = 1;
    throw err;
  });

async function setup() {
  if (process.env.npm_config_superblock && process.env.npm_config_block) {
    throw new Error(`Please do not use both a block and superblock as input.`);
  }

  // liveServer starts synchronously
  liveServer.start({
    host: '127.0.0.1',
    port: '8080',
    root: path.resolve(__dirname, 'stubs'),
    mount: [['/js', path.join(clientPath, 'static/js')]],
    open: false,
    logLevel: 0
  });
  browser = await puppeteer.launch({
    args: [
      // Required for Docker version of Puppeteer
      '--no-sandbox',
      '--disable-setuid-sandbox',
      // This will write shared memory files into /tmp instead of /dev/shm,
      // because Docker’s default for /dev/shm is 64MB
      '--disable-dev-shm-usage'
      // dumpio: true
    ]
  });
  global.Worker = createPseudoWorker(await newPageContext(browser));
  page = await newPageContext(browser);
  await page.setViewport({ width: 300, height: 150 });

  const lang = testedLang();

  let challenges = await getChallenges(lang);

  // the next few statements create a list of all blocks and superblocks
  // as they appear in the list of challenges
  const blocks = challenges.map(({ block }) => block);
  const superBlocks = challenges.map(({ superBlock }) => superBlock);
  const targetBlockStrings = [...new Set(blocks)];
  const targetSuperBlockStrings = [...new Set(superBlocks)];

  // the next few statements will filter challenges based on command variables
  if (process.env.npm_config_superblock) {
    const filter = stringSimilarity.findBestMatch(
      process.env.npm_config_superblock,
      targetSuperBlockStrings
    ).bestMatch.target;

    console.log(`\nsuperBlock being tested: ${filter}`);
    challenges = challenges.filter(
      challenge => challenge.superBlock === filter
    );

    if (!challenges.length) {
      throw new Error(`No challenges found with superBlock "${filter}"`);
    }
  }

  if (process.env.npm_config_block) {
    const filter = stringSimilarity.findBestMatch(
      process.env.npm_config_block,
      targetBlockStrings
    ).bestMatch.target;

    console.log(`\nblock being tested: ${filter}`);
    challenges = challenges.filter(challenge => challenge.block === filter);

    if (!challenges.length) {
      throw new Error(`No challenges found with block "${filter}"`);
    }
  }

  const meta = {};
  for (const challenge of challenges) {
    const dashedBlockName = dasherize(challenge.block);
    if (!meta[dashedBlockName]) {
      meta[dashedBlockName] = (await getMetaForBlock(
        dashedBlockName
      )).challengeOrder;
    }
  }
  return {
    meta,
    challenges,
    lang
  };
}

// cleanup calls some async functions, but it's the last thing that happens, so
// no need to await anything.
function cleanup() {
  if (browser) {
    browser.close();
  }
  liveServer.shutdown();
  spinner.stop();
}

function runTests(challengeData) {
  describe('Check challenges', function() {
    after(function() {
      cleanup();
    });
    populateTestsForLang(challengeData);
  });
  spinner.text = 'Testing';
  run();
}

async function getChallenges(lang) {
  const challenges = await getChallengesForLang(lang).then(curriculum =>
    Object.keys(curriculum)
      .map(key => curriculum[key].blocks)
      .reduce((challengeArray, superBlock) => {
        const challengesForBlock = Object.keys(superBlock).map(
          key => superBlock[key].challenges
        );
        return [...challengeArray, ...flatten(challengesForBlock)];
      }, [])
  );
  return challenges;
}

function validateBlock(challenge) {
  const dashedBlock = dasherize(challenge.block);
  if (!helpCategory.hasOwnProperty(dashedBlock)) {
    return `'${dashedBlock}' block not found as a helpCategory in client/utils/challengeTypes.js file for the '${challenge.title}' challenge`;
  } else {
    return null;
  }
}

function populateTestsForLang({ lang, challenges, meta }) {
  const mongoIds = new MongoIds();
  const challengeTitles = new ChallengeTitles();
  const validateChallenge = challengeSchemaValidator(lang);

  describe(`Check challenges (${lang})`, function() {
    this.timeout(5000);
    challenges.forEach(challenge => {
      const dashedBlockName = dasherize(challenge.block);
      describe(challenge.block || 'No block', function() {
        describe(challenge.title || 'No title', function() {
          it('Matches a title in meta.json', function() {
            const index = meta[dashedBlockName].findIndex(
              arr => arr[1] === challenge.title
            );

            if (index < 0) {
              throw new AssertionError(
                `Cannot find title "${challenge.title}" in meta.json file`
              );
            }
          });

          it('Matches an ID in meta.json', function() {
            const index = meta[dashedBlockName].findIndex(
              arr => arr[0] === challenge.id
            );

            if (index < 0) {
              throw new AssertionError(
                `Cannot find ID "${challenge.id}" in meta.json file`
              );
            }
          });

          it('Common checks', function() {
            const result = validateChallenge(challenge);
            const invalidBlock = validateBlock(challenge);

            if (result.error) {
              throw new AssertionError(result.error);
            }
            if (challenge.challengeType !== 7 && invalidBlock) {
              throw new Error(invalidBlock);
            }
            const { id, title } = challenge;
            mongoIds.check(id, title);
            challengeTitles.check(title);
          });

          const { challengeType } = challenge;
          if (
            challengeType !== challengeTypes.html &&
            challengeType !== challengeTypes.js &&
            challengeType !== challengeTypes.bonfire &&
            challengeType !== challengeTypes.modern &&
            challengeType !== challengeTypes.backend
          ) {
            return;
          }

          let { tests = [] } = challenge;
          tests = tests.filter(test => !!test.testString);
          if (tests.length === 0) {
            it('Check tests. No tests.');
            return;
          }

          describe('Check tests syntax', function() {
            tests.forEach(test => {
              it(`Check for: ${test.text}`, function() {
                assert.doesNotThrow(() => new vm.Script(test.testString));
              });
            });
          });

          let { files = [] } = challenge;
          if (challengeType === challengeTypes.backend) {
            it('Check tests is not implemented.');
            return;
          }

          if (files.length > 1) {
            it('Check tests.', () => {
              throw new Error('Seed file should be only the one.');
            });
            return;
          }

          const buildChallenge =
            challengeType === challengeTypes.js ||
            challengeType === challengeTypes.bonfire
              ? buildJSChallenge
              : buildDOMChallenge;

          files = files.map(createPoly);
          it('Test suite must fail on the initial contents', async function() {
            this.timeout(5000 * tests.length + 1000);
            // suppress errors in the console.
            const oldConsoleError = console.error;
            console.error = () => {};
            let fails = false;
            let testRunner;
            try {
              testRunner = await createTestRunner(
                { ...challenge, files },
                '',
                buildChallenge
              );
            } catch {
              fails = true;
            }
            if (!fails) {
              for (const test of tests) {
                try {
                  await testRunner(test);
                } catch (e) {
                  fails = true;
                  break;
                }
              }
            }
            console.error = oldConsoleError;
            assert(fails, 'Test suit does not fail on the initial contents');
          });

          let { solutions = [] } = challenge;
          const noSolution = new RegExp('// solution required');
          solutions = solutions.filter(
            solution => !!solution && !noSolution.test(solution)
          );

          if (solutions.length === 0) {
            it('Check tests. No solutions');
            return;
          }

          describe('Check tests against solutions', function() {
            solutions.forEach((solution, index) => {
              it(`Solution ${index + 1} must pass the tests`, async function() {
                this.timeout(5000 * tests.length + 1000);
                const testRunner = await createTestRunner(
                  { ...challenge, files },
                  solution,
                  buildChallenge
                );
                for (const test of tests) {
                  await testRunner(test);
                }
              });
            });
          });
        });
      });
    });
  });
}

async function createTestRunner(
  { required = [], template, files },
  solution,
  buildChallenge
) {
  if (solution) {
    files[0].contents = solution;
  }

  const { build, sources, loadEnzyme } = await buildChallenge({
    files,
    required,
    template
  });
  const code = sources && 'index' in sources ? sources['index'] : '';

  const evaluator = await (buildChallenge === buildDOMChallenge
    ? getContextEvaluator(build, sources, code, loadEnzyme)
    : getWorkerEvaluator(build, sources, code));

  return async ({ text, testString }) => {
    try {
      const { pass, err } = await evaluator.evaluate(testString, 5000);
      if (!pass) {
        throw new AssertionError(err.message);
      }
    } catch (err) {
      reThrow(err, text);
    }
  };
}

async function getContextEvaluator(build, sources, code, loadEnzyme) {
  await initializeTestRunner(build, sources, code, loadEnzyme);

  return {
    evaluate: async (testString, timeout) =>
      Promise.race([
        new Promise((_, reject) =>
          setTimeout(() => reject('timeout'), timeout)
        ),
        await page.evaluate(async testString => {
          return await document.__runTest(testString);
        }, testString)
      ])
  };
}

async function getWorkerEvaluator(build, sources, code) {
  const testWorker = createWorker(testEvaluator, { terminateWorker: true });
  return {
    evaluate: async (testString, timeout) =>
      await testWorker.execute({ testString, build, code, sources }, timeout)
        .done
  };
}

async function initializeTestRunner(build, sources, code, loadEnzyme) {
  await page.reload();
  await page.setContent(build);
  await page.evaluate(
    async (code, sources, loadEnzyme) => {
      const getUserInput = fileName => sources[fileName];
      await document.__initTestFrame({ code, getUserInput, loadEnzyme });
    },
    code,
    sources,
    loadEnzyme
  );
}

function reThrow(err, text) {
  if (typeof err === 'string') {
    throw new AssertionError(
      `${text}
         ${err}`
    );
  } else {
    err.message = `${text}
       ${err.message}`;
    throw err;
  }
}
<|endoftext|>


<commit_before>import { startSubmit, stopSubmit, reset } from 'redux-form'
import _ from 'lodash'
import Promise from 'bluebird'
import { LOAD_MODULE, ADD_LOT, UPDATE_LOT, SEARCH } from './actionTypes'
import { getContractByAbiName, loadAbiByName, getContract, blockchain, coinbase, listenAddress } from '../../utils/web3'
import { promiseFor } from '../../utils/helper'
import { flashMessage } from '../app/actions'

export function loadLot(address, lotAbi, tokenAbi) {
  const lot = getContract(lotAbi, address)
  let item = {}
  return lot.call('closed')
    .then((closed) => {
      if (!closed) {
        // если лот открыт, то получаем данные по лоту
        return Promise.join(
          lot.call('seller'),
          lot.call('buyer'),
          lot.call('quantity_sale'),
          lot.call('quantity_buy'),
          lot.call('sale'),
          lot.call('buy'),
          lot.call('commissionToken'),
          lot.call('commission'),
          lot.call('commissionAmount'),
          (seller, buyer, quantitySale, quantityBuy, sale, buy, commissionToken,
            commission, commissionAmount) => {
            const commissionNum = _.toNumber(commission) / 100;
            const commissionAmountNum = _.toNumber(commissionAmount);
            const saleQuantityFull = _.toNumber(quantitySale)
            let quantitySaleView = saleQuantityFull
            let saleCommission = 0
            if (sale === commissionToken) {
              quantitySaleView -= commissionAmountNum / 2
              // saleQuantityFull += commissionAmountNum
              saleCommission = commissionNum
            }
            const buyQuantityFull = _.toNumber(quantityBuy)
            let quantityBuyView = buyQuantityFull
            let buyCommission = 0
            if (buy === commissionToken) {
              quantityBuyView -= commissionAmountNum / 2
              // buyQuantityFull += commissionAmountNum
              buyCommission = commissionNum
            }
            return {
              my: (seller === coinbase()),
              seller,
              buyer,
              sale_quantity: quantitySaleView,
              buy_quantity: quantityBuyView,
              sale_quantity_full: saleQuantityFull,
              buy_quantity_full: buyQuantityFull,
              sale_commission: saleCommission,
              buy_commission: buyCommission,
              sale_address: sale,
              buy_address: buy,
              commission_amount: commissionAmountNum
            }
          }
        );
      }
      return false;
    })
    .then((lotResult) => {
      if (lotResult) {
        // если данные по лоту получены, то получаем данные по токенам лота
        item = { address, closed, ...lotResult }
        const tokenSale = getContract(tokenAbi, item.sale_address)
        const tokenBuy = getContract(tokenAbi, item.buy_address)
        return Promise.join(
          tokenSale.call('name'),
          tokenSale.call('allowance', [item.seller, address]),
          tokenSale.call('balanceOf', [item.seller]),
          tokenSale.call('symbol'),
          tokenSale.call('decimals'),
          tokenBuy.call('name'),
          tokenBuy.call('allowance', [coinbase(), address]),
          tokenBuy.call('balanceOf', [coinbase()]),
          tokenBuy.call('symbol'),
          tokenBuy.call('decimals'),
          (saleName, saleApprove, saleBalance, saleSymbol, saleDecimals,
            buyName, buyApprove, buyBalance, buySymbol, buyDecimals) => {
            const saleDecimalsFormat = _.toNumber(saleDecimals)
            let saleDecimalsNum = saleDecimalsFormat
            if (saleDecimalsNum > 0) {
              saleDecimalsNum = Math.pow(10, saleDecimalsNum)
            } else {
              saleDecimalsNum = 1
            }
            const buyDecimalsFormat = _.toNumber(buyDecimals)
            let buyDecimalsNum = buyDecimalsFormat
            if (buyDecimals > 0) {
              buyDecimalsNum = Math.pow(10, buyDecimalsNum)
            } else {
              buyDecimalsNum = 1
            }
            const saleApproveNum = _.toNumber(saleApprove)
            const saleBalanceNum = _.toNumber(saleBalance)
            const buyApproveNum = _.toNumber(buyApprove)
            const buyBalanceNum = _.toNumber(buyBalance)
            return {
              sale_name: saleName,
              approve_sale_quantity: saleApproveNum > saleBalanceNum ?
                saleBalanceNum : saleApproveNum,
              saleSymbol,
              buy_name: buyName,
              approve_buy_quantity: buyApproveNum > buyBalanceNum ?
                buyBalanceNum : buyApproveNum,
              buySymbol,
              saleDecimalsFormat,
              saleDecimalsNum,
              buyDecimalsFormat,
              buyDecimalsNum
            }
          }
        );
      }
      return false;
    })
    .then((tokensInfoResult) => {
      if (tokensInfoResult) {
        item.sale_quantity = (item.sale_quantity / tokensInfoResult.saleDecimalsNum)
          .toFixed(tokensInfoResult.saleDecimalsFormat);
        item.buy_quantity = (item.buy_quantity / tokensInfoResult.buyDecimalsNum)
          .toFixed(tokensInfoResult.buyDecimalsFormat);
        item.sale_quantity_full = (item.sale_quantity_full / tokensInfoResult.saleDecimalsNum)
          .toFixed(tokensInfoResult.saleDecimalsFormat);
        item.buy_quantity_full = (item.buy_quantity_full / tokensInfoResult.buyDecimalsNum)
          .toFixed(tokensInfoResult.buyDecimalsFormat);
        return { ...item, ...tokensInfoResult }
      }
      return false;
    })
}

export function updateLotModule(addressModule, address) {
  return (dispatch) => {
    let tokenAbi
    let lotAbi
    loadAbiByName('TokenEmission')
      .then((abi) => {
        tokenAbi = abi
        return loadAbiByName('Lot')
      })
      .then((abi) => {
        lotAbi = abi
        return loadLot(address, lotAbi, tokenAbi)
      })
      .then((lot) => {
        if (lot) {
          dispatch({
            type: UPDATE_LOT,
            payload: {
              address: addressModule,
              lot
            }
          })
        }
      })
  }
}

export function addLotModule(adressModule, address, lotAbi, tokenAbi) {
  return (dispatch) => {
    loadLot(address, lotAbi, tokenAbi)
      .then((lot) => {
        if (lot) {
          dispatch({
            type: ADD_LOT,
            payload: {
              address: adressModule,
              lot
            }
          })
          listenAddress(lot.address, 'loadModule', () => {
            dispatch(loadModule(adressModule)) /* eslint no-use-before-define: 0 */
          })
          listenAddress(lot.sale_address, 'loadLotMarket' + lot.address, () => {
            dispatch(updateLotModule(adressModule, lot.address))
          })
          listenAddress(lot.buy_address, 'loadLotMarket' + lot.address, () => {
            dispatch(updateLotModule(adressModule, lot.address))
          })
        }
      })
  }
}

export function loadModule(marketAddress) {
  return (dispatch) => {
    let market
    let tokenAbi
    let lotAbi
    getContractByAbiName('Market', marketAddress)
      .then((contract) => {
        market = contract
        return Promise.join(
          contract.call('commissionToken'),
          contract.call('commission'),
          (commissionToken, commission) => (
            {
              commissionToken,
              commission: _.toNumber(commission) / 100 / 2
            }
          )
        )
      })
      .then((commission) => {
        dispatch({
          type: LOAD_MODULE,
          payload: {
            address: marketAddress,
            ...commission,
            lots: []
          }
        })
        return loadAbiByName('TokenEmission')
      })
      .then((abi) => {
        tokenAbi = abi
        return loadAbiByName('Lot')
      })
      .then((abi) => {
        lotAbi = abi
      })
      .then(() => {
        market.call('first')
          .then(firstAddress => (
            promiseFor(address => address !== '0x0000000000000000000000000000000000000000', (address) => {
              dispatch(addLotModule(marketAddress, address, lotAbi, tokenAbi));
              return market.call('next', [address]);
            }, firstAddress)
          ))
          .then(() => {
            listenAddress(marketAddress, 'loadModule', (address) => {
              dispatch(loadModule(address))
            })
          });
      })
  }
}

export function search(form) {
  return {
    type: SEARCH,
    payload: form
  }
}

export function dealLot(marketAddress, address) {
  return (dispatch) => {
    getContractByAbiName('Lot', address)
      .then(contract => contract.send('deal', [coinbase()]))
      .then((txId) => {
        dispatch(flashMessage('tx: ' + txId))
        return blockchain.subscribeTx(txId)
      })
      .then(() => {
        dispatch(flashMessage('Лот куплен'))
      })
  }
}

export function removeLot(marketAddress, address) {
  return (dispatch) => {
    getContractByAbiName('Market', marketAddress)
      .then(contract => contract.send('remove', [address]))
      .then((txId) => {
        dispatch(flashMessage('tx: ' + txId))
        return blockchain.subscribeTx(txId)
      })
      .then(() => {
        dispatch(flashMessage('Лот удален'))
      })
  }
}

export function approveLot(marketAddress, lot, token, value) {
  return (dispatch) => {
    getContractByAbiName('TokenEmission', token)
      .then(contract => contract.send('approve', [lot, value]))
      .then((txId) => {
        dispatch(flashMessage('tx: ' + txId))
        return blockchain.subscribeTx(txId)
      })
      .then(() => {
        dispatch(flashMessage('Дан доступ'))
      })
  }
}

function run(dispatch, address, func, values) {
  const params = values;
  if (func === 'setCommission') {
    params[0] *= 100 * 2;
  }

  return getContractByAbiName('Market', address)
    .then(contract => contract.send(func, params))
    .then((txId) => {
      dispatch(flashMessage('txId: ' + txId))
      return blockchain.subscribeTx(txId)
    })
    .then(transaction => transaction.blockNumber)
}

export function submit(marketAddress, action, form) {
  return (dispatch) => {
    dispatch(startSubmit('FormMarket'));
    let func
    switch (action) {
      case 'lot':
        func = 'append'
        break
      case 'setCommissionToken':
        func = 'setCommissionToken'
        break
      case 'setCommission':
        func = 'setCommission'
        break
      default:
        func = false;
    }
    if (func) {
      run(dispatch, marketAddress, func, _.values(form))
        .then((blockNumber) => {
          dispatch(stopSubmit('FormMarket'))
          dispatch(reset('FormMarket'))
          dispatch(flashMessage('blockNumber: ' + blockNumber))
        })
        .catch(() => {
          dispatch(stopSubmit('FormMarket'))
        })
    }
  }
}
<commit_msg>fix approve decimals<commit_after>import { startSubmit, stopSubmit, reset } from 'redux-form'
import _ from 'lodash'
import Promise from 'bluebird'
import { LOAD_MODULE, ADD_LOT, UPDATE_LOT, SEARCH } from './actionTypes'
import { getContractByAbiName, loadAbiByName, getContract, blockchain, coinbase, listenAddress } from '../../utils/web3'
import { promiseFor } from '../../utils/helper'
import { flashMessage } from '../app/actions'

export function loadLot(address, lotAbi, tokenAbi) {
  const lot = getContract(lotAbi, address)
  let item = {}
  return lot.call('closed')
    .then((closed) => {
      if (!closed) {
        // если лот открыт, то получаем данные по лоту
        return Promise.join(
          lot.call('seller'),
          lot.call('buyer'),
          lot.call('quantity_sale'),
          lot.call('quantity_buy'),
          lot.call('sale'),
          lot.call('buy'),
          lot.call('commissionToken'),
          lot.call('commission'),
          lot.call('commissionAmount'),
          (seller, buyer, quantitySale, quantityBuy, sale, buy, commissionToken,
            commission, commissionAmount) => {
            const commissionNum = _.toNumber(commission) / 100;
            const commissionAmountNum = _.toNumber(commissionAmount);
            const saleQuantityFull = _.toNumber(quantitySale)
            let quantitySaleView = saleQuantityFull
            let saleCommission = 0
            if (sale === commissionToken) {
              quantitySaleView -= commissionAmountNum / 2
              // saleQuantityFull += commissionAmountNum
              saleCommission = commissionNum
            }
            const buyQuantityFull = _.toNumber(quantityBuy)
            let quantityBuyView = buyQuantityFull
            let buyCommission = 0
            if (buy === commissionToken) {
              quantityBuyView -= commissionAmountNum / 2
              // buyQuantityFull += commissionAmountNum
              buyCommission = commissionNum
            }
            return {
              my: (seller === coinbase()),
              seller,
              buyer,
              sale_quantity: quantitySaleView,
              buy_quantity: quantityBuyView,
              sale_quantity_full: saleQuantityFull,
              buy_quantity_full: buyQuantityFull,
              sale_commission: saleCommission,
              buy_commission: buyCommission,
              sale_address: sale,
              buy_address: buy,
              commission_amount: commissionAmountNum
            }
          }
        );
      }
      return false;
    })
    .then((lotResult) => {
      if (lotResult) {
        // если данные по лоту получены, то получаем данные по токенам лота
        item = { address, closed, ...lotResult }
        const tokenSale = getContract(tokenAbi, item.sale_address)
        const tokenBuy = getContract(tokenAbi, item.buy_address)
        return Promise.join(
          tokenSale.call('name'),
          tokenSale.call('allowance', [item.seller, address]),
          tokenSale.call('balanceOf', [item.seller]),
          tokenSale.call('symbol'),
          tokenSale.call('decimals'),
          tokenBuy.call('name'),
          tokenBuy.call('allowance', [coinbase(), address]),
          tokenBuy.call('balanceOf', [coinbase()]),
          tokenBuy.call('symbol'),
          tokenBuy.call('decimals'),
          (saleName, saleApprove, saleBalance, saleSymbol, saleDecimals,
            buyName, buyApprove, buyBalance, buySymbol, buyDecimals) => {
            const saleDecimalsFormat = _.toNumber(saleDecimals)
            let saleDecimalsNum = saleDecimalsFormat
            if (saleDecimalsNum > 0) {
              saleDecimalsNum = Math.pow(10, saleDecimalsNum)
            } else {
              saleDecimalsNum = 1
            }
            const buyDecimalsFormat = _.toNumber(buyDecimals)
            let buyDecimalsNum = buyDecimalsFormat
            if (buyDecimals > 0) {
              buyDecimalsNum = Math.pow(10, buyDecimalsNum)
            } else {
              buyDecimalsNum = 1
            }
            const saleApproveNum = _.toNumber(saleApprove)
            const saleBalanceNum = _.toNumber(saleBalance)
            const buyApproveNum = _.toNumber(buyApprove)
            const buyBalanceNum = _.toNumber(buyBalance)
            return {
              sale_name: saleName,
              approve_sale_quantity: saleApproveNum > saleBalanceNum ?
                saleBalanceNum : saleApproveNum,
              saleSymbol,
              buy_name: buyName,
              approve_buy_quantity: buyApproveNum > buyBalanceNum ?
                buyBalanceNum : buyApproveNum,
              buySymbol,
              saleDecimalsFormat,
              saleDecimalsNum,
              buyDecimalsFormat,
              buyDecimalsNum
            }
          }
        );
      }
      return false;
    })
    .then((tokensInfoResult) => {
      if (tokensInfoResult) {
        item.sale_quantity = (item.sale_quantity / tokensInfoResult.saleDecimalsNum)
          .toFixed(tokensInfoResult.saleDecimalsFormat);
        item.buy_quantity = (item.buy_quantity / tokensInfoResult.buyDecimalsNum)
          .toFixed(tokensInfoResult.buyDecimalsFormat);
        return { ...item, ...tokensInfoResult }
      }
      return false;
    })
}

export function updateLotModule(addressModule, address) {
  return (dispatch) => {
    let tokenAbi
    let lotAbi
    loadAbiByName('TokenEmission')
      .then((abi) => {
        tokenAbi = abi
        return loadAbiByName('Lot')
      })
      .then((abi) => {
        lotAbi = abi
        return loadLot(address, lotAbi, tokenAbi)
      })
      .then((lot) => {
        if (lot) {
          dispatch({
            type: UPDATE_LOT,
            payload: {
              address: addressModule,
              lot
            }
          })
        }
      })
  }
}

export function addLotModule(adressModule, address, lotAbi, tokenAbi) {
  return (dispatch) => {
    loadLot(address, lotAbi, tokenAbi)
      .then((lot) => {
        if (lot) {
          dispatch({
            type: ADD_LOT,
            payload: {
              address: adressModule,
              lot
            }
          })
          listenAddress(lot.address, 'loadModule', () => {
            dispatch(loadModule(adressModule)) /* eslint no-use-before-define: 0 */
          })
          listenAddress(lot.sale_address, 'loadLotMarket' + lot.address, () => {
            dispatch(updateLotModule(adressModule, lot.address))
          })
          listenAddress(lot.buy_address, 'loadLotMarket' + lot.address, () => {
            dispatch(updateLotModule(adressModule, lot.address))
          })
        }
      })
  }
}

export function loadModule(marketAddress) {
  return (dispatch) => {
    let market
    let tokenAbi
    let lotAbi
    getContractByAbiName('Market', marketAddress)
      .then((contract) => {
        market = contract
        return Promise.join(
          contract.call('commissionToken'),
          contract.call('commission'),
          (commissionToken, commission) => (
            {
              commissionToken,
              commission: _.toNumber(commission) / 100 / 2
            }
          )
        )
      })
      .then((commission) => {
        dispatch({
          type: LOAD_MODULE,
          payload: {
            address: marketAddress,
            ...commission,
            lots: []
          }
        })
        return loadAbiByName('TokenEmission')
      })
      .then((abi) => {
        tokenAbi = abi
        return loadAbiByName('Lot')
      })
      .then((abi) => {
        lotAbi = abi
      })
      .then(() => {
        market.call('first')
          .then(firstAddress => (
            promiseFor(address => address !== '0x0000000000000000000000000000000000000000', (address) => {
              dispatch(addLotModule(marketAddress, address, lotAbi, tokenAbi));
              return market.call('next', [address]);
            }, firstAddress)
          ))
          .then(() => {
            listenAddress(marketAddress, 'loadModule', (address) => {
              dispatch(loadModule(address))
            })
          });
      })
  }
}

export function search(form) {
  return {
    type: SEARCH,
    payload: form
  }
}

export function dealLot(marketAddress, address) {
  return (dispatch) => {
    getContractByAbiName('Lot', address)
      .then(contract => contract.send('deal', [coinbase()]))
      .then((txId) => {
        dispatch(flashMessage('tx: ' + txId))
        return blockchain.subscribeTx(txId)
      })
      .then(() => {
        dispatch(flashMessage('Лот куплен'))
      })
  }
}

export function removeLot(marketAddress, address) {
  return (dispatch) => {
    getContractByAbiName('Market', marketAddress)
      .then(contract => contract.send('remove', [address]))
      .then((txId) => {
        dispatch(flashMessage('tx: ' + txId))
        return blockchain.subscribeTx(txId)
      })
      .then(() => {
        dispatch(flashMessage('Лот удален'))
      })
  }
}

export function approveLot(marketAddress, lot, token, value) {
  return (dispatch) => {
    getContractByAbiName('TokenEmission', token)
      .then(contract => contract.send('approve', [lot, value]))
      .then((txId) => {
        dispatch(flashMessage('tx: ' + txId))
        return blockchain.subscribeTx(txId)
      })
      .then(() => {
        dispatch(flashMessage('Дан доступ'))
      })
  }
}

function run(dispatch, address, func, values) {
  const params = values;
  if (func === 'setCommission') {
    params[0] *= 100 * 2;
  }

  return getContractByAbiName('Market', address)
    .then(contract => contract.send(func, params))
    .then((txId) => {
      dispatch(flashMessage('txId: ' + txId))
      return blockchain.subscribeTx(txId)
    })
    .then(transaction => transaction.blockNumber)
}

export function submit(marketAddress, action, form) {
  return (dispatch) => {
    dispatch(startSubmit('FormMarket'));
    let func
    switch (action) {
      case 'lot':
        func = 'append'
        break
      case 'setCommissionToken':
        func = 'setCommissionToken'
        break
      case 'setCommission':
        func = 'setCommission'
        break
      default:
        func = false;
    }
    if (func) {
      run(dispatch, marketAddress, func, _.values(form))
        .then((blockNumber) => {
          dispatch(stopSubmit('FormMarket'))
          dispatch(reset('FormMarket'))
          dispatch(flashMessage('blockNumber: ' + blockNumber))
        })
        .catch(() => {
          dispatch(stopSubmit('FormMarket'))
        })
    }
  }
}
<|endoftext|>


<commit_before>"use strict";
log('running deepdeligations.js');

var Ping = {
    options: {
        name: 'name not set',
    },
    ping: function () {
        log('ping from ' + this.options.name);
    },
};

var PingPong = Object.create(Ping);
PingPong.pong = function () {
  log('pong from ' + this.options.name);
};

PingPong.pingpong = function () {
    this.ping();
    this.pong();
};

var pingPong = Object.create(PingPong);
pingPong.options.name = "PingPong1";
pingPong.ping();
pingPong.pong();
try {
    pingPong.ing.ping();
} catch (e) {
    log(e);
}
log(typeof pingPong.ping);
pingPong.pingpong();
<commit_msg>PingPong with a setName<commit_after>"use strict";
log('running deepdeligations.js');

var Ping = {
    options: {
        name: 'name not set',
    },
    ping: function () {
        log('ping from ' + this.options.name);
    },
    setName: function (name) {
        this.options.name = name;
    }
};

var PingPong = Object.create(Ping);
PingPong.pong = function () {
  log('pong from ' + this.options.name);
};

PingPong.pingpong = function () {
    this.ping();
    this.pong();
};

var pingPong = Object.create(PingPong);
pingPong.setName("PingPong1");
pingPong.ping();
pingPong.pong();
try {
    pingPong.ing.ping();
} catch (e) {
    log(e);
}
log(typeof pingPong.ping);
pingPong.pingpong();
<|endoftext|>


<commit_before>
"use strict";

$(function () {
  // Read templates (html) and save for later use.
  Template.html( $('#templates').html() );
});

// ================================================================
// ================== Events ======================================
// ================================================================

create_event('template compiled');

// ================================================================
// ================== Templates ===================================
// ================================================================

var Template = {

  FNS         : {},
  VARS_REGEXP : /\{([^\}]+)\}/g,

  html : function (html) {
    if (html)
      this._html = $(html);
    if (!this._html)
      throw new Error('Template HTML not ready.');
    return this._html;
  },

  read : function (se) {
    var t = Template.html().closest(se);
    if (!t)
      throw new Error('Template not found: ' + se);
    return outer_html(t).replace(this.VARS_REGEXP, "<%- $1 %>");
  },

  compile: function (se, data) {
    if (!this.FNS[se])
      this.FNS[se] = _.template(this.read(se));

    var o = $(this.FNS[se](data));
    emit('template compiled', {dom: o});
    return o;
  }

}; // === Template

<commit_msg>Fixed: Template was not finding nested.<commit_after>
"use strict";

$(function () {
  // Read templates (html) and save for later use.
  Template.html( $('#templates').html() );
});

// ================================================================
// ================== Events ======================================
// ================================================================

create_event('template compiled');

// ================================================================
// ================== Templates ===================================
// ================================================================

var Template = {

  FNS         : {},
  VARS_REGEXP : /\{([^\}]+)\}/g,

  html : function (html) {
    if (html)
      this._html = $(html).wrap('<p/>').parent();
    if (!this._html)
      throw new Error('Template HTML not ready.');
    return this._html;
  },

  read : function (se) {
    var t = Template.html().find(se);
    if (!t.length)
      throw new Error('Template not found: ' + se);
    return outer_html(t).replace(this.VARS_REGEXP, "<%- $1 %>");
  },

  compile: function (se, data) {
    if (!this.FNS[se])
      this.FNS[se] = _.template(this.read(se));

    var o = $(this.FNS[se](data));
    emit('template compiled', {dom: o});
    return o;
  }

}; // === Template

<|endoftext|>