spec/graphql/query/context_spec.rb in graphql-1.6.8 vs spec/graphql/query/context_spec.rb in graphql-1.7.0

- old
+ new

@@ -3,39 +3,106 @@ describe GraphQL::Query::Context do CTX = [] before { CTX.clear } - let(:query_type) { GraphQL::ObjectType.define { - name "Query" - field :context, types.String do - argument :key, !types.String - resolve ->(target, args, ctx) { ctx[args[:key]] } + let(:parent_info_type) { + GraphQL::ObjectType.define { + name "ParentInfo" + field :object, types.String do + resolve ->(o, a, c) { c.parent.parent.object } + end + field :objectClassName, types.String do + resolve ->(o, a, c) { c.parent.parent.object.class.name } + end + field :valueClassName, types.String do + resolve ->(o, a, c) { c.parent.parent.value.class.name } + end + field :value, types.String do + resolve ->(o, a, c) { c.parent.parent.value.to_s } + end + } + } + let(:backtrace_type) { + GraphQL::ObjectType.define do + name "Backtrace" + field :backtraceEntry, types.String do + argument :idx, !types.Int + resolve ->(o, a, c) { c.backtrace[a[:idx]] } + end + field :backtraceArray, types[types.String] do + resolve ->(o, a, c) { c.backtrace.to_a } + end + field :backtraceTable, types.String do + resolve ->(o, a, c) { c.backtrace.inspect } + end end - field :contextAstNodeName, types.String do - resolve ->(target, args, ctx) { ctx.ast_node.class.name } - end - field :contextIrepNodeName, types.String do - resolve ->(target, args, ctx) { ctx.irep_node.class.name } - end - field :queryName, types.String do - resolve ->(target, args, ctx) { ctx.query.class.name } - end + } + let(:query_type) { + parent_info = parent_info_type + backtrace = backtrace_type + GraphQL::ObjectType.define { + name "Query" + field :context, types.String do + argument :key, !types.String + resolve ->(target, args, ctx) { ctx[args[:key]] } + end + field :contextAstNodeName, types.String do + resolve ->(target, args, ctx) { ctx.ast_node.class.name } + end + field :contextIrepNodeName, types.String do + resolve ->(target, args, ctx) { ctx.irep_node.class.name } + end + field :queryName, types.String do + resolve ->(target, args, ctx) { ctx.query.class.name } + end - field :pushContext, types.Int do - resolve ->(t,a,c) { CTX << c; 1 } - end + field :pushContext, types.Int do + resolve ->(t,a,c) { CTX << c; 1 } + end - field :pushQueryError, types.Int do - resolve ->(t,a,c) { - c.query.context.add_error(GraphQL::ExecutionError.new("Query-level error")) - 1 + field :pushQueryError, types.Int do + resolve ->(t,a,c) { + c.query.context.add_error(GraphQL::ExecutionError.new("Query-level error")) + 1 + } + end + + field :parentInfo, parent_info, resolve: ->(o,a,c) { :noop } + field :backtrace, backtrace, resolve: Proc.new { :noop } + } + } + + let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)} + let(:result) { schema.execute(query_string, root_value: "rootval", context: {"some_key" => "some value"})} + + describe "access to parent context" do + let(:query_string) { %| + { + parentInfo { + value + valueClassName + object + objectClassName + } } + |} + + it "exposes the parent object" do + expected = { + "data" => { + "parentInfo" => { + "objectClassName" => "String", + "object" => "rootval", + "value" => "{}", + "valueClassName" => "Hash", + } + } + } + assert_equal(expected, result) end - }} - let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)} - let(:result) { schema.execute(query_string, context: {"some_key" => "some value"})} + end describe "access to passed-in values" do let(:query_string) { %| query getCtx { context(key: "some_key") } |} @@ -55,10 +122,50 @@ expected = {"data" => {"contextAstNodeName" => "GraphQL::Language::Nodes::Field"}} assert_equal(expected, result) end end + describe "#backtrace" do + let(:query_string) { %| + query { + backtrace { + b1: backtraceEntry(idx: 0) + b2: backtraceEntry(idx: 1) + b3: backtraceEntry(idx: 2) + backtraceArray + backtraceTable + } + pushContext + } + |} + + it "exposes the GraphQL backtrace" do + backtrace_result = result.fetch("data").fetch("backtrace") + assert_equal "4:11: Backtrace.backtraceEntry as b1", backtrace_result.fetch("b1") + assert_equal "3:9: Query.backtrace", backtrace_result.fetch("b2") + assert_equal "2:7: query", backtrace_result.fetch("b3") + assert_equal ["7:11: Backtrace.backtraceArray", "3:9: Query.backtrace", "2:7: query"], backtrace_result.fetch("backtraceArray") + expected_table = [ + 'Loc | Field | Object | Arguments | Result', + '8:11 | Backtrace.backtraceTable | :noop | {} | nil', + '3:9 | Query.backtrace | "rootval" | {} | {b1: "4:11: Backtrace.backtraceEntry as b1", b2: "3:9: Query.backtrace", b3: "2:7: query", backtr...', + '2:7 | query | "rootval" | {} | {}', + '', + ].join("\n") + assert_equal expected_table, backtrace_result.fetch("backtraceTable") + + expected_table_2 = <<-TABLE +Loc | Field | Object | Arguments | Result +10:9 | Query.pushContext | "rootval" | {} | 1 +2:7 | query | "rootval" | {} | {backtrace: {...}, pushContext: 1} +TABLE + + ctx = CTX.last + assert_equal expected_table_2, ctx.backtrace.to_s + end + end + describe "access to the InternalRepresentation node" do let(:query_string) { %| query getCtx { contextIrepNodeName } |} @@ -78,29 +185,29 @@ assert_equal(expected, result) end end describe "empty values" do - let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil) } + let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil, object: nil) } it "returns returns nil and reports key? => false" do assert_equal(nil, context[:some_key]) assert_equal(false, context.key?(:some_key)) assert_raises(KeyError) { context.fetch(:some_key) } end end describe "assigning values" do - let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil) } + let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil, object: nil) } it "allows you to assign new contexts" do assert_equal(nil, context[:some_key]) context[:some_key] = "wow!" assert_equal("wow!", context[:some_key]) end describe "namespaces" do - let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: {a: 1}) } + let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: {a: 1}, object: nil) } it "doesn't conflict with base values" do ns = context.namespace(:stuff) ns[:b] = 2 assert_equal({a: 1}, context.to_h)