<commit_before>/**
 * Created by bdunn and ssreedharan on 18/09/2014.
 */
module.exports = exports = Validator;

function Validator(swagger) {
    this.customValidators = {};
    if(!(this instanceof Validator)) {
        return new Validator(swagger);
    }

    var self = this;

    this.swagger = swagger;
    if(swagger) {
        swagger.validateModel = function(modelName, obj, allowBlankTarget) {
            // this is now going to run in the scope of swagger...
            var model = modelName;
            if(isStringType(modelName))
            {
                model = this.allModels[modelName];
            }

            return validate(obj, model, this.allModels, allowBlankTarget, self.customValidators);
        };
    }
}

Validator.prototype.validate = function(target, swaggerModel, swaggerModels, allowBlankTarget) {
    return validate(target, swaggerModel, swaggerModels, allowBlankTarget, this.customValidators);
};

Validator.prototype.addFieldValidator = function(modelName, fieldName, validatorFunction){
    if(!modelName) {
        throw new Error("ModelName is required");
    } else if(typeof modelName !== 'string') {
        throw new Error("ModelName must be a string");
    }

    if(!fieldName) {
        throw new Error("FieldName is required");
    } else if(typeof fieldName !== 'string') {
        throw new Error("FieldName must be a string");
    }

    if(!validatorFunction) {
        throw new Error("ValidatorFunction is required");
    } else if(typeof validatorFunction !== 'function') {
        throw new Error("ValidatorFunction is not a function");
    }

    var modelValidator = this.customValidators[modelName];
    if(!modelValidator) {
        modelValidator = {};
        modelValidator[fieldName] = [ validatorFunction ];
        this.customValidators[modelName] = modelValidator;
        return true;
    } else {
        var fieldValidators = modelValidator[fieldName];
        if(!fieldValidators) {
            fieldValidators = [ validatorFunction ];
            modelValidator[fieldName] = fieldValidators;
            return true;
        } else {
            fieldValidators.push(validatorFunction);
            return true;
        }
    }

    return false;
};

Validator.prototype.getFieldValidators = function(modelName, fieldName){
    return getCustomValidators(modelName, fieldName, this.customValidators);
};

function getCustomValidators(modelName, fieldName, validators) {
    if(validators) {
        if (!validators[modelName]) {
            return null;
        } else if (!validators[modelName][fieldName]) {
            return null;
        } else {
            return validators[modelName][fieldName];
        }
    }

    return null;
}

function validate(target, swaggerModel, swaggerModels, allowBlankTargets, customValidators) {
    if(swaggerModels === true && allowBlankTargets === undefined) {
        allowBlankTargets = true;
        swaggerModels = undefined;
    } else if(swaggerModels === false || swaggerModels === null) {
            swaggerModels = undefined;
    }

    if(!target) {
        return createReturnObject(new Error('Unable to validate an undefined value.'));
    } else if(allowBlankTargets !== true && isEmpty(target)) {
        return createReturnObject((new Error('Unable to validate an empty value.')));
    }

    if(typeof target !== "object") {
        return createReturnObject(new Error('Unable to validate a model that is not proper JSON'));
    }
    if(!swaggerModel) {
        return createReturnObject(new Error('Unable to validate against an undefined model.'));
    }

    var requireFieldErrs;

    if(swaggerModel.required && swaggerModel.required.length > 0) {
        requireFieldErrs = validateRequiredFields(target, swaggerModel.required);
        if (requireFieldErrs) {
            return createReturnObject(requireFieldErrs);
        }
    }

    var validationErrs = validateSpec(target, swaggerModel, swaggerModels, customValidators);

    if (validationErrs) {
        return createReturnObject(validationErrs, swaggerModel.id);
    } else {
        return createReturnObject();
    }
}

function isEmpty(target) {
    for(var p in target) {
        if(target[p] != target.constructor.prototype[p]) {
            return false;
        }
    }
    return true;
}

function createReturnObject(errors, modelName) {
    var result = {
    };

    if(!errors) {
        result.valid = true;
        result.errorCount = 0;
    } else {
        result.valid = false;
        if(!errors.message) {
            result.errorCount = errors.length;
            result.errors = errors;
        } else {
            result.errorCount = 1;
            result.errors = [ errors ];
        }
    }

    if(modelName) {
        result.modelName = modelName;
    }

    return result;
}

function validateSpec(target, model, models, customValidators) {
    var properties = model.properties;
    var errors = [];
    if(!properties) {
        return null;
    }

    for(key in properties) {
        var field = properties[key];
        var value = target[key];

        if (value !== undefined) {
            var valueErrors = validateValue(key, field, value, models);

            if(!valueErrors) {
                valueErrors = validateCustom(model.id, key, value, customValidators);
            }

            if (valueErrors) {
                valueErrors.forEach(function (error) {
                    errors.push(error);
                })
            }
        }
    }

    return errors.length > 0 ? errors : null;
}

function validateCustom(modelName, name, value, customValidators) {
    var validations = getCustomValidators(modelName, name, customValidators);

    if(!validations) {
        return null;
    }
    var errors = [];
    validations.forEach(function(validation) {
        try {
            var validationErrors = validation(name, value);

            if (validationErrors) {
                if (validationErrors.message) {
                    errors.push(validationErrors);
                } else {
                    validationErrors.forEach(function (validationError) {
                        errors.push(validationError);
                    });
                }
            }
        } catch(e) {
            console.warn(error);
        }
    });

    return errors.length > 0 ? errors : null;
};

function validateValue(key, field, value, models) {
    var errors = [];
    if(value !== undefined) {
        var typeErr = validateType(key, value, field, models);
        if (typeErr) {
            if (typeErr.valid === undefined) {
                errors.push(typeErr);
                return errors;
            } else if (!typeErr.valid) {
                typeErr.errors.forEach(function (error) {
                    errors.push(error);
                });
                return errors;
            } else {
                return null;
            }
        }

        if(field.validatedType === 'string') {
            if (field.minLength > 0 || field.maxLength > 0) {
                var err = validateMinMaxLength(key, value, field.minLength, field.maxLength);
                if (err) errors.push(err);
            }
        }
        if(field.type === 'integer' || field.type === 'number' || field.validatedType === 'date' || field.validatedType === 'date-time') {
            if (field.minimum || field.maximum) {
                var err = validateMinMaxValue(key, value, field.minimum, field.maximum);
                if (err) errors.push(err);
            }

            if (field.exclusiveMinimum || field.exclusiveMaximum) {
                var minimum;
                var maximum;
                if(field.exclusiveMinimum || field.exclusiveMinimum === 0) {
                    minimum = field.exclusiveMinimum + 1;
                }
                if(field.exclusiveMaximum || field.exclusiveMaximum === 0) {
                    maximum = field.exclusiveMaximum - 1;
                }
                if (field.validatedType === "date" || field.validatedType === 'date-time') {
                    if(field.exclusiveMinimum) minimum = incrementDateString(field.exclusiveMinimum, 1);
                    if(field.exclusiveMaximum) maximum = incrementDateString(field.exclusiveMaximum, -1);
                    value = new Date(value).toISOString();
                } else if(field.type === 'number' || field.validatedType === 'float' || field.validatedType === 'double') {
                    if(field.exclusiveMinimum) minimum = field.exclusiveMinimum + 0.00000000001;
                    if(field.exclusiveMaximum) maximum = field.exclusiveMaximum - 0.00000000001;
                }
                var err = validateMinMaxValue(key, value, minimum, maximum, true);
                if (err) errors.push(err);
            }
        }

        if (field.enum) {
            var err = validateEnums(key, value, field.enum);
            if (err) errors.push(err);
        }
    }

    return errors.length > 0 ? errors : null;
}

function validateType(name, property, field, models) {

    var expectedType = field.type;
    if(!expectedType) {
        if(models && field.$ref) {
            return validate(property, models[field.$ref], models);
        } else {
            return null;
        }
    } else {
        expectedType = expectedType.toLowerCase();
    }

    if(expectedType === 'array') {
        if(field.items && field.items.type) {
            // These items are a baser type and not a referenced model
            var fieldType = field.items.type;
            var count = 0;
            var arrayErrors = []
            property.forEach(function (value) {
                var errors =  validateValue(name + count.toString(), field.items, value, models)
                if(errors) {
                    errors.forEach(function(error) {
                        arrayErrors.push(error);
                    });
                }
                count = count + 1;
            });

            if(arrayErrors.length > 0) {
                return createReturnObject(arrayErrors, "Array of " + fieldType + " (" + name + ")");
            }
        } else if(models && field.items && field.items.$ref) {
            // These items are a referenced model
            var model = models[field.items.$ref];
            if(model) {
                var count = 0;
                var arrayErrors = [];
                property.forEach(function(value) {
                    var errors = validate(value, model.properties, models);
                    if(errors && !errors.valid) {
                        errors.errors.forEach(function(error) {
                            arrayErrors.push(error);
                        })
                    }
                })

                if(arrayErrors.length > 0) {
                    return createReturnObject(arrayErrors, "Array of " + field.items.$ref + " (" + name + ")");
                }
            }
        }
        // We can't do arrays yet but we need to make sure that they do not fail.
        return null;
    }

    var format = field.format;
    if(format) {
        format = format.toLowerCase();
    }

    if(property === undefined) {
        return null;
    }

    if(expectedType === 'string') {
        if (isStringType(property, format)) {
            field.validatedType = format || expectedType;
            return null;
        }
    } else if(expectedType === 'boolean') {
        if(isExpectedType(property, expectedType)) {
            field.validatedType = format || expectedType;
            return null;
        }
    } else if(expectedType === 'integer') {
        if(isIntegerType(property, format)) {
            field.validatedType = format || expectedType;
            return null;
        }
    } else if(expectedType === 'number') {
        if(isNumberType(property, format)) {
            field.validatedType = format || expectedType;
            return null;
        }
    }

    //if(!format) {
        return new Error(name + ' (' + wrapNUllProperty(property) + ') is not a type of ' + (format || expectedType));
    //} else {
    //    return new Error(name + ' (' + wrapNUllProperty(property) + ') is not a type of ' + format)
    //}
}

function isStringType(property, format) {
    if (isExpectedType(property, 'string')) {
        if(!format) {
            return true;
        } else if(format === 'date' || format === 'date-time') {
            var date = new Date(property);
            if(date !== "Invalid Date" && !isNaN(date) && isNaN(property)) {
                if(format === 'date' && property.length !== 10) {
                    return false;
                }
                return true;
            }
        }
    }
    return false;
}

function isIntegerType(property, format) {
    if(!format) {
        if(isNumberType(property)) {
            return true;
        }
    } else if(format === 'int32') {
        var int32Max = Math.pow(2, 31) - 1;
        var value = parseInt(property);
        if(!isNaN(value) && isFinite(property) && value >= -(int32Max + 1) && value <= int32Max) {
            return true;
        }
    } else if(format === 'int64') {
        var value = parseInt(property);
        if(!isNaN(value) && isFinite(property)) {
            return true;
        }
    }
    return false;
}

function isNumberType(property, format) {
    if(!format || format === 'float' || format === 'double') {
        if (!isNaN(parseFloat(property)) && isFinite(property)) {
            return true;
        }
    }
    return false;
}

function isExpectedType(property, expectedType) {
    if (typeof property === expectedType) {
        return true;
    }
    return false;
}

function wrapNUllProperty(property) {
    if(property === null) {
        return "{null}";
    }
    if(property === "") {
        return "{empty string}";
    }

    return property;
}

function validateMinLength(name, value, minLength) {
    if(minLength > 0) {
        if(value.length < minLength) {
            if(minLength === 1) {
                return new Error(name + ' cannot be blank');
            }
            return new Error(name + ' must be at least ' + minLength.toString() + ' characters long');
        }
    }
    return null;
}

function validateMaxLength(name, value, maxLength) {
    if(maxLength > 0) {
        if(value.length > maxLength) {
            return new Error(name + ' must be no more than ' + maxLength.toString() + ' characters long');
        }
    }
    return null;
}

function validateMinMaxLength(name, value, minLength, maxLength) {
    if(!minLength && !maxLength) {
        return null;
    } else if(!minLength) {
        return validateMaxLength(name, value, maxLength);
    } else if(!maxLength) {
        return validateMinLength(name, value, minLength);
    }
    if(value.length < minLength || value.length > maxLength){
        if(minLength === 1) {
            return new Error(name + ' cannot be blank and cannot be longer than ' + maxLength.toString() + ' characters long');
        }
        return new Error(name + ' must be at least ' + minLength.toString() + ' characters long and no more than ' + maxLength.toString() + ' characters long');
    }
    return null;
}

function validateMinValue(name, value, minValue) {
    if(minValue || minValue === 0) {
        if(value < minValue) {
            return new Error(name + ' must be at least ' + minValue.toString());
        }
    }
    return null;
}

function validateMaxValue(name, value, maxValue) {
    if(maxValue || maxValue === 0) {
        if(value > maxValue) {
            return new Error(name + ' must be no more than ' + maxValue.toString());
        }
    }
    return null;
}

function validateMinMaxValue(name, value, minValue, maxValue, exclusive) {
    if(exclusive) {

    }
    if(!minValue && !maxValue) {
        return null;
    } else if(!minValue) {
        return validateMaxValue(name, value, maxValue);
    } else if(!maxValue) {
        return validateMinValue(name, value, minValue);
    }

    if(value < minValue || value > maxValue) {
        return new Error(name + ' must be at least ' + minValue.toString() + ' and no more than ' + maxLength.toString());
    }
    return null;
}

function validateRequiredFields(object, fields) {
    if (!(fields instanceof Array)) {
        throw new Error('fields must be an array of required fields');
    }

    var errors = [];
    for (var i = 0; i < fields.length; ++i) {
        var property = fields[i];
        try {
            if(!object.hasOwnProperty(property) || object[property] === "") {
                errors.push(new Error(property + ' is a required field'));
            }
        } catch (e) {
            errors.push(new Error('object does not have property ' + property));
        }

    }

    return errors.length > 0 ? errors : null;
}

function validateEnums(name, value, enums) {
    for(var index in enums) {
        if(value === enums[index]) {
            return null;
        }
    }

    return new Error(name + ' is not set to an allowed value (see enum)');
}

function incrementDateString(dateString, increment) {
    var incrementingDate = new Date(dateString);
    incrementingDate.setMilliseconds(incrementingDate.getMilliseconds() + increment);
    return incrementingDate.toISOString();
}<commit_msg>Resolve #21 raised by @sgajavada<commit_after>/**
 * Created by bdunn and ssreedharan on 18/09/2014.
 */
module.exports = exports = Validator;

function Validator(swagger) {
    this.customValidators = {};
    if(!(this instanceof Validator)) {
        return new Validator(swagger);
    }

    var self = this;

    this.swagger = swagger;
    if(swagger) {
        swagger.validateModel = function(modelName, obj, allowBlankTarget) {
            // this is now going to run in the scope of swagger...
            var model = modelName;
            if(isStringType(modelName))
            {
                model = this.allModels[modelName];
            }

            return validate(obj, model, this.allModels, allowBlankTarget, self.customValidators);
        };
    }
}

Validator.prototype.validate = function(target, swaggerModel, swaggerModels, allowBlankTarget) {
    return validate(target, swaggerModel, swaggerModels, allowBlankTarget, this.customValidators);
};

Validator.prototype.addFieldValidator = function(modelName, fieldName, validatorFunction){
    if(!modelName) {
        throw new Error("ModelName is required");
    } else if(typeof modelName !== 'string') {
        throw new Error("ModelName must be a string");
    }

    if(!fieldName) {
        throw new Error("FieldName is required");
    } else if(typeof fieldName !== 'string') {
        throw new Error("FieldName must be a string");
    }

    if(!validatorFunction) {
        throw new Error("ValidatorFunction is required");
    } else if(typeof validatorFunction !== 'function') {
        throw new Error("ValidatorFunction is not a function");
    }

    var modelValidator = this.customValidators[modelName];
    if(!modelValidator) {
        modelValidator = {};
        modelValidator[fieldName] = [ validatorFunction ];
        this.customValidators[modelName] = modelValidator;
        return true;
    } else {
        var fieldValidators = modelValidator[fieldName];
        if(!fieldValidators) {
            fieldValidators = [ validatorFunction ];
            modelValidator[fieldName] = fieldValidators;
            return true;
        } else {
            fieldValidators.push(validatorFunction);
            return true;
        }
    }

    return false;
};

Validator.prototype.getFieldValidators = function(modelName, fieldName){
    return getCustomValidators(modelName, fieldName, this.customValidators);
};

function getCustomValidators(modelName, fieldName, validators) {
    if(validators) {
        if (!validators[modelName]) {
            return null;
        } else if (!validators[modelName][fieldName]) {
            return null;
        } else {
            return validators[modelName][fieldName];
        }
    }

    return null;
}

function validate(target, swaggerModel, swaggerModels, allowBlankTargets, customValidators) {
    if(swaggerModels === true && allowBlankTargets === undefined) {
        allowBlankTargets = true;
        swaggerModels = undefined;
    } else if(swaggerModels === false || swaggerModels === null) {
            swaggerModels = undefined;
    }

    if(!target) {
        return createReturnObject(new Error('Unable to validate an undefined value.'));
    } else if(allowBlankTargets !== true && isEmpty(target)) {
        return createReturnObject((new Error('Unable to validate an empty value.')));
    }

    if(typeof target !== "object") {
        return createReturnObject(new Error('Unable to validate a model that is not proper JSON'));
    }
    if(!swaggerModel) {
        return createReturnObject(new Error('Unable to validate against an undefined model.'));
    }

    var requireFieldErrs;

    if(swaggerModel.required && swaggerModel.required.length > 0) {
        requireFieldErrs = validateRequiredFields(target, swaggerModel.required);
        if (requireFieldErrs) {
            return createReturnObject(requireFieldErrs);
        }
    }

    var validationErrs = validateSpec(target, swaggerModel, swaggerModels, customValidators);

    if (validationErrs) {
        return createReturnObject(validationErrs, swaggerModel.id);
    } else {
        return createReturnObject();
    }
}

function isEmpty(target) {
    for(var p in target) {
        if(target[p] != target.constructor.prototype[p]) {
            return false;
        }
    }
    return true;
}

function createReturnObject(errors, modelName) {
    var result = {
    };

    if(!errors) {
        result.valid = true;
        result.errorCount = 0;
    } else {
        result.valid = false;
        if(!errors.message) {
            result.errorCount = errors.length;
            result.errors = errors;
        } else {
            result.errorCount = 1;
            result.errors = [ errors ];
        }
    }

    if(modelName) {
        result.modelName = modelName;
    }

    return result;
}

function validateSpec(target, model, models, customValidators) {
    var properties = model.properties;
    var errors = [];
    if(!properties) {
        return null;
    }

    for(key in properties) {
        var field = properties[key];
        var value = target[key];

        if (value !== undefined) {
            var valueErrors = validateValue(key, field, value, models);

            if(!valueErrors) {
                valueErrors = validateCustom(model.id, key, value, customValidators);
            }

            if (valueErrors) {
                valueErrors.forEach(function (error) {
                    errors.push(error);
                })
            }
        }
    }

    return errors.length > 0 ? errors : null;
}

