module GraphQL::Compatibility::LazyExecutionSpecification

Attributes

lazy_schema[RW]

Public Class Methods

build_suite(execution_strategy) click to toggle source

@param execution_strategy [<#new, execute>] An execution strategy class @return [Class<Minitest::Test>] A test suite for this execution strategy

# File lib/graphql/compatibility/lazy_execution_specification.rb, line 8
def self.build_suite(execution_strategy)
  Class.new(Minitest::Test) do
    class << self
      attr_accessor :lazy_schema
    end

    self.lazy_schema = LazySchema.build(execution_strategy)

    def test_it_resolves_lazy_values
      pushes = []
      query_str = %Q|
      {
        p1: push(value: 1) {
          value
        }
        p2: push(value: 2) {
          push(value: 3) {
            value
            push(value: 21) {
              value
            }
          }
        }
        p3: push(value: 4) {
          push(value: 5) {
            value
            push(value: 22) {
              value
            }
          }
        }
      }
      |
      res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})

      expected_data = {
        "p1"=>{"value"=>1},
        "p2"=>{"push"=>{"value"=>3, "push"=>{"value"=>21}}},
        "p3"=>{"push"=>{"value"=>5, "push"=>{"value"=>22}}},
      }
      assert_equal expected_data, res["data"]

      expected_pushes = [
        [1,2,4], # first level
        [3,5], # second level
        [21, 22],
      ]
      assert_equal expected_pushes, pushes
    end

    def test_it_maintains_path
      query_str = %Q|
      {
        push(value: 2) {
          push(value: 3) {
            fail1: push(value: 14) {
              value
            }
            fail2: push(value: 14) {
              value
            }
          }
        }
      }
      |
      res = self.class.lazy_schema.execute(query_str, context: {pushes: []})
      assert_equal nil, res["data"]
      # The first fail causes the second field to never resolve
      assert_equal 1, res["errors"].length
      assert_equal ["push", "push", "fail1", "value"], res["errors"][0]["path"]
    end

    def test_it_resolves_mutation_values_eagerly
      pushes = []
      query_str = %Q|
      mutation {
        p1: push(value: 1) {
          value
        }
        p2: push(value: 2) {
          push(value: 3) {
            value
          }
        }
        p3: push(value: 4) {
          p5: push(value: 5) {
            value
          }
          p6: push(value: 6) {
            value
          }
        }
      }
      |
      res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})

      expected_data = {
        "p1"=>{"value"=>1},
        "p2"=>{"push"=>{"value"=>3}},
        "p3"=>{"p5"=>{"value"=>5},"p6"=>{"value"=>6}},
      }
      assert_equal expected_data, res["data"]

      expected_pushes = [
        [1],        # first operation
        [2], [3],   # second operation
        [4], [5, 6], # third operation
      ]
      assert_equal expected_pushes, pushes
    end

    def test_it_resolves_lazy_connections
      pushes = []
      query_str = %Q|
      {
        pushes(values: [1,2,3]) {
          edges {
            node {
              value
              push(value: 4) {
                value
              }
            }
          }
        }
      }
      |
      res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})

      expected_edges = [
        {"node"=>{"value"=>1, "push"=>{"value"=>4}}},
        {"node"=>{"value"=>2, "push"=>{"value"=>4}}},
        {"node"=>{"value"=>3, "push"=>{"value"=>4}}},
      ]
      assert_equal expected_edges, res["data"]["pushes"]["edges"]
      assert_equal [[1, 2, 3], [4, 4, 4]], pushes
    end

    def test_it_calls_lazy_resolve_instrumentation
      query_str = %Q|
      {
        p1: push(value: 1) {
          value
        }
        p2: push(value: 2) {
          push(value: 3) {
            value
          }
        }
        pushes(values: [1,2,3]) {
          edges {
            node {
              value
              push(value: 4) {
                value
              }
            }
          }
        }
      }
      |

      log = []
      self.class.lazy_schema.execute(query_str, context: {lazy_instrumentation: log, pushes: []})
      expected_log = [
        "PUSH",
        "Query.push: 1",
        "Query.push: 2",
        "Query.pushes: [1, 2, 3]",
        "PUSH",
        "LazyPush.push: 3",
        "LazyPushEdge.node: 1",
        "LazyPushEdge.node: 2",
        "LazyPushEdge.node: 3",
        "PUSH",
        "LazyPush.push: 4",
        "LazyPush.push: 4",
        "LazyPush.push: 4",
      ]
      assert_equal expected_log, log
    end

    def test_it_skips_ctx_skip
      query_string = <<-GRAPHQL
      {
        p0: push(value: 15) { value }
        p1: push(value: 1) { value }
        p2: push(value: 2) {
          value
          p3: push(value: 15) {
            value
          }
        }
      }
      GRAPHQL
      pushes = []
      res = self.class.lazy_schema.execute(query_string, context: {pushes: pushes})
      assert_equal [[1,2]], pushes
      assert_equal({"data"=>{"p1"=>{"value"=>1}, "p2"=>{"value"=>2}}}, res)
    end
  end
end

Public Instance Methods

