rubocop-graphql 0.10.3 → 0.11.3

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: 60522da6cb205f7667084ee8a44f5500a426e4e52d677c60dee314d7e11e2129
4
- data.tar.gz: 6d091ec89349bd1b2d9ca160c53566fd11cd2dc0a786f33e81a12e7b46e9a20e
3
+ metadata.gz: ffc9fa90011bdaddbf2d485a5948ede1e7bf2ade1c91c3a960799a1e0cd47bb3
4
+ data.tar.gz: 4dcbb755ed55538cfb8539b86f0c186e13b201bbfd0bbf3201d3091b8058c0fe
5
5
  SHA512:
6
- metadata.gz: 708fbacb5879ce6be4ff0b9a9f34f85d13e1b65945a854c4b63cd96d9a74e145a8f20c1d792fcca9639ac524cb5c5353ddc09dd6f68e556c7e0167fbd4a9c544
7
- data.tar.gz: e827fa568a4a472b2246185afc47bca7c119b9af60a3cc77e8d9033556866468988f1f79b8e2e2f60a8b43381e97a416f9825e61317a850475961414b29578ac
6
+ metadata.gz: 25cf86cd5e3e3942eafed3383df445c3f71296bc63a617ba4a0a9e597f6c355a1f5f94b1f2718439cd5606c50573758b8d3381a40af59937ba20cba150a9fe3d
7
+ data.tar.gz: 745057b345ba218c88b5a21addced87fc6bd972147ac72281efa0e1c1db005694f3ec44d33dc6760bdff68edddf8fedaff1d23f270ca3fc5162b5f01652da902
data/config/default.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  GraphQL:
2
2
  Include:
3
3
  - "**/graphql/**/*"
4
+ Exclude:
5
+ - "spec/**/*"
6
+ - "test/**/*"
4
7
 
5
8
  GraphQL/ArgumentDescription:
6
9
  Enabled: true
@@ -12,6 +15,11 @@ GraphQL/ArgumentName:
12
15
  VersionAdded: '0.80'
13
16
  Description: 'This cop checks whether argument names are snake_case'
14
17
 
18
+ GraphQL/ArgumentUniqueness:
19
+ Enabled: true
20
+ VersionAdded: '0.80'
21
+ Description: 'This cop enforces arguments to be defined once per block'
22
+
15
23
  GraphQL/ResolverMethodLength:
16
24
  Enabled: true
17
25
  VersionAdded: '0.80'
@@ -50,6 +58,11 @@ GraphQL/FieldName:
50
58
  Description: 'This cop checks whether field names are snake_case'
51
59
  SafeAutoCorrect: false
52
60
 
61
+ GraphQL/FieldUniqueness:
62
+ Enabled: true
63
+ VersionAdded: '0.80'
64
+ Description: 'This cop enforces fields to be defined once'
65
+
53
66
  GraphQL/ExtractInputType:
54
67
  Enabled: true
55
68
  VersionAdded: '0.80'
@@ -90,3 +103,5 @@ GraphQL/OrderedFields:
90
103
  Enabled: true
91
104
  VersionAdded: '0.80'
92
105
  Description: 'Fields should be alphabetically sorted within groups'
