rubocop-graphql 0.4.1 → 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: 67638fefeb268ea870db034bc46363245b644ec8df5f620878e8e1c90b681975
4
- data.tar.gz: b378c1830557ccbf00b7be144b6ac6141c7246e60b848d91b14a5cc8eee86a2a
3
+ metadata.gz: 99b9cc340e883dfe2dd4d0662a04383fde0a0b648cd1716f8aaec8eef8aab486
4
+ data.tar.gz: 928eee0593772d1614c6527ebefeb11753b3797408a98bdd84ae6c6fa46ca8da
5
5
  SHA512:
6
- metadata.gz: e9dbfcab7cdb4820b9ab7d1a9425bb1378bcc279aebb82116058398f9b66b97d90c6af5edf38dd0c94d079f57395ffc7055936e00d89ec98c72e606b4c4d955a
7
- data.tar.gz: 0dd262d908e7de3cbb2fc8b57aab421a7e32214f42322c1bdeab03f43b96072e349e2d0165158df123e78cf0700b9bebc95acb4876a7b5ba655c0fa44eb566f6
6
+ metadata.gz: 736f86f09bc7123fd0c5227ce35f771a83d75532d9231becd4a444b725fbddac7494fadcbffe929ddfcb0609e6ff80d53510d379792141e12d5d7c3fb08f4056
7
+ data.tar.gz: 2603c7d27cccd23e904c9345b9b1728a16bf99a1c03162ff93281a0a64f7f1621f5f8ad874af950671275be4a8f743dbbae71e8439d0f369b8ae4c9b5586e26e
@@ -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
 
@@ -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
 
@@ -33,6 +33,10 @@ module RuboCop
33
33
  (send nil? :description (:str $_))
34
34
  PATTERN
35
35
 
36
+ def_node_matcher :has_multiline_string_description?, <<~PATTERN
37
+ (send nil? :description (:dstr ...))
38
+ PATTERN
39
+
36
40
  def_node_matcher :interface?, <<~PATTERN
37
41
  (send nil? :include (const ...))
38
42
  PATTERN
@@ -54,7 +58,9 @@ module RuboCop
54
58
  private
55
59
 
56
60
  def has_description?(node)
57
- has_i18n_description?(node) || has_string_description?(node)
61
+ has_i18n_description?(node) ||
62
+ has_string_description?(node) ||
63
+ has_multiline_string_description?(node)
58
64
  end
59
65
 
60
66
  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
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module GraphQL
6
+ # Field should be alphabetically sorted within groups.
7
+ #
8
+ # @example
9
+ # # good
10
+ #
11
+ # class UserType < BaseType
12
+ # field :name, String, null: true
13
+ # field :phone, String, null: true do
14
+ # argument :something, String, required: false
15
+ # end
16
+ # end
17
+ #
18
+ # # good
19
+ #
20
+ # class UserType < BaseType
21
+ # field :phone, String, null: true
22
+ #
23
+ # field :name, String, null: true
24
+ # end
25
+ #
26
+ # # bad
27
+ #
28
+ # class UserType < BaseType
29
+ # field :phone, String, null: true
30
+ # field :name, String, null: true
31
+ # end
32
+ #
33
+ class OrderedFields < Cop
34
+ MSG = "Fields should be sorted in an alphabetical order within their "\
35
+ "section. "\
36
+ "Field `%<current>s` should appear before `%<previous>s`."
37
+
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)
57
+
58
+ lambda do |corrector|
59
+ swap_range(corrector, current_range, previous_range)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def register_offense(previous, current)
66
+ message = format(
67
+ self.class::MSG,
68
+ previous: field_name(previous),
69
+ current: field_name(current)
70
+ )
71
+ add_offense(current, message: message)
72
+ end
73
+
74
+ def field_name(node)
75
+ if node.block_type?
76
+ field_name(node.send_node)
77
+ else
78
+ node.first_argument.value.to_s
79
+ end
80
+ end
81
+
82
+ def consecutive_lines(previous, current)
83
+ previous.source_range.last_line == current.source_range.first_line - 1
84
+ end
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
+
101
+ def_node_search :field_declarations, <<~PATTERN
102
+ {
103
+ (send nil? :field (:sym _) ...)
104
+ (block
105
+ (send nil? :field (:sym _) ...) ...)
106
+ }
107
+ PATTERN
108
+ end
109
+ end
110
+ end
111
+ end
@@ -13,3 +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"
17
+ require_relative "graphql/ordered_fields"
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module GraphQL
3
- VERSION = "0.4.1".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.4.1
4
+ version: 0.7.0
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-08-17 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
@@ -56,16 +56,22 @@ dependencies:
56
56
  name: rubocop
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0.87'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '2'
62
65
  type: :runtime
63
66
  prerelease: false
64
67
  version_requirements: !ruby/object:Gem::Requirement
65
68
  requirements:
66
- - - "~>"
69
+ - - ">="
67
70
  - !ruby/object:Gem::Version
68
71
  version: '0.87'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '2'
69
75
  description: A collection of RuboCop cops to improve GraphQL-related code
70
76
  email:
71
77
  - dmitry.a.tsepelev@gmail.com
@@ -88,6 +94,8 @@ files:
88
94
  - lib/rubocop/cop/graphql/field_method.rb
89
95
  - lib/rubocop/cop/graphql/field_name.rb
90
96
  - lib/rubocop/cop/graphql/object_description.rb
97
+ - lib/rubocop/cop/graphql/ordered_arguments.rb
98
+ - lib/rubocop/cop/graphql/ordered_fields.rb
91
99
  - lib/rubocop/cop/graphql/resolver_method_length.rb
92
100
  - lib/rubocop/cop/graphql_cops.rb
93
101
  - lib/rubocop/graphql.rb
@@ -109,7 +117,7 @@ metadata:
109
117
  homepage_uri: https://github.com/DmitryTsepelev/rubocop-graphql
110
118
  source_code_uri: https://github.com/DmitryTsepelev/rubocop-graphql
111
119
  changelog_uri: https://github.com/DmitryTsepelev/rubocop-graphql/CHANGELOG.md
112
- post_install_message:
120
+ post_install_message:
113
121
  rdoc_options: []
114
122
  require_paths:
115
123
  - lib
@@ -124,8 +132,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
132
  - !ruby/object:Gem::Version
125
133
  version: '0'
126
134
  requirements: []
127
- rubygems_version: 3.0.3
128
- signing_key:
135
+ rubygems_version: 3.1.2
136
+ signing_key:
129
137
  specification_version: 4
130
138
  summary: Automatic performance checking tool for Ruby code.
131
139
  test_files: []