function validateCustom(modelName, name, value, customValidators) {
    var validations = getCustomValidators(modelName, name, customValidators);

    if(!validations) {
        return null;
    }
    var errors = [];
    validations.forEach(function(validation) {
        try {
            var validationErrors = validation(name, value);

            if (validationErrors) {
                if (validationErrors.message) {
                    errors.push(validationErrors);
                } else {
                    validationErrors.forEach(function (validationError) {
                        errors.push(validationError);
                    });
                }
            }
        } catch(e) {
            console.warn(error);
        }
    });

    return errors.length > 0 ? errors : null;
};

function validateValue(key, field, value, models) {
    var errors = [];
    if(value !== undefined) {
        var typeErr = validateType(key, value, field, models);
        if (typeErr) {
            if (typeErr.valid === undefined) {
                errors.push(typeErr);
                return errors;
            } else if (!typeErr.valid) {
                typeErr.errors.forEach(function (error) {
                    errors.push(error);
                });
                return errors;
            } else {
                return null;
            }
        }

        if(field.validatedType === 'string') {
            if (field.minLength > 0 || field.maxLength > 0) {
                var err = validateMinMaxLength(key, value, field.minLength, field.maxLength);
                if (err) errors.push(err);
            }
        }
        if(field.type === 'integer' || field.type === 'number' || field.validatedType === 'date' || field.validatedType === 'date-time') {
            if (field.minimum || field.maximum) {
                var err = validateMinMaxValue(key, value, field.minimum, field.maximum);
                if (err) errors.push(err);
            }

            if (field.exclusiveMinimum || field.exclusiveMaximum) {
                var minimum;
                var maximum;
                if(field.exclusiveMinimum || field.exclusiveMinimum === 0) {
                    minimum = field.exclusiveMinimum + 1;
                }
                if(field.exclusiveMaximum || field.exclusiveMaximum === 0) {
                    maximum = field.exclusiveMaximum - 1;
                }
                if (field.validatedType === "date" || field.validatedType === 'date-time') {
                    if(field.exclusiveMinimum) minimum = incrementDateString(field.exclusiveMinimum, 1);
                    if(field.exclusiveMaximum) maximum = incrementDateString(field.exclusiveMaximum, -1);
                    value = new Date(value).toISOString();
                } else if(field.type === 'number' || field.validatedType === 'float' || field.validatedType === 'double') {
                    if(field.exclusiveMinimum) minimum = field.exclusiveMinimum + 0.00000000001;
                    if(field.exclusiveMaximum) maximum = field.exclusiveMaximum - 0.00000000001;
                }
                var err = validateMinMaxValue(key, value, minimum, maximum, true);
                if (err) errors.push(err);
            }
        }

        if (field.enum) {
            var err = validateEnums(key, value, field.enum);
            if (err) errors.push(err);
        }
    }

    return errors.length > 0 ? errors : null;
}

function validateType(name, property, field, models) {

    var expectedType = field.type;
    if(!expectedType) {
        if(models && field.$ref) {
            return validate(property, models[field.$ref], models);
        } else {
            return null;
        }
    } else {
        expectedType = expectedType.toLowerCase();
    }

    if(expectedType === 'array') {
        if(field.items && field.items.type) {
            // These items are a baser type and not a referenced model
            var fieldType = field.items.type;
            var count = 0;
            var arrayErrors = []
            property.forEach(function (value) {
                var errors =  validateValue(name + count.toString(), field.items, value, models)
                if(errors) {
                    errors.forEach(function(error) {
                        arrayErrors.push(error);
                    });
                }
                count = count + 1;
            });

            if(arrayErrors.length > 0) {
                return createReturnObject(arrayErrors, "Array of " + fieldType + " (" + name + ")");
            }
        } else if(models && field.items && field.items.$ref) {
            // These items are a referenced model
            var model = models[field.items.$ref];
            if(model) {
                var count = 0;
                var arrayErrors = [];
                property.forEach(function(value) {
                    var errors = validate(value, model, models);
                    if(errors && !errors.valid) {
                        errors.errors.forEach(function(error) {
                            arrayErrors.push(error);
                        })
                    }
                });

                if(arrayErrors.length > 0) {
                    return createReturnObject(arrayErrors, "Array of " + field.items.$ref + " (" + name + ")");
                }
            }
        }
        // We can't do arrays yet but we need to make sure that they do not fail.
        return null;
    }

    var format = field.format;
    if(format) {
        format = format.toLowerCase();
    }

    if(property === undefined) {
        return null;
    }

    if(expectedType === 'string') {
        if (isStringType(property, format)) {
            field.validatedType = format || expectedType;
            return null;
        }
    } else if(expectedType === 'boolean') {
        if(isExpectedType(property, expectedType)) {
            field.validatedType = format || expectedType;
            return null;
        }
    } else if(expectedType === 'integer') {
        if(isIntegerType(property, format)) {
            field.validatedType = format || expectedType;
            return null;
        }
    } else if(expectedType === 'number') {
        if(isNumberType(property, format)) {
            field.validatedType = format || expectedType;
            return null;
        }
    }

    //if(!format) {
        return new Error(name + ' (' + wrapNUllProperty(property) + ') is not a type of ' + (format || expectedType));
    //} else {
    //    return new Error(name + ' (' + wrapNUllProperty(property) + ') is not a type of ' + format)
    //}
}

function isStringType(property, format) {
    if (isExpectedType(property, 'string')) {
        if(!format) {
            return true;
        } else if(format === 'date' || format === 'date-time') {
            var date = new Date(property);
            if(date !== "Invalid Date" && !isNaN(date) && isNaN(property)) {
                if(format === 'date' && property.length !== 10) {
                    return false;
                }
                return true;
            }
        }
    }
    return false;
}

function isIntegerType(property, format) {
    if(!format) {
        if(isNumberType(property)) {
            return true;
        }
    } else if(format === 'int32') {
        var int32Max = Math.pow(2, 31) - 1;
        var value = parseInt(property);
        if(!isNaN(value) && isFinite(property) && value >= -(int32Max + 1) && value <= int32Max) {
            return true;
        }
    } else if(format === 'int64') {
        var value = parseInt(property);
        if(!isNaN(value) && isFinite(property)) {
            return true;
        }
    }
    return false;
}

function isNumberType(property, format) {
    if(!format || format === 'float' || format === 'double') {
        if (!isNaN(parseFloat(property)) && isFinite(property)) {
            return true;
        }
    }
    return false;
}

function isExpectedType(property, expectedType) {
    if (typeof property === expectedType) {
        return true;
    }
    return false;
}

function wrapNUllProperty(property) {
    if(property === null) {
        return "{null}";
    }
    if(property === "") {
        return "{empty string}";
    }

    return property;
}

function validateMinLength(name, value, minLength) {
    if(minLength > 0) {
        if(value.length < minLength) {
            if(minLength === 1) {
                return new Error(name + ' cannot be blank');
            }
            return new Error(name + ' must be at least ' + minLength.toString() + ' characters long');
        }
    }
    return null;
}

function validateMaxLength(name, value, maxLength) {
    if(maxLength > 0) {
        if(value.length > maxLength) {
            return new Error(name + ' must be no more than ' + maxLength.toString() + ' characters long');
        }
    }
    return null;
}

function validateMinMaxLength(name, value, minLength, maxLength) {
    if(!minLength && !maxLength) {
        return null;
    } else if(!minLength) {
        return validateMaxLength(name, value, maxLength);
    } else if(!maxLength) {
        return validateMinLength(name, value, minLength);
    }
    if(value.length < minLength || value.length > maxLength){
        if(minLength === 1) {
            return new Error(name + ' cannot be blank and cannot be longer than ' + maxLength.toString() + ' characters long');
        }
        return new Error(name + ' must be at least ' + minLength.toString() + ' characters long and no more than ' + maxLength.toString() + ' characters long');
    }
    return null;
}

function validateMinValue(name, value, minValue) {
    if(minValue || minValue === 0) {
        if(value < minValue) {
            return new Error(name + ' must be at least ' + minValue.toString());
        }
    }
    return null;
}

function validateMaxValue(name, value, maxValue) {
    if(maxValue || maxValue === 0) {
        if(value > maxValue) {
            return new Error(name + ' must be no more than ' + maxValue.toString());
        }
    }
    return null;
}

function validateMinMaxValue(name, value, minValue, maxValue, exclusive) {
    if(exclusive) {

    }
    if(!minValue && !maxValue) {
        return null;
    } else if(!minValue) {
        return validateMaxValue(name, value, maxValue);
    } else if(!maxValue) {
        return validateMinValue(name, value, minValue);
    }

    if(value < minValue || value > maxValue) {
        return new Error(name + ' must be at least ' + minValue.toString() + ' and no more than ' + maxLength.toString());
    }
    return null;
}

function validateRequiredFields(object, fields) {
    if (!(fields instanceof Array)) {
        throw new Error('fields must be an array of required fields');
    }

    var errors = [];
    for (var i = 0; i < fields.length; ++i) {
        var property = fields[i];
        try {
            if(!object.hasOwnProperty(property) || object[property] === "") {
                errors.push(new Error(property + ' is a required field'));
            }
        } catch (e) {
            errors.push(new Error('object does not have property ' + property));
        }

    }

    return errors.length > 0 ? errors : null;
}

function validateEnums(name, value, enums) {
    for(var index in enums) {
        if(value === enums[index]) {
            return null;
        }
    }

    return new Error(name + ' is not set to an allowed value (see enum)');
}

function incrementDateString(dateString, increment) {
    var incrementingDate = new Date(dateString);
    incrementingDate.setMilliseconds(incrementingDate.getMilliseconds() + increment);
    return incrementingDate.toISOString();
}<|endoftext|>


<commit_before>/**
 * @copyright Copyright 2016 Kevin Locke <kevin@kevinlocke.name>
 * @license MIT
 */

'use strict';

var gitBranchIs = require('..');

