graphql 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graph_ql/{types → definition_helpers}/argument_definer.rb +0 -0
  3. data/lib/graph_ql/definition_helpers/definable.rb +18 -0
  4. data/lib/graph_ql/{types → definition_helpers}/field_definer.rb +0 -0
  5. data/lib/graph_ql/definition_helpers/forwardable.rb +10 -0
  6. data/lib/graph_ql/definition_helpers/non_null_with_bang.rb +9 -0
  7. data/lib/graph_ql/definition_helpers/string_named_hash.rb +12 -0
  8. data/lib/graph_ql/{types → definition_helpers}/type_definer.rb +1 -0
  9. data/lib/graph_ql/directive.rb +9 -5
  10. data/lib/graph_ql/directives/directive_chain.rb +1 -1
  11. data/lib/graph_ql/field.rb +1 -5
  12. data/lib/graph_ql/parser/transform.rb +1 -3
  13. data/lib/graph_ql/query.rb +14 -3
  14. data/lib/graph_ql/query/arguments.rb +6 -5
  15. data/lib/graph_ql/query/field_resolution_strategy.rb +3 -3
  16. data/lib/graph_ql/{types → scalars}/boolean_type.rb +0 -0
  17. data/lib/graph_ql/{types → scalars}/float_type.rb +1 -1
  18. data/lib/graph_ql/scalars/id_type.rb +6 -0
  19. data/lib/graph_ql/{types → scalars}/int_type.rb +0 -0
  20. data/lib/graph_ql/{types → scalars}/scalar_type.rb +0 -4
  21. data/lib/graph_ql/{types → scalars}/string_type.rb +0 -0
  22. data/lib/graph_ql/static_validation.rb +7 -10
  23. data/lib/graph_ql/static_validation/all_rules.rb +23 -0
  24. data/lib/graph_ql/static_validation/literal_validator.rb +0 -3
  25. data/lib/graph_ql/static_validation/{argument_literals_are_compatible.rb → rules/argument_literals_are_compatible.rb} +0 -0
  26. data/lib/graph_ql/static_validation/{arguments_are_defined.rb → rules/arguments_are_defined.rb} +5 -0
  27. data/lib/graph_ql/static_validation/{directives_are_defined.rb → rules/directives_are_defined.rb} +0 -0
  28. data/lib/graph_ql/static_validation/{fields_are_defined_on_type.rb → rules/fields_are_defined_on_type.rb} +0 -0
  29. data/lib/graph_ql/static_validation/{fields_have_appropriate_selections.rb → rules/fields_have_appropriate_selections.rb} +0 -0
  30. data/lib/graph_ql/static_validation/{fields_will_merge.rb → rules/fields_will_merge.rb} +13 -5
  31. data/lib/graph_ql/static_validation/rules/fragment_spreads_are_possible.rb +50 -0
  32. data/lib/graph_ql/static_validation/{fragment_types_exist.rb → rules/fragment_types_exist.rb} +0 -0
  33. data/lib/graph_ql/static_validation/rules/fragments_are_finite.rb +23 -0
  34. data/lib/graph_ql/static_validation/rules/fragments_are_on_composite_types.rb +27 -0
  35. data/lib/graph_ql/static_validation/{fragments_are_used.rb → rules/fragments_are_used.rb} +0 -0
  36. data/lib/graph_ql/static_validation/{required_arguments_are_present.rb → rules/required_arguments_are_present.rb} +0 -0
  37. data/lib/graph_ql/static_validation/rules/variable_default_values_are_correctly_typed.rb +24 -0
  38. data/lib/graph_ql/static_validation/rules/variable_usages_are_allowed.rb +47 -0
  39. data/lib/graph_ql/static_validation/rules/variables_are_input_types.rb +27 -0
  40. data/lib/graph_ql/static_validation/rules/variables_are_used_and_defined.rb +31 -0
  41. data/lib/graph_ql/static_validation/type_stack.rb +13 -1
  42. data/lib/graph_ql/static_validation/validator.rb +14 -18
  43. data/lib/graph_ql/type_kinds.rb +8 -4
  44. data/lib/graph_ql/{enum.rb → types/enum.rb} +7 -6
  45. data/lib/graph_ql/types/input_object_type.rb +3 -10
  46. data/lib/graph_ql/{interface.rb → types/interface.rb} +0 -4
  47. data/lib/graph_ql/types/list_type.rb +0 -4
  48. data/lib/graph_ql/types/non_null_type.rb +0 -4
  49. data/lib/graph_ql/types/object_type.rb +28 -13
  50. data/lib/graph_ql/{union.rb → types/union.rb} +0 -4
  51. data/lib/graph_ql/version.rb +1 -1
  52. data/lib/graphql.rb +9 -40
  53. data/readme.md +26 -20
  54. data/spec/graph_ql/directive_spec.rb +4 -4
  55. data/spec/graph_ql/introspection/directive_type_spec.rb +2 -2
  56. data/spec/graph_ql/introspection/schema_type_spec.rb +3 -2
  57. data/spec/graph_ql/introspection/type_type_spec.rb +7 -7
  58. data/spec/graph_ql/parser/parser_spec.rb +6 -2
  59. data/spec/graph_ql/query_spec.rb +26 -8
  60. data/spec/graph_ql/scalars/id_type_spec.rb +24 -0
  61. data/spec/graph_ql/schema/type_reducer_spec.rb +1 -0
  62. data/spec/graph_ql/schema/type_validator_spec.rb +1 -1
  63. data/spec/graph_ql/static_validation/{argument_literals_are_compatible_spec.rb → rules/argument_literals_are_compatible_spec.rb} +1 -1
  64. data/spec/graph_ql/static_validation/{arguments_are_defined_spec.rb → rules/arguments_are_defined_spec.rb} +1 -1
  65. data/spec/graph_ql/static_validation/{directives_are_defined_spec.rb → rules/directives_are_defined_spec.rb} +1 -1
  66. data/spec/graph_ql/static_validation/{fields_are_defined_on_type_spec.rb → rules/fields_are_defined_on_type_spec.rb} +1 -1
  67. data/spec/graph_ql/static_validation/{fields_have_appropriate_selections_spec.rb → rules/fields_have_appropriate_selections_spec.rb} +1 -1
  68. data/spec/graph_ql/static_validation/{fields_will_merge_spec.rb → rules/fields_will_merge_spec.rb} +1 -1
  69. data/spec/graph_ql/static_validation/rules/fragment_spreads_are_possible_spec.rb +46 -0
  70. data/spec/graph_ql/static_validation/{fragment_types_exist_spec.rb → rules/fragment_types_exist_spec.rb} +1 -1
  71. data/spec/graph_ql/static_validation/rules/fragments_are_finite_spec.rb +43 -0
  72. data/spec/graph_ql/static_validation/rules/fragments_are_on_composite_types_spec.rb +48 -0
  73. data/spec/graph_ql/static_validation/{fragments_are_used_spec.rb → rules/fragments_are_used_spec.rb} +1 -1
  74. data/spec/graph_ql/static_validation/{required_arguments_are_present_spec.rb → rules/required_arguments_are_present_spec.rb} +1 -1
  75. data/spec/graph_ql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +43 -0
  76. data/spec/graph_ql/static_validation/rules/variable_usages_are_allowed_spec.rb +45 -0
  77. data/spec/graph_ql/static_validation/rules/variables_are_input_types_spec.rb +36 -0
  78. data/spec/graph_ql/static_validation/rules/variables_are_used_and_defined_spec.rb +44 -0
  79. data/spec/graph_ql/static_validation/type_stack_spec.rb +2 -2
  80. data/spec/graph_ql/static_validation/validator_spec.rb +44 -5
  81. data/spec/graph_ql/types/enum_spec.rb +10 -0
  82. data/spec/graph_ql/{interface_spec.rb → types/interface_spec.rb} +1 -1
  83. data/spec/graph_ql/types/object_type_spec.rb +13 -0
  84. data/spec/graph_ql/{union_spec.rb → types/union_spec.rb} +0 -0
  85. data/spec/support/dummy_app.rb +7 -6
  86. data/spec/support/dummy_data.rb +3 -3
  87. metadata +74 -46
  88. data/lib/graph_ql/types/non_null_with_bang.rb +0 -5
  89. data/spec/graph_ql/enum_spec.rb +0 -5
