From 54bb0ea92d52df1cf8597a3ff1c0565399d70c8a Mon Sep 17 00:00:00 2001 From: Alexander Linne Date: Fri, 23 Oct 2026 18:27:10 +0200 Subject: [PATCH] feat: identify and name slices by their captures, like ArchUnit A slice was identified by its name, a single string, and named after what the pattern captured with nothing to mark it as a slice. A custom SliceAssignment had no way to say what its slice consists of, and a slice name read like a namespace. Identify a slice by its parts, as ArchUnit's SliceIdentifier does: for a slice pattern, the values its capture groups captured, in group order. SliceIdentifier.Parts holds them, and equality, hash code, CompareTo and therefore the grouping in SliceAssignment.Apply compare the parts (and Ignored) alone. The matcher still captures a single value per type, so every pattern slice has one part and groups exactly as before. SliceIdentifier.Of(IEnumerable) creates a slice with several parts; Of(string) is the same slice as Of(new[] { part }). Name every slice after its parts like ArchUnit's default: "Slice " followed by the parts joined with " - ": App.(*) App.Orders Slice Orders App.(**) App.Orders.Web Slice Orders.Web Of(new[] { "Orders", "Http" }) Slice Orders - Http The prefix keeps a name from being mistaken for a namespace. It applies to every slice, including SlicedBy and custom SliceAssignments, and it is what failure messages and diagrams show, flat or nested. SliceIdentifier no longer derives from StringIdentifier: the parts are all that identifies a slice. Violation stores need a string key, which SlicesShould takes from the slice's name when it reports a violation, so a store holds what failure messages show, e.g. "Slice Orders", as ArchUnit's stores, which keep violation messages, do. Hand-built parts that contain " - " can share a name, and thus a key, with another slice: Of(new[] { "A - B" }) and Of(new[] { "A", "B" }) are different slices, both named "Slice A - B". Parts captured by a pattern never contain " - ", and ArchUnit has the same limitation. The exporter rejects two slices that would be drawn under the same name, instead of drawing them as one node. The guide's "Cycle Rule" section becomes "Slice Rules", with how slices are named and frozen, and the NotDependOnEachOther rule. Breaking changes: - Slices are named "Slice ..." from their parts, which changes every slice failure message and slice diagram label. - Frozen slice violations are stored by the slice's name, so stores written before no longer match and have to be regenerated. - New are SliceIdentifier.Parts and SliceIdentifier.Of(IEnumerable). - SliceIdentifier no longer derives from StringIdentifier, so its Identifier field is gone, and ToString() returns the slice's name. Signed-off-by: Alexander Linne --- .../Domain/PlantUml/Export/PlantUmlDiagram.cs | 15 ++- .../PlantUml/Export/PlantUmlFileBuilder.cs | 39 +++++- ArchUnitNET/Domain/SliceIdentifier.cs | 102 +++++++++++--- ArchUnitNET/Fluent/Slices/SlicesShould.cs | 6 +- .../Storage/CustomPathFrozenRules.json | 12 +- .../ArchUnitNET/Storage/FrozenRules.json | 12 +- .../ArchUnitNET/Storage/FrozenRules.xml | 12 +- .../PlantUml/PlantUmlSliceDiagramTests.cs | 54 ++++++-- ...Tests.BuildUmlBySlicesFocusOn.verified.txt | 16 +-- ..._Matching_ColorsFocusedSlices.verified.txt | 16 +-- ...FocusOn_SingleAsteriskPattern.verified.txt | 10 +- ...uildUmlBySlicesNested_C4Style.verified.txt | 30 ++--- ...cesNested_CaptureGroupAtStart.verified.txt | 8 +- ...mlBySlicesNested_DirectCircle.verified.txt | 6 +- ...BySlicesNested_DoubleAsterisk.verified.txt | 30 ++--- ...Nested_DuplicatePrefixSegment.verified.txt | 2 +- ...licesNested_LimitDependencies.verified.txt | 26 ++-- ...sNested_MultipleCaptureGroups.verified.txt | 26 ++-- ...ed_NonContiguousCaptureGroups.verified.txt | 26 ++-- ...licesNested_SameNamedPackages.verified.txt | 16 +-- ...ted_SameNamedPackages_C4Style.verified.txt | 16 +-- ...BySlicesNested_SingleAsterisk.verified.txt | 12 +- ...ests.BuildUmlBySlices_C4Style.verified.txt | 30 ++--- ...ircle_RendersCircleDependency.verified.txt | 6 +- ...ildUmlBySlices_DoubleAsterisk.verified.txt | 30 ++--- ...cludeNodesWithoutDependencies.verified.txt | 24 ++-- ...ces_LimitDependencies_Compact.verified.txt | 26 ++-- ...ySlices_MultipleCaptureGroups.verified.txt | 26 ++-- ...es_NonContiguousCaptureGroups.verified.txt | 26 ++-- ...ildUmlBySlices_SingleAsterisk.verified.txt | 12 +- ...BySlices_WithDependencyFilter.verified.txt | 28 ++-- .../Fluent/Slices/SliceDomainTests.cs | 126 +++++++++++++++++- ArchUnitNETTests/Fluent/Slices/SlicesTests.cs | 55 ++++---- ...binesEvaluationAndDescription.verified.txt | 12 +- ...binesEvaluationAndDescription.verified.txt | 12 +- ...binesEvaluationAndDescription.verified.txt | 36 ++--- ...binesEvaluationAndDescription.verified.txt | 24 ++-- ...bnamespaces_ReportsEveryCycle.verified.txt | 12 +- ...eturnsDescriptiveCycleMessage.verified.txt | 8 +- ...spaces_ReportsEveryDependency.verified.txt | 54 ++++---- ...sDescriptiveDependencyMessage.verified.txt | 12 +- documentation/docs/guide.md | 35 ++++- 42 files changed, 691 insertions(+), 395 deletions(-) diff --git a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs index 1412fd343..20ff96be9 100644 --- a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs +++ b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlDiagram.cs @@ -57,13 +57,14 @@ public string GetPlantUmlString(RenderOptions renderOptions) /// /// /// A slice is identified in the diagram by its name, but not every name is a valid id. - /// PlantUML rejects "[Inner] as App.Outer+Inner" and "Container(App.Orders.*.Http, ...)" - /// as syntax errors, and slice names can contain such characters: SlicedBy names slices - /// after type names such as "Outer+Inner" or "List`1", and a hand-built SliceIdentifier - /// can be called anything. No character that a namespace cannot contain works in their - /// place either, so the id is made from the name with those characters replaced by "_", - /// and suffixed until it clashes with no other name in the diagram. The name itself stays - /// the label, and slices whose names are valid ids keep them. + /// PlantUML rejects "[Inner] as App.Outer+Inner" and "Container(Slice Orders, ...)" as + /// syntax errors, and slice names can contain such characters: every slice description + /// starts with "Slice " and joins several parts with " - ", SlicedBy names slices after + /// type names such as "Outer+Inner" or "List`1", and a hand-built SliceIdentifier can be + /// called anything. No character that a namespace cannot contain works in their place + /// either, so the id is made from the name with those characters replaced by "_", and + /// suffixed until it clashes with no other name in the diagram. The name itself stays the + /// label, and slices whose names are valid ids keep them. /// /// A valid name can still be taken by a package: a nested slice named after its own /// namespace, such as "App.Orders", would share its id with the package "App.Orders" it diff --git a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlFileBuilder.cs b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlFileBuilder.cs index 2384d3d3d..8a2b66ac7 100644 --- a/ArchUnitNET/Domain/PlantUml/Export/PlantUmlFileBuilder.cs +++ b/ArchUnitNET/Domain/PlantUml/Export/PlantUmlFileBuilder.cs @@ -138,12 +138,14 @@ public PlantUmlFileBuilder WithDependenciesFrom( /// package of the deepest namespace that contains all of its types. With /// , only the arrows between slices whose /// types share an equally deep namespace are drawn. + /// Two slices would be drawn under the same name. public PlantUmlFileBuilder WithDependenciesFrom( IEnumerable slices, GenerationOptions generationOptions = null ) { _sliceList = slices.Distinct().ToList(); + AssertDistinctNames(); RemovePatternInappropriateSlices(); AssignCommonNamespaces(); @@ -315,7 +317,7 @@ var parent in parentNamespaces.Where(parentName => /// Only /// is read; the defaults if null. /// The package is empty, a single dot or a namespace - /// that no slice lies in. + /// that no slice lies in, or two slices would be drawn under the same name. public PlantUmlFileBuilder WithDependenciesFromFocusOn( IEnumerable slices, string package, @@ -323,6 +325,7 @@ public PlantUmlFileBuilder WithDependenciesFromFocusOn( ) { _sliceList = slices.Distinct().ToList(); + AssertDistinctNames(); switch (package) { @@ -509,6 +512,40 @@ private void ReplaceCirclesWithAppropriateDependencyType() } } + /// + /// Rejects two slices with the same name, which the diagram would draw as one node. Only + /// slices with different parts can share one, when a part contains " - ", as + /// ["A - B"] and ["A", "B"] are both named "Slice A - B". + /// + private void AssertDistinctNames() + { + var slicesByName = new Dictionary(); + foreach (var slice in _sliceList) + { + if (slicesByName.TryGetValue(slice.Description, out var other)) + { + throw new ArgumentException( + "The slices with parts " + + FormatParts(other) + + " and " + + FormatParts(slice) + + " would both be drawn as \"" + + slice.Description + + "\"." + ); + } + + slicesByName.Add(slice.Description, slice); + } + } + + private static string FormatParts(Slice slice) + { + return "[" + + string.Join(", ", slice.Identifier.Parts.Select(part => "\"" + part + "\"")) + + "]"; + } + /// /// The slices that a dependency starts or ends at, in the order of the slice list. /// diff --git a/ArchUnitNET/Domain/SliceIdentifier.cs b/ArchUnitNET/Domain/SliceIdentifier.cs index 60af37821..375e69aaf 100644 --- a/ArchUnitNET/Domain/SliceIdentifier.cs +++ b/ArchUnitNET/Domain/SliceIdentifier.cs @@ -1,40 +1,103 @@ -namespace ArchUnitNET.Domain +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ArchUnitNET.Domain { - public class SliceIdentifier : StringIdentifier, IHasDescription + /// + /// Identifies a slice by its parts: for a slice pattern, the values its capture groups + /// captured, in group order. Two identifiers are the same slice exactly when their parts are + /// equal and both are ignored or both are not. + /// + public class SliceIdentifier : IHasDescription { public static readonly SliceIdentifierComparer Comparer = new SliceIdentifierComparer(); public readonly bool Ignored; private SliceIdentifier( - string identifier, + IReadOnlyList parts, bool ignored, int? countOfAsteriskInPattern = null ) - : base(identifier) { + Parts = parts; Ignored = ignored; CountOfAsteriskInPattern = countOfAsteriskInPattern; } - public string Description => Identifier; + /// + /// What identifies the slice: for a slice pattern, the values its capture groups + /// captured, in group order. "App.(**)" over "App.Orders.Web" gives + /// [Orders.Web]. + /// + public IReadOnlyList Parts { get; } + + /// + /// The slice's name, built from its parts: "Slice " followed by the parts joined with + /// " - ", e.g. "Slice Orders - Http". It depends on the parts only, so equal slices always + /// have the same name. + /// + public string Description => "Slice " + string.Join(" - ", Parts); public readonly int? CountOfAsteriskInPattern; - public static SliceIdentifier Of(string identifier, int? countOfAsteriskInPattern = null) + /// + /// Creates an identifier for a slice with a single part, the same slice as + /// Of(new[] { part }). + /// + /// + /// The slice's only part: a custom SliceAssignment that returns identifiers with the + /// same part for two types puts them into the same slice. + /// + /// + /// The number of "(*)" groups in the pattern, if the slice comes from one. + /// + public static SliceIdentifier Of(string part, int? countOfAsteriskInPattern = null) { - return new SliceIdentifier(identifier, false, countOfAsteriskInPattern); + return new SliceIdentifier(CheckParts(new[] { part }), false, countOfAsteriskInPattern); + } + + /// + /// Creates an identifier for the slice with the given parts. Identifiers with equal parts, + /// in the same order, belong to the same slice. + /// + /// The parts, at least one; none of them may be null. + /// There are no parts, or one of them is null. + public static SliceIdentifier Of(IEnumerable parts) + { + return new SliceIdentifier(CheckParts(parts), false); } public static SliceIdentifier Ignore() { - return new SliceIdentifier("Ignored", true); + return new SliceIdentifier(new[] { "Ignored" }, true); + } + + private static IReadOnlyList CheckParts(IEnumerable parts) + { + if (parts == null) + { + throw new ArgumentNullException(nameof(parts)); + } + + var list = parts.ToList(); + if (list.Count == 0) + { + throw new ArgumentException("A slice needs at least one part.", nameof(parts)); + } + + if (list.Any(part => part == null)) + { + throw new ArgumentException("A slice part can't be null.", nameof(parts)); + } + + return list.AsReadOnly(); } /// - /// Is true when the two SliceIdentifiers belong to the same slice + /// Whether the two identifiers belong to the same slice: both ignored, or both not + /// ignored with the same parts. /// - /// - /// public bool CompareTo(SliceIdentifier other) { if (other == null) @@ -43,12 +106,12 @@ public bool CompareTo(SliceIdentifier other) } return Ignored && other.Ignored - || !Ignored && !other.Ignored && Identifier == other.Identifier; + || !Ignored && !other.Ignored && Parts.SequenceEqual(other.Parts); } private bool Equals(SliceIdentifier other) { - return Identifier == other.Identifier && Ignored == other.Ignored; + return Ignored == other.Ignored && Parts.SequenceEqual(other.Parts); } public override bool Equals(object obj) @@ -70,10 +133,19 @@ public override int GetHashCode() { unchecked { - var hashCode = 397 ^ Identifier.GetHashCode(); - hashCode = (hashCode * 397) ^ Ignored.GetHashCode(); + var hashCode = Ignored.GetHashCode(); + foreach (var part in Parts) + { + hashCode = (hashCode * 397) ^ part.GetHashCode(); + } + return hashCode; } } + + public override string ToString() + { + return Description; + } } } diff --git a/ArchUnitNET/Fluent/Slices/SlicesShould.cs b/ArchUnitNET/Fluent/Slices/SlicesShould.cs index 5e1fc1cfa..c67c60874 100644 --- a/ArchUnitNET/Fluent/Slices/SlicesShould.cs +++ b/ArchUnitNET/Fluent/Slices/SlicesShould.cs @@ -91,7 +91,7 @@ Architecture architecture } var cycleIdentifier = new EnumerableIdentifier( - cycle.Contents.Select(slice => slice.Identifier) + cycle.Contents.Select(slice => new StringIdentifier(slice.Description)) ); yield return new EvaluationResult( cycle, @@ -106,7 +106,7 @@ Architecture architecture else { var slicesIdentifier = new EnumerableIdentifier( - slicesList.Select(slice => slice.Identifier) + slicesList.Select(slice => new StringIdentifier(slice.Description)) ); yield return new EvaluationResult( slicesList, @@ -166,7 +166,7 @@ Architecture architecture yield return new EvaluationResult( slice, - slice.Identifier, + new StringIdentifier(slice.Description), passed, description, archRule, diff --git a/ArchUnitNETTests/ArchUnitNET/Storage/CustomPathFrozenRules.json b/ArchUnitNETTests/ArchUnitNET/Storage/CustomPathFrozenRules.json index 9216791d3..ceb002561 100644 --- a/ArchUnitNETTests/ArchUnitNET/Storage/CustomPathFrozenRules.json +++ b/ArchUnitNETTests/ArchUnitNET/Storage/CustomPathFrozenRules.json @@ -15,12 +15,12 @@ { "ArchRuleDescription": "Slices matching \"SlicesTestAssembly.MultipleSubnamespaces.(**)\" should not depend on each other", "Violations": [ - "Slice3", - "Slice3.Group1", - "Slice2", - "Slice2.Service", - "Slice1", - "Slice1.Service" + "Slice Slice3", + "Slice Slice3.Group1", + "Slice Slice2", + "Slice Slice2.Service", + "Slice Slice1", + "Slice Slice1.Service" ] } ] \ No newline at end of file diff --git a/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.json b/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.json index 5e4531c65..93b5d4c34 100644 --- a/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.json +++ b/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.json @@ -21,12 +21,12 @@ { "ArchRuleDescription": "Slices matching \"SlicesTestAssembly.MultipleSubnamespaces.(**)\" should not depend on each other", "Violations": [ - "Slice3", - "Slice3.Group1", - "Slice2", - "Slice2.Service", - "Slice1", - "Slice1.Service" + "Slice Slice3", + "Slice Slice3.Group1", + "Slice Slice2", + "Slice Slice2.Service", + "Slice Slice1", + "Slice Slice1.Service" ] }, { diff --git a/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.xml b/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.xml index c0905ff78..785f1107e 100644 --- a/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.xml +++ b/ArchUnitNETTests/ArchUnitNET/Storage/FrozenRules.xml @@ -12,11 +12,11 @@ ArchUnitNETTests.Fluent.FreezeTests+Violation - Slice3 - Slice3.Group1 - Slice2 - Slice2.Service - Slice1 - Slice1.Service + Slice Slice3 + Slice Slice3.Group1 + Slice Slice2 + Slice Slice2.Service + Slice Slice1 + Slice Slice1.Service \ No newline at end of file diff --git a/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs b/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs index 974e9a766..d88b9e718 100644 --- a/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs +++ b/ArchUnitNETTests/Domain/PlantUml/PlantUmlSliceDiagramTests.cs @@ -155,7 +155,8 @@ public Task BuildUmlBySlicesFocusOn_Matching_ColorsFocusedSlices() { // Slices that are not nested have no namespace, so the focused ones take // PlantUmlSlice.BuildString's namespace-less branch with a colour set, which renders - // "[Slice1] #99ffd1". The focus string is a namespace, flat or nested. + // "[Slice Slice1] as Slice_Slice1 #99ffd1". The focus string is a namespace, flat or + // nested. var slices = SortedSlices(SliceRuleDefinition.Slices().Matching(Root + "(**)")); var uml = new PlantUmlFileBuilder() .WithDependenciesFromFocusOn(slices, Root + "Slice1") @@ -374,8 +375,11 @@ public void BuildUmlBySlicesFocusOn_SiblingWithSamePrefix_IsNotFocused() .WithDependenciesFromFocusOn(slices, "SlicesTestAssembly.PrefixSiblings.Orders") .AsString(); - Assert.Contains("[Orders] #99ffd1", uml); - Assert.Contains("[OrdersArchive]" + Environment.NewLine, uml); + Assert.Contains("[Slice Orders] as Slice_Orders #99ffd1", uml); + Assert.Contains( + "[Slice OrdersArchive] as Slice_OrdersArchive" + Environment.NewLine, + uml + ); } [Fact] @@ -388,9 +392,9 @@ public void BuildUmlBySlicesFocusOn_SliceSpanningTheNamespace_IsANeighbour() .WithDependenciesFromFocusOn(slices, Root + "Slice3", Nested) .AsString(); - Assert.Contains("[Slice3] as Slice3 #99ffd1", uml); - Assert.Contains("[Services] as Services" + Environment.NewLine, uml); - Assert.Contains("[Services] --|> [Slice3]", uml); + Assert.Contains("[Slice Slice3] as Slice_Slice3 #99ffd1", uml); + Assert.Contains("[Slice Services] as Slice_Services" + Environment.NewLine, uml); + Assert.Contains("[Slice_Services] --|> [Slice_Slice3]", uml); } [Fact] @@ -406,7 +410,7 @@ public void BuildUmlBySlicesFocusOn_FocusesTheSameSlicesFlatAndNested() .AsString(); Assert.Equal(DrawnSlices(flat), DrawnSlices(nested)); - Assert.Contains("Slice3.Group1 (focused)", DrawnSlices(flat)); + Assert.Contains("Slice Slice3.Group1 (focused)", DrawnSlices(flat)); } // --- Where nested slices are drawn ----------------------------------------------- @@ -436,9 +440,9 @@ public void BuildUmlBySlicesNested_SliceSitsInItsOwnNamespace() Assert.Contains( Lines( " package \"Slice3\" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 {", - " [Slice3] as Slice3", + " [Slice Slice3] as Slice_Slice3", " package \"Group1\" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 {", - " [Slice3.Group1] as Slice3.Group1" + " [Slice Slice3.Group1] as Slice_Slice3.Group1" ), uml ); @@ -469,7 +473,7 @@ public void BuildUmlBySlicesNested_CustomSliceAssignment() Assert.Contains( Lines( "package \"SlicesTestAssembly.MultipleSubnamespaces\" as SlicesTestAssembly.MultipleSubnamespaces {", - " [Services] as Services" + " [Slice Services] as Slice_Services" ), uml ); @@ -491,7 +495,10 @@ public void BuildUmlBySlicesNested_SliceWithoutCommonNamespace_IsDrawnOnItsOwn() .ToList(); var uml = new PlantUmlFileBuilder().WithDependenciesFrom(slices, Nested).AsString(); - Assert.Contains(Environment.NewLine + "[Mixed]" + Environment.NewLine, uml); + Assert.Contains( + Environment.NewLine + "[Slice Mixed] as Slice_Mixed" + Environment.NewLine, + uml + ); } // --- One set of slices, drawn flat and nested ------------------------------------ @@ -505,9 +512,30 @@ public void BuildUmlBySlices_SameSlicesDrawnFlatAndNested() var nested = new PlantUmlFileBuilder().WithDependenciesFrom(slices, Nested).AsString(); Assert.DoesNotContain("package", flat); - Assert.Contains("[Slice1.Service]", flat); + Assert.Contains("[Slice Slice1] as Slice_Slice1", flat); Assert.Contains("package \"SlicesTestAssembly.MultipleSubnamespaces\"", nested); - Assert.Contains("[Slice1.Service] as Slice1.Service", nested); + Assert.Contains("[Slice Slice1] as Slice_Slice1", nested); + } + + // --- Two slices may not share a node ---------------------------------------------- + + [Fact] + public void BuildUmlBySlices_SameDiagramName_Throws() + { + // Different slices, both described "Slice A - B". + var slices = new[] + { + new Slice(SliceIdentifier.Of(new[] { "A - B" }), Array.Empty()), + new Slice(SliceIdentifier.Of(new[] { "A", "B" }), Array.Empty()), + }; + + var ex = Assert.Throws(() => + new PlantUmlFileBuilder().WithDependenciesFrom(slices) + ); + Assert.Equal( + "The slices with parts [\"A - B\"] and [\"A\", \"B\"] would both be drawn as \"Slice A - B\".", + ex.Message + ); } /// diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt index 86cc1d774..45e1e0c82 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn.verified.txt @@ -6,23 +6,23 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { - [Slice1] as Slice1 #99ffd1 + [Slice Slice1] as Slice_Slice1 #99ffd1 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service { - [Slice1.Service] as Slice1.Service #99ffd1 + [Slice Slice1.Service] as Slice_Slice1.Service #99ffd1 } } package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service { - [Slice2.Service] as Slice2.Service + [Slice Slice2.Service] as Slice_Slice2.Service } } package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { - [Slice3] as Slice3 + [Slice Slice3] as Slice_Slice3 } } -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice3] --|> [Slice1] +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice3] --|> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_Matching_ColorsFocusedSlices.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_Matching_ColorsFocusedSlices.verified.txt index b96ed6505..efeb37eb4 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_Matching_ColorsFocusedSlices.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_Matching_ColorsFocusedSlices.verified.txt @@ -4,12 +4,12 @@ HIDE_STEREOTYPE() -[Slice1] #99ffd1 -[Slice1.Service] #99ffd1 -[Slice2] -[Slice2.Service] -[Slice3] -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice3] --|> [Slice1] +[Slice Slice1] as Slice_Slice1 #99ffd1 +[Slice Slice1.Service] as Slice_Slice1.Service #99ffd1 +[Slice Slice2] as Slice_Slice2 +[Slice Slice2.Service] as Slice_Slice2.Service +[Slice Slice3] as Slice_Slice3 +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice3] --|> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern.verified.txt index 4f22ba744..8be4f71fe 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesFocusOn_SingleAsteriskPattern.verified.txt @@ -6,16 +6,16 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { - [Slice1] as Slice1 + [Slice Slice1] as Slice_Slice1 } package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 } package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { - [Slice3] as Slice3 #99ffd1 + [Slice Slice3] as Slice_Slice3 #99ffd1 } } -[Slice2] --|> [Slice3] -[Slice3] --|> [Slice1] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_C4Style.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_C4Style.verified.txt index 7acc06996..cfb62273f 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_C4Style.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_C4Style.verified.txt @@ -6,38 +6,38 @@ HIDE_STEREOTYPE() Boundary(SlicesTestAssembly.MultipleSubnamespaces, SlicesTestAssembly.MultipleSubnamespaces) { Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice1, Slice1) { - Container(Slice1, Slice1) + Container(Slice_Slice1, Slice Slice1) Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service, Service) { - Container(Slice1.Service, Slice1.Service) + Container(Slice_Slice1.Service, Slice Slice1.Service) } } Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice2, Slice2) { - Container(Slice2, Slice2) + Container(Slice_Slice2, Slice Slice2) Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service, Service) { - Container(Slice2.Service, Slice2.Service) + Container(Slice_Slice2.Service, Slice Slice2.Service) } } Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3, Slice3) { - Container(Slice3, Slice3) + Container(Slice_Slice3, Slice Slice3) Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1, Group1) { - Container(Slice3.Group1, Slice3.Group1) + Container(Slice_Slice3.Group1, Slice Slice3.Group1) Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner, Inner) { - Container(Slice3.Group1.Inner, Slice3.Group1.Inner) + Container(Slice_Slice3.Group1.Inner, Slice Slice3.Group1.Inner) } } Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2, Group2) { - Container(Slice3.Group2, Slice3.Group2) + Container(Slice_Slice3.Group2, Slice Slice3.Group2) Boundary(SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner, Inner) { - Container(Slice3.Group2.Inner, Slice3.Group2.Inner) + Container(Slice_Slice3.Group2.Inner, Slice Slice3.Group2.Inner) } } } } -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_CaptureGroupAtStart.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_CaptureGroupAtStart.verified.txt index eeb8ee985..21f34602b 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_CaptureGroupAtStart.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_CaptureGroupAtStart.verified.txt @@ -6,17 +6,17 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly" as SlicesTestAssembly { package "DotDotSemantics.Alpha.Service" as SlicesTestAssembly.DotDotSemantics.Alpha.Service { - [SlicesTestAssembly.DotDotSemantics.Alpha] as SlicesTestAssembly.DotDotSemantics.Alpha + [Slice SlicesTestAssembly.DotDotSemantics.Alpha] as Slice_SlicesTestAssembly.DotDotSemantics.Alpha } package "MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1.Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service { - [SlicesTestAssembly.MultipleSubnamespaces.Slice1] as SlicesTestAssembly.MultipleSubnamespaces.Slice1 + [Slice SlicesTestAssembly.MultipleSubnamespaces.Slice1] as Slice_SlicesTestAssembly.MultipleSubnamespaces.Slice1 } package "Slice2.Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service { - [SlicesTestAssembly.MultipleSubnamespaces.Slice2] as SlicesTestAssembly.MultipleSubnamespaces.Slice2 + [Slice SlicesTestAssembly.MultipleSubnamespaces.Slice2] as Slice_SlicesTestAssembly.MultipleSubnamespaces.Slice2 } } } -[SlicesTestAssembly.MultipleSubnamespaces.Slice1] --|> [SlicesTestAssembly.MultipleSubnamespaces.Slice2] +[Slice_SlicesTestAssembly.MultipleSubnamespaces.Slice1] --|> [Slice_SlicesTestAssembly.MultipleSubnamespaces.Slice2] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DirectCircle.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DirectCircle.verified.txt index 08df7321b..aa64dece2 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DirectCircle.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DirectCircle.verified.txt @@ -6,12 +6,12 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.DirectCircle" as SlicesTestAssembly.DirectCircle { package "Slice1" as SlicesTestAssembly.DirectCircle.Slice1 { - [Slice1] as Slice1 + [Slice Slice1] as Slice_Slice1 } package "Slice2" as SlicesTestAssembly.DirectCircle.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 } } -[Slice1] <-[#red]> [Slice2] +[Slice_Slice1] <-[#red]> [Slice_Slice2] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DoubleAsterisk.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DoubleAsterisk.verified.txt index da111c5a5..cabf48d2e 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DoubleAsterisk.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DoubleAsterisk.verified.txt @@ -6,38 +6,38 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { - [Slice1] as Slice1 + [Slice Slice1] as Slice_Slice1 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service { - [Slice1.Service] as Slice1.Service + [Slice Slice1.Service] as Slice_Slice1.Service } } package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service { - [Slice2.Service] as Slice2.Service + [Slice Slice2.Service] as Slice_Slice2.Service } } package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { - [Slice3] as Slice3 + [Slice Slice3] as Slice_Slice3 package "Group1" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 { - [Slice3.Group1] as Slice3.Group1 + [Slice Slice3.Group1] as Slice_Slice3.Group1 package "Inner" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner { - [Slice3.Group1.Inner] as Slice3.Group1.Inner + [Slice Slice3.Group1.Inner] as Slice_Slice3.Group1.Inner } } package "Group2" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 { - [Slice3.Group2] as Slice3.Group2 + [Slice Slice3.Group2] as Slice_Slice3.Group2 package "Inner" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner { - [Slice3.Group2.Inner] as Slice3.Group2.Inner + [Slice Slice3.Group2.Inner] as Slice_Slice3.Group2.Inner } } } } -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DuplicatePrefixSegment.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DuplicatePrefixSegment.verified.txt index 4da60c5df..9e2496e5a 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DuplicatePrefixSegment.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_DuplicatePrefixSegment.verified.txt @@ -5,7 +5,7 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.DuplicatePrefix.Sub.DuplicatePrefix.Sub" as SlicesTestAssembly.DuplicatePrefix.Sub.DuplicatePrefix.Sub { - [DuplicatePrefix.Sub] as DuplicatePrefix.Sub + [Slice DuplicatePrefix.Sub] as Slice_DuplicatePrefix.Sub } @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_LimitDependencies.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_LimitDependencies.verified.txt index 7f821f149..f0749540d 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_LimitDependencies.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_LimitDependencies.verified.txt @@ -6,36 +6,36 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { - [Slice1] as Slice1 + [Slice Slice1] as Slice_Slice1 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service { - [Slice1.Service] as Slice1.Service + [Slice Slice1.Service] as Slice_Slice1.Service } } package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service { - [Slice2.Service] as Slice2.Service + [Slice Slice2.Service] as Slice_Slice2.Service } } package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { - [Slice3] as Slice3 + [Slice Slice3] as Slice_Slice3 package "Group1" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 { - [Slice3.Group1] as Slice3.Group1 + [Slice Slice3.Group1] as Slice_Slice3.Group1 package "Inner" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Inner { - [Slice3.Group1.Inner] as Slice3.Group1.Inner + [Slice Slice3.Group1.Inner] as Slice_Slice3.Group1.Inner } } package "Group2" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 { - [Slice3.Group2] as Slice3.Group2 + [Slice Slice3.Group2] as Slice_Slice3.Group2 package "Inner" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2.Inner { - [Slice3.Group2.Inner] as Slice3.Group2.Inner + [Slice Slice3.Group2.Inner] as Slice_Slice3.Group2.Inner } } } } -[Slice1] --> [Slice2] -[Slice1.Service] --> [Slice2.Service] -[Slice2] --> [Slice3] -[Slice3] --> [Slice1] +[Slice_Slice1] --> [Slice_Slice2] +[Slice_Slice1.Service] --> [Slice_Slice2.Service] +[Slice_Slice2] --> [Slice_Slice3] +[Slice_Slice3] --> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_MultipleCaptureGroups.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_MultipleCaptureGroups.verified.txt index 0b106110b..9e1b7f74b 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_MultipleCaptureGroups.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_MultipleCaptureGroups.verified.txt @@ -6,32 +6,32 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { - [Slice1] as Slice1 + [Slice Slice1] as Slice_Slice1 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service { - [Slice1.Service] as Slice1.Service + [Slice Slice1.Service] as Slice_Slice1.Service } } package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service { - [Slice2.Service] as Slice2.Service + [Slice Slice2.Service] as Slice_Slice2.Service } } package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { - [Slice3] as Slice3 + [Slice Slice3] as Slice_Slice3 package "Group1" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 { - [Slice3.Group1] as Slice3.Group1 + [Slice Slice3.Group1] as Slice_Slice3.Group1 } package "Group2" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 { - [Slice3.Group2] as Slice3.Group2 + [Slice Slice3.Group2] as Slice_Slice3.Group2 } } } -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_NonContiguousCaptureGroups.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_NonContiguousCaptureGroups.verified.txt index 0b106110b..9e1b7f74b 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_NonContiguousCaptureGroups.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_NonContiguousCaptureGroups.verified.txt @@ -6,32 +6,32 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { - [Slice1] as Slice1 + [Slice Slice1] as Slice_Slice1 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service { - [Slice1.Service] as Slice1.Service + [Slice Slice1.Service] as Slice_Slice1.Service } } package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 package "Service" as SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service { - [Slice2.Service] as Slice2.Service + [Slice Slice2.Service] as Slice_Slice2.Service } } package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { - [Slice3] as Slice3 + [Slice Slice3] as Slice_Slice3 package "Group1" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1 { - [Slice3.Group1] as Slice3.Group1 + [Slice Slice3.Group1] as Slice_Slice3.Group1 } package "Group2" as SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group2 { - [Slice3.Group2] as Slice3.Group2 + [Slice Slice3.Group2] as Slice_Slice3.Group2 } } } -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages.verified.txt index b60093fe6..c2df74ba9 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages.verified.txt @@ -6,23 +6,23 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.SameNamedSubnamespaces" as SlicesTestAssembly.SameNamedSubnamespaces { package "Billing.Domain" as SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain { - [Billing.Domain] as Billing.Domain + [Slice Billing.Domain] as Slice_Billing.Domain package "Model" as SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model { - [Billing.Domain.Model] as Billing.Domain.Model + [Slice Billing.Domain.Model] as Slice_Billing.Domain.Model } } package "Orders.Domain" as SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain { - [Orders.Domain] as Orders.Domain + [Slice Orders.Domain] as Slice_Orders.Domain package "Model" as SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain.Model { - [Orders.Domain.Model] as Orders.Domain.Model + [Slice Orders.Domain.Model] as Slice_Orders.Domain.Model } } package "Web" as SlicesTestAssembly.SameNamedSubnamespaces.Web { - [Web] as Web + [Slice Web] as Slice_Web } } -[Orders.Domain] --|> [Billing.Domain] -[Orders.Domain.Model] --|> [Billing.Domain.Model] -[Web] --|> [Billing.Domain] +[Slice_Orders.Domain] --|> [Slice_Billing.Domain] +[Slice_Orders.Domain.Model] --|> [Slice_Billing.Domain.Model] +[Slice_Web] --|> [Slice_Billing.Domain] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages_C4Style.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages_C4Style.verified.txt index 69f5c7906..50fb55d3a 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages_C4Style.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SameNamedPackages_C4Style.verified.txt @@ -6,23 +6,23 @@ HIDE_STEREOTYPE() Boundary(SlicesTestAssembly.SameNamedSubnamespaces, SlicesTestAssembly.SameNamedSubnamespaces) { Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain, Billing.Domain) { - Container(Billing.Domain, Billing.Domain) + Container(Slice_Billing.Domain, Slice Billing.Domain) Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Billing.Domain.Model, Model) { - Container(Billing.Domain.Model, Billing.Domain.Model) + Container(Slice_Billing.Domain.Model, Slice Billing.Domain.Model) } } Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain, Orders.Domain) { - Container(Orders.Domain, Orders.Domain) + Container(Slice_Orders.Domain, Slice Orders.Domain) Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Orders.Domain.Model, Model) { - Container(Orders.Domain.Model, Orders.Domain.Model) + Container(Slice_Orders.Domain.Model, Slice Orders.Domain.Model) } } Boundary(SlicesTestAssembly.SameNamedSubnamespaces.Web, Web) { - Container(Web, Web) + Container(Slice_Web, Slice Web) } } -[Orders.Domain] --|> [Billing.Domain] -[Orders.Domain.Model] --|> [Billing.Domain.Model] -[Web] --|> [Billing.Domain] +[Slice_Orders.Domain] --|> [Slice_Billing.Domain] +[Slice_Orders.Domain.Model] --|> [Slice_Billing.Domain.Model] +[Slice_Web] --|> [Slice_Billing.Domain] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SingleAsterisk.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SingleAsterisk.verified.txt index 393c2fb54..4efb81054 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SingleAsterisk.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlicesNested_SingleAsterisk.verified.txt @@ -6,17 +6,17 @@ HIDE_STEREOTYPE() package "SlicesTestAssembly.MultipleSubnamespaces" as SlicesTestAssembly.MultipleSubnamespaces { package "Slice1" as SlicesTestAssembly.MultipleSubnamespaces.Slice1 { - [Slice1] as Slice1 + [Slice Slice1] as Slice_Slice1 } package "Slice2" as SlicesTestAssembly.MultipleSubnamespaces.Slice2 { - [Slice2] as Slice2 + [Slice Slice2] as Slice_Slice2 } package "Slice3" as SlicesTestAssembly.MultipleSubnamespaces.Slice3 { - [Slice3] as Slice3 + [Slice Slice3] as Slice_Slice3 } } -[Slice1] --|> [Slice2] -[Slice2] --|> [Slice3] -[Slice3] --|> [Slice1] +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_C4Style.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_C4Style.verified.txt index 851e24568..9b02ce5b4 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_C4Style.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_C4Style.verified.txt @@ -4,19 +4,19 @@ HIDE_STEREOTYPE() -Container(Slice1, Slice1) -Container(Slice1.Service, Slice1.Service) -Container(Slice2, Slice2) -Container(Slice2.Service, Slice2.Service) -Container(Slice3, Slice3) -Container(Slice3.Group1, Slice3.Group1) -Container(Slice3.Group1.Inner, Slice3.Group1.Inner) -Container(Slice3.Group2, Slice3.Group2) -Container(Slice3.Group2.Inner, Slice3.Group2.Inner) -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +Container(Slice_Slice1, Slice Slice1) +Container(Slice_Slice1.Service, Slice Slice1.Service) +Container(Slice_Slice2, Slice Slice2) +Container(Slice_Slice2.Service, Slice Slice2.Service) +Container(Slice_Slice3, Slice Slice3) +Container(Slice_Slice3.Group1, Slice Slice3.Group1) +Container(Slice_Slice3.Group1.Inner, Slice Slice3.Group1.Inner) +Container(Slice_Slice3.Group2, Slice Slice3.Group2) +Container(Slice_Slice3.Group2.Inner, Slice Slice3.Group2.Inner) +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DirectCircle_RendersCircleDependency.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DirectCircle_RendersCircleDependency.verified.txt index ffc596323..846b74ca6 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DirectCircle_RendersCircleDependency.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DirectCircle_RendersCircleDependency.verified.txt @@ -4,7 +4,7 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice2] -[Slice1] <-[#red]> [Slice2] +[Slice Slice1] as Slice_Slice1 +[Slice Slice2] as Slice_Slice2 +[Slice_Slice1] <-[#red]> [Slice_Slice2] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DoubleAsterisk.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DoubleAsterisk.verified.txt index b33b9dcab..92de1e097 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DoubleAsterisk.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_DoubleAsterisk.verified.txt @@ -4,19 +4,19 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice1.Service] -[Slice2] -[Slice2.Service] -[Slice3] -[Slice3.Group1] -[Slice3.Group1.Inner] -[Slice3.Group2] -[Slice3.Group2.Inner] -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice Slice1] as Slice_Slice1 +[Slice Slice1.Service] as Slice_Slice1.Service +[Slice Slice2] as Slice_Slice2 +[Slice Slice2.Service] as Slice_Slice2.Service +[Slice Slice3] as Slice_Slice3 +[Slice Slice3.Group1] as Slice_Slice3.Group1 +[Slice Slice3.Group1.Inner] as Slice_Slice3.Group1.Inner +[Slice Slice3.Group2] as Slice_Slice3.Group2 +[Slice Slice3.Group2.Inner] as Slice_Slice3.Group2.Inner +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_ExcludeNodesWithoutDependencies.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_ExcludeNodesWithoutDependencies.verified.txt index c5667533f..5baf30abd 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_ExcludeNodesWithoutDependencies.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_ExcludeNodesWithoutDependencies.verified.txt @@ -4,16 +4,16 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice1.Service] -[Slice2] -[Slice2.Service] -[Slice3] -[Slice3.Group1] -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice Slice1] as Slice_Slice1 +[Slice Slice1.Service] as Slice_Slice1.Service +[Slice Slice2] as Slice_Slice2 +[Slice Slice2.Service] as Slice_Slice2.Service +[Slice Slice3] as Slice_Slice3 +[Slice Slice3.Group1] as Slice_Slice3.Group1 +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_LimitDependencies_Compact.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_LimitDependencies_Compact.verified.txt index 991ec5378..4d06a235e 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_LimitDependencies_Compact.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_LimitDependencies_Compact.verified.txt @@ -4,17 +4,17 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice1.Service] -[Slice2] -[Slice2.Service] -[Slice3] -[Slice3.Group1] -[Slice3.Group1.Inner] -[Slice3.Group2] -[Slice3.Group2.Inner] -[Slice1] --> [Slice2] -[Slice1.Service] --> [Slice2.Service] -[Slice2] --> [Slice3] -[Slice3] --> [Slice1] +[Slice Slice1] as Slice_Slice1 +[Slice Slice1.Service] as Slice_Slice1.Service +[Slice Slice2] as Slice_Slice2 +[Slice Slice2.Service] as Slice_Slice2.Service +[Slice Slice3] as Slice_Slice3 +[Slice Slice3.Group1] as Slice_Slice3.Group1 +[Slice Slice3.Group1.Inner] as Slice_Slice3.Group1.Inner +[Slice Slice3.Group2] as Slice_Slice3.Group2 +[Slice Slice3.Group2.Inner] as Slice_Slice3.Group2.Inner +[Slice_Slice1] --> [Slice_Slice2] +[Slice_Slice1.Service] --> [Slice_Slice2.Service] +[Slice_Slice2] --> [Slice_Slice3] +[Slice_Slice3] --> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_MultipleCaptureGroups.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_MultipleCaptureGroups.verified.txt index 041ebd608..8e5c21f27 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_MultipleCaptureGroups.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_MultipleCaptureGroups.verified.txt @@ -4,17 +4,17 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice1.Service] -[Slice2] -[Slice2.Service] -[Slice3] -[Slice3.Group1] -[Slice3.Group2] -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice Slice1] as Slice_Slice1 +[Slice Slice1.Service] as Slice_Slice1.Service +[Slice Slice2] as Slice_Slice2 +[Slice Slice2.Service] as Slice_Slice2.Service +[Slice Slice3] as Slice_Slice3 +[Slice Slice3.Group1] as Slice_Slice3.Group1 +[Slice Slice3.Group2] as Slice_Slice3.Group2 +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_NonContiguousCaptureGroups.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_NonContiguousCaptureGroups.verified.txt index 041ebd608..8e5c21f27 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_NonContiguousCaptureGroups.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_NonContiguousCaptureGroups.verified.txt @@ -4,17 +4,17 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice1.Service] -[Slice2] -[Slice2.Service] -[Slice3] -[Slice3.Group1] -[Slice3.Group2] -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] -[Slice3.Group1] --|> [Slice3] +[Slice Slice1] as Slice_Slice1 +[Slice Slice1.Service] as Slice_Slice1.Service +[Slice Slice2] as Slice_Slice2 +[Slice Slice2.Service] as Slice_Slice2.Service +[Slice Slice3] as Slice_Slice3 +[Slice Slice3.Group1] as Slice_Slice3.Group1 +[Slice Slice3.Group2] as Slice_Slice3.Group2 +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] +[Slice_Slice3.Group1] --|> [Slice_Slice3] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_SingleAsterisk.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_SingleAsterisk.verified.txt index c37caedd7..a4f69a9d3 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_SingleAsterisk.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_SingleAsterisk.verified.txt @@ -4,10 +4,10 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice2] -[Slice3] -[Slice1] --|> [Slice2] -[Slice2] --|> [Slice3] -[Slice3] --|> [Slice1] +[Slice Slice1] as Slice_Slice1 +[Slice Slice2] as Slice_Slice2 +[Slice Slice3] as Slice_Slice3 +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_WithDependencyFilter.verified.txt b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_WithDependencyFilter.verified.txt index 969b504e8..61a2c05ad 100644 --- a/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_WithDependencyFilter.verified.txt +++ b/ArchUnitNETTests/Domain/PlantUml/Snapshots/PlantUmlSliceDiagramTests.BuildUmlBySlices_WithDependencyFilter.verified.txt @@ -4,18 +4,18 @@ HIDE_STEREOTYPE() -[Slice1] -[Slice1.Service] -[Slice2] -[Slice2.Service] -[Slice3] -[Slice3.Group1] -[Slice3.Group1.Inner] -[Slice3.Group2] -[Slice3.Group2.Inner] -[Slice1] --|> [Slice2] -[Slice1.Service] --|> [Slice2.Service] -[Slice2] --|> [Slice3] -[Slice2.Service] --|> [Slice3] -[Slice3] --|> [Slice1] +[Slice Slice1] as Slice_Slice1 +[Slice Slice1.Service] as Slice_Slice1.Service +[Slice Slice2] as Slice_Slice2 +[Slice Slice2.Service] as Slice_Slice2.Service +[Slice Slice3] as Slice_Slice3 +[Slice Slice3.Group1] as Slice_Slice3.Group1 +[Slice Slice3.Group1.Inner] as Slice_Slice3.Group1.Inner +[Slice Slice3.Group2] as Slice_Slice3.Group2 +[Slice Slice3.Group2.Inner] as Slice_Slice3.Group2.Inner +[Slice_Slice1] --|> [Slice_Slice2] +[Slice_Slice1.Service] --|> [Slice_Slice2.Service] +[Slice_Slice2] --|> [Slice_Slice3] +[Slice_Slice2.Service] --|> [Slice_Slice3] +[Slice_Slice3] --|> [Slice_Slice1] @enduml diff --git a/ArchUnitNETTests/Fluent/Slices/SliceDomainTests.cs b/ArchUnitNETTests/Fluent/Slices/SliceDomainTests.cs index bf2866ab8..d7ae5f03c 100644 --- a/ArchUnitNETTests/Fluent/Slices/SliceDomainTests.cs +++ b/ArchUnitNETTests/Fluent/Slices/SliceDomainTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using ArchUnitNET.Domain; using ArchUnitNET.Domain.Extensions; @@ -65,7 +65,7 @@ public void Slice_ToString_ReturnsDescription() { var slice = new Slice(SliceIdentifier.Of("SomeSlice"), Array.Empty()); - Assert.Equal("SomeSlice", slice.ToString()); + Assert.Equal("Slice SomeSlice", slice.ToString()); Assert.Equal(slice.Description, slice.ToString()); } @@ -104,6 +104,14 @@ public void SliceIdentifier_CompareTo_Null_ReturnsFalse() Assert.False(SliceIdentifier.Of("A").CompareTo(null)); } + [Fact] + public void SliceIdentifier_CompareTo_OneIgnored_ReturnsFalse() + { + // Same parts, so only the Ignored flag tells the two apart. + Assert.False(SliceIdentifier.Of("Ignored").CompareTo(SliceIdentifier.Ignore())); + Assert.False(SliceIdentifier.Ignore().CompareTo(SliceIdentifier.Of("Ignored"))); + } + [Fact] public void SliceIdentifier_Equals_Branches() { @@ -116,6 +124,120 @@ public void SliceIdentifier_Equals_Branches() Assert.False(identifier.Equals(SliceIdentifier.Of("B"))); } + [Fact] + public void SliceIdentifier_Equals_ComparesParts() + { + var identifier = SliceIdentifier.Of(new[] { "A", "B" }); + + Assert.Equal(SliceIdentifier.Of(new[] { "A", "B" }), identifier); + Assert.Equal( + SliceIdentifier.Of(new[] { "A", "B" }).GetHashCode(), + identifier.GetHashCode() + ); + Assert.NotEqual(SliceIdentifier.Of(new[] { "B", "A" }), identifier); + Assert.NotEqual(SliceIdentifier.Of("A.B"), identifier); + Assert.NotEqual(SliceIdentifier.Of(new[] { "A", "B", "C" }), identifier); + } + + [Fact] + public void SliceIdentifier_OfString_IsASingleSlicePart() + { + var ofString = SliceIdentifier.Of("Orders"); + var ofParts = SliceIdentifier.Of(new[] { "Orders" }); + + Assert.Equal(new[] { "Orders" }, ofString.Parts); + Assert.Equal(ofParts, ofString); + Assert.Equal("Slice Orders", ofString.Description); + Assert.Equal("Slice Orders", ofParts.Description); + } + + [Fact] + public void SliceIdentifier_Description_PrefixesTheJoinedParts() + { + Assert.Equal("Slice Orders.Web", SliceIdentifier.Of("Orders.Web").Description); + Assert.Equal( + "Slice Orders - Http", + SliceIdentifier.Of(new[] { "Orders", "Http" }).Description + ); + } + + [Fact] + public void SliceIdentifier_Of_RejectsMissingParts() + { + Assert.Throws(() => + SliceIdentifier.Of((System.Collections.Generic.IEnumerable)null) + ); + Assert.Throws(() => SliceIdentifier.Of(new string[0])); + Assert.Throws(() => SliceIdentifier.Of(new[] { "A", null })); + } + + [Fact] + public void SliceIdentifier_PartsContainingTheSeparator_AreADifferentSlice() + { + // Both are described "Slice A - B", but they are different slices. + var onePart = SliceIdentifier.Of(new[] { "A - B" }); + var twoParts = SliceIdentifier.Of(new[] { "A", "B" }); + + Assert.Equal(onePart.Description, twoParts.Description); + Assert.NotEqual(onePart, twoParts); + Assert.False(SliceIdentifier.Comparer.Equals(onePart, twoParts)); + } + + [Fact] + public void SliceIdentifier_ToString_IsTheDescription() + { + Assert.Equal("Slice Orders", SliceIdentifier.Of("Orders").ToString()); + } + + // --- Violation keys, which violation stores keep --------------------------------- + + [Fact] + public void ViolationKey_IsTheDescription() + { + var keys = SliceRuleDefinition + .Slices() + .Matching(Root + "(*)") + .Should() + .NotDependOnEachOther() + .Evaluate(Architecture) + .Select(result => result.EvaluatedObjectIdentifier.Identifier); + + Assert.Contains("Slice Slice1", keys); + } + + [Fact] + public void ViolationKey_OfSeveralParts_IsTheDescription() + { + // Patterns capture a single part, so a custom assignment builds several. + var creator = new SliceRuleCreator(); + creator.SetSliceAssignment( + new SliceAssignment( + type => SliceIdentifier.Of(new[] { "Custom", type.Name }), + "by name" + ) + ); + + var keys = new SlicesShould(creator) + .NotDependOnEachOther() + .Evaluate(Architecture) + .Select(result => result.EvaluatedObjectIdentifier.Identifier); + + Assert.Contains("Slice Custom - Slice1Class", keys); + } + + // --- SlicedBy ------------------------------------------------------------------ + + [Fact] + public void SlicedBy_NamesSlicesAfterTheTypeLikeEveryOtherSlice() + { + var type = Architecture.GetClassOfType(typeof(MixedTypesClass)); + + var slice = Assert.Single(new IType[] { type }.SlicedBy("")); + + Assert.Equal(new[] { type.FullName }, slice.Identifier.Parts); + Assert.Equal("Slice " + type.FullName, slice.Description); + } + [Fact] public void SliceIdentifierComparer_Equals_NullFirstArgument_ReturnsFalse() { diff --git a/ArchUnitNETTests/Fluent/Slices/SlicesTests.cs b/ArchUnitNETTests/Fluent/Slices/SlicesTests.cs index 232cb4a2b..67290d3ba 100644 --- a/ArchUnitNETTests/Fluent/Slices/SlicesTests.cs +++ b/ArchUnitNETTests/Fluent/Slices/SlicesTests.cs @@ -176,15 +176,15 @@ public void Matching_SingleAsterisk_CapturesEveryDepth() Assert.Equal( new[] { - "Slice1", - "Slice1.Service", - "Slice2", - "Slice2.Service", - "Slice3", - "Slice3.Group1", - "Slice3.Group1.Inner", - "Slice3.Group2", - "Slice3.Group2.Inner", + "Slice Slice1", + "Slice Slice1.Service", + "Slice Slice2", + "Slice Slice2.Service", + "Slice Slice3", + "Slice Slice3.Group1", + "Slice Slice3.Group1.Inner", + "Slice Slice3.Group2", + "Slice Slice3.Group2.Inner", }, Descriptions(Root + "(*)") ); @@ -199,7 +199,10 @@ public void Matching_SingleAsteriskDotDot_CapturesEveryDepth() [Fact] public void Matching_DoubleAsteriskDotDot_FoldsSubnamespacesIntoParent() { - Assert.Equal(new[] { "Slice1", "Slice2", "Slice3" }, Descriptions(Root + "(**)..")); + Assert.Equal( + new[] { "Slice Slice1", "Slice Slice2", "Slice Slice3" }, + Descriptions(Root + "(**)..") + ); } /// @@ -227,8 +230,8 @@ public void Matching_DoubleAsteriskDotDot_DropsTypesDirectlyInCapturedNamespace( .ToArray() ); - Assert.Equal(new[] { Root + "Slice1.Service.Service1Class" }, types["Slice1"]); - Assert.Equal(new[] { Root + "Slice2.Service.Service2Class" }, types["Slice2"]); + Assert.Equal(new[] { Root + "Slice1.Service.Service1Class" }, types["Slice Slice1"]); + Assert.Equal(new[] { Root + "Slice2.Service.Service2Class" }, types["Slice Slice2"]); Assert.Equal( new[] { @@ -237,7 +240,7 @@ public void Matching_DoubleAsteriskDotDot_DropsTypesDirectlyInCapturedNamespace( Root + "Slice3.Group2.Group2Class", Root + "Slice3.Group2.Inner.Inner2Class", }, - types["Slice3"] + types["Slice Slice3"] ); } @@ -276,7 +279,7 @@ public void DuplicatePrefixSegment_CapturesAfterTheFirstOccurrenceOfThePrefix() .ToList(); Assert.Single(slices); - Assert.Equal("DuplicatePrefix.Sub", slices[0].Description); + Assert.Equal("Slice DuplicatePrefix.Sub", slices[0].Description); } // --- ".." semantics ------------------------------------------------------------- @@ -287,11 +290,11 @@ public void DotDot_BetweenCaptureGroups_CapturesEveryDepth() Assert.Equal( new[] { - "Alpha.Service", - "AlphaService", - "Outer.Inner", - "Outer.Mid.Inner", - "Single", + "Slice Alpha.Service", + "Slice AlphaService", + "Slice Outer.Inner", + "Slice Outer.Mid.Inner", + "Slice Single", }, Descriptions(DotDot + "(*)..(*)") ); @@ -303,11 +306,11 @@ public void DotDot_BeforeLiteral_CapturesEveryDepth() Assert.Equal( new[] { - "Alpha.Service", - "AlphaService", - "Outer.Inner", - "Outer.Mid.Inner", - "Single", + "Slice Alpha.Service", + "Slice AlphaService", + "Slice Outer.Inner", + "Slice Outer.Mid.Inner", + "Slice Single", }, Descriptions(DotDot + "(*)..Service") ); @@ -328,8 +331,8 @@ public void DotDot_BeforeLiteral_GivesAlphaServiceAndAlphaDotServiceDistinctSlic // holding exactly the one type it's made of. This is not evidence the matcher tells // the two shapes apart -- it would look identical if it ignored segment boundaries // entirely. - Assert.Single(slices.Single(slice => slice.Description == "AlphaService").Types); - Assert.Single(slices.Single(slice => slice.Description == "Alpha.Service").Types); + Assert.Single(slices.Single(slice => slice.Description == "Slice AlphaService").Types); + Assert.Single(slices.Single(slice => slice.Description == "Slice Alpha.Service").Types); } // --- failure messages ----------------------------------------------------------- diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_FluentDefinition_CombinesEvaluationAndDescription.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_FluentDefinition_CombinesEvaluationAndDescription.verified.txt index 15d5cc49f..7c6f6bb58 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_FluentDefinition_CombinesEvaluationAndDescription.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_FluentDefinition_CombinesEvaluationAndDescription.verified.txt @@ -21,11 +21,11 @@ All Evaluations passed Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles and Types that have full name "SlicesTestAssembly.DotDotSemantics.Outer.Mid.Inner.MidInnerClass" should exist Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Result: True @@ -33,11 +33,11 @@ Description: SlicesTestAssembly.DotDotSemantics.Outer.Mid.Inner.MidInnerClass pa Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_WithArchRule_CombinesEvaluationAndDescription.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_WithArchRule_CombinesEvaluationAndDescription.verified.txt index c22e38343..f13e66cbd 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_WithArchRule_CombinesEvaluationAndDescription.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.And_WithArchRule_CombinesEvaluationAndDescription.verified.txt @@ -26,11 +26,11 @@ Message: Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles and Types that have name "NotTheNameOfAnyObject" should exist Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Result: False @@ -38,11 +38,11 @@ Description: There are no objects matching the criteria Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_FluentDefinition_CombinesEvaluationAndDescription.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_FluentDefinition_CombinesEvaluationAndDescription.verified.txt index 14faa3188..acbf6584a 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_FluentDefinition_CombinesEvaluationAndDescription.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_FluentDefinition_CombinesEvaluationAndDescription.verified.txt @@ -3,21 +3,21 @@ Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class @@ -28,11 +28,11 @@ Slice3 -> Slice1 Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles or Types that have full name "SlicesTestAssembly.DotDotSemantics.Outer.Mid.Inner.MidInnerClass" should exist Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Result: True @@ -40,11 +40,11 @@ Description: SlicesTestAssembly.DotDotSemantics.Outer.Mid.Inner.MidInnerClass pa Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class @@ -55,11 +55,11 @@ Slice3 -> Slice1 Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles or Types that have name "NotTheNameOfAnyObject" should exist Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Result: False @@ -67,11 +67,11 @@ Description: There are no objects matching the criteria Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_WithArchRule_CombinesEvaluationAndDescription.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_WithArchRule_CombinesEvaluationAndDescription.verified.txt index 42340d70c..c2a19f195 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_WithArchRule_CombinesEvaluationAndDescription.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SliceRuleCombinationTests.Or_WithArchRule_CombinesEvaluationAndDescription.verified.txt @@ -3,11 +3,11 @@ Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles or Types that have full name "SlicesTestAssembly.DotDotSemantics.Outer.Mid.Inner.MidInnerClass" should exist Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Result: True @@ -15,11 +15,11 @@ Description: SlicesTestAssembly.DotDotSemantics.Outer.Mid.Inner.MidInnerClass pa Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class @@ -30,11 +30,11 @@ Slice3 -> Slice1 Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles or Types that have name "NotTheNameOfAnyObject" should exist Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Result: False @@ -42,11 +42,11 @@ Description: There are no objects matching the criteria Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_MultipleSubnamespaces_ReportsEveryCycle.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_MultipleSubnamespaces_ReportsEveryCycle.verified.txt index b15623362..88b409548 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_MultipleSubnamespaces_ReportsEveryCycle.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_MultipleSubnamespaces_ReportsEveryCycle.verified.txt @@ -1,21 +1,21 @@ Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles Result: False Description: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should be free of cycles" failed: Cycle found: -Slice2 -> Slice3 +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -Slice3 -> Slice1 +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_WithCycle_ReturnsDescriptiveCycleMessage.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_WithCycle_ReturnsDescriptiveCycleMessage.verified.txt index 03a2b704c..0bb65e78b 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_WithCycle_ReturnsDescriptiveCycleMessage.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.BeFreeOfCycles_WithCycle_ReturnsDescriptiveCycleMessage.verified.txt @@ -1,17 +1,17 @@ Query: Slices matching "SlicesTestAssembly.DirectCircle.(*)" should be free of cycles Result: False Description: Cycle found: -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.DirectCircle.Slice1.Slice1Class -> SlicesTestAssembly.DirectCircle.Slice2.Slice2Class -Slice2 -> Slice1 +Slice Slice2 -> Slice Slice1 SlicesTestAssembly.DirectCircle.Slice2.Slice2Class -> SlicesTestAssembly.DirectCircle.Slice1.Slice1Class Message: "Slices matching "SlicesTestAssembly.DirectCircle.(*)" should be free of cycles" failed: Cycle found: -Slice1 -> Slice2 +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.DirectCircle.Slice1.Slice1Class -> SlicesTestAssembly.DirectCircle.Slice2.Slice2Class -Slice2 -> Slice1 +Slice Slice2 -> Slice Slice1 SlicesTestAssembly.DirectCircle.Slice2.Slice2Class -> SlicesTestAssembly.DirectCircle.Slice1.Slice1Class diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_MultipleSubnamespaces_ReportsEveryDependency.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_MultipleSubnamespaces_ReportsEveryDependency.verified.txt index 0a801d01b..d17bbc960 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_MultipleSubnamespaces_ReportsEveryDependency.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_MultipleSubnamespaces_ReportsEveryDependency.verified.txt @@ -1,64 +1,64 @@ Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should not depend on each other Result: False -Description: Slice1 does depend on other slices: -Slice1 -> Slice2 +Description: Slice Slice1 does depend on other slices: +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class Result: False -Description: Slice1.Service does depend on other slices: -Slice1.Service -> Slice2.Service +Description: Slice Slice1.Service does depend on other slices: +Slice Slice1.Service -> Slice Slice2.Service SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service.Service1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service.Service2Class Result: False -Description: Slice2 does depend on other slices: -Slice2 -> Slice3 +Description: Slice Slice2 does depend on other slices: +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class Result: False -Description: Slice2.Service does depend on other slices: -Slice2.Service -> Slice3 +Description: Slice Slice2.Service does depend on other slices: +Slice Slice2.Service -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service.Service2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class Result: False -Description: Slice3 does depend on other slices: -Slice3 -> Slice1 +Description: Slice Slice3 does depend on other slices: +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class Result: False -Description: Slice3.Group1 does depend on other slices: -Slice3.Group1 -> Slice3 +Description: Slice Slice3.Group1 does depend on other slices: +Slice Slice3.Group1 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Group1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class Result: True -Description: Slice3.Group1.Inner does not depend on another slice. +Description: Slice Slice3.Group1.Inner does not depend on another slice. Result: True -Description: Slice3.Group2 does not depend on another slice. +Description: Slice Slice3.Group2 does not depend on another slice. Result: True -Description: Slice3.Group2.Inner does not depend on another slice. +Description: Slice Slice3.Group2.Inner does not depend on another slice. Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**)" should not depend on each other" failed: - Slice1 does depend on other slices: -Slice1 -> Slice2 + Slice Slice1 does depend on other slices: +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class - Slice1.Service does depend on other slices: -Slice1.Service -> Slice2.Service + Slice Slice1.Service does depend on other slices: +Slice Slice1.Service -> Slice Slice2.Service SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service.Service1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service.Service2Class - Slice2 does depend on other slices: -Slice2 -> Slice3 + Slice Slice2 does depend on other slices: +Slice Slice2 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Slice2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class - Slice2.Service does depend on other slices: -Slice2.Service -> Slice3 + Slice Slice2.Service does depend on other slices: +Slice Slice2.Service -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service.Service2Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class - Slice3 does depend on other slices: -Slice3 -> Slice1 + Slice Slice3 does depend on other slices: +Slice Slice3 -> Slice Slice1 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice1.Slice1Class - Slice3.Group1 does depend on other slices: -Slice3.Group1 -> Slice3 + Slice Slice3.Group1 does depend on other slices: +Slice Slice3.Group1 -> Slice Slice3 SlicesTestAssembly.MultipleSubnamespaces.Slice3.Group1.Group1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice3.Slice3Class diff --git a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_ReturnsDescriptiveDependencyMessage.verified.txt b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_ReturnsDescriptiveDependencyMessage.verified.txt index 448e70e4b..56687bc1e 100644 --- a/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_ReturnsDescriptiveDependencyMessage.verified.txt +++ b/ArchUnitNETTests/Fluent/Slices/Snapshots/SlicesTests.NotDependOnEachOther_ReturnsDescriptiveDependencyMessage.verified.txt @@ -1,17 +1,17 @@ Query: Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**).." should not depend on each other Result: False -Description: Slice1 does depend on other slices: -Slice1 -> Slice2 +Description: Slice Slice1 does depend on other slices: +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service.Service1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service.Service2Class Result: True -Description: Slice2 does not depend on another slice. +Description: Slice Slice2 does not depend on another slice. Result: True -Description: Slice3 does not depend on another slice. +Description: Slice Slice3 does not depend on another slice. Message: "Slices matching "SlicesTestAssembly.MultipleSubnamespaces.(**).." should not depend on each other" failed: - Slice1 does depend on other slices: -Slice1 -> Slice2 + Slice Slice1 does depend on other slices: +Slice Slice1 -> Slice Slice2 SlicesTestAssembly.MultipleSubnamespaces.Slice1.Service.Service1Class -> SlicesTestAssembly.MultipleSubnamespaces.Slice2.Service.Service2Class diff --git a/documentation/docs/guide.md b/documentation/docs/guide.md index ed193526d..1d3df4d90 100644 --- a/documentation/docs/guide.md +++ b/documentation/docs/guide.md @@ -174,13 +174,46 @@ IArchRule rule = Classes().That().DoNotHaveAnyAttributes(typeof(Display)).Should .NotDependOnAny(Classes().That().AreAssignableTo(typeof(ICanvas))); ``` -### 3.6. Cycle Rule +### 3.6. Slice Rules +Slices group types by namespace. A *slice* is the set of types whose namespaces produced the same +captured values from a pattern -- with `"App.(*)"`, the types in `App.Orders` form one slice, those in +`App.Shipping` another. + +To use the `Slices()` entry point directly, add: +```cs +using static ArchUnitNET.Fluent.Slices.SliceRuleDefinition; +``` + +#### How slices are named +A slice is identified by **what its capture groups captured**, in group order. Two types end up in +the same slice exactly when their groups captured the same values. + +A slice is named after its captures: `Slice ` followed by the captured values joined with ` - `. The +name never reads as a namespace, and it is what failure messages and diagrams show. + +| Pattern | Namespace | Slice name | +|---|---|---| +| `App.(*)` | `App.Orders` | `Slice Orders` | +| `App.(**)` | `App.Orders.Web` | `Slice Orders.Web` | + +Frozen violations of a slice rule (see `FreezingArchRule`) are stored by the slice name, e.g. +`Slice Orders`. + +#### Cycle-free rule ![Cycle](img/cycle.svg) ```cs IArchRule rule = Slices().Matching("Module.(*)").Should() .BeFreeOfCycles(); ``` +#### No-dependency rule +```cs +IArchRule rule = Slices().Matching("Module.(*)").Should() + .NotDependOnEachOther(); +``` +`NotDependOnEachOther` forbids *any* dependency between slices, where `BeFreeOfCycles` only forbids +circular ones. + ## 4. How to check To get a meaningful error message we recommend using