var BBPromise = require('bluebird').Promise;
// eslint-disable-next-line no-undef
var PPromise = typeof Promise === 'function' ? Promise : BBPromise;
var assert = require('assert');
var assertMatch = require('../test-lib/assert-match');
var constants = require('../test-lib/constants');
var path = require('path');

// Local copy of shared constants
var BRANCH_CURRENT = constants.BRANCH_CURRENT;
var BRANCH_NON_EXISTENT = constants.BRANCH_NON_EXISTENT;
var BRANCH_SAME_COMMIT = constants.BRANCH_SAME_COMMIT;
var SUBDIR_NAME = constants.SUBDIR_NAME;
var TEST_REPO_PATH = constants.TEST_REPO_PATH;

describe('gitBranchIs', function() {
  it('callback true for current branch name', function(done) {
    gitBranchIs(BRANCH_CURRENT, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('callback false for non-existent branch name', function(done) {
    gitBranchIs(BRANCH_NON_EXISTENT, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, false);
      done();
    });
  });

  it('callback false for different branch, same commit', function(done) {
    gitBranchIs(BRANCH_SAME_COMMIT, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, false);
      done();
    });
  });

  it('callback true for same branch name in subdir', function(done) {
    gitBranchIs(BRANCH_CURRENT, {cwd: SUBDIR_NAME}, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('can specify additional git arguments', function(done) {
    var options = {
      cwd: '..',
      gitArgs: ['-C', TEST_REPO_PATH]
    };
    gitBranchIs(BRANCH_CURRENT, options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('gitArgs takes precedence over gitDir', function(done) {
    var options = {
      gitArgs: ['--git-dir=.git'],
      gitDir: 'invalid'
    };
    gitBranchIs(BRANCH_CURRENT, options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('can specify git executable and args', function(done) {
    var options = {
      gitArgs: [path.join('..', 'test-bin', 'echo-surprise.js')],
      gitPath: process.execPath
    };
    gitBranchIs('surprise', options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('callback Error outside of git repo', function(done) {
    gitBranchIs(BRANCH_CURRENT, {cwd: '/'}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  it('callback Error if cwd doesn\'t exist', function(done) {
    gitBranchIs(BRANCH_CURRENT, {cwd: 'invalid'}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  it('callback Error if git is not executable', function(done) {
    var badGitPath = path.join(__dirname, '..', 'package.json');
    gitBranchIs(BRANCH_CURRENT, {gitPath: badGitPath}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  it('callback Error if gitDir is not a git repo', function(done) {
    gitBranchIs(BRANCH_CURRENT, {gitDir: SUBDIR_NAME}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  // Just like git -C and --git-dir
  it('gitDir is relative to cwd', function(done) {
    var options = {
      cwd: SUBDIR_NAME,
      gitDir: path.join('..', '.git')
    };
    gitBranchIs(BRANCH_CURRENT, options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('gitPath is relative to cwd', function(done) {
    var options = {
      cwd: SUBDIR_NAME,
      gitArgs: [path.join('..', '..', 'test-bin', 'echo-surprise.js')],
      gitPath: path.relative(SUBDIR_NAME, process.execPath)
    };
    gitBranchIs('surprise', options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  describe('.getBranch()', function() {
    it('gets the branch name', function(done) {
      gitBranchIs.getBranch(function(err, result) {
        assert.ifError(err);
        assert.strictEqual(result, BRANCH_CURRENT);
        done();
      });
    });
  });

  describe('with global Promise', function() {
    var hadPromise, oldPromise;

    before('ensure global Promise', function() {
      if (global.Promise !== PPromise) {
        hadPromise = hasOwnProperty.call(global, 'Promise');
        oldPromise = global.Promise;
        global.Promise = PPromise;
      }
    });

    after('restore global Promise', function() {
      if (hadPromise === true) {
        global.Promise = oldPromise;
      } else if (hadPromise === false) {
        delete global.Promise;
      }
    });

    it('Promise resolves true for same branch name', function() {
      var promise = gitBranchIs(BRANCH_CURRENT);
      assert(promise instanceof global.Promise);
      return promise.then(function(result) {
        assert.strictEqual(result, true);
      });
    });

    it('Promise resolves false for different branch name', function() {
      var promise = gitBranchIs('invalid');
      assert(promise instanceof global.Promise);
      return promise.then(function(result) {
        assert.strictEqual(result, false);
      });
    });

    it('Promise rejects on Error', function() {
      var promise = gitBranchIs(BRANCH_CURRENT, 'opts');
      assert(promise instanceof global.Promise);
      return promise.then(
          function(result) { throw new Error('expecting Error'); },
          function(err) {
            assert(err instanceof TypeError);
            assertMatch(err.message, /\boptions\b/);
          }
      );
    });

    describe('.getBranch()', function() {
      it('resolves to the branch name', function() {
        var promise = gitBranchIs.getBranch();
        assert(promise instanceof global.Promise);
        return promise.then(function(result) {
          assert.strictEqual(result, BRANCH_CURRENT);
        });
      });

      it('rejects on Error', function() {
        var promise = gitBranchIs.getBranch(BRANCH_CURRENT);
        assert(promise instanceof global.Promise);
        return promise.then(
          function(result) { throw new Error('expecting Error'); },
          function(err) {
            assert(err instanceof TypeError);
            assertMatch(err.message, /\boptions\b/);
          }
        );
      });
    });
  });

  describe('without global Promise', function() {
    var hadPromise, oldPromise;

    before('remove global Promise', function() {
      if (global.Promise) {
        hadPromise = hasOwnProperty.call(global, 'Promise');
        oldPromise = global.Promise;
        // Note:  Deleting triggers Mocha's global leak detection.
        // Also wouldn't work if global scope had a prototype chain.
        global.Promise = undefined;
      }
    });

    after('restore global Promise', function() {
      if (oldPromise) {
        if (hadPromise) {
          global.Promise = oldPromise;
        } else {
          delete global.Promise;
        }
      }
    });

    it('throws without a callback', function() {
      assert.throws(
          function() {
            gitBranchIs(BRANCH_CURRENT);
          },
          function(err) {
            return err instanceof TypeError &&
                /\bcallback\b/.test(err.message);
          }
      );
    });

    describe('.getBranch()', function() {
      it('throws without a callback', function() {
        assert.throws(
            function() {
              gitBranchIs.getBranch();
            },
            function(err) {
              return err instanceof TypeError &&
                  /\bcallback\b/.test(err.message);
            }
        );
      });
    });
  });
});
<commit_msg>Test that gitArgs can be falsey<commit_after>/**
 * @copyright Copyright 2016 Kevin Locke <kevin@kevinlocke.name>
 * @license MIT
 */

'use strict';

var gitBranchIs = require('..');

var BBPromise = require('bluebird').Promise;
// eslint-disable-next-line no-undef
var PPromise = typeof Promise === 'function' ? Promise : BBPromise;
var assert = require('assert');
var assertMatch = require('../test-lib/assert-match');
var constants = require('../test-lib/constants');
var path = require('path');

// Local copy of shared constants
var BRANCH_CURRENT = constants.BRANCH_CURRENT;
var BRANCH_NON_EXISTENT = constants.BRANCH_NON_EXISTENT;
var BRANCH_SAME_COMMIT = constants.BRANCH_SAME_COMMIT;
var SUBDIR_NAME = constants.SUBDIR_NAME;
var TEST_REPO_PATH = constants.TEST_REPO_PATH;

describe('gitBranchIs', function() {
  it('callback true for current branch name', function(done) {
    gitBranchIs(BRANCH_CURRENT, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('callback false for non-existent branch name', function(done) {
    gitBranchIs(BRANCH_NON_EXISTENT, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, false);
      done();
    });
  });

  it('callback false for different branch, same commit', function(done) {
    gitBranchIs(BRANCH_SAME_COMMIT, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, false);
      done();
    });
  });

  it('callback true for same branch name in subdir', function(done) {
    gitBranchIs(BRANCH_CURRENT, {cwd: SUBDIR_NAME}, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('can specify additional git arguments', function(done) {
    var options = {
      cwd: '..',
      gitArgs: ['-C', TEST_REPO_PATH]
    };
    gitBranchIs(BRANCH_CURRENT, options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('null gitArgs is ignored', function(done) {
    gitBranchIs(BRANCH_CURRENT, {gitArgs: null}, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('gitArgs takes precedence over gitDir', function(done) {
    var options = {
      gitArgs: ['--git-dir=.git'],
      gitDir: 'invalid'
    };
    gitBranchIs(BRANCH_CURRENT, options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('can specify git executable and args', function(done) {
    var options = {
      gitArgs: [path.join('..', 'test-bin', 'echo-surprise.js')],
      gitPath: process.execPath
    };
    gitBranchIs('surprise', options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('callback Error outside of git repo', function(done) {
    gitBranchIs(BRANCH_CURRENT, {cwd: '/'}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  it('callback Error if cwd doesn\'t exist', function(done) {
    gitBranchIs(BRANCH_CURRENT, {cwd: 'invalid'}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  it('callback Error if git is not executable', function(done) {
    var badGitPath = path.join(__dirname, '..', 'package.json');
    gitBranchIs(BRANCH_CURRENT, {gitPath: badGitPath}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  it('callback Error if gitDir is not a git repo', function(done) {
    gitBranchIs(BRANCH_CURRENT, {gitDir: SUBDIR_NAME}, function(err, result) {
      assert(err instanceof Error);
      assert(result === undefined || result === null);
      done();
    });
  });

  // Just like git -C and --git-dir
  it('gitDir is relative to cwd', function(done) {
    var options = {
      cwd: SUBDIR_NAME,
      gitDir: path.join('..', '.git')
    };
    gitBranchIs(BRANCH_CURRENT, options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  it('gitPath is relative to cwd', function(done) {
    var options = {
      cwd: SUBDIR_NAME,
      gitArgs: [path.join('..', '..', 'test-bin', 'echo-surprise.js')],
      gitPath: path.relative(SUBDIR_NAME, process.execPath)
    };
    gitBranchIs('surprise', options, function(err, result) {
      assert.ifError(err);
      assert.strictEqual(result, true);
      done();
    });
  });

  describe('.getBranch()', function() {
    it('gets the branch name', function(done) {
      gitBranchIs.getBranch(function(err, result) {
        assert.ifError(err);
        assert.strictEqual(result, BRANCH_CURRENT);
        done();
      });
    });
  });

  describe('with global Promise', function() {
    var hadPromise, oldPromise;

    before('ensure global Promise', function() {
      if (global.Promise !== PPromise) {
        hadPromise = hasOwnProperty.call(global, 'Promise');
        oldPromise = global.Promise;
        global.Promise = PPromise;
      }
    });

    after('restore global Promise', function() {
      if (hadPromise === true) {
        global.Promise = oldPromise;
      } else if (hadPromise === false) {
        delete global.Promise;
      }
    });

    it('Promise resolves true for same branch name', function() {
      var promise = gitBranchIs(BRANCH_CURRENT);
      assert(promise instanceof global.Promise);
      return promise.then(function(result) {
        assert.strictEqual(result, true);
      });
    });

    it('Promise resolves false for different branch name', function() {
      var promise = gitBranchIs('invalid');
      assert(promise instanceof global.Promise);
      return promise.then(function(result) {
        assert.strictEqual(result, false);
      });
    });

    it('Promise rejects on Error', function() {
      var promise = gitBranchIs(BRANCH_CURRENT, 'opts');
      assert(promise instanceof global.Promise);
      return promise.then(
          function(result) { throw new Error('expecting Error'); },
          function(err) {
            assert(err instanceof TypeError);
            assertMatch(err.message, /\boptions\b/);
          }
      );
    });

    describe('.getBranch()', function() {
      it('resolves to the branch name', function() {
        var promise = gitBranchIs.getBranch();
        assert(promise instanceof global.Promise);
        return promise.then(function(result) {
          assert.strictEqual(result, BRANCH_CURRENT);
        });
      });

      it('rejects on Error', function() {
        var promise = gitBranchIs.getBranch(BRANCH_CURRENT);
        assert(promise instanceof global.Promise);
        return promise.then(
          function(result) { throw new Error('expecting Error'); },
          function(err) {
            assert(err instanceof TypeError);
            assertMatch(err.message, /\boptions\b/);
          }
        );
      });
    });
  });

  describe('without global Promise', function() {
    var hadPromise, oldPromise;

    before('remove global Promise', function() {
      if (global.Promise) {
        hadPromise = hasOwnProperty.call(global, 'Promise');
        oldPromise = global.Promise;
        // Note:  Deleting triggers Mocha's global leak detection.
        // Also wouldn't work if global scope had a prototype chain.
        global.Promise = undefined;
      }
    });

    after('restore global Promise', function() {
      if (oldPromise) {
        if (hadPromise) {
          global.Promise = oldPromise;
        } else {
          delete global.Promise;
        }
      }
    });

    it('throws without a callback', function() {
      assert.throws(
          function() {
            gitBranchIs(BRANCH_CURRENT);
          },
          function(err) {
            return err instanceof TypeError &&
                /\bcallback\b/.test(err.message);
          }
      );
    });

    describe('.getBranch()', function() {
      it('throws without a callback', function() {
        assert.throws(
            function() {
              gitBranchIs.getBranch();
            },
            function(err) {
              return err instanceof TypeError &&
                  /\bcallback\b/.test(err.message);
            }
        );
      });
    });
  });
});
<|endoftext|>


<commit_before>define(["Ti/_/declare", "Ti/_/event", "Ti/_/lang", "Ti/_/style", "Ti/_/UI/Widget", "Ti/UI", "Ti/Filesystem"],
	function(declare, event, lang, style, Widget, UI, Filesystem) {

	var setStyle = style.set,
		is = require.is,
		on = require.on,
		InternalImageView = declare(Widget, {

			domType: "img",
			onload: null,
			onerror: null,

			constructor: function() {
				this.domNode.ondragstart = function() { return false; }; // Prevent images from being dragged
			},

			_getContentSize: function() {
				return {
					width: this.domNode.width,
					height: this.domNode.height
				}
			},

			_preLayout: function(boundingWidth, boundingHeight, isParentWidthSize, isParentHeightSize) {
				// We have to remove the old style to get the image to scale to its default size,
				// otherwise we are just reading in whatever we set in the last doLayout(), which is
				// 0 if the image was not loaded...thus always clamping it to 0.
				this.domNode.style.width = "";
				this.domNode.style.height = "";

				var imageRatio = this.domNode.width / this.domNode.height,
					values = this.properties.__values__,
					oldWidth = values.width,
					oldHeight = values.height;

				if (!isParentWidthSize && !isParentHeightSize) {
					if (boundingWidth / boundingHeight > imageRatio) {
						values.width = boundingHeight * imageRatio;
						values.height = boundingHeight;
					} else {
						values.width = boundingWidth;
						values.height = boundingWidth / imageRatio;
					}
				} else if (!isParentWidthSize) {
					values.width = boundingWidth;
					values.height = boundingWidth / imageRatio;
				} else if (!isParentHeightSize) {
					values.width = boundingHeight * imageRatio;
					values.height = boundingHeight;
				} else {
					values.width = UI.SIZE;
					values.height = UI.SIZE;
				}

				return oldWidth !== values.width || oldHeight !== values.height;
			},

			_imageRatio: 1,

			properties: {
				src: {
					set: function(value) {
						var node = this.domNode,
							disp = "none",
							handles,
							onerror = lang.hitch(this, function(e) {
								event.off(handles);
								this._triggerLayout();
								this.onerror && this.onerror(e);
							});

						if (value) {
							disp = "inherit";
							handles = [
								on(node, "load", this, function() {
									node.style.width = "";
									node.style.height = "";
									var imageRatio = node.width / node.height;
									isNaN(imageRatio) && (imageRatio = node.width === 0 ? 1 : Infinity);
									this._imageRatio = imageRatio;
									this._triggerLayout();
									this.onload && this.onload();
								}),
								on(node, "error", onerror),
								on(node, "abort", onerror)
							];
							node.src = require.cache(value) || value;
						}

						setStyle(node, "display", disp);
						return value;
					}
				}
			}
		});

	return declare("Ti.UI.ImageView", Widget, {

		_createImage: function(src, onload, onerror) {
			var m = is(src, "String") && src.match(/^(.+)\:\/\//);
			m && ~Filesystem.protocols.indexOf(m[1]) && (src = Filesystem.getFile(src));
			switch (src && src.declaredClass) {
				case "Ti.Filesystem.File":
					src = src.read();
				case "Ti.Blob":
					src = src.toString();
			}
			return new InternalImageView({
				onload: onload,
				onerror: onerror,
				src: src
			});
		},

		_defaultWidth: UI.SIZE,

		_defaultHeight: UI.SIZE,

		_slideshowCount: 0,

		_setSlideshowInterval: function() {
			var self = this,
				imgs = self._images;
			clearInterval(this._slideshowTimer);

			this._slideshowTimer = setInterval(function(){
				var rollover = false;

				setStyle(imgs[self._currentIndex].domNode, "display", "none");

				if (self.reverse) {
					if (--self._currentIndex === 0) {
						self._currentIndex = self.images.length - 1;
						rollover = true;
					}
				} else if (++self._currentIndex === self.images.length) {
					self._currentIndex = 0;
					rollover = true;
				}

				setStyle(imgs[self._currentIndex].domNode, "display", "inherit");

				if (self.repeatCount && rollover && ++self._slideshowCount === self.repeatCount) {
					self.stop();
					return;
				}

				self.fireEvent("change", {
					index: self._currentIndex
				});
			}, this.duration);
		},

		start: function(){
			if (this._images) {
				this._setState(0, 1);
				this._slideshowCount = 0;
				this._setSlideshowInterval();
				this.fireEvent("start");
			}
		},

		stop: function(){
			var imgs = this._images;
			if (imgs) {
				clearInterval(this._slideshowTimer);
				if (imgs.length) {
					var start = 0;
					this.reverse && (start = imgs.length - 1);
					this._currentIndex && setStyle(imgs[this._currentIndex].domNode, "display", "none");
					setStyle(imgs[start].domNode, "display", "inherit");
					this._currentIndex = start;
				}
				this._setState(0, 0);
				this.fireEvent("stop");
			}
		},

		pause: function(){
			if (this._images) {
				clearInterval(this._slideshowTimer);
				this._setState(1, 0);
				this.fireEvent("pause");
			}
		},

		resume: function() {
			if (this._images) {
				this._setSlideshowInterval();
				this._setState(0, 1);
			}
		},

		_setState: function(paused, animating) {
			this.constants.paused = !!paused;
			this.constants.animating = !!animating;
		},

		constants: {
			animating: false,
			paused: false
		},

		properties: {
			duration: {
				set: function(value) {
					return Math.max(30, value);
				},
				value: 200
			},

			image: {
				set: function(value) {
					this._removeAllChildren();
					this._images = void 0;
					this._add(this._createImage(value, function() {
						this.fireEvent("load", {
							state: "image"
						});
					}, function(e) {
						this.fireEvent("error", e);
					}));
					return value;
				}
			},

			defaultImage: {
				set: function(value) {
					if (this._children.length == 0) {
						this._removeAllChildren();
						this._images = void 0;

						this._add(this._createImage(
							value,
							function() {
								this.fireEvent("load", {
									state: "image"
								});
							},
							function(e) {
								this.fireEvent("error", e);
							}
						));

						return value;
					}
				}
			},

			images: {
				set: function(value) {
					var imgs = void 0,
						counter = 0,
						errored = 0;
					this._removeAllChildren();
					if (is(value, "Array")) {
						imgs = [];
						value.forEach(function(val) {
							var img = this._createImage(val, function() {
								!errored && ++counter === value.length && this.fireEvent("load", {
									state: "image"
								});
							}, function(e) {
								errored || (errored = 1) && this.fireEvent("error", e);
							});
							setStyle(img.domNode, "display", "none");
							imgs.push(img);
							this._add(img);
						}, this);
					}
					this._images = imgs;
					return value;
				},

				post: function() {
					this.stop();
				}
			},

			repeatCount: 0,

			reverse: false
		}

	});

});<commit_msg>code cleanup<commit_after>define(["Ti/_/declare", "Ti/_/event", "Ti/_/lang", "Ti/_/style", "Ti/_/UI/Widget", "Ti/UI", "Ti/Filesystem"],
	function(declare, event, lang, style, Widget, UI, Filesystem) {

	var setStyle = style.set,
		is = require.is,
		on = require.on,
		InternalImageView = declare(Widget, {

			domType: "img",
			onload: null,
			onerror: null,

			constructor: function() {
				this.domNode.ondragstart = function() { return false; }; // Prevent images from being dragged
			},

			_getContentSize: function() {
				return {
					width: this.domNode.width,
					height: this.domNode.height
				}
			},

			_preLayout: function(boundingWidth, boundingHeight, isParentWidthSize, isParentHeightSize) {
				// We have to remove the old style to get the image to scale to its default size,
				// otherwise we are just reading in whatever we set in the last doLayout(), which is
				// 0 if the image was not loaded...thus always clamping it to 0.
				this.domNode.style.width = "";
				this.domNode.style.height = "";

				var imageRatio = this.domNode.width / this.domNode.height,
					values = this.properties.__values__,
					oldWidth = values.width,
					oldHeight = values.height;

				if (!isParentWidthSize && !isParentHeightSize) {
					if (boundingWidth / boundingHeight > imageRatio) {
						values.width = boundingHeight * imageRatio;
						values.height = boundingHeight;
					} else {
						values.width = boundingWidth;
						values.height = boundingWidth / imageRatio;
					}
				} else if (!isParentWidthSize) {
					values.width = boundingWidth;
					values.height = boundingWidth / imageRatio;
				} else if (!isParentHeightSize) {
					values.width = boundingHeight * imageRatio;
					values.height = boundingHeight;
				} else {
					values.width = UI.SIZE;
					values.height = UI.SIZE;
				}

				return oldWidth !== values.width || oldHeight !== values.height;
			},

			_imageRatio: 1,

			properties: {
				src: {
					set: function(value) {
						var node = this.domNode,
							disp = "none",
							handles,
							onerror = lang.hitch(this, function(e) {
								event.off(handles);
								this._triggerLayout();
								this.onerror && this.onerror(e);
							});

						if (value) {
							disp = "inherit";
							handles = [
								on(node, "load", this, function() {
									node.style.width = "";
									node.style.height = "";
									var imageRatio = node.width / node.height;
									isNaN(imageRatio) && (imageRatio = node.width === 0 ? 1 : Infinity);
									this._imageRatio = imageRatio;
									this._triggerLayout();
									this.onload && this.onload();
								}),
								on(node, "error", onerror),
								on(node, "abort", onerror)
							];
							node.src = require.cache(value) || value;
						}

						setStyle(node, "display", disp);
						return value;
					}
				}
			}
		});

	return declare("Ti.UI.ImageView", Widget, {

		_createImage: function(src, onload, onerror) {
			var m = is(src, "String") && src.match(/^(.+)\:\/\//);
			m && ~Filesystem.protocols.indexOf(m[1]) && (src = Filesystem.getFile(src));
			switch (src && src.declaredClass) {
				case "Ti.Filesystem.File":
					src = src.read();
				case "Ti.Blob":
					src = src.toString();
			}
			return new InternalImageView({
				onload: onload,
				onerror: onerror,
				src: src
			});
		},

		_defaultWidth: UI.SIZE,

		_defaultHeight: UI.SIZE,

		_slideshowCount: 0,

		_setSlideshowInterval: function() {
			var self = this,
				imgs = self._images;
			clearInterval(this._slideshowTimer);

			this._slideshowTimer = setInterval(function(){
				var rollover = false;

				setStyle(imgs[self._currentIndex].domNode, "display", "none");

				if (self.reverse) {
					if (--self._currentIndex === 0) {
						self._currentIndex = self.images.length - 1;
						rollover = true;
					}
				} else if (++self._currentIndex === self.images.length) {
					self._currentIndex = 0;
					rollover = true;
				}

				setStyle(imgs[self._currentIndex].domNode, "display", "inherit");

				if (self.repeatCount && rollover && ++self._slideshowCount === self.repeatCount) {
					self.stop();
					return;
				}

				self.fireEvent("change", {
					index: self._currentIndex
				});
			}, this.duration);
		},

		start: function(){
			if (this._images) {
				this._setState(0, 1);
				this._slideshowCount = 0;
				this._setSlideshowInterval();
				this.fireEvent("start");
			}
		},

		stop: function(){
			var imgs = this._images;
			if (imgs) {
				clearInterval(this._slideshowTimer);
				if (imgs.length) {
					var start = 0;
					this.reverse && (start = imgs.length - 1);
					this._currentIndex && setStyle(imgs[this._currentIndex].domNode, "display", "none");
					setStyle(imgs[start].domNode, "display", "inherit");
					this._currentIndex = start;
				}
				this._setState(0, 0);
				this.fireEvent("stop");
			}
		},

		pause: function(){
			if (this._images) {
				clearInterval(this._slideshowTimer);
				this._setState(1, 0);
				this.fireEvent("pause");
			}
		},

		resume: function() {
			if (this._images) {
				this._setSlideshowInterval();
				this._setState(0, 1);
			}
		},

		_setState: function(paused, animating) {
			this.constants.paused = !!paused;
			this.constants.animating = !!animating;
		},

		constants: {
			animating: false,
			paused: false
		},

		properties: {
			duration: {
				set: function(value) {
					return Math.max(30, value);
				},
				value: 200
			},

			image: {
				set: function(value) {
					this._removeAllChildren();
					this._images = void 0;
					this._add(this._createImage(value, function() {
						this.fireEvent("load", {
							state: "image"
						});
					}, function(e) {
						this.fireEvent("error", e);
					}));
					return value;
				}
			},

			defaultImage: {
				set: function(value) {
					if (this._children.length == 0) {
						this._images = void 0;
						this._add(this._createImage(
							value,
							function() {
								this.fireEvent("load", {
									state: "image"
								});
							},
							function(e) {
								this.fireEvent("error", e);
							}
						));

						return value;
					}
				}
			},

			images: {
				set: function(value) {
					var imgs = void 0,
						counter = 0,
						errored = 0;
					this._removeAllChildren();
					if (is(value, "Array")) {
						imgs = [];
						value.forEach(function(val) {
							var img = this._createImage(val, function() {
								!errored && ++counter === value.length && this.fireEvent("load", {
									state: "image"
								});
							}, function(e) {
								errored || (errored = 1) && this.fireEvent("error", e);
							});
							setStyle(img.domNode, "display", "none");
							imgs.push(img);
							this._add(img);
						}, this);
					}
					this._images = imgs;
					return value;
				},

				post: function() {
					this.stop();
				}
			},

			repeatCount: 0,

			reverse: false
		}

	});

});<|endoftext|>


<commit_before>import { describe, it } from 'mocha';
import { expect } from 'chai';
import humanizaNumeros from '../dist/index.js';

describe('humanizaNumeros', function () {
  it('deve arredondar corretamente para cima', function () {
    expect(humanizaNumeros(1560, 1)).to.equal('1,6 Mil');
    expect(humanizaNumeros(1451, 1)).to.equal('1,5 Mil');
  });
  it('deve arredondar corretamente para baixo', function () {
    expect(humanizaNumeros(1449, 1)).to.equal('1,4 Mil');
  });
  it('deve arredondar corretamente em quantidade de dígitos decimais', function () {
    expect(humanizaNumeros(1449, 1)).to.equal('1,4 Mil');
    expect(humanizaNumeros(1449, 2)).to.equal('1,45 Mil');
    expect(humanizaNumeros(1449, 3)).to.equal('1,449 Mil');
    expect(humanizaNumeros(1449, 4)).to.equal('1,4490 Mil');
    expect(humanizaNumeros(1449, 5)).to.equal('1,44900 Mil');
  });
  it('deve apresentar corretamente no singular', function () {
    expect(humanizaNumeros(1111111, 1)).to.equal('1,1 Milhão');
    expect(humanizaNumeros(1111111111, 1)).to.equal('1,1 Bilhão');
    expect(humanizaNumeros(1111111111111, 1)).to.equal('1,1 Trilhão');
  });
  it('deve apresentar corretamente no plural', function () {
    expect(humanizaNumeros(2111111, 1)).to.equal('2,1 Milhões');
    expect(humanizaNumeros(2111111111, 1)).to.equal('2,1 Bilhões');
    expect(humanizaNumeros(2111111111111, 1)).to.equal('2,1 Trilhões');
  });
  it('deve apresentar corretamente os milhares', function () {
    expect(humanizaNumeros(1234, 1)).to.equal('1,2 Mil');
  });
  it('deve apresentar corretamente os milhões', function () {
    expect(humanizaNumeros(1234567, 1)).to.equal('1,2 Milhão');
  });
  it('deve apresentar corretamente os bilhões', function () {
    expect(humanizaNumeros(1234567890, 1)).to.equal('1,2 Bilhão');
  });
  it('deve apresentar corretamente os trilhões', function () {
    expect(humanizaNumeros(1234567890000, 1)).to.equal('1,2 Trilhão');
  });
  it('deve apresentar quatrilhões como milhares de trilhões', function () {
    expect(humanizaNumeros(1234567890000000, 1)).to.equal('1.234 Trilhões');
  });
  it('deve apresentar números muito grandes como notação científica', function () {
    expect(humanizaNumeros(1234567890000000000, 1)).to.equal('1.2x10^18');
  });
});<commit_msg>test(future): remove tests that are not going to be covered anytime soon<commit_after>import { describe, it } from 'mocha';
import { expect } from 'chai';
import humanizaNumeros from '../dist/index.js';

describe('humanizaNumeros', function () {
  it('deve arredondar corretamente para cima', function () {
    expect(humanizaNumeros(1560, 1)).to.equal('1,6 Mil');
    expect(humanizaNumeros(1451, 1)).to.equal('1,5 Mil');
  });
  it('deve arredondar corretamente para baixo', function () {
    expect(humanizaNumeros(1449, 1)).to.equal('1,4 Mil');
  });
  it('deve arredondar corretamente em quantidade de dígitos decimais', function () {
    expect(humanizaNumeros(1449, 1)).to.equal('1,4 Mil');
    expect(humanizaNumeros(1449, 2)).to.equal('1,45 Mil');
    expect(humanizaNumeros(1449, 3)).to.equal('1,449 Mil');
    expect(humanizaNumeros(1449, 4)).to.equal('1,4490 Mil');
    expect(humanizaNumeros(1449, 5)).to.equal('1,44900 Mil');
  });
  it('deve apresentar corretamente no singular', function () {
    expect(humanizaNumeros(1111111, 1)).to.equal('1,1 Milhão');
    expect(humanizaNumeros(1111111111, 1)).to.equal('1,1 Bilhão');
    expect(humanizaNumeros(1111111111111, 1)).to.equal('1,1 Trilhão');
  });
  it('deve apresentar corretamente no plural', function () {
    expect(humanizaNumeros(2111111, 1)).to.equal('2,1 Milhões');
    expect(humanizaNumeros(2111111111, 1)).to.equal('2,1 Bilhões');
    expect(humanizaNumeros(2111111111111, 1)).to.equal('2,1 Trilhões');
  });
  it('deve apresentar corretamente os milhares', function () {
    expect(humanizaNumeros(1234, 1)).to.equal('1,2 Mil');
  });
  it('deve apresentar corretamente os milhões', function () {
    expect(humanizaNumeros(1234567, 1)).to.equal('1,2 Milhão');
  });
  it('deve apresentar corretamente os bilhões', function () {
    expect(humanizaNumeros(1234567890, 1)).to.equal('1,2 Bilhão');
  });
  it('deve apresentar corretamente os trilhões', function () {
    expect(humanizaNumeros(1234567890000, 1)).to.equal('1,2 Trilhão');
  });
  /**
   * Proposta de features:
   */
  /*
  it('deve apresentar quatrilhões como milhares de trilhões', function () {
    expect(humanizaNumeros(1234567890000000, 1)).to.equal('1.234 Trilhões');
  });
  it('deve apresentar números muito grandes como notação científica', function () {
    expect(humanizaNumeros(1234567890000000000, 1)).to.equal('1.2x10^18');
  });
  */
});<|endoftext|>


<commit_before>/*
*
* RGB Password
* @author: James White
* @date: 20/11/11
*
*/

window.onload = function() {

	var password = {

		selector: document.getElementById("password"),
		hash_selector: document.getElementById("password_hash"),

	};

	password.selector.onkeyup = function() {

		var rgb_values = rgb.getValue(this.value);

		document.getElementById("one").style.backgroundColor = "rgb("
			+ rgb_values.one.r + ", "
			+ rgb_values.one.g + ", "
			+ rgb_values.one.b +
		")";

		document.getElementById("two").style.backgroundColor = "rgb("
			+ rgb_values.two.r + ", "
			+ rgb_values.two.g + ", "
			+ rgb_values.two.b +
		")";

		document.getElementById("three").style.backgroundColor = "rgb("
			+ rgb_values.three.r + ", "
			+ rgb_values.three.g + ", "
			+ rgb_values.three.b +
		")";

		console.log("1: " + document.getElementById("one").style.backgroundColor);
		console.log("2: " + document.getElementById("two").style.backgroundColor);
		console.log("3: " + document.getElementById("three").style.backgroundColor);

	};

	var characters = ["p", "J", "i", "3", "M", "g", "U", "x", "Z", "B", "w", "S", "W", "u", "j", "A", "D", "Q", "N", "s", "K", "G", "O", "z", "_", "l", "H", "R", "k", "6", "b", "h", "q", "d", "e", "Y", "1", "c", ".", "4", "v", "L", "y", "f", "7", "2", "V", "0", "a", "n", "E", "F", "5", "9", "8", "m", "r", "t", "X", "C", "I", "T", "P", "o"];

	var rgb = {};

	rgb.getValue = function (input) {

		// Set up our slices object and it's default values
		var slices = {

			one: {

				length: 0,
				value: "",
				rgb_value: {

					r: 255,
					g: 255,
					b: 255

				}

			},

			two: {

				length: 0,
				value: "",
				rgb_value: {

					r: 255,
					g: 255,
					b: 255

				}

			},

			three: {

				length: 0,
				value: "",
				rgb_value: {

					r: 255,
					g: 255,
					b: 255

				}

			}

		}

		// If possible divide the password into 3 equals slices
		if( input.length % 3 === 0 ) {

			slices.one.length = input.length / 3;
			slices.two.length = input.length / 3;
			slices.three.length = input.length / 3;

		}

		// Otherwise try and split up as evenly as we can
		else {

			var rounded_third = Math.ceil(input.length / 3);

			slices.one.length = rounded_third; // 33%
			slices.two.length = rounded_third; // 33%
			slices.three.length = input.length - (2 * rounded_third); // 34%

		}

		// Slice up the password!
		slices.one.value = input.substr(0, slices.one.length);
		slices.two.value = input.substr(slices.one.length, slices.two.length);
		slices.three.value = input.substr(slices.two.length, slices.three.length);

		// Loop through each slice of the password
		for(var slice_number in slices) {

			var slice = slices[slice_number],
				 character,
				 character_key,
				 character_value;

			for(colour in slice.rgb_value) {

				// Take a copy of the array so we don"t
				// mess up the original random order it"s in
				characters_array = characters;

				// Need to find a better way of sorting the array's
				// that isn't random so the patterns can still be
				// recognised each time but still produces enough
				// different colours

				if( colour == "r" ) {

					characters_array.reverse();

				}

				//else if( colour == "g" ) {

					// Nothing much going on here..

				//}

				else if( colour == "b" ) {

					characters_array.reverse();

				}

				// Loop through all the characters(and numbers) in our characters object
				for(character_key in characters_array) {

					character = characters_array[character_key];

					// Add 20 to the character value so we get some
					// *slightly* nicer colours
					character_value = parseInt(character_key) + 15;

					if( slice.value.indexOf(character) !== -1 ) {

						slice.rgb_value[colour] = Math.floor( (240/64) * character_value);

						// We"ve found our character match, so let's not carry on looping
						break;

					}

				}

			}

		}

		return {

			one: slices.one.rgb_value,
			two: slices.two.rgb_value,
			three: slices.three.rgb_value,

		};

	}

};<commit_msg>Dry up repeated code. Use array instead of object where appropriate<commit_after>/*
*
* RGB Password
* @author: James White
* @date: 20/11/11
*
*/

window.onload = function() {

	var password = {

		selector: document.getElementById("password"),
		hash_selector: document.getElementById("password_hash"),

	};

	password.selector.onkeyup = function() {

		var rgb_values = rgb.getValue(this.value);

		document.getElementById("one").style.backgroundColor = "rgb("
			+ rgb_values[0].r + ", "
			+ rgb_values[0].g + ", "
			+ rgb_values[0].b +
		")";

		document.getElementById("two").style.backgroundColor = "rgb("
			+ rgb_values[1].r + ", "
			+ rgb_values[1].g + ", "
			+ rgb_values[1].b +
		")";

		document.getElementById("three").style.backgroundColor = "rgb("
			+ rgb_values[2].r + ", "
			+ rgb_values[2].g + ", "
			+ rgb_values[2].b +
		")";

		console.log("1: " + document.getElementById("one").style.backgroundColor);
		console.log("2: " + document.getElementById("two").style.backgroundColor);
		console.log("3: " + document.getElementById("three").style.backgroundColor);

	};

	var characters = ["p", "J", "i", "3", "M", "g", "U", "x", "Z", "B", "w", "S", "W", "u", "j", "A", "D", "Q", "N", "s", "K", "G", "O", "z", "_", "l", "H", "R", "k", "6", "b", "h", "q", "d", "e", "Y", "1", "c", ".", "4", "v", "L", "y", "f", "7", "2", "V", "0", "a", "n", "E", "F", "5", "9", "8", "m", "r", "t", "X", "C", "I", "T", "P", "o"];

	var rgb = {};

	rgb.getValue = function (input) {

		// Set up our slices object and it's default values
		var slices = [];
		for (var i=0; i < 3; i++) {
		  slices.push({
  			length: 0,
  			value: "",
  			rgb_value: {
  				r: 255,
  				g: 255,
  				b: 255
  			}
  		});
		}

		// If possible divide the password into 3 equals slices
		if( input.length % 3 === 0 ) {

			slices[0].length = input.length / 3;
			slices[1].length = input.length / 3;
			slices[2].length = input.length / 3;

		}

		// Otherwise try and split up as evenly as we can
		else {

			var rounded_third = Math.ceil(input.length / 3);

			slices[0].length = rounded_third; // 33%
			slices[1].length = rounded_third; // 33%
			slices[2].length = input.length - (2 * rounded_third); // 34%

		}

		// Slice up the password!
		slices[0].value = input.substr(0, slices[0].length);
		slices[1].value = input.substr(slices[0].length, slices[1].length);
		slices[2].value = input.substr(slices[1].length, slices[2].length);

		// Loop through each slice of the password
		for(var slice_number in slices) {

			var slice = slices[slice_number],
				 character,
				 character_key,
				 character_value;

			for(colour in slice.rgb_value) {

				// Take a copy of the array so we don"t
				// mess up the original random order it"s in
				characters_array = characters;

				// Need to find a better way of sorting the array's
				// that isn't random so the patterns can still be
				// recognised each time but still produces enough
				// different colours

				if( colour == "r" ) {

					characters_array.reverse();

				}

				//else if( colour == "g" ) {

					// Nothing much going on here..

				//}

				else if( colour == "b" ) {

					characters_array.reverse();

				}

				// Loop through all the characters(and numbers) in our characters object
				for(character_key in characters_array) {

					character = characters_array[character_key];

					// Add 20 to the character value so we get some
					// *slightly* nicer colours
					character_value = parseInt(character_key) + 15;

					if( slice.value.indexOf(character) !== -1 ) {

						slice.rgb_value[colour] = Math.floor( (240/64) * character_value);

						// We"ve found our character match, so let's not carry on looping
						break;

					}

				}

			}

		}

		return [
			slices[0].rgb_value,
			slices[1].rgb_value,
			slices[2].rgb_value,
		];

	}

};<|endoftext|>


<commit_before>import React from 'react';

export const RenderInterpretationQuarterlyNIH = (props) => {
    return (

                         props.sortBy('affiliationName')}>Expert Panel
                         props.sortBy('totalInterpretations')}>Total Interpretations
                         props.sortBy('interpretationsWithSavedSummary')}>Interpretations with saved summaries
                         props.sortBy('interpretationsProvisional')}>Interpretations provisioned
                         props.sortBy('interpretationsApproved')}>Interpretations approved

                    {props.affiliatedInterpreationsList.map(item => {
                        return (

                                {item.affiliationName}
                                {item.totalInterpretations}
                                {item.interpretationsWithSavedSummary}
                                {item.interpretationsProvisional}
                                {item.interpretationsApproved}

                        );
                    })}

    );
}
<commit_msg>Added functional stateless component for rendering GDM data<commit_after>import React from 'react';

/**
 * Method to render variant interpretations quarterly report for NIH
 */
export const RenderInterpretationQuarterlyNIH = (props) => {
    return (

                         props.sortBy('affiliationName')}>Expert Panel
                         props.sortBy('totalInterpretations')}>Total Interpretations (started)
                         props.sortBy('interpretationsWithSavedSummary')}>Interpretations with saved summaries (not provisioned or approved)
                         props.sortBy('interpretationsProvisional')}>Interpretations provisioned
                         props.sortBy('interpretationsApproved')}>Interpretations approved

                    {props.affiliatedInterpreationsList.map(item => {
                        return (

                                {item.affiliationName}
                                {item.totalInterpretations}
                                {item.interpretationsWithSavedSummary}
                                {item.interpretationsProvisional}
                                {item.interpretationsApproved}

                        );
                    })}

    );
}

/**
 * Method to render gene-disease records quarterly report for NIH
 */
export const RenderGeneDiseaseRecordQuarterlyNIH = (props) => {
    return (

                         props.sortBy('affiliationName')}>Expert Panel
                         props.sortBy('totalGDMs')}>Total Gene-Disease records (started)
                         props.sortBy('gdmsWithSavedSummary')}>Gene-Disease records with saved classifications (not provisioned or approved or published)
                         props.sortBy('gdmsProvisional')}>Gene-Disease records provisioned
                         props.sortBy('gdmsApproved')}>Gene-Disease records approved
                         props.sortBy('gdmsPublished')}>Gene-Disease records published

                    {props.affiliatedGDMsList.map(item => {
                        return (

                                {item.affiliationName}
                                {item.totalGdms}
                                {item.gdmsWithSavedSummary}
                                {item.gdmsProvisional}
                                {item.gdmsApproved}
                                {item.gdmsPublished}

                        );
                    })}

    );
}
<|endoftext|>


<commit_before>//   Copyright 2014-2015 François de Campredon
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

'use strict';

var testUtils = require('./testUtils');
var test = require('tape');
var React = require('react');
var StateStreamMixin = require('../').StateStreamMixin;
var Rx = require('rx');
var sinon = require('sinon');

test('StateStreamMixin', function (t) {

  t.test('setup', function (t) {
    t.end();
  });

  t.test('errors', function (t) {

    var Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      render: function () {
        return null;
      }
    });

    t.throws(
      function () {
        testUtils.render(React.createElement(Component));
      },
      /Component use the StateStreamMixin it should provide a 'getStateStream' function/,
      'it should throw an error if getStateStream is not defined'
    );

    Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      getStateStream: function () {
        return { hello: 'string'};
      },
      render: function () {
        return null;
      }
    });

    t.throws(
      function () {
        testUtils.render(React.createElement(Component));
      },
      /'Component.getStateStream' should return an Rx.Observable, given : \[object Object\]/,
      'it should throw an error if getStateStream does not return an observable'
    );

    Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      getStateStream: function () {
        return Rx.Observable.of(1);
      },
      render: function () {
        return null;
      }
    });

    t.throws(
      function () {
        testUtils.render(React.createElement(Component));
      },
      /The observable returned by 'Component.getStateStream' should publish Objects or null given : 1/,
      'it should throw an error if the Observable returned by getStateStream does not not resolve with an object or null'
    );

    t.end();

  });

  t.test('behavior', function (t) {
    var stateStream = new Rx.BehaviorSubject({ foo: 'bar'});
    var getStateSteamSpy = sinon.spy(function () {
      return stateStream;
    });
    var Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      getStateStream: getStateSteamSpy,
      render: function () {
        return null;
      }
    });

    var component = testUtils.render(React.createElement(Component));

    t.ok(getStateSteamSpy.called, 'it should have called getStateStreamSpy');

    t.deepEquals(component.state, { foo: 'bar'}, 'state should have been merged with the value of stateStream');

    stateStream.onNext({hello: 'world'});

    t.deepEquals(component.state, { foo: 'bar', hello: 'world'}, 'state should have been merged with the new value of stateStream');

    testUtils.unmount();

    t.notOk(stateStream.hasObservers(), 'the subscrition to stateStream should have been cleaned after that the component has been unmounted ');

    t.end();
  });

  t.test('teardown', function (t) {
    t.end();
  });

});
<commit_msg>cleanAllSubscriptions test<commit_after>//   Copyright 2014-2015 François de Campredon
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

'use strict';

var testUtils = require('./testUtils');
var test = require('tape');
var React = require('react');
var StateStreamMixin = require('../').StateStreamMixin;
var cleanAllSubscriptions = require('../').cleanAllSubscriptions;
var Rx = require('rx');
var sinon = require('sinon');

test('StateStreamMixin', function (t) {

  t.test('setup', function (t) {
    t.end();
  });

  t.test('errors', function (t) {

    var Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      render: function () {
        return null;
      }
    });

    t.throws(
      function () {
        testUtils.render(React.createElement(Component));
      },
      /Component use the StateStreamMixin it should provide a 'getStateStream' function/,
      'it should throw an error if getStateStream is not defined'
    );

    Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      getStateStream: function () {
        return { hello: 'string'};
      },
      render: function () {
        return null;
      }
    });

    t.throws(
      function () {
        testUtils.render(React.createElement(Component));
      },
      /'Component.getStateStream' should return an Rx.Observable, given : \[object Object\]/,
      'it should throw an error if getStateStream does not return an observable'
    );

    Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      getStateStream: function () {
        return Rx.Observable.of(1);
      },
      render: function () {
        return null;
      }
    });

    t.throws(
      function () {
        testUtils.render(React.createElement(Component));
      },
      /The observable returned by 'Component.getStateStream' should publish Objects or null given : 1/,
      'it should throw an error if the Observable returned by getStateStream does not not resolve with an object or null'
    );

    t.end();

  });

  t.test('behavior', function (t) {
    var stateStream = new Rx.BehaviorSubject({ foo: 'bar'});
    var getStateSteamSpy = sinon.spy(function () {
      return stateStream;
    });
    var Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      getStateStream: getStateSteamSpy,
      render: function () {
        return null;
      }
    });

    var component = testUtils.render(React.createElement(Component));

    t.ok(getStateSteamSpy.called, 'it should have called getStateStreamSpy');

    t.deepEquals(component.state, { foo: 'bar'}, 'state should have been merged with the value of stateStream');

    stateStream.onNext({hello: 'world'});

    t.deepEquals(component.state, { foo: 'bar', hello: 'world'}, 'state should have been merged with the new value of stateStream');

    testUtils.unmount();

    t.notOk(stateStream.hasObservers(), 'the subscrition to stateStream should have been cleaned after that the component has been unmounted ');

    t.end();
  });

  t.test('cleanAllSubscriptions', function (t) {
    var stateStream = new Rx.BehaviorSubject({ foo: 'bar'});
    var Component = React.createClass({
      displayName: 'Component',
      mixins: [StateStreamMixin],
      getStateStream: function () {
        return stateStream;
      },
      render: function () {
        return null;
      }
    });

    var component = testUtils.render(React.createElement(Component));
    cleanAllSubscriptions();
    stateStream.onNext({ hello: 'world'});
    t.deepEquals(component.state, { foo: 'bar'}, 'the state should not been bound anymore to stateStream after a call to `cleanAllSubscriptions`');
    t.notOk(stateStream.hasObservers(), 'the subscrition to stateStream should have been cleaned after a call tp `cleanAllSubscriptions` ');
    t.end();
  });

});
<|endoftext|>