graphql_matchers.rb 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. # frozen_string_literal: true
  2. RSpec::Matchers.define :have_graphql_fields do |*expected|
  3. match do |klass|
  4. expected_field_names = expected.map do |name|
  5. GraphQLHelpers.fieldnamerize(name)
  6. end
  7. expect(GraphQLHelpers.keys_for_klass(klass)).to(
  8. contain_exactly(*expected_field_names),
  9. )
  10. end
  11. failure_message do |klass|
  12. expected_field_names = expected.map do |name|
  13. GraphQLHelpers.fieldnamerize(name)
  14. end
  15. keys = GraphQLHelpers.keys_for_klass(klass)
  16. missing = expected_field_names - keys
  17. extra = keys - expected_field_names
  18. message = []
  19. message << "is missing fields: <#{missing.inspect}>" if missing.any?
  20. message << "contained unexpected fields: <#{extra.inspect}>" if extra.any?
  21. message.join("\n")
  22. end
  23. end
  24. RSpec::Matchers.define :have_graphql_field do |field_name|
  25. match do |klass|
  26. expect(GraphQLHelpers.keys_for_klass(klass)).to(
  27. include(GraphQLHelpers.fieldnamerize(field_name)),
  28. )
  29. end
  30. end
  31. RSpec::Matchers.define :have_graphql_mutation do |mutation_class|
  32. match do |field|
  33. expect(field).to be_present
  34. expect(field.resolver).to eq(mutation_class)
  35. end
  36. end
  37. RSpec::Matchers.define :have_graphql_arguments do |*expected|
  38. match do |field|
  39. expected_argument_names = expected.map do |name|
  40. GraphQLHelpers.fieldnamerize(name)
  41. end
  42. actual = GraphQLHelpers.arguments_for_field(field)
  43. argument_names = expected_argument_names
  44. expect(actual).to contain_exactly(*argument_names)
  45. end
  46. failure_message do |field|
  47. expected_argument_names = expected.map do |name|
  48. GraphQLHelpers.fieldnamerize(name)
  49. end
  50. keys = GraphQLHelpers.arguments_for_field(field)
  51. missing = expected_argument_names - keys
  52. extra = keys - expected_argument_names
  53. message = []
  54. message << "is missing arguments: <#{missing.inspect}>" if missing.any?
  55. if extra.any?
  56. message << "contained unexpected arguments: <#{extra.inspect}>"
  57. end
  58. message.join("\n")
  59. end
  60. end
  61. RSpec::Matchers.define :include_graphql_arguments do |*expected|
  62. match do |field|
  63. expected_argument_names = expected.map do |name|
  64. GraphQLHelpers.fieldnamerize(name)
  65. end
  66. actual = GraphQLHelpers.arguments_for_field(field)
  67. argument_names = expected_argument_names
  68. expect(actual).to include(*argument_names)
  69. end
  70. failure_message do |field|
  71. expected_argument_names = expected.map do |name|
  72. GraphQLHelpers.fieldnamerize(name)
  73. end
  74. keys = GraphQLHelpers.arguments_for_field(field)
  75. missing = expected_argument_names - keys
  76. "is missing arguments: <#{missing.inspect}>" if missing.any?
  77. end
  78. end
  79. RSpec::Matchers.define :include_graphql_arguments_with_plurals do |*expected|
  80. match do |field|
  81. expected_argument_names = expected.map do |name|
  82. GraphQLHelpers.fieldnamerize(name)
  83. end
  84. all = GraphQLHelpers.arguments_for_field(field)
  85. plurals = GraphQLHelpers.plural_arguments_for_field(field)
  86. expected = all - plurals
  87. argument_names = expected_argument_names
  88. expect(expected).to include(*argument_names)
  89. end
  90. failure_message do |field|
  91. expected_argument_names = expected.map do |name|
  92. GraphQLHelpers.fieldnamerize(name)
  93. end
  94. all = GraphQLHelpers.arguments_for_field(field)
  95. plurals = GraphQLHelpers.plural_arguments_for_field(field)
  96. keys = all - plurals
  97. missing = expected_argument_names - keys
  98. "is missing arguments: <#{missing.inspect}>"
  99. end
  100. end
  101. RSpec::Matchers.define :have_graphql_type do |expected|
  102. match do |field|
  103. # `expected.to_graphql` does not work on Array types because they are _not_
  104. # GraphQL:: objects. There seems to be two options:
  105. #
  106. # 1) Grab the return type from the field to compare to `expected`:
  107. # expect(
  108. # field.metadata[:type_class].instance_variable_get('@return_type_expr')
  109. # ).to eq(expected)
  110. #
  111. # or
  112. #
  113. # 2) Run `expected` through the private GraphQL API and call `to_graphql` on
  114. # the result, while still having to grab important field metadata:
  115. # null = field.metadata[:type_class]
  116. # .instance_variable_get('@return_type_null')
  117. # expect(field.type).do eq(
  118. # GraphQL::Schema::Member::BuildType.parse_type(
  119. # [::Types::PokemonType], null: null,
  120. # ).to_graphql,
  121. # )
  122. #
  123. # Neither option seems very great, but at least with option 2, we compare
  124. # exactly the expectation. Let's do both?
  125. type_class, graphql_type =
  126. case field
  127. when GraphQL::Schema::Field
  128. [field, field.type.to_graphql]
  129. else
  130. [field.metadata[:type_class], field.type]
  131. end
  132. null = type_class.instance_variable_get('@return_type_null')
  133. parsed_type = GraphQL::Schema::Member::BuildType
  134. .parse_type(expected, null: null)
  135. unless expected.is_a? GraphQL::ScalarType
  136. parsed_type = parsed_type.to_graphql
  137. end
  138. expect(graphql_type).to eq(parsed_type)
  139. actual = type_class.instance_variable_get('@return_type_expr').to_s
  140. expect(actual).to eq(expected.to_s)
  141. end
  142. end
  143. RSpec::Matchers.define :have_graphql_resolver do |expected|
  144. match do |field|
  145. case expected
  146. when Method
  147. expect(field.metadata[:type_class].resolve_proc).to eq(expected)
  148. else
  149. expect(field.metadata[:type_class].resolver).to eq(expected)
  150. end
  151. end
  152. end