public void CanUseAdHocTypes()
        {
            // In this test, we want to ensure that we can compare items which may flatten down to the same item, but aren't actually the same .net object
            var underlyingComparer = new ObjectComparer {
                ObjectComparerMismatchedKeysBehaviour = ObjectComparerMismatchedKeysBehaviour.TreatMissingValueAsNull, ObjectComparerNoAvailablePluginBehaviour = ObjectComparerNoAvailablePluginBehaviour.Throw
            };

            underlyingComparer.ComparisonPlugins.Add(new Plugins.FunctionBasedComparerPlugin((name, obj1, obj2) =>
            {
                if (name.EndsWith("cricket"))
                {
                    return new ObjectComparerPluginResults {
                        ComparisonResultType = ComparisonResultType.Equal
                    }
                }
                ;

                return(new ObjectComparerPluginResults {
                    ComparisonResultType = ComparisonResultType.UnableToCompare
                });
            }));

            underlyingComparer.ComparisonPlugins.Add(new Plugins.SimpleStringComparerPlugin());
            underlyingComparer.ComparisonPlugins.Add(new Plugins.DoubleComparerPlugin());
            underlyingComparer.ComparisonPlugins.Add(new Plugins.Int32ComparerPlugin());

            var objectFlattener = new BorsukSoftware.ObjectFlattener.ObjectFlattener {
                NoAvailablePluginBehaviour = ObjectFlattener.NoAvailablePluginBehaviour.Throw
            };

            objectFlattener.Plugins.Add(new BorsukSoftware.ObjectFlattener.Plugins.StandardPlugin());

            var items1 = Enumerable.Range(0, 200).
                         Select(i => new { james = i, bob = i.ToString() });

            var items2 = Enumerable.Range(0, 200).
                         Select(i => new { bob = i.ToString(), james = i, cricket = 2.3 });

            var comparer     = new ObjectSetComparer(objectFlattener, underlyingComparer);
            var comparedSets = comparer.CompareObjectSets <object>((idx, obj) =>
            {
                var dict             = new Dictionary <string, object>();
                dict[idx.ToString()] = idx;
                return(dict);
            },
                                                                   items1,
                                                                   items2);

            Assert.Empty(comparedSets.Differences);
            Assert.Empty(comparedSets.AdditionalKeys);
            Assert.Empty(comparedSets.MissingKeys);
            Assert.Equal(200, comparedSets.MatchingKeysCount);
            Assert.Empty(comparedSets.IncomparableKeys);
        }
        public void DuplicateKey_Additional()
        {
            var underlyingComparer = new ObjectComparer {
                ObjectComparerMismatchedKeysBehaviour = ObjectComparerMismatchedKeysBehaviour.Throw, ObjectComparerNoAvailablePluginBehaviour = ObjectComparerNoAvailablePluginBehaviour.Throw
            };

            underlyingComparer.ComparisonPlugins.Add(new Plugins.SimpleStringComparerPlugin());
            underlyingComparer.ComparisonPlugins.Add(new Plugins.DoubleComparerPlugin());
            underlyingComparer.ComparisonPlugins.Add(new Plugins.Int32ComparerPlugin());

            var objectFlattener = new BorsukSoftware.ObjectFlattener.ObjectFlattener {
                NoAvailablePluginBehaviour = ObjectFlattener.NoAvailablePluginBehaviour.Throw
            };

            objectFlattener.Plugins.Add(new BorsukSoftware.ObjectFlattener.Plugins.StandardPlugin());

            var items1 = Enumerable.Range(0, 200).
                         Select(i => new ComparisonObjectType {
                KeyPart1 = i.ToString(), Value1 = 2.3 * i, Value2 = 2.4 * i, Value3 = 2.5 * i
            }).
                         ToList();

            var items2 = Enumerable.Range(0, 200).Concat(new[] { 0 }).
                         Select(i => new ComparisonObjectType {
                KeyPart1 = i.ToString(), Value1 = 2.3 * i, Value2 = 2.4 * i, Value3 = 2.5 * i
            }).
                         ToList();

            var comparer     = new ObjectSetComparer(objectFlattener, underlyingComparer);
            var comparedSets = comparer.CompareObjectSets((idx, obj) =>
            {
                var dict         = new Dictionary <string, object>();
                dict["KeyPart1"] = obj.KeyPart1;
                dict["KeyPart2"] = obj.KeyPart2;
                return(dict);
            },
                                                          items1,
                                                          items2);

            Assert.Empty(comparedSets.Differences);
            Assert.Empty(comparedSets.AdditionalKeys);
            Assert.Empty(comparedSets.MissingKeys);
            Assert.Equal(199, comparedSets.MatchingKeysCount);

            Assert.Single(comparedSets.IncomparableKeys);
            var incomparableItem = comparedSets.IncomparableKeys.Single();

            incomparableItem.Key.Should().BeEquivalentTo(new[] { new KeyValuePair <string, object>("KeyPart1", "0"), new KeyValuePair <string, object>("KeyPart2", "Macro") });
            Assert.Equal(1, incomparableItem.Value.ExpectedObjects.Count);
            Assert.Equal(2, incomparableItem.Value.ActualObjects.Count);
        }
