Example #1
0
        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));
        }
Example #5
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        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));
        }
Example #10
0
        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));
        }
Example #12
0
        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);
        }
Example #15
0
        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));
        }
Example #18
0
        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);
        }
Example #19
0
        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));
        }
Example #23
0
        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));
        }
Example #24
0
        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));
        }