-
Notifications
You must be signed in to change notification settings - Fork 306
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
Сазонов Александр #237
base: master
Are you sure you want to change the base?
Сазонов Александр #237
Changes from 38 commits
ad2d818
e68c53d
f5e166b
55e34ba
6d20961
8056773
d667276
9e1ec6f
898414c
7e04cfb
903e69b
86704ff
d0636b7
891e73d
8fdf444
1320a4a
91a0388
fd798c6
53157f1
9047c0e
e71f57f
0ac9619
3ad22ea
3b25de2
18aa897
0e7de68
3843478
e42563c
055b888
02a9b74
574bcc8
f983fe4
692ce6c
677cdf9
5f6471e
0647fae
99b191c
7ee7523
a777a93
2b4a1ed
72851ba
a1d4e86
af5b600
1acce94
936f24c
20fbb7f
ceda81c
8482ee9
a18455d
19ea2dc
25352da
57390e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
using FluentAssertions; | ||
using NUnit.Framework.Interfaces; | ||
using System.Drawing; | ||
using TagsCloudVisualization; | ||
using TagsCloudVisualization.Extensions; | ||
using TagsCloudVisualization.Interfaces; | ||
|
||
namespace TagsCloudTests; | ||
|
||
[TestFixture] | ||
[Parallelizable(scope: ParallelScope.All)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А можно ли этот атрибут применить на всю сборку? Чтобы на каждый класс не вешать его There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. да, если использовать наследование, где базовый класс будет иметь все необходимые нам атрибуты There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А еще варианты? Можем в шарпе есть решение? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Можно через таски. Условно сделать массив тасок со всеми тестами и запустить их параллельно There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Можно через атрибут на всю сборку - There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Атрибут - ок) Также могу порекомендовать такие глобальные штуки выносить в самостоятельные файлы, т.к. они не принадлежат конкретному файлу с тестами, а всем) |
||
public class CloudLayouterShould | ||
{ | ||
private readonly Point _defaultCenter = new(0, 0); | ||
AlexxSaz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private readonly Random _random = new(); | ||
|
||
public virtual ICloudLayouter GetCloudLayouter(Point center) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А зачем There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. идея в том, чтобы было возможно наследуя класс, переопределить этот метод, где он будет возвращать другой cloudLayouter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А зачем? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если сделать другой cloudLayouter форма которого - окружность. То можно будет унаследовать тесты и добавить какие-то специфические к конкретному layouter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Но зачем это решать наследованием?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А как это решается? через DI? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Лучше стараться избегать наследования, т.к. с ним ооочень легко наплутать Можно через DI и делегирование) вариантов много разных |
||
new CircularCloudLayouter(center); | ||
|
||
[Test] | ||
[Repeat(5)] | ||
public void PutNextRectangle_ReturnRectangleWithExpectedLocation_AfterFirstExecution() | ||
{ | ||
var expectedCenter = new Point(_random.Next(-10, 10), _random.Next(-10, 10)); | ||
var rectangleWidth = _random.Next(5, 100); | ||
var rectangleSize = new Size(rectangleWidth, rectangleWidth / 2); | ||
AlexxSaz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var cloudLayouter = GetCloudLayouter(expectedCenter); | ||
|
||
var actualRectangle = cloudLayouter.PutNextRectangle(rectangleSize); | ||
|
||
actualRectangle.GetCentralPoint().Should().BeEquivalentTo(expectedCenter); | ||
} | ||
|
||
[TestCase(-1, 1)] | ||
[TestCase(1, -1)] | ||
[TestCase(0, 0)] | ||
public void PutNextRectangle_ThrowArgumentOutOfRangeException_AfterExecutionWith(int width, int height) | ||
{ | ||
var rectangleSize = new Size(width, height); | ||
var circularCloudLayouter = new CircularCloudLayouter(_defaultCenter); | ||
|
||
var executePutNewRectangle = () => circularCloudLayouter.PutNextRectangle(rectangleSize); | ||
|
||
executePutNewRectangle.Should().Throw<ArgumentOutOfRangeException>(); | ||
} | ||
|
||
[Test] | ||
[Repeat(5)] | ||
public void PutNextRectangle_ReturnRectangleThatNotIntersectsWithOther_AfterManyExecution() | ||
{ | ||
var seenRectangles = new HashSet<Rectangle>(); | ||
var rectangleSizes = GetSizes(_random.Next(10, 100), _random.Next(100, 200)); | ||
var cloudLayouter = GetCloudLayouter(_defaultCenter); | ||
|
||
var rectangleList = rectangleSizes | ||
.Select(size => cloudLayouter.PutNextRectangle(size)); | ||
|
||
foreach (var rectangle in rectangleList) | ||
{ | ||
seenRectangles.Add(rectangle); | ||
rectangleList | ||
.Where(rect => !seenRectangles.Contains(rect)) | ||
.All(rect => rect.IntersectsWith(rectangle)) | ||
.Should().BeFalse(); | ||
AlexxSaz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
[Test] | ||
[Repeat(5)] | ||
public void PutNextRectangle_ReturnLastRectanglesWithCloseRadius_AfterManyExecution() | ||
{ | ||
var largestSide = _random.Next(100, 200); | ||
var rectangleSizes = GetSizes(_random.Next(5, 10), largestSide); | ||
var radii = new List<double>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Что такое There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. гугл сказал, что это множественное число от radius=) |
||
var circularCloudLayouter = new CircularCloudLayouter(_defaultCenter); | ||
var lastIndex = (int)(largestSide * 0.9); | ||
var expectedDifference = (int)(largestSide * 0.05); | ||
|
||
foreach (var rectangleSize in rectangleSizes) | ||
{ | ||
var currSquare = circularCloudLayouter.PutNextRectangle(rectangleSize); | ||
var squareCenter = currSquare.GetCentralPoint(); | ||
radii.Add(Math.Round(squareCenter.GetDistanceTo(_defaultCenter))); | ||
} | ||
|
||
for (var i = lastIndex; i < largestSide; i++) | ||
{ | ||
(radii[i] - radii[i - 1]).Should().BeLessOrEqualTo(expectedDifference); | ||
} | ||
} | ||
|
||
[Test] | ||
[Repeat(5)] | ||
public void PutNextRectangle_ReturnRectangleWithMaximumDensity_AfterManyExecution() | ||
{ | ||
var rectangleWidth = _random.Next(5, 1000); | ||
var rectangleSize = new Size(rectangleWidth, rectangleWidth / 2); | ||
var diagonal = Math.Sqrt(Math.Pow(rectangleSize.Height, 2) + Math.Pow(rectangleSize.Width, 2)); | ||
var circularCloudLayouter = new CircularCloudLayouter(_defaultCenter); | ||
var radii = new List<double>(); | ||
var rectangleCount = _random.Next(10, 200); | ||
|
||
for (var i = 0; i < rectangleCount; i++) | ||
{ | ||
var currSquare = circularCloudLayouter.PutNextRectangle(rectangleSize); | ||
var squareCenter = currSquare.GetCentralPoint(); | ||
radii.Add(Math.Round(squareCenter.GetDistanceTo(_defaultCenter))); | ||
} | ||
|
||
var radiusDifferences = radii | ||
.Skip(1) | ||
.Zip(radii, (current, previous) => current - previous); | ||
foreach (var difference in radiusDifferences) | ||
difference.Should().BeLessOrEqualTo(diagonal); | ||
} | ||
|
||
private static IEnumerable<Size> GetSizes(int lowest, int largest) => | ||
Enumerable.Range(lowest, largest) | ||
.Select(number => new Size(number, number / 2)) | ||
.Reverse(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System.Drawing; | ||
using FluentAssertions; | ||
using TagsCloudVisualization.Extensions; | ||
|
||
namespace TagsCloudTests; | ||
|
||
[TestFixture] | ||
[Parallelizable(scope: ParallelScope.All)] | ||
public class PointExtensionShould | ||
{ | ||
[TestCase(0, 0, 1, 2)] | ||
[TestCase(0, 0, 1, 0)] | ||
[TestCase(3, 5, 0, 5)] | ||
public void PointShiftTo_ReturnedMovedPoint_WhenSet(int pointX, int pointY, int shiftX, int shiftY) | ||
{ | ||
var point = new Point(pointX, pointY); | ||
var movementDirection = new Size(shiftX, shiftY); | ||
|
||
var movedPoint = Point.Add(point, movementDirection); | ||
|
||
MoveTo_CheckShift(point, movementDirection, movedPoint); | ||
} | ||
|
||
[Test] | ||
public void MoveTo_ReturnedNotMovedPoint_WhenSetZeroDirection() | ||
{ | ||
var point = new Point(5, 6); | ||
|
||
MoveTo_CheckShift(point, new Size(0, 0), point); | ||
} | ||
|
||
public void MoveTo_CheckShift(Point point, Size movementDirection, Point expectedPoint) | ||
AlexxSaz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
var movedPoint = point.MoveTo(movementDirection); | ||
|
||
movedPoint.Should().BeEquivalentTo(expectedPoint); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System.Drawing; | ||
using FluentAssertions; | ||
using TagsCloudVisualization; | ||
using TagsCloudVisualization.Extensions; | ||
using TagsCloudVisualization.Interfaces; | ||
|
||
namespace TagsCloudTests; | ||
|
||
[TestFixture] | ||
[Parallelizable(scope: ParallelScope.All)] | ||
public class PointGeneratorShould | ||
{ | ||
private readonly Point _defaultCenter = new(1, 1); | ||
private readonly Random _random = new(); | ||
|
||
public virtual IPointGenerator GetPointGenerator(Point center) => | ||
new SpiralPointGenerator(center); | ||
|
||
[Test] | ||
public void GetNewPoint_ReturnCenter_AfterFirstExecution() | ||
{ | ||
var pointGenerator = GetPointGenerator(_defaultCenter); | ||
var newPointIterator = pointGenerator.GeneratePoint().GetEnumerator(); | ||
AlexxSaz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
newPointIterator.MoveNext(); | ||
var point = newPointIterator.Current; | ||
|
||
point.Should().BeEquivalentTo(_defaultCenter); | ||
} | ||
|
||
[TestCase(0)] | ||
[TestCase(-1)] | ||
public void ThrowArgumentOutOfRangeException_AfterExecutionWith(double radiusStep) | ||
{ | ||
var pointGeneratorCreate = () => new SpiralPointGenerator(_defaultCenter, radiusStep); | ||
|
||
pointGeneratorCreate.Should().Throw<ArgumentOutOfRangeException>(); | ||
} | ||
|
||
[Test] | ||
[Repeat(5)] | ||
public void GetNewPoint_ReturnPointWithGreaterRadius_AfterManyExecutions() | ||
{ | ||
const double radiusStep = 0.02; | ||
const double radiusCheckPeriod = 1 / radiusStep; | ||
var newPointGenerator = new SpiralPointGenerator(_defaultCenter, radiusStep); | ||
var pointIterator = newPointGenerator.GeneratePoint().GetEnumerator(); | ||
var prevSpiralRadius = 0; | ||
var pointsCount = radiusCheckPeriod * _random.Next(10, 100); | ||
|
||
for (var i = 1; i <= pointsCount; i++) | ||
{ | ||
pointIterator.MoveNext(); | ||
var currPoint = pointIterator.Current; | ||
if (i % radiusCheckPeriod != 0) continue; | ||
var currSpiralRadius = (int)currPoint.GetDistanceTo(_defaultCenter); | ||
currSpiralRadius.Should().BeGreaterThanOrEqualTo(prevSpiralRadius); | ||
prevSpiralRadius = currSpiralRadius; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using System.Drawing; | ||
using FluentAssertions; | ||
using TagsCloudVisualization.Extensions; | ||
|
||
namespace TagsCloudTests; | ||
|
||
[TestFixture] | ||
[Parallelizable(scope: ParallelScope.All)] | ||
public class RectangleExtensionShould | ||
{ | ||
[Test] | ||
[Repeat(5)] | ||
public void GetCentralPoint_ReturnExpectedCenter_AfterExecutionWithRandomRectangle() | ||
{ | ||
var rectangleLocation = new Point(0, 0); | ||
var random = new Random(); | ||
var rectangleSize = new Size(random.Next(1, 100), random.Next(1, 100)); | ||
var rectangle = new Rectangle(rectangleLocation, rectangleSize); | ||
var expectedCentralPoint = new Point(rectangleLocation.X + rectangleSize.Width / 2, | ||
rectangleLocation.Y - rectangleSize.Height / 2); | ||
|
||
rectangle.GetCentralPoint().Should().Be(expectedCentralPoint); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System.Drawing; | ||
using FluentAssertions; | ||
using TagsCloudVisualization; | ||
|
||
namespace TagsCloudTests; | ||
|
||
[TestFixture] | ||
[Parallelizable(ParallelScope.All)] | ||
public class TagCloudCreatorShould | ||
{ | ||
private readonly Point _defaultCenter = new(0, 0); | ||
private readonly Random _random = new(); | ||
|
||
[Test] | ||
[Repeat(5)] | ||
public void Create_ReturnTagCloudEquivalentToConstructor_AfterExecution() | ||
{ | ||
var rectangleSizes = Enumerable.Range(_random.Next(2, 10), _random.Next(20, 100)). | ||
Select(width => new Size(width, width / 2)).Reverse(); | ||
var currCloudLayouter = new CircularCloudLayouter(_defaultCenter); | ||
var expectedCloudLayouter = new CircularCloudLayouter(_defaultCenter); | ||
var defaultTagCloud = new TagCloud(currCloudLayouter); | ||
foreach (var rectangleSize in rectangleSizes) | ||
defaultTagCloud.AddNextRectangleWith(rectangleSize); | ||
|
||
var expectedTagCloud = TagCloudCreator.Create(rectangleSizes, expectedCloudLayouter); | ||
AlexxSaz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
defaultTagCloud.Should().BeEquivalentTo(expectedTagCloud); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Не нашел тестов на :
Если такие есть, отпиши в этом комменте их названия и логику работы. Потому что те, что я нашел, как будто не проверяют все эти требования
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Переписал тесты. В новых коммитах:
тест PutNextRectangle_ReturnRectanglesInCircle_AfterManyExecution проверяет, что сумма площади всех прямоугольников примерно равна площади окружности, в которой прямоугольники находятся. А также, что расстояние от каждого прямоугольника до центра лейаута меньше, чем радиус окружности. Этот тест говорит о том, что форма облака - окружность, а также, что облако максимально плотное.
тест PutNextRectangle_ReturnRectangleThatNotIntersectsWithOther_AfterManyExecution проверяет, что каждый из прямоугольников на лейауте не пересекается со всеми остальными прямоугольниками, кроме себя самого.