private static ICondition <TRuleType> createPlantUmlCondition(PlantUmlDiagram diagram)
        {
            ClassDiagramAssociation classDiagramAssociation = new ClassDiagramAssociation(diagram);

            ConditionResult Condition(TRuleType ruleType)
            {
                if (ruleType.Dependencies.All(d => !classDiagramAssociation.Contains(d.Target)))
                {
                    return(new ConditionResult(ruleType, true));
                }
                List <string> allAllowedTargets = new List <string>();

                allAllowedTargets.AddRange(classDiagramAssociation.GetNamespaceIdentifiersFromComponentOf(ruleType)
                                           .Concat(classDiagramAssociation.GetTargetNamespaceIdentifiers(ruleType))
                                           .ToList());

                var pass = true;
                var dynamicFailDescription = "does depend on";

                foreach (var dependency in ruleType.GetTypeDependencies())
                {
                    if (classDiagramAssociation.Contains(dependency) && !allAllowedTargets.Any(pattern => dependency.FullNameMatches(pattern, true)))
                    {
                        dynamicFailDescription += pass ? " " + dependency.FullName : " and " + dependency.FullName;
                        pass = false;
                    }
                }
                return(new ConditionResult(ruleType, pass, dynamicFailDescription));
            }

            return(new SimpleCondition <TRuleType>(Condition, "adhere to PlantUML diagram."));
        }
        public void ReportsIfClassIsContainedInAnyComponent()
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                ClassDiagramAssociation classDiagramAssociation = CreateAssociation(TestDiagram.From(memoryStream)
                                                                                    .Component("Object").WithStereoTypes(typeof(object).Namespace)
                                                                                    .Write());

                Assert.True(classDiagramAssociation.Contains(Architecture.GetClassOfType(typeof(object))), "association contains " + typeof(object).Name);
                Assert.False(classDiagramAssociation.Contains(Architecture.GetClassOfType(typeof(Class2))), "association contains " + typeof(Class2).Name);
            }
        }
        public void RejectsClassNotContainedInAnyComponent()
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                ClassDiagramAssociation classDiagramAssociation = CreateAssociation(TestDiagram.From(memoryStream)
                                                                                    .Component("SomeComponent").WithStereoTypes(".*.SomeStereotype.")
                                                                                    .Write());

                Class classNotContained = Architecture.GetClassOfType(typeof(object));

                InvalidOperationException exception = Assert.Throws <InvalidOperationException>(() => classDiagramAssociation.GetTargetNamespaceIdentifiers(classNotContained));
                Assert.Equal(string.Format("Class {0} is not contained in any component", typeof(object).Name), exception.Message);
            }
        }
        public void GetNamespaceIdentifierAssociatedWithClass()
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                string expectedNamespaceIdentifier = typeof(SomeOriginClass).Namespace;
                ClassDiagramAssociation classDiagramAssociation = CreateAssociation(TestDiagram.From(memoryStream)
                                                                                    .Component("A").WithStereoTypes(expectedNamespaceIdentifier)
                                                                                    .Component("B").WithStereoTypes(".*.Noclasshere")
                                                                                    .Write());

                Class clazz = Architecture.GetClassOfType(typeof(SomeOriginClass));
                Assert.Equal(expectedNamespaceIdentifier, classDiagramAssociation.GetNamespaceIdentifiersFromComponentOf(clazz).Single());
            }
        }
        public void ClassResidesInMultipleNamespaces()
        {
            string path = Path.Combine(Path.GetTempPath(), "plantuml_diagram_" + Guid.NewGuid() + ".puml");

            using (FileStream fileStream = File.Create(path))
            {
                TestDiagram.From(fileStream)
                .Component("A").WithStereoTypes(".*.FooNamespace.*")
                .Component("B").WithStereoTypes(".*.BarNamespace.*")
                .Write();
            }

            ClassDiagramAssociation classDiagramAssociation = CreateAssociation(path);
            Class classContainedInTwoComponents             = Architecture.GetClassOfType(typeof(ClassInFooAndBarNamespace));

            ComponentIntersectionException exception = Assert.Throws <ComponentIntersectionException>(() => classDiagramAssociation.GetTargetNamespaceIdentifiers(classContainedInTwoComponents));

            Assert.Equal(string.Format("Class {0} may not be contained in more than one component, but is contained in [A, B]", typeof(ClassInFooAndBarNamespace).Name), exception.Message);
        }
        public void GetTargetNamespaceIdentifierOfClass()
        {
            string expectedTarget1 = ".*.Target1";
            string expectedTarget2 = ".*.Target2";

            using (MemoryStream memoryStream = new MemoryStream())
            {
                ClassDiagramAssociation classDiagramAssociation = CreateAssociation(TestDiagram.From(memoryStream)
                                                                                    .Component("A").WithStereoTypes(Regex.Replace(typeof(SomeOriginClass).Namespace, @".*\.", ".*."))
                                                                                    .Component("B").WithStereoTypes(expectedTarget1)
                                                                                    .Component("C").WithStereoTypes(expectedTarget2)
                                                                                    .DependencyFrom("[A]").To("[B]")
                                                                                    .DependencyFrom("[A]").To("[C]")
                                                                                    .Write());

                Class clazz = Architecture.GetClassOfType(typeof(SomeOriginClass));

                Assert.Equal(new[] { expectedTarget1, expectedTarget2 }, classDiagramAssociation.GetTargetNamespaceIdentifiers(clazz).OrderBy(s => s).ToList());
            }
        }