mirror of https://github.com/ErsatzTV/ErsatzTV.git
33 changed files with 14167 additions and 74 deletions
@ -0,0 +1,34 @@ |
|||||||
|
using ErsatzTV.Core.Interfaces.Scheduling; |
||||||
|
using ErsatzTV.Core.Scheduling; |
||||||
|
using NSubstitute; |
||||||
|
using NUnit.Framework; |
||||||
|
using Shouldly; |
||||||
|
|
||||||
|
namespace ErsatzTV.Core.Tests.Scheduling; |
||||||
|
|
||||||
|
[TestFixture] |
||||||
|
public class CountExpressionTests |
||||||
|
{ |
||||||
|
[Test] |
||||||
|
[TestCase("2", 2)] |
||||||
|
[TestCase("count", 10)] |
||||||
|
[TestCase("count / 2", 5)] |
||||||
|
[TestCase("count * 2", 20)] |
||||||
|
[TestCase("count + 1", 11)] |
||||||
|
[TestCase("count - 1", 9)] |
||||||
|
[TestCase("random % 4 + 1", 3)] |
||||||
|
[TestCase("invalid", 0)] |
||||||
|
[TestCase("count / 0", 0)] |
||||||
|
public void Should_Evaluate_Expression(string expression, int expected) |
||||||
|
{ |
||||||
|
var enumerator = Substitute.For<IMediaCollectionEnumerator>(); |
||||||
|
enumerator.Count.Returns(10); |
||||||
|
|
||||||
|
var random = Substitute.For<Random>(); |
||||||
|
random.Next().Returns(2); |
||||||
|
|
||||||
|
int result = CountExpression.Evaluate(expression, enumerator, random, CancellationToken.None); |
||||||
|
|
||||||
|
result.ShouldBe(expected); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
using ErsatzTV.Core.Interfaces.Scheduling; |
||||||
|
using NCalc; |
||||||
|
|
||||||
|
namespace ErsatzTV.Core.Scheduling; |
||||||
|
|
||||||
|
public static class CountExpression |
||||||
|
{ |
||||||
|
public static int Evaluate( |
||||||
|
string countExpression, |
||||||
|
IMediaCollectionEnumerator enumerator, |
||||||
|
Random random, |
||||||
|
CancellationToken cancellationToken) |
||||||
|
{ |
||||||
|
int enumeratorCount = enumerator is PlaylistEnumerator playlistEnumerator |
||||||
|
? playlistEnumerator.CountForRandom |
||||||
|
: enumerator.Count; |
||||||
|
var expression = new Expression(countExpression); |
||||||
|
expression.EvaluateParameter += (name, e) => |
||||||
|
{ |
||||||
|
e.Result = name switch |
||||||
|
{ |
||||||
|
"count" => enumeratorCount, |
||||||
|
"random" => enumeratorCount > 0 ? random.Next() % enumeratorCount : 0, |
||||||
|
_ => e.Result |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
object expressionResult = 0; |
||||||
|
try |
||||||
|
{ |
||||||
|
expressionResult = expression.Evaluate(cancellationToken); |
||||||
|
} |
||||||
|
catch (Exception) |
||||||
|
{ |
||||||
|
// do nothing
|
||||||
|
} |
||||||
|
|
||||||
|
return expressionResult switch |
||||||
|
{ |
||||||
|
double d when double.IsInfinity(d) || double.IsNaN(d) => 0, |
||||||
|
double doubleResult => (int)Math.Floor(doubleResult), |
||||||
|
int intResult => intResult, |
||||||
|
long longResult => (int)longResult, |
||||||
|
_ => 0 |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@ |
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||||
|
|
||||||
|
#nullable disable |
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.MySql.Migrations |
||||||
|
{ |
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Change_ProgramScheduleItemMultipleCountString : Migration |
||||||
|
{ |
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||||
|
{ |
||||||
|
migrationBuilder.AlterColumn<string>( |
||||||
|
name: "Count", |
||||||
|
table: "ProgramScheduleMultipleItem", |
||||||
|
type: "longtext", |
||||||
|
nullable: true, |
||||||
|
oldClrType: typeof(int), |
||||||
|
oldType: "int") |
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"); |
||||||
|
} |
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||||
|
{ |
||||||
|
migrationBuilder.AlterColumn<int>( |
||||||
|
name: "Count", |
||||||
|
table: "ProgramScheduleMultipleItem", |
||||||
|
type: "int", |
||||||
|
nullable: false, |
||||||
|
defaultValue: 0, |
||||||
|
oldClrType: typeof(string), |
||||||
|
oldType: "longtext", |
||||||
|
oldNullable: true) |
||||||
|
.OldAnnotation("MySql:CharSet", "utf8mb4"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@ |
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||||
|
|
||||||
|
#nullable disable |
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.Sqlite.Migrations |
||||||
|
{ |
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Change_ProgramScheduleItemMultipleCountString : Migration |
||||||
|
{ |
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||||
|
{ |
||||||
|
migrationBuilder.AlterColumn<string>( |
||||||
|
name: "Count", |
||||||
|
table: "ProgramScheduleMultipleItem", |
||||||
|
type: "TEXT", |
||||||
|
nullable: true, |
||||||
|
oldClrType: typeof(int), |
||||||
|
oldType: "INTEGER"); |
||||||
|
} |
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||||
|
{ |
||||||
|
migrationBuilder.AlterColumn<int>( |
||||||
|
name: "Count", |
||||||
|
table: "ProgramScheduleMultipleItem", |
||||||
|
type: "INTEGER", |
||||||
|
nullable: false, |
||||||
|
defaultValue: 0, |
||||||
|
oldClrType: typeof(string), |
||||||
|
oldType: "TEXT", |
||||||
|
oldNullable: true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue