Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CodeLens support for minitest spec-style tests #1265

Merged
merged 1 commit into from
Jan 17, 2024

Conversation

snutij
Copy link
Contributor

@snutij snutij commented Dec 20, 2023

Motivation

Closes: #820

Add test code lenses to files wrote in minitest spec-style.

Implementation

Following what is already done by previous implementation:

  • handle describe & it keyword and get name and command test
  • to have nested group, like with nested classes:
    • increment the group_id for describe on on_call_node_enter
    • decrement the group_id for describe on on_call_node_leave

Automated Tests

I've added fixture & expectation file as other code lens cases.

Manual Tests

  • In file test/fixtures/minitest_spec_tests.rb
  • Lenses & testing tab should be populated
  • To be able to run test through lenses, these lines are required at the top of the file:
require "minitest/autorun"
class Foo
end
screenshots image image

@snutij snutij requested a review from a team as a code owner December 20, 2023 23:01
@snutij snutij requested review from andyw8 and st0012 December 20, 2023 23:01
@snutij snutij force-pushed the handle-codelens-for-minitest-spec-style branch from 438e6f1 to 0a4c9d1 Compare December 20, 2023 23:11
Copy link
Contributor

@andyw8 andyw8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far! Most of the team is off until early January, so there may a little delay before we can follow up.

@@ -47,6 +47,8 @@ class CodeLens < ExtensibleListener
)
ACCESS_MODIFIERS = T.let([:public, :private, :protected], T::Array[Symbol])
SUPPORTED_TEST_LIBRARIES = T.let(["minitest", "test-unit"], T::Array[String])
DESCRIBE_KEYWORD = T.let(:describe, Symbol)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need some more discussion, but we may want to start splitting up code_lens.rb into some separate responsibilities.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, this could be cleaner as file tends to increase and manage multiple scenarios. Let me know if there is a decision about it after team holidays 🎄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to keep as is for this PR at least. We talked about the possibility of moving the Gemfile code lenses into hover instead, which might be better than splitting code lens and would go well with #1279.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is acted, feel free to assign me, I like the idea, even more since feedback about too much noise in the Gemfile. 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! I owed you the issue I mentioned. Here it is in case you're interested in tackling it #1339.

lib/ruby_lsp/requests/code_lens.rb Outdated Show resolved Hide resolved
@snutij snutij force-pushed the handle-codelens-for-minitest-spec-style branch from b0769d9 to ab49cec Compare January 12, 2024 09:15
@andyw8
Copy link
Contributor

andyw8 commented Jan 12, 2024

Looks great! I tried testing it on https://github.com/Shopify/tapioca by adding ruby-lsp to the Gemfile and pointing it to this branch. For some reason, the code lenses aren't appearing, even why I copy the exact fixture file from this PR... would you mind taking a look to see what could be causing that?

@snutij
Copy link
Contributor Author

snutij commented Jan 14, 2024

Hi @andyw8, this is a good catch. Quite hard to use both VS Code extensions and ruby-lsp server in debug mode with a third repository. 😁

There are actually two issues with tapioca repository and ruby-lsp codelens.

  • First: Tapioca import rails in its dependencies, so it's early returned before any codelens creation.

  • Second: this is a mix between class syntax and describe syntax. This is creating a mismatch between group_id (which is incremented by the class, but without creating codelens) and testItem creation in the extensions. This can be fixed by changing the condition to if (res.data.group_id && Boolean(groupIdMap[res.data.group_id])). Tested locally, this is working outside tapioca repository. I can push this fix on the extension repository and fixture & expectation here if you think it's relevant.

I hope this message is as clear as this is in my mind 😄

@snutij snutij force-pushed the handle-codelens-for-minitest-spec-style branch from ab49cec to 1882b59 Compare January 15, 2024 17:53
@snutij snutij requested a review from andyw8 January 16, 2024 13:45
@vinistock
Copy link
Member

First: Tapioca import rails in its dependencies

This makes sense and it's a weakness of our current approach. If rails is in the Gemfile, but not used for ActiveSupport::TestCase, then we do the wrong thing. I don't think we should hold his PR back because of that, but it's something we need to re-think in the future.

Ideally, when we keep track of inheritance, we can check if the test inherits from ActiveSupport::TestCase and then use that to make the decision, which is a lot more precise than looking for the gem.

Second: this is a mix between class syntax and describe syntax

Does Minitest allow you to run a test class like the ones used in Tapioca? If so, I think both the describe and the class declarations ending in Spec should push new groups.

@snutij
Copy link
Contributor Author

snutij commented Jan 17, 2024

Does Minitest allow you to run a test class like the ones used in Tapioca? If so, I think both the describe and the class declarations ending in Spec should push new groups.

Giving this kind of code (without rails dependency and the fix in extension):

require "minitest/autorun"
class Foo
end

class FooSpec < Minitest::Spec
   describe Foo do
      it "test_one" do; end
   end
end

You'll be able to run it with minitest, each level. But commands generated are:

  • class: bundle exec ruby -Itest foo_spec.rb --name /FooSpec/
  • describe: bundle exec ruby -Itest foo_spec.rb --name /Foo/
  • it: bundle exec ruby -Itest foo_spec.rb --name /test_one/

The class level will run nothing, as this /FooSpec/ match no test, tests cases are generated based on the describe & it name, in this example we have a Foo#test_0001_foo.

@andyw8
Copy link
Contributor

andyw8 commented Jan 17, 2024

The section of the Minitest readme dealing with minitest/spec shows only describe at the top-level, so I'm wondering if this may be a mis-use of the library 🤔

@st0012
Copy link
Member

st0012 commented Jan 17, 2024

Looking at minitest's spec tests and ruby/spec, one of the biggest user of this pattern, I kinda feel Tapioca uses it in an unconventional way. So it may not be the best test subject for this feature.

@andyw8
Copy link
Contributor

andyw8 commented Jan 17, 2024

I'm experimenting with Tapioca to see what's involved in switching over, it doesn't seem there's much.

Copy link
Contributor

@andyw8 andyw8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do need to accomodate the mixed syntax, that can be separate, so let's go ahead with this.

@andyw8 andyw8 merged commit 2632c6d into Shopify:main Jan 17, 2024
16 checks passed
@paracycle
Copy link
Member

paracycle commented Feb 12, 2024

Looking at minitest's spec tests and ruby/spec, one of the biggest user of this pattern, I kinda feel Tapioca uses it in an unconventional way. So it may not be the best test subject for this feature.

I don't think this is accurate, since the documentation of describe explicitly describes the usage in Tapioca as a way to share single test superclass: https://github.com/minitest/minitest/blob/master/lib/minitest/spec.rb#L47-L69:

  ##
  # Describe a series of expectations for a given target +desc+.
  #
  # Defines a test class subclassing from either Minitest::Spec or
  # from the surrounding describe's class. The surrounding class may
  # subclass Minitest::Spec manually in order to easily share code:
  #
  #     class MySpec < Minitest::Spec
  #       # ... shared code ...
  #     end
  #
  #     class TestStuff < MySpec
  #       it "does stuff" do
  #         # shared code available here
  #       end
  #       describe "inner stuff" do
  #         it "still does stuff" do
  #           # ...and here
  #         end
  #       end
  #     end
  #
  # For more information on getting started with writing specs, see:

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.

CodeLens support for minitest spec-style tests
5 participants