diff --git a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDependency.cs b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDependency.cs index 50530a951..8191b4b41 100644 --- a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDependency.cs +++ b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDependency.cs @@ -51,24 +51,13 @@ public string GetPlantUmlString(RenderOptions renderOptions = null) + Environment.NewLine; case DependencyType.OneToPackage: - return "[" - + Origin - + "] -[#red]> " - + GetChildNamespace(Target) - + Environment.NewLine; + return "[" + Origin + "] -[#red]> " + Target + Environment.NewLine; case DependencyType.PackageToOne: - return GetChildNamespace(Origin) - + " -[#blue]> [" - + Target - + "]" - + Environment.NewLine; + return Origin + " -[#blue]> [" + Target + "]" + Environment.NewLine; case DependencyType.PackageToPackage: - return GetChildNamespace(Origin) - + " -[#green]> " - + GetChildNamespace(Target) - + Environment.NewLine; + return Origin + " -[#green]> " + Target + Environment.NewLine; case DependencyType.OneToOneCompact: if (OriginCountOfDots() == TargetCountOfDots()) @@ -93,10 +82,7 @@ public string GetPlantUmlString(RenderOptions renderOptions = null) && (OriginCountOfDots() == 0 || HaveSameParentNamespace(Origin, Target)) ) { - return GetChildNamespace(Origin) - + " ..> " - + GetChildNamespace(Target) - + Environment.NewLine; + return Origin + " ..> " + Target + Environment.NewLine; } return ""; @@ -119,7 +105,7 @@ public string GetPlantUmlString(RenderOptions renderOptions = null) if (tmp != Origin && HaveSameParentNamespace(tmp, Origin)) { - return Origin + " --> " + GetChildNamespace(tmp) + Environment.NewLine; + return Origin + " --> " + tmp + Environment.NewLine; } } else @@ -132,7 +118,7 @@ public string GetPlantUmlString(RenderOptions renderOptions = null) if (tmp != Target && HaveSameParentNamespace(tmp, Target)) { - return GetChildNamespace(tmp) + " -> " + Target + Environment.NewLine; + return tmp + " -> " + Target + Environment.NewLine; } } return ""; @@ -147,9 +133,6 @@ public string GetPlantUmlString(RenderOptions renderOptions = null) private static string GetParentNamespace(string ns) => ns.Remove(ns.LastIndexOf(".", StringComparison.Ordinal)); - private static string GetChildNamespace(string ns) => - ns.Remove(0, ns.LastIndexOf(".", StringComparison.Ordinal) + 1); - private static bool HaveSameParentNamespace(string origin, string target) => (GetParentNamespace(origin) == GetParentNamespace(target)); diff --git a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs index bdc6996a7..6d808cd65 100644 --- a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs +++ b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs @@ -29,20 +29,48 @@ public string GetPlantUmlString(RenderOptions renderOptions) ) .AppendLine(); result.AppendLine("HIDE_STEREOTYPE()").AppendLine(); - result.Append( - PlantUmlElements - .OrderBy(element => element.GetType() != typeof(PlantUmlNamespace)) - .ThenBy(element => element.GetType() != typeof(PlantUmlSlice)) - .ThenBy(element => element.GetType() != typeof(PlantUmlClass)) - .ThenBy(element => element.GetType() != typeof(PlantUmlInterface)) - .Aggregate( - "", - (umlString, umlElement) => - umlString + umlElement.GetPlantUmlString(renderOptions) - ) - ); + var orderedElements = PlantUmlElements + .OrderBy(element => element.GetType() != typeof(PlantUmlNamespace)) + .ThenBy(element => element.GetType() != typeof(PlantUmlSlice)) + .ThenBy(element => element.GetType() != typeof(PlantUmlClass)) + .ThenBy(element => element.GetType() != typeof(PlantUmlInterface)); + foreach (var element in MergeNestedSlices(orderedElements)) + { + result.Append(element.GetPlantUmlString(renderOptions)); + } result.AppendLine("@enduml"); return result.ToString(); } + + /// + /// Replaces all nested slices that share a root package with a single tree for that + /// package, placed where its first slice was. All other elements keep their position. + /// + private static IEnumerable MergeNestedSlices( + IEnumerable elements + ) + { + var mergedElements = new List(); + var sliceTrees = new Dictionary(); + foreach (var element in elements) + { + if (!(element is PlantUmlSlice slice) || !slice.IsNested) + { + mergedElements.Add(element); + } + else if (sliceTrees.TryGetValue(slice.RootPackage, out var tree)) + { + tree.Add(slice); + } + else + { + tree = new PlantUmlSliceTree(slice); + sliceTrees.Add(slice.RootPackage, tree); + mergedElements.Add(tree); + } + } + + return mergedElements; + } } } diff --git a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlSlice.cs b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlSlice.cs index ad4aa0405..236adf340 100644 --- a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlSlice.cs +++ b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlSlice.cs @@ -1,6 +1,5 @@ -using System; -using System.ComponentModel.Design; -using System.Diagnostics; +using System.Collections.Generic; +using System.Linq; using System.Text; namespace ArchUnitNET.Domain.PlantUml.Export @@ -38,111 +37,99 @@ public void UseS4Style() C4Style = true; } - public string GetPlantUmlString(RenderOptions renderOptions) - { - var result = C4Style ? BuildStringC4Style() : BuildString(); + internal bool IsNested => Namespace != null; - if (Hyperlink != null) + internal bool IsC4Style => C4Style; + + internal string SliceColor => Color; + + /// + /// The outermost package this slice is nested in, which is its whole namespace. + /// + internal string RootPackage => Namespace.Remove(Namespace.Length - 1); + + /// + /// The packages this slice is nested in, outermost first. The first entry is the whole + /// namespace of the slice, the others are the segments between it and the leaf. + /// + internal IReadOnlyList PackagePath + { + get { - result.Append(" [[" + Hyperlink + "]] "); + var path = new List { RootPackage }; + var segments = _name.Remove(0, Namespace.Length).Split('.'); + path.AddRange(segments.Take(segments.Length - 1)); + return path; } - - return result.AppendLine().ToString(); } - private StringBuilder BuildString() + /// + /// The label of the component inside its innermost package, or an empty string if the + /// slice only stands for that package. + /// + internal string Leaf { - var result = new StringBuilder(); - if (Namespace != null) + get { - result.Append("package " + Namespace.Remove(Namespace.Length - 1)); var name = _name.Remove(0, Namespace.Length); - var iter = 1; - while (name.Contains(".")) - { - var dotPattern = name.IndexOf(".", StringComparison.Ordinal); - result.AppendLine(" {"); - result.Append("package " + name.Remove(dotPattern)); - name = name.Remove(0, dotPattern + 1); - iter++; - } + return name.Substring(name.LastIndexOf('.') + 1); + } + } - if (name != "") - { - result.AppendLine(" {"); - result.Append("[" + name + "] as " + _name); - if (Color != null) - { - result.AppendLine(" #" + Color); - } - else - { - result.AppendLine(); - } - } - else if (Color != null) - { - result.AppendLine(" #" + Color + " {"); - } - else - { - result.AppendLine(" {"); - } + public string GetPlantUmlString(RenderOptions renderOptions) + { + if (IsNested) + { + return new PlantUmlSliceTree(this).GetPlantUmlString(renderOptions); + } - for (var i = iter; i > 0; i--) - { - result.AppendLine("}"); - } + var result = new StringBuilder(); + if (C4Style) + { + result.Append("Container(" + _name + ", " + _name + ")"); + AppendHyperlink(result); } else { result.Append("[" + _name + "]"); + AppendHyperlink(result); if (Color != null) { result.Append(" #" + Color); } } - return result; + return result.AppendLine().ToString(); } - private StringBuilder BuildStringC4Style() + internal string GetLeafString() { var result = new StringBuilder(); - if (Namespace == null) + if (C4Style) { - result.Append("Container(" + _name + ", " + _name + ")"); - return result; + result.Append("Container(" + _name + ", " + Leaf + ")"); + AppendHyperlink(result); } - - var namespc = Namespace.Remove(Namespace.Length - 1); - result.Append("Boundary(" + namespc + ", " + namespc + ") "); - var name = _name.Remove(0, Namespace.Length); - var iter = 1; - while (name.Contains(".")) + else { - var dotPattern = name.IndexOf(".", StringComparison.Ordinal); - result.AppendLine(" {"); - result.Append( - "Boundary(" + name.Remove(dotPattern) + ", " + name.Remove(dotPattern) + ") " - ); - name = name.Remove(0, dotPattern + 1); - iter++; + result.Append("[" + Leaf + "] as " + _name); + AppendHyperlink(result); + if (Color != null) + { + result.Append(" #" + Color); + } } - result.AppendLine(" {"); - if (name != "") - { - result.Append("Container(" + _name + ", " + name + ")"); - result.AppendLine(); - } + return result.ToString(); + } - for (var i = iter; i > 0; i--) + // PlantUML only accepts a link in front of the color, not after it. + private void AppendHyperlink(StringBuilder result) + { + if (Hyperlink != null) { - result.AppendLine("}"); + result.Append(" [[" + Hyperlink + "]] "); } - - return result; } } } diff --git a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlSliceTree.cs b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlSliceTree.cs new file mode 100644 index 000000000..6c9ac6e76 --- /dev/null +++ b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlSliceTree.cs @@ -0,0 +1,132 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ArchUnitNET.Domain.PlantUml.Export +{ + /// + /// A package (or C4 boundary) that holds nested slices, rendered as a single block. + /// + /// + /// Every nested slice carries the full chain of packages it lives in. Rendering each slice on + /// its own would re-open its parent packages once per slice. PlantUML merges those re-opened + /// packages, but the source then reads nothing like a hand-written diagram. Collecting the + /// slices into a tree first opens every package exactly once. + /// + /// PlantUML identifies a package by its name, not by where it is nested, so two packages + /// called "Domain" under different parents would be drawn as one. Every package is therefore + /// labelled with its own segment but identified by its full path, which is also the name the + /// dependencies use to point at it. + /// + internal class PlantUmlSliceTree : IPlantUmlElement + { + private readonly string _name; + private readonly string _path; + private readonly bool _c4Style; + private string _color; + + // Child packages and components in the order they were first seen, so the output keeps + // the order in which the slices were added. + private readonly List _children = new List(); + + /// + /// Creates the tree for the root package of the given nested slice, holding that slice. + /// + public PlantUmlSliceTree(PlantUmlSlice slice) + : this(slice.RootPackage, slice.RootPackage, slice.IsC4Style) + { + Add(slice); + } + + private PlantUmlSliceTree(string name, string path, bool c4Style) + { + _name = name; + _path = path; + _c4Style = c4Style; + } + + /// + /// Adds a nested slice whose outermost package is the root of this tree, creating the + /// packages between the root and the slice as needed. + /// + public void Add(PlantUmlSlice slice) + { + var node = this; + foreach (var segment in slice.PackagePath.Skip(1)) + { + node = node.GetOrAddPackage(segment, slice.IsC4Style); + } + + if (slice.Leaf != "") + { + node._children.Add(slice); + } + else if (slice.SliceColor != null) + { + node._color = slice.SliceColor; + } + } + + public string GetPlantUmlString(RenderOptions renderOptions) + { + var result = new StringBuilder(); + Render(result, 0); + return result.AppendLine().ToString(); + } + + private PlantUmlSliceTree GetOrAddPackage(string name, bool c4Style) + { + var package = _children + .OfType() + .FirstOrDefault(child => child._name == name); + if (package == null) + { + package = new PlantUmlSliceTree(name, _path + "." + name, c4Style); + _children.Add(package); + } + + return package; + } + + private void Render(StringBuilder result, int depth) + { + var indent = new string(' ', 2 * depth); + var childIndent = new string(' ', 2 * (depth + 1)); + if (_c4Style) + { + result.AppendLine(indent + "Boundary(" + _path + ", " + _name + ") {"); + } + else if (_color != null) + { + result.AppendLine( + indent + "package \"" + _name + "\" as " + _path + " #" + _color + " {" + ); + } + else + { + result.AppendLine(indent + "package \"" + _name + "\" as " + _path + " {"); + } + + // PlantUML draws an empty package as a single node that shows both its label and its + // alias. A blank placeholder keeps it a regular package that only shows its label. + if (!_c4Style && _children.Count == 0) + { + result.AppendLine(childIndent + "label \" \" as " + _path + ".__empty__"); + } + + foreach (var child in _children) + { + if (child is PlantUmlSliceTree package) + { + package.Render(result, depth + 1); + } + else + { + result.AppendLine(childIndent + ((PlantUmlSlice)child).GetLeafString()); + } + } + + result.AppendLine(indent + "}"); + } + } +} diff --git a/ArchUnitNETTests/Domain/PlantUml/PlantUmlFileBuilderTest.cs b/ArchUnitNETTests/Domain/PlantUml/PlantUmlFileBuilderTest.cs index feae85002..e323e0945 100644 --- a/ArchUnitNETTests/Domain/PlantUml/PlantUmlFileBuilderTest.cs +++ b/ArchUnitNETTests/Domain/PlantUml/PlantUmlFileBuilderTest.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using ArchUnitNET.Domain; using ArchUnitNET.Domain.Extensions; using ArchUnitNET.Domain.PlantUml.Exceptions; using ArchUnitNET.Domain.PlantUml.Export; using ArchUnitNET.Fluent.Slices; using ArchUnitNET.Loader; +using VerifyXunit; using Xunit; namespace ArchUnitNETTests.Domain.PlantUml @@ -66,66 +68,16 @@ public void BuildUmlBySlicesTest() } [Fact] - public void BuildUmlByDependenciesTest() + public Task BuildUmlByDependenciesTest() { - var builder = new PlantUmlFileBuilder().WithElements(Dependencies); - var uml = builder.AsString(); - Assert.NotEmpty(uml); + return VerifyElements(Dependencies); + } - var expectedUml = - "@startuml" - + Environment.NewLine - + Environment.NewLine - + "!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml" - + Environment.NewLine - + Environment.NewLine - + "HIDE_STEREOTYPE()" - + Environment.NewLine - + Environment.NewLine - + "[a] --|> [b]" - + Environment.NewLine - + "[b] --|> [c]" - + Environment.NewLine - + "[c] --|> [a]" - + Environment.NewLine - + "@enduml" - + Environment.NewLine; - Assert.Equal(expectedUml, uml); - } - - [Fact] - public void BuildUmlByDependenciesWithObjectsWithNoDependenciesTest() + [Fact] + public Task BuildUmlByDependenciesWithObjectsWithNoDependenciesTest() { var classesWithoutDependencies = new[] { new PlantUmlClass("d") }; - var builder = new PlantUmlFileBuilder().WithElements( - Dependencies.Concat(classesWithoutDependencies) - ); - var uml = builder.AsString(); - Assert.NotEmpty(uml); - - var expectedUml = - "@startuml" - + Environment.NewLine - + Environment.NewLine - + "!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml" - + Environment.NewLine - + Environment.NewLine - + "HIDE_STEREOTYPE()" - + Environment.NewLine - + Environment.NewLine - + "class \"d\" {" - + Environment.NewLine - + "}" - + Environment.NewLine - + "[a] --|> [b]" - + Environment.NewLine - + "[b] --|> [c]" - + Environment.NewLine - + "[c] --|> [a]" - + Environment.NewLine - + "@enduml" - + Environment.NewLine; - Assert.Equal(expectedUml, uml); + return VerifyElements(Dependencies.Concat(classesWithoutDependencies)); } [Fact] @@ -136,6 +88,157 @@ public void SliceWithHyperlinkAppendsHyperlinkTest() Assert.Equal("[Slice1] [[https://example.com]] " + Environment.NewLine, uml); } + [Fact] + public void SliceWithHyperlinkAndColorPutsHyperlinkBeforeColorTest() + { + var slice = new PlantUmlSlice( + "Slice1", + color: "99ffd1", + hyperlink: "https://example.com" + ); + var uml = slice.GetPlantUmlString(new RenderOptions()); + Assert.Equal("[Slice1] [[https://example.com]] #99ffd1" + Environment.NewLine, uml); + } + + [Fact] + public Task NestedSliceWithHyperlinkTest() + { + return VerifyElements( + new[] { new PlantUmlSlice("A.B.C", "A.", hyperlink: "https://example.com") } + ); + } + + [Fact] + public Task SlicesSharingParentPackagesTest() + { + return VerifyElements( + new[] + { + new PlantUmlSlice("A.X.One", "A."), + new PlantUmlSlice("A.Y.Two", "A."), + new PlantUmlSlice("A.X.Deep.Three", "A."), + new PlantUmlSlice("B.Four", "B."), + } + ); + } + + [Fact] + public Task PackageOnlySliceWithColorTest() + { + return VerifyElements( + new[] + { + new PlantUmlSlice("A.X.One", "A."), + new PlantUmlSlice("A.X.", "A.", "99ffd1"), + } + ); + } + + [Fact] + public Task EmptyPackageTest() + { + return VerifyElements( + new[] + { + new PlantUmlSlice("A.X.One", "A."), + new PlantUmlSlice("A.Y.", "A.", "99ffd1"), + } + ); + } + + [Fact] + public Task FlatSlicesNextToNestedSlicesTest() + { + return VerifyElements( + new[] + { + new PlantUmlSlice("Flat1"), + new PlantUmlSlice("A.X", "A."), + new PlantUmlSlice("Flat2"), + new PlantUmlSlice("A.Y", "A."), + } + ); + } + + [Fact] + public Task C4StyleSlicesSharingParentBoundariesTest() + { + var one = new PlantUmlSlice("A.X.One", "A."); + var two = new PlantUmlSlice("A.X.Two", "A."); + one.UseS4Style(); + two.UseS4Style(); + return VerifyElements(new[] { one, two }); + } + + [Fact] + public Task SameNamedPackagesUnderDifferentParentsTest() + { + return VerifyElements( + new[] + { + new PlantUmlSlice("A.Orders.Domain.Model", "A."), + new PlantUmlSlice("A.Billing.Domain.Model", "A."), + } + ); + } + + [Fact] + public Task C4StyleSameNamedBoundariesUnderDifferentParentsTest() + { + var orders = new PlantUmlSlice("A.Orders.Domain.Model", "A."); + var billing = new PlantUmlSlice("A.Billing.Domain.Model", "A."); + orders.UseS4Style(); + billing.UseS4Style(); + return VerifyElements(new[] { orders, billing }); + } + + [Theory] + [InlineData(DependencyType.OneToPackage, "[A.Web] -[#red]> A.Billing.Domain")] + [InlineData(DependencyType.PackageToOne, "A.Web -[#blue]> [A.Billing.Domain]")] + [InlineData(DependencyType.PackageToPackage, "A.Web -[#green]> A.Billing.Domain")] + public void PackageArrowsTest(DependencyType dependencyType, string expected) + { + var dependency = new PlantUmlDependency("A.Web", "A.Billing.Domain", dependencyType); + Assert.Equal(expected + Environment.NewLine, dependency.GetPlantUmlString()); + } + + [Fact] + public void PackageToPackageIfSameParentNamespaceArrowTest() + { + var dependency = new PlantUmlDependency( + "A.Orders.Domain", + "A.Orders.Model", + DependencyType.PackageToPackageIfSameParentNamespace + ); + Assert.Equal( + "A.Orders.Domain ..> A.Orders.Model" + Environment.NewLine, + dependency.GetPlantUmlString() + ); + } + + [Fact] + public void OneToOneIfSameParentNamespacePackageArrowsTest() + { + var toPackage = new PlantUmlDependency( + "A.Web", + "A.Billing.Domain", + DependencyType.OneToOneIfSameParentNamespace + ); + var fromPackage = new PlantUmlDependency( + "A.Billing.Domain", + "A.Web", + DependencyType.OneToOneIfSameParentNamespace + ); + Assert.Equal( + "A.Web --> A.Billing" + Environment.NewLine, + toPackage.GetPlantUmlString() + ); + Assert.Equal( + "A.Billing -> A.Web" + Environment.NewLine, + fromPackage.GetPlantUmlString() + ); + } + [Fact] public void HandleIllegalComponentNamesTest() { @@ -160,7 +263,7 @@ public void HandleIllegalComponentNamesTest() } [Fact] - public void SpecialCharactersInComponentNamesTest() + public Task SpecialCharactersInComponentNamesTest() { var dependenciesWithSpecialCharacters = new List { @@ -172,35 +275,17 @@ public void SpecialCharactersInComponentNamesTest() { new PlantUmlClass("!§´`$%&/()=?\\\täöüß^°-*+,-.,;:<>|@€"), }; - var builder = new PlantUmlFileBuilder().WithElements( + return VerifyElements( dependenciesWithSpecialCharacters.Concat(classesWithSpecialCharacters) ); - var uml = builder.AsString(); - Assert.NotEmpty(uml); + } - var expectedUml = - "@startuml" - + Environment.NewLine - + Environment.NewLine - + "!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml" - + Environment.NewLine - + Environment.NewLine - + "HIDE_STEREOTYPE()" - + Environment.NewLine - + Environment.NewLine - + "class \"!§´`$%&/()=?\\\täöüß^°-*+,-.,;:<>|@€\" {" - + Environment.NewLine - + "}" - + Environment.NewLine - + "[!\"§´`] --|> [$%&/()=?]" - + Environment.NewLine - + "[\\\t%] --|> [äöüß]" - + Environment.NewLine - + "[^°-*+.,;:] --|> [<>|@€]" - + Environment.NewLine - + "@enduml" - + Environment.NewLine; - Assert.Equal(expectedUml, uml); + private static Task VerifyElements(IEnumerable elements) + { + return Verifier + .Verify(new PlantUmlFileBuilder().WithElements(elements).AsString()) + .DisableDiff() // Don't open diff tool during the test + .UseDirectory("Snapshots"); } } diff --git a/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs b/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs index f069b07b5..06b29fe24 100644 --- a/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs +++ b/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs @@ -182,6 +182,31 @@ public Task BuildUmlBySlicesMatchingWithPackages_DirectCircle() return VerifyUml(uml); } + // --- Packages with the same name under different parents stay apart ---------- + // + // Orders and Billing both contain a Domain package. PlantUML identifies a package by + // its name, so unless each one is identified by its full path, both Domain packages + // are drawn as one, and the arrows into Billing.Domain end in Orders.Domain. + + private const string SameNamedRoot = "SlicesTestAssembly.SameNamedSubnamespaces."; + + [Fact] + public Task BuildUmlBySlicesMatchingWithPackages_SameNamedPackages() + { + return VerifySlices( + SliceRuleDefinition.Slices().MatchingWithPackages(SameNamedRoot + "(**)") + ); + } + + [Fact] + public Task BuildUmlBySlicesMatchingWithPackages_SameNamedPackages_C4Style() + { + return VerifySlices( + SliceRuleDefinition.Slices().MatchingWithPackages(SameNamedRoot + "(**)"), + new GenerationOptions { C4Style = true } + ); + } + // --- LimitDependencies without namespaces takes the OneToOneCompact branch ---- [Fact] diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.BuildUmlByDependenciesTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.BuildUmlByDependenciesTest.verified.txt new file mode 100644 index 000000000..ce6518e6a --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.BuildUmlByDependenciesTest.verified.txt @@ -0,0 +1,10 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +[a] --|> [b] +[b] --|> [c] +[c] --|> [a] +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.BuildUmlByDependenciesWithObjectsWithNoDependenciesTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.BuildUmlByDependenciesWithObjectsWithNoDependenciesTest.verified.txt new file mode 100644 index 000000000..59d29273b --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.BuildUmlByDependenciesWithObjectsWithNoDependenciesTest.verified.txt @@ -0,0 +1,12 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +class "d" { +} +[a] --|> [b] +[b] --|> [c] +[c] --|> [a] +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.C4StyleSameNamedBoundariesUnderDifferentParentsTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.C4StyleSameNamedBoundariesUnderDifferentParentsTest.verified.txt new file mode 100644 index 000000000..8d130143a --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.C4StyleSameNamedBoundariesUnderDifferentParentsTest.verified.txt @@ -0,0 +1,20 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +Boundary(A, A) { + Boundary(A.Orders, Orders) { + Boundary(A.Orders.Domain, Domain) { + Container(A.Orders.Domain.Model, Model) + } + } + Boundary(A.Billing, Billing) { + Boundary(A.Billing.Domain, Domain) { + Container(A.Billing.Domain.Model, Model) + } + } +} + +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.C4StyleSlicesSharingParentBoundariesTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.C4StyleSlicesSharingParentBoundariesTest.verified.txt new file mode 100644 index 000000000..59dfbabe5 --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.C4StyleSlicesSharingParentBoundariesTest.verified.txt @@ -0,0 +1,14 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +Boundary(A, A) { + Boundary(A.X, X) { + Container(A.X.One, One) + Container(A.X.Two, Two) + } +} + +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.EmptyPackageTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.EmptyPackageTest.verified.txt new file mode 100644 index 000000000..8fac76fc3 --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.EmptyPackageTest.verified.txt @@ -0,0 +1,16 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +package "A" as A { + package "X" as A.X { + [One] as A.X.One + } + package "Y" as A.Y #99ffd1 { + label " " as A.Y.__empty__ + } +} + +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.FlatSlicesNextToNestedSlicesTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.FlatSlicesNextToNestedSlicesTest.verified.txt new file mode 100644 index 000000000..7eb231dab --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.FlatSlicesNextToNestedSlicesTest.verified.txt @@ -0,0 +1,14 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +[Flat1] +package "A" as A { + [X] as A.X + [Y] as A.Y +} + +[Flat2] +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.NestedSliceWithHyperlinkTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.NestedSliceWithHyperlinkTest.verified.txt new file mode 100644 index 000000000..43e4fe012 --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.NestedSliceWithHyperlinkTest.verified.txt @@ -0,0 +1,13 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +package "A" as A { + package "B" as A.B { + [C] as A.B.C [[https://example.com]] + } +} + +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.PackageOnlySliceWithColorTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.PackageOnlySliceWithColorTest.verified.txt new file mode 100644 index 000000000..5adb6e8b4 --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.PackageOnlySliceWithColorTest.verified.txt @@ -0,0 +1,13 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +package "A" as A { + package "X" as A.X #99ffd1 { + [One] as A.X.One + } +} + +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SameNamedPackagesUnderDifferentParentsTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SameNamedPackagesUnderDifferentParentsTest.verified.txt new file mode 100644 index 000000000..3657083ed --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SameNamedPackagesUnderDifferentParentsTest.verified.txt @@ -0,0 +1,20 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +package "A" as A { + package "Orders" as A.Orders { + package "Domain" as A.Orders.Domain { + [Model] as A.Orders.Domain.Model + } + } + package "Billing" as A.Billing { + package "Domain" as A.Billing.Domain { + [Model] as A.Billing.Domain.Model + } + } +} + +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SlicesSharingParentPackagesTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SlicesSharingParentPackagesTest.verified.txt new file mode 100644 index 000000000..509c8eefa --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SlicesSharingParentPackagesTest.verified.txt @@ -0,0 +1,23 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +package "A" as A { + package "X" as A.X { + [One] as A.X.One + package "Deep" as A.X.Deep { + [Three] as A.X.Deep.Three + } + } + package "Y" as A.Y { + [Two] as A.Y.Two + } +} + +package "B" as B { + [Four] as B.Four +} + +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SpecialCharactersInComponentNamesTest.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SpecialCharactersInComponentNamesTest.verified.txt new file mode 100644 index 000000000..f7a8e9730 --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlFileBuilderTest.SpecialCharactersInComponentNamesTest.verified.txt @@ -0,0 +1,12 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +class "!§´`$%&/()=?\ äöüß^°-*+,-.,;:<>|@€" { +} +[!"§´`] --|> [$%&/()=?] +[\ %] --|> [äöüß] +[^°-*+.,;:] --|> [<>|@€] +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt index bf61e1915..28668d82b 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt @@ -4,28 +4,18 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice1 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service #99ffd1 -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice2 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice1 #99ffd1 { -} +package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { + package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 #99ffd1 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service #99ffd1 + } + package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service + } + package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { + label " " as SlicesTestAssembly.MultipleSubnamespaces.Slice3.__empty__ + } } [SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -Slice3 -[#green]> Slice1 +SlicesTestAssembly.MultipleSubnamespaces.Slice3 -[#green]> SlicesTestAssembly.MultipleSubnamespaces.Slice1 @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern_SkipsSlicesWithoutFocusString.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern_SkipsSlicesWithoutFocusString.verified.txt index 01d54e434..37d98cbf3 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern_SkipsSlicesWithoutFocusString.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern_SkipsSlicesWithoutFocusString.verified.txt @@ -4,21 +4,16 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice1 { -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice2 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -[Slice3] as SlicesTestAssembly.MultipleSubnamespaces.Slice3 #99ffd1 +package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { + package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { + label " " as SlicesTestAssembly.MultipleSubnamespaces.Slice1.__empty__ + } + package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service + } + [Slice3] as SlicesTestAssembly.MultipleSubnamespaces.Slice3 #99ffd1 } [SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice3] -[SlicesTestAssembly.MultipleSubnamespaces.Slice3] -[#red]> Slice1 +[SlicesTestAssembly.MultipleSubnamespaces.Slice3] -[#red]> SlicesTestAssembly.MultipleSubnamespaces.Slice1 @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_C4Style.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_C4Style.verified.txt index cec8d4002..b042a3dba 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_C4Style.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_C4Style.verified.txt @@ -4,35 +4,24 @@ HIDE_STEREOTYPE() -Boundary(SlicesTestAssembly.MultipleSubnamespaces, SlicesTestAssembly.MultipleSubnamespaces) { -Boundary(Slice1, Slice1) { -Container(SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service, Service) -} -} - -Boundary(SlicesTestAssembly.MultipleSubnamespaces, SlicesTestAssembly.MultipleSubnamespaces) { -Boundary(Slice2, Slice2) { -Container(SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service, Service) -} -} - -Boundary(SlicesTestAssembly.MultipleSubnamespaces, SlicesTestAssembly.MultipleSubnamespaces) { -Boundary(Slice3, Slice3) { -Boundary(Group1, Group1) { -Container(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner, Inner) -} -} -} - -Boundary(SlicesTestAssembly.MultipleSubnamespaces, SlicesTestAssembly.MultipleSubnamespaces) { -Boundary(Slice3, Slice3) { -Boundary(Group2, Group2) { -Container(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner, Inner) -} -} +Boundary(SlicesTestAssembly.MultipleSubnamespaces, SlicesTestAssembly.MultipleSubnamespaces) { + Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice1, Slice1) { + Container(SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service, Service) + } + Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice2, Slice2) { + Container(SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service, Service) + } + Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3, Slice3) { + Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1, Group1) { + Container(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner, Inner) + } + Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2, Group2) { + Container(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner, Inner) + } + } } [SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> Slice3 -Slice3 -[#green]> Slice1 +[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> SlicesTestAssembly.MultipleSubnamespaces.Slice3 +SlicesTestAssembly.MultipleSubnamespaces.Slice3 -[#green]> SlicesTestAssembly.MultipleSubnamespaces.Slice1 @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DirectCircle.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DirectCircle.verified.txt index d1981eff7..1202286f3 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DirectCircle.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DirectCircle.verified.txt @@ -4,12 +4,9 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.DirectCircle { -[Slice1] as SlicesTestAssembly.DirectCircle.Slice1 -} - -package SlicesTestAssembly.DirectCircle { -[Slice2] as SlicesTestAssembly.DirectCircle.Slice2 +package "SlicesTestAssembly.DirectCircle" as SlicesTestAssembly.DirectCircle { + [Slice1] as SlicesTestAssembly.DirectCircle.Slice1 + [Slice2] as SlicesTestAssembly.DirectCircle.Slice2 } [SlicesTestAssembly.DirectCircle.Slice1] <-[#red]> [SlicesTestAssembly.DirectCircle.Slice2] diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DoubleAsterisk.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DoubleAsterisk.verified.txt index 2e17772dc..882f21891 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DoubleAsterisk.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_DoubleAsterisk.verified.txt @@ -4,35 +4,24 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice1 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice2 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -package Group1 { -[Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner -} -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -package Group2 { -[Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner -} -} +package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { + package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service + } + package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service + } + package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { + package "Group1" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 { + [Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner + } + package "Group2" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 { + [Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner + } + } } [SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> Slice3 -Slice3 -[#green]> Slice1 +[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> SlicesTestAssembly.MultipleSubnamespaces.Slice3 +SlicesTestAssembly.MultipleSubnamespaces.Slice3 -[#green]> SlicesTestAssembly.MultipleSubnamespaces.Slice1 @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_LimitDependencies.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_LimitDependencies.verified.txt index 44b61fc01..a050a9c2d 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_LimitDependencies.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_LimitDependencies.verified.txt @@ -4,35 +4,24 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice1 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice2 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -package Group1 { -[Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner -} -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -package Group2 { -[Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner -} -} +package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { + package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service + } + package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service + } + package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { + package "Group1" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 { + [Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner + } + package "Group2" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 { + [Inner] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner + } + } } -Slice1 ..> Slice2 -Slice2 ..> Slice3 -Slice3 ..> Slice1 +SlicesTestAssembly.MultipleSubnamespaces.Slice1 ..> SlicesTestAssembly.MultipleSubnamespaces.Slice2 +SlicesTestAssembly.MultipleSubnamespaces.Slice2 ..> SlicesTestAssembly.MultipleSubnamespaces.Slice3 +SlicesTestAssembly.MultipleSubnamespaces.Slice3 ..> SlicesTestAssembly.MultipleSubnamespaces.Slice1 @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_MultipleCaptureGroups.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_MultipleCaptureGroups.verified.txt index 9416d0726..58bf4a94f 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_MultipleCaptureGroups.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_MultipleCaptureGroups.verified.txt @@ -4,31 +4,20 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice1 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice2 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -[Group1] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -[Group2] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 -} +package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { + package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service + } + package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service + } + package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { + [Group1] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 + [Group2] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 + } } [SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> Slice3 -Slice3 -[#green]> Slice1 +[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> SlicesTestAssembly.MultipleSubnamespaces.Slice3 +SlicesTestAssembly.MultipleSubnamespaces.Slice3 -[#green]> SlicesTestAssembly.MultipleSubnamespaces.Slice1 @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_NonContiguousCaptureGroups.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_NonContiguousCaptureGroups.verified.txt index 9416d0726..58bf4a94f 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_NonContiguousCaptureGroups.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_NonContiguousCaptureGroups.verified.txt @@ -4,31 +4,20 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice1 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice2 { -[Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -[Group1] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 -} -} - -package SlicesTestAssembly.MultipleSubnamespaces { -package Slice3 { -[Group2] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 -} +package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { + package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service + } + package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { + [Service] as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service + } + package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { + [Group1] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 + [Group2] as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 + } } [SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> Slice3 -Slice3 -[#green]> Slice1 +[SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service] -[#red]> SlicesTestAssembly.MultipleSubnamespaces.Slice3 +SlicesTestAssembly.MultipleSubnamespaces.Slice3 -[#green]> SlicesTestAssembly.MultipleSubnamespaces.Slice1 @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SameNamedPackages.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SameNamedPackages.verified.txt new file mode 100644 index 000000000..5338f9f99 --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SameNamedPackages.verified.txt @@ -0,0 +1,23 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +package "SlicesTestAssembly.SameNamedSubnamespaces" as SlicesTestAssembly.SameNamedSubnamespaces { + package "Billing" as SlicesTestAssembly.SameNamedSubnamespaces.Billing { + package "Domain" as SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain { + [Model] as SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model + } + } + package "Orders" as SlicesTestAssembly.SameNamedSubnamespaces.Orders { + package "Domain" as SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain { + [Model] as SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain.Model + } + } + [Web] as SlicesTestAssembly.SameNamedSubnamespaces.Web +} + +[SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain.Model] --|> [SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model] +[SlicesTestAssembly.SameNamedSubnamespaces.Web] -[#red]> SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SameNamedPackages_C4Style.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SameNamedPackages_C4Style.verified.txt new file mode 100644 index 000000000..4d3dc2e23 --- /dev/null +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SameNamedPackages_C4Style.verified.txt @@ -0,0 +1,23 @@ +@startuml + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +HIDE_STEREOTYPE() + +Boundary(SlicesTestAssembly.SameNamedSubnamespaces, SlicesTestAssembly.SameNamedSubnamespaces) { + Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Billing, Billing) { + Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain, Domain) { + Container(SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model, Model) + } + } + Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Orders, Orders) { + Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain, Domain) { + Container(SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain.Model, Model) + } + } + Container(SlicesTestAssembly.SameNamedSubnamespaces.Web, Web) +} + +[SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain.Model] --|> [SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model] +[SlicesTestAssembly.SameNamedSubnamespaces.Web] -[#red]> SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain +@enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SingleAsterisk.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SingleAsterisk.verified.txt index 6e0cbf47d..63fde3d69 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SingleAsterisk.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesMatchingWithPackages_SingleAsterisk.verified.txt @@ -4,16 +4,10 @@ HIDE_STEREOTYPE() -package SlicesTestAssembly.MultipleSubnamespaces { -[Slice1] as SlicesTestAssembly.MultipleSubnamespaces.Slice1 -} - -package SlicesTestAssembly.MultipleSubnamespaces { -[Slice2] as SlicesTestAssembly.MultipleSubnamespaces.Slice2 -} - -package SlicesTestAssembly.MultipleSubnamespaces { -[Slice3] as SlicesTestAssembly.MultipleSubnamespaces.Slice3 +package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { + [Slice1] as SlicesTestAssembly.MultipleSubnamespaces.Slice1 + [Slice2] as SlicesTestAssembly.MultipleSubnamespaces.Slice2 + [Slice3] as SlicesTestAssembly.MultipleSubnamespaces.Slice3 } [SlicesTestAssembly.MultipleSubnamespaces.Slice1] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice2] diff --git a/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Billing/Domain/BillingDomainClass.cs b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Billing/Domain/BillingDomainClass.cs new file mode 100644 index 000000000..3909c30fe --- /dev/null +++ b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Billing/Domain/BillingDomainClass.cs @@ -0,0 +1,3 @@ +namespace SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain; + +public class BillingDomainClass { } diff --git a/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Billing/Domain/Model/BillingModelClass.cs b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Billing/Domain/Model/BillingModelClass.cs new file mode 100644 index 000000000..05aa00072 --- /dev/null +++ b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Billing/Domain/Model/BillingModelClass.cs @@ -0,0 +1,3 @@ +namespace SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model; + +public class BillingModelClass { } diff --git a/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Orders/Domain/Model/OrdersModelClass.cs b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Orders/Domain/Model/OrdersModelClass.cs new file mode 100644 index 000000000..538d2b0f3 --- /dev/null +++ b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Orders/Domain/Model/OrdersModelClass.cs @@ -0,0 +1,8 @@ +using SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model; + +namespace SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain.Model; + +public class OrdersModelClass +{ + public BillingModelClass Reference = null!; +} diff --git a/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Orders/Domain/OrdersDomainClass.cs b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Orders/Domain/OrdersDomainClass.cs new file mode 100644 index 000000000..3d018516f --- /dev/null +++ b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Orders/Domain/OrdersDomainClass.cs @@ -0,0 +1,8 @@ +using SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain; + +namespace SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain; + +public class OrdersDomainClass +{ + public BillingDomainClass Reference = null!; +} diff --git a/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Web/WebClass.cs b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Web/WebClass.cs new file mode 100644 index 000000000..af2e3e56a --- /dev/null +++ b/TestAssemblies/SlicesTestAssembly/SameNamedSubnamespaces/Web/WebClass.cs @@ -0,0 +1,8 @@ +using SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain; + +namespace SlicesTestAssembly.SameNamedSubnamespaces.Web; + +public class WebClass +{ + public BillingDomainClass Reference = null!; +}