ruby-lsp-rails-factory-bot 0.4.0 → 0.6.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 +4 -4
- data/README.md +13 -8
- data/lib/ruby_lsp/rails/factory_bot/addon.rb +6 -0
- data/lib/ruby_lsp/rails/factory_bot/definition.rb +108 -0
- data/lib/ruby_lsp/rails/factory_bot/hover.rb +26 -16
- data/lib/ruby_lsp/rails/factory_bot/server_addon/base_handler.rb +1 -1
- data/lib/ruby_lsp_rails_factory_bot.rb +1 -1
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecaef6088d61c2afa9d54e033f288ab6221f3e607214f31d7a2c4749a9c58450
|
4
|
+
data.tar.gz: 813d00d86a4f54c299ab0cd8db98760f8d0e33207d1621fc454813acd70914d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04755031614a46a02d65feb63b1f926e0ab4525d3e6b561f7964712ea9e46dfceccbfda8471586e518c2af5e308edb9050a1f36c8cff700b66804946e994c852
|
7
|
+
data.tar.gz: 822d8093fc8d3c113d17ddedd6e5fa7c37254b67c79227d6e7c6bbd97ee6bea436f17d7e387ed1a5b160b0e9841e37a23996cdf1ea19a17524e027ab12790c0f
|
data/README.md
CHANGED
@@ -12,30 +12,35 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
12
12
|
|
13
13
|
$ gem install ruby-lsp-rails-factory-bot
|
14
14
|
|
15
|
-
Note that this currenlty uses a fork of ruby-lsp-rails (to extend its server to be able to provide factory information).
|
16
|
-
|
17
15
|
## Usage
|
18
16
|
|
19
|
-
Hover over
|
17
|
+
Hover over a factory name, trait, or attribute
|
20
18
|
|
21
|
-

|
22
20
|
|
23
21
|
Receive completion suggestions as you type
|
24
22
|
|
25
23
|

|
26
24
|
|
25
|
+
Click through to definitions
|
26
|
+
|
27
|
+

|
28
|
+
|
29
|
+

