graphql 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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