ruby-lsp-rails-factory-bot 0.2.0 → 0.3.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 +18 -0
- data/lib/ruby_lsp/rails/factory_bot/addon.rb +4 -21
- data/lib/ruby_lsp/rails/factory_bot/completion.rb +54 -17
- data/lib/ruby_lsp_rails_factory_bot.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01d1b4f936612100587a05ace6ca2c46fd654484c7d1125245e3c3afd7ce2fb2
|
|
4
|
+
data.tar.gz: cd15946860a27dbaa31ba14b8f429c5afb7f4bd21a9eeb1aca0f01411006bebf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e09bd8301b1003c30ba6efdba15c6c945f4f0ca0adbda81e8f290bcf4a0dff480c1c482e28499a5477d80a656a358018788a6a5022441da8698c940272089e2c
|
|
7
|
+
data.tar.gz: 3b145ca533d21b291cd545dde273f4c6f333ea255beca536c01f44e488b02a813d4beab114a4d4269b3c0add785b020df3cc875777d28183b2f338a7005a38df
|
data/README.md
CHANGED
|
@@ -20,6 +20,24 @@ Hover over an attribute or factory definition
|
|
|
20
20
|
|
|
21
21
|

|
|
22
22
|
|
|
23
|
+
Receive completion suggestions as you type
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
### Supports
|
|
28
|
+
|
|
29
|
+
| | Hover | Completion | Go to definition |
|
|
30
|
+
| ------------- |-------------| -----| ----|
|
|
31
|
+
| Factory name | ✅ | ⭕️ | ❌ |
|
|
32
|
+
| Trait | ✅ | ⭕️ | ❌ |
|
|
33
|
+
| Attribute | ✅ | ✅ | ❌ |
|
|
34
|
+
|
|
35
|
+
Notes:
|
|
36
|
+
|
|
37
|
+
- 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
|
|
39
|
+
|
|
40
|
+
|
|
23
41
|
## Development
|
|
24
42
|
|
|
25
43
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -27,15 +27,10 @@ module RubyLsp
|
|
|
27
27
|
FactoryBot::ADDON_NAME
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
# ensure_addon_registered!
|
|
36
|
-
|
|
37
|
-
# Completion.new(response_builder, node_context, dispatcher, runner_client)
|
|
38
|
-
# end
|
|
30
|
+
def create_completion_listener(response_builder, node_context, dispatcher, _uri)
|
|
31
|
+
register_addon!
|
|
32
|
+
Completion.new(response_builder, node_context, dispatcher, runner_client)
|
|
33
|
+
end
|
|
39
34
|
|
|
40
35
|
# TODO: need URI param to be able to filter by file name
|
|
41
36
|
def create_hover_listener(response_builder, node_context, dispatcher)
|
|
@@ -75,18 +70,6 @@ module RubyLsp
|
|
|
75
70
|
@rails_addon.rails_runner_client
|
|
76
71
|
end
|
|
77
72
|
|
|
78
|
-
FACTORY_BOT_METHODS = %i[
|
|
79
|
-
create
|
|
80
|
-
build
|
|
81
|
-
build_stubbed
|
|
82
|
-
attributes_for
|
|
83
|
-
].flat_map { |attr| [attr, :"#{attr}_list", :"#{attr}_pair"] }.freeze
|
|
84
|
-
|
|
85
|
-
def factory_bot_call_args?(node_context)
|
|
86
|
-
node_context.call_node && FACTORY_BOT_METHODS.include?(node_context.call_node.name)
|
|
87
|
-
true
|
|
88
|
-
end
|
|
89
|
-
|
|
90
73
|
def log(msg)
|
|
91
74
|
return if !@outgoing_queue || @outgoing_queue.closed?
|
|
92
75
|
|
|
@@ -8,11 +8,7 @@ module RubyLsp
|
|
|
8
8
|
module Rails
|
|
9
9
|
module FactoryBot
|
|
10
10
|
# The listener that is created when the user requests autocomplete at the relevant time.
|
|
11
|
-
#
|
|
12
|
-
# NOTE: autocompletion is only triggered on certain node types - almost exclusively call nodes
|
|
13
|
-
# and constants IIRC, so you cannot currently receive autocomplete options for symbols (eg.
|
|
14
|
-
# factory or trait names) :/
|
|
15
|
-
class Completion
|
|
11
|
+
class Completion # rubocop:disable Metrics/ClassLength
|
|
16
12
|
include RubyLsp::Requests::Support::Common
|
|
17
13
|
|
|
18
14
|
def initialize(response_builder, node_context, dispatcher, server_client)
|
|
@@ -24,10 +20,12 @@ module RubyLsp
|
|
|
24
20
|
end
|
|
25
21
|
|
|
26
22
|
def on_call_node_enter(node)
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
call_node = @node_context.call_node
|
|
24
|
+
return unless call_node
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
return unless FactoryBot::FACTORY_BOT_METHODS.include?(call_node.name)
|
|
27
|
+
|
|
28
|
+
process_arguments_pattern(node, call_node.arguments&.arguments)
|
|
31
29
|
rescue StandardError => e
|
|
32
30
|
$stderr.write(e, e.backtrace)
|
|
33
31
|
end
|
|
@@ -40,26 +38,50 @@ module RubyLsp
|
|
|
40
38
|
handle_factory(factory_name_node, node_string_value(factory_name_node))
|
|
41
39
|
|
|
42
40
|
in [Prism::SymbolNode => factory_name_node, *, Prism::SymbolNode => trait_node]
|
|
43
|
-
|
|
41
|
+
already_used_traits = gather_already_used_traits(arguments)
|
|
42
|
+
handle_trait(
|
|
43
|
+
node_string_value(factory_name_node), node, already_used_traits, node_string_value(trait_node),
|
|
44
|
+
)
|
|
44
45
|
|
|
45
46
|
in [Prism::SymbolNode => _factory_name_node, *, Prism::KeywordHashNode => _kw_node] |
|
|
46
47
|
[Prism::SymbolNode => _factory_name_node, *, Prism::HashNode => _kw_node] |
|
|
47
48
|
[Prism::SymbolNode => _factory_name_node, *, Prism::CallNode => _call_node]
|
|
48
49
|
|
|
49
|
-
attr_name = _call_node
|
|
50
|
-
|
|
50
|
+
attr_name = node_string_value(_call_node || _kw_node.elements.last.key)
|
|
51
|
+
already_used_attrs = gather_already_used_attrs(_kw_node)
|
|
52
|
+
handle_attribute(node_string_value(_factory_name_node), node, already_used_attrs, attr_name)
|
|
51
53
|
else
|
|
52
54
|
nil
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
def node_string_value(node)
|
|
57
|
-
node
|
|
59
|
+
case node
|
|
60
|
+
when Prism::CallNode
|
|
61
|
+
node.name.to_s
|
|
62
|
+
when Prism::SymbolNode
|
|
63
|
+
node.value.to_s
|
|
64
|
+
when nil
|
|
65
|
+
""
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def gather_already_used_attrs(kw_node)
|
|
70
|
+
attrs = Set.new
|
|
71
|
+
return attrs unless kw_node
|
|
72
|
+
|
|
73
|
+
kw_node.elements.each do |e|
|
|
74
|
+
attrs.add(node_string_value(e.key))
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
attrs
|
|
58
78
|
end
|
|
59
79
|
|
|
60
|
-
def handle_attribute(factory_name, node, value = "")
|
|
80
|
+
def handle_attribute(factory_name, node, already_used_attrs, value = "")
|
|
61
81
|
range = range_from_node(node)
|
|
62
82
|
make_request(:attributes, factory_name: factory_name, name: value)&.each do |attr|
|
|
83
|
+
next if already_used_attrs.member?(attr[:name].to_s)
|
|
84
|
+
|
|
63
85
|
label_details = Interface::CompletionItemLabelDetails.new(description: attr[:type])
|
|
64
86
|
|
|
65
87
|
@response_builder << serialise_attribute(attr[:name], label_details, attr[:owner], range)
|
|
@@ -77,24 +99,39 @@ module RubyLsp
|
|
|
77
99
|
)
|
|
78
100
|
end
|
|
79
101
|
|
|
80
|
-
def
|
|
102
|
+
def gather_already_used_traits(arguments)
|
|
103
|
+
trait_names = Set.new
|
|
104
|
+
# skip the first one because it's factory name
|
|
105
|
+
1.upto(arguments.length - 1) do |i|
|
|
106
|
+
arg = arguments[i]
|
|
107
|
+
next if arg.is_a?(Prism::IntegerNode)
|
|
108
|
+
break unless arg.is_a?(Prism::SymbolNode)
|
|
109
|
+
|
|
110
|
+
trait_names.add(arg.value.to_s)
|
|
111
|
+
end
|
|
112
|
+
trait_names
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def handle_trait(factory_name, node, already_used_traits, value = "")
|
|
81
116
|
make_request(:traits, factory_name: factory_name, name: value)&.each do |tr|
|
|
117
|
+
next if already_used_traits.member?(tr[:name].to_s)
|
|
118
|
+
|
|
82
119
|
label_details = Interface::CompletionItemLabelDetails.new(description: tr[:owner])
|
|
83
120
|
range = range_from_node(node)
|
|
84
121
|
name = tr[:name]
|
|
85
122
|
|
|
86
|
-
@response_builder << serialise_trait(name, range, label_details)
|
|
123
|
+
@response_builder << serialise_trait(name, range, label_details, tr[:owner])
|
|
87
124
|
end
|
|
88
125
|
end
|
|
89
126
|
|
|
90
|
-
def serialise_trait(name, range, label_details)
|
|
127
|
+
def serialise_trait(name, range, label_details, owner)
|
|
91
128
|
Interface::CompletionItem.new(
|
|
92
129
|
label: name,
|
|
93
130
|
filter_text: name,
|
|
94
131
|
label_details: label_details,
|
|
95
132
|
text_edit: Interface::TextEdit.new(range: range, new_text: name),
|
|
96
133
|
kind: Constant::CompletionItemKind::PROPERTY,
|
|
97
|
-
data: { owner_name: nil, guessed_type:
|
|
134
|
+
data: { owner_name: nil, guessed_type: owner },
|
|
98
135
|
)
|
|
99
136
|
end
|
|
100
137
|
|
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.3.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-02-
|
|
11
|
+
date: 2025-02-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: factory_bot
|