README.md in rspec-graphql_matchers-1.0.0.pre.0.1 vs README.md in rspec-graphql_matchers-1.0

- old
+ new

@@ -12,71 +12,59 @@ ## Usage The matchers currently supported are: -- `expect(a_graphql_object).to have_a_field(field_name).that_returns(valid_type)` +- `expect(a_graphql_object).to have_a_field(field_name).of_type(valid_type)` - `expect(a_graphql_object).to implement(interface_name, ...)` - `expect(a_mutation_type).to have_a_return_field(field_name).returning(valid_type)` - `expect(a_mutation_type).to have_an_input_field(field_name).of_type(valid_type)` - `expect(a_field).to be_of_type(valid_type)` -- `expect(an_input).to accept_arguments(hash_of_arg_names_and_valid_types)` -- `expect(an_input).to accept_arguments(hash_of_arg_names_and_valid_types)` +- `expect(an_input).to accept_argument(argument_name).of_type(valid_type)` Where a valid type for the expectation is either: - A reference to the actual type you expect; -- A String representation of a type: `"String!"`, `"Int!"`, `"[String]!"` +- [Recommended] A String representation of a type: `"String!"`, `"Int!"`, `"[String]!"` (note the exclamation mark at the end, as required by the [GraphQL specs](http://graphql.org/). For objects defined with the legacy `#define` api, testing `:property`, `:hash_key` and _metadata_ is also possible by chaining `.with_property`, `.with_hash_key` and `.with_metadata`. For example: - `expect(a_graphql_object).to have_a_field(field_name).with_property(property_name).with_metadata(metadata_hash)` - `expect(a_graphql_object).to have_a_field(field_name).with_hash_key(hash_key)` ## Examples -Given a `GraphQL::ObjectType` defined as +Given a GraphQL object defined as ```ruby - -PostType = GraphQL::ObjectType.define do - name "Post" +class PostType < GraphQL::Schema::Object + graphql_name "Post" description "A blog post" - interfaces [GraphQL::Relay::Node.interface] + implements GraphQL::Relay::Node.interface - field :id, !types.ID, - property: :post_id + field :id, ID, null: false + field :comments, [String], null: false + field :isPublished, Boolean, null: true - field :comments, - !types[types.String], - hash_key: :post_comments - - field :isPublished, - admin_only: true - - field :subposts, PostType do - type !PostType - - argument :filter, types.String - argument :id, types.ID + field :subposts, PostType, null: true do + argument :filter, types.String, required: false + argument :id, types.ID, required: false end end ``` ### 1) Test your type defines the correct fields: ```ruby describe PostType do - it 'defines a field id of type ID!' do - expect(subject).to have_field(:id).that_returns(!types.ID) - end + subject { described_class } - # Fluent alternatives - it { is_expected.to have_field(:id).of_type("ID!") } - it { is_expected.to have_a_field(:id).returning("ID!") } + 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") } end ``` ### 2) Test a specific field type with `be_of_type` matcher: @@ -90,84 +78,58 @@ end describe 'subposts' do subject { PostType.fields['subposts'] } - # You can use your type object directly when building expectations - it 'has type PostType' do - expect(subject).to be_of_type(!PostType) - end - - # Or as usual, a literal String - it { is_expected.to be_of_type('Post!') } + it { is_expected.to be_of_type('Post') } end end ``` -Keep in mind that when using strings as type expectation you have to use the -type name (`Post`) and not the constant name (`PostType`). +### 3) For objects defined using the legacy `#define` api, you can also use `with_property`, `with_hash_key` and `with_metadata`: -Using your type objects directly is riskier than the string representation, since -renaming the graphql name of an object is potentially a breaking change that -wouldn't get caught by your test suite. - -You can also use the built-in [graphql-ruby](https://github.com/rmosolgo/graphql-ruby) scalar types: - ```ruby -# ensure you have the GraphQL type definer available in your tests -types = GraphQL::Define::TypeDefiner.instance +PostTypeWithDefineApi = GraphQL::ObjectType.define do + name "DefinedPost" -describe PostType do - describe 'comments' do - subject { PostType.fields['comments'] } - it { is_expected.to be_of_type(!types[types.String]) } - it { is_expected.to be_of_type('[String]!') } - end + interfaces [GraphQL::Relay::Node.interface] + + field :id, !types.ID, property: :post_id + field :comments, !types[types.String], hash_key: :post_comments + field :isPublished, admin_only: true end -``` -### 3) Test a specific field with `with_property`, `with_hash_key` and `with_metadata` - -```ruby -describe PostType do - it { is_expected.to have_a_field(:id).with_property(:post_id) } +describe PostTypeWithDefineApi do + it { is_expected.to have_a_field(:id).of_type('ID!').with_property(:post_id) } it { is_expected.to have_a_field(:comments).with_hash_key(:post_comments) } it { is_expected.to have_a_field(:isPublished).with_metadata(admin_only: true) } end ``` -### 4) Test the arguments accepted by a field with `accept_arguments` matcher: +### 4) Test the arguments accepted by a field with `accept_argument` matcher: ```ruby describe PostType do describe 'subposts' do subject { PostType.fields['subposts'] } - let(:a_whole_bunch_of_args) do - { filter: 'String', id: types.Int, pippo: 'Float', posts: PostType } - end - it 'accepts a filter and an id argument, of types String and ID' do - expect(subject).to accept_arguments(filter: types.String, id: types.ID) + expect(subject).to accept_argument(:filter).of_type('String') + expect(subject).to accept_argument(:id).of_type('ID') end - # You can also test if a field does not accept args. Not quite useful :D. - it { is_expected.not_to accept_arguments(a_whole_bunch_of_args) } + it { is_expected.not_to accept_argument(:weirdo) } end end ``` -The spec will only pass if all attributes/types specified in the hash are -defined on the field. - -For better fluency, `accept_arguments` is also available in singular form, as -`accept_argument`. - ### 5) Test an object's interface implementations: ```ruby describe PostType do + subject { described_class } + it 'implements interface Node' do expect(subject).to implement('Node') end # Accepts arguments as an array and type objects directly @@ -176,9 +138,11 @@ end ``` ## TODO +- Support GraphQL 1.9.x; +- Check the method used for resolving a field; - New matchers! ## Contributing - Send Bug reports, suggestions or any general