rubocop-graphql 0.6.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f19fb45c31f7313ff9617b4fbb5e34848123ec0a7e9e2c9b809f68e2555ffcc
4
- data.tar.gz: bd33d1bb602dc21f5732e5262a582ed0364d89f72138b48cef5ae01545f3acc5
3
+ metadata.gz: 62d96a424a721e274ada4265af5482248fd8786a07c9d533dadf368d39b0e142
4
+ data.tar.gz: b0e1877a97532a0190036b71c5068d95b3572a728b7eb2e2c51ee9b3c35869ce
5
5
  SHA512:
6
- metadata.gz: 721e3f6f4b686ae8fd51a741a1e9379d77098f7569cc6ac9143b4535dc344927f991af71ac104df47fd944a6d9e7cd204ed03c4e860d91f56ef6e9b3dc6f6d08
7
- data.tar.gz: 2d3179d6818fbabb4a1f1ed54676413db55215ea0f1c6fdc5645adf46943faa3dd2f86faca200736e8ed243b1d208d686b6ace8619c4174631078699d43f220f
6
+ metadata.gz: 7cbf14cb18196ed2ec0cbf75299f867674c2ac47a716f55b335cfb258377e4fd0d00968d51d28890fdb81d07211d2e4d6192efabf56bd349d0436c58c3c1e8e0
7
+ data.tar.gz: 4fb8ff31d9f3a500ed58118945c41451fa1178d3ace5635242861e176ec2fae4f1b31512dca2135d639a7d74e61d9c98d6fca4912fcd3609e033fc8241efba56
@@ -7,6 +7,7 @@ require_relative "rubocop/graphql/ext/snake_case"
7
7
  require_relative "rubocop/graphql"
8
8
  require_relative "rubocop/graphql/version"
9
9
  require_relative "rubocop/graphql/inject"
10
+ require_relative "rubocop/graphql/description_method"
10
11
  require_relative "rubocop/graphql/node_pattern"
11
12
 
12
13
  require_relative "rubocop/graphql/argument"
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # class will invoke the inherited hook instead
13
13
  class << self
14
14
  undef inherited
15
- def inherited(*); end
15
+ def inherited(*); end # rubocop:disable Lint/MissingSuper
16
16
  end
17
17
 
18
18
  # Special case `Module#<` so that the rspec support rubocop exports
@@ -47,7 +47,7 @@ module RuboCop
47
47
  )
48
48
 
49
49
  # Invoke the original inherited hook so our cops are recognized
50
- def self.inherited(subclass)
50
+ def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
51
51
  RuboCop::Cop::Cop.inherited(subclass)
52
52
  end
53
53
 
@@ -32,7 +32,12 @@ module RuboCop
32
32
  if (body = schema_member.body)
33
33
  arguments = body.select { |node| argument?(node) }
34
34
 
35
- add_offense(arguments.last) if arguments.count > cop_config["MaxArguments"]
35
+ excess_arguments = arguments.count - cop_config["MaxArguments"]
36
+ return unless excess_arguments.positive?
37
+
38
+ arguments.last(excess_arguments).each do |excess_argument|
39
+ add_offense(excess_argument)
40
+ end
36
41
  end
37
42
  end
38
43
  end
@@ -109,7 +109,7 @@ module RuboCop
109
109
  field_definition?(node) || field_definition_with_body?(node)
110
110
  end
111
111
 
112
- source_to_insert = "\n" + indent(node) + node.source
112
+ source_to_insert = "\n#{indent(node)}#{node.source}"
113
113
  corrector.insert_after(first_field.loc.expression, source_to_insert)
114
114
 
115
115
  range = range_with_surrounding_space(range: node.loc.expression, side: :left)
@@ -143,7 +143,7 @@ module RuboCop
143
143
 
144
144
  field_definition = field_definition_with_body?(node.parent) ? node.parent : node
145
145
 
146
- source_to_insert = indent(method_definition) + field_definition.source + "\n\n"
146
+ source_to_insert = "#{indent(method_definition)}#{field_definition.source}\n\n"
147
147
  method_range = range_by_whole_lines(method_definition.loc.expression)
148
148
  corrector.insert_before(method_range, source_to_insert)
149
149
 
@@ -22,6 +22,7 @@ module RuboCop
22
22
  #
23
23
  class ObjectDescription < Cop
24
24
  include RuboCop::GraphQL::NodePattern
25
+ include RuboCop::GraphQL::DescriptionMethod
25
26
 
26
27
  MSG = "Missing type description"
27
28
 
@@ -29,10 +30,6 @@ module RuboCop
29
30
  (send nil? :description (send (const nil? :I18n) :t ...))
30
31
  PATTERN
31
32
 
32
- def_node_matcher :has_string_description?, <<~PATTERN
33
- (send nil? :description (:str $_))
34
- PATTERN
35
-
36
33
  def_node_matcher :interface?, <<~PATTERN
37
34
  (send nil? :include (const ...))
38
35
  PATTERN
