Class: GraphWeaver::Testing::FakeClient
- Inherits:
-
Object
- Object
- GraphWeaver::Testing::FakeClient
- Includes:
- Selection
- Defined in:
- lib/graph_weaver/testing/fake_client.rb
Overview
A fake client that fabricates schema-correct responses for whatever query arrives — the zero-setup way to test code built on generated modules:
fake = GraphWeaver::Testing::FakeClient.new(schema:)
result = PersonQuery.execute!(id: "1", fake — positionally)
result.person.name # => a plausible String, typed and castable
Values are type-correct by construction (real enum values, valid __typename members for unions/interfaces, iso8601 for date scalars), so every fake response casts cleanly through the generated structs. See Values for value fabrication (mode: :faker / :literal).
overrides: pin fields by GraphQL name — schema vocabulary, so keys survive query refactors. "Type.field" beats "field"; values are literals or zero-arg procs. (An override with a wrong-typed value is also the way to simulate a corrupt payload — casting raises GraphWeaver::TypeError.)
FakeClient.new(schema:, overrides: {
"Person.name" => "Daniel",
"email" => -> { "test@example.com" },
})
Partial failures: fail_at simulates a field-level error with spec-correct null propagation — the field's error lands in the errors array (with its concrete path), the field becomes null, and nulls bubble past non-null positions to the nearest nullable ancestor, just like a real server:
FakeClient.new(schema:, fail_at: "person.pets.name")
FakeClient.new(schema:, fail_at: { path: "person.email", message: "hidden", code: "PRIVATE" })
errors: appends verbatim top-level errors alongside the fake data.
Type mismatches: corrupt: names fields ("Type.field") that should arrive wire-corrupted — a wrong-typed value derived from the schema, so casting raises GraphWeaver::TypeError. One spec checks the failure path; every other spec gets working data:
FakeClient.new(schema:, corrupt: "Person.birthday")
seed: makes a run reproducible (also seeds faker). Per-instance options fall back to GraphWeaver::Testing.config.
Constant Summary collapse
- NULL_BUBBLE =
sentinel: a simulated failure bubbling up to the nearest nullable spot
Object.new.freeze
Instance Method Summary collapse
- #execute(query, variables: {}) ⇒ Object
-
#initialize(schema:, overrides: {}, seed: nil, mode: nil, list_size: nil, null_chance: nil, errors: nil, fail_at: nil, corrupt: nil) ⇒ FakeClient
constructor
A new instance of FakeClient.
Methods included from Selection
#applies?, #each_field, #load_operation, #operation_root_type
Constructor Details
#initialize(schema:, overrides: {}, seed: nil, mode: nil, list_size: nil, null_chance: nil, errors: nil, fail_at: nil, corrupt: nil) ⇒ FakeClient
Returns a new instance of FakeClient.
56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/graph_weaver/testing/fake_client.rb', line 56 def initialize(schema:, overrides: {}, seed: nil, mode: nil, list_size: nil, null_chance: nil, errors: nil, fail_at: nil, corrupt: nil) config = GraphWeaver::Testing.config @schema = schema @overrides = config.overrides.merge(overrides) @values = GraphWeaver::Testing::Values.new(seed:, mode:) @list_size = list_size || config.list_size @null_chance = null_chance || config.null_chance # NOT Array(): it would explode a bare Hash into key/value pairs @extra_errors = wrap(errors).map { |error| normalize_error(error) } @fail_at = wrap(fail_at).map { |spec| normalize_fail_spec(spec) } @corrupt = wrap(corrupt) end |
Instance Method Details
#execute(query, variables: {}) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/graph_weaver/testing/fake_client.rb', line 70 def execute(query, variables: {}) operation = load_operation(query) root_type = operation_root_type(operation) @path = [] @failures = [] data = object_value(root_type, operation.selections) data = nil if data.equal?(NULL_BUBBLE) # total propagation, like a real server response = { "data" => data } errors = @failures + @extra_errors response["errors"] = errors unless errors.empty? response end |