@@ -17,8 +17,4 @@ class GraphQL::Union
17
17
  type_name = object.class.name
18
18
  possible_types.find {|t| t.name == type_name}
19
19
  end
20
-
21
- def to_s
22
- "<GraphQL::Union #{name}>"
23
- end
24
20
  end
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/graphql.rb CHANGED
@@ -12,56 +12,26 @@ module GraphQL
12
12
  raise [line, col, string].join(", ")
13
13
  end
14
14
 
15
- module Definable
16
- def attr_definable(*names)
17
- attr_accessor(*names)
18
- names.each do |name|
19
- ivar_name = "@#{name}".to_sym
20
- define_method(name) do |new_value=nil|
21
- new_value && self.instance_variable_set(ivar_name, new_value)
22
- instance_variable_get(ivar_name)
23
- end
24
- end
25
- end
26
- end
27
-
28
- module Forwardable
29
- def delegate(*methods, to:)
30
- methods.each do |method_name|
31
- define_method(method_name) do |*args|
32
- self.public_send(to).public_send(method_name, *args)
33
- end
34
- end
35
- end
36
- end
37
-
38
15
  module Introspection; end
39
16
  end
40
17
 
18
+ def require_dir(dir)
19
+ Dir.glob(File.expand_path("../graph_ql/#{dir}/*.rb", __FILE__)).each do |file|
20
+ require file
21
+ end
22
+ end
41
23
  # Order matters for these:
