Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NullElements/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.cs]

# SA1600: Elements should be documented
dotnet_diagnostic.SA1600.severity = none

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это стоило выключать только для тестов, для всего проекта не надо

39 changes: 39 additions & 0 deletions NullElements/NullElements.Tests/NullElements.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<None Remove="stylecop.json" />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit.Analyzers" Version="4.4.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NullElements\NullElements.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>

</Project>
108 changes: 108 additions & 0 deletions NullElements/NullElements.Tests/NullElementsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// <copyright file="NullElementsTests.cs" company="Kalinin Andrew">
// Copyright (c) Kalinin Andrew. All rights reserved.
// </copyright>

namespace NullElements.Tests

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Используйте file-scoped namespaces, так сейчас не пишут уже

{
public class NullElementsTests
{
[Test]
public void Add_NumberToEmptyList_ShouldIncreaseCountByOne()
{
var testList = new MyList<int>();
testList.Add(5);

Assert.That(testList.Count, Is.EqualTo(1));
}

[Test]
public void Add_Overflow_ShouldDoubleInternalArraySize()
{
var testList = new MyList<int>();
var initialCapacity = 10;
for (int i = 0; i < initialCapacity + 1; ++i)
{
testList.Add(i);
}

Assert.That(testList.Count, Is.EqualTo(11));
}

[Test]
public void GetEnumerator_ValidData_ShouldIterateInCorrectOrder()
{
var testList = new MyList<int>();
testList.Add(1);
testList.Add(2);

var result = new System.Collections.Generic.List<int>();
foreach (var item in testList)
{
result.Add(item);
}

Assert.That(result, Is.EqualTo(new[] { 1, 2 }));
}

[Test]
public void GetEnumerator_WhenListIsEmpty_ShouldNotIterate()
{
var testList = new MyList<string>();

var iterations = 0;
foreach (var item in testList)
{
iterations++;
}

Assert.That(iterations, Is.EqualTo(0));
}

[Test]
public void CountNulls_String_ShouldReturnCorrectCount()
{
var testList = new MyList<string>();
testList.Add("hello");
testList.Add(null);

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-windows

Cannot convert null literal to non-nullable reference type.

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-windows

Cannot convert null literal to non-nullable reference type.

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu

Cannot convert null literal to non-nullable reference type.

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu

Cannot convert null literal to non-nullable reference type.

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu

Cannot convert null literal to non-nullable reference type.

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu

Cannot convert null literal to non-nullable reference type.

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-windows

Cannot convert null literal to non-nullable reference type.

Check warning on line 66 in NullElements/NullElements.Tests/NullElementsTests.cs

View workflow job for this annotation

GitHub Actions / build-windows

Cannot convert null literal to non-nullable reference type.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут стоило явно заглушить предупреждения nullability, хотя бы с помощью оператора !. Потому что собираться должно без предупреждений.

testList.Add(string.Empty);
testList.Add("world");

var result = Counter.CountNulls(testList, new StringNullChecker());

Assert.That(result, Is.EqualTo(2));
}

[Test]
public void CountNulls_Int_ShouldReturnCorrectCountZeros()
{
var testList = new MyList<int>();
testList.Add(0);
testList.Add(1);
testList.Add(0);

var result = Counter.CountNulls(testList, new IntNullChecker());

Assert.That(result, Is.EqualTo(2));
}

[Test]
public void CountNulls_WhenIntListIsEmpty_ShouldReturnZero()
{
var testList = new MyList<int>();

var result = Counter.CountNulls(testList, new IntNullChecker());

Assert.That(result, Is.EqualTo(0));
}

[Test]
public void CountNulls_WhenStringListIsEmpty_ShouldReturnZero()
{
var testList = new MyList<string>();

var result = Counter.CountNulls(testList, new StringNullChecker());

Assert.That(result, Is.EqualTo(0));
}
}
}
15 changes: 15 additions & 0 deletions NullElements/NullElements.Tests/stylecop.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// ACTION REQUIRED: This file was automatically added to your project, but it
// will not take effect until additional steps are taken to enable it. See the
// following page for additional information:
Comment on lines +2 to +4

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут говорится, что надо конфигурацию применить и удалить этот комментарий

//
// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md

"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "Kalinin Andrew",
"copyrightText": "Copyright (c) {companyName}. All rights reserved."
}
}
}
36 changes: 36 additions & 0 deletions NullElements/NullElements.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35806.99 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NullElements", "NullElements\NullElements.csproj", "{2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NullElements.Tests", "NullElements.Tests\NullElements.Tests.csproj", "{1AE28732-923A-4DDE-BE64-28751F09CC28}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36D591C7-65C7-A0D1-1CBC-10CDE441BDC8}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2BA0FF1E-3004-4D5F-A36F-9E7122EE2145}.Release|Any CPU.Build.0 = Release|Any CPU
{1AE28732-923A-4DDE-BE64-28751F09CC28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1AE28732-923A-4DDE-BE64-28751F09CC28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1AE28732-923A-4DDE-BE64-28751F09CC28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1AE28732-923A-4DDE-BE64-28751F09CC28}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {979D0980-DB24-4BC7-909D-644F6A87E14F}
EndGlobalSection
EndGlobal
45 changes: 45 additions & 0 deletions NullElements/NullElements/Counter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// <copyright file="Counter.cs" company="Kalinin Andrew">
// Copyright (c) Kalinin Andrew. All rights reserved.
// </copyright>

namespace NullElements
{
/// <summary>
/// Provides utility methods for working with collections.
/// </summary>
public static class Counter
{
/// <summary>
/// Counts elements that match null-equivalent conditions.
/// </summary>
/// <typeparam name="T">The type of elements in the list.</typeparam>
/// <param name="list">The collection to inspect.</param>
/// <param name="checker">The null-equivalence checker implementation.</param>
/// <returns>The number of null-equivalent elements.</returns>
/// <exception cref="ArgumentNullException">Thrown when list or checker is null.</
public static int CountNulls<T>(MyList<T> list, ICheckNulls<T> checker)
{
if (list == null)
{
throw new ArgumentNullException(nameof(list));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArgumentNullException.ThrowIfNull

}

if (checker == null)
{
throw new ArgumentNullException(nameof(checker));
}

int count = 0;

foreach (var item in list)
{
if (checker.IsNull(item))
{
count++;
}
}

return count;
}
}
}
20 changes: 20 additions & 0 deletions NullElements/NullElements/ICheckNulls.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// <copyright file="ICheckNulls.cs" company="Kalinin Andrew">
// Copyright (c) Kalinin Andrew. All rights reserved.
// </copyright>

namespace NullElements
{
/// <summary>
/// Interface for checking if elements meet null-equivalent conditions.
/// </summary>
/// <typeparam name="T">The type of elements to check.</typeparam>
public interface ICheckNulls<T>
{
/// <summary>
/// Determines if an item should be considered null-equivalent.
/// </summary>
/// <param name="item">The item to check.</param>
/// <returns>True if the item is considered null-equivalent, otherwise False.</returns>
bool IsNull(T item);
}
}
19 changes: 19 additions & 0 deletions NullElements/NullElements/IntNullChecker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// <copyright file="IntNullChecker.cs" company="Kalinin Andrew">
// Copyright (c) Kalinin Andrew. All rights reserved.
// </copyright>

namespace NullElements
{
/// <summary>
/// Null-equivalence checker for integer values.
/// </summary>
public class IntNullChecker : ICheckNulls<int>
{
/// <summary>
/// Determines if an integer is zero.
/// </summary>
/// <param name="item">The integer to check.</param>
/// <returns>True if the value is zero, otherwise False.</returns>
public bool IsNull(int item) => item == 0;
}
}
59 changes: 59 additions & 0 deletions NullElements/NullElements/MyList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// <copyright file="MyList.cs" company="Kalinin Andrew">
// Copyright (c) Kalinin Andrew. All rights reserved.
// </copyright>

using System.Collections;

/// <summary>
/// Custom generic list implementation with dynamic resizing.
/// </summary>
/// <typeparam name="T">The type of elements in the list.</typeparam>
public class MyList<T> : IEnumerable<T>
{
private T[] items;

private int count;

/// <summary>
/// Initializes a new instance of the <see cref="MyList{T}"/> class.
/// </summary>
public MyList()
{
this.items = new T[4];
this.count = 0;
}

public int Count => this.count;

/// <summary>
/// Adds an item to the end of the list.
/// </summary>
/// <param name="item">The item to add.</param>
public void Add(T item)
{
if (this.count == this.items.Length)
{
Array.Resize(ref this.items, this.items.Length == 0 ? 10 : this.items.Length * 2);
}

this.items[this.count] = item;
this.count++;
}

/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>An enumerator for the list.</returns>
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < this.count; ++i)
{
yield return this.items[i];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так оно не будет проверять на то, что список не поменялся. Можно было просто запомнить count в локальной переменной и на каждой итерации сравнивать её с текущим count

}
}

IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использовали бы =>

}
25 changes: 25 additions & 0 deletions NullElements/NullElements/NullElements.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<None Remove="stylecop.json" />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
13 changes: 13 additions & 0 deletions NullElements/NullElements/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// <copyright file="Program.cs" company="Kalinin Andrew">
// Copyright (c) Kalinin Andrew. All rights reserved.
// </copyright>

using NullElements;

var intList = new MyList<int>();
intList.Add(0);
intList.Add(0);
intList.Add(0);
intList.Add(0);

Console.WriteLine(Counter.CountNulls(intList, new IntNullChecker()));
Loading
Loading