From b3787cfb6a17d31867c16f51f59834d7a81fbf6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Brand=C3=A3o?= Date: Tue, 31 Mar 2020 20:42:51 -0300 Subject: [PATCH 1/2] Bring back support to snake_case names --- README.md | 43 +++++++++++++++++++++- lib/rspec/graphql_matchers/have_a_field.rb | 22 ++++++++--- spec/rspec/have_a_field_matcher_spec.rb | 8 ++++ 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 141ec16..81a3d5c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,10 @@ describe PostType do it { is_expected.to have_field(:id).of_type(!types.ID) } it { is_expected.to have_field(:comments).of_type("[String!]!") } it { is_expected.to have_field(:isPublished).of_type("Boolean") } + + # The gem automatically converts field names to CamelCase, so this will + # pass even though the field was defined as field :isPublished + it { is_expected.to have_field(:is_published).of_type("Boolean") } end ``` @@ -138,10 +142,45 @@ describe PostType do end ``` +### 6) Using camelize: false on field names + +By default the graphql gem camelizes field names. This gem deals with it transparently: + +```ruby +class ObjectMessingWithCamelsAndSnakesType < GraphQL::Schema::Object + graphql_name 'ObjectMessingWithCamelsAndSnakes' + + implements GraphQL::Relay::Node.interface + + field :me_gusta_los_camellos, ID, null: false + + # note the camelize: false + field :prefiero_serpientes, ID, null: false, camelize: false +end +``` + +The following specs demonstrate the current behavior of the gem regarding fields: + +```ruby +describe ObjectMessingWithCamelsAndSnakesType do + subject { described_class } + + # For a field name that was automatically camelized, you can add expectations + # against both versions and we handle it transparently: + it { is_expected.to have_a_field(:meGustaLosCamellos) } + it { is_expected.to have_a_field(:me_gusta_los_camellos) } + + # However, when using camelize: false, you have to use the exact case of the field definition: + it { is_expected.to have_a_field(:prefiero_serpientes) } + it { is_expected.not_to have_a_field(:prefieroSerpientes) } # Note we're using `not_to` +end +``` + +This behaviour is currently active only on field name matching. PRs are welcome to +reproduce it to arguments as well. + ## TODO -- Support GraphQL 1.9.x; -- Check the method used for resolving a field; - New matchers! ## Contributing diff --git a/lib/rspec/graphql_matchers/have_a_field.rb b/lib/rspec/graphql_matchers/have_a_field.rb index e190c80..736fa9c 100644 --- a/lib/rspec/graphql_matchers/have_a_field.rb +++ b/lib/rspec/graphql_matchers/have_a_field.rb @@ -10,7 +10,10 @@ module RSpec module GraphqlMatchers class HaveAField < BaseMatcher def initialize(expected_field_name, fields = :fields) - @expected_field_name = GraphQL::Schema::Member::BuildType.camelize(expected_field_name.to_s) + @expected_field_name = expected_field_name.to_s + @expected_camel_field_name = GraphQL::Schema::Member::BuildType.camelize( + @expected_field_name + ) @fields = fields.to_sym @expectations = [] end @@ -18,12 +21,10 @@ def initialize(expected_field_name, fields = :fields) def matches?(graph_object) @graph_object = graph_object - @actual_field = field_collection[@expected_field_name] - @actual_field = @actual_field.to_graphql if @actual_field.respond_to?(:to_graphql) - return false if @actual_field.nil? + return false if actual_field.nil? @results = @expectations.reject do |matcher| - matcher.matches?(@actual_field) + matcher.matches?(actual_field) end @results.empty? @@ -57,7 +58,7 @@ def failure_message base_msg = "expected #{member_name(@graph_object)} " \ "to define field `#{@expected_field_name}`" \ - return "#{base_msg} #{failure_messages.join(', ')}" if @actual_field + return "#{base_msg} #{failure_messages.join(', ')}" if actual_field "#{base_msg} but no field was found with that name" end @@ -68,6 +69,15 @@ def description private + def actual_field + @actual_field ||= begin + field = field_collection[@expected_field_name] + field ||= field_collection[@expected_camel_field_name] + + field.respond_to?(:to_graphql) ? field.to_graphql : field + end + end + def descriptions @results.map(&:description) end diff --git a/spec/rspec/have_a_field_matcher_spec.rb b/spec/rspec/have_a_field_matcher_spec.rb index 016e105..2bc6bf9 100644 --- a/spec/rspec/have_a_field_matcher_spec.rb +++ b/spec/rspec/have_a_field_matcher_spec.rb @@ -19,6 +19,10 @@ module RSpec::GraphqlMatchers expect(a_type).to have_a_field(:isTest) end + it 'matches a non camelized field with the underscored field name' do + expect(a_type).to have_a_field(:not_camelized) + end + it 'fails when the type does not define the expected field' do expect { expect(a_type).to have_a_field(:ids) } .to fail_with( @@ -110,6 +114,7 @@ module RSpec::GraphqlMatchers field :id, types.ID, null: false field :other, types.String, hash_key: :other_on_hash, null: true field :is_test, types.Boolean, null: true + field :not_camelized, types.String, null: false, camelize: false end end @@ -123,6 +128,7 @@ module RSpec::GraphqlMatchers field :other, types.String, hash_key: :other_on_hash, null: true field :is_test, types.Boolean, null: true + field :not_camelized, types.String, null: false, camelize: false end Class.new(GraphQL::Schema::Object) do @@ -153,6 +159,8 @@ module RSpec::GraphqlMatchers hash_key: :other_on_hash field :isTest, types.Boolean + + field :not_camelized, types.String, camelize: false end end From ef313d1b056232c7fb1a16fa88b91d42d4b3b647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Brand=C3=A3o?= Date: Tue, 31 Mar 2020 20:44:35 -0300 Subject: [PATCH 2/2] Version 1.2.1 bump --- CHANGELOG.md | 4 ++++ lib/rspec/graphql_matchers/version.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d83b10b..0c72ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ### Bug fixes +## 1.2.1 (March 31st, 2020) + +- Fixed issue causing the last release to break expectations against snake_cased fields (fixes https://github.com/khamusa/rspec-graphql_matchers/issues/30). + ## 1.2 (Feb 6th, 2020) - Added support to underscored arguments in have_field (https://github.com/khamusa/rspec-graphql_matchers/pull/29 thanks to @makketagg) diff --git a/lib/rspec/graphql_matchers/version.rb b/lib/rspec/graphql_matchers/version.rb index 86ea3c6..7a60398 100644 --- a/lib/rspec/graphql_matchers/version.rb +++ b/lib/rspec/graphql_matchers/version.rb @@ -2,6 +2,6 @@ module Rspec module GraphqlMatchers - VERSION = '1.2' + VERSION = '1.2.1' end end