42
24
 
43
- require 'graph_ql/types/non_null_with_bang'
25
+ require_dir('definition_helpers')
44
26
  require 'graph_ql/types/object_type'
45
- require 'graph_ql/types/list_type'
46
- require 'graph_ql/types/scalar_type'
47
- require 'graph_ql/types/non_null_type'
48
- require 'graph_ql/types/input_value'
49
- require 'graph_ql/types/input_object_type'
50
-
51
- require 'graph_ql/types/type_definer'
52
- require 'graph_ql/types/field_definer'
53
- require 'graph_ql/types/argument_definer'
27
+ require_dir('types')
54
28
 
55
- require 'graph_ql/enum'
56
29
  require 'graph_ql/field'
57
- require 'graph_ql/union'
58
30
  require 'graph_ql/type_kinds'
59
31
  require 'graph_ql/introspection/typename_field'
60
32
 
61
- require 'graph_ql/types/int_type'
62
- require 'graph_ql/types/string_type'
63
- require 'graph_ql/types/float_type'
64
- require 'graph_ql/types/boolean_type'
33
+ require 'graph_ql/scalars/scalar_type'
34
+ require_dir('scalars')
65
35
 
66
36
  require 'graph_ql/introspection/input_value_type'
67
37
  require 'graph_ql/introspection/enum_value_type'
@@ -87,7 +57,6 @@ require 'graph_ql/schema'
87
57
 
88
58
  # Order does not matter for these:
89
59
 
90
- require 'graph_ql/interface'
91
60
  require 'graph_ql/query'
92
61
  require 'graph_ql/repl'
93
62
  require 'graph_ql/static_validation'
data/readme.md CHANGED
@@ -27,7 +27,7 @@
27
27
  t.name "Post"
28
28
  t.description "A blog post"
