Skip to content

Commit bec141a

Browse files
authored
Merge pull request #12 from ElvinEfendi/allow-new-enum-values-config
Allow new enum values config
2 parents 925e3c7 + 99e2ea3 commit bec141a

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

lib/graphql/client.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def self.dump_schema(schema, io = nil, context: {})
9191
result
9292
end
9393

94-
def initialize(schema:, execute: nil, enforce_collocated_callers: false)
94+
def initialize(schema:, execute: nil, enforce_collocated_callers: false, raise_on_unknown_enum_value: true)
9595
@schema = self.class.load_schema(schema)
9696
@execute = execute
9797
@document = GraphQL::Language::Nodes::Document.new(definitions: [])
@@ -101,7 +101,7 @@ def initialize(schema:, execute: nil, enforce_collocated_callers: false)
101101
if schema.is_a?(Class)
102102
@possible_types = schema.possible_types
103103
end
104-
@types = Schema.generate(@schema)
104+
@types = Schema.generate(@schema, raise_on_unknown_enum_value: raise_on_unknown_enum_value)
105105
end
106106

107107
# A cache of the schema's merged possible types

lib/graphql/client/schema.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def get_class(type_name)
4343
def set_class(type_name, klass)
4444
class_name = normalize_type_name(type_name)
4545

46-
if constants.include?(class_name.to_sym)
46+
if const_defined?(class_name, false)
4747
raise ArgumentError,
4848
"Can't define #{class_name} to represent type #{type_name} " \
4949
"because it's already defined"
@@ -66,9 +66,10 @@ def normalize_type_name(type_name)
6666
end
6767
end
6868

69-
def self.generate(schema)
69+
def self.generate(schema, raise_on_unknown_enum_value: true)
7070
mod = Module.new
7171
mod.extend ClassMethods
72+
mod.define_singleton_method(:raise_on_unknown_enum_value) { raise_on_unknown_enum_value }
7273

7374
cache = {}
7475
schema.types.each do |name, type|

lib/graphql/client/schema/enum_type.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ def initialize(obj, enum_value, enum)
1616
@enum = enum
1717
end
1818

19+
def unknown_enum_value?
20+
false
21+
end
22+
1923
def respond_to_missing?(method_name, include_private = false)
2024
if method_name[-1] == "?" && @enum.include?(method_name[0..-2])
2125
true
@@ -37,6 +41,12 @@ def method_missing(method_name, *args)
3741
end
3842
end
3943

44+
class UnexpectedEnumValue < String
45+
def unknown_enum_value?
46+
true
47+
end
48+
end
49+
4050
# Internal: Construct enum wrapper from another GraphQL::EnumType.
4151
#
4252
# type - GraphQL::EnumType instance
@@ -78,8 +88,13 @@ def [](value)
7888
def cast(value, _errors = nil)
7989
case value
8090
when String
81-
raise Error, "unexpected enum value #{value}" unless @values.key?(value)
82-
@values[value]
91+
if @values.key?(value)
92+
@values[value]
93+
elsif schema_module.raise_on_unknown_enum_value
94+
raise Error, "unexpected enum value #{value}"
95+
else
96+
UnexpectedEnumValue.new(value).freeze
97+
end
8398
when NilClass
8499
value
85100
else

test/test_schema.rb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def self.resolve_type(_type, _obj, _ctx)
7373
end
7474
end
7575

76-
Types = GraphQL::Client::Schema.generate(Schema)
76+
Types = GraphQL::Client::Schema.generate(Schema, raise_on_unknown_enum_value: true)
7777

7878
def test_query_object_class
7979
assert_equal QueryType, Types::Query.type
@@ -149,6 +149,34 @@ def test_plan_enum_constants
149149
refute Types::Plan::SMALL.free?
150150
assert Types::Plan::SMALL.small?
151151
refute Types::Plan::SMALL.large?
152+
153+
assert_raises GraphQL::Client::Error do
154+
Types::Plan.cast("unknown_value")
155+
end
156+
end
157+
158+
def test_unknown_enum_values
159+
size = Class.new(GraphQL::Schema::Enum) do
160+
graphql_name "Size"
161+
value "SMALL"
162+
value "MEDIUM"
163+
value "LARGE"
164+
end
165+
166+
query_type = Class.new(GraphQL::Schema::Object) do
167+
graphql_name "Query"
168+
field :size, size, null: false
169+
end
170+
171+
schema = Class.new(GraphQL::Schema) do
172+
query query_type
173+
end
174+
175+
types = GraphQL::Client::Schema.generate(schema, raise_on_unknown_enum_value: false)
176+
177+
assert_equal "unknown_value", types::Size.cast("unknown_value")
178+
assert types::Size.cast("unknown_value").unknown_enum_value?
179+
refute types::Size.cast("SMALL").unknown_enum_value?
152180
end
153181

154182
def test_to_non_null_type

0 commit comments

Comments
 (0)