graphql 0.18.15 → 0.19.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/graphql/define/assign_global_id_field.rb +1 -2
  3. data/lib/graphql/directive.rb +41 -7
  4. data/lib/graphql/directive/deprecated_directive.rb +11 -0
  5. data/lib/graphql/directive/include_directive.rb +2 -2
  6. data/lib/graphql/directive/skip_directive.rb +2 -2
  7. data/lib/graphql/input_object_type.rb +14 -0
  8. data/lib/graphql/internal_representation/node.rb +8 -4
  9. data/lib/graphql/introspection/arguments_field.rb +0 -1
  10. data/lib/graphql/introspection/directive_location_enum.rb +3 -2
  11. data/lib/graphql/introspection/directive_type.rb +12 -7
  12. data/lib/graphql/introspection/enum_value_type.rb +4 -2
  13. data/lib/graphql/introspection/enum_values_field.rb +0 -1
  14. data/lib/graphql/introspection/field_type.rb +8 -7
  15. data/lib/graphql/introspection/fields_field.rb +0 -1
  16. data/lib/graphql/introspection/input_fields_field.rb +0 -1
  17. data/lib/graphql/introspection/input_value_type.rb +8 -10
  18. data/lib/graphql/introspection/interfaces_field.rb +0 -1
  19. data/lib/graphql/introspection/of_type_field.rb +0 -1
  20. data/lib/graphql/introspection/possible_types_field.rb +0 -1
  21. data/lib/graphql/introspection/schema_type.rb +11 -9
  22. data/lib/graphql/introspection/type_kind_enum.rb +3 -3
  23. data/lib/graphql/introspection/type_type.rb +9 -6
  24. data/lib/graphql/language/generation.rb +4 -1
  25. data/lib/graphql/language/lexer.rb +353 -316
  26. data/lib/graphql/language/lexer.rl +8 -6
  27. data/lib/graphql/language/nodes.rb +12 -0
  28. data/lib/graphql/language/parser.rb +553 -501
  29. data/lib/graphql/language/parser.y +26 -16
  30. data/lib/graphql/language/parser_tests.rb +20 -1
  31. data/lib/graphql/list_type.rb +5 -1
  32. data/lib/graphql/non_null_type.rb +4 -0
  33. data/lib/graphql/object_type.rb +1 -1
  34. data/lib/graphql/query/literal_input.rb +1 -1
  35. data/lib/graphql/relay.rb +1 -1
  36. data/lib/graphql/relay/global_id_resolve.rb +3 -5
  37. data/lib/graphql/relay/node.rb +34 -0
  38. data/lib/graphql/scalar_type.rb +1 -1
  39. data/lib/graphql/schema.rb +43 -15
  40. data/lib/graphql/schema/loader.rb +2 -2
  41. data/lib/graphql/schema/printer.rb +50 -8
  42. data/lib/graphql/schema/unique_within_type.rb +28 -0
  43. data/lib/graphql/schema/validation.rb +10 -3
  44. data/lib/graphql/static_validation/rules/fields_will_merge.rb +9 -1
  45. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +8 -2
  46. data/lib/graphql/type_kinds.rb +12 -12
  47. data/lib/graphql/version.rb +1 -1
  48. data/readme.md +6 -5
  49. data/spec/graphql/argument_spec.rb +1 -1
  50. data/spec/graphql/execution_error_spec.rb +53 -0
  51. data/spec/graphql/introspection/directive_type_spec.rb +10 -0
  52. data/spec/graphql/introspection/input_value_type_spec.rb +23 -0
  53. data/spec/graphql/language/generation_spec.rb +4 -0
  54. data/spec/graphql/query/executor_spec.rb +2 -2
  55. data/spec/graphql/relay/mutation_spec.rb +1 -1
  56. data/spec/graphql/relay/node_spec.rb +87 -0
  57. data/spec/graphql/schema/catchall_middleware_spec.rb +1 -1
  58. data/spec/graphql/schema/loader_spec.rb +37 -4
  59. data/spec/graphql/schema/printer_spec.rb +30 -7
  60. data/spec/graphql/schema/unique_within_type_spec.rb +27 -0
  61. data/spec/graphql/schema/validation_spec.rb +7 -11
  62. data/spec/graphql/schema_spec.rb +32 -2
  63. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +14 -15
  64. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +10 -10
  65. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +1 -5
  66. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +3 -5
  67. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +7 -11
  68. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +1 -4
  69. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +10 -13
  70. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +3 -5
  71. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +2 -4
  72. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -6
  73. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -4
  74. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +7 -7
  75. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -4
  76. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -4
  77. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +3 -6
  78. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -4
  79. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +12 -14
  80. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +7 -9
  81. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +20 -22
  82. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +27 -23
  83. data/spec/spec_helper.rb +1 -0
  84. data/spec/support/dairy_app.rb +2 -2
  85. data/spec/support/star_wars_schema.rb +15 -18
  86. data/spec/support/static_validation_helpers.rb +27 -0
  87. metadata +25 -5
  88. data/lib/graphql/relay/global_node_identification.rb +0 -138
  89. data/spec/graphql/relay/global_node_identification_spec.rb +0 -153