106
+
107
+
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module GraphQL
6
+ # This cop detects duplicate argument definitions
7
+ #
8
+ # @example
9
+ # # good
10
+ #
11
+ # class BanUser < BaseMutation
12
+ # argument :user_id, ID, required: true
13
+ # end
14
+ #
15
+ # # bad
16
+ #
17
+ # class BanUser < BaseMutation
18
+ # argument :user_id, ID, required: true
19
+ # argument :user_id, ID, required: true
20
+ # end
21
+ #
22
+ class ArgumentUniqueness < Base
23
+ MSG = "Argument names should only be defined once per block. "\
24
+ "Argument `%<current>s` is duplicated%<field_name>s."
25
+
26
+ def on_class(node)
27
+ global_argument_names = Set.new
28
+ argument_names_by_field = {}
29
+
30
+ argument_declarations(node).each do |current|
31
+ current_field_name = field_name(current)
32
+ current_argument_name = argument_name(current)
33
+
34
+ if current_field_name
35
+ argument_names_by_field[current_field_name] ||= Set.new
36
+ argument_names = argument_names_by_field[current_field_name]
37
+ else
38
+ argument_names = global_argument_names
39
+ end
40
+
41
+ unless argument_names.include?(current_argument_name)
42
+ argument_names.add(current_argument_name)
43
+ next
44
+ end
45
+
46
+ register_offense(current)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def register_offense(current)
53
+ current_field_name = field_name(current)
54
+ field_name_message = " in field `#{current_field_name}`" if current_field_name
55
+
56
+ message = format(
57
+ self.class::MSG,
58
+ current: argument_name(current),
59
+ field_name: field_name_message
60
+ )
61
+
62
+ add_offense(current, message: message)
63
+ end
64
+
65
+ def argument_name(node)
66
+ node.first_argument.value.to_s
67
+ end
68
+
69
+ # Find parent field block, if available
70
+ def field_name(node)
71
+ return if node.nil?
72
+
73
+ is_field_block = node.block_type? &&
74
+ node.respond_to?(:method_name) &&
75
+ node.method_name == :field
76
+ return node.send_node.first_argument.value.to_s if is_field_block
77
+
78
+ field_name(node.parent)
79
+ end
80
+
81
+ def_node_search :argument_declarations, <<~PATTERN
82
+ (send nil? :argument (:sym _) ...)
83
+ PATTERN
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module GraphQL
6
+ # This cop detects duplicate field definitions within
7
+ # the same type
8
+ #
9
+ # @example
10
+ # # good
11
+ #
12
+ # class UserType < BaseType
13
+ # field :name, String, null: true
14
+ # field :phone, String, null: true do
15
+ # argument :something, String, required: false
16
+ # end
17
+ # end
18
+ #
19
+ # # bad
20
+ #
21
+ # class UserType < BaseType
22
+ # field :name, String, null: true
23
+ # field :phone, String, null: true
24
+ # field :phone, String, null: true do
25
+ # argument :something, String, required: false
26
+ # end
27
+ # end
28
+ #
29
+ class FieldUniqueness < Base
30
+ MSG = "Field names should only be defined once per type. "\
31
+ "Field `%<current>s` is duplicated."
32
+
33
+ def on_class(node)
34
+ return if nested_class?(node)
35
+
36
+ field_names_by_class = Hash.new { |h, k| h[k] = Set.new }
37
+
38
+ field_declarations(node).each do |current|
39
+ current_class = current_class_name(current)
40
+ field_names = field_names_by_class[current_class]
41
+ current_field_name = field_name(current)
42
+
43
+ unless field_names.include?(current_field_name)
44
+ field_names.add(current_field_name)
45
+ next
46
+ end
47
+
48
+ register_offense(current)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def nested_class?(node)
55
+ node.each_ancestor(:class).any?
56
+ end
57
+
58
+ def register_offense(current)
59
+ message = format(
60
+ self.class::MSG,
61
+ current: field_name(current)
62
+ )
63
+
64
+ add_offense(current, message: message)
65
+ end
66
+
67
+ def field_name(node)
68
+ node.first_argument.value.to_s
69
+ end
70
+
71
+ def current_class_name(node)
72
+ node.each_ancestor(:class).first.defined_module_name
73
+ end
74
+
75
+ def_node_search :field_declarations, <<~PATTERN
76
+ {
77
+ (send nil? :field (:sym _) ...)
78
+ }
79
+ PATTERN
80
+ end
81
+ end
82
+ end
83
+ end
@@ -59,7 +59,7 @@ module RuboCop
59
59
  def on_class(node)
60
60
  argument_declarations(node).each_cons(2) do |previous, current|
61
61
  next unless consecutive_lines(previous, current)
62
- next if argument_name(current) > argument_name(previous)
62
+ next if argument_name(current) >= argument_name(previous)
63
63
 
64
64
  register_offense(previous, current)
65
65
  end
@@ -42,7 +42,7 @@ module RuboCop
42
42
  def on_class(node)
43
43
  field_declarations(node).each_cons(2) do |previous, current|
44
44
  next unless consecutive_lines(previous, current)
45
- next if field_name(current) > field_name(previous)
45
+ next if field_name(current) >= field_name(previous)
46
46
 
47
47
  register_offense(previous, current)
48
48
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "graphql/argument_description"
4
4
  require_relative "graphql/argument_name"
5
+ require_relative "graphql/argument_uniqueness"
5
6
  require_relative "graphql/extract_input_type"
6
7
  require_relative "graphql/extract_type"
7
8
  require_relative "graphql/field_definitions"
@@ -9,6 +10,7 @@ require_relative "graphql/field_description"
9
10
  require_relative "graphql/field_hash_key"
10
11
  require_relative "graphql/field_method"
11
12
  require_relative "graphql/field_name"
13
+ require_relative "graphql/field_uniqueness"
12
14
  require_relative "graphql/legacy_dsl"
13
15
  require_relative "graphql/resolver_method_length"
14
16
  require_relative "graphql/object_description"
@@ -21,7 +21,8 @@ module RuboCop
21
21
  extend RuboCop::NodePattern::Macros
22
22
 
23
23
  def_node_matcher :description_kwarg?, <<~PATTERN
24
- (send nil? :description {({str|dstr} ...)|(send ({str|dstr} ...) _)})
24
+ (send nil? :description
25
+ {({str|dstr|const} ...)|(send const ...)|(send ({str|dstr} ...) _)})
25
26
  PATTERN
26
27
 
27
28
  def find_description_method(nodes)
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module GraphQL
3
- VERSION = "0.10.3".freeze
3
+ VERSION = "0.11.3".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.10.3
4
+ version: 0.11.3
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: 2021-11-09 00:00:00.000000000 Z
11
+ date: 2021-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,6 +86,7 @@ files:
86
86
  - lib/rubocop-graphql.rb
87
87
  - lib/rubocop/cop/graphql/argument_description.rb
88
88
  - lib/rubocop/cop/graphql/argument_name.rb
89
+ - lib/rubocop/cop/graphql/argument_uniqueness.rb
89
90
  - lib/rubocop/cop/graphql/extract_input_type.rb
90
91
  - lib/rubocop/cop/graphql/extract_type.rb
91
92
  - lib/rubocop/cop/graphql/field_definitions.rb
@@ -93,6 +94,7 @@ files:
93
94
  - lib/rubocop/cop/graphql/field_hash_key.rb
94
95
  - lib/rubocop/cop/graphql/field_method.rb
95
96
  - lib/rubocop/cop/graphql/field_name.rb
97
+ - lib/rubocop/cop/graphql/field_uniqueness.rb
96
98
  - lib/rubocop/cop/graphql/legacy_dsl.rb
97
99
  - lib/rubocop/cop/graphql/object_description.rb
98
100
  - lib/rubocop/cop/graphql/ordered_arguments.rb
@@ -120,7 +122,7 @@ metadata:
120
122
  homepage_uri: https://github.com/DmitryTsepelev/rubocop-graphql
121
123
  source_code_uri: https://github.com/DmitryTsepelev/rubocop-graphql
122
124
  changelog_uri: https://github.com/DmitryTsepelev/rubocop-graphql/CHANGELOG.md
123
- post_install_message:
125
+ post_install_message:
124
126
  rdoc_options: []
125
127
  require_paths:
126
128
  - lib
@@ -135,8 +137,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
137
  - !ruby/object:Gem::Version
136
138
  version: '0'
137
139
  requirements: []
138
- rubygems_version: 3.1.6
139
- signing_key:
140
+ rubygems_version: 3.0.3.1
141
+ signing_key:
140
142
  specification_version: 4
141
143
  summary: Automatic performance checking tool for Ruby code.
142
144
  test_files: []