Skip to content
Snippets Groups Projects
Commit 1050ccff authored by Jakub Konvička's avatar Jakub Konvička
Browse files

feat(#19): Add UNIt tests

parent ee974e9f
Branches feature/UnitTesting
Tags
2 merge requests!10Merge: Release version 1.1,!6Merge Feature/unit testing
......@@ -21,9 +21,9 @@ public class ClassBuilder : IClassBuilder
return this;
}
public IOperationBuilder AddOperation(string name, PropertyType returnType, VisibilityType visibilityType, string returnTypeValue)
public IOperationBuilder AddOperation(string name, PropertyType returnType, VisibilityType visibilityType)
{
return new OperationBuilder(_xmiClassDiagramUmlBuilder, _class, name, returnType, visibilityType, returnTypeValue);
return new OperationBuilder(_xmiClassDiagramUmlBuilder, _class, name, returnType, visibilityType);
}
public IClassBuilder AddAssociation(string targetClassName, VisibilityType visibilityType, AssociationType associationType)
......
......@@ -11,11 +11,11 @@ public class OperationBuilder : IOperationBuilder
private XmiElement _class { get; set; }
private XmiElement _operation { get; set; }
internal OperationBuilder(XmiClassDiagramUmlBuilder xmiClassDiagramUmlBuilder, XmiElement class_, string name, PropertyType returnType, VisibilityType visibilityType, string returnTypeValue)
internal OperationBuilder(XmiClassDiagramUmlBuilder xmiClassDiagramUmlBuilder, XmiElement class_, string name, PropertyType returnType, VisibilityType visibilityType)
{
_xmiClassDiagramUmlBuilder = xmiClassDiagramUmlBuilder;
_class = class_;
_operation = _xmiClassDiagramUmlBuilder.AddOperation(_class, name, returnType, visibilityType, returnTypeValue);
_operation = _xmiClassDiagramUmlBuilder.AddOperation(_class, name, returnType, visibilityType);
}
public IClassBuilder AddProperty(string name, VisibilityType visibilityType, PropertyType propertyType)
......@@ -24,9 +24,9 @@ public class OperationBuilder : IOperationBuilder
return this;
}
public IOperationBuilder AddOperation(string name, PropertyType returnType, VisibilityType visibilityType, string returnTypeValue)
public IOperationBuilder AddOperation(string name, PropertyType returnType, VisibilityType visibilityType)
{
_operation = _xmiClassDiagramUmlBuilder.AddOperation(_class, name, returnType, visibilityType, returnTypeValue);
_operation = _xmiClassDiagramUmlBuilder.AddOperation(_class, name, returnType, visibilityType);
return this;
}
......
......@@ -5,7 +5,7 @@ namespace DiagramBuilder.Class.Interface;
public interface IClassBuilder
{
IClassBuilder AddProperty(string name, VisibilityType visibilityType, PropertyType propertyType);
IOperationBuilder AddOperation(string name, PropertyType returnType, VisibilityType visibilityType, string returnTypeValue);
IOperationBuilder AddOperation(string name, PropertyType returnType, VisibilityType visibilityType);
IClassBuilder AddAssociation(string targetClass, VisibilityType visibilityType, AssociationType associationType);
IClassBuilder AddGeneralization(string targetClass);
}
\ No newline at end of file
......@@ -63,7 +63,7 @@ public class XmiClassDiagramUmlBuilder : DiagramUmlBuilder
AddLowerValueAttribute(property, PropertyType.LiteralInteger, null);
}
public XmiElement AddOperation(XmiElement parent, string name, PropertyType returnType, VisibilityType visibilityType, string returnTypeValue)
public XmiElement AddOperation(XmiElement parent, string name, PropertyType returnType, VisibilityType visibilityType)
{
//add visibility attribute
var visibilityAttribute = new XmiAttributeDTO()
......@@ -235,30 +235,37 @@ public class XmiClassDiagramUmlBuilder : DiagramUmlBuilder
{
foreach (var association in _associations)
{
var targetElement = _elementClasses[association.Target.ClassName];
//add association="package1-Association1"
var attributes = new List<XmiAttributeDTO>()
if (_elementClasses.TryGetValue(association.Target.ClassName, out var targetElement))
{
new XmiAttributeDTO()
//add association="package1-Association1"
var attributes = new List<XmiAttributeDTO>()
{
AttributeName = "association",
AttributeValue = $"{association.Package}-{association.Name}"
},
new XmiAttributeDTO()
{
AttributeName = "type",
AttributeValue = $"{association.Package}-{association.Source.ClassName}"
}
};
AddOwnedAttribute(targetElement, XmiType.UmlProperty, association.Target.AssociationProperyName, attributes);
var package = _packages[association.Package];
new XmiAttributeDTO()
{
AttributeName = "association",
AttributeValue = $"{association.Package}-{association.Name}"
},
new XmiAttributeDTO()
{
AttributeName = "type",
AttributeValue = $"{association.Package}-{association.Source.ClassName}"
}
};
AddOwnedAttribute(targetElement, XmiType.UmlProperty, association.Target.AssociationProperyName, attributes);
var package = _packages[association.Package];
var memberEndAttribute = new XmiAttributeDTO()
var memberEndAttribute = new XmiAttributeDTO()
{
AttributeName = "memberEnd",
AttributeValue = $"{association.Package}-{association.Target.ClassName}-{association.Target.AssociationProperyName} {association.Package}-{association.Source.ClassName}-{association.Source.AssociationProperyName}"
};
AddPackagedElement(package, XmiType.UmlAssociation, association.Name, new() { memberEndAttribute });
}
else
{
AttributeName = "memberEnd",
AttributeValue = $"{association.Package}-{association.Target.ClassName}-{association.Target.AssociationProperyName} {association.Package}-{association.Source.ClassName}-{association.Source.AssociationProperyName}"
};
AddPackagedElement(package, XmiType.UmlAssociation, association.Name, new() { memberEndAttribute });
throw new ArgumentException($"Target class {association.Target.ClassName} not found");
}
}
}
}
\ No newline at end of file
......@@ -89,7 +89,7 @@ public class CppClassDiagramVisitor : CPP14ParserBaseVisitor<object>
if(member is Function function)
{
var operationBuilder = _classes.Last().Value.AddOperation(function.Name, Convertor.StringToPropertyType(function.ReturnType), actualAccessSpecifier, function.ReturnType);
var operationBuilder = _classes.Last().Value.AddOperation(function.Name, Convertor.StringToPropertyType(function.ReturnType), actualAccessSpecifier);
foreach(var param in function.Parameters)
{
operationBuilder.AddParameter(param.Name, Convertor.StringToPropertyType(param.Type));
......
......@@ -138,6 +138,143 @@ public class ClassDiagramTests
}
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
public void BuildDiagramWithProperties(int numberOfProperties)
{
if (numberOfProperties >= 1)
{
var package = ClassDiagramBuilder.AddPackage("TestPackage");
var testClass = package.AddClass("TestClass", false);
for (int i = 1; i <= numberOfProperties; i++)
{
testClass.AddProperty($"Property{i}", VisibilityType.Public, PropertyType.PrimitiveTypeString);
}
var xmi = ClassDiagramBuilder.BuildDiagram();
AssertCommonAssertions(xmi);
}
}
[Test]
public void BuildDiagramWithMultiplePackagesAndClasses()
{
var package1 = ClassDiagramBuilder.AddPackage("Package1");
package1.AddClass("Class1", false)
.AddAssociation("Class2", VisibilityType.Public, AssociationType.Association);
var package2 = ClassDiagramBuilder.AddPackage("Package2");
package2.AddClass("Class2", false)
.AddAssociation("Class1", VisibilityType.Public, AssociationType.Aggregation);
var xmi = ClassDiagramBuilder.BuildDiagram();
AssertCommonAssertions(xmi);
}
[Test]
[TestCase("Class1", VisibilityType.Public, AssociationType.Association, true)]
[TestCase("Class1", VisibilityType.Private, AssociationType.Association, true)]
[TestCase("Class1", VisibilityType.Protected, AssociationType.Association, true)]
[TestCase("Class1", VisibilityType.Public, AssociationType.Aggregation, true)]
[TestCase("Class1", VisibilityType.Private, AssociationType.Aggregation, true)]
[TestCase("Class1", VisibilityType.Protected, AssociationType.Aggregation, true)]
[TestCase("Class1", VisibilityType.Public, AssociationType.Composition, true)]
[TestCase("Class1", VisibilityType.Private, AssociationType.Composition, true)]
[TestCase("Class1", VisibilityType.Protected, AssociationType.Composition, true)]
[TestCase("Class2", VisibilityType.Public, AssociationType.Association, true)]
[TestCase("Class2", VisibilityType.Private, AssociationType.Association, true)]
[TestCase("Class2", VisibilityType.Protected, AssociationType.Association, true)]
[TestCase("Class2", VisibilityType.Public, AssociationType.Aggregation, true)]
[TestCase("Class2", VisibilityType.Private, AssociationType.Aggregation, true)]
[TestCase("Class2", VisibilityType.Protected, AssociationType.Aggregation, true)]
[TestCase("Class2", VisibilityType.Public, AssociationType.Composition, true)]
[TestCase("Class2", VisibilityType.Private, AssociationType.Composition, true)]
[TestCase("Class2", VisibilityType.Protected, AssociationType.Composition, true)]
[TestCase("NonExistingClassName", VisibilityType.Public, AssociationType.Association, false)]
[TestCase("NonExistingClassName", VisibilityType.Private, AssociationType.Association, false)]
[TestCase("NonExistingClassName", VisibilityType.Protected, AssociationType.Association, false)]
public void BuildDiagramWithMixedAssociationsAndGeneralization(string targetAssociation, AssociationType type, VisibilityType visibilityType, bool isValid)
{
var package = ClassDiagramBuilder.AddPackage("TestPackage");
var class1 = package.AddClass("Class1", false);
var class2 = package.AddClass("Class2", false);
class2.AddAssociation(targetAssociation, visibilityType, type);
if (!isValid)
{
Assert.Throws<ArgumentException>(() => ClassDiagramBuilder.BuildDiagram());
}
else
{
var xmi = ClassDiagramBuilder.BuildDiagram();
AssertCommonAssertions(xmi);
}
}
[Test]
public void BuildDiagramWithDuplicateClassNames()
{
var package = ClassDiagramBuilder.AddPackage("TestPackage");
// Add classes with the same name (should handle gracefully)
var class1 = package.AddClass("Class1", false);
Assert.Throws<ArgumentException>(() => package.AddClass("Class1", false));
var xmi = ClassDiagramBuilder.BuildDiagram();
AssertCommonAssertions(xmi);
}
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(10)]
public void BuildDiagramWithOperations(int numberOfOperations)
{
if (numberOfOperations >= 1)
{
var package = ClassDiagramBuilder.AddPackage("TestPackage");
var testClass = package.AddClass("TestClass", false);
for (int i = 1; i <= numberOfOperations; i++)
{
testClass.AddOperation($"Operation{i}", PropertyType.PrimitiveTypeBoolean, VisibilityType.Public);
}
var xmi = ClassDiagramBuilder.BuildDiagram();
AssertCommonAssertions(xmi);
}
}
[Test]
public void BuildEmptyDiagramWithNoClasses()
{
var xmi = ClassDiagramBuilder.BuildDiagram();
Assert.IsFalse(string.IsNullOrEmpty(xmi), "XMI should not be null or empty");
AssertCommonAssertions(xmi);
}
[Test]
public void BuildDiagramWithGeneralization()
{
var package = ClassDiagramBuilder.AddPackage("TestPackage");
var class1 = package.AddClass("Class1", false);
var class2 = package.AddClass("Class2", false);
class2.AddGeneralization("Class1");
var xmi = ClassDiagramBuilder.BuildDiagram();
AssertCommonAssertions(xmi);
// Add specific assertions for generalization
Assert.IsTrue(xmi.Contains("general=\"TestPackage-Class1\""), "XMI should contain Generalization");
}
void ValidateSchema()
......@@ -179,4 +316,18 @@ public class ClassDiagramTests
_errors.Add((e.Severity.ToString(), e.Message));
}
}
private void AssertCommonAssertions(string xmi)
{
Assert.IsFalse(string.IsNullOrEmpty(xmi), "XMI should not be null or empty");
Assert.IsTrue(xmi.Contains("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"), "XMI should contain the XML header");
// Add more assertions based on the expected structure of your XMI
if (!string.IsNullOrEmpty(generatedFileName))
{
File.WriteAllText(generatedFileName, xmi);
ValidateSchema();
RemoveGeneratedFile();
}
}
}
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment