Exemple #1
0
        public void OrderSensitiveValueComparisonListTests_DefaultObjectComparer()
        {
            var equalityComparer = new DefaultObjectComparer <ArtifactChange>();

            var listOne = CreateTestList(equalityComparer);

            // Populate the second list with references from the first.
            var listTwo = new OrderSensitiveValueComparisonList <ArtifactChange>(equalityComparer);

            for (int i = 0; i < listOne.Count; i++)
            {
                listTwo.Add(listOne[i]);
            }

            // Every list s/be equal to itself.
            listOne.Equals(listOne).Should().Be(true);

            // Two lists with shared objects, by reference, in the same
            // order should be regarded as equivalent.
            listOne.Equals(listTwo).Should().Be(true);

            ArtifactChange toSwap = listTwo[0];

            listTwo[0] = listTwo[1];
            listTwo[1] = toSwap;

            // We have reordered two objects that are themselves identical.
            // The comparison should fail as the order of references changed.
            listOne.Equals(listTwo).Should().Be(false);
        }
Exemple #2
0
        private static OrderSensitiveValueComparisonList <Artifact> ConstructFilesChain(IList <Artifact> existingFiles, Artifact currentFile)
        {
            var fileChain = new OrderSensitiveValueComparisonList <Artifact>(Artifact.ValueComparer);

            int parentIndex;

            do
            {
                currentFile = currentFile.DeepClone();
                parentIndex = currentFile.ParentIndex;

                // Index information is entirely irrelevant for the identity of nested files,
                // as each element of the chain could be stored at arbitrary locations in
                // the run.files table. And so we elide this information.
                currentFile.ParentIndex = -1;
                if (currentFile.Location != null)
                {
                    currentFile.Location.Index = -1;
                }

                fileChain.Add(currentFile);

                if (parentIndex != -1)
                {
                    currentFile = existingFiles[parentIndex];
                }
            } while (parentIndex != -1);

            return(fileChain);
        }
        private static OrderSensitiveValueComparisonList <LogicalLocation> ConstructLogicalLocationsChain(
            LogicalLocation currentLogicalLocation,
            IList <LogicalLocation> existingLogicalLocations)
        {
            var logicalLocationChain = new OrderSensitiveValueComparisonList <LogicalLocation>(LogicalLocation.ValueComparer);

            int parentIndex;

            do
            {
                currentLogicalLocation = currentLogicalLocation.DeepClone();
                parentIndex            = currentLogicalLocation.ParentIndex;

                // Index information is entirely irrelevant for the identity of nested logical locations,
                // as each element of the chain could be stored at arbitrary locations in the
                // run.logicalLocations table. And so we elide this information.
                currentLogicalLocation.ParentIndex = -1;
                currentLogicalLocation.Index       = -1;

                logicalLocationChain.Add(currentLogicalLocation);

                if (parentIndex != -1)
                {
                    currentLogicalLocation = existingLogicalLocations[parentIndex];
                }
            } while (parentIndex != -1);

            return(logicalLocationChain);
        }
        private int CacheArtifact(Artifact artifact, IList <Artifact> currentArtifacts)
        {
            artifact = artifact.DeepClone();

            int parentIndex = artifact.ParentIndex;

            // Ensure all parent nodes are remapped.
            if (parentIndex != -1)
            {
                // Important: the input results we are rewriting need to refer
                // to the historical files index in order to understand parenting.
                artifact.ParentIndex = CacheArtifact(currentArtifacts[parentIndex], currentArtifacts);
            }

            // Equally important, the artifact chain is a specially constructed key that
            // operates against the newly constructed files array in CurrentArtifacts.
            OrderSensitiveValueComparisonList <Artifact> artifactChain = ConstructArtifactsChain(artifact, Artifacts);

            if (!ArtifactToIndex.TryGetValue(artifactChain, out int remappedIndex))
            {
                remappedIndex = ArtifactToIndex.Count;

                this.Artifacts.Add(artifact);
                ArtifactToIndex[artifactChain] = remappedIndex;

                Debug.Assert(ArtifactToIndex.Count == this.Artifacts.Count);

                if (artifact.Location != null)
                {
                    artifact.Location.Index = remappedIndex;
                }
            }

            return(remappedIndex);
        }
        private int CacheLogicalLocation(LogicalLocation logicalLocation, IList <LogicalLocation> currentLogicalLocations)
        {
            logicalLocation = logicalLocation.DeepClone();

            // Ensure all parent nodes are remapped.
            int parentIndex = logicalLocation.ParentIndex;

            if (parentIndex != -1)
            {
                logicalLocation.ParentIndex = CacheLogicalLocation(currentLogicalLocations[parentIndex], currentLogicalLocations);
            }

            OrderSensitiveValueComparisonList <LogicalLocation> logicalLocationChain = ConstructLogicalLocationsChain(logicalLocation, LogicalLocations);

            if (!LogicalLocationToIndex.TryGetValue(logicalLocationChain, out int remappedIndex))
            {
                remappedIndex         = LogicalLocationToIndex.Count;
                logicalLocation.Index = remappedIndex;

                this.LogicalLocations.Add(logicalLocation);
                LogicalLocationToIndex[logicalLocationChain] = remappedIndex;
            }

            return(remappedIndex);
        }
        public void OrderSensitiveValueComparisonListTests_ValueComparer()
        {
            // Two identical lists with elements that are
            // distinct objects, by reference.
            OrderSensitiveValueComparisonList <ArtifactChange> listOne = CreateTestList(ArtifactChange.ValueComparer);
            OrderSensitiveValueComparisonList <ArtifactChange> listTwo = CreateTestList(ArtifactChange.ValueComparer);

            // Every list s/be equal to itself
            listOne.Equals(listOne).Should().Be(true);

            // As initialized, these objects are different, due
            // to a unique GUID property on each list
            listOne.Equals(listTwo).Should().Be(false);

            // Make the two lists equivalent, by value
            listTwo[2].SetProperty(DIFFERENTIATING_PROPERTY_NAME, listOne[2].GetProperty <Guid>(DIFFERENTIATING_PROPERTY_NAME));
            listOne.Equals(listTwo).Should().Be(true);

            ArtifactChange toSwap = listTwo[0];

            listTwo[0] = listTwo[1];
            listTwo[1] = toSwap;

            // We have reordered two objects that are themselves identical.
            // by value. The comparison should still succeed.
            listOne.Equals(listTwo).Should().Be(true);
        }
Exemple #7
0
        private OrderSensitiveValueComparisonList <ArtifactChange> CreateTestList(IEqualityComparer <ArtifactChange> equalityComparer)
        {
            // Test list. First two elements are identical. The third element is unique.
            var fileChangeOne = new ArtifactChange();
            var fileChangeTwo = new ArtifactChange();

            var  fileChangeThree         = new ArtifactChange();
            Guid differentiatingProperty = Guid.NewGuid();

            fileChangeThree.SetProperty(DIFFERENTIATING_PROPERTY_NAME, differentiatingProperty);

            var list = new OrderSensitiveValueComparisonList <ArtifactChange>(equalityComparer);

            list.AddRange(new[] { fileChangeOne, fileChangeTwo, fileChangeThree });

            return(list);
        }