29
29
  t.fields({
30
- id: field.build(type: !types.Int)
30
+ id: field.build(type: !types.Int),
31
31
  title: field.build(type: !types.String),
32
32
  body: field.build(type: !types.String),
33
33
  comments: field.build(type: types[!CommentType])
@@ -76,29 +76,35 @@
76
76
  - [`queries_controller.rb`](https://github.com/rmosolgo/graphql-ruby-demo/blob/master/app/controllers/queries_controller.rb) for a Rails example
77
77
  - Try it on [heroku](http://graphql-ruby-demo.herokuapp.com)
78
78
 
79
- ## To Do:
80
-
81
- - Validations:
82
- - Implement validations:
83
- - [Fragment spreads are on Object/Union/Interface](http://facebook.github.io/graphql/#sec-Fragments-On-Composite-Types)
84
- - [Fragments don't go infinite](http://facebook.github.io/graphql/#sec-Fragment-spreads-must-not-form-cycles)
85
- - [Fragment spreads are possible](http://facebook.github.io/graphql/#sec-Fragment-spread-is-possible)
86
- - [In object scope, object-typed fragments are the same type](http://facebook.github.io/graphql/#sec-Object-Spreads-In-Object-Scope)
87
- - [In object scope, abstract-typed fragments fit that object](http://facebook.github.io/graphql/#sec-Abstract-Spreads-in-Object-Scope)
88
- - [In abstract scope, object-typed fragments fit that type](http://facebook.github.io/graphql/#sec-Object-Spreads-In-Abstract-Scope)
89
- - [In abstract scope, abstract-typed fragments must share a type](http://facebook.github.io/graphql/#sec-Abstract-Spreads-in-Abstract-Scope)
90
- - everything in [Variables](http://facebook.github.io/graphql/#sec-Validation.Operations.Variables)
91
- - directives:
92
- - `@skip` has precedence over `@include`
93
- - directives on fragments: http://facebook.github.io/graphql/#sec-Fragment-Directives
94
- - Support any "real" value for enum, not just stringified name (see `Character::EPISODES` in demo)
95
- - field merging (https://github.com/graphql/graphql-js/issues/19#issuecomment-118515077)
79
+ ## To Do
80
+
81
+ - To match spec:
82
+ - Directives:
83
+ - `@skip` has precedence over `@include`
84
+ - directives on fragments: http://facebook.github.io/graphql/#sec-Fragment-Directives
85
+ - Field merging
86
+ - if you were to request a field, then request it in a fragment, it would get looked up twice
87
+ - https://github.com/graphql/graphql-js/issues/19#issuecomment-118515077
96
88
  - Code clean-up
97
89
  - Unify unwrapping types (It's on `TypeKind` but it's still not right)
98
- - de-dup stringify keys logic in `Field` and `ObjectType` and `Directive`
90
+ - Cook up some path other than "n+1s everywhere"
99
91
 
100
- ## Goals:
92
+ ## Goals
101
93
 
102
94
  - Implement the GraphQL spec & support a Relay front end
103
95
  - Provide idiomatic, plain-Ruby API with similarities to reference implementation where possible
104
96
  - Support `graphql-rails`
97
+
98
+ ## Getting Involved
99
+
100
+ - __Say hi & ask questions__ in the [#ruby channel on Slack](https://graphql-slack.herokuapp.com/) or [on Twitter](https://twitter.com/rmosolgo)!
101
+ - __Report bugs__ by posting a description, full stack trace, and all relevant code in a [GitHub issue](https://github.com/rmosolgo/graphql-ruby/issues).
102
+ - __Features & patches__ are welcome! Consider discussing it in an [issue](https://github.com/rmosolgo/graphql-ruby/issues) or in the [#ruby channel on Slack](https://graphql-slack.herokuapp.com/) to make sure we're on the same page.
103
+ - __Run the tests__ with `rake test` or start up guard with `bundle exec guard`.
104
+
105
+ ## Other Resources
106
+
107
+ - [GraphQL Spec](http://facebook.github.io/graphql/)
108
+ - Other implementations: [graphql-links](https://github.com/emmenko/graphql-links)
109
+ - `graphql-ruby` + Rails demo ([src](https://github.com/rmosolgo/graphql-ruby-demo) / [heroku](http://graphql-ruby-demo.herokuapp.com))
110
+ - [GraphQL Slack](https://graphql-slack.herokuapp.com/)
@@ -23,14 +23,14 @@ describe GraphQL::Directive do
23
23
  fragment dontSkipIdField on Cheese { dontSkipId: id @skip(if: false) }
24
24
  |}
25
25
  it 'intercepts fields' do
26
- expected = { "data" => {"directives" => {
26
+ expected = { "data" =>{
27
27
  "cheese" => {
28
28
  "dontSkipFlavor" => "Brie",
29
29
  "includeFlavor" => "Brie",
30
30
  "includeId" => 1,
31
31
  "dontSkipId" => 1,
32
32
  },
33
- }}}
33
+ }}
34
34
  assert_equal(expected, result)
35
35
  end
36
36
  end
@@ -65,7 +65,7 @@ describe GraphQL::Directive do
65
65
  |}
66
66
 
67
67
  it 'intercepts fragment spreads' do
68
- expected = { "data" => {"directives" => {
68
+ expected = { "data" => {
69
69
  "cheese" => {
70
70
  "dontSkipFlavor" => "Brie",
71
71
  "includeFlavor" => "Brie",
@@ -74,7 +74,7 @@ describe GraphQL::Directive do
74
74
  "dontSkipInlineId" => 1,
75
75
  "includeInlineId" => 1,
76
76
  },
77
- }}}
77
+ }}
78
78
  assert_equal(expected, result)
79
79
  end
80
80
  end
@@ -11,7 +11,7 @@ describe GraphQL::Introspection::DirectiveType do
11
11
  let(:result) { GraphQL::Query.new(DummySchema, query_string).result }
12
12
 
13
13
  it 'shows directive info ' do
14
- expected = { "data" => {"getDirectives" => {
14
+ expected = { "data" => {
15
15
  "__schema" => {
16
16
  "directives" => [
17
17
  {
@@ -34,7 +34,7 @@ describe GraphQL::Introspection::DirectiveType do
34
34
  },
35
35
  ]
36
36
  }
37
- }}}
37
+ }}
38
38
  assert_equal(expected, result)
39
39
  end
40
40
  end
@@ -12,12 +12,13 @@ describe GraphQL::Introspection::SchemaType do
12
12
  |}
13
13
  let(:result) { GraphQL::Query.new(DummySchema, query_string).result }
14
14
  it 'exposes the schema' do
15
- expected = { "data" => { "getSchema" => {
15
+ expected = { "data" => {
16
16
  "__schema" => {
17
17
  "types" => DummySchema.types.values.map { |t| t.name.nil? ? (p t; raise("no name for #{t}")) : {"name" => t.name} },
18
18
  "queryType"=>{
19
19
  "fields"=>[
20
20
  {"name"=>"cheese"},
21
+ {"name"=>"milk"},
21
22
  {"name"=>"fromSource"},
22
23
  {"name"=>"favoriteEdible"},
23
24
  {"name"=>"searchDairy"},
@@ -34,7 +35,7 @@ describe GraphQL::Introspection::SchemaType do
34
35
  ]
35
36
  },
36
37
  }
37
- }}}
38
+ }}
38
39
  assert_equal(expected, result)
39
40
  end
40
41
  end
@@ -25,7 +25,7 @@ describe GraphQL::Introspection::TypeType do
25
25
  {"name"=>"SHEEP", "isDeprecated"=> false },
26
26
  ]}
27
27
  it 'exposes metadata about types' do
28
- expected = {"data"=> { "introspectionQuery" => {
28
+ expected = {"data"=> {
29
29
  "cheeseType" => {
30
30
  "name"=> "Cheese",
31
31
  "kind" => "OBJECT",
@@ -37,7 +37,7 @@ describe GraphQL::Introspection::TypeType do
37
37
  {"name"=>"AnimalProduct"}
38
38
  ],
39
39
  "fields"=>[
40
- {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Int"}}},
40
+ {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"ID"}}},
41
41
  {"type"=>{"name"=>"DairyAnimal", "ofType"=>nil}},
42
42
  {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Float"}}},
43
43
  {"type"=>{"name"=>"List", "ofType"=>{"name"=>"String"}}},
@@ -63,7 +63,7 @@ describe GraphQL::Introspection::TypeType do
63
63
  {"name"=>"__typename"},
64
64
  ]
65
65
  }
66
- }}}
66
+ }}
67
67
  assert_equal(expected, query.result)
68
68
  end
69
69
 
@@ -78,7 +78,7 @@ describe GraphQL::Introspection::TypeType do
78
78
  it 'can expose deprecated fields' do
79
79
  typename = cheese_fields.pop
80
80
  new_cheese_fields = cheese_fields + [deprecated_fields, typename]
81
- expected = { "data" => { "introspectionQuery" => {
81
+ expected = { "data" => {
82
82
  "cheeseType" => {
83
83
  "name"=> "Cheese",
84
84
  "kind" => "OBJECT",
@@ -89,7 +89,7 @@ describe GraphQL::Introspection::TypeType do
89
89
  "kind"=>"ENUM",
90
90
  "enumValues"=> dairy_animals + [{"name" => "YAK", "isDeprecated" => true}],
91
91
  },
92
- }}}
92
+ }}
93
93
  assert_equal(expected, query.result)
94
94
  end
95
95
 
@@ -101,7 +101,7 @@ describe GraphQL::Introspection::TypeType do
101
101
  |}
102
102
 
103
103
  it 'exposes metadata about input objects' do
104
- expected = { "data" => { "introspectionQuery" => {
104
+ expected = { "data" => {
105
105
  "__type" => {
106
106
  "name"=>"DairyProductInput",
107
107
  "description"=>"Properties for finding a dairy product",
@@ -111,7 +111,7 @@ describe GraphQL::Introspection::TypeType do
111
111
  {"name"=>"fatContent", "type"=>{ "name" => "Float"}, "defaultValue"=>nil}
112
112
  ]
113
113
  }
114
- }}}
114
+ }}
115
115
  assert_equal(expected, query.result)
116
116
  end
117
117
  end
@@ -9,7 +9,11 @@ describe GraphQL::Parser do
9
9
  # a read-only:
10
10
  query getStuff {id, name @skip(if: true)}
11
11
  # a mutation:
12
- mutation changeStuff($override: Boolean!, $cucumbers: [Vegetable]!) @veggie, @healthy(vitamins: true) {
12
+ mutation changeStuff(
13
+ $override: Boolean = true,
14
+ $cucumbers: [Vegetable]!,
15
+ $input: SomeInputType = {key: "value"},
16
+ ) @veggie, @healthy(vitamins: true) {
13
17
  # change the cucumber
14
18
  changeStuff(thing: $cucumbers) {
15
19
  id,
@@ -72,7 +76,7 @@ describe GraphQL::Parser do
72
76
  assert(parser.operation_variable_definition.parse_with_debug("$myVar: [Int]"), "it gets list variables")
73
77
  assert(parser.operation_variable_definition.parse_with_debug("$myVar: Elephant!"), "it gets non-null variables")
74
78
  assert(parser.operation_variable_definition.parse_with_debug("$myVar: [Food]!"), "it gets non-null list variables")
75
- assert(parser.operation_variable_definitions.parse_with_debug(%|($myVar: Elephant!, $myList: [Float], $myString: String="Cheese")|), "it gets a list of defns")
79
+ assert(parser.operation_variable_definitions.parse_with_debug(%|($myVar: Elephant!, $myList: [Float], $myString: String = "Cheese")|), "it gets a list of defns")
76
80
  end
77
81
 
78
82
  describe 'value' do
@@ -4,17 +4,17 @@ describe GraphQL::Query do
4
4
  describe '#execute' do
5
5
  let(:query_string) { %|
6
6
  query getFlavor($cheeseId: Int!) {
7
- brie: cheese(id: 1) { ...cheeseFields, ... milkFields, taste: flavor },
7
+ brie: cheese(id: 1) { ...cheeseFields, taste: flavor },
8
8
  cheese(id: $cheeseId) {
9
9
  __typename,
10
10
  id,
11
11
  ...cheeseFields,
12
12
  ... edibleFields,
13
13
  ... on Cheese { cheeseKind: flavor },
14
- ... on Milk { source }
15
14
  }
16
15
  fromSource(source: COW) { id }
17
- firstSheep: searchDairy(product: {source: SHEEP}) { ... dairyFields }
16
+ fromSheep: fromSource(source: SHEEP) { id }
17
+ firstSheep: searchDairy(product: {source: SHEEP}) { ... dairyFields, ... milkFields }
18
18
  favoriteEdible { __typename, fatContent }
19
19
  }
20
20
  fragment cheeseFields on Cheese { flavor }
@@ -26,11 +26,11 @@ describe GraphQL::Query do
26
26
  }
27
27
  |}
28
28
  let(:debug) { false }
29
- let(:query) { GraphQL::Query.new(DummySchema, query_string, context: {}, params: {"cheeseId" => 2}, debug: debug)}
29
+ let(:query) { GraphQL::Query.new(DummySchema, query_string, params: {"cheeseId" => 2}, debug: debug)}
30
30
  let(:result) { query.result }
31
31
 
32
32
  it 'returns fields on objects' do
33
- expected = {"data"=> { "getFlavor" => {
33
+ expected = {"data"=> {
34
34
  "brie" => { "flavor" => "Brie", "taste" => "Brie" },
35
35
  "cheese" => {
36
36
  "__typename" => "Cheese",
@@ -40,9 +40,10 @@ describe GraphQL::Query do
40
40
  "cheeseKind" => "Gouda",
41
41
  },
42
42
  "fromSource" => [{ "id" => 1 }, {"id" => 2}],
43
+ "fromSheep"=>[{"id"=>3}],
43
44
  "firstSheep" => { "flavor" => "Manchego" },
44
45
  "favoriteEdible"=>{"__typename"=>"Milk", "fatContent"=>0.04},
45
- }}}
46
+ }}
46
47
  assert_equal(expected, result)
47
48
  end
48
49
 
@@ -81,14 +82,31 @@ describe GraphQL::Query do
81
82
  |}
82
83
  it 'executes mutations in order' do
83
84
  expected = {"data"=>{
84
- "setInOrder"=>{
85
85
  "first"=> [1],
86
86
  "second"=>[1, 5],
87
87
  "third"=> [1, 5, 2],
88
- }
89
88
  }}
90
89
  assert_equal(expected, result)
91
90
  end
92
91
  end
93
92
  end
93
+
94
+ describe 'context' do
95
+ let(:context_field) { GraphQL::Field.new do |f, types, field, args|
96
+ f.type(GraphQL::STRING_TYPE)
97
+ f.arguments(key: args.build(type: types.String))
98
+ f.resolve -> (target, args, ctx) { ctx[args["key"]] }
99
+ end}
100
+ let(:query_type) { GraphQL::ObjectType.new {|t| t.fields({context: context_field})}}
101
+ let(:schema) { GraphQL::Schema.new(query: query_type, mutation: nil)}
102
+ let(:query) { GraphQL::Query.new(schema, query_string, context: {"some_key" => "some value"})}
103
+ let(:query_string) { %|
104
+ query getCtx { context(key: "some_key") }
105
+ |}
106
+
107
+ it 'passes context to fields' do
108
+ expected = {"data" => {"context" => "some value"}}
109
+ assert_equal(expected, query.result)
110
+ end
111
+ end
94
112
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::ID_TYPE do
4
+ let(:query) { GraphQL::Query.new(DummySchema, query_string)}
5
+ let(:result) { query.result }
6
+
7
+ describe 'coercion for int inputs' do
8
+ let(:query_string) { %|query getMilk { cow: milk(id: 1) { id } }| }
9
+
10
+ it 'coerces IDs from ints and serializes as strings' do
11
+ expected = {"data" => {"cow" => {"id" => "1"}}}
12
+ assert_equal(expected, result)
13
+ end
14
+ end
15
+
16
+ describe 'coercion for string inputs' do
17
+ let(:query_string) { %|query getMilk { cow: milk(id: "1") { id } }| }
18
+
19
+ it 'coerces IDs from strings and serializes as strings' do
20
+ expected = {"data" => {"cow" => {"id" => "1"}}}
21
+ assert_equal(expected, result)
22
+ end
23
+ end
24
+ end
@@ -11,6 +11,7 @@ describe GraphQL::Schema::TypeReducer do
11
11
  "Float" => GraphQL::FLOAT_TYPE,
12
12
  "Edible" => EdibleInterface,
13
13
  "Milk" => MilkType,
14
+ "ID" => GraphQL::ID_TYPE,
14
15
  "AnimalProduct" => AnimalProductInterface,
15
16
  }
16
17
  assert_equal(expected.keys, reducer.result.keys)
@@ -45,7 +45,7 @@ describe GraphQL::Schema::TypeValidator do
45
45
  let(:errors) { e = []; GraphQL::Schema::TypeValidator.new.validate(object, e); e;}
46
46
  it 'must be 2+ types, must be only object types' do
47
47
  expected = [
48
- "Something.possible_types must be objects, but some aren't: <GraphQL::InputObjectType DairyProductInput>",
48
+ "Something.possible_types must be objects, but some aren't: DairyProductInput",
49
49
  "Union Something must be defined with 2 or more types, not 1",
50
50
  ]
51
51
  assert_equal(expected, errors)
@@ -14,7 +14,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
14
14
  }
15
15
  |)}
16
16
 
17
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::ArgumentLiteralsAreCompatible]) }
17
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::ArgumentLiteralsAreCompatible]) }
18
18
  let(:errors) { validator.validate(document) }
19
19
 
20
20
  it 'finds undefined arguments to fields and directives' do