@@ -54,7 +51,8 @@ module RuboCop
54
51
  private
55
52
 
56
53
  def has_description?(node)
57
- has_i18n_description?(node) || has_string_description?(node)
54
+ has_i18n_description?(node) ||
55
+ description_kwarg?(node)
58
56
  end
59
57
 
60
58
  def child_nodes(node)
@@ -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"
@@ -5,6 +5,7 @@ module RuboCop
5
5
  class Argument
6
6
  class Block
7
7
  extend RuboCop::NodePattern::Macros
8
+ include DescriptionMethod
8
9
 
9
10
  def_node_matcher :argument_block, <<~PATTERN
10
11
  (block
@@ -14,16 +15,12 @@ module RuboCop
14
15
  )
15
16
  PATTERN
16
17
 
17
- def_node_matcher :description_kwarg?, <<~PATTERN
18
- (send nil? :description (str ...))
19
- PATTERN
20
-
21
18
  def initialize(argument_node)
22
19
  @nodes = argument_block(argument_node) || []
23
20
  end
24
21
 
25
22
  def description
26
- @nodes.find { |kwarg| description_kwarg?(kwarg) }
23
+ find_description_method(@nodes)
27
24
  end
28
25
  end
29
26
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module GraphQL
5
+ # Matches a variety of description formats commonly seen in Rails applications
6
+ #
7
+ # description 'blah'
8
+ #
9
+ # description "blah"
10
+ #
11
+ # description <<~EOT
12
+ # blah
13
+ # bloop
14
+ # EOT
15
+ #
16
+ # description <<-EOT.squish
17
+ # blah
18
+ # bloop
19
+ # EOT
20
+ module DescriptionMethod
21
+ extend RuboCop::NodePattern::Macros
22
+
23
+ def_node_matcher :description_kwarg?, <<~PATTERN
24
+ (send nil? :description {({str|dstr} ...)|(send ({str|dstr} ...) _)})
25
+ PATTERN
26
+
27
+ def find_description_method(nodes)
28
+ nodes.find { |kwarg| description_kwarg?(kwarg) }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -5,6 +5,7 @@ module RuboCop
5
5
  class Field
6
6
  class Block
7
7
  extend RuboCop::NodePattern::Macros
8
+ include DescriptionMethod
8
9
 
9
10
  def_node_matcher :field_block, <<~PATTERN
10
11
  (block
@@ -14,16 +15,12 @@ module RuboCop
14
15
  )
15
16
  PATTERN
16
17
 
17
- def_node_matcher :description_kwarg?, <<~PATTERN
18
- (send nil? :description (str ...))
19
- PATTERN
20
-
21
18
  def initialize(field_node)
22
19
  @nodes = field_block(field_node) || []
23
20
  end
24
21
 
25
22
  def description
26
- @nodes.find { |kwarg| description_kwarg?(kwarg) }
23
+ find_description_method(@nodes)
27
24
  end
28
25
  end
29
26
  end
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module GraphQL
3
- VERSION = "0.6.0".freeze
3
+ VERSION = "0.8.1".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.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Tsepelev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-22 00:00:00.000000000 Z
11
+ date: 2021-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -61,7 +61,7 @@ dependencies:
61
61
  version: '0.87'
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
- version: '1.1'
64
+ version: '2'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -71,7 +71,7 @@ dependencies:
71
71
  version: '0.87'
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
- version: '1.1'
74
+ version: '2'
75
75
  description: A collection of RuboCop cops to improve GraphQL-related code
76
76
  email:
77
77
  - dmitry.a.tsepelev@gmail.com
@@ -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
@@ -101,6 +102,7 @@ files:
101
102
  - lib/rubocop/graphql/argument.rb
102
103
  - lib/rubocop/graphql/argument/block.rb
103
104
  - lib/rubocop/graphql/argument/kwargs.rb
105
+ - lib/rubocop/graphql/description_method.rb
104
106
  - lib/rubocop/graphql/ext/snake_case.rb
105
107
  - lib/rubocop/graphql/field.rb
106
108
  - lib/rubocop/graphql/field/block.rb
@@ -116,7 +118,7 @@ metadata:
116
118
  homepage_uri: https://github.com/DmitryTsepelev/rubocop-graphql
117
119
  source_code_uri: https://github.com/DmitryTsepelev/rubocop-graphql
118
120
  changelog_uri: https://github.com/DmitryTsepelev/rubocop-graphql/CHANGELOG.md
119
- post_install_message:
121
+ post_install_message:
120
122
  rdoc_options: []
121
123
  require_paths:
122
124
  - lib
@@ -131,8 +133,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
133
  - !ruby/object:Gem::Version
132
134
  version: '0'
133
135
  requirements: []
134
- rubygems_version: 3.0.3
135
- signing_key:
136
+ rubygems_version: 3.1.2
137
+ signing_key:
136
138
  specification_version: 4
137
139
  summary: Automatic performance checking tool for Ruby code.
138
140
  test_files: []