Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Added Tests
  • Loading branch information
michaelstaib committed Jul 1, 2024
commit f00e0f3d649aaeb809c151ef41c648f0a8f3660a
8 changes: 7 additions & 1 deletion src/HotChocolate/Core/src/Abstractions/Executable~1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,34 @@ namespace HotChocolate;
/// </typeparam>
public abstract class Executable<T> : IExecutable<T>
{
/// <inheritdoc />
public abstract object Source { get; }

/// <inheritdoc />
public abstract ValueTask<T?> FirstOrDefaultAsync(CancellationToken cancellationToken = default);

async ValueTask<object?> IExecutable.FirstOrDefaultAsync(CancellationToken cancellationToken)
=> await FirstOrDefaultAsync(cancellationToken);


/// <inheritdoc />
public abstract ValueTask<T?> SingleOrDefaultAsync(CancellationToken cancellationToken = default);

async ValueTask<object?> IExecutable.SingleOrDefaultAsync(CancellationToken cancellationToken)
=> await SingleOrDefaultAsync(cancellationToken);

/// <inheritdoc />
public abstract ValueTask<List<T>> ToListAsync(CancellationToken cancellationToken = default);

async ValueTask<IList> IExecutable.ToListAsync(CancellationToken cancellationToken)
=> await ToListAsync(cancellationToken);

/// <inheritdoc />
public virtual string Print() => Source.ToString() ?? Source.GetType().FullName ?? Source.GetType().Name;

/// <inheritdoc />
public sealed override string ToString() => Print();

/// <inheritdoc />
public abstract IAsyncEnumerable<T> ToAsyncEnumerable(CancellationToken cancellationToken = default);

async IAsyncEnumerable<object?> IExecutable.ToAsyncEnumerable(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

namespace HotChocolate;

public static class AsyncEnumerableExecutableTests
{
[Fact]
public static async Task EmptyAsyncEnumerable_FirstOrDefault_Null()
{
// arrange
IAsyncEnumerable<string> query = new EmptyAsyncEnumerable();

// act
var result = await Executable.From(query).FirstOrDefaultAsync();

// assert
Assert.Null(result);
}

[Fact]
public static async Task ListAsyncEnumerable_FirstOrDefault_A()
{
// arrange
IAsyncEnumerable<string> query = new ListAsyncEnumerable(["a", "b"]);

// act
var result = await Executable.From(query).FirstOrDefaultAsync();

// assert
Assert.Equal("a", result);
}

[Fact]
public static async Task EmptyAsyncEnumerable_SingleOrDefault_Null()
{
// arrange
IAsyncEnumerable<string> query = new EmptyAsyncEnumerable();

// act
var result = await Executable.From(query).FirstOrDefaultAsync();

// assert
Assert.Null(result);
}

[Fact]
public static async Task ListAsyncEnumerable_SingleOrDefault_A()
{
// arrange
IAsyncEnumerable<string> query = new ListAsyncEnumerable(["a"]);

// act
var result = await Executable.From(query).FirstOrDefaultAsync();

// assert
Assert.Equal("a", result);
}

[Fact]
public static async Task ListAsyncEnumerable_SingleOrDefault_Throw()
{
// arrange
IAsyncEnumerable<string> query = new ListAsyncEnumerable(["a", "b"]);

// act
async Task Error() => await Executable.From(query).SingleOrDefaultAsync();

// assert
await Assert.ThrowsAsync<GraphQLException>(Error);
}

[Fact]
public static async Task ListAsyncEnumerable_ToListAsync()
{
// arrange
IAsyncEnumerable<string> query = new ListAsyncEnumerable(["a", "b"]);

// act
var result = await Executable.From(query).ToListAsync();

// assert
Assert.Collection(
result,
r => Assert.Equal("a", r),
r => Assert.Equal("b", r));
}

[Fact]
public static async Task ListAsyncEnumerable_ToAsyncEnumerable()
{
// arrange
IAsyncEnumerable<string> query = new ListAsyncEnumerable(["a", "b"]);

// act
var result = Executable.From(query).ToAsyncEnumerable();

// assert
await foreach (var item in result)
{
Assert.True(item is "a" or "b");
}
}

private class EmptyAsyncEnumerable : IQueryable<string>, IAsyncEnumerable<string>
{
public Type ElementType
=> throw new NotSupportedException();

public Expression Expression
=> throw new NotSupportedException();

public IQueryProvider Provider
=> throw new NotSupportedException();

public IEnumerator<string> GetEnumerator()
=> throw new NotSupportedException();

IEnumerator IEnumerable.GetEnumerator()
=> throw new NotSupportedException();

public async IAsyncEnumerator<string> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
await new ValueTask();
yield break;
}
}

private class ListAsyncEnumerable(string[] items) : IQueryable<string>, IAsyncEnumerable<string>
{
public Type ElementType
=> throw new NotSupportedException();

public Expression Expression
=> throw new NotSupportedException();

public IQueryProvider Provider
=> throw new NotSupportedException();

public IEnumerator<string> GetEnumerator()
=> throw new NotSupportedException();

IEnumerator IEnumerable.GetEnumerator()
=> throw new NotSupportedException();

public async IAsyncEnumerator<string> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
await new ValueTask();

foreach (var item in items)
{
yield return item;
}
}
}
}
Loading