Exemplo n.º 1
0
        public void ShouldDetectBaseClassRemovalComplex()
        {
            var objPrev = DynamicClass.Create("B",
                                              DynamicClass.Create("W",
                                                                  DynamicClass.Create("Z",
                                                                                      DynamicClass.Create("A",
                                                                                                          DynamicClass.Create("X",
                                                                                                                              DynamicClass.Create("O")))))).Instantiate();
            var objCurr = DynamicClass.Create("B", DynamicClass.Create("A")).Instantiate();

            var stampPrev = new TypeStamp(objPrev.GetType());
            var stampCurr = new TypeStamp(objCurr.GetType());

            var compareResult = stampCurr.CompareWith(stampPrev);

            Assert.IsEmpty(compareResult.FieldsMoved);
            Assert.IsEmpty(compareResult.ClassesAdded);
            Assert.IsEmpty(compareResult.ClassesRenamed);
            Assert.IsEmpty(compareResult.FieldsRemoved);
            Assert.IsEmpty(compareResult.FieldsAdded);
            Assert.IsEmpty(compareResult.FieldsChanged);

            Assert.AreEqual(4, compareResult.ClassesRemoved.Count);
            Assert.IsTrue(compareResult.ClassesRemoved[0].StartsWith("O"));
            Assert.IsTrue(compareResult.ClassesRemoved[1].StartsWith("X"));
            Assert.IsTrue(compareResult.ClassesRemoved[2].StartsWith("Z"));
            Assert.IsTrue(compareResult.ClassesRemoved[3].StartsWith("W"));
        }
Exemplo n.º 2
0
        public void ShouldFindNoDifferences()
        {
            var obj   = DynamicClass.Create("C", DynamicClass.Create("B", DynamicClass.Create("A"))).Instantiate();
            var stamp = new TypeStamp(obj.GetType());

            var compareResult = stamp.CompareWith(stamp);

            Assert.IsTrue(compareResult.Empty);
        }
Exemplo n.º 3
0
        public void ShouldNotDetectInsertionOfTransientField()
        {
            var objPrev = DynamicClass.Create("A").Instantiate();
            var objCurr = DynamicClass.Create("A").WithTransientField("a", typeof(int)).Instantiate();

            var stampPrev = new TypeStamp(objPrev.GetType());
            var stampCurr = new TypeStamp(objCurr.GetType());

            var compareResult = stampCurr.CompareWith(stampPrev);

            Assert.IsTrue(compareResult.Empty);
        }
Exemplo n.º 4
0
        public void Stamp(Type type)
        {
            if (!StampHelpers.IsStampNeeded(type, treatCollectionAsUserObject))
            {
                return;
            }
            if (alreadyWritten.Contains(type))
            {
                return;
            }
            alreadyWritten.Add(type);

            var ts = new TypeStamp(type);

            ts.WriteTo(writer);
        }
Exemplo n.º 5
0
        public void ShouldDetectInsertionOfOverridingField()
        {
            var objPrev = DynamicClass.Create("A", DynamicClass.Create("Base").WithField("a", typeof(int))).Instantiate();
            var objCurr = DynamicClass.Create("A", DynamicClass.Create("Base").WithField("a", typeof(int))).WithField("a", typeof(int)).Instantiate();

            var stampPrev = new TypeStamp(objPrev.GetType());
            var stampCurr = new TypeStamp(objCurr.GetType());

            var compareResult = stampCurr.CompareWith(stampPrev);

            Assert.IsEmpty(compareResult.ClassesAdded);
            Assert.IsEmpty(compareResult.ClassesRemoved);
            Assert.IsEmpty(compareResult.ClassesRenamed);
            Assert.IsEmpty(compareResult.FieldsMoved);
            Assert.IsEmpty(compareResult.FieldsRemoved);
            Assert.IsEmpty(compareResult.FieldsChanged);

            Assert.AreEqual(1, compareResult.FieldsAdded.Count);
            Assert.AreEqual("a", compareResult.FieldsAdded[0].Name);
        }
Exemplo n.º 6
0
        public void ShouldDetectClassRenameSimple()
        {
            var objPrev = DynamicClass.Create("A").Instantiate();
            var objCurr = DynamicClass.Create("B").Instantiate();

            var stampPrev = new TypeStamp(objPrev.GetType());
            var stampCurr = new TypeStamp(objCurr.GetType());

            var compareResult = stampCurr.CompareWith(stampPrev);

            Assert.IsEmpty(compareResult.ClassesAdded);
            Assert.IsEmpty(compareResult.ClassesRemoved);
            Assert.IsEmpty(compareResult.FieldsMoved);
            Assert.IsEmpty(compareResult.FieldsRemoved);
            Assert.IsEmpty(compareResult.FieldsAdded);
            Assert.IsEmpty(compareResult.FieldsChanged);

            Assert.AreEqual(1, compareResult.ClassesRenamed.Count);
            Assert.IsTrue(compareResult.ClassesRenamed[0].Item1.StartsWith("A"));
            Assert.IsTrue(compareResult.ClassesRenamed[0].Item2.StartsWith("B"));
        }
Exemplo n.º 7
0
        public void ReadStamp(Type type, bool treatCollectionAsUserObject)
        {
            if (!StampHelpers.IsStampNeeded(type, treatCollectionAsUserObject))
            {
                return;
            }
            if (stampCache.ContainsKey(type))
            {
                return;
            }

            var streamTypeStamp = new TypeStamp();

            streamTypeStamp.ReadFrom(reader);

            if (streamTypeStamp.ModuleGUID == type.Module.ModuleVersionId)
            {
                stampCache.Add(type, StampHelpers.GetFieldsInSerializationOrder(type, true).Select(x => new FieldInfoOrEntryToOmit(x)).ToList());
                return;
            }
            if (versionToleranceLevel == VersionToleranceLevel.Guid)
            {
                throw new InvalidOperationException(string.Format("The class was serialized with different module version id {0}, current one is {1}.",
                                                                  streamTypeStamp.ModuleGUID, type.Module.ModuleVersionId));
            }

            var result            = new List <FieldInfoOrEntryToOmit>();
            var assemblyTypeStamp = new TypeStamp(type, true);

            if (assemblyTypeStamp.Classes.Count != streamTypeStamp.Classes.Count && !versionToleranceLevel.HasFlag(VersionToleranceLevel.InheritanceChainChange))
            {
                throw new InvalidOperationException(string.Format("Class hierarchy changed. Expected {0} classes in a chain, but found {1}.", assemblyTypeStamp.Classes.Count, streamTypeStamp.Classes.Count));
            }

            var cmpResult = assemblyTypeStamp.CompareWith(streamTypeStamp);

            if (cmpResult.ClassesRenamed.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.TypeNameChanged))
            {
                if (versionToleranceLevel.HasFlag(VersionToleranceLevel.AssemblyVersionChanged))
                {
                    foreach (var renamed in cmpResult.ClassesRenamed)
                    {
                        var beforeStrippedVersion = Regex.Replace(renamed.Item1, "Version=[0-9.]*", string.Empty);
                        var afterStrippedVersion  = Regex.Replace(renamed.Item2, "Version=[0-9.]*", string.Empty);

                        if (beforeStrippedVersion != afterStrippedVersion)
                        {
                            throw new InvalidOperationException(string.Format("Class name changed from {0} to {1}", cmpResult.ClassesRenamed[0].Item1, cmpResult.ClassesRenamed[0].Item2));
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Class name changed from {0} to {1}", cmpResult.ClassesRenamed[0].Item1, cmpResult.ClassesRenamed[0].Item2));
                }
            }
            if (cmpResult.FieldsAdded.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.FieldAddition))
            {
                throw new InvalidOperationException(string.Format("Field added: {0}.", cmpResult.FieldsAdded[0].Name));
            }
            if (cmpResult.FieldsRemoved.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.FieldRemoval))
            {
                throw new InvalidOperationException(string.Format("Field removed: {0}.", cmpResult.FieldsRemoved[0].Name));
            }
            if (cmpResult.FieldsMoved.Any() && !versionToleranceLevel.HasFlag(VersionToleranceLevel.FieldMove))
            {
                throw new InvalidOperationException(string.Format("Field moved: {0}.", cmpResult.FieldsMoved.ElementAt(0).Key.Name));
            }

            foreach (var field in streamTypeStamp.GetFieldsInAlphabeticalOrder())
            {
                if (cmpResult.FieldsRemoved.Contains(field))
                {
                    result.Add(new FieldInfoOrEntryToOmit(Type.GetType(field.TypeAQN)));
                }
                else if (cmpResult.FieldsMoved.ContainsKey(field))
                {
                    var moved = cmpResult.FieldsMoved[field];
                    var finfo = Type.GetType(moved.OwningTypeAQN).GetField(moved.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    result.Add(new FieldInfoOrEntryToOmit(finfo));
                }
                else
                {
                    var finfo = Type.GetType(field.OwningTypeAQN).GetField(field.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    result.Add(new FieldInfoOrEntryToOmit(finfo));
                }
            }

            foreach (var field in assemblyTypeStamp.GetFieldsInAlphabeticalOrder().Where(x => x.IsConstructor))
            {
                var finfo = Type.GetType(field.OwningTypeAQN).GetField(field.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                result.Add(new FieldInfoOrEntryToOmit(finfo));
            }

            stampCache.Add(type, result);
        }