Skip to content

Add SliceRules #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Aug 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions ArchUnitNET/Domain/TypeDependencyComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 Florian Gather <florian.gather@tngtech.com>
// Copyright 2019 Paula Ruiz <paularuiz22@gmail.com>
// Copyright 2019 Fritz Brandhuber <fritz.brandhuber@tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
//

using System.Collections.Generic;
using ArchUnitNET.Domain.Dependencies.Types;

namespace ArchUnitNET.Domain
{
public class TypeDependencyComparer : IEqualityComparer<ITypeDependency>
{
public bool Equals(ITypeDependency x, ITypeDependency y)
{
if (ReferenceEquals(x, y))
{
return true;
}

return x != null && y != null && Equals(x.Origin, y.Origin) && Equals(x.Target, y.Target);
}

public int GetHashCode(ITypeDependency obj)
{
unchecked
{
return (obj.Origin.GetHashCode() * 397) ^ obj.Target.GetHashCode();
}
}
}
}
8 changes: 4 additions & 4 deletions ArchUnitNET/Fluent/EvaluationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

namespace ArchUnitNET.Fluent
{
public class EvaluationResult
public class EvaluationResult : IHasDescription
{
public EvaluationResult([CanBeNull] ICanBeAnalyzed obj, bool passed, string description,
public EvaluationResult([CanBeNull] object obj, bool passed, string description,
ICanBeEvaluated archRule, Architecture architecture)
{
EvaluatedObject = obj;
Expand All @@ -22,10 +22,10 @@ public EvaluationResult([CanBeNull] ICanBeAnalyzed obj, bool passed, string desc
}

public ICanBeEvaluated ArchRule { get; }
[CanBeNull] public ICanBeAnalyzed EvaluatedObject { get; }
[CanBeNull] public object EvaluatedObject { get; }
public bool Passed { get; }
public string Description { get; }
public Architecture Architecture { get; }
public string Description { get; }

public override string ToString()
{
Expand Down
2 changes: 1 addition & 1 deletion ArchUnitNET/Fluent/Extensions/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static class TypeExtensions
{
public static bool CallsMethod(this IHasDependencies type, MethodMember method)
{
return type.GetCalledMethods().Contains(type);
return type.GetCalledMethods().Contains(method);
}

public static bool CallsMethod(this IHasDependencies type, string pattern, bool useRegularExpressions = false)
Expand Down
33 changes: 33 additions & 0 deletions ArchUnitNET/Fluent/Slices/GivenSlices.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 Florian Gather <florian.gather@tngtech.com>
// Copyright 2019 Paula Ruiz <paularuiz22@gmail.com>
// Copyright 2019 Fritz Brandhuber <fritz.brandhuber@tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
//

using System.Collections.Generic;
using ArchUnitNET.Domain;

namespace ArchUnitNET.Fluent.Slices
{
public class GivenSlices
{
private readonly SliceRuleCreator _ruleCreator;

public GivenSlices(SliceRuleCreator ruleCreator)
{
_ruleCreator = ruleCreator;
}

public SlicesShould Should()
{
_ruleCreator.AddToDescription("should");
return new SlicesShould(_ruleCreator);
}

public IEnumerable<Slice> GetSlices(Architecture architecture)
{
return _ruleCreator.GetSlices(architecture);
}
}
}
29 changes: 29 additions & 0 deletions ArchUnitNET/Fluent/Slices/Slice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2019 Florian Gather <florian.gather@tngtech.com>
// Copyright 2019 Paula Ruiz <paularuiz22@gmail.com>
// Copyright 2019 Fritz Brandhuber <fritz.brandhuber@tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
//

using System.Collections.Generic;
using System.Linq;
using ArchUnitNET.Domain;
using ArchUnitNET.Domain.Dependencies.Types;

namespace ArchUnitNET.Fluent.Slices
{
public class Slice : IHasDescription
{
public readonly SliceIdentifier Identifier;
public readonly IEnumerable<IType> Types;

public Slice(SliceIdentifier identifier, IEnumerable<IType> types)
{
Identifier = identifier;
Types = types;
}

public IEnumerable<ITypeDependency> Dependencies => Types.SelectMany(type => type.Dependencies);
public string Description => Identifier.Description;
}
}
34 changes: 34 additions & 0 deletions ArchUnitNET/Fluent/Slices/SliceAssignment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2019 Florian Gather <florian.gather@tngtech.com>
// Copyright 2019 Paula Ruiz <paularuiz22@gmail.com>
// Copyright 2019 Fritz Brandhuber <fritz.brandhuber@tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
//

using System;
using System.Collections.Generic;
using System.Linq;
using ArchUnitNET.Domain;

namespace ArchUnitNET.Fluent.Slices
{
public class SliceAssignment : IHasDescription
{
private readonly Func<IType, SliceIdentifier> _assignIdentifierFunc;


public SliceAssignment(Func<IType, SliceIdentifier> assignIdentifierFunc, string description)
{
_assignIdentifierFunc = assignIdentifierFunc;
Description = description;
}

public string Description { get; }

public IEnumerable<Slice> Apply(IEnumerable<IType> types)
{
return types.GroupBy(_assignIdentifierFunc, (identifier, enumerable) => new Slice(identifier, enumerable),
SliceIdentifier.Comparer);
}
}
}
80 changes: 80 additions & 0 deletions ArchUnitNET/Fluent/Slices/SliceIdentifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2019 Florian Gather <florian.gather@tngtech.com>
// Copyright 2019 Paula Ruiz <paularuiz22@gmail.com>
// Copyright 2019 Fritz Brandhuber <fritz.brandhuber@tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
//

namespace ArchUnitNET.Fluent.Slices
{
public class SliceIdentifier : IHasDescription
{
public static readonly SliceIdentifierComparer Comparer = new SliceIdentifierComparer();
public readonly string Identifier;
public readonly bool Ignored;


private SliceIdentifier(string identifier, bool ignored)
{
Identifier = identifier;
Ignored = ignored;
}

public string Description => Identifier;

public static SliceIdentifier Of(string identifier)
{
return new SliceIdentifier(identifier, false);
}

public static SliceIdentifier Ignore()
{
return new SliceIdentifier("Ignored", true);
}

/// <summary>
/// Is true when the two SliceIdentifiers belong to the same slice
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
public bool CompareTo(SliceIdentifier other)
{
if (other == null)
{
return false;
}

return Ignored && other.Ignored || !Ignored && !other.Ignored && Identifier == other.Identifier;
}

private bool Equals(SliceIdentifier other)
{
return Identifier == other.Identifier && Ignored == other.Ignored;
}

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}

if (ReferenceEquals(this, obj))
{
return true;
}

return obj.GetType() == GetType() && Equals((SliceIdentifier) obj);
}

public override int GetHashCode()
{
unchecked
{
var hashCode = 397 ^ Identifier.GetHashCode();
hashCode = (hashCode * 397) ^ Ignored.GetHashCode();
return hashCode;
}
}
}
}
24 changes: 24 additions & 0 deletions ArchUnitNET/Fluent/Slices/SliceIdentifierComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2019 Florian Gather <florian.gather@tngtech.com>
// Copyright 2019 Paula Ruiz <paularuiz22@gmail.com>
// Copyright 2019 Fritz Brandhuber <fritz.brandhuber@tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
//

using System.Collections.Generic;

namespace ArchUnitNET.Fluent.Slices
{
public class SliceIdentifierComparer : IEqualityComparer<SliceIdentifier>
{
public bool Equals(SliceIdentifier x, SliceIdentifier y)
{
return x != null && x.CompareTo(y);
}

public int GetHashCode(SliceIdentifier obj)
{
return obj.GetHashCode();
}
}
}
54 changes: 54 additions & 0 deletions ArchUnitNET/Fluent/Slices/SliceRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2019 Florian Gather <florian.gather@tngtech.com>
// Copyright 2019 Paula Ruiz <paularuiz22@gmail.com>
// Copyright 2019 Fritz Brandhuber <fritz.brandhuber@tngtech.com>
//
// SPDX-License-Identifier: Apache-2.0
//

using System.Collections.Generic;
using ArchUnitNET.Domain;

namespace ArchUnitNET.Fluent.Slices
{
public class SliceRule : IArchRule
{
private readonly SliceRuleCreator _ruleCreator;

public SliceRule(SliceRuleCreator ruleCreator)
{
_ruleCreator = ruleCreator;
}

public string Description => _ruleCreator.Description;

public bool HasNoViolations(Architecture architecture)
{
return _ruleCreator.HasNoViolations(architecture);
}

public IEnumerable<EvaluationResult> Evaluate(Architecture architecture)
{
return _ruleCreator.Evaluate(architecture);
}

public CombinedArchRuleDefinition And()
{
return new CombinedArchRuleDefinition(_ruleCreator, LogicalConjunctionDefinition.And);
}

public CombinedArchRuleDefinition Or()
{
return new CombinedArchRuleDefinition(_ruleCreator, LogicalConjunctionDefinition.Or);
}

public IArchRule And(IArchRule archRule)
{
return new CombinedArchRule(_ruleCreator, LogicalConjunctionDefinition.And, archRule);
}

public IArchRule Or(IArchRule archRule)
{
return new CombinedArchRule(_ruleCreator, LogicalConjunctionDefinition.Or, archRule);
}
}
}
Loading