ruby-lsp-rails-factory-bot 0.3.0 → 0.5.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: 01d1b4f936612100587a05ace6ca2c46fd654484c7d1125245e3c3afd7ce2fb2
4
- data.tar.gz: cd15946860a27dbaa31ba14b8f429c5afb7f4bd21a9eeb1aca0f01411006bebf
3
+ metadata.gz: 74a733cd2866ef2bf14eef3cb4a7dd97dec52c7a315bed5ea884860bcb268f10
4
+ data.tar.gz: b3ff978e4038960010882e6b51bf079aa057de8ba7ce60acb37b278aaec304ba
5
5
  SHA512:
6
- metadata.gz: e09bd8301b1003c30ba6efdba15c6c945f4f0ca0adbda81e8f290bcf4a0dff480c1c482e28499a5477d80a656a358018788a6a5022441da8698c940272089e2c
7
- data.tar.gz: 3b145ca533d21b291cd545dde273f4c6f333ea255beca536c01f44e488b02a813d4beab114a4d4269b3c0add785b020df3cc875777d28183b2f338a7005a38df
6
+ metadata.gz: f32b35548606386cf6bfdac973f5437d5a182984f8285f512f47f90f5a49d46598415de52661ed1c4962538b5c1dc29af29a497e2083de4e14a2981d62fe8b5d
7
+ data.tar.gz: 98bfeb00adb8386588921797416174e6a7121f678b6b081c678f3367cf4e327aded286423ff93879f190524891c3274464d3ec191eb568727b9b947d2cb4b3f9
data/README.md CHANGED
@@ -24,18 +24,25 @@ Receive completion suggestions as you type
24
24
 
