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)