Skip to content
Merged
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
143 changes: 143 additions & 0 deletions .github/workflows/dotnet-desktop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: .NET Tests & Auto-commit

on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches-ignore: [main]
workflow_dispatch:

permissions:
contents: write
pull-requests: write
issues: read

jobs:

check-target:
runs-on: ubuntu-latest
outputs:
pr_valid: ${{ steps.check.outputs.pr_valid }}
steps:
- name: 🚫 Проверка PR в main
id: check
shell: bash
run: |
PR_BASE="${{ github.event.pull_request.base.ref }}"
echo "Base branch: $PR_BASE"
if [ "$PR_BASE" = "main" ]; then
echo "❌ Нельзя отправлять работу в main ветку."
echo "pr_valid=false" >> $GITHUB_OUTPUT
exit 1
else
echo "✅ PR направлен в '$PR_BASE', можно запускать тесты."
echo "pr_valid=true" >> $GITHUB_OUTPUT
fi

tests:
name: Run test
runs-on: windows-latest
needs: check-target
if: |
(github.event_name == 'pull_request' && needs.check-target.outputs.pr_valid == 'true') ||
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch'
strategy:
matrix:
configuration: [Debug]

steps:
- name: Checkout code safely
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.sha || github.ref }}
fetch-depth: 0

- name: Install .NET Core
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
9.0.x

- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v2

- name: Restore
run: dotnet restore Lab9/Lab9.sln

- name: Build
run: dotnet build Lab9/Lab9.sln --configuration ${{ matrix.configuration }} --no-restore

- name: Run tests (league cascade)
id: cascade
shell: pwsh
env:
CFG: ${{ matrix.configuration }}
run: |
$testProjectPath = "Lab9Test/Lab9Test.csproj"
$testDir = "Lab9Test"

Write-Host "Building test project..."
dotnet build $testProjectPath -c $Env:CFG --no-restore

$tfm = (dotnet list $testProjectPath framework --framework net9.0 | Select-Object -Last 1).Trim()
if (-not $tfm) { $tfm = "net9.0" }

$dll = Join-Path $PWD "$testDir\bin\$Env:CFG\$tfm\Lab9Test.dll"

Write-Host "Ожидаемая DLL: $dll"

if (-not (Test-Path $dll)) {
Write-Error "DLL не найдена: $dll"
Write-Host "`nСодержимое bin папки:"
Get-ChildItem "$testDir\bin" -Recurse -ErrorAction SilentlyContinue |
Select-Object FullName | Out-Host
exit 1
}

Write-Host "DLL успешно найдена`n"

$leagues = @{
"Purple" = @("Task1","Task2","Task3","Task4")
"Blue" = @("Task1","Task2","Task3","Task4")
"Green" = @("Task1","Task2","Task3","Task4")
"White" = @("Task1","Task2","Task3","Task4")
}

foreach ($leagueName in $leagues.Keys) {
Write-Host "Лига: $leagueName"
$allPassed = $true

foreach ($cls in $leagues[$leagueName]) {
$filter = "FullyQualifiedName~$leagueName.$cls"
Write-Host " Запуск: $leagueName.$cls"

dotnet vstest $dll --TestCaseFilter:"$filter" --Logger:"trx;LogFileName=test-$leagueName-$cls.trx"

if ($LASTEXITCODE -ne 0) {
Write-Host " ❌ $leagueName.$cls не прошёл" -ForegroundColor Red
$allPassed = $false
} else {
Write-Host " ✅ $leagueName.$cls прошёл" -ForegroundColor Green
}
}

if ($allPassed) {
Write-Host "✅ Все тесты лиги $leagueName прошли! Останавливаем каскад." -ForegroundColor Green
exit 0
} else {
Write-Host "⚠️ Лига $leagueName не прошла полностью. Переходим к следующей..." -ForegroundColor Yellow
}
}

Write-Host "❌ Ни одна лига полностью не прошла." -ForegroundColor Red
exit 1

- name: Upload TRX
if: always()
uses: actions/upload-artifact@v4
with:
name: trx-${{ matrix.configuration }}
path: '**/test-*.trx'
11 changes: 11 additions & 0 deletions Lab9/Blue/Blue.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
namespace Lab9.Blue
{
public abstract class Blue
{
public string Input { get; protected set; }
protected Blue(string input) => Input = input;
public abstract void Review();
public virtual void ChangeText(string text)
{
Input = text;
Review();
}
}
}
62 changes: 62 additions & 0 deletions Lab9/Blue/Task1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace Lab9.Blue
{
public class Task1 : Blue
{
public Task1(string input) : base(input) {}
public string[] Output { get; protected set; }
public override void Review()
{
if (Input == null)
{
Output = null;
return;
}
string[] words = Input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
string current = "";
int count = 0;
foreach (var i in words)
{
if (current.Length == 0)
{
current += i;
}
else if (current.Length != 0 && current.Length + 1 + i.Length <= 50)
{
current += " " + i;
}
else
{
count++;
current = i;
}
}
if (current.Length > 0) count++;

Output = new string[count];
int ind = 0;
current = "";
foreach (var i in words)
{
if (current.Length == 0)
{
current += i;
}
else if (current.Length + 1 + i.Length <= 50)
{
current += " " + i;
}
else
{
Output[ind++] = current;
current = i;
}
}
if (current.Length > 0) Output[ind] = current;
}
public override string ToString()
{
return string.Join(Environment.NewLine, Output);
}

}
}
90 changes: 90 additions & 0 deletions Lab9/Blue/Task2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
namespace Lab9.Blue
{
public class Task2 : Blue
{
private string _sequence;

public Task2(string input, string sequence) : base(input)
{
_sequence = sequence;
}
public string Output { get; private set; }
public override string ToString() => Output ?? "";
public override void Review()
{
if (Input == null || _sequence == null)
{
Output = Input;
return;
}
string[] parts = Input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
int length = 0;
foreach (string part in parts)
{
int start = 0;
while (start < part.Length && !IsWordChar(part[start]))
start++;
int end = part.Length - 1;
while (end >= 0 && !IsWordChar(part[end]))
end--;
if (start > end)
{
length++;
continue;
}

string prefix = part.Substring(0, start);
string word = part.Substring(start, end - start + 1);
string suffix = part.Substring(end + 1);

if (word.Contains(_sequence, StringComparison.OrdinalIgnoreCase))
{
string newPart = prefix + suffix;
if (newPart.Length > 0) length++;
}
else length++;
}

string[] result = new string[length];
int ind = 0;
foreach (string part in parts)
{
int start = 0;
while (start < part.Length && !IsWordChar(part[start]))
start++;
int end = part.Length - 1;
while (end >= 0 && !IsWordChar(part[end]))
end--;
if (start > end)
{
result[ind++] = part;
continue;
}

string prefix = part.Substring(0, start);
string word = part.Substring(start, end - start + 1);
string suffix = part.Substring(end + 1);

if (word.Contains(_sequence, StringComparison.OrdinalIgnoreCase))
{
string newPart = prefix + suffix;
if (newPart.Length > 0) result[ind++] = newPart;
}
else result[ind++] = part;
}

Output = String.Join(" ", result);
Output = Output.Replace(" .", ".");
Output = Output.Replace(" ,", ",");
Output = Output.Replace(" !", "!");
Output = Output.Replace(" ?", "?");
Output = Output.Replace(" :", ":");
Output = Output.Replace(" ;", ";");
}
private bool IsWordChar(char c)
{
return char.IsLetter(c) || c == '-' || c == '\'';
}

}
}
Loading
Loading