diff --git a/.idea/.idea.Shapes/.idea/.name b/.idea/.idea.Shapes/.idea/.name deleted file mode 100644 index 6fd8e14..0000000 --- a/.idea/.idea.Shapes/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -Shapes \ No newline at end of file diff --git a/.idea/.idea.Shapes/.idea/contentModel.xml b/.idea/.idea.Shapes/.idea/contentModel.xml index fff3ada..1f435b2 100644 --- a/.idea/.idea.Shapes/.idea/contentModel.xml +++ b/.idea/.idea.Shapes/.idea/contentModel.xml @@ -1,12 +1,12 @@ - - - - - - + + + + + + @@ -50,6 +50,7 @@ + @@ -59,10 +60,12 @@ + + diff --git a/Shapes.sln b/Shapes.sln index 8b4d161..eff6927 100644 --- a/Shapes.sln +++ b/Shapes.sln @@ -2,8 +2,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shapes", "Shapes\Shapes.csproj", "{3DEEB67E-89F4-403E-8210-EEBD5A01C64D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Temp", "Temp\Temp.csproj", "{781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{E7BB8603-7B34-4C9E-9C1F-916527FD68A5}" EndProject Global @@ -16,10 +14,6 @@ Global {3DEEB67E-89F4-403E-8210-EEBD5A01C64D}.Debug|Any CPU.Build.0 = Debug|Any CPU {3DEEB67E-89F4-403E-8210-EEBD5A01C64D}.Release|Any CPU.ActiveCfg = Release|Any CPU {3DEEB67E-89F4-403E-8210-EEBD5A01C64D}.Release|Any CPU.Build.0 = Release|Any CPU - {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {781AE2D9-ADBF-4AA4-9D9D-78AFBF04A6F5}.Release|Any CPU.Build.0 = Release|Any CPU {E7BB8603-7B34-4C9E-9C1F-916527FD68A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E7BB8603-7B34-4C9E-9C1F-916527FD68A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {E7BB8603-7B34-4C9E-9C1F-916527FD68A5}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/Shapes/Circle.cs b/Shapes/Circle.cs index d18c86d..64fb4f9 100644 --- a/Shapes/Circle.cs +++ b/Shapes/Circle.cs @@ -13,6 +13,26 @@ namespace Shapes [DataContract] public class Circle : GeometricShape { + + + [DataMember] + public override Color Fill { get; set; } + + [DataMember] + public override Color Stroke { get; set; } + + [DataMember] + public override Point CenterPoint { get; protected set; } + + [DataMember] + public double Radius { get; private set; } + + [DataMember] + public double Height { get; internal set; } + + [DataMember] + public double Width { get; internal set; } + internal IFileIO _fileWriter; /** @@ -52,17 +72,6 @@ namespace Shapes Width = radius * 2; } - [DataMember] public override Color Fill { get; set; } - - [DataMember] public override Color Stroke { get; set; } - - [DataMember] public override Point CenterPoint { get; protected set; } - - [DataMember] public double Radius { get; private set; } - - [DataMember] public override double Height { get; internal set; } - - [DataMember] public override double Width { get; internal set; } [ExcludeFromCodeCoverage] internal override void ComputeCenter() diff --git a/Shapes/CompositeShape.cs b/Shapes/CompositeShape.cs index 41a895b..b0ab9c9 100644 --- a/Shapes/CompositeShape.cs +++ b/Shapes/CompositeShape.cs @@ -1,20 +1,37 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; - +using System.Runtime.CompilerServices; +using System.Runtime.Serialization; +[assembly:InternalsVisibleTo("UnitTests")] namespace Shapes { + [DataContract] public class CompositeShape : Shape { - private readonly List thisShapesList = new List(); - + [DataMember] + internal readonly List thisShapesList = new List(); + [DataMember] public override Color Fill { get; set; } + [DataMember] public override Color Stroke { get; set; } + [DataMember] + public override List Points { get; protected set; } + + internal IFileIO _fileWriter; + + public CompositeShape() + { + Points = new List(); + } public void Add(Shape shape) { + Stroke = Color.Black; + Points.AddRange(shape.Points); if (shape.CompositeShape) throw new ShapeException("This shape has already been added to a composite"); if (shape == this) @@ -36,10 +53,10 @@ namespace Shapes public override void Save(Stream stream) { - var fileWriter = new FileIO(); - fileWriter.SaveShape(stream, this); + _fileWriter.SaveShape(stream, this); } + [ExcludeFromCodeCoverage] public override void Draw(Stream stream) { var tmp = new Bitmap(1000, 1000); @@ -60,6 +77,13 @@ namespace Shapes public void RemoveShape(Shape shape) { + if(Points.Count > 0) + { + foreach (var point in shape.Points) + { + Points.Remove(point); + } + } if (!thisShapesList.Contains(shape)) throw new ShapeException($"{shape.GetType().Name} is not part of the composite shape."); thisShapesList.Remove(shape); @@ -71,7 +95,7 @@ namespace Shapes while (thisShapesList.Count > 0) { thisShapesList[0].CompositeShape = false; - thisShapesList.Remove(thisShapesList[0]); + RemoveShape(thisShapesList[0]); } } } diff --git a/Shapes/FileIO.cs b/Shapes/FileIO.cs index 3c60f10..ffd82ee 100644 --- a/Shapes/FileIO.cs +++ b/Shapes/FileIO.cs @@ -1,8 +1,10 @@ +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.Serialization.Json; namespace Shapes { + [ExcludeFromCodeCoverage] public class FileIO : IFileIO { public void SaveShape(Stream stream, Shape shape) diff --git a/Shapes/GeometricShape.cs b/Shapes/GeometricShape.cs index 99574bf..7581a10 100644 --- a/Shapes/GeometricShape.cs +++ b/Shapes/GeometricShape.cs @@ -9,11 +9,8 @@ namespace Shapes [KnownType(typeof(Triangle))] public abstract class GeometricShape : Shape { - [DataMember] public abstract double Width { get; internal set; } - - [DataMember] public abstract double Height { get; internal set; } - - [DataMember] public abstract Point CenterPoint { get; protected set; } + [DataMember] + public abstract Point CenterPoint { get; protected set; } internal abstract void ComputeCenter(); @@ -42,20 +39,14 @@ namespace Shapes { var tmpCenter = CenterPoint; - var property = GetType().GetProperties().Equals(nameof(Points)); - Console.WriteLine(property.GetType()); - - if (property) - { - Console.WriteLine(property.GetType()); + foreach (var point in Points) { var tmpPoint = point - tmpCenter; - Console.WriteLine($"({tmpPoint.X}, {tmpPoint.Y})"); point.X = deltaX + tmpPoint.X; point.Y = deltaY + tmpPoint.Y; } - } + CenterPoint = new Point(deltaX, deltaY); } diff --git a/Shapes/Image.cs b/Shapes/Image.cs index 8338057..10570ac 100644 --- a/Shapes/Image.cs +++ b/Shapes/Image.cs @@ -1,9 +1,11 @@ +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.IO; using static Shapes.ImageManager; namespace Shapes { + [ExcludeFromCodeCoverage] public class Image : Rectangle { public Image(Point point1, Point point2, Point point3, Point point4, Stream stream) : base(point1, point2, diff --git a/Shapes/ImageManager.cs b/Shapes/ImageManager.cs index aa9f6f5..2babf05 100644 --- a/Shapes/ImageManager.cs +++ b/Shapes/ImageManager.cs @@ -1,9 +1,11 @@ using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.IO; namespace Shapes { + [ExcludeFromCodeCoverage] public static class ImageManager { private static readonly Hashtable _images; diff --git a/Shapes/Line.cs b/Shapes/Line.cs index c649f32..43d52e0 100644 --- a/Shapes/Line.cs +++ b/Shapes/Line.cs @@ -6,6 +6,10 @@ namespace Shapes [DataContract(Name = "Line", Namespace = "Shapes")] public class Line { + [DataMember] + public Point Point1 { get; private set; } + [DataMember] + public Point Point2 { get; private set; } /** * Constructor based on x-y Locations * @param x1 The x-location of first point -- must be a valid double. @@ -34,10 +38,6 @@ namespace Shapes Point2 = point2; } - [DataMember] public Point Point1 { get; private set; } - - [DataMember] public Point Point2 { get; private set; } - /** * Move a line * diff --git a/Shapes/Rectangle.cs b/Shapes/Rectangle.cs index 71d21e9..69e7bf6 100644 --- a/Shapes/Rectangle.cs +++ b/Shapes/Rectangle.cs @@ -14,6 +14,23 @@ namespace Shapes public class Rectangle : GeometricShape { internal IFileIO _fileWriter; + + [DataMember] + public override List Points { get; protected set; } + [DataMember] + public override Color Fill { get; set; } + [DataMember] + public override Color Stroke { get; set; } + [DataMember] + public List Lines { get; } + [DataMember] + public override Point CenterPoint { get; protected set; } + [DataMember] + public double Width { get; internal set; } + [DataMember] + public double Height { get; internal set; } + + public Rectangle(Point point1, Point point2, Point point3, Point point4) { @@ -92,20 +109,7 @@ namespace Shapes Validator.ValidateRectangle(Points, $"Attempted to create an invalid shape {GetType()}"); } - [DataMember] public override List Points { get; internal set; } - - [DataMember] public override Color Fill { get; set; } - - [DataMember] public override Color Stroke { get; set; } - - [DataMember] public List Lines { get; } - - [DataMember] public override Point CenterPoint { get; protected set; } - - [DataMember] public sealed override double Width { get; internal set; } - - [DataMember] public sealed override double Height { get; internal set; } - + public override double ComputeArea() { return Height * Width; diff --git a/Shapes/Shape.cs b/Shapes/Shape.cs index e774a1f..657d536 100644 --- a/Shapes/Shape.cs +++ b/Shapes/Shape.cs @@ -15,14 +15,15 @@ namespace Shapes CompositeShape = false; } - [DataMember] public virtual List Points { get; internal set; } - - [DataMember] public abstract Color Fill { get; set; } - - [DataMember] public abstract Color Stroke { get; set; } - - [DataMember] protected internal bool CompositeShape { get; set; } - + [DataMember] + public virtual List Points { get; protected set; } + [DataMember] + public abstract Color Fill { get; set; } + [DataMember] + public abstract Color Stroke { get; set; } + [DataMember] + protected internal bool CompositeShape { get; set; } + public abstract double ComputeArea(); diff --git a/Shapes/ShapeFactory.cs b/Shapes/ShapeFactory.cs index e1c503c..09e9dd6 100644 --- a/Shapes/ShapeFactory.cs +++ b/Shapes/ShapeFactory.cs @@ -1,7 +1,9 @@ +using System.Diagnostics.CodeAnalysis; using System.IO; namespace Shapes { + [ExcludeFromCodeCoverage] public class ShapeFactory { public T GetShapeFromFile(FileStream fileStream) diff --git a/Shapes/Triangle.cs b/Shapes/Triangle.cs index b3c8b59..c827ff7 100644 --- a/Shapes/Triangle.cs +++ b/Shapes/Triangle.cs @@ -1,9 +1,12 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace Shapes @@ -11,6 +14,24 @@ namespace Shapes [DataContract(Name = "Triangle", Namespace = "Shapes")] public class Triangle : GeometricShape { + + [DataMember] + public sealed override List Points { get; protected set; } + + [DataMember] + public override Color Fill { get; set; } + + [DataMember] + public override Color Stroke { get; set; } + + [DataMember] + public sealed override Point CenterPoint { get; protected set; } + + [DataMember] + public List Lines { get; internal set; } + + internal IFileIO _fileWriter; + public Triangle(Point point1, Point point2, Point point3) { Stroke = Color.Black; @@ -26,14 +47,7 @@ namespace Shapes Lines.Add(new Line(point2, point3)); Lines.Add(new Line(point3, point1)); - var centerOfLine1 = (point1 - point2) / 2 + point1; - var centerTriangle = (point1 - centerOfLine1) / 2 + point1; - - - CenterPoint = centerTriangle; - - Height = new Line(point1, point3).ComputeLength(); - Width = new Line(point1, point2).ComputeLength(); + ComputeCenter(); } public Triangle(double x1, double y1, double x2, double y2, double x3, double y3) @@ -56,28 +70,10 @@ namespace Shapes Lines.Add(new Line(point2, point3)); Lines.Add(new Line(point3, point1)); - var centerOfLine3 = (point1 - point3) / 2 + point1; - var centerTriangle = (point1 - centerOfLine3) / 2 + point1; - - Height = new Line(point1, point3).ComputeLength(); - Width = new Line(point1, point2).ComputeLength(); - - CenterPoint = centerTriangle; + ComputeCenter(); } - [DataMember] public sealed override List Points { get; internal set; } - - [DataMember] public override Color Fill { get; set; } - - [DataMember] public override Color Stroke { get; set; } - - [DataMember] public override double Height { get; internal set; } - - [DataMember] public override double Width { get; internal set; } - - [DataMember] public sealed override Point CenterPoint { get; protected set; } - - [DataMember] public List Lines { get; internal set; } + public override double ComputeArea() { @@ -103,14 +99,13 @@ namespace Shapes public override void Save(Stream stream) { - var fileWriter = new FileIO(); - fileWriter.SaveShape(stream, this); + _fileWriter.SaveShape(stream, this); } [ExcludeFromCodeCoverage] public override void Draw(Stream stream) { - var tmp = new Bitmap((int) Width * 2, (int) Height * 2); + var tmp = new Bitmap((int) Lines.Max(x => x.ComputeLength()) * 2, (int) Lines.Max(x => x.ComputeLength()) * 2); var blackPen = new Pen(Stroke, 3); // Draw line to screen. using (var graphics = Graphics.FromImage(tmp)) @@ -128,9 +123,10 @@ namespace Shapes internal override void ComputeCenter() { - var centerOfLine3 = (Points[0] - Points[2]) / 2 + Points[0]; - var centerTriangle = (Points[0] - centerOfLine3) / 2 + Points[0]; - CenterPoint = centerTriangle; + var x = (Points[0].X + Points[1].X + Points[2].X) * 0.33333333333; + var y = (Points[0].Y + Points[1].Y + Points[2].Y) * 0.33333333333; + CenterPoint = new Point(x, y); + } } } \ No newline at end of file diff --git a/Shapes/Validator.cs b/Shapes/Validator.cs index 1ec606f..48284e6 100644 --- a/Shapes/Validator.cs +++ b/Shapes/Validator.cs @@ -34,11 +34,24 @@ namespace Shapes || Math.Abs(lengthLine1.ComputeLength() - lengthLine2.ComputeLength()) > TOLERANCE) throw new ShapeException(errorMessage); +// while (pointList.Count > 0) +// { +// var tmp = pointList[0]; +// pointList.Remove(tmp); +// if (pointList.Contains(tmp)) throw new ShapeException(errorMessage); +// } + while (pointList.Count > 0) { var tmp = pointList[0]; pointList.Remove(tmp); - if (pointList.Contains(tmp)) throw new ShapeException(errorMessage); + foreach (var point in pointList) + { + if (point.X.Equals(tmp.X) && point.Y.Equals(tmp.Y)) + throw new ShapeException(errorMessage); + } + + //if (pointList.Contains(tmp)) throw new ShapeException(errorMessage); } } } diff --git a/Temp/Program.cs b/Temp/Program.cs index 53c8030..757f3fa 100644 --- a/Temp/Program.cs +++ b/Temp/Program.cs @@ -36,10 +36,10 @@ namespace Temp var triangle = new Triangle(new Point(3, 3), new Point(7, 3), new Point(7, 6)); Console.WriteLine( - $"\n \n ({triangle.Points[0].X}, {triangle.Points[0].Y}) ({triangle.Points[1].X}, {triangle.Points[1].Y}) ({triangle.Points[2].X}, {triangle.Points[2].Y}) Center: ({triangle.CenterPoint.X}, {triangle.CenterPoint.Y}) Area = {triangle.ComputeArea()} Height: {triangle.Height}"); + $"\n \n ({triangle.Points[0].X}, {triangle.Points[0].Y}) ({triangle.Points[1].X}, {triangle.Points[1].Y}) ({triangle.Points[2].X}, {triangle.Points[2].Y}) Center: ({triangle.CenterPoint.X}, {triangle.CenterPoint.Y}) Area = {triangle.ComputeArea()} "); triangle.Rotate(30); Console.WriteLine( - $"({triangle.Points[0].X}, {triangle.Points[0].Y}) ({triangle.Points[1].X}, {triangle.Points[1].Y}) ({triangle.Points[2].X}, {triangle.Points[2].Y}) Center: ({triangle.CenterPoint.X}, {triangle.CenterPoint.Y}) Area = {triangle.ComputeArea()} Height: {triangle.Height}"); + $"({triangle.Points[0].X}, {triangle.Points[0].Y}) ({triangle.Points[1].X}, {triangle.Points[1].Y}) ({triangle.Points[2].X}, {triangle.Points[2].Y}) Center: ({triangle.CenterPoint.X}, {triangle.CenterPoint.Y}) Area = {triangle.ComputeArea()}"); var composite = new CompositeShape(); @@ -59,7 +59,7 @@ namespace Temp var fs = new FileStream(@"/Users/bradybodily/Documents/testing/test.txt", FileMode.Open); var triangle2 = new ShapeFactory().GetShapeFromFile(fs); Console.WriteLine( - $"({triangle2.Points[0].X}, {triangle2.Points[0].Y}) ({triangle2.Points[1].X}, {triangle2.Points[1].Y}) ({triangle2.Points[2].X}, {triangle2.Points[2].Y}) Center: ({triangle2.CenterPoint.X}, {triangle2.CenterPoint.Y}) Area = {triangle2.ComputeArea()} Height: {triangle2.Height}"); + $"({triangle2.Points[0].X}, {triangle2.Points[0].Y}) ({triangle2.Points[1].X}, {triangle2.Points[1].Y}) ({triangle2.Points[2].X}, {triangle2.Points[2].Y}) Center: ({triangle2.CenterPoint.X}, {triangle2.CenterPoint.Y}) Area = {triangle2.ComputeArea()} "); var imf = new FileStream(@"/Users/bradybodily/Documents/testing/visual-reverse-image-search-v2_intro.jpg", FileMode.Create); diff --git a/UnitTests/CircleTests.cs b/UnitTests/CircleTests.cs index dbdc8cb..609c611 100644 --- a/UnitTests/CircleTests.cs +++ b/UnitTests/CircleTests.cs @@ -35,6 +35,7 @@ namespace Tests Assert.AreEqual(Color.Aqua, circle.Fill); Assert.IsNull(circle.Points); Assert.AreEqual(1, circle.Radius); + Assert.IsFalse(circle.CompositeShape); } @@ -53,6 +54,7 @@ namespace Tests Assert.AreEqual(Color.Aqua, circle.Fill); Assert.IsNull(circle.Points); Assert.AreEqual(1, circle.Radius); + Assert.IsFalse(circle.CompositeShape); } [Test] diff --git a/UnitTests/CompositeShapeTests.cs b/UnitTests/CompositeShapeTests.cs new file mode 100644 index 0000000..7924a7e --- /dev/null +++ b/UnitTests/CompositeShapeTests.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Reflection.Metadata; +using Moq; +using NUnit.Framework; +using Shapes; +using Point = Shapes.Point; +using Rectangle = Shapes.Rectangle; + +namespace Tests +{ + public class CompositeShapeTests + { + private Mock _mockFileStream; + private Mock _mockFileIO; + + [SetUp] + public void SetUp() + { + _mockFileIO = new Mock(); + _mockFileStream = new Mock(); + } + + [Test] + public void CompositeShape() + { + var points = new List(); + var composite = new CompositeShape(); + var rpoint1 = new Point(20, 20); + var rpoint2 = new Point(30, 20); + var rpoint3 = new Point(30, 30); + var rpoint4 = new Point(20, 30); + + var rect = new Rectangle(rpoint1, rpoint2, rpoint3, rpoint4); + + var tpoint1 = new Point(0, 0); + var tpoint2 = new Point(3, 0); + var tpoint3 = new Point(0, 3); + var triangle = new Triangle(tpoint1, tpoint2, tpoint3); + + points.Add(rpoint1); + points.Add(rpoint2); + points.Add(rpoint3); + points.Add(rpoint4); + points.Add(tpoint1); + points.Add(tpoint2); + points.Add(tpoint3); + + var area = rect.ComputeArea() + triangle.ComputeArea(); + + composite.Add(rect); + composite.Add(triangle); + + Assert.AreEqual(area, composite.ComputeArea()); + Assert.AreEqual(Color.Empty, composite.Fill); + Assert.AreEqual(Color.Black, composite.Stroke); + composite.Fill = Color.Aqua; + Assert.AreEqual(Color.Aqua, composite.Fill); + + + + foreach (var point in composite.Points) + { + Assert.Contains(point, points); + } + + } + + [Test] + public void RemoveShapeTest() + { + var points = new List(); + var composite = new CompositeShape(); + var rpoint1 = new Point(20, 20); + var rpoint2 = new Point(30, 20); + var rpoint3 = new Point(30, 30); + var rpoint4 = new Point(20, 30); + + var rect = new Rectangle(rpoint1, rpoint2, rpoint3, rpoint4); + + var tpoint1 = new Point(0, 0); + var tpoint2 = new Point(3, 0); + var tpoint3 = new Point(0, 3); + var triangle = new Triangle(tpoint1, tpoint2, tpoint3); + + points.Add(rpoint1); + points.Add(rpoint2); + points.Add(rpoint3); + points.Add(rpoint4); + + + var area = rect.ComputeArea() + triangle.ComputeArea(); + + composite.Add(rect); + composite.Add(triangle); + + Assert.AreEqual(area, composite.ComputeArea()); + + composite.RemoveShape(triangle); + + foreach (var point in composite.Points) + { + Assert.Contains(point, points); + } + Assert.AreEqual(rect.ComputeArea(), composite.ComputeArea()); + } + + [Test] + public void RemoveShapeNotInComposite() + { + var composite = new CompositeShape(); + var circle = new Circle(20,20,5); + Assert.That(()=> composite.RemoveShape(circle), Throws.TypeOf() + .With.Message.EqualTo($"{typeof(Circle).Name} is not part of the composite shape.")); + } + + [Test] + public void AddShapeTwicetest() + { + var c = new CompositeShape(); + var rpoint1 = new Point(20, 20); + var rpoint2 = new Point(30, 20); + var rpoint3 = new Point(30, 30); + var rpoint4 = new Point(20, 30); + var rect = new Rectangle(rpoint1, rpoint2, rpoint3, rpoint4); + c.Add(rect); + Assert.That(()=> c.Add(rect), Throws.TypeOf() + .With.Message.EqualTo("This shape has already been added to a composite")); + } + + [Test] + public void AddCompositeToSelf() + { + var c = new CompositeShape(); + Assert.That(()=> c.Add(c), Throws.TypeOf() + .With.Message.EqualTo("You cant add a shape to itself")); + } + + [Test] + public void AddShapeToTwoComposits() + { + var c = new CompositeShape(); + var co = new CompositeShape(); + var rpoint1 = new Point(20, 20); + var rpoint2 = new Point(30, 20); + var rpoint3 = new Point(30, 30); + var rpoint4 = new Point(20, 30); + var rect = new Rectangle(rpoint1, rpoint2, rpoint3, rpoint4); + c.Add(rect); + Assert.That(()=> co.Add(rect), Throws.TypeOf() + .With.Message.EqualTo("This shape has already been added to a composite")); + } + + [Test] + public void RemoveAllShapes() + { + var c = new CompositeShape(); + var rpoint1 = new Point(20, 20); + var rpoint2 = new Point(30, 20); + var rpoint3 = new Point(30, 30); + var rpoint4 = new Point(20, 30); + var rect = new Rectangle(rpoint1, rpoint2, rpoint3, rpoint4); + c.Add(rect); + var tpoint1 = new Point(0, 0); + var tpoint2 = new Point(3, 0); + var tpoint3 = new Point(0, 3); + var triangle = new Triangle(tpoint1, tpoint2, tpoint3); + c.Add(triangle); + + c.RemoveAllShapes(); + Assert.AreEqual(0,c.Points.Count); + Assert.AreEqual(0, c.thisShapesList.Count); + } + + [Test] + public void ScaleTest() + { + var c = new CompositeShape(); + var rpoint1 = new Point(1, 1); + var rpoint2 = new Point(2, 1); + var rpoint3 = new Point(2, 2); + var rpoint4 = new Point(1, 2); + var rect = new Rectangle(rpoint1, rpoint2, rpoint3, rpoint4); + c.Add(rect); + var tpoint1 = new Point(0, 0); + var tpoint2 = new Point(1, 0); + var tpoint3 = new Point(0, 1); + var triangle = new Triangle(tpoint1, tpoint2, tpoint3); + c.Add(triangle); + var area = c.ComputeArea()*2; + c.Scale(2); + Assert.Less(Math.Abs(c.ComputeArea()-area), .000000000000001); + } + + [Test] + public void SaveTest() + { + Shape createdObj = null; + var c = new CompositeShape(); + _mockFileIO.Setup(x => x.SaveShape(It.IsAny(), It.IsAny())) + .Callback((i, x) => { createdObj = x; }); + + c._fileWriter = _mockFileIO.Object; + + c.Save(_mockFileStream.Object); + Assert.AreEqual(c, createdObj); + + _mockFileIO.Verify(x => x.SaveShape(It.IsAny(), + It.IsAny()), Times.Once); + + } + } +} \ No newline at end of file diff --git a/UnitTests/PointTests.cs b/UnitTests/PointTests.cs new file mode 100644 index 0000000..d581c2a --- /dev/null +++ b/UnitTests/PointTests.cs @@ -0,0 +1,73 @@ +using System.Drawing; +using NUnit.Framework; +using Point = Shapes.Point; + +namespace Tests +{ + public class PointTests + { + [SetUp] + public void SetUp() + { + + } + + [Test] + public void ColorTests() + { + var point = new Point(10,10); + Assert.AreEqual(Color.Black, point.Color); + point.Color = Color.Aqua; + Assert.AreEqual(Color.Aqua, point.Color); + } + + [Test] + public void MoveTest() + { + var point = new Point(10, 10); + point.Move(20, 20); + Assert.AreEqual(point.X, 30); + Assert.AreEqual(point.Y, 30); + } + + [Test] + public void CopyTest() + { + var point = new Point(20, 20); + Assert.AreEqual(point.Color, point.Copy().Color); + Assert.AreEqual(point.X, point.Copy().X); + Assert.AreEqual(point.Y, point.Copy().Y); + + } + + [Test] + public void SubtractionTest() + { + var point1 = new Point(5, 5); + var point2 = new Point(15, 15); + var point3 = point2 - point1; + Assert.AreEqual(point3.X, 10); + Assert.AreEqual(point3.Y, 10); + + } + [Test] + public void AdditionTest() + { + var point1 = new Point(5, 5); + var point2 = new Point(15, 15); + var point3 = point2 + point1; + Assert.AreEqual(20, point3.X); + Assert.AreEqual(20, point3.Y); + + } + [Test] + public void DivisionTest() + { + var point1 = new Point(10, 10); + var point3 = point1 / 2; + Assert.AreEqual(point3.X, 5); + Assert.AreEqual(point3.Y, 5); + + } + } +} \ No newline at end of file diff --git a/UnitTests/RectangleTests.cs b/UnitTests/RectangleTests.cs index 39a0989..f4b1ee8 100644 --- a/UnitTests/RectangleTests.cs +++ b/UnitTests/RectangleTests.cs @@ -40,6 +40,7 @@ namespace Tests Assert.AreEqual(rectangle.ComputeArea(), 100); Assert.AreEqual(rectangle.CalculateHeight(), 10); Assert.AreEqual(rectangle.CalculateWidth(), 10); + Assert.IsFalse(rectangle.CompositeShape); rectangle.Fill = Color.Aqua; Assert.AreEqual(Color.Aqua, rectangle.Fill); foreach (var line in rectangle.Lines) @@ -74,6 +75,7 @@ namespace Tests Assert.AreEqual(100, rectangle.ComputeArea()); Assert.AreEqual(10, rectangle.CalculateHeight()); Assert.AreEqual(10, rectangle.CalculateWidth()); + Assert.IsFalse(rectangle.CompositeShape); rectangle.Fill = Color.Aqua; Assert.AreEqual(Color.Aqua, rectangle.Fill); foreach (var line in rectangle.Lines) @@ -99,6 +101,7 @@ namespace Tests Assert.AreEqual(100, rectangle.ComputeArea()); Assert.AreEqual(10, rectangle.CalculateHeight()); Assert.AreEqual(10, rectangle.CalculateWidth()); + Assert.IsFalse(rectangle.CompositeShape); rectangle.Fill = Color.Aqua; Assert.AreEqual(Color.Aqua, rectangle.Fill); foreach (var line in rectangle.Lines) @@ -190,6 +193,51 @@ namespace Tests Assert.That(()=> rectangle.Scale(-20), Throws.TypeOf() .With.Message.EqualTo("Invalid scale factor")); } + + [Test] + public void MoveTest() + { + var rectangle = new Rectangle( + new Point(20, 20), + new Point(30, 20), + new Point(30, 30), + new Point(20, 30)); + + rectangle.Move(40,40); + Assert.AreEqual(35 ,rectangle.Points[0].X); + Assert.AreEqual(35 ,rectangle.Points[0].Y); + + Assert.AreEqual(45 ,rectangle.Points[1].X); + Assert.AreEqual(35 ,rectangle.Points[1].Y); + + Assert.AreEqual(45 ,rectangle.Points[2].X); + Assert.AreEqual(45 ,rectangle.Points[2].Y); + + Assert.AreEqual(35 ,rectangle.Points[3].X); + Assert.AreEqual(45 ,rectangle.Points[3].Y); + } + + [Test] + public void RotateTest() + { + var rectangle = new Rectangle( + new Point(20, 20), + new Point(30, 20), + new Point(30, 30), + new Point(20, 30)); + rectangle.Rotate(90); + Assert.AreEqual(30 ,rectangle.Points[0].X); + Assert.AreEqual(20 ,rectangle.Points[0].Y); + + Assert.AreEqual(30 ,rectangle.Points[1].X); + Assert.AreEqual(30 ,rectangle.Points[1].Y); + + Assert.AreEqual(20 ,rectangle.Points[2].X); + Assert.AreEqual(30 ,rectangle.Points[2].Y); + + Assert.AreEqual(20 ,rectangle.Points[3].X); + Assert.AreEqual(20 ,rectangle.Points[3].Y); + } } } \ No newline at end of file diff --git a/UnitTests/TriangleTests.cs b/UnitTests/TriangleTests.cs index e1f30b7..91b133b 100644 --- a/UnitTests/TriangleTests.cs +++ b/UnitTests/TriangleTests.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.IO; +using System.Text; +using Moq; using NUnit.Framework; using Shapes; using Point = Shapes.Point; @@ -9,11 +12,17 @@ namespace Tests { public class TriangleTests { + private Mock _mockFileStream; + private Mock _mockFileIO; + [SetUp] public void Setup() { + _mockFileIO = new Mock(); + _mockFileStream = new Mock(); } + [Test] public void TrianglePoints() { @@ -35,8 +44,8 @@ namespace Tests Assert.AreEqual(point3, triangle.Lines[1].Point2); Assert.AreEqual(point3, triangle.Lines[2].Point1); Assert.AreEqual(point1, triangle.Lines[2].Point2); - Assert.AreEqual(3, triangle.Height); - Assert.AreEqual(3, triangle.Width); + Assert.IsFalse(triangle.CompositeShape); + } @@ -78,8 +87,8 @@ namespace Tests Assert.AreEqual(point3y, triangle.Lines[1].Point2.Y); Assert.AreEqual(point3y, triangle.Lines[2].Point1.Y); Assert.AreEqual(point1y, triangle.Lines[2].Point2.Y); - Assert.AreEqual(3, triangle.Height); - Assert.AreEqual(3, triangle.Width); + Assert.IsFalse(triangle.CompositeShape); + } @@ -124,10 +133,31 @@ namespace Tests { var triangle = new Triangle( new Point(0, 0), - new Point(1, 0), - new Point(0, 1)); - Assert.AreEqual(.25, triangle.CenterPoint.X); - Assert.AreEqual(.5, triangle.CenterPoint.Y); + new Point(3, 0), + new Point(0, 3)); + Assert.LessOrEqual(Math.Abs(1 - triangle.CenterPoint.X), 2E-11d); + Assert.LessOrEqual(Math.Abs(1 - triangle.CenterPoint.Y), 2E-11d); + + } + + [Test] + public void SaveTest() + { + Shape createdObj = null; + var triangle = new Triangle( + new Point(0, 0), + new Point(3, 0), + new Point(0, 3)); + _mockFileIO.Setup(x => x.SaveShape(It.IsAny(), It.IsAny())) + .Callback((i, x) => { createdObj = x; }); + + triangle._fileWriter = _mockFileIO.Object; + + triangle.Save(_mockFileStream.Object); + Assert.AreEqual(triangle, createdObj); + + _mockFileIO.Verify(x => x.SaveShape(It.IsAny(), + It.IsAny()), Times.Once); } } diff --git a/UnitTests/ValidatorTests.cs b/UnitTests/ValidatorTests.cs new file mode 100644 index 0000000..c59ceda --- /dev/null +++ b/UnitTests/ValidatorTests.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using Shapes; +using static Shapes.Validator; + +namespace Tests +{ + public class ValidatorTests + { + [SetUp] + public void SetUp() + { + + } + + [Test] + public void ValidatePositiveDoubleTest() + { + Assert.That(()=> ValidatePositiveDouble(-10, "Error"), Throws.TypeOf() + .With.Message.EqualTo("Error")); + } + + [Test] + public void ValidateDoubleTest() + { + Assert.That(()=> ValidateDouble(Double.NaN, "Error"), Throws.TypeOf() + .With.Message.EqualTo("Error")); + } + + [Test] + public void ValidateRectangleTest() + { + List points = new List(); + points.Add(new Point(30, 30)); + points.Add(new Point(30, 30)); + points.Add(new Point(30, 30)); + points.Add(new Point(30, 30)); + + Assert.That(()=> ValidateRectangle(points, "Error"), Throws.TypeOf() + .With.Message.EqualTo("Error")); + } + } +} \ No newline at end of file