rubocop-graphql 0.8.0 → 0.10.0

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: c68112dd907111859f0c8ca78ad31c6bea918c11411d9d89a4a4ae289fc3630d
4
- data.tar.gz: cfeed828552dcdc4509b476f4d6a9672c111ef2e11001fad01f52b3699d26bc9
3
+ metadata.gz: 0d039f4e52b3e606bee7cfc92f14743ead168fd8e9afeefc9c3f73a5e8f97acb
4
+ data.tar.gz: 443920f9aa279503373dc467b91d5f8bb3e8fe510037c12e791a6231a1612cb3
5
5
  SHA512:
6
- metadata.gz: 7a20bb455185e7eb0ceeffb6da3f33438a416f003ce6fd7287483a34aab61301051a72e0b6b13967ead0c2b14c5ce31d28f4c9c864ed24ab627b34e7f322e40c
7
- data.tar.gz: e3badf19ec0a0ec03fe7be4d71324cb65e70f64c2ed3919334836f5d532e10fd16b3f54f58f2e909c987b72957027a13fa27fedf35f1bba2d2cceb6c9e66ca69
6
+ metadata.gz: 475dd5aa2de580c3ddc072fa66bc9cc09818dbf0e720bd1a2b874c56cba537dbd3dd63aa99e5bf30e33612981fddd4bb547f9224d5bab3352568564c93f1814e
7
+ data.tar.gz: c6faab3fb41885f25938ff17f8b18eafe4c2c6ba5a951a118ddeba5985448907597527242a35c1944f9f9a43067be2ec8e5849e605f206530c085c6c4e1da24c
data/config/default.yml CHANGED
@@ -1,7 +1,6 @@
1
- AllCops:
2
- GraphQL:
3
- Patterns:
4
- - "(?:^|/)graphql/"
1
+ GraphQL:
2
+ Include:
3
+ - "**/graphql/**/*"
5
4
 
6
5
  GraphQL/ArgumentDescription:
7
6
  Enabled: true
@@ -49,6 +48,7 @@ GraphQL/FieldName:
49
48
  Enabled: true
50
49
  VersionAdded: '0.80'
51
50
  Description: 'This cop checks whether field names are snake_case'
51
+ SafeAutoCorrect: false
52
52
 
53
53
  GraphQL/ExtractInputType:
54
54
  Enabled: true
@@ -68,10 +68,15 @@ GraphQL/ExtractType:
68
68
  - min
69
69
  - max
70
70
 
71
+ GraphQL/LegacyDsl:
72
+ Enabled: true
73
+ VersionAdded: '0.80'
74
+ Description: 'Checks that types are defined with class-based API'
75
+
71
76
  GraphQL/ObjectDescription:
72
77
  Enabled: true
73
78
  VersionAdded: '0.80'
74
79
  Description: 'Ensures all types have a description'
75
80
  Exclude:
76
81
  - '**/*_schema.rb'
