List <ComparisonReport> TestZippedFiles(string zipFile, string outputFolder) { output.WriteLine(zipFile); var result = new List <ComparisonReport>(); using (var file = File.OpenRead(zipFile)) using (var zip = new ZipArchive(file, ZipArchiveMode.Read)) { foreach (var entry in zip.Entries.Where(e => Path.GetExtension(e.Name) == ".xbrl")) { output.WriteLine($"\t{entry.Name}"); var outputFile = Path.Combine(outputFolder, Path.ChangeExtension(entry.Name, "out")); var memoryStream = new MemoryStream(); using (var zipStream = entry.Open()) zipStream.CopyTo(memoryStream); var instance = Instance.FromStream(memoryStream); instance.ToFile(outputFile); var report = InstanceComparer.Report(instance, Instance.FromFile(outputFile)); File.WriteAllLines(Path.Combine(outputFolder, Path.ChangeExtension(entry.Name, "log")), report.Messages); result.Add(report); } } return(result); }
public static void ChooseBasicComparisons() { // Load same file twice // change the other a little, save it and reload so we get a fresh instance // bypassing some bugs that lead to not everything updating on the fly :( var path = Path.Combine("data", "minimal.xbrl"); var tempPath = Path.GetTempFileName(); var first = Instance.FromFile(path); var second = Instance.FromFile(path); var period = new Period(2050, 12, 31); var entity = new Entity("foo", "bar"); foreach (var context in second.Contexts) { context.Period = period; context.Entity = entity; } second.ToFile(tempPath); second = Instance.FromFile(tempPath); ComparisonReport report = null; string[] expectedMessages = null; BasicComparisons basicSelection; // Full comparison outputs both Entity and Period from basic and detailed comparion report = InstanceComparer.Report(first, second, ComparisonTypes.All); Assert.False(report.Result); expectedMessages = new string[] { "Different Entity", "Different Period", $"(a) {first.Contexts[0].Entity}", $"(b) {second.Contexts[0].Entity}", $"(a) {first.Contexts[0].Period}", $"(b) {second.Contexts[0].Period}" }; Assert.Equal(expectedMessages, report.Messages);//, report.Messages.Join(Environment.NewLine)); // basic comparison with all flags reports Entity and Period basicSelection = BasicComparisons.All; report = InstanceComparer.Report(first, second, ComparisonTypes.Basic); Assert.False(report.Result); expectedMessages = new string[] { "Different Entity", "Different Period", }; Assert.Equal(expectedMessages, report.Messages);//, report.Messages.Join(Environment.NewLine)); // basic comparison without Entity and Period flags does not list any differences basicSelection &= ~BasicComparisons.Entity; basicSelection &= ~BasicComparisons.Period; report = InstanceComparer.Report(first, second, ComparisonTypes.Basic, basicSelection); Assert.True(report.Result); }
public static void CompareDifferentUnits() { var path = Path.Combine("data", "reference.xbrl"); var first = Instance.FromFile(path); var second = Instance.FromFile(path); var unit = new Unit("uUSD", "iso4217:USD"); second.Units.Add(unit); second.Facts[1].Unit = unit; second.Units.Remove("uEUR"); // write+read just to make sure all references are updated internally :( var tmpfile = Path.GetTempFileName(); second.ToFile(tmpfile); second = Instance.FromFile(tmpfile); var report = InstanceComparer.Report(first, second, ComparisonTypes.All); Assert.False(report.Result); var expectedMessages = new string[] { "Different Units", $"(a) {first.Facts[1]} ({first.Facts[1].Context.Scenario})", $"(b) {second.Facts[1]} ({second.Facts[1].Context.Scenario})", "(a) iso4217:EUR", "(b) iso4217:USD", }; Assert.Equal(expectedMessages, report.Messages);//, report.Messages.Join(Environment.NewLine)); }
public static void CompareReportTest() { // load same instance twice var path = Path.Combine("data", "reference.xbrl"); var report = InstanceComparer.Report(path, path, ComparisonTypes.Contexts); Assert.True(report.Result, string.Join(Environment.NewLine, report.Messages)); }
static ComparisonReport TestFile(string inputFile, string outputFile, string reportFile) { Instance.FromFile(inputFile).ToFile(outputFile); var report = InstanceComparer.Report(inputFile, outputFile); File.WriteAllLines(reportFile, report.Messages); return(report); }
public static void InstancesAreComparableAfterCreation() { var first = new Instance(); var second = new Instance(); var comparison = InstanceComparer.Report(first, second); Assert.True(comparison.Result, string.Join(Environment.NewLine, comparison.Messages)); }
public static void CompareDomainNamespacesOfTotallyDifferentInstances() { var firstPath = Path.Combine("data", "reference.xbrl"); var secondPath = Path.Combine("data", "ars.xbrl"); var report = InstanceComparer.Report(firstPath, secondPath, ComparisonTypes.DomainNamespaces); Assert.False(report.Result); Assert.NotEmpty(report.Messages); }
public static void CompareDomainNamespacesOfTotallyDifferentInstances() { var firstPath = Path.Combine("data", "reference.xbrl"); var secondPath = Path.Combine("data", "ars.xbrl"); var report = InstanceComparer.Report(firstPath, secondPath, ComparisonTypes.DomainNamespaces); Console.WriteLine(string.Join(Environment.NewLine, report.Messages)); Assert.IsFalse(report.Result); CollectionAssert.IsNotEmpty(report.Messages); }
public static void CompareScenarioMemberOrderDifferent() { var left = Instance.FromFile(Path.Combine("data", "memberorder0.xbrl")); var right = Instance.FromFile(Path.Combine("data", "memberorder1.xbrl")); Assert.Equal(left, right); var report = InstanceComparer.Report(left, right); Assert.True(report.Result, string.Join(Environment.NewLine, report.Messages)); }
public static void CompareEntityWithNoEntity() { var first = Instance.FromFile(Path.Combine("data", "empty_instance.xbrl")); var second = Instance.FromFile(Path.Combine("data", "empty_instance.xbrl")); second.Entity = new Entity("LEI", "00000000000000000098"); second.Period = new Period(2016, 05, 31); second.AddFilingIndicator("foo", false); // should not throw Assert.IsNotNull(InstanceComparer.Report(first, second)); }
public static void CompareInstanceToItselfWithPath() { // load same instance twice and compare var path = Path.Combine("data", "reference.xbrl"); var report = InstanceComparer.Report(path, path); // comparison should find the instances equivalent Assert.True(report.Result); // there should be no differences reported Assert.Empty(report.Messages);//, report.Messages.Join(Environment.NewLine)); }
public static void CompareInstanceToItself() { // load same instance twice and compare var path = Path.Combine("data", "reference.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); var report = InstanceComparer.Report(firstInstance, secondInstance); Console.WriteLine(string.Join(Environment.NewLine, report.Messages)); // comparison should find the instances equivalent Assert.IsTrue(report.Result); // there should be no differences reported CollectionAssert.IsEmpty(report.Messages); }
public static void CompareFactWithMissingUnit() { var path = Path.Combine("data", "reference.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); // comparing this should not throw secondInstance.Facts[0].Unit = null; var report = InstanceComparer.Report(firstInstance, secondInstance); Assert.False(report.Result); Assert.Equal(2, report.Messages.Count); //, report.Messages.Join(Environment.NewLine)); }
public static void BypassTaxonomyVersion() { var path = Path.Combine("data", "reference.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); secondInstance.TaxonomyVersion = null; var types = ComparisonTypes.All & ~ComparisonTypes.TaxonomyVersion; var report = InstanceComparer.Report(firstInstance, secondInstance, types); Assert.True(report.Result); }
public void DefaultNamespaceIsHandledCorrectly() { // should be completely the same instance // first has canonical prefix "xbrli" for "http://www.xbrl.org/2003/instance" // and second has it as default namespace var first = Path.Combine("data", "reference.xbrl"); var second = Path.Combine("data", "reference_defaultns.xbrl"); var report = InstanceComparer.Report(first, second); if (!report.Result) { Console.WriteLine(report); } Assert.True(report.Result); }
public static void CompareBasicNullValues() { // load same instance twice and compare var path = Path.Combine("data", "reference.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); secondInstance.TaxonomyVersion = null; secondInstance.SchemaReference = null; var report = InstanceComparer.Report(firstInstance, secondInstance, ComparisonTypes.Basic); // comparison should find the instances different and not throw Assert.False(report.Result); Assert.NotEmpty(report.Messages);//, report.Messages.Join(Environment.NewLine)); }
public static void CompareSimilarFacts() { // load same instance twice and compare var path = Path.Combine("data", "reference.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); secondInstance.Facts[0].Value = "0"; secondInstance.Facts[1].Value = "0"; var report = InstanceComparer.Report(firstInstance, secondInstance, ComparisonTypes.Facts); // comparison should find the instances different and not throw Assert.False(report.Result); Assert.NotEmpty(report.Messages); Assert.Equal(4, report.Messages.Count); // report.Messages.Join(Environment.NewLine)); }
public static void CompareInstancesTypedMemberDifferent() { // load same instance twice var path = Path.Combine("data", "reference.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); // change second only slightly and compare secondInstance.Contexts[1].Scenario.TypedMembers[0].Value = "abcd"; var report = InstanceComparer.Report(firstInstance, secondInstance); Console.WriteLine(string.Join(Environment.NewLine, report.Messages)); // not the same anymore Assert.IsFalse(report.Result); // should contain some differences CollectionAssert.IsNotEmpty(report.Messages); // one context is different, report should reflect this once per instance Assert.AreEqual(2, report.Messages.Count); }
public static void CompareLargeInstanceMinorDifferenceInFact() { // load same instance twice var path = Path.Combine("data", "ars.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); // change second only slightly and compare // original is 0 secondInstance.Facts[33099].Value = "0.0"; var report = InstanceComparer.Report(firstInstance, secondInstance, ComparisonTypes.Facts); Console.WriteLine(string.Join(Environment.NewLine, report.Messages)); // not the same anymore Assert.IsFalse(report.Result); // should contain some differences CollectionAssert.IsNotEmpty(report.Messages); // one context is different, report should reflect this once per instance Assert.AreEqual(2, report.Messages.Count); }
public static void CompareLargeInstanceMinorDifferenceInFact() { // load same instance twice var path = Path.Combine("data", "ars.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); // change one fact in both instances // original is 0 firstInstance.Facts[33099].Value = "FOOBAR"; secondInstance.Facts[33099].Value = "DEADBEEF"; var report = InstanceComparer.Report(firstInstance, secondInstance, ComparisonTypes.Facts); // not the same anymore Assert.False(report.Result); // should contain some differences Assert.NotEmpty(report.Messages); // one fact is different, report should reflect this once per instance Assert.Equal(2, report.Messages.Count);// report.Messages.Join(Environment.NewLine)); }
public static void ComparisonReportContainsContextWithNullScenario() { // load same instance twice var path = Path.Combine("data", "reference.xbrl"); var firstInstance = Instance.FromFile(path); var secondInstance = Instance.FromFile(path); // modify other one so they produce differences to report foreach (var context in secondInstance.Contexts) { context.Entity.Identifier.Value = "00000000000000000098"; } var report = InstanceComparer.Report(firstInstance, secondInstance); // comparison should find the instances different and not crash Assert.False(report.Result); // there should be some differences reported Assert.NotEmpty(report.Messages);//, report.Messages.Join(Environment.NewLine)); }
public static void CompareDifferentEntityAndPeriodOnly() { var path = Path.Combine("data", "reference.xbrl"); var path2 = Path.Combine("data", "reference2.xbrl"); var report = InstanceComparer.Report(path, path2); Assert.False(report.Result); string[] expectedMessages = { "Different Entity", "Different Period", "(a) Identifier=http://standards.iso.org/iso/17442:1234567890ABCDEFGHIJ", "(b) Identifier=http://standards.iso.org/iso/17442:00000000000000000098", "(a) Instant=2014-12-31", "(b) Instant=2015-12-31" }; // Does NOT report the differences for each context Assert.Equal(expectedMessages, report.Messages);//, report.Messages.Join(Environment.NewLine)); }
public void CompareSolvencyReferenceInstance() { var instance = CreateSolvencyInstance(); // unless done when loading, duplicate objects // aren't automatically removed until serialization so do it before comparisons instance.RemoveUnusedObjects(); var referencePath = Path.Combine("data", "reference.xbrl"); var referenceInstance = Instance.FromFile(referencePath, true); // Instances are functionally equivalent: // They have the same number of contexts and scenarios of the contexts match member-by-member // Members are checked by dimension, domain and value, namespaces included // They have the same facts matched by metric, value, decimals and unit // Entity and Period are also matched // Some things are NOT checked, eg. taxonomy version, context names //Assert.Equal(instance, referenceInstance); string tempFile = "temp.xbrl"; instance.ToFile(tempFile); var newInstance = Instance.FromFile(tempFile, true); // Assert.True(newInstance.Equals(instance)); var report = InstanceComparer.Report(instance, newInstance); if (!report.Result) { Console.WriteLine(report); } Assert.Empty(report.Messages); Assert.True(newInstance.Equals(referenceInstance)); newInstance.Contexts[1].AddExplicitMember("AM", "s2c_AM:x1"); Assert.False(newInstance.Equals(referenceInstance)); }
public void AddLargeNumberOfContexts() { // This test demonstrates the usual scenario of adding contexts to an instance // There is a performance hit that comes from checking each new context // against existing ones to avoid duplicates (GetContext) // This of course does not scale well // Duplicate checking and removing can be done at caller side when // creating the scenarios and/or after adding all contexts // So now there is a new method (CreateContext) // that does not check for duplicates var numberOfRuns = 5000; Instance instance; Context context = null; Scenario scenario; Stopwatch sw; instance = CreateTestInstance(); sw = Stopwatch.StartNew(); for (int i = 0; i < numberOfRuns; i++) { scenario = new Scenario(); scenario.ExplicitMembers.Add("BL", "s2c_LB:x142"); scenario.ExplicitMembers.Add("CS", "s2c_CS:x26"); scenario.ExplicitMembers.Add("LX", "s2c_GA:LU"); scenario.ExplicitMembers.Add("PI", "s2c_PI:x1"); scenario.ExplicitMembers.Add("VG", "s2c_AM:x80"); scenario.TypedMembers.Add("XX", "ID", "12345"); scenario.ExplicitMembers.Add("VL", $"s2c_VM:x{i}"); // <- change one member slightly so each context is different scenario.Instance = instance; // GetContext compares the scenario to existing ones // and returns the match if found // creates and returns a new one if not found context = instance.GetContext(scenario); instance.AddFact(context, "mi363", "uEUR", "-3", $"{i}"); } //output.WriteLine($"instance made with GetContext has {instance.Contexts.Count} contexts"); // removing duplicates should not be needed but // make sure we do the same cleanup for both methods // so any timing is comparable instance.CollapseDuplicateContexts(); instance.RemoveUnusedObjects(); sw.Stop(); output.WriteLine($"GetContext {sw.Elapsed}"); instance.ToFile("GetContext.xbrl"); // load a minimal instance to work with // and setup a scenario to add instance = CreateTestInstance(); sw = Stopwatch.StartNew(); for (int i = 0; i < numberOfRuns; i++) { scenario = new Scenario(); scenario.ExplicitMembers.Add("BL", "s2c_LB:x142"); scenario.ExplicitMembers.Add("CS", "s2c_CS:x26"); scenario.ExplicitMembers.Add("LX", "s2c_GA:LU"); scenario.ExplicitMembers.Add("PI", "s2c_PI:x1"); scenario.ExplicitMembers.Add("VG", "s2c_AM:x80"); scenario.TypedMembers.Add("XX", "ID", "12345"); scenario.ExplicitMembers.Add("VL", $"s2c_VM:x{i}"); // <- change one member slightly so each context is different scenario.Instance = instance; // CreateContext always creates and returns a new context // without overhead of checking existing ones for duplicates context = instance.CreateContext(scenario); instance.AddFact(context, "mi363", "uEUR", "-3", $"{i}"); } //output.WriteLine($"instance made with CreateContext has {instance.Contexts.Count} contexts"); // since we didn't check for existing matching scenarios // there can be duplicates that need to be cleaned up instance.CollapseDuplicateContexts(); instance.RemoveUnusedObjects(); sw.Stop(); output.WriteLine($"CreateContext {sw.Elapsed}"); instance.ToFile("CreateContext.xbrl"); // both methods should produce same result var result = InstanceComparer.Report("GetContext.xbrl", "CreateContext.xbrl"); Assert.True(result.Result, string.Join(Environment.NewLine, result.Messages)); }