#![allow(clippy::unwrap_used)]
use serde_json::json;
#[test]
fn test_mutation_non_nullable_return_type() {
let non_nullable = json!({
"name": "createUser",
"return_type": "User!",
});
assert_eq!(non_nullable["return_type"], json!("User!"));
assert!(non_nullable["return_type"].as_str().unwrap().ends_with('!'));
}
#[test]
fn test_mutation_nullable_return_type() {
let nullable = json!({
"name": "maybeUser",
"return_type": "User",
});
assert_eq!(nullable["return_type"], json!("User"));
assert!(!nullable["return_type"].as_str().unwrap().ends_with('!'));
}
#[test]
fn test_mutation_array_return_type_non_nullable_items() {
let array_non_null_items = json!({
"name": "getIds",
"return_type": "[Int!]!",
});
assert_eq!(array_non_null_items["return_type"], json!("[Int!]!"));
let type_str = array_non_null_items["return_type"].as_str().unwrap();
assert!(type_str.starts_with('['));
assert!(type_str.ends_with("]!"));
}
#[test]
fn test_mutation_array_return_type_nullable_items() {
let array_nullable_items = json!({
"name": "getTags",
"return_type": "[String]",
});
assert_eq!(array_nullable_items["return_type"], json!("[String]"));
let type_str = array_nullable_items["return_type"].as_str().unwrap();
assert!(type_str.starts_with('['));
assert!(type_str.ends_with(']'));
assert!(!type_str.ends_with("]!"));
}
#[test]
fn test_mutation_scalar_return_types_nullability() {
let scalar_types = vec![
("String!", true), ("String", false), ("Int!", true), ("Int", false), ("Boolean!", true), ("Boolean", false), ("Float!", true), ("Float", false), ("ID!", true), ("ID", false), ];
for (type_str, should_be_non_nullable) in scalar_types {
let mutation = json!({
"name": "operation",
"return_type": type_str,
});
let ret_type = mutation["return_type"].as_str().unwrap();
let is_non_nullable = ret_type.ends_with('!');
assert_eq!(
is_non_nullable, should_be_non_nullable,
"Type {} should have non_nullable={}",
type_str, should_be_non_nullable
);
}
}
#[test]
fn test_mutation_custom_type_return_nullability() {
let custom_types = vec![
("User!", true),
("User", false),
("CreateUserPayload!", true),
("CreateUserPayload", false),
("MutationResponse!", true),
("MutationResponse", false),
];
for (type_str, should_be_non_nullable) in custom_types {
let mutation = json!({
"name": "operation",
"return_type": type_str,
});
let ret_type = mutation["return_type"].as_str().unwrap();
let is_non_nullable = ret_type.ends_with('!');
assert_eq!(
is_non_nullable, should_be_non_nullable,
"Custom type {} should have non_nullable={}",
type_str, should_be_non_nullable
);
}
}
#[test]
fn test_mutation_nested_array_nullability() {
let nested_arrays = vec![
("[Int!]!", "non-nullable array of non-nullable ints"),
("[Int!]", "nullable array of non-nullable ints"),
("[Int]!", "non-nullable array of nullable ints"),
("[Int]", "nullable array of nullable ints"),
("[[String!]!]!", "nested arrays, all non-nullable"),
("[[String!]]", "nested arrays, outer nullable"),
("[[String]!]", "nested arrays, middle non-nullable"),
("[[String]]", "nested arrays, all nullable"),
];
for (type_str, _description) in nested_arrays {
let mutation = json!({
"name": "operation",
"return_type": type_str,
});
let ret_type = mutation["return_type"].as_str().unwrap();
assert_eq!(ret_type, type_str, "Type should be preserved exactly");
let exclamation_count = type_str.matches('!').count();
let stored_count = ret_type.matches('!').count();
assert_eq!(stored_count, exclamation_count, "Nullability markers should be preserved");
}
}
#[test]
fn test_mutation_nullability_with_input_args() {
let mutation_with_args = json!({
"name": "updateUser",
"arguments": [
{
"name": "id",
"type": "ID!",
"required": true
},
{
"name": "input",
"type": "UpdateUserInput!",
"required": true
},
{
"name": "notify",
"type": "Boolean",
"required": false
}
],
"return_type": "User!"
});
let args = mutation_with_args["arguments"].as_array().unwrap();
assert_eq!(args[0]["type"], json!("ID!"));
assert_eq!(args[1]["type"], json!("UpdateUserInput!"));
assert_eq!(args[2]["type"], json!("Boolean"));
assert_eq!(mutation_with_args["return_type"], json!("User!"));
}
#[test]
fn test_mutation_list_return_nullability_combinations() {
let combinations = vec![
"[Type]", "[Type!]", "[Type]!", "[Type!]!", ];
for type_str in combinations {
let mutation = json!({
"return_type": type_str,
});
assert_eq!(mutation["return_type"].as_str().unwrap(), type_str);
let ret_type = mutation["return_type"].as_str().unwrap();
assert!(ret_type.starts_with('['), "Should start with [");
assert!(ret_type.contains(']'), "Should contain ]");
}
}
#[test]
fn test_mutation_return_type_distinctions() {
let user_non_nullable = json!({"return_type": "User!"});
let user_nullable = json!({"return_type": "User"});
let user_list_non_nullable = json!({"return_type": "[User]!"});
let user_list_nullable = json!({"return_type": "[User]"});
assert_ne!(user_non_nullable["return_type"], user_nullable["return_type"]);
assert_ne!(user_list_non_nullable["return_type"], user_list_nullable["return_type"]);
assert_ne!(user_non_nullable["return_type"], user_list_non_nullable["return_type"]);
assert_eq!(user_non_nullable["return_type"], json!("User!"));
assert_eq!(user_nullable["return_type"], json!("User"));
assert_eq!(user_list_non_nullable["return_type"], json!("[User]!"));
assert_eq!(user_list_nullable["return_type"], json!("[User]"));
}