diff --git a/CDP4Rules.NetCore.Tests/RuleCheckers/RequirementRuleCheckerTestFixture.cs b/CDP4Rules.NetCore.Tests/RuleCheckers/RequirementRuleCheckerTestFixture.cs new file mode 100644 index 000000000..8b3d0d1b2 --- /dev/null +++ b/CDP4Rules.NetCore.Tests/RuleCheckers/RequirementRuleCheckerTestFixture.cs @@ -0,0 +1,107 @@ +// +// Copyright (c) 2015-2019 RHEA System S.A. +// +// Author: Sam Gerené +// +// This file is part of CDP4-SDK Community Edition +// +// The CDP4-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The CDP4-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Rules.NetCore.Tests.RuleCheckers +{ + using System; + using System.Linq; + using CDP4Common.CommonData; + using CDP4Common.EngineeringModelData; + using CDP4Common.SiteDirectoryData; + using CDP4Rules.Common; + using CDP4Rules.RuleCheckers; + using NUnit.Framework; + + /// + /// Suite of tests for the class. + /// + [TestFixture] + public class RequirementRuleCheckerTestFixture + { + private RequirementRuleChecker requirementRuleChecker; + + private RequirementsSpecification requirementsSpecification; + + private Requirement requirement_1; + + private Requirement requirement_2; + + private Requirement requirement_3; + + [SetUp] + public void SetUp() + { + this.requirementRuleChecker = new RequirementRuleChecker(); + + this.requirementsSpecification = new RequirementsSpecification(); + this.requirement_1 = new Requirement { Iid = Guid.Parse("0816f4b2-7715-47be-88c1-514530bca0c2") }; + this.requirement_2 = new Requirement { Iid = Guid.Parse("998f7f11-0153-4331-b7ee-33e36b278d3a") }; + this.requirement_3 = new Requirement { Iid = Guid.Parse("ca3a7e32-4862-42c9-8435-b4f7dbdfac83") }; + + this.requirementsSpecification.Requirement.Add(this.requirement_1); + this.requirementsSpecification.Requirement.Add(this.requirement_2); + this.requirementsSpecification.Requirement.Add(this.requirement_3); + } + + [Test] + public void Verify_when_Check_is_called_with_null_exception_is_thrown() + { + Assert.Throws(() => this.requirementRuleChecker.CheckWhetherTheRequirementShortNameIsUniqueInContainerRequirementsSpecification(null)); + } + + [Test] + public void Verify_when_Check_is_called_with_non_Category_exception_is_thrown() + { + var alias = new Alias(); + + Assert.Throws(() => this.requirementRuleChecker.CheckWhetherTheRequirementShortNameIsUniqueInContainerRequirementsSpecification(alias)); + } + + [Test] + public void Verify_that_when_requirement_ShortNames_are_not_unique_within_RequirementsSpecification_result_is_returned() + { + this.requirement_1.ShortName = "REQ-1"; + this.requirement_2.ShortName = "REQ-1"; + this.requirement_3.ShortName = "REQ-3"; + + var result = this.requirementRuleChecker.CheckWhetherTheRequirementShortNameIsUniqueInContainerRequirementsSpecification(this.requirement_1).Single(); + + Assert.That(result.Id, Is.EqualTo("MA-0800")); + Assert.That(result.Thing, Is.EqualTo(requirement_1)); + Assert.That(result.Description, Is.EqualTo("The Requirement.ShortName is not unique within the container RequirementsSpecification: 998f7f11-0153-4331-b7ee-33e36b278d3a:REQ-1")); + Assert.That(result.Severity, Is.EqualTo(SeverityKind.Warning)); + } + + [Test] + public void Verify_that_when_requirement_ShortNames_are_unique_within_RequirementsSpecification_no_result_is_returned() + { + this.requirement_1.ShortName = "REQ-1"; + this.requirement_2.ShortName = "REQ-2"; + this.requirement_3.ShortName = "REQ-3"; + + var results = this.requirementRuleChecker.CheckWhetherTheRequirementShortNameIsUniqueInContainerRequirementsSpecification(this.requirement_1); + + Assert.That(results, Is.Empty); + } + } +} \ No newline at end of file diff --git a/CDP4Rules/RuleCheckers/RequirementRuleChecker.cs b/CDP4Rules/RuleCheckers/RequirementRuleChecker.cs new file mode 100644 index 000000000..8595b21f0 --- /dev/null +++ b/CDP4Rules/RuleCheckers/RequirementRuleChecker.cs @@ -0,0 +1,111 @@ +// +// Copyright (c) 2015-2019 RHEA System S.A. +// +// Author: Sam Gerené +// +// This file is part of CDP4-SDK Community Edition +// +// The CDP4-SDK Community Edition is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// The CDP4-SDK Community Edition is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace CDP4Rules.RuleCheckers +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using CDP4Common.CommonData; + using CDP4Common.EngineeringModelData; + using CDP4Rules.Common; + + /// + /// The purpose of the is to execute the rules for instances of type + /// + [RuleChecker(typeof(Requirement))] + public class RequirementRuleChecker : RuleChecker + { + /// + /// Checks whether the is unique within the container + /// + /// + /// The subject + /// + /// + /// An which is empty when no rule violations are encountered. + /// + /// + /// thrown when is null + /// + /// + /// thrown when is not an + /// + [Rule("MA-0800")] + public IEnumerable CheckWhetherTheRequirementShortNameIsUniqueInContainerRequirementsSpecification(Thing thing) + { + var requirement = this.VerifyThingArgument(thing); + + var results = new List(); + var ruleAttribute = System.Reflection.MethodBase.GetCurrentMethod().GetCustomAttribute(); + var rule = StaticRuleProvider.QueryRules().Single(r => r.Id == ruleAttribute.Id); + + var requirementsSpecification = (RequirementsSpecification)thing.Container; + + var duplicates = requirementsSpecification.Requirement.Where(r => r.ShortName == requirement.ShortName && r.Iid != requirement.Iid); + + if (duplicates.Any()) + { + var duplicateIdentifiers = string.Join(",", duplicates.Select(r => r.Iid)); + var duplicateShortNames = string.Join(",", duplicates.Select(r => r.ShortName)); + + var result = new RuleCheckResult(thing, rule.Id, $"The Requirement.ShortName is not unique within the container RequirementsSpecification: {duplicateIdentifiers}:{duplicateShortNames}", SeverityKind.Warning); + results.Add(result); + } + + return results; + } + + /// + /// Verifies that the is of the correct type + /// + /// + /// the subject + /// + /// + /// an instance of + /// + /// + /// thrown when is null + /// + /// + /// thrown when is not an + /// + private Requirement VerifyThingArgument(Thing thing) + { + if (thing == null) + { + throw new ArgumentNullException($"The {nameof(thing)} may not be null"); + } + + var requirement = thing as Requirement; + if (requirement == null) + { + throw new ArgumentException($"{nameof(thing)} with Iid:{thing.Iid} is not an Requirement"); + } + + return requirement; + } + } +} \ No newline at end of file