test_it_calls_lazy_resolve_instrumentation() click to toggle source
# File lib/graphql/compatibility/lazy_execution_specification.rb, line 146
def test_it_calls_lazy_resolve_instrumentation
  query_str = %Q|
  {
    p1: push(value: 1) {
      value
    }
    p2: push(value: 2) {
      push(value: 3) {
        value
      }
    }
    pushes(values: [1,2,3]) {
      edges {
        node {
          value
          push(value: 4) {
            value
          }
        }
      }
    }
  }
  |

  log = []
  self.class.lazy_schema.execute(query_str, context: {lazy_instrumentation: log, pushes: []})
  expected_log = [
    "PUSH",
    "Query.push: 1",
    "Query.push: 2",
    "Query.pushes: [1, 2, 3]",
    "PUSH",
    "LazyPush.push: 3",
    "LazyPushEdge.node: 1",
    "LazyPushEdge.node: 2",
    "LazyPushEdge.node: 3",
    "PUSH",
    "LazyPush.push: 4",
    "LazyPush.push: 4",
    "LazyPush.push: 4",
  ]
  assert_equal expected_log, log
end
test_it_maintains_path() click to toggle source
# File lib/graphql/compatibility/lazy_execution_specification.rb, line 58
def test_it_maintains_path
  query_str = %Q|
  {
    push(value: 2) {
      push(value: 3) {
        fail1: push(value: 14) {
          value
        }
        fail2: push(value: 14) {
          value
        }
      }
    }
  }
  |
  res = self.class.lazy_schema.execute(query_str, context: {pushes: []})
  assert_equal nil, res["data"]
  # The first fail causes the second field to never resolve
  assert_equal 1, res["errors"].length
  assert_equal ["push", "push", "fail1", "value"], res["errors"][0]["path"]
end
test_it_resolves_lazy_connections() click to toggle source
# File lib/graphql/compatibility/lazy_execution_specification.rb, line 119
def test_it_resolves_lazy_connections
  pushes = []
  query_str = %Q|
  {
    pushes(values: [1,2,3]) {
      edges {
        node {
          value
          push(value: 4) {
            value
          }
        }
      }
    }
  }
  |
  res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})

  expected_edges = [
    {"node"=>{"value"=>1, "push"=>{"value"=>4}}},
    {"node"=>{"value"=>2, "push"=>{"value"=>4}}},
    {"node"=>{"value"=>3, "push"=>{"value"=>4}}},
  ]
  assert_equal expected_edges, res["data"]["pushes"]["edges"]
  assert_equal [[1, 2, 3], [4, 4, 4]], pushes
end
test_it_resolves_lazy_values() click to toggle source
# File lib/graphql/compatibility/lazy_execution_specification.rb, line 16
def test_it_resolves_lazy_values
  pushes = []
  query_str = %Q|
  {
    p1: push(value: 1) {
      value
    }
    p2: push(value: 2) {
      push(value: 3) {
        value
        push(value: 21) {
          value
        }
      }
    }
    p3: push(value: 4) {
      push(value: 5) {
        value
        push(value: 22) {
          value
        }
      }
    }
  }
  |
  res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})

  expected_data = {
    "p1"=>{"value"=>1},
    "p2"=>{"push"=>{"value"=>3, "push"=>{"value"=>21}}},
    "p3"=>{"push"=>{"value"=>5, "push"=>{"value"=>22}}},
  }
  assert_equal expected_data, res["data"]

  expected_pushes = [
    [1,2,4], # first level
    [3,5], # second level
    [21, 22],
  ]
  assert_equal expected_pushes, pushes
end
test_it_resolves_mutation_values_eagerly() click to toggle source
# File lib/graphql/compatibility/lazy_execution_specification.rb, line 80
def test_it_resolves_mutation_values_eagerly
  pushes = []
  query_str = %Q|
  mutation {
    p1: push(value: 1) {
      value
    }
    p2: push(value: 2) {
      push(value: 3) {
        value
      }
    }
    p3: push(value: 4) {
      p5: push(value: 5) {
        value
      }
      p6: push(value: 6) {
        value
      }
    }
  }
  |
  res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})

  expected_data = {
    "p1"=>{"value"=>1},
    "p2"=>{"push"=>{"value"=>3}},
    "p3"=>{"p5"=>{"value"=>5},"p6"=>{"value"=>6}},
  }
  assert_equal expected_data, res["data"]

  expected_pushes = [
    [1],        # first operation
    [2], [3],   # second operation
    [4], [5, 6], # third operation
  ]
  assert_equal expected_pushes, pushes
end
test_it_skips_ctx_skip() click to toggle source
# File lib/graphql/compatibility/lazy_execution_specification.rb, line 190
def test_it_skips_ctx_skip
  query_string = <<-GRAPHQL
  {
    p0: push(value: 15) { value }
    p1: push(value: 1) { value }
    p2: push(value: 2) {
      value
      p3: push(value: 15) {
        value
      }
    }
  }
  GRAPHQL
  pushes = []
  res = self.class.lazy_schema.execute(query_string, context: {pushes: pushes})
  assert_equal [[1,2]], pushes
  assert_equal({"data"=>{"p1"=>{"value"=>1}, "p2"=>{"value"=>2}}}, res)
end