@@ -9,6 +9,7 @@ require "minitest/autorun"
9
9
  require "minitest/focus"
10
10
  require "minitest/reporters"
11
11
  require "pry"
12
+ require 'pry-stack_explorer'
12
13
  Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
13
14
 
14
15
  Minitest::Spec.make_my_diffs_pretty!
@@ -62,7 +62,7 @@ CheeseType = GraphQL::ObjectType.define do
62
62
  field :similarCheese, CheeseType, "Cheeses like this one", property: :this_should_be_overriden do
63
63
  # metadata test
64
64
  joins [:cheeses, :milks]
65
- argument :source, !types[!DairyAnimalEnum]
65
+ argument :source, !types[!DairyAnimalEnum], default_value: [1]
66
66
  resolve -> (t, a, c) {
67
67
  # get the strings out:
68
68
  sources = a["source"]
@@ -235,7 +235,7 @@ end
235
235
  SourceFieldDefn = Proc.new {
236
236
  type GraphQL::ListType.new(of_type: CheeseType)
237
237
  description "Cheese from source"
238
- argument :source, DairyAnimalEnum, default_value: "COW"
238
+ argument :source, DairyAnimalEnum, default_value: 1
239
239
  resolve -> (target, arguments, context) {
240
240
  CHEESES.values.select{ |c| c.source == arguments["source"] }
241
241
  }
@@ -1,28 +1,16 @@
1
1
  # Adapted from graphql-relay-js
2
2
  # https://github.com/graphql/graphql-relay-js/blob/master/src/__tests__/starWarsSchema.js
3
3
 
4
- # This object exposes helpers for working with global IDs:
5
- # - global id creation & "decrypting"
6
- # - a find-object-by-global ID field
7
- # - an interface for Relay ObjectTypes to implement
8
- # See global_node_identification.rb for the full API.
9
- NodeIdentification = GraphQL::Relay::GlobalNodeIdentification.define do
10
- object_from_id -> (node_id, ctx) do
11
- type_name, id = NodeIdentification.from_global_id(node_id)
12
- STAR_WARS_DATA[type_name][id]
13
- end
14
- end
15
-
16
4
  Ship = GraphQL::ObjectType.define do
17
5
  name "Ship"
18
- interfaces [NodeIdentification.interface]
6
+ interfaces [GraphQL::Relay::Node.interface]
19
7
  global_id_field :id
20
8
  field :name, types.String
21
9
  end
22
10
 
23
11
  BaseType = GraphQL::ObjectType.define do
24
12
  name "Base"
25
- interfaces [NodeIdentification.interface]
13
+ interfaces [GraphQL::Relay::Node.interface]
26
14
  global_id_field :id
27
15
  field :name, types.String
28
16
  field :planet, types.String
@@ -69,9 +57,9 @@ end
69
57
 
70
58
  Faction = GraphQL::ObjectType.define do
71
59
  name "Faction"
72
- interfaces [NodeIdentification.interface]
60
+ interfaces [GraphQL::Relay::Node.interface]
73
61
 
74
- field :id, !types.ID, resolve: GraphQL::Relay::GlobalIdResolve.new(type_name: "Faction", property: :id)
62
+ field :id, !types.ID, resolve: GraphQL::Relay::GlobalIdResolve.new(type: Faction)
75
63
  field :name, types.String
76
64
  connection :ships, Ship.connection_type do
77
65
  resolve -> (obj, args, ctx) {
@@ -192,7 +180,7 @@ QueryType = GraphQL::ObjectType.define do
192
180
  resolve -> (obj, args, ctx) { Base.find(3) }
193
181
  end
194
182
 
195
- field :node, field: NodeIdentification.field
183
+ field :node, GraphQL::Relay::Node.field
196
184
  end
197
185
 
198
186
  MutationType = GraphQL::ObjectType.define do
@@ -204,7 +192,7 @@ end
204
192
  StarWarsSchema = GraphQL::Schema.define do
205
193
  query(QueryType)
206
194
  mutation(MutationType)
207
- node_identification(NodeIdentification)
195
+
208
196
  resolve_type -> (object, ctx) {
209
197
  if object == :test_error
210
198
  :not_a_type
@@ -218,4 +206,13 @@ StarWarsSchema = GraphQL::Schema.define do
218
206
  nil
219
207
  end
220
208
  }
209
+
210
+ object_from_id -> (node_id, ctx) do
211
+ type_name, id = GraphQL::Schema::UniqueWithinType.decode(node_id)
212
+ STAR_WARS_DATA[type_name][id]
213
+ end
214
+
215
+ id_from_object -> (object, type, ctx) do
216
+ GraphQL::Schema::UniqueWithinType.encode(type.name, object.id)
217
+ end
221
218
  end
@@ -0,0 +1,27 @@
1
+ # This module assumes you have `let(:query_string)` in your spec.
2
+ # It provides `errors` which are the validation errors for that string,
3
+ # as validated against `DummySchema`.
4
+ # You can override `schema` to provide another schema
5
+ # @example testing static validation
6
+ # include StaticValidationHelpers
7
+ # let(:query_string) { " ... " }
8
+ # it "validates" do
9
+ # assert_equal(errors, [ ... ])
10
+ # assert_equal(error_messages, [ ... ])
11
+ # end
12
+ module StaticValidationHelpers
13
+ def errors
14
+ target_schema = schema
15
+ validator = GraphQL::StaticValidation::Validator.new(schema: target_schema)
16
+ query = GraphQL::Query.new(target_schema, query_string)
17
+ validator.validate(query)[:errors]
18
+ end
19
+
20
+ def error_messages
21
+ errors.map { |e| e["message"] }
22
+ end
23
+
24
+ def schema
25
+ DummySchema
26
+ end
27
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.15
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-23 00:00:00.000000000 Z
11
+ date: 2016-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codeclimate-test-reporter
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-stack_explorer
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: guard
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -295,6 +309,7 @@ files:
295
309
  - lib/graphql/define/non_null_with_bang.rb
296
310
  - lib/graphql/define/type_definer.rb
297
311
  - lib/graphql/directive.rb
312
+ - lib/graphql/directive/deprecated_directive.rb
298
313
  - lib/graphql/directive/include_directive.rb
299
314
  - lib/graphql/directive/skip_directive.rb
300
315
  - lib/graphql/enum_type.rb
@@ -370,8 +385,8 @@ files:
370
385
  - lib/graphql/relay/edge.rb
371
386
  - lib/graphql/relay/edge_type.rb
372
387
  - lib/graphql/relay/global_id_resolve.rb
373
- - lib/graphql/relay/global_node_identification.rb
374
388
  - lib/graphql/relay/mutation.rb
389
+ - lib/graphql/relay/node.rb
375
390
  - lib/graphql/relay/page_info.rb
376
391
  - lib/graphql/relay/relation_connection.rb
377
392
  - lib/graphql/scalar_type.rb
@@ -387,6 +402,7 @@ files:
387
402
  - lib/graphql/schema/timeout_middleware.rb
388
403
  - lib/graphql/schema/type_expression.rb
389
404
  - lib/graphql/schema/type_map.rb
405
+ - lib/graphql/schema/unique_within_type.rb
390
406
  - lib/graphql/schema/validation.rb
391
407
  - lib/graphql/static_validation.rb
392
408
  - lib/graphql/static_validation/all_rules.rb
@@ -466,8 +482,8 @@ files:
466
482
  - spec/graphql/relay/array_connection_spec.rb
467
483
  - spec/graphql/relay/connection_field_spec.rb
468
484
  - spec/graphql/relay/connection_type_spec.rb
469
- - spec/graphql/relay/global_node_identification_spec.rb
470
485
  - spec/graphql/relay/mutation_spec.rb
486
+ - spec/graphql/relay/node_spec.rb
471
487
  - spec/graphql/relay/page_info_spec.rb
472
488
  - spec/graphql/relay/relation_connection_spec.rb
473
489
  - spec/graphql/scalar_type_spec.rb
@@ -479,6 +495,7 @@ files:
479
495
  - spec/graphql/schema/rescue_middleware_spec.rb
480
496
  - spec/graphql/schema/timeout_middleware_spec.rb
481
497
  - spec/graphql/schema/type_expression_spec.rb
498
+ - spec/graphql/schema/unique_within_type_spec.rb
482
499
  - spec/graphql/schema/validation_spec.rb
483
500
  - spec/graphql/schema_spec.rb
484
501
  - spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb
@@ -511,6 +528,7 @@ files:
511
528
  - spec/support/minimum_input_object.rb
512
529
  - spec/support/star_wars_data.rb
513
530
  - spec/support/star_wars_schema.rb
531
+ - spec/support/static_validation_helpers.rb
514
532
  homepage: http://github.com/rmosolgo/graphql-ruby
515
533
  licenses:
516
534
  - MIT
@@ -581,8 +599,8 @@ test_files:
581
599
  - spec/graphql/relay/array_connection_spec.rb
582
600
  - spec/graphql/relay/connection_field_spec.rb
583
601
  - spec/graphql/relay/connection_type_spec.rb
584
- - spec/graphql/relay/global_node_identification_spec.rb
585
602
  - spec/graphql/relay/mutation_spec.rb
603
+ - spec/graphql/relay/node_spec.rb
586
604
  - spec/graphql/relay/page_info_spec.rb
587
605
  - spec/graphql/relay/relation_connection_spec.rb
588
606
  - spec/graphql/scalar_type_spec.rb
@@ -594,6 +612,7 @@ test_files:
594
612
  - spec/graphql/schema/rescue_middleware_spec.rb
595
613
  - spec/graphql/schema/timeout_middleware_spec.rb
596
614
  - spec/graphql/schema/type_expression_spec.rb
615
+ - spec/graphql/schema/unique_within_type_spec.rb
597
616
  - spec/graphql/schema/validation_spec.rb
598
617
  - spec/graphql/schema_spec.rb
599
618
  - spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb
@@ -626,3 +645,4 @@ test_files:
626
645
  - spec/support/minimum_input_object.rb
627
646
  - spec/support/star_wars_data.rb
628
647
  - spec/support/star_wars_schema.rb
648
+ - spec/support/static_validation_helpers.rb
@@ -1,138 +0,0 @@
1
- require 'singleton'
2
- module GraphQL
3
- module Relay
4
- # This object provides helpers for working with global IDs.
5
- # It's assumed you'll only have 1!
6
- #
7
- # GlobalIdField depends on that, since it calls class methods
8
- # which delegate to the singleton instance.
9
- #
10
- class GlobalNodeIdentification
11
- include GraphQL::Define::InstanceDefinable
12
- accepts_definitions(:object_from_id, :type_from_object, :to_global_id, :from_global_id, :description)
13
- lazy_defined_attr_accessor :description
14
-
15
- # Memoize the schema to support deprecated node_ident-level resolve functions
16
- # TODO: remove after Schema.resolve_type is required
17
- attr_accessor :schema
18
-
19
- class << self
20
- attr_accessor :id_separator
21
- end
22
-
23
- self.id_separator = "-"
24
-
25
- def initialize
26
- @to_global_id_proc = DEFAULT_TO_GLOBAL_ID
27
- @from_global_id_proc = DEFAULT_FROM_GLOBAL_ID
28
- end
29
-
30
- # Returns `NodeInterface`, which all Relay types must implement
31
- def interface
32
- @interface ||= begin
33
- ensure_defined
34
- ident = self
35
- if @type_from_object_proc
36
- # TODO: remove after Schema.resolve_type is required
37
- GraphQL::InterfaceType.define do
38
- name "Node"
39
- field :id, !types.ID
40
- resolve_type -> (obj, ctx) {
41
- ident.type_from_object(obj)
42
- }
43
- end
44
- else
45
- GraphQL::InterfaceType.define do
46
- name "Node"
47
- field :id, !types.ID
48
- end
49
- end
50
- end
51
- end
52
-
53
- # Returns a field for finding objects from a global ID, which Relay needs
54
- def field
55
- ensure_defined
56
- ident = self
57
- GraphQL::Field.define do
58
- type(ident.interface)
59
- argument :id, !types.ID
60
- resolve -> (obj, args, ctx) {
61
- ctx.query.schema.node_identification.object_from_id(args[:id], ctx)
62
- }
63
- description ident.description
64
- end
65
- end
66
-
67
- DEFAULT_TO_GLOBAL_ID = -> (type_name, id) {
68
- id_str = id.to_s
69
- if type_name.include?(self.id_separator) || id_str.include?(self.id_separator)
70
- raise "to_global_id(#{type_name}, #{id}) contains reserved characters `#{self.id_separator}`"
71
- end
72
- Base64.strict_encode64([type_name, id_str].join(self.id_separator))
73
- }
74
-
75
- DEFAULT_FROM_GLOBAL_ID = -> (global_id) {
76
- Base64.decode64(global_id).split(self.id_separator)
77
- }
78
-
79
- # Create a global ID for type-name & ID
80
- # (This is an opaque transform)
81
- def to_global_id(type_name, id)
82
- ensure_defined
83
- @to_global_id_proc.call(type_name, id)
84
- end
85
-
86
- def to_global_id=(proc)
87
- ensure_defined
88
- @to_global_id_proc = proc
89
- end
90
-
91
- # Get type-name & ID from global ID
92
- # (This reverts the opaque transform)
93
- def from_global_id(global_id)
94
- ensure_defined
95
- @from_global_id_proc.call(global_id)
96
- end
97
-
98
- def from_global_id=(proc)
99
- ensure_defined
100
- @from_global_id_proc = proc
101
- end
102
-
103
- # Use the provided config to
104
- # get a type for a given object
105
- # TODO: remove after Schema.resolve_type is required
106
- def type_from_object(object)
107
- ensure_defined
108
- warn("type_from_object(object) is deprecated; use Schema.resolve_type(object) instead")
109
-
110
- if @type_from_object_proc
111
- type_from_obj = @type_from_object_proc
112
- schema.resolve_type = -> (obj, ctx) { type_from_obj.call(obj) }
113
- @type_from_object_proc = nil
114
- end
115
-
116
- schema.resolve_type(object, nil)
117
- end
118
-
119
- def type_from_object=(new_type_from_object_proc)
120
- ensure_defined
121
- warn("type_from_object(object) is deprecated; use Schema.resolve_type(object) instead")
122
- @type_from_object_proc = new_type_from_object_proc
123
- end
124
-
125
- # Use the provided config to
126
- # get an object from a UUID
127
- def object_from_id(id, ctx)
128
- ensure_defined
129
- @object_from_id_proc.call(id, ctx)
130
- end
131
-
132
- def object_from_id=(proc)
133
- ensure_defined
134
- @object_from_id_proc = proc
135
- end
136
- end
137
- end
138
- end
@@ -1,153 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe GraphQL::Relay::GlobalNodeIdentification do
4
- let(:node_identification) { StarWarsSchema.node_identification }
5
- describe 'NodeField' do
6
- it 'finds objects by id' do
7
- global_id = node_identification.to_global_id("Faction", "1")
8
- result = star_wars_query(%|{
9
- node(id: "#{global_id}") {
10
- id,
11
- ... on Faction {
12
- name
13
- ships(first: 1) {
14
- edges {
15
- node {
16
- name
17
- }
18
- }
19
- }
20
- }
21
- }
22
- }|)
23
- expected = {"data" => {
24
- "node"=>{
25
- "id"=>"RmFjdGlvbi0x",
26
- "name"=>"Alliance to Restore the Republic",
27
- "ships"=>{
28
- "edges"=>[
29
- {"node"=>{
30
- "name" => "X-Wing"
31
- }
32
- }
33
- ]
34
- }
35
- }
36
- }}
37
- assert_equal(expected, result)
38
- end
39
- end
40
-
41
- after do
42
- # Set the id_separator back to it's default after each spec, since some of
43
- # them change it at runtime
44
- GraphQL::Relay::GlobalNodeIdentification.id_separator = "-"
45
- end
46
-
47
- describe 'id_separator' do
48
- it "allows you to change it at runtime" do
49
- GraphQL::Relay::GlobalNodeIdentification.id_separator = "-zomg-"
50
-
51
- assert_equal("-zomg-", GraphQL::Relay::GlobalNodeIdentification.id_separator)
52
- end
53
- end
54
-
55
- describe "type_from_object" do
56
- it "works even though it's deprecated" do
57
- thing_type = GraphQL::ObjectType.define do
58
- name "Thing"
59
- global_id_field :id
60
- field :object_id, types.Int
61
- end
62
-
63
- node_ident = GraphQL::Relay::GlobalNodeIdentification.define do
64
- type_from_object -> (obj) { thing_type }
65
- end
66
-
67
- schema = GraphQL::Schema.define do
68
- node_identification(node_ident)
69
- end
70
-
71
- schema.send(:ensure_defined)
72
- assert_equal thing_type, node_ident.type_from_object(nil)
73
- assert_equal thing_type, schema.resolve_type(nil, nil)
74
- end
75
- end
76
-
77
- describe 'to_global_id / from_global_id ' do
78
- it 'Converts typename and ID to and from ID' do
79
- global_id = node_identification.to_global_id("SomeType", 123)
80
- type_name, id = node_identification.from_global_id(global_id)
81
- assert_equal("SomeType", type_name)
82
- assert_equal("123", id)
83
- end
84
-
85
- it "allows you to change the id_separator" do
86
- GraphQL::Relay::GlobalNodeIdentification.id_separator = "---"
87
-
88
- global_id = node_identification.to_global_id("Type-With-UUID", "250cda0e-a89d-41cf-99e1-2872d89f1100")
89
- type_name, id = node_identification.from_global_id(global_id)
90
- assert_equal("Type-With-UUID", type_name)
91
- assert_equal("250cda0e-a89d-41cf-99e1-2872d89f1100", id)
92
- end
93
-
94
- it "raises an error if you try and use a reserved character in the ID" do
95
- err = assert_raises(RuntimeError) {
96
- node_identification.to_global_id("Best-Thing", "234")
97
- }
98
- assert_includes err.message, "to_global_id(Best-Thing, 234) contains reserved characters `-`"
99
- end
100
-
101
- describe "custom definitions" do
102
- let(:custom_node_identification) {
103
- ident = GraphQL::Relay::GlobalNodeIdentification.define do
104
- to_global_id -> (type_name, id) {
105
- "#{type_name}/#{id}"
106
- }
107
-
108
- from_global_id -> (global_id) {
109
- global_id.split("/")
110
- }
111
-
112
- object_from_id -> (node_id, ctx) do
113
- type_name, id = ident.from_global_id(node_id)
114
- STAR_WARS_DATA[type_name][id]
115
- end
116
-
117
- description "Hello, World!"
118
- end
119
- }
120
-
121
- before do
122
- @prev_node_identification = StarWarsSchema.node_identification
123
- StarWarsSchema.node_identification = custom_node_identification
124
- end
125
-
126
- after do
127
- StarWarsSchema.node_identification = @prev_node_identification
128
- end
129
-
130
- describe "generating IDs" do
131
- it "Applies custom-defined ID generation" do
132
- result = star_wars_query(%| { largestBase { id } }|)
133
- generated_id = result["data"]["largestBase"]["id"]
134
- assert_equal "Base/3", generated_id
135
- end
136
- end
137
-
138
- describe "fetching by ID" do
139
- it "Deconstructs the ID by the custom proc" do
140
- result = star_wars_query(%| { node(id: "Base/1") { ... on Base { name } } }|)
141
- base_name = result["data"]["node"]["name"]
142
- assert_equal "Yavin", base_name
143
- end
144
- end
145
-
146
- describe "setting a description" do
147
- it "allows you to set a description" do
148
- assert_equal "Hello, World!", custom_node_identification.field.description
149
- end
150
- end
151
- end
152
- end
153
- end