Пример #3
0
        private static void SimpleMode()
        {
            Console.WriteLine("Simple mode");
            var @object = new
            {
                property1  = 2.3,
                property2  = 2.3f,
                property3  = "str",
                property4  = 1,
                property5  = 1L,
                property6  = (short)1,
                nestedProp = new
                {
                    nes1 = 2.3d,
                    nes2 = 5.6,
                    sd   = "AOF"
                }
            };

            var @object2 = new
            {
                property1  = 2.31,
                property2  = 2.33f,
                property3  = "str",
                property4  = 1,
                property5  = 1L,
                property6  = (short)1,
                nestedProp = new
                {
                    nes1 = 2.3f,
                    nes2 = 5.6,
                    sd   = "aof"
                }
            };

            var extractor = new BorsukSoftware.ObjectFlattener.ObjectFlattener();

            extractor.Plugins.Add(new BorsukSoftware.ObjectFlattener.Plugins.StandardPlugin()
            {
                ProcessFields     = true,
                ProcessProperties = true
            });

            var comparer = new BorsukSoftware.Testing.Comparison.ObjectComparer
            {
                ObjectComparerNoAvailablePluginBehaviour = BorsukSoftware.Testing.Comparison.ObjectComparerNoAvailablePluginBehaviour.ReportAsDifference
            };

            comparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.DoubleComparerPlugin());
            comparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.FloatComparerPlugin());
            comparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.Int16ComparerPlugin());
            comparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.Int32ComparerPlugin());
            comparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.Int64ComparerPlugin());
            comparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.SimpleStringComparerPlugin()
            {
                IgnoreCase = true
            });

            var output = comparer.CompareValues(extractor.FlattenObject(null, @object), extractor.FlattenObject(null, object2));

            foreach (var pair in output)
            {
                Console.WriteLine($" {pair.Key} - {pair.Value.ExpectedValue} ({pair.Value.ExpectedValue?.GetType()?.Name}) vs. {pair.Value.ActualValue} ({pair.Value.ActualValue?.GetType()?.Name})=> {pair.Value.ComparisonPayload}");
            }
        }
        public void Standard()
        {
            var underlyingComparer = new ObjectComparer {
                ObjectComparerMismatchedKeysBehaviour = ObjectComparerMismatchedKeysBehaviour.Throw, ObjectComparerNoAvailablePluginBehaviour = ObjectComparerNoAvailablePluginBehaviour.Throw
            };

            // To exclude KeyPart1 / 2 from being compared, they can either be marked as always passing OR they can be excluded from the object flattening process. Usually easier to do so in the comparer
            // Note that this isn't really necessary as if the keys match, then these values will be equal and therefore should pass (unless there's no comparer plugin specified for them of course)
            underlyingComparer.ComparisonPlugins.Add(new Plugins.FunctionBasedComparerPlugin((name, obj1, obj2) =>
            {
                if (name.EndsWith(nameof(ComparisonObjectType.KeyPart1)) || name.EndsWith(nameof(ComparisonObjectType.KeyPart2)))
                {
                    return new ObjectComparerPluginResults {
                        ComparisonResultType = ComparisonResultType.Equal
                    }
                }
                ;

                return(new ObjectComparerPluginResults {
                    ComparisonResultType = ComparisonResultType.UnableToCompare
                });
            }));

            // If it was desired to exclude a particular value from the comparison, say a new field has been added and comparisons wish to be done excluding that, then create
            // a custom plugin for the comparer to mark those values as having matched
            // underlyingComparer.ComparisonPlugins.Add(new Plugins.FunctionBasedComparerPlugin((name, obj1, obj2) =>
            // {
            //     if (name.EndsWith(nameof(ComparisonObjectType.RandomValue)))
            //         return new ObjectComparerPluginResults { ComparisonResultType = ComparisonResultType.Equal };
            //
            //     return new ObjectComparerPluginResults { ComparisonResultType = ComparisonResultType.UnableToCompare };
            // }));
            // The alternative is to exclude the object from flattening...


            underlyingComparer.ComparisonPlugins.Add(new Plugins.SimpleStringComparerPlugin());
            underlyingComparer.ComparisonPlugins.Add(new Plugins.DoubleComparerPlugin());
            underlyingComparer.ComparisonPlugins.Add(new Plugins.Int32ComparerPlugin());

            var objectFlattener = new BorsukSoftware.ObjectFlattener.ObjectFlattener {
                NoAvailablePluginBehaviour = ObjectFlattener.NoAvailablePluginBehaviour.Throw
            };

            // Uncomment this code to not report the value for RandomValue in the output (note, must be at the beginning of the list to avoid the standard plugin handling it)
            // objectFlattener.Plugins.Add(new BorsukSoftware.ObjectFlattener.Plugins.FunctionBasedPlugin((name, obj) => name.EndsWith(nameof(ComparisonObjectType.RandomValue)), (of, name, obj) => Enumerable.Empty<KeyValuePair<string, object>>());

            objectFlattener.Plugins.Add(new BorsukSoftware.ObjectFlattener.Plugins.StandardPlugin());

            var items1 = Enumerable.Range(0, 200).
                         Select(i => new ComparisonObjectType {
                KeyPart1 = i.ToString(), Value1 = 2.3 * i, Value2 = 2.4 * i, Value3 = 2.5 * i
            }).
                         ToList();

            var items2 = Enumerable.Range(0, 200).
                         Select(i => new ComparisonObjectType {
                KeyPart1 = i.ToString(), Value1 = 2.3 * i, Value2 = 2.4 * i, Value3 = 2.5 * i
            }).
                         ToList();

            items2[23].Value3  += 6.7;
            items2[27].KeyPart1 = "28";

            var comparer     = new ObjectSetComparer(objectFlattener, underlyingComparer);
            var comparedSets = comparer.CompareObjectSets((idx, obj) =>
            {
                var dict         = new Dictionary <string, object>();
                dict["KeyPart1"] = obj.KeyPart1;
                dict["KeyPart2"] = obj.KeyPart2;
                return(dict);
            },
                                                          items1,
                                                          items2);

            Assert.Single(comparedSets.Differences);
            var difference = comparedSets.Differences.Single();

            difference.Key.Should().BeEquivalentTo(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("KeyPart1", "23"), new KeyValuePair <string, object>("KeyPart2", "Macro") });

            Assert.Single(comparedSets.MissingKeys);
            var missingKey = comparedSets.MissingKeys.Single();

            missingKey.Should().BeEquivalentTo(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("KeyPart1", "27"), new KeyValuePair <string, object>("KeyPart2", "Macro") });

            Assert.Single(comparedSets.IncomparableKeys);
            var incomparableKey = comparedSets.IncomparableKeys.Single();

            incomparableKey.Key.Should().BeEquivalentTo(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("KeyPart1", "28"), new KeyValuePair <string, object>("KeyPart2", "Macro") });

            Assert.Equal(197, comparedSets.MatchingKeysCount);
        }
Пример #5
0
        private static void FinanceMode()
        {
            Console.WriteLine("Finance mode");

            // Spoof up some data - typically this would be read in from your actual system / expected set of results etc.
            DataStucture[] data = new DataStucture[2];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = new DataStucture();

                data[i].InstrumentLevelResults = new InstrumentResults[200];
                for (int j = 0; j < data[i].InstrumentLevelResults.Length; ++j)
                {
                    data[i].InstrumentLevelResults[j] = new InstrumentResults()
                    {
                        BaseCurrency      = "GBP",
                        Identifier        = $"Trade #{j}",
                        LocalValue        = 200 + (20 * j),
                        BaseCurrencyValue = 200 + (20 * j)
                    };
                }
            }

            var r             = new Random();
            var itemsToUpdate = r.Next(20);

            for (int i = 0; i < itemsToUpdate; ++i)
            {
                var idx = r.Next(data[1].InstrumentLevelResults.Length);
                data[1].InstrumentLevelResults[idx].LocalValue += 2 * r.NextDouble();

                // Randomly adjust a second value for demonstration purposes
                if (r.NextDouble() < 0.2)
                {
                    data[1].InstrumentLevelResults[idx].BaseCurrencyValue += 2 * r.NextDouble();
                }
            }

            var objectFlattener = new BorsukSoftware.ObjectFlattener.ObjectFlattener();

            objectFlattener.Plugins.Add(new BorsukSoftware.ObjectFlattener.Plugins.StandardPlugin());

            var objectComparer = new BorsukSoftware.Testing.Comparison.ObjectComparer();

            objectComparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.SimpleStringComparerPlugin());
            objectComparer.ComparisonPlugins.Add(new BorsukSoftware.Testing.Comparison.Plugins.DoubleComparerPlugin());

            // Perform the actual comparison...
            var comparisons = Enumerable.Range(0, data[0].InstrumentLevelResults.Length).
                              Select(i => new { i, expected = data[0].InstrumentLevelResults[i], actual = data[1].InstrumentLevelResults[i] }).
                              Select(tuple => new
            {
                tuple.actual,
                tuple.expected,
                comparisons = objectComparer.CompareValues(
                    objectFlattener.FlattenObject(null, tuple.expected),
                    objectFlattener.FlattenObject(null, tuple.actual)).ToList()
            }).
                              ToList();

            // Create a friendly output format for display
            var matching    = comparisons.Where(t => t.comparisons.Count == 0).ToList();
            var differences = comparisons.Where(t => t.comparisons.Count != 0).ToList();

            var output = new
            {
                summary = new
                {
                    matching    = matching.Count,
                    differences = differences.Count
                },
                differences = differences.Select(t => new
                {
                    identifier  = t.actual.Identifier,
                    differences = t.comparisons.Select(t2 => new
                    {
                        key        = t2.Key,
                        expected   = t2.Value.ExpectedValue,
                        actual     = t2.Value.ActualValue,
                        difference = t2.Value.ComparisonPayload
                    })
                }),
            };

            var text = System.Text.Json.JsonSerializer.Serialize(output, new System.Text.Json.JsonSerializerOptions {
                WriteIndented = true
            });

            Console.WriteLine(text);
        }