public void Test35CombineBadStatusFail()
        {
            //SETUP
            var status1 = new SuccessOrErrors <string>();
            var status2 = "hello";

            //ATTEMPT
            var ex = Assert.Throws <ArgumentNullException>(() => status1.Combine(status2));

            //VERIFY
            ex.Message.ShouldStartWith("The status parameter was not derived from a type that supported ISuccessOrErrors.");
        }
        public void Test21CombineUnsetStatusHasNoErrorsOk()
        {
            //SETUP
            var status1 = new SuccessOrErrors <string>();
            var status2 = new SuccessOrErrors();

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.HasErrors.ShouldEqual(false);
        }
        public void Test20CombineDefaultsToNotValidOk()
        {
            //SETUP
            var status1 = new SuccessOrErrors <string>();
            var status2 = new SuccessOrErrors();

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.ToString().ShouldEqual("Not currently setup");
        }
        public void Test26CombineOtherSetSuccessOk()
        {
            //SETUP
            var status1 = new SuccessOrErrors <string>();
            var status2 = new SuccessOrErrors <DateTime>();

            status2.SetSuccessWithResult(DateTime.Now, "This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.ToString().ShouldEqual("Not currently setup");
        }
        public void Test26CombineOtherSetSuccessOk()
        {
            //SETUP
            var status1 = new SuccessOrErrors();
            var status2 = new SuccessOrErrors();

            status2.SetSuccessMessage("This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.ToString().ShouldEqual("Not currently setup");
        }
        public void Test25CombineSetSuccessOk()
        {
            //SETUP
            var status1 = new SuccessOrErrors();
            var status2 = new SuccessOrErrors();

            status1.SetSuccessMessage("This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(true);
            status1.HasErrors.ShouldEqual(false);
            status1.HasWarnings.ShouldEqual(false);
            status1.SuccessMessage.ShouldEqual("This was successful.");
            status1.Errors.Count.ShouldEqual(0);
        }
        public void Test31CombineAddOtherSingleErrorOk()
        {
            //SETUP
            var status1 = new SuccessOrErrors <string>();
            var status2 = new SuccessOrErrors();

            status2.AddSingleError("This was {0}.", "bad");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.HasErrors.ShouldEqual(true);
            status1.SuccessMessage.ShouldEqual("");
            status1.Errors.Count.ShouldEqual(1);
            status1.Errors[0].ErrorMessage.ShouldEqual("This was bad.");
            status1.Errors[0].MemberNames.Count().ShouldEqual(0);
        }
        public void Test27SuccessWithOtherWarningsOk()
        {
            //SETUP
            var status1 = new SuccessOrErrors <string>();
            var status2 = new SuccessOrErrors();

            status2.AddWarning("This is a warning");
            status1.SetSuccessWithResult("The result", "This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(true);
            status1.HasErrors.ShouldEqual(false);
            status1.HasWarnings.ShouldEqual(true);
            status1.SuccessMessage.ShouldEqual("This was successful. (has 1 warnings)");
            status1.Warnings.Count.ShouldEqual(1);
            status1.Warnings[0].ShouldEqual("Warning: This is a warning");
        }
Пример #9
0
        private ISuccessOrErrors CheckColumn(SqlColumnInfo sqlCol, EfColumnInfo clrCol, string combinedName)
        {
            var status = new SuccessOrErrors();

            if (sqlCol.SqlTypeName != clrCol.SqlTypeName)
            {
                status.AddSingleError(
                    "Column Type: The SQL {0} column {1}.{2} type does not match EF. SQL type = {3}, EF type = {4}.",
                    _sqlDbRefString, combinedName, clrCol.SqlColumnName, sqlCol.SqlTypeName, clrCol.SqlTypeName);
            }

            if (sqlCol.IsNullable != clrCol.IsNullable)
            {
                status.AddSingleError(
                    "Column Nullable: SQL {0} column {1}.{2} nullablity does not match. SQL is {3}NULL, EF is {4}NULL.",
                    _sqlDbRefString, combinedName, clrCol.SqlColumnName,
                    sqlCol.IsNullable ? "" : "NOT ",
                    clrCol.IsNullable ? "" : "NOT ");
            }

            if (sqlCol.IsPrimaryKey != clrCol.IsPrimaryKey)
            {
                status.AddSingleError(
                    "Primary Key: The SQL {0}  column {1}.{2} primary key settings don't match. SQL says it is {3}a key, EF says it is {4}a key.",
                    _sqlDbRefString, combinedName, clrCol.SqlColumnName,
                    sqlCol.IsPrimaryKey ? "" : "NOT ",
                    clrCol.IsPrimaryKey ? "" : "NOT ");
            }
            else if (sqlCol.IsPrimaryKey && sqlCol.PrimaryKeyOrder != clrCol.PrimaryKeyOrder)
            {
                status.AddSingleError(
                    "Primary Key Order: The SQL {0}  column {1}.{2} primary key order does not match. SQL order = {3}, EF order = {4}.",
                    _sqlDbRefString, combinedName, clrCol.SqlColumnName,
                    sqlCol.PrimaryKeyOrder, clrCol.PrimaryKeyOrder);
            }

            return(status.Combine(CheckMaxLength(sqlCol, clrCol, combinedName)));
        }
        public void Test20CombineDefaultsToNotValidOk()
        {
            //SETUP  
            var status1 = new SuccessOrErrors<string>();
            var status2 = new SuccessOrErrors();

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.ToString().ShouldEqual("Not currently setup");
        }
        public void Test35CombineBadStatusFail()
        {
            //SETUP  
            var status1 = new SuccessOrErrors<string>();
            var status2 = "hello";

            //ATTEMPT
            var ex = Assert.Throws<ArgumentNullException>(() => status1.Combine(status2));

            //VERIFY
            ex.Message.ShouldStartWith("The status parameter was not derived from a type that supported ISuccessOrErrors.");
        }
        public void Test31CombineAddOtherSingleErrorOk()
        {
            //SETUP  
            var status1 = new SuccessOrErrors<string>();
            var status2 = new SuccessOrErrors();
            status2.AddSingleError("This was {0}.", "bad");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.HasErrors.ShouldEqual(true);
            status1.SuccessMessage.ShouldEqual("");
            status1.Errors.Count.ShouldEqual(1);
            status1.Errors[0].ErrorMessage.ShouldEqual("This was bad.");
            status1.Errors[0].MemberNames.Count().ShouldEqual(0);
        }
        public void Test27SuccessWithOtherWarningsOk()
        {
            //SETUP  
            var status1 = new SuccessOrErrors<string>();
            var status2 = new SuccessOrErrors();
            status2.AddWarning("This is a warning");
            status1.SetSuccessWithResult("The result", "This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(true);
            status1.HasErrors.ShouldEqual(false);
            status1.HasWarnings.ShouldEqual(true);
            status1.SuccessMessage.ShouldEqual("This was successful. (has 1 warnings)");
            status1.Warnings.Count.ShouldEqual(1);
            status1.Warnings[0].ShouldEqual("Warning: This is a warning");
        }
        public void Test26CombineOtherSetSuccessOk()
        {
            //SETUP 
            var status1 = new SuccessOrErrors<string>();
            var status2 = new SuccessOrErrors<DateTime>();
            status2.SetSuccessWithResult(DateTime.Now, "This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.ToString().ShouldEqual("Not currently setup");
        }
        public void Test25CombineSetSuccessOk()
        {
            //SETUP 
            var status1 = new SuccessOrErrors<string>();
            var status2 = new SuccessOrErrors();
            status1.SetSuccessWithResult("The result", "This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(true);
            status1.HasErrors.ShouldEqual(false);
            status1.HasWarnings.ShouldEqual(false);
            status1.Result.ShouldEqual("The result");
            status1.SuccessMessage.ShouldEqual("This was successful.");
            status1.Errors.Count.ShouldEqual(0);
        }
        public void Test21CombineUnsetStatusHasNoErrorsOk()
        {
            //SETUP  
            var status1 = new SuccessOrErrors<string>();
            var status2 = new SuccessOrErrors();

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.HasErrors.ShouldEqual(false);
        }
        /// <summary>
        /// This checks that the EF relationship is mirrored in the SQL
        /// </summary>
        /// <param name="tableInfo"></param>
        /// <param name="relEfCol"></param>
        /// <returns>returns status with optional name of SQL many-many table. Used to mark that table as having been used</returns>
        public ISuccessOrErrors <string> CheckEfRelationshipToSql(EfTableInfo tableInfo, EfRelationshipInfo relEfCol)
        {
            var    status = new SuccessOrErrors <string>();
            string manyToManyTableName = null;

            if (relEfCol.FromToRelationships.FromMultiplicity == EfRelationshipTypes.Many)
            {
                //handle from many

                if (relEfCol.FromToRelationships.ToMultiplicity == EfRelationshipTypes.Many)
                {
                    //many to many - look for a linking table in the list of _potentialManyToManyTablesDict that has the right foreignKeys

                    var fromEfTable = GetEfTableDataFromClass(tableInfo.ClrClassType);
                    var toEfTable   = GetEfTableDataFromCollection(relEfCol);
                    var fromKeys    = fromEfTable.NormalCols.Where(x => x.IsPrimaryKey);
                    var toKeys      = toEfTable.NormalCols.Where(x => x.IsPrimaryKey);

                    var linkCombinedNames =
                        AllManyToManyTablesThatHaveTheRightForeignKeys(fromKeys, toKeys, fromEfTable.TableName, toEfTable.TableName).ToList();

                    if (!linkCombinedNames.Any())
                    {
                        status.AddSingleError(
                            "Missing Link Table: EF has a {0} relationship between {1}.{2} and {3} but we could not find a linking table with the right foreign keys.",
                            relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toEfTable.TableName);
                    }
                    else
                    {
                        //now we check the entries in the linking tab
                        if (linkCombinedNames.Count > 1)
                        {
                            status.AddWarning(
                                "Ambigous Link Table: EF has a {0} relationship between {1}.{2} and {3}. This was ambigous so we may not have fully checked this.",
                                relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName,
                                toEfTable.TableName);
                        }

                        manyToManyTableName = linkCombinedNames.First();
                        foreach (var foreignKey in _allSqlInfo.ForeignKeys.Where(x => x.ParentTableNameWithScheme == manyToManyTableName)
                                 .Where(foreignKey => !foreignKey.IsCascade))
                        {
                            status.AddSingleError(
                                "Cascade Delete: The {0} relationship between {1}.{2} and {3} has a foreign key {4} that is not CASCASE DELETE." +
                                "  All linking table foreign keys should have CASCASE DELETE.",
                                relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName,
                                toEfTable.TableName, foreignKey.ConstraintName);
                        }
                    }
                }
                else
                {
                    //many to one
                    var toSqlTableStatus = GetSqlTableDataFromClass(relEfCol.ClrColumnType);
                    if (toSqlTableStatus.HasErrors)
                    {
                        return(status.Combine(toSqlTableStatus));
                    }

                    var foreignKeys = GetForeignKeys(tableInfo.TableName, toSqlTableStatus.Result);
                    if (!foreignKeys.Any())
                    {
                        status.AddSingleError(
                            "Missing Foreign Key: EF has a {0} relationship between {1}.{2} and {3} but we don't find that in SQL.",
                            relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toSqlTableStatus.Result.TableName);
                    }
                    else
                    {
                        //Look at cascase deletes
                        foreach (var foreignKey in foreignKeys.Where(foreignKey => relEfCol.FromToRelationships.ToIsCascadeDelete != foreignKey.IsCascade))
                        {
                            status.AddSingleError(
                                "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." +
                                " SQL foreign key say {4}, EF setting is {5}.",
                                relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toSqlTableStatus.Result.TableName,
                                foreignKey.DeleteAction,
                                relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION");
                        }
                    }
                }
            }
            else
            {
                //The parent is single, which implies that the child holds the key

                if (relEfCol.FromToRelationships.ToMultiplicity == EfRelationshipTypes.Many)
                {
                    //typical one to many

                    var fromSqlTableStatus = GetSqlTableDataFromCollection(relEfCol);
                    if (fromSqlTableStatus.HasErrors)
                    {
                        return(status.Combine(fromSqlTableStatus));
                    }
                    var toSqlTable  = _sqlInfoDict[tableInfo.CombinedName];
                    var foreignKeys = GetForeignKeys(fromSqlTableStatus.Result.TableName, toSqlTable);

                    if (!foreignKeys.Any())
                    {
                        status.AddSingleError(
                            "Missing Foreign Key: EF has a {0} relationship between {1} and {2}.{3} but we don't find that in SQL.",
                            relEfCol.FromToRelationships, fromSqlTableStatus.Result.TableName, tableInfo.TableName,
                            relEfCol.ClrColumnName);
                    }
                    else
                    {
                        //Look at cascase deletes
                        foreach (var foreignKey in foreignKeys.Where(foreignKey => relEfCol.FromToRelationships.FromIsCascadeDelete != foreignKey.IsCascade))
                        {
                            status.AddSingleError(
                                "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." +
                                " SQL foreign key say {4}, EF setting is {5}.",
                                relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, toSqlTable.TableName,
                                foreignKey.DeleteAction,
                                relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION");
                        }
                    }
                }
                else
                {
                    //one to one/OneOrZero or reverse
                    var sqlTableEnd1Status = GetSqlTableDataFromClass(relEfCol.ClrColumnType);
                    if (sqlTableEnd1Status.HasErrors)
                    {
                        return(status.Combine(sqlTableEnd1Status));
                    }

                    var sqlTableEnd2 = _sqlInfoDict[tableInfo.CombinedName];

                    //There is one foreign key for both directions. Therefore we need to check both

                    var foreignKey1 = GetForeignKeys(sqlTableEnd1Status.Result.TableName, sqlTableEnd2).SingleOrDefault();
                    var foreignKey2 = GetForeignKeys(sqlTableEnd2.TableName, sqlTableEnd1Status.Result).SingleOrDefault();

                    if (foreignKey1 == null && foreignKey2 == null)
                    {
                        status.AddSingleError(
                            "Missing Foreign Key: EF has a {0} relationship between {1}.{2} and {3} but we don't find that in SQL.",
                            relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, sqlTableEnd1Status.Result.TableName);
                    }
                    else if (foreignKey1 != null && relEfCol.FromToRelationships.FromIsCascadeDelete != foreignKey1.IsCascade)
                    {
                        //Look at cascase deletes
                        status.AddSingleError(
                            "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." +
                            " SQL foreign key say {4}, EF setting is {5}.",
                            relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, sqlTableEnd1Status.Result.TableName,
                            foreignKey1.DeleteAction,
                            relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION");
                    }
                    else if (foreignKey2 != null && relEfCol.FromToRelationships.ToIsCascadeDelete != foreignKey2.IsCascade)
                    {
                        //Look at cascase deletes
                        status.AddSingleError(
                            "Cascade Delete: The {0} relationship between {1}.{2} and {3} has different cascase delete value." +
                            " SQL foreign key say {4}, EF setting is {5}.",
                            relEfCol.FromToRelationships, tableInfo.TableName, relEfCol.ClrColumnName, sqlTableEnd1Status.Result.TableName,
                            foreignKey1.DeleteAction,
                            relEfCol.FromToRelationships.ToIsCascadeDelete ? "CASCADE" : "NO_ACTION");
                    }
                }
            }

            return(status.HasErrors ? status : status.SetSuccessWithResult(manyToManyTableName, "All Ok"));
        }
        public void Test26CombineOtherSetSuccessOk()
        {
            //SETUP 
            var status1 = new SuccessOrErrors();
            var status2 = new SuccessOrErrors();
            status2.SetSuccessMessage("This was {0}.", "successful");

            //ATTEMPT
            status1.Combine(status2);

            //VERIFY
            status1.IsValid.ShouldEqual(false);
            status1.ToString().ShouldEqual("Not currently setup");
        }