-
Notifications
You must be signed in to change notification settings - Fork 32
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
Зайцев ДА #28
base: master
Are you sure you want to change the base?
Зайцев ДА #28
Changes from 17 commits
8ef5f53
97d8e0b
5699f10
d5a233b
321858b
3053fe8
d66cb7a
3696e60
23f4ab1
3177d5b
235f958
03f49dd
f227cdb
474eff0
c36e741
d658b56
5ee9f76
21bd13b
ea1627e
265b25c
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,64 @@ | ||
using McMaster.Extensions.CommandLineUtils; | ||
using Autofac; | ||
using TagsCloudContainer; | ||
|
||
public class ConsoleClient | ||
{ | ||
[Option("--input", "Path to the input file.", CommandOptionType.SingleValue)] | ||
public string? InputDirectory { get; set; } | ||
|
||
[Option("--output", "Path to the output file.", CommandOptionType.SingleValue)] | ||
public string? OutputDirectory { get; set; } | ||
|
||
[Option("--width", "Width of the picture.", CommandOptionType.SingleValue)] | ||
public int PictureWidth { get; set; } | ||
|
||
[Option("--height", "Height of the picture.", CommandOptionType.SingleValue)] | ||
public int PictureHeight { get; set; } | ||
|
||
[Option("--font", "Font for the picture text.", CommandOptionType.SingleValue)] | ||
public string? Font { get; set; } | ||
|
||
[Option("--stopwords", "Comma-separated list of stop words.", CommandOptionType.SingleValue)] | ||
public string? StopWordsInput { get; set; } | ||
|
||
[Option("--rightwords", "Comma-separated list of right words.", CommandOptionType.SingleValue)] | ||
public string? RightWordsInput { get; set; } | ||
|
||
[Option("--colors", "Comma-separated list of colors in ARGB format (e.g., 255,0,0,255).", CommandOptionType.SingleValue)] | ||
public string? ColorsInput { get; set; } | ||
|
||
public static int Main(string[] args) | ||
{ | ||
return RunConsoleClient(args); | ||
} | ||
|
||
private static int RunConsoleClient(string[] args) | ||
{ | ||
return CommandLineApplication.Execute<ConsoleClient>(args); | ||
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. Тут нужно было разделить класс на два:
В целом, можно было вынести только настройки и свойства в отдельный класс и уже было бы сильно хорошо Зачем это делать? Две ответственности: про запуск приложения и про логику непосредственно приложения. Например, на консольный клиент может захотеться написать тест. В текущем виде он неразрывен от метода Main, что будет неправильно затаскивать в тесты |
||
} | ||
|
||
private void OnExecute() | ||
{ | ||
var config = new Config( | ||
InputDirectory ?? Constants.InputDirectory, | ||
OutputDirectory ?? Constants.OutputDirectory, | ||
PictureWidth == default ? Constants.PictureWidth : PictureWidth, | ||
PictureHeight == default ? Constants.PictureHeight : PictureHeight, | ||
Font ?? Constants.Font, | ||
StopWordsInput?.Split(',').Select(x => x.ToLower()).ToArray() ?? Constants.StopWords, | ||
RightWordsInput?.Split(',').Select(x => x.ToLower()).ToArray() ?? Constants.RightWords, | ||
ColorsInput?.Split(',') ?? Constants.PictureColors | ||
); | ||
|
||
var container = ApplicationRunner.BuildContainer(config); | ||
|
||
using var scope = container.BeginLifetimeScope(); | ||
var runner = scope.Resolve<IApplicationRunner>(); | ||
runner.Run(); | ||
} | ||
|
||
|
||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0-windows</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.1.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\TagsCloudContainer\TagsCloudContainer.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
using FluentAssertions; | ||
using NUnit.Framework.Interfaces; | ||
using System.Drawing; | ||
using TagsCloudContainer; | ||
using TagsCloudContainer.Layouters; | ||
using TagsCloudContainer.Visualizers; | ||
using TagsCloudContainer.WordClasses; | ||
|
||
namespace TagCloudContainerTests; | ||
|
||
[TestFixture] | ||
public class CircularCloudLayouterTests | ||
{ | ||
|
||
private CircularCloudLayouter layouter; | ||
private Config config; | ||
private IVisualizer visualizer; | ||
|
||
private readonly string text = "text"; | ||
private readonly Font font = new("Arial", 15); | ||
|
||
[SetUp] | ||
public void Setup() | ||
{ | ||
config = new Config(); | ||
layouter = new CircularCloudLayouter(config); | ||
visualizer = new ImageVisualizer(config); | ||
} | ||
|
||
[TearDown] | ||
public void Teardown() | ||
{ | ||
var testResult = TestContext.CurrentContext.Result.Outcome; | ||
var testName = TestContext.CurrentContext.Test.Name; | ||
if (Equals(testResult, ResultState.Failure) || | ||
Equals(testResult == ResultState.Error)) | ||
{ | ||
var drawer = visualizer; | ||
var directory = Path.Combine(Constants.ProjectDirectory, $"FailedTestTagCloud.{testName}.jpeg"); | ||
config.OutputDirectory = directory; | ||
drawer.GenerateImage(layouter.Rectangles); | ||
Console.WriteLine($"Tag cloud visualization saved to file {directory}"); | ||
} | ||
} | ||
|
||
private SizeWord GetDefaultSizeWord(Size size) | ||
{ | ||
return new SizeWord(text, size, font); | ||
} | ||
|
||
[Test] | ||
public void CircularCloudLayouter_Constructor_CorrectlySetCenter() | ||
{ | ||
layouter.GetLayout([]); | ||
|
||
layouter.Center | ||
.Should() | ||
.Be(new Point(config.PictureWidth / 2, config.PictureHeight / 2)); | ||
} | ||
|
||
[Test] | ||
public void PutNextRectangle_PlacesFirstRectangleToCenter() | ||
{ | ||
var size = new Size(50, 50); | ||
|
||
var rectangles = layouter.GetLayout([GetDefaultSizeWord(size)]); | ||
var centerRecLocation = CircularCloudLayouter. | ||
GetCornerPoint(layouter.Center, size); | ||
|
||
rectangles | ||
.First() | ||
.Bounds | ||
.Location | ||
.Should() | ||
.Be(centerRecLocation); | ||
} | ||
|
||
[Test] | ||
public void PutNextRectangle_RectanglesDoesNotIntersect() | ||
{ | ||
var sizeList = new List<SizeWord>(); | ||
|
||
for (int i = 10; i < 100; i += 10) | ||
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. Снова про явные типы и var |
||
for (int j = 5; j < 50; j += 5) | ||
sizeList.Add(GetDefaultSizeWord(new Size(i, j))); | ||
|
||
var rectangles = layouter.GetLayout(sizeList); | ||
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. Не используется |
||
var length = layouter.Rectangles.Count; | ||
for (int i = 0; i < length - 1; i++) | ||
for (int j = 0; j < length - 1; j++) | ||
{ | ||
if (i != j) | ||
layouter.Rectangles[i] | ||
.Bounds | ||
.IntersectsWith(layouter.Rectangles[j].Bounds) | ||
.Should().BeFalse(); | ||
} | ||
} | ||
|
||
[Test] | ||
public void PutNextRectangle_IncreaseDistanceFromCenter_WithMoreRectangles() | ||
{ | ||
var sizeList = new List<SizeWord> | ||
{ | ||
GetDefaultSizeWord(new Size(20,10)) | ||
}; | ||
|
||
for (int i = 10; i < 100; i += 10) | ||
for (int j = 10; j < 50; j += 10) | ||
sizeList.Add(GetDefaultSizeWord(new Size(i, j))); | ||
sizeList.Add(GetDefaultSizeWord(new (20, 30))); | ||
|
||
var rectangles = layouter.GetLayout(sizeList); | ||
var firstRectangle = rectangles.First(); | ||
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. Не исправлено |
||
var lastRectangle = rectangles.Last(); | ||
|
||
var firstDistance = FindDistance(layouter.Center, firstRectangle.Bounds.Location); | ||
var lastDistance = FindDistance(layouter.Center, lastRectangle.Bounds.Location); | ||
|
||
lastDistance.Should().BeGreaterThan(firstDistance); | ||
} | ||
|
||
private double FindDistance(Point r1, Point r2) | ||
{ | ||
return Math.Sqrt(Math.Pow(r2.X - r1.X, 2) + Math.Pow(r2.Y - r1.Y, 2)); | ||
} | ||
|
||
[Test] | ||
public void PutNextRectangle_ShouldPlaceRectanglesInSpiral() | ||
{ | ||
var sizeList = new List<SizeWord> | ||
{ | ||
GetDefaultSizeWord(new Size(10,10)), | ||
GetDefaultSizeWord(new Size(10,10)), | ||
GetDefaultSizeWord(new Size(10,10)), | ||
GetDefaultSizeWord(new Size(10,10)), | ||
GetDefaultSizeWord(new Size(10,10)) | ||
}; | ||
|
||
var rectangles = layouter.GetLayout(sizeList); | ||
var firstRectangle = rectangles.First().Bounds; | ||
|
||
CircularCloudLayouter.GetCenterPoint(firstRectangle).Should().Be(layouter.Center); | ||
for (int i = 1; i < 4; i++) | ||
{ | ||
var rect = layouter.Rectangles[i]; | ||
FindDistance(firstRectangle.Location, rect.Bounds.Location).Should().BeLessThan(30); | ||
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. А как этот тест доказывает, что прямоугольники расположены по спирали? |
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using TagsCloudContainer.FileReaders; | ||
|
||
namespace TagCloudContainerTests; | ||
|
||
[TestFixture] | ||
public class FileReadTest | ||
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. Предлагаю такие тяжелые тесты запускать в параллель |
||
{ | ||
private static readonly VerifySettings Settings = new(); | ||
private IReader Reader; | ||
private string FolderPath; | ||
|
||
[SetUp] | ||
public void Setup() | ||
{ | ||
Settings.UseDirectory("Snapshots"); | ||
var projectDirectory = | ||
Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\")); | ||
FolderPath = Path.Combine(projectDirectory, "Files"); | ||
} | ||
|
||
[Test] | ||
[Parallelizable(ParallelScope.Self)] | ||
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 Task Reader_TxtReading() | ||
{ | ||
Reader = new TxtFileReader(); | ||
|
||
var filePath = Path.Combine(FolderPath, "wordsTXT.txt"); | ||
var actual = Reader.Read(filePath); | ||
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. Давай разделять пустыми строками блоки |
||
|
||
return Verify(actual, Settings); | ||
} | ||
|
||
[Test] | ||
[Parallelizable(ParallelScope.Self)] | ||
public Task Reader_DocxReading() | ||
{ | ||
Reader = new DocxFileReader(); | ||
|
||
var filePath = Path.Combine(FolderPath, "wordsDOCX.docx"); | ||
var actual = Reader.Read(filePath); | ||
|
||
return Verify(actual, Settings); | ||
} | ||
|
||
[Test] | ||
[Parallelizable(ParallelScope.Self)] | ||
public Task Reader_DocReading() | ||
{ | ||
Reader = new DocFileReader(); | ||
|
||
var filePath = Path.Combine(FolderPath, "wordsDOC.doc"); | ||
var actual = Reader.Read(filePath); | ||
|
||
return Verify(actual, Settings); | ||
} | ||
} |
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.
Хочется в репозитории иметь примеры генерации изображений твоим кодом. Чтобы наглядно видеть про изменения размеров и так далее. Хотя бы тестах