Skip to content

Commit 9bf9f7e

Browse files
author
wesleyjellis
authored
Merge pull request #8 from Shopify/explicit_null_input
Allow manually specifying nil on input objects
2 parents 726193b + 25bde02 commit 9bf9f7e

File tree

2 files changed

+49
-10
lines changed

2 files changed

+49
-10
lines changed

codegen/lib/graphql_swift_gen/templates/type.swift.erb

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,33 +210,54 @@ extension <%= schema_name %> {
210210
}
211211
<% when 'INPUT_OBJECT' %>
212212
open class <%= type.name %> {
213-
<% type.input_fields.each do |field| %>
213+
<% type.required_input_fields.each do |field| %>
214214
open var <%= escape_reserved_word(field.camelize_name) %>: <%= swift_input_type(field.type) %>
215215
<% end %>
216+
<% type.optional_input_fields.each do |field| %>
217+
open var <%= escape_reserved_word(field.camelize_name) %>: <%= swift_input_type(field.type) %> {
218+
didSet {
219+
<%= escape_reserved_word(field.camelize_name) %>Seen = true
220+
}
221+
}
222+
private var <%= escape_reserved_word(field.camelize_name) %>Seen: Bool = false
223+
<% end %>
216224

217225
public init(
218-
<% input_fields = type.required_input_fields + type.optional_input_fields %>
226+
<% input_fields = type.required_input_fields + type.optional_input_fields # manually ordered with required fields first %>
219227
<% input_fields.each do |field| %>
220-
<% default = field.type.non_null? ? "" : " = nil" %>
221228
<% seperator = field == input_fields.last ? "" : "," %>
222-
<%= escape_reserved_word(field.camelize_name) %>: <%= swift_input_type(field.type) %><%= default %><%= seperator %>
229+
<% if field.type.non_null? %>
230+
<%= escape_reserved_word(field.camelize_name) %>: <%= swift_input_type(field.type) %><%= seperator %>
231+
<% else %>
232+
<%= escape_reserved_word(field.camelize_name) %>: <%= swift_input_type(field.type) %>? = nil<%= seperator %>
233+
<% end %>
223234
<% end %>
224235
) {
225-
<% type.input_fields.each do |field| %>
236+
<% type.required_input_fields.each do |field| %>
226237
self.<%= escape_reserved_word(field.camelize_name) %> = <%= escape_reserved_word(field.camelize_name) %>
227238
<% end %>
239+
<% type.optional_input_fields.each do |field| %>
240+
<% field_name = escape_reserved_word(field.camelize_name) %>
241+
if let <%= field_name %> = <%= field_name %> {
242+
self.<%= field_name %>Seen = true
243+
self.<%= field_name %> = <%= field_name %>
244+
}
245+
<% end %>
228246
}
229247
230248
func serialize() -> String {
231249
var fields: [String] = []
232-
<% type.input_fields.each do |field| %>
233-
<% unless field.type.non_null? %>
250+
<% type.required_input_fields.each do |field| %>
251+
fields.append("<%= field.name %>:<%= generate_build_input_code(field.camelize_name, field.type.unwrap_non_null) %>")
252+
<% end %>
253+
<% type.optional_input_fields.each do |field| %>
254+
if <%= escape_reserved_word(field.camelize_name) %>Seen {
234255
if let <%= escape_reserved_word(field.camelize_name) %> = <%= escape_reserved_word(field.camelize_name) %> {
235-
<% end %>
236256
fields.append("<%= field.name %>:<%= generate_build_input_code(field.camelize_name, field.type.unwrap_non_null) %>")
237-
<% unless field.type.non_null? %>
257+
} else {
258+
fields.append("<%= field.name %>:null")
238259
}
239-
<% end %>
260+
}
240261
<% end %>
241262
return "{\(fields.joined(separator: ","))}"
242263
}

support/Tests/GraphQLSupportTests/IntegrationTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ class IntegrationTests: XCTestCase {
5656
XCTAssertEqual(queryString, "mutation{set_integer(input:{key:\"answer\",value:42,negate:true})}")
5757
}
5858

59+
func testInputObjectExplictNilConstructor() {
60+
let query = Generated.buildMutation { $0
61+
.setInteger(input: Generated.SetIntegerInput(key: "answer", value: 42, negate: .some(nil)))
62+
}
63+
let queryString = String(describing: query)
64+
XCTAssertEqual(queryString, "mutation{set_integer(input:{key:\"answer\",value:42,negate:null})}")
65+
}
66+
67+
func testInputObjectExplictNilSetLater() {
68+
let input = Generated.SetIntegerInput(key: "answer", value: 42)
69+
input.negate = nil
70+
let query = Generated.buildMutation { $0
71+
.setInteger(input: input)
72+
}
73+
let queryString = String(describing: query)
74+
XCTAssertEqual(queryString, "mutation{set_integer(input:{key:\"answer\",value:42,negate:null})}")
75+
}
76+
5977
func testScalarInput() {
6078
let ttl = date(year: 2017, month: 1, day: 31, hour: 10, minute: 9, second: 48)
6179
let query = Generated.buildMutation { $0

0 commit comments

Comments
 (0)