Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added DateOnly and TimeOnly to Data #4552

Merged
merged 4 commits into from
Dec 14, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ public static IFilterConventionDescriptor BindDefaultTypes(
.BindComparableType<Guid>()
.BindComparableType<DateTime>()
.BindComparableType<DateTimeOffset>()
#if NET6_0_OR_GREATER
.BindComparableType<DateOnly>()
.BindComparableType<TimeOnly>()
#endif
.BindComparableType<TimeSpan>();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ protected ExecutorBuilder CreateProviderTester<TRuntimeType>(
.Field("foo")
.Type<StringType>()
.Resolve("bar"))
.AddType(type);
.AddType(type)
.AddType(new TimeSpanType(TimeSpanFormat.DotNet));

builder.Create();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using HotChocolate.Language;
using HotChocolate.Types;
using Snapshooter.Xunit;
using Xunit;

namespace HotChocolate.Data.Filters.Expressions;

public class QueryableFilterVisitorDateOnlyTests
: FilterVisitorTestBase
{
#if NET6_0_OR_GREATER
[Fact]
public void Create_ShortEqual_Expression()
{
// arrange
IValueNode value = Utf8GraphQLParser.Syntax.ParseValueLiteral(
"{ value: { eq: \"2020-12-12\" }}");
ExecutorBuilder tester = CreateProviderTester(new FooFilterInput());

// act
Func<Foo, bool> func = tester.Build<Foo>(value);

// assert
var a = new Foo { Value = new DateOnly(2020,12,12) };
Assert.True(func(a));

var b = new Foo { Value = new DateOnly(2020,12,13) };
Assert.False(func(b));
}

[Fact]
public void Create_ShortNotEqual_Expression()
{
// arrange
IValueNode value = Utf8GraphQLParser.Syntax.ParseValueLiteral(
"{ value: { neq: \"2020-12-12\" }}");
ExecutorBuilder tester = CreateProviderTester(new FooFilterInput());

// act
Func<Foo, bool> func = tester.Build<Foo>(value);


// assert
var a = new Foo { Value = new DateOnly(2020,12,13) };
Assert.True(func(a));

var b = new Foo { Value = new DateOnly(2020,12,12)};
Assert.False(func(b));
}

[Fact]
public void Create_ShortNullableEqual_Expression()
{
// arrange
IValueNode value = Utf8GraphQLParser.Syntax.ParseValueLiteral(
"{ value: { eq: null }}");
ExecutorBuilder tester = CreateProviderTester(new FooNullableFilterInput());

// act
Func<FooNullable, bool> func = tester.Build<FooNullable>(value);

// assert
var a = new FooNullable { Value = null };
Assert.True(func(a));

var b = new FooNullable { Value = new DateOnly(2020,12,13) };
Assert.False(func(b));
}

public class Foo
{
public DateOnly Value { get; set; }
}

public class FooNullable
{
public DateOnly? Value { get; set; }
}

public class FooFilterInput
: FilterInputType<Foo>
{
}
public class FooNullableFilterInput
: FilterInputType<FooNullable>
{
}
#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using HotChocolate.Language;
using Xunit;

namespace HotChocolate.Data.Filters.Expressions;

public class QueryableFilterVisitorTimeOnlyTests
: FilterVisitorTestBase
{
#if NET6_0_OR_GREATER
[Fact]
public void Create_ShortEqual_Expression()
{
// arrange
IValueNode value = Utf8GraphQLParser.Syntax.ParseValueLiteral(
"{ value: { eq: \"23:59:59\" }}");
ExecutorBuilder tester = CreateProviderTester(new FooFilterInput());

// act
Func<Foo, bool> func = tester.Build<Foo>(value);

// assert
var a = new Foo { Value = new TimeOnly(23, 59, 59) };
Assert.True(func(a));

var b = new Foo { Value = new TimeOnly(1, 59, 59) };
Assert.False(func(b));
}

[Fact]
public void Create_ShortNotEqual_Expression()
{
// arrange
IValueNode value = Utf8GraphQLParser.Syntax.ParseValueLiteral(
"{ value: { neq: \"23:59:59\" }}");
ExecutorBuilder tester = CreateProviderTester(new FooFilterInput());

// act
Func<Foo, bool> func = tester.Build<Foo>(value);


// assert
var a = new Foo { Value = new TimeOnly(1, 59, 59) };
Assert.True(func(a));

var b = new Foo { Value = new TimeOnly(23, 59, 59) };
Assert.False(func(b));
}

[Fact]
public void Create_ShortNullableEqual_Expression()
{
// arrange
IValueNode value = Utf8GraphQLParser.Syntax.ParseValueLiteral(
"{ value: { eq: null }}");
ExecutorBuilder tester = CreateProviderTester(new FooNullableFilterInput());

// act
Func<FooNullable, bool> func = tester.Build<FooNullable>(value);

// assert
var a = new FooNullable { Value = null };
Assert.True(func(a));

var b = new FooNullable { Value = new TimeOnly(23, 59, 59) };
Assert.False(func(b));
}

public class Foo
{
public TimeOnly Value { get; set; }
}

public class FooNullable
{
public TimeOnly? Value { get; set; }
}

public class FooFilterInput
: FilterInputType<Foo>
{
}

public class FooNullableFilterInput
: FilterInputType<FooNullable>
{
}
#endif
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using HotChocolate.Types;
using Snapshooter;
using Snapshooter.Xunit;
using Xunit;

Expand Down Expand Up @@ -43,7 +45,11 @@ public void Create_Implicit_Operation()
.Create();

// assert
#if NET6_0_OR_GREATER
schema.ToString().MatchSnapshot(new SnapshotNameExtension("NET6"));
#else
schema.ToString().MatchSnapshot();
#endif
}

[Fact]
Expand All @@ -65,7 +71,7 @@ public void Create_Explicit_Operation()
.Create();

// assert
schema.ToString().MatchSnapshot();
schema.ToString().MatchSnapshot(new SnapshotNameExtension("NET6"));
}

public class FooFilterInput : FilterInputType
Expand All @@ -79,18 +85,40 @@ protected override void Configure(IFilterInputTypeDescriptor descriptor)
public class Foo
{
public short BarShort { get; set; }

public int BarInt { get; set; }

public long BarLong { get; set; }

public float BarFloat { get; set; }

public double BarDouble { get; set; }

public decimal BarDecimal { get; set; }

public short? BarShortNullable { get; set; }

public int? BarIntNullable { get; set; }

public long? BarLongNullable { get; set; }

public float? BarFloatNullable { get; set; }

public double? BarDoubleNullable { get; set; }

public decimal? BarDecimalNullable { get; set; }

public FooBar FooBar { get; set; }

#if NET6_0_OR_GREATER
public DateOnly DateOnly { get; set; }

public DateOnly? DateOnlyNullable { get; set; }

public TimeOnly TimeOnly { get; set; }

public TimeOnly? TimeOnlyNullable { get; set; }
#endif
}

public enum FooBar
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
schema {
query: Query
}

type Query {
foo(test: FooFilterInput): String
}

input ComparableInt32OperationFilterInput {
eq: Int
neq: Int
in: [Int!]
nin: [Int!]
gt: Int
ngt: Int
gte: Int
ngte: Int
lt: Int
nlt: Int
lte: Int
nlte: Int
}

input FooFilterInput {
and: [FooFilterInput!]
or: [FooFilterInput!]
comparable: ComparableInt32OperationFilterInput
}

"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`."
directive @defer("If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." label: String "Deferred when true." if: Boolean) on FRAGMENT_SPREAD | INLINE_FRAGMENT

"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`."
directive @stream("If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." label: String "The initial elements that shall be send down to the consumer." initialCount: Int! = 0 "Streamed when true." if: Boolean) on FIELD
Loading