|
30
|
+
|
31
|
+
|
27
32
|
### Supports
|
28
33
|
|
29
34
|
| | Hover | Completion | Go to definition |
|
30
35
|
| ------------- |-------------| -----| ----|
|
31
|
-
|
|
32
|
-
| Trait | ✅ | ⭕️ |
|
33
|
-
|
|
36
|
+
| Attribute | ✅ | ✅ | ✅ |
|
37
|
+
| Trait | ✅ | ⭕️ | ✅
|
38
|
+
| Factory name | ✅ | ⭕️ | ❌ ||
|
34
39
|
|
35
40
|
Notes:
|
36
41
|
|
37
42
|
- 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
|
-
-
|
43
|
+
- Factory definition is not supported at the moment (limitation of current implementation), but might come in due course
|
39
44
|
|
40
45
|
|
41
46
|
## 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"
|
@@ -37,6 +38,11 @@ module RubyLsp
|
|
37
38
|
Hover.new(response_builder, node_context, dispatcher, runner_client, @ruby_index)
|
38
39
|
end
|
39
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
|
+
|
40
46
|
def workspace_did_change_watched_files(changes)
|
41
47
|
return unless changes.any? do |change|
|
42
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
|
-
#
|
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
|
|
@@ -61,6 +61,12 @@ module RubyLsp
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
def build_response(title, documentation, link)
|
65
|
+
@response_builder.push(title, category: :title) if title
|
66
|
+
@response_builder.push(documentation, category: :documentation) if documentation
|
67
|
+
@response_builder.push(link, category: :links) if link
|
68
|
+
end
|
69
|
+
|
64
70
|
def handle_attribute(symbol_node, factory_node)
|
65
71
|
name = symbol_node.value.to_s
|
66
72
|
attribute = make_request(
|
@@ -70,10 +76,14 @@ module RubyLsp
|
|
70
76
|
|
71
77
|
return unless attribute
|
72
78
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
79
|
+
build_response(attribute[:name].to_s, attribute[:type].to_s, link_location(attribute[:source_location]))
|
80
|
+
end
|
81
|
+
|
82
|
+
def factory_documentation(factory)
|
83
|
+
index_entry = @ruby_index.first_unqualified_const(factory[:name])
|
84
|
+
return markdown_from_index_entries(factory[:model_class], index_entry) if index_entry
|
85
|
+
|
86
|
+
factory[:model_class].to_s
|
77
87
|
end
|
78
88
|
|
79
89
|
def handle_factory(symbol_node)
|
@@ -81,20 +91,12 @@ module RubyLsp
|
|
81
91
|
factory = make_request(:factories, name: name)&.find { |f| f[:name] == name }
|
82
92
|
return unless factory
|
83
93
|
|
84
|
-
|
85
|
-
|
86
|
-
hint = if index_entry
|
87
|
-
markdown_from_index_entries(factory[:model_class], index_entry)
|
88
|
-
else
|
89
|
-
"#{factory[:name]} (#{factory[:model_class]})"
|
90
|
-
end
|
91
|
-
|
92
|
-
@response_builder.push(hint, category: :documentation)
|
94
|
+
build_response(factory[:name], factory_documentation(factory), nil)
|
93
95
|
end
|
94
96
|
|
95
97
|
def trait_tooltip(trait, factory_name)
|
96
98
|
source = trait[:source]&.length&.positive? ? trait[:source] : nil
|
97
|
-
source
|
99
|
+
source ? "```ruby\n#{source}\n```" : "trait of #{trait[:owner] || factory_name}"
|
98
100
|
end
|
99
101
|
|
100
102
|
def handle_trait(symbol_node, factory_node)
|
@@ -107,7 +109,7 @@ module RubyLsp
|
|
107
109
|
|
108
110
|
return unless trait
|
109
111
|
|
110
|
-
|
112
|
+
build_response(trait[:name], trait_tooltip(trait, factory_name), link_location(trait[:source_location]))
|
111
113
|
end
|
112
114
|
|
113
115
|
def make_request(request_name, **params)
|
@@ -117,6 +119,14 @@ module RubyLsp
|
|
117
119
|
**params,
|
118
120
|
)
|
119
121
|
end
|
122
|
+
|
123
|
+
def link_location(source_location)
|
124
|
+
return unless source_location
|
125
|
+
|
126
|
+
return if source_location.empty?
|
127
|
+
|
128
|
+
"[Definition](#{URI::Generic.from_path(path: source_location[0])}#L#{source_location[1]})"
|
129
|
+
end
|
120
130
|
end
|
121
131
|
end
|
122
132
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp-rails-factory-bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- johansenja
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: factory_bot
|
@@ -66,8 +66,8 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: A ruby-lsp-rails extension for factorybot,
|
70
|
-
|
69
|
+
description: A ruby-lsp-rails extension for factorybot, supporting hover, go-to-definition
|
70
|
+
and autocompletion - for factories, traits and attributes
|
71
71
|
email:
|
72
72
|
- 43235608+johansenja@users.noreply.github.com
|
73
73
|
executables: []
|
@@ -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
|
@@ -113,8 +114,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
114
|
- !ruby/object:Gem::Version
|
114
115
|
version: '0'
|
115
116
|
requirements: []
|
116
|
-
rubygems_version: 3.
|
117
|
+
rubygems_version: 3.5.11
|
117
118
|
signing_key:
|
118
119
|
specification_version: 4
|
119
|
-
summary: A ruby-lsp-rails extension for factorybot
|
120
|
+
summary: A ruby-lsp-rails extension for factorybot, supporting hover, go-to-definition
|
121
|
+
and autocompletion
|
120
122
|
test_files: []
|