77
- - '**/base_*.rb'
82
+ - '**/base_*.rb'
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UnderscoreString
4
+ refine String do
5
+ # This method was extracted from activesupport in Rails:
6
+ # https://github.com/rails/rails/blob/8dab534ca81dd32c6a83ac03596a1feb7ddaaca7/activesupport/lib/active_support/inflector/methods.rb#L96
7
+
8
+ def underscore
9
+ camel_cased_word = self
10
+ regex = /(?:(?<=([A-Za-z\d]))|\b)((?=a)b)(?=\b|[^a-z])/
11
+ return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
12
+
13
+ word = camel_cased_word.to_s.gsub("::", "/")
14
+ word.gsub!(regex) { "#{Regexp.last_match(1) && '_'}#{Regexp.last_match(2).downcase}" }
15
+ word.gsub!(/([A-Z\d]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
16
+ (Regexp.last_match(1) || Regexp.last_match(2)) << "_"
17
+ end
18
+ word.tr!("-", "_")
19
+ word.downcase!
20
+ word
21
+ end
22
+ end
23
+ end
@@ -7,7 +7,9 @@ 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"
12
+ require_relative "rubocop/graphql/swap_range"
11
13
 
12
14
  require_relative "rubocop/graphql/argument"
13
15
  require_relative "rubocop/graphql/argument/block"
@@ -18,7 +18,7 @@ module RuboCop
18
18
  # argument :uuid, ID, required: true
19
19
  # end
20
20
  #
21
- class ArgumentDescription < Cop
21
+ class ArgumentDescription < Base
22
22
  include RuboCop::GraphQL::NodePattern
23
23
 
24
24
  MSG = "Missing argument description"
@@ -18,7 +18,7 @@ module RuboCop
18
18
  # argument :userId, ID, required: true
19
19
  # end
20
20
  #
21
- class ArgumentName < Cop
21
+ class ArgumentName < Base
22
22
  include RuboCop::GraphQL::NodePattern
23
23
 
24
24
  using RuboCop::GraphQL::Ext::SnakeCase
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module GraphQL
6
- class ExtractInputType < Cop
6
+ class ExtractInputType < Base
7
7
  # This cop checks fields on common prefix groups
8
8
  #
9
9
  # # @example
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module GraphQL
6
- class ExtractType < Cop
6
+ class ExtractType < Base
7
7
  # This cop checks fields on common prefix groups
8
8
  #
9
9
  # # @example
@@ -44,7 +44,8 @@ module RuboCop
44
44
  # object.contact_data.last_name
45
45
  # end
46
46
  # end
47
- class FieldDefinitions < Cop
47
+ class FieldDefinitions < Base
48
+ extend AutoCorrector
48
49
  include ConfigurableEnforcedStyle
49
50
  include RuboCop::GraphQL::NodePattern
50
51
  include RuboCop::Cop::RangeHelp
@@ -75,17 +76,6 @@ module RuboCop
75
76
  end
76
77
  end
77
78
 
78
- def autocorrect(node)
79
- lambda do |corrector|
80
- case style
81
- when :define_resolver_after_definition
82
- place_resolver_after_definitions(corrector, node)
83
- when :group_definitions
84
- group_field_declarations(corrector, node)
85
- end
86
- end
87
- end
88
-
89
79
  private
90
80
 
91
81
  GROUP_DEFS_MSG = "Group all field definitions together."
@@ -98,7 +88,9 @@ module RuboCop
98
88
  fields.each_with_index do |node, idx|
99
89
  next if node.sibling_index == first_field.sibling_index + idx
100
90
 
101
- add_offense(node, message: GROUP_DEFS_MSG)
91
+ add_offense(node, message: GROUP_DEFS_MSG) do |corrector|
92
+ group_field_declarations(corrector, node)
93
+ end
102
94
  end
103
95
  end
104
96
 
@@ -133,7 +125,9 @@ module RuboCop
133
125
 
134
126
  return if method_definition.sibling_index - field_sibling_index == 1
135
127
 
136
- add_offense(field.node, message: RESOLVER_AFTER_FIELD_MSG)
128
+ add_offense(field.node, message: RESOLVER_AFTER_FIELD_MSG) do |corrector|
129
+ place_resolver_after_definitions(corrector, field.node)
130
+ end
137
131
  end
138
132
 
139
133
  def place_resolver_after_definitions(corrector, node)
@@ -18,7 +18,7 @@ module RuboCop
18
18
  # field :name, String, null: true
19
19
  # end
20
20
  #
21
- class FieldDescription < Cop
21
+ class FieldDescription < Base
22
22
  include RuboCop::GraphQL::NodePattern
23
23
 
24
24
  MSG = "Missing field description"
@@ -23,7 +23,8 @@ module RuboCop
23
23
  # end
24
24
  # end
25
25
  #
26
- class FieldHashKey < Cop
26
+ class FieldHashKey < Base
27
+ extend AutoCorrector
27
28
  include RuboCop::GraphQL::NodePattern
28
29
  include RuboCop::Cop::RangeHelp
29
30
 
@@ -47,32 +48,32 @@ module RuboCop
47
48
  method_definition = resolver_method_definition_for(field)
48
49
 
49
50
  if (suggested_hash_key_name = hash_key_to_use(method_definition))
50
- add_offense(node, message: message(suggested_hash_key_name))
51
+ add_offense(node, message: message(suggested_hash_key_name)) do |corrector|
52
+ autocorrect(corrector, node)
53
+ end
51
54
  end
52
55
  end
53
56
 
54
- def autocorrect(node)
55
- lambda do |corrector|
56
- field = RuboCop::GraphQL::Field.new(node)
57
- method_definition = resolver_method_definition_for(field)
58
- suggested_hash_key_name = hash_key_to_use(method_definition)
57
+ private
59
58
 
60
- corrector.insert_after(
61
- node.loc.expression, ", hash_key: #{suggested_hash_key_name.inspect}"
62
- )
59
+ def message(hash_key)
60
+ format(MSG, hash_key: hash_key)
61
+ end
63
62
 
64
- range = range_with_surrounding_space(
65
- range: method_definition.loc.expression, side: :left
66
- )
63
+ def autocorrect(corrector, node)
64
+ field = RuboCop::GraphQL::Field.new(node)
65
+ method_definition = resolver_method_definition_for(field)
66
+ suggested_hash_key_name = hash_key_to_use(method_definition)
67
67
 
68
- corrector.remove(range)
69
- end
70
- end
68
+ corrector.insert_after(
69
+ node.loc.expression, ", hash_key: #{suggested_hash_key_name.inspect}"
70
+ )
71
71
 
72
- private
72
+ range = range_with_surrounding_space(
73
+ range: method_definition.loc.expression, side: :left
74
+ )
73
75
 
74
- def message(hash_key)
75
- format(MSG, hash_key: hash_key)
76
+ corrector.remove(range)
76
77
  end
77
78
 
78
79
  def resolver_method_definition_for(field)
@@ -23,7 +23,8 @@ module RuboCop
23
23
  # end
24
24
  # end
25
25
  #
26
- class FieldMethod < Cop
26
+ class FieldMethod < Base
27
+ extend AutoCorrector
27
28
  include RuboCop::GraphQL::NodePattern
28
29
  include RuboCop::Cop::RangeHelp
29
30
 
@@ -46,22 +47,9 @@ module RuboCop
46
47
  method_definition = suggest_method_name_for(field)
47
48
 
48
49
  if (suggested_method_name = method_to_use(method_definition))
49
- add_offense(node, message: message(suggested_method_name))
50
- end
51
- end
52
-
53
- def autocorrect(node)
54
- lambda do |corrector|
55
- field = RuboCop::GraphQL::Field.new(node)
56
- method_definition = suggest_method_name_for(field)
57
- suggested_method_name = method_to_use(method_definition)
58
-
59
- corrector.insert_after(node.loc.expression, ", method: :#{suggested_method_name}")
60
-
61
- range = range_with_surrounding_space(
62
- range: method_definition.loc.expression, side: :left
63
- )
64
- corrector.remove(range)
50
+ add_offense(node, message: message(suggested_method_name)) do |corrector|
51
+ autocorrect(corrector, node)
52
+ end
65
53
  end
66
54
  end
67
55
 
@@ -71,6 +59,19 @@ module RuboCop
71
59
  format(MSG, method_name: method_name)
72
60
  end
73
61
 
62
+ def autocorrect(corrector, node)
63
+ field = RuboCop::GraphQL::Field.new(node)
64
+ method_definition = suggest_method_name_for(field)
65
+ suggested_method_name = method_to_use(method_definition)
66
+
67
+ corrector.insert_after(node.loc.expression, ", method: :#{suggested_method_name}")
68
+
69
+ range = range_with_surrounding_space(
70
+ range: method_definition.loc.expression, side: :left
71
+ )
72
+ corrector.remove(range)
73
+ end
74
+
74
75
  def suggest_method_name_for(field)
75
76
  method_name = field.resolver_method_name
76
77
  field.schema_member.find_method_definition(method_name)
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../../../refinements/underscore_string"
4
+
5
+ using UnderscoreString unless String.method_defined?(:underscore)
6
+
3
7
  module RuboCop
4
8
  module Cop
5
9
  module GraphQL
@@ -18,7 +22,8 @@ module RuboCop
18
22
  # field :firstName, String, null: true
19
23
  # end
20
24
  #
21
- class FieldName < Cop
25
+ class FieldName < Base
26
+ extend AutoCorrector
22
27
  include RuboCop::GraphQL::NodePattern
23
28
 
24
29
  using RuboCop::GraphQL::Ext::SnakeCase
@@ -31,7 +36,17 @@ module RuboCop
31
36
  field = RuboCop::GraphQL::Field.new(node)
32
37
  return if field.name.snake_case?
33
38
 
34
- add_offense(node)
39
+ add_offense(node) do |corrector|
40
+ rename_field_name(corrector, field, node)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def rename_field_name(corrector, field, node)
47
+ name_field = field.name.to_s
48
+ new_line = node.source.sub(name_field, name_field.underscore)
49
+ corrector.replace(node, new_line)
35
50
  end
36
51
  end
37
52
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # This cop checks whether type definitions are class-based or legacy.
6
+ #
7
+ # @example
8
+ # # good
9
+ #
10
+ # class Example < BaseType
11
+ # ....
12
+ # end
13
+ #
14
+ # # bad
15
+ #
16
+ # Example = GraphQL::ObjectType.define do
17
+ # ....
18
+ # ....
19
+ # end
20
+ #
21
+ module GraphQL
22
+ class LegacyDsl < Base
23
+ def_node_matcher :legacy_dsl?, <<~PATTERN
24
+ (block
25
+ (send
26
+ (const
27
+ (const nil? :GraphQL) _) :define)
28
+ ...
29
+ )
30
+ PATTERN
31
+
32
+ MSG = "Avoid using legacy based type-based definitions. Use class-based defintions instead."
33
+
34
+ def on_send(node)
35
+ return unless node.parent.type == :block
36
+
37
+ add_offense(node.parent) if legacy_dsl?(node.parent)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -20,8 +20,9 @@ module RuboCop
20
20
  # # ...
21
21
  # end
22
22
  #
23
- class ObjectDescription < Cop
23
+ class ObjectDescription < Base
24
24
  include RuboCop::GraphQL::NodePattern
25
+ include RuboCop::GraphQL::DescriptionMethod
25
26
 
26
27
  MSG = "Missing type description"
27
28
 
@@ -29,14 +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
- def_node_matcher :has_multiline_string_description?, <<~PATTERN
37
- (send nil? :description (:dstr ...))
38
- PATTERN
39
-
40
33
  def_node_matcher :interface?, <<~PATTERN
41
34
  (send nil? :include (const ...))
42
35
  PATTERN
@@ -59,8 +52,7 @@ module RuboCop
59
52
 
60
53
  def has_description?(node)
61
54
  has_i18n_description?(node) ||
62
- has_string_description?(node) ||
63
- has_multiline_string_description?(node)
55
+ description_kwarg?(node)
64
56
  end
65
57
 
66
58
  def child_nodes(node)
@@ -48,15 +48,16 @@ module RuboCop
48
48
  # end
49
49
  # end
50
50
  #
51
- class OrderedArguments < Cop
51
+ class OrderedArguments < Base
52
+ extend AutoCorrector
53
+
54
+ include RuboCop::GraphQL::SwapRange
55
+
52
56
  MSG = "Arguments should be sorted in an alphabetical order within their section. " \
53
57
  "Field `%<current>s` should appear before `%<previous>s`."
54
58
 
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|
59
+ def on_class(node)
60
+ argument_declarations(node).each_cons(2) do |previous, current|
60
61
  next unless consecutive_lines(previous, current)
61
62
  next if argument_name(current) > argument_name(previous)
62
63
 
@@ -64,43 +65,18 @@ module RuboCop
64
65
  end
65
66
  end
66
67
 
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
68
  private
81
69
 
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
70
  def register_offense(previous, current)
98
71
  message = format(
99
72
  self.class::MSG,
100
73
  previous: argument_name(previous),
101
74
  current: argument_name(current)
102
75
  )
103
- add_offense(current, message: message)
76
+
77
+ add_offense(current, message: message) do |corrector|
78
+ swap_range(corrector, current, previous)
79
+ end
104
80
  end
105
81
 
106
82
  def argument_name(node)
@@ -30,33 +30,21 @@ module RuboCop
30
30
  # field :name, String, null: true
31
31
  # end
32
32
  #
33
- class OrderedFields < Cop
33
+ class OrderedFields < Base
34
+ extend AutoCorrector
35
+
36
+ include RuboCop::GraphQL::SwapRange
37
+
34
38
  MSG = "Fields should be sorted in an alphabetical order within their "\
35
39
  "section. "\
36
40
  "Field `%<current>s` should appear before `%<previous>s`."
37
41
 
38
- def investigate(processed_source)
39
- return if processed_source.blank?
40
-
41
- field_declarations(processed_source.ast)
42
- .each_cons(2) do |previous, current|
43
- next unless consecutive_lines(previous, current)
44
- next if field_name(current) > field_name(previous)
45
-
46
- register_offense(previous, current)
47
- end
48
- end
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)
42
+ def on_class(node)
43
+ field_declarations(node).each_cons(2) do |previous, current|
44
+ next unless consecutive_lines(previous, current)
45
+ next if field_name(current) > field_name(previous)
57
46
 
58
- lambda do |corrector|
59
- swap_range(corrector, current_range, previous_range)
47
+ register_offense(previous, current)
60
48
  end
61
49
  end
62
50
 
@@ -68,7 +56,10 @@ module RuboCop
68
56
  previous: field_name(previous),
69
57
  current: field_name(current)
70
58
  )
