Skip to content

Count only enabled capabilities in the enabledFeatures array test - #4209

Open
mtsmfm wants to merge 1 commit into
Shopify:mainfrom
mtsmfm:count-enabled-capabilities
Open

mtsmfm wants to merge 1 commit into
Shopify:mainfrom
mtsmfm:count-enabled-capabilities

Conversation

@mtsmfm

@mtsmfm mtsmfm commented Sep 17, 2026

Copy link
Copy Markdown

Motivation

Hi! Thank you for maintaining this great project.

LSP 3.18 is no longer marked as under development (microsoft/language-server-protocol@9b3b38b), so I'm updating the language_server-protocol gem to 3.18. Here is the work in progress: mtsmfm/language_server-protocol-ruby#151

While doing that, I'm considering taking the opportunity to fix a long-standing behavior that was my own mistake in the gem, and I'd like to hear your thoughts.

Currently, passing false explicitly to an optional interface property is treated the same as not passing it at all:

require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "language_server-protocol"
end

puts LanguageServer::Protocol::Interface::ServerCapabilities.new(definition_provider: false).to_json
# => {}

I'd like to change the result to {"definitionProvider":false}.

For capability flags such as definitionProvider, false and an omitted key mean the same thing, so I don't expect any runtime impact there. However, the specification does have optional boolean properties where an explicit false carries meaning, e.g. WorkDoneProgressReport.cancellable (omitted: leave the cancel button as is, false: disable it) and ExecutionSummary.success (omitted: unknown, false: failed). These have existed since 3.17, so the gem has been silently dropping those values. As a gem behavior, I believe an explicit false should be respected. None of the major dependents pass these properties through the gem's interfaces today, so nothing changes for them in practice.

I ran the test suites of the major dependents (ruby-lsp, rubocop, steep, standard) against the 3.18 branch, and test_initialize_enabled_features_with_array is the only failure.

I'm planning to release a pre-release version of 3.18 first just in case. Please let me know if you have any concerns.

Implementation

test_initialize_enabled_features_with_array asserts the exact number of keys in the serialized capabilities. With enabledFeatures given as an array, disabled features resolve to false (via Hash.new(false) in Server#run_initialize) and are passed straight to Interface::ServerCapabilities.new. With the 3.18 gem those false values are kept, so the key count grows from 5 to 10.

This PR makes the test count only the enabled capabilities, so it passes with both the current and the upcoming gem version.

Automated Tests

This PR only changes an existing test. I ran test/server_test.rb against both language_server-protocol 3.17.0.5 and the 3.18 branch, and it passes with both.

Manual Tests

No manual testing is needed since only a test is changed.

Note that even after the new SDK gem version is released, the current gemspec (~> 3.17.0) won't allow installing 3.18, so the runtime behavior of the Ruby LSP is unaffected until the dependency is bumped:

s.add_dependency("language_server-protocol", "~> 3.17.0")

@mtsmfm
mtsmfm requested a review from a team as a code owner September 17, 2026 03:13
When `enabledFeatures` is an array, absent features resolve to `false`
and are passed as-is to `Interface::ServerCapabilities.new`. The test
asserted the exact number of keys, relying on language_server-protocol
dropping `false` values from the serialized capabilities.

A future version of the language_server-protocol gem will keep `false`
for optional properties and only omit `nil`, which is valid per the
specification but changes the number of keys.

Count only the capabilities that are not `false` so the test passes
with either behavior.
@mtsmfm
mtsmfm force-pushed the count-enabled-capabilities branch from 4445f4c to 1267727 Compare September 17, 2026 03:17

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant