Skip to content

Instantly share code, notes, and snippets.

@IPWright83
Created April 24, 2024 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IPWright83/e2ebf4fa80eae240f55312027373ee0d to your computer and use it in GitHub Desktop.
Save IPWright83/e2ebf4fa80eae240f55312027373ee0d to your computer and use it in GitHub Desktop.
Sublime Text JavaScript Test Explorer Plugin

This is a basic unpacked Sublime Text Plugin designed provide a Test Explorer view within a JavaScript file. It looks for describe and it blocks to put together a menu that you can then explore with the standard navigation controls in a Sublime menu. It should therefore work with Jest/Jasmine etc.

image

The file needs to be in included within the Packages\User directory within Sublime. You can get to this by going to Settings > Browser Packages. Once included you'll need to setup a key binding like so:

{ "keys": ["command+t"], "command": "test_explorer_menu" }

I designed it for my own personal use but anyone is free to use it, just don't redistribute without permission.

import sublime
import sublime_plugin
import re
class TestExplorerMenuCommand(sublime_plugin.TextCommand):
def run(self, edit):
# Parse the current view to extract out describe and it blocks
test_names = self.parse_test_file()
# Generate test menu sub-tree
test_menu = self.generate_test_menu(test_names)
# Display the test menu
self.window().show_quick_panel(test_menu, self.on_done)
def filter_empty(value):
if (value):
return True
return False
def parse_test_file(self):
describe_rgx = re.compile(r'describe\s*\(\s*(?:`([^`]+)`|["\']([^"\']+)["\'])\s*,?\s*(?:async\s+)?\(\s*\)\s*=>\s*{')
it_rgx = re.compile(r'it\s*\(\s*(?:`([^`]+)`|["\']([^"\']+)["\'])\s*,?\s*(?:async\s+)?\(\s*\)\s*=>\s*{')
content = self.view.substr(sublime.Region(0, self.view.size()))
describe_blocks = describe_rgx.findall(content)
it_blocks = it_rgx.findall(content)
results = []
## Find line numbers
for block in describe_blocks:
description = next((item for item in block if item), None) # Get the first non-empty string
if description:
region = self.view.find(r'\b{}\b'.format(re.escape(description)), 0)
if region:
line_number, _ = self.view.rowcol(region.begin())
results.append((description, line_number + 1, "describe"))
## Find line numbers
for block in it_blocks:
it = next((item for item in block if item), None)
if it:
region = self.view.find(r'\b{}\b'.format(re.escape(it)), 0)
if region:
line_number, _ = self.view.rowcol(region.begin())
results.append((it, line_number + 1, "it"))
return results
def generate_test_menu(self, test_names):
test_menu = []
self.sorted_names = sorted(test_names, key=lambda x:x[1])
max_description_width = max(len(block[0]) for block in self.sorted_names) + 4
for test in self.sorted_names:
if test[2] == "describe":
name = test[0]
item = "describe: {}".format(test[0])
test_menu.append(item)
else:
name = test[0]
item = " it: {}".format(test[0])
test_menu.append(item)
return test_menu
def on_done(self, index):
if index != -1:
item = self.sorted_names[index]
if item != None:
line_number = item[1];
self.view.run_command("goto_line", {"line": line_number})
pass
def window(self):
return self.view.window()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment