rubocop-graphql 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2393f8c4972a479e9618f3ed9f846a819b0efa8bf13e53f319bbc176c50a470b
4
- data.tar.gz: 4326de68922f560a042ecbee99f70f421a09c05e0502291e4b4624c90a369233
3
+ metadata.gz: 99b9cc340e883dfe2dd4d0662a04383fde0a0b648cd1716f8aaec8eef8aab486
4
+ data.tar.gz: 928eee0593772d1614c6527ebefeb11753b3797408a98bdd84ae6c6fa46ca8da
5
5
  SHA512:
6
- metadata.gz: 1d65dbf3f6d5a623afbd74524e485ff4c570157ab23eae396e7ca5e343ff3ea2546d8433fc67dff38e2d63985ebc2881de3ba37e58ed5943ef2521fb2be93d36
7
- data.tar.gz: 718957be35d17116319a4d18ba707b96236e813e9acd8fa724888623550f6dffafc2c07e774a181f5f576c2e949d92e3c264badc2c30ef4897d440781a3b1c32
6
+ metadata.gz: 736f86f09bc7123fd0c5227ce35f771a83d75532d9231becd4a444b725fbddac7494fadcbffe929ddfcb0609e6ff80d53510d379792141e12d5d7c3fb08f4056
7
+ data.tar.gz: 2603c7d27cccd23e904c9345b9b1728a16bf99a1c03162ff93281a0a64f7f1621f5f8ad874af950671275be4a8f743dbbae71e8439d0f369b8ae4c9b5586e26e
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module GraphQL
6
+ # Arguments should be alphabetically sorted within groups.
7
+ #
8
+ # @example
9
+ # # good
10
+ #
11
+ # class UpdateProfile < BaseMutation
12
+ # argument :email, String, required: false
13
+ # argument :name, String, required: false
14
+ # end
15
+ #
16
+ # # good
17
+ #
18
+ # class UpdateProfile < BaseMutation
19
+ # argument :uuid, ID, required: true
20
+ #
21
+ # argument :email, String, required: false
22
+ # argument :name, String, required: false
23
+ # end
24
+ #
25
+ # # good
26
+ #
27
+ # class UserType < BaseType
28
+ # field :posts, PostType do
29
+ # argument :created_after, ISO8601DateTime, required: false
30
+ # argument :created_before, ISO8601DateTime, required: false
31
+ # end
32
+ # end
33
+ #
34
+ # # bad
35
+ #
36
+ # class UpdateProfile < BaseMutation
37
+ # argument :uuid, ID, required: true
38
+ # argument :name, String, required: false
39
+ # argument :email, String, required: false
40
+ # end
41
+ #
42
+ # # bad
43
+ #
44
+ # class UserType < BaseType
45
+ # field :posts, PostType do
46
+ # argument :created_before, ISO8601DateTime, required: false
47
+ # argument :created_after, ISO8601DateTime, required: false
48
+ # end
49
+ # end
50
+ #
51
+ class OrderedArguments < Cop
52
+ MSG = "Arguments should be sorted in an alphabetical order within their section. " \
53
+ "Field `%<current>s` should appear before `%<previous>s`."
54
+
55
+ def investigate(processed_source)
56
+ return if processed_source.blank?
57
+
58
+ argument_declarations(processed_source.ast)
59
+ .each_cons(2) do |previous, current|
60
+ next unless consecutive_lines(previous, current)
61
+ next if argument_name(current) > argument_name(previous)
62
+
63
+ register_offense(previous, current)
64
+ end
65
+ end
66
+
67
+ def autocorrect(node)
68
+ declarations = argument_declarations(processed_source.ast)
69
+ node_index = declarations.map(&:location).find_index(node.location)
70
+ previous_declaration = declarations.to_a[node_index - 1]
71
+
72
+ current_range = declaration(node)
73
+ previous_range = declaration(previous_declaration)
74
+
75
+ lambda do |corrector|
76
+ swap_range(corrector, current_range, previous_range)
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def declaration(node)
83
+ buffer = processed_source.buffer
84
+ begin_pos = node.source_range.begin_pos
85
+ end_line = buffer.line_for_position(node.loc.expression.end_pos)
86
+ end_pos = buffer.line_range(end_line).end_pos
87
+ Parser::Source::Range.new(buffer, begin_pos, end_pos)
88
+ end
89
+
90
+ def swap_range(corrector, range1, range2)
91
+ src1 = range1.source
92
+ src2 = range2.source
93
+ corrector.replace(range1, src2)
94
+ corrector.replace(range2, src1)
95
+ end
96
+
97
+ def register_offense(previous, current)
98
+ message = format(
99
+ self.class::MSG,
100
+ previous: argument_name(previous),
101
+ current: argument_name(current)
102
+ )
103
+ add_offense(current, message: message)
104
+ end
105
+
106
+ def argument_name(node)
107
+ node.first_argument.value.to_s
108
+ end
109
+
110
+ def consecutive_lines(previous, current)
111
+ previous.source_range.last_line == current.source_range.first_line - 1
112
+ end
113
+
114
+ def_node_search :argument_declarations, <<~PATTERN
115
+ (send nil? :argument (:sym _) ...)
116
+ PATTERN
117
+ end
118
+ end
119
+ end
120
+ end
@@ -47,6 +47,19 @@ module RuboCop
47
47
  end
48
48
  end
49
49
 
50
+ def autocorrect(node)
51
+ declarations = field_declarations(processed_source.ast)
52
+ node_index = declarations.map(&:location).find_index(node.location)
53
+ previous_declaration = declarations.to_a[node_index - 1]
54
+
55
+ current_range = declaration(node)
56
+ previous_range = declaration(previous_declaration)
57
+
58
+ lambda do |corrector|
59
+ swap_range(corrector, current_range, previous_range)
60
+ end
61
+ end
62
+
50
63
  private
51
64
 
52
65
  def register_offense(previous, current)
@@ -70,6 +83,21 @@ module RuboCop
70
83
  previous.source_range.last_line == current.source_range.first_line - 1
71
84
  end
72
85
 
86
+ def declaration(node)
87
+ buffer = processed_source.buffer
88
+ begin_pos = node.source_range.begin_pos
89
+ end_line = buffer.line_for_position(node.loc.expression.end_pos)
90
+ end_pos = buffer.line_range(end_line).end_pos
91
+ Parser::Source::Range.new(buffer, begin_pos, end_pos)
92
+ end
93
+
94
+ def swap_range(corrector, range1, range2)
95
+ src1 = range1.source
96
+ src2 = range2.source
97
+ corrector.replace(range1, src2)
98
+ corrector.replace(range2, src1)
99
+ end
100
+
73
101
  def_node_search :field_declarations, <<~PATTERN
74
102
  {
75
103
  (send nil? :field (:sym _) ...)
@@ -13,4 +13,5 @@ require_relative "graphql/field_method"
13
13
  require_relative "graphql/field_name"
14
14
  require_relative "graphql/resolver_method_length"
15
15
  require_relative "graphql/object_description"
16
+ require_relative "graphql/ordered_arguments"
16
17
  require_relative "graphql/ordered_fields"
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module GraphQL
3
- VERSION = "0.6.2".freeze
3
+ VERSION = "0.7.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Tsepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-03 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,7 @@ files:
94
94
  - lib/rubocop/cop/graphql/field_method.rb
95
95
  - lib/rubocop/cop/graphql/field_name.rb
96
96
  - lib/rubocop/cop/graphql/object_description.rb
97
+ - lib/rubocop/cop/graphql/ordered_arguments.rb
97
98
  - lib/rubocop/cop/graphql/ordered_fields.rb
98
99
  - lib/rubocop/cop/graphql/resolver_method_length.rb
99
100
  - lib/rubocop/cop/graphql_cops.rb