Skip to content

Commit

Permalink
Test coverage improvements for edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Jcparkyn committed Apr 28, 2024
1 parent 2c8738c commit 704a2c2
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 20 deletions.
13 changes: 8 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@


# Unreleased
# [v0.7.0] - Unreleased

## Added
- The non-generic `QueryOptions` class can now be implicitly cast to `QueryOptions<TArg, TResult>`.

## Changed
- **BREAKING CHANGE**: If a query succeeds and then fails on a refetch, `query.Data` now returns `null`/`default`, instead of the old data. Also, `query.LastData` now returns the data from the last successful request (even if the arg was different) instead of `null`/`default`.
- `QueryOptions.OnSuccess` is now called when a cached result is returned (unless it's stale).
- `QueryOptions.OnSuccess` is now called when a cached result is returned (unless it's stale). Note: `EndpointOptions.OnSuccess` is unchanged, and still won't be called when a cached result is returned.

## Fixed
- If a query fails during a refetch, `query.LastData` now returns the last successful data for this arg, rather than falling back to a previous arg.
## Development
- More tests.
- Sample project improvements.

[Changes][v0.7.0]

# [v0.6.0] - 1 Dec 2023

Expand Down Expand Up @@ -204,7 +207,7 @@ This release removes the concept of mutations as the previously existed, and ins

[Changes][v0.1.0]


[v0.7.0]: https://github.com/Jcparkyn/phetch/compare/v0.6.0...v0.7.0
[v0.6.0]: https://github.com/Jcparkyn/phetch/compare/v0.5.1...v0.6.0
[v0.5.1]: https://github.com/Jcparkyn/phetch/compare/v0.5.0...v0.5.1
[v0.5.0]: https://github.com/Jcparkyn/phetch/compare/v0.4.0...v0.5.0
Expand Down
12 changes: 3 additions & 9 deletions src/Phetch.Core/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public class Query<TArg, TResult> : IQuery<TArg, TResult>
private FixedQuery<TArg, TResult>? _currentQuery;

/// <inheritdoc/>
public event Action StateChanged = delegate { };
public event Action? StateChanged;

/// <inheritdoc/>
public event Action<QuerySuccessEventArgs<TArg, TResult>>? Succeeded;
Expand Down Expand Up @@ -342,14 +342,8 @@ public async Task<TResult> SetArgAsync(TArg arg)
StateChanged?.Invoke();
}
}
if (newQuery.LastInvocation is { } task)
{
return await task;
}

// Probably not possible to get here, but just in case
Debug.Fail("newQuery should have been invoked before this point");
return newQuery.Data!;
Debug.Assert(newQuery.LastInvocation is not null, "newQuery should have been invoked before this point");
return await newQuery.LastInvocation;
}

/// <inheritdoc/>
Expand Down
20 changes: 14 additions & 6 deletions test/Phetch.Tests/OptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@

public class OptionsTests
{
[Fact]
public void QueryOptions_should_convert_from_non_generic_options()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void QueryOptions_should_convert_from_non_generic_options(bool useCtor)
{
var onSuccess = (EventArgs e) => { };
var onFailure = (QueryFailureEventArgs e) => { };
Expand All @@ -21,7 +23,9 @@ public void QueryOptions_should_convert_from_non_generic_options()
OnFailure = onFailure,
};

var options2 = new QueryOptions<int, string>(options);
var options2 = useCtor
? new QueryOptions<int, string>(options)
: (QueryOptions<int, string>)options;

using (new AssertionScope())
{
Expand All @@ -32,8 +36,10 @@ public void QueryOptions_should_convert_from_non_generic_options()
}
}

[Fact]
public void EndpointOptions_should_convert_from_non_generic_options()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void EndpointOptions_should_convert_from_non_generic_options(bool useCtor)
{
var onSuccess = (EventArgs e) => { };
var onFailure = (QueryFailureEventArgs e) => { };
Expand All @@ -47,7 +53,9 @@ public void EndpointOptions_should_convert_from_non_generic_options()
CacheTime = TimeSpan.FromSeconds(2),
};

var options2 = new EndpointOptions<int, string>(options);
var options2 = useCtor
? new EndpointOptions<int, string>(options)
: options;

using (new AssertionScope())
{
Expand Down
16 changes: 16 additions & 0 deletions test/Phetch.Tests/Query/QueryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,22 @@ public async Task LastData_refetch_error_then_arg_change()
query.LastData.Should().Be("0");
}

[UIFact]
public void Idle_query_tests()
{
var query = new ParameterlessEndpoint<string>(
_ => ReturnAsync("test")
).Use();

AssertIsIdleState(query);

// These should be no-ops:
query.Detach();
query.Cancel();

AssertIsIdleState(query);
}

private static void AssertIsIdleState<TArg, TResult>(Query<TArg, TResult> query)
{
query.Status.Should().Be(QueryStatus.Idle);
Expand Down
8 changes: 8 additions & 0 deletions test/Phetch.Tests/Query/TriggerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ await query.Invoking(q => q.TriggerAsync(10, onFailure: e => args = e)).Should()
args.Arg.Should().Be(10);
}

[UIFact]
public async Task Should_validate_params()
{
var query = null as Query<int, string>;
var act = () => query!.TriggerAsync(0, onSuccess: _ => { });
await act.Should().ThrowAsync<ArgumentException>();
}

[UIFact]
public async Task Should_not_inkove_failure_callback_when_cancelled()
{
Expand Down

0 comments on commit 704a2c2

Please sign in to comment.