25
25
  ![lsp-factory-bot-completion](https://github.com/user-attachments/assets/4255a86a-8f36-4de2-8d10-8cb5a3f49e50)
26
26
 
27
+ Click through to definitions
28
+
29
+ ![lsp-factory-bot-definition-trait](https://github.com/user-attachments/assets/92a4b224-b587-442d-9463-50d526872039)
30
+
31
+ ![lsp-factory-bot-definition-attribute](https://github.com/user-attachments/assets/d8650678-6759-42c8-b015-0fdbd4045494)
32
+
33
+
27
34
  ### Supports
28
35
 
29
36
  | | Hover | Completion | Go to definition |
30
37
  | ------------- |-------------| -----| ----|
31
- | Factory name | ✅ | ⭕️ | |
32
- | Trait | ✅ | ⭕️ | |
33
- | Attribute | ✅ | | ❌ |
38
+ | Attribute | ✅ | | |
39
+ | Trait | ✅ | ⭕️ |
40
+ | Factory name | ✅ | ⭕️ | ❌ ||
34
41
 
35
42
  Notes:
36
43
 
37
44
  - The extension has "understanding" of factory/trait completion items, but due to limitations on when ruby-lsp displays the completion suggestions, they aren't visible for Symbols (eg. factory/trait names) :/ though they happen to be visible for symbols in Hash/Kw notation (ie with `:` after - `key: ...`)
38
- - Go to definition not supported yet but might come soon
45
+ - Factory definition is not supported at the moment (current limitation of factory bot), but might come in due course
39
46
 
40
47
 
41
48
  ## Development
@@ -5,6 +5,7 @@ require "ruby_lsp/ruby_lsp_rails/addon"
5
5
 
6
6
  require_relative "completion"
7
7
  require_relative "hover"
8
+ require_relative "definition"
8
9
  require_relative "addon_name"
9
10
  require_relative "../factory_bot"
10
11
  require_relative "../../../ruby_lsp_rails_factory_bot"
@@ -32,16 +33,16 @@ module RubyLsp
32
33
  Completion.new(response_builder, node_context, dispatcher, runner_client)
33
34
  end
34
35
 
35
- # TODO: need URI param to be able to filter by file name
36
36
  def create_hover_listener(response_builder, node_context, dispatcher)
37
- unless @addon_registered
38
- register_addon!
39
- return
40
- end
41
-
37
+ register_addon!
42
38
  Hover.new(response_builder, node_context, dispatcher, runner_client, @ruby_index)
43
39
  end
44
40
 
41
+ def create_definition_listener(response_builder, _uri, node_context, dispatcher)
42
+ register_addon!
43
+ Definition.new(response_builder, node_context, dispatcher, runner_client)
44
+ end
45
+
45
46
  def workspace_did_change_watched_files(changes)
46
47
  return unless changes.any? do |change|
47
48
  change[:uri].match?(/(?:spec|test).+factor.+\.rb/)
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby_lsp/internal"
4
+
5
+ require_relative "addon_name"
6
+
7
+ module RubyLsp
8
+ module Rails
9
+ module FactoryBot
10
+ # Definition listener - calls the registered methods when the appropriate nodes are entered
11
+ class Definition
12
+ include RubyLsp::Requests::Support::Common
13
+
14
+ def initialize(response_builder, node_context, dispatcher, server_client)
15
+ @response_builder = response_builder
16
+ @node_context = node_context
17
+ @server_client = server_client
18
+
19
+ dispatcher.register self, :on_symbol_node_enter
20
+ end
21
+
22
+ def on_symbol_node_enter(symbol_node)
23
+ parent = @node_context.parent
24
+ call_node = @node_context.call_node
25
+
26
+ return unless call_node
27
+
28
+ # "parent" isn't strictly speaking the immediate parent as in the AST - the
29
+ # element it refers to is a bit opinionated... in this case, it is always the call node,
30
+ # whether the symbol is an argument in the call_node args, or a symbol in a kw hash :/
31
+ unless parent.is_a?(Prism::CallNode) || FactoryBot::FACTORY_BOT_METHODS.include?(call_node.message.to_sym)
32
+ return
33
+ end
34
+
35
+ process_arguments_pattern(symbol_node, call_node.arguments.arguments)
36
+ end
37
+
38
+ private
39
+
40
+ def process_arguments_pattern(symbol_node, arguments) # rubocop:disable Metrics/MethodLength
41
+ case arguments
42
+ in [^symbol_node, *]
43
+ # factory location currently not available
44
+ #
45
+ # handle_factory(symbol_node)
46
+ in [Prism::SymbolNode => _factory_node, *, ^symbol_node] |
47
+ [Prism::SymbolNode => _factory_node, *, ^symbol_node, Prism::KeywordHashNode] |
48
+ [Prism::SymbolNode => _factory_node, *, ^symbol_node, Prism::HashNode] |
49
+ [Prism::SymbolNode => _factory_node, ^symbol_node, *] |
50
+ [Prism::SymbolNode => _factory_node, Prism::IntegerNode, ^symbol_node, *] |
51
+ [Prism::SymbolNode => _factory_node, Prism::IntegerNode, *, ^symbol_node, Prism::KeywordHashNode] |
52
+ [Prism::SymbolNode => _factory_node, Prism::IntegerNode, *, ^symbol_node, Prism::HashNode]
53
+
54
+ handle_trait(symbol_node, _factory_node)
55
+
56
+ in [Prism::SymbolNode => _factory_node, *, Prism::KeywordHashNode => _kw_hash] |
57
+ [Prism::SymbolNode => _factory_node, *, Prism::HashNode => _kw_hash]
58
+
59
+ handle_attribute(symbol_node, _factory_node) if _kw_hash.elements.any? { |e| e.key == symbol_node }
60
+ else
61
+ nil
62
+ end
63
+ end
64
+
65
+ def handle_attribute(symbol_node, factory_node)
66
+ name = symbol_node.value.to_s
67
+ attribute = make_request(
68
+ :attributes,
69
+ factory_name: factory_node.value.to_s, name: name,
70
+ )&.find { |attr| attr[:name] == name }
71
+
72
+ return unless attribute && attribute[:source_location]&.length&.positive?
73
+
74
+ @response_builder << Support::LocationBuilder.line_location_from_s(attribute[:source_location].join(":"))
75
+ end
76
+
77
+ def handle_factory(symbol_node)
78
+ name = symbol_node.value.to_s
79
+ factory = make_request(:factories, name: name)&.find { |f| f[:name] == name }
80
+ return unless factory && factory[:source_location]&.length&.positive?
81
+
82
+ @response_builder << Support::LocationBuilder.line_location_from_s(factory[:source_location].join(":"))
83
+ end
84
+
85
+ def handle_trait(symbol_node, factory_node)
86
+ factory_name = factory_node.value.to_s
87
+ trait_name = symbol_node.value.to_s
88
+
89
+ trait = make_request(:traits, factory_name: factory_name, name: trait_name)&.find do |tr|
90
+ tr[:name] == trait_name
91
+ end
92
+
93
+ return unless trait && trait[:source_location]&.length&.positive?
94
+
95
+ @response_builder << Support::LocationBuilder.line_location_from_s(trait[:source_location].join(":"))
96
+ end
97
+
98
+ def make_request(request_name, **params)
99
+ @server_client.delegate_request(
100
+ server_addon_name: FactoryBot::ADDON_NAME,
101
+ request_name: request_name.to_s,
102
+ **params,
103
+ )
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -7,7 +7,7 @@ require_relative "addon_name"
7
7
  module RubyLsp
8
8
  module Rails
9
9
  module FactoryBot
10
- # The listener that is created during relevant hover actions
10
+ # Hover listener - calls the registered methods when the appropriate nodes are entered
11
11
  class Hover
12
12
  include RubyLsp::Requests::Support::Common
13
13
 
@@ -43,8 +43,12 @@ module RubyLsp
43
43
  in [^symbol_node, *]
44
44
  handle_factory(symbol_node)
45
45
  in [Prism::SymbolNode => _factory_node, *, ^symbol_node] |
46
+ [Prism::SymbolNode => _factory_node, *, ^symbol_node, Prism::KeywordHashNode] |
47
+ [Prism::SymbolNode => _factory_node, *, ^symbol_node, Prism::HashNode] |
46
48
  [Prism::SymbolNode => _factory_node, ^symbol_node, *] |
47
- [Prism::SymbolNode => _factory_node, Integer, ^symbol_node, *]
49
+ [Prism::SymbolNode => _factory_node, Prism::IntegerNode, ^symbol_node, *] |
50
+ [Prism::SymbolNode => _factory_node, Prism::IntegerNode, *, ^symbol_node, Prism::KeywordHashNode] |
51
+ [Prism::SymbolNode => _factory_node, Prism::IntegerNode, *, ^symbol_node, Prism::HashNode]
48
52
 
49
53
  handle_trait(symbol_node, _factory_node)
50
54
 
@@ -88,6 +92,11 @@ module RubyLsp
88
92
  @response_builder.push(hint, category: :documentation)
89
93
  end
90
94
 
95
+ def trait_tooltip(trait, factory_name)
96
+ source = trait[:source]&.length&.positive? ? trait[:source] : nil
97
+ source || "#{trait[:name]} (trait of #{trait[:owner] || factory_name})"
98
+ end
99
+
91
100
  def handle_trait(symbol_node, factory_node)
92
101
  factory_name = factory_node.value.to_s
93
102
  trait_name = symbol_node.value.to_s
@@ -98,10 +107,7 @@ module RubyLsp
98
107
 
99
108
  return unless trait
100
109
 
101
- @response_builder.push(
102
- "#{trait[:name]} (trait of #{trait[:owner] || factory_name})",
103
- category: :documentation,
104
- )
110
+ @response_builder.push(trait_tooltip(trait, factory_name), category: :documentation)
105
111
  end
106
112
 
107
113
  def make_request(request_name, **params)
@@ -3,7 +3,7 @@
3
3
  module RubyLsp
4
4
  module Rails
5
5
  module FactoryBot
6
- VERSION = "0.3.0"
6
+ VERSION = "0.5.0"
7
7
  REQUIRED_RUBY_LSP_RAILS_VERSION = "~> 0.4"
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp-rails-factory-bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - johansenja
@@ -82,6 +82,7 @@ files:
82
82
  - lib/ruby_lsp/rails/factory_bot/addon.rb
83
83
  - lib/ruby_lsp/rails/factory_bot/addon_name.rb
84
84
  - lib/ruby_lsp/rails/factory_bot/completion.rb
85
+ - lib/ruby_lsp/rails/factory_bot/definition.rb
85
86
  - lib/ruby_lsp/rails/factory_bot/hover.rb
86
87
  - lib/ruby_lsp/rails/factory_bot/server_addon.rb
87
88
  - lib/ruby_lsp/rails/factory_bot/server_addon/attribute_handler.rb