71
- add_offense(current, message: message)
59
+
60
+ add_offense(current, message: message) do |corrector|
61
+ swap_range(corrector, current, previous)
62
+ end
72
63
  end
73
64
 
74
65
  def field_name(node)
@@ -83,21 +74,6 @@ module RuboCop
83
74
  previous.source_range.last_line == current.source_range.first_line - 1
84
75
  end
85
76
 
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
-
101
77
  def_node_search :field_declarations, <<~PATTERN
102
78
  {
103
79
  (send nil? :field (:sym _) ...)
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # Comment lines can optionally be ignored.
8
8
  #
9
9
  # The maximum allowed length is configurable using the Max option.
10
- class ResolverMethodLength < Cop
10
+ class ResolverMethodLength < Base
11
11
  include RuboCop::Cop::ConfigurableMax
12
12
  include RuboCop::Cop::CodeLength
13
13
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "graphql/cop"
4
-
5
3
  require_relative "graphql/argument_description"
6
4
  require_relative "graphql/argument_name"
7
5
  require_relative "graphql/extract_input_type"
@@ -11,6 +9,7 @@ require_relative "graphql/field_description"
11
9
  require_relative "graphql/field_hash_key"
12
10
  require_relative "graphql/field_method"
13
11
  require_relative "graphql/field_name"
12
+ require_relative "graphql/legacy_dsl"
14
13
  require_relative "graphql/resolver_method_length"
15
14
  require_relative "graphql/object_description"
16
15
  require_relative "graphql/ordered_arguments"
@@ -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
@@ -20,7 +20,7 @@ module RuboCop
20
20
  PATTERN
21
21
 
22
22
  def initialize(argument_node)
23
- @nodes = argument_kwargs(argument_node)
23
+ @nodes = argument_kwargs(argument_node) || []
24
24
  end
25
25
 
26
26
  def description
@@ -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
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module GraphQL
5
+ module SwapRange
6
+ def swap_range(corrector, current, previous)
7
+ current_range = declaration(current)
8
+ previous_range = declaration(previous)
9
+
10
+ src1 = current_range.source
11
+ src2 = previous_range.source
12
+
13
+ corrector.replace(current_range, src2)
14
+ corrector.replace(previous_range, src1)
15
+ end
16
+
17
+ def declaration(node)
18
+ buffer = processed_source.buffer
19
+ begin_pos = node.source_range.begin_pos
20
+ end_line = buffer.line_for_position(node.loc.expression.end_pos)
21
+ end_pos = buffer.line_range(end_line).end_pos
22
+ Parser::Source::Range.new(buffer, begin_pos, end_pos)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module GraphQL
3
- VERSION = "0.8.0".freeze
3
+ VERSION = "0.10.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.8.0
4
+ version: 0.10.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-04-08 00:00:00.000000000 Z
11
+ date: 2021-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -82,10 +82,10 @@ files:
82
82
  - LICENSE.txt
83
83
  - README.md
84
84
  - config/default.yml
85
+ - lib/refinements/underscore_string.rb
85
86
  - lib/rubocop-graphql.rb
86
87
  - lib/rubocop/cop/graphql/argument_description.rb
87
88
  - lib/rubocop/cop/graphql/argument_name.rb
88
- - lib/rubocop/cop/graphql/cop.rb
89
89
  - lib/rubocop/cop/graphql/extract_input_type.rb
90
90
  - lib/rubocop/cop/graphql/extract_type.rb
91
91
  - lib/rubocop/cop/graphql/field_definitions.rb
@@ -93,6 +93,7 @@ files:
93
93
  - lib/rubocop/cop/graphql/field_hash_key.rb
94
94
  - lib/rubocop/cop/graphql/field_method.rb
95
95
  - lib/rubocop/cop/graphql/field_name.rb
96
+ - lib/rubocop/cop/graphql/legacy_dsl.rb
96
97
  - lib/rubocop/cop/graphql/object_description.rb
97
98
  - lib/rubocop/cop/graphql/ordered_arguments.rb
98
99
  - lib/rubocop/cop/graphql/ordered_fields.rb
@@ -102,6 +103,7 @@ files:
102
103
  - lib/rubocop/graphql/argument.rb
103
104
  - lib/rubocop/graphql/argument/block.rb
104
105
  - lib/rubocop/graphql/argument/kwargs.rb
106
+ - lib/rubocop/graphql/description_method.rb
105
107
  - lib/rubocop/graphql/ext/snake_case.rb
106
108
  - lib/rubocop/graphql/field.rb
107
109
  - lib/rubocop/graphql/field/block.rb
@@ -109,6 +111,7 @@ files:
109
111
  - lib/rubocop/graphql/inject.rb
110
112
  - lib/rubocop/graphql/node_pattern.rb
111
113
  - lib/rubocop/graphql/schema_member.rb
114
+ - lib/rubocop/graphql/swap_range.rb
112
115
  - lib/rubocop/graphql/version.rb
113
116
  homepage: https://github.com/DmitryTsepelev/rubocop-graphql
114
117
  licenses:
@@ -125,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
128
  requirements:
126
129
  - - ">="
127
130
  - !ruby/object:Gem::Version
128
- version: '2.4'
131
+ version: '2.5'
129
132
  required_rubygems_version: !ruby/object:Gem::Requirement
130
133
  requirements:
131
134
  - - ">="
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- # Inspied by https://github.com/rubocop-hq/rubocop-rspec/blob/3a2088f79737e2e8e0e21482783f7d61411bf021/lib/rubocop/cop/rspec/cop.rb
5
- module Cop
6
- WorkaroundGraphqlCop = Cop.dup
7
-
8
- # Clone of the the normal RuboCop::Cop::Cop class so we can rewrite
9
- # the inherited method without breaking functionality
10
- class WorkaroundGraphqlCop
11
- # Remove the Cop.inherited method to be a noop. Our RSpec::Cop
12
- # class will invoke the inherited hook instead
13
- class << self
14
- undef inherited
15
- def inherited(*); end # rubocop:disable Lint/MissingSuper
16
- end
17
-
18
- # Special case `Module#<` so that the rspec support rubocop exports
19
- # is compatible with our subclass
20
- def self.<(other)
21
- other.equal?(RuboCop::Cop::Cop) || super
22
- end
23
- end
24
- private_constant(:WorkaroundGraphqlCop)
25
-
26
- module GraphQL
27
- # @abstract parent class to graphql-ruby cops
28
- #
29
- # The criteria for whether rubocop-rspec analyzes a certain ruby file
30
- # is configured via `AllCops/GraphQL`. For example, if you want to
31
- # customize your project to scan all files within a `graph/` directory
32
- # then you could add this to your configuration:
33
- #
34
- # @example configuring analyzed paths
35
- #
36
- # AllCops:
37
- # GraphQL:
38
- # Patterns:
39
- # - '(?:^|/)graph/'
40
- class Cop < WorkaroundGraphqlCop
41
- DEFAULT_CONFIGURATION =
42
- RuboCop::GraphQL::CONFIG.fetch("AllCops").fetch("GraphQL")
43
-
44
- DEFAULT_PATTERN_RE = Regexp.union(
45
- DEFAULT_CONFIGURATION.fetch("Patterns")
46
- .map(&Regexp.public_method(:new))
47
- )
48
-
49
- # Invoke the original inherited hook so our cops are recognized
50
- def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
51
- RuboCop::Cop::Cop.inherited(subclass)
52
- end
53
-
54
- def relevant_file?(file)
55
- relevant_rubocop_graphql_file?(file) && super
56
- end
57
-
58
- private
59
-
60
- def relevant_rubocop_graphql_file?(file)
61
- graphql_pattern =~ file
62
- end
63
-
64
- def graphql_pattern
65
- if rspec_graphql_config?
66
- Regexp.union(rspec_graphql_config.map(&Regexp.public_method(:new)))
67
- else
68
- DEFAULT_PATTERN_RE
69
- end
70
- end
71
-
72
- def all_cops_config
73
- config
74
- .for_all_cops
75
- end
76
-
77
- def rspec_graphql_config?
78
- return unless all_cops_config.key?("GraphQL")
79
-
80
- all_cops_config.fetch("GraphQL").key?("Patterns")
81
- end
82
-
83
- def rspec_graphql_config
84
- all_cops_config
85
- .fetch("GraphQL", DEFAULT_CONFIGURATION)
86
- .fetch("Patterns")
87
- end
88
- end
89
- end
90
- end
91
- end