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 support for variables in list and objects. #896

Merged
merged 13 commits into from
Jul 8, 2019

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar_baz"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar_baz"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar_baz"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Data": {
"foo": "bar"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
using System.Collections.Generic;
using System;
using HotChocolate.Language;
using HotChocolate.Types;
using HotChocolate.Utilities;
using Moq;
using Xunit;
using Snapshooter.Xunit;

namespace HotChocolate.Execution
{
public class VariableToValueRewriterTests
{
[Fact]
public void Value_Is_Null()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<StringType>()))
.Create();

var type = schema.GetType<InputObjectType>("Foo");
var variables = Mock.Of<IVariableCollection>();
var typeConversion = new TypeConversion();

// act
Action action = () => VariableToValueRewriter.Rewrite(
null, type, variables, typeConversion);

// assert
Assert.Throws<ArgumentNullException>(action);
}

[Fact]
public void Type_Is_Null()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<StringType>()))
.Create();

var value = new ObjectValueNode(
new ObjectFieldNode(
"a",
new StringValueNode("abc")));
var variables = Mock.Of<IVariableCollection>();
var typeConversion = new TypeConversion();

// act
Action action = () => VariableToValueRewriter.Rewrite(
value, null, variables, typeConversion);

// assert
Assert.Throws<ArgumentNullException>(action);
}

[Fact]
public void Variables_Is_Null()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<StringType>()))
.Create();

var value = new ObjectValueNode(
new ObjectFieldNode(
"a",
new StringValueNode("abc")));
var type = schema.GetType<InputObjectType>("Foo");
var typeConversion = new TypeConversion();

// act
Action action = () => VariableToValueRewriter.Rewrite(
value, type, null, typeConversion);

// assert
Assert.Throws<ArgumentNullException>(action);
}

[Fact]
public void TypeConversion_Is_Null()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<StringType>()))
.Create();

var value = new ObjectValueNode(
new ObjectFieldNode(
"a",
new StringValueNode("abc")));
var type = schema.GetType<InputObjectType>("Foo");
var variables = Mock.Of<IVariableCollection>();

// act
Action action = () => VariableToValueRewriter.Rewrite(
value, type, variables, null);

// assert
Assert.Throws<ArgumentNullException>(action);
}

[Fact]
public void Replace_Object_Variable_First_Level()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<StringType>()))
.Create();

var value = new ObjectValueNode(
new ObjectFieldNode(
"bar",
new VariableNode("abc")));
var type = schema.GetType<InputObjectType>("Foo");
var variables = new VariableCollectionMock("abc", "def");
var typeConversion = new TypeConversion();

// act
IValueNode rewritten = VariableToValueRewriter.Rewrite(
value, type, variables, typeConversion);

// assert
QuerySyntaxSerializer.Serialize(rewritten).MatchSnapshot();
}

[Fact]
public void Replace_Object_Variable_Second_Level()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type(new NamedTypeNode("Bar"))))
.AddType(new InputObjectType(d => d
.Name("Bar")
.Field("baz").Type<StringType>()))
.Create();

var innerValue = new ObjectValueNode(
new ObjectFieldNode(
"baz",
new VariableNode("abc")));

var value = new ObjectValueNode(
new ObjectFieldNode(
"bar",
innerValue));

var type = schema.GetType<InputObjectType>("Foo");
var variables = new VariableCollectionMock("abc", "def");
var typeConversion = new TypeConversion();

// act
IValueNode rewritten = VariableToValueRewriter.Rewrite(
value, type, variables, typeConversion);

// assert
QuerySyntaxSerializer.Serialize(rewritten).MatchSnapshot();
}

[Fact]
public void Replace_List_Variable_Second_Level()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<ListType<StringType>>()))
.Create();

var value = new ObjectValueNode(
new ObjectFieldNode(
"bar",
new ListValueNode(new VariableNode("abc"))));
var type = schema.GetType<InputObjectType>("Foo");
var variables = new VariableCollectionMock("abc", "def");
var typeConversion = new TypeConversion();

// act
IValueNode rewritten = VariableToValueRewriter.Rewrite(
value, type, variables, typeConversion);

// assert
QuerySyntaxSerializer.Serialize(rewritten).MatchSnapshot();
}

[Fact]
public void Cannot_Convert_Variable()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<StringType>()))
.Create();

var value = new ObjectValueNode(
new ObjectFieldNode(
"bar",
new VariableNode("abc")));
var type = schema.GetType<InputObjectType>("Foo");
var variables = new VariableCollectionMock("abc", new Foo());
var typeConversion = new TypeConversion();

// act
Action action = () => VariableToValueRewriter.Rewrite(
value, type, variables, typeConversion);

// assert
Assert.Throws<QueryException>(action).Errors.MatchSnapshot();
}

[Fact]
public void Convert_Variable()
{
// arrange
ISchema schema = CreateSchemaBuilder()
.AddType(new InputObjectType(d => d
.Name("Foo")
.Field("bar").Type<StringType>()))
.Create();

var value = new ObjectValueNode(
new ObjectFieldNode(
"bar",
new VariableNode("abc")));
var type = schema.GetType<InputObjectType>("Foo");
var variables = new VariableCollectionMock("abc", 123);
var typeConversion = new TypeConversion();

// act
IValueNode rewritten = VariableToValueRewriter.Rewrite(
value, type, variables, typeConversion);

// assert
QuerySyntaxSerializer.Serialize(rewritten).MatchSnapshot();
}


private ISchemaBuilder CreateSchemaBuilder()
{
return SchemaBuilder.New()
.AddQueryType(c =>
c.Name("Query")
.Field("foo")
.Type<StringType>()
.Resolver("bar"));
}

private class VariableCollectionMock
: IVariableCollection
{
private Dictionary<string, object> _values =
new Dictionary<string, object>();

public VariableCollectionMock(string variableName, object value)
{
_values[variableName] = value;
}

public T GetVariable<T>(string variableName)
{
return (T)_values[variableName];
}

public bool TryGetVariable<T>(string variableName, out T variableValue)
{
if (_values.TryGetValue(variableName, out object value)
&& value is T casted)
{
variableValue = casted;
return true;
}

variableValue = default;
return false;
}
}

private class Foo { }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"Message": "Unable to convert the specified variable value.",
"Code": null,
"Path": null,
"Locations": [],
"Exception": null,
"Extensions": {}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ bar: "123" }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ bar: [ "def" ] }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ bar: "def" }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ bar: { baz: "def" } }
Loading