-
-
Save vmuriart/41cda77ec2a01b4c6f0048ac8d1cc522 to your computer and use it in GitHub Desktop.
Revisions
-
kaste revised this gist
Dec 5, 2013 . 2 changed files with 2 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,10 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,8 +6,8 @@ The plugin basically runs (and re-runs) some given tests, and annotates your fil You usually set up at least two keyboard shortcuts. { "keys": ["ctrl+t"], "command": "pytest_rerun"}, { "keys": ["ctrl+shift+t"], "command": "pytest_set_and_run"} With that given, hit `ctrl+shift+t` while you're in a test and the file will be run. `ctrl-t` will re-run the command at any time. If you `ctrl+shift+t` while not editing a test, **all** tests will be run. Again `ctrl+t` will re-run the last command. -
kaste revised this gist
Dec 5, 2013 . 1 changed file with 94 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,94 @@ import sublime import os standard_exec = __import__("exec") class ExecCommand(standard_exec.ExecCommand): def create_output_view(self, title): view = self.window.new_file() view.settings().set("no_history", True) # view.settings().set("gutter", False) view.settings().set("line_numbers", False) view.settings().set("syntax", "Packages/Python/Python.tmLanguage") view.set_name(title) view.set_scratch(True) return view def run(self, cmd = [], file_regex = "", line_regex = "", working_dir = "", encoding = "utf-8", env = {}, quiet = False, kill = False, title = "", # xeno.by # Catches "path" and "shell" **kwargs): if kill: if self.proc: self.proc.kill() self.proc = None self.append_data(None, "[Cancelled]") return # modified version of xeno.by: wannabes = filter(lambda v: v.name() == (title or " ".join(cmd)), self.window.views()) if len(wannabes): self.output_view = wannabes[0] self.output_view.show(self.output_view.size()) self.output_view.set_read_only(False) edit = self.output_view.begin_edit() self.output_view.erase(edit, sublime.Region(0, self.output_view.size())) self.output_view.sel().clear() self.output_view.sel().add(sublime.Region(self.output_view.size())) self.output_view.end_edit(edit) self.output_view.set_read_only(True) else: self.output_view = self.create_output_view(title or " ".join(cmd)) # Default the to the current files directory if no working directory was given if (working_dir == "" and self.window.active_view() and self.window.active_view().file_name()): working_dir = os.path.dirname(self.window.active_view().file_name()) self.output_view.settings().set("result_file_regex", file_regex) self.output_view.settings().set("result_line_regex", line_regex) self.output_view.settings().set("result_base_dir", working_dir) self.encoding = encoding self.quiet = quiet self.proc = None if not self.quiet: print "Running " + " ".join(cmd) sublime.status_message("Running " + " ".join(cmd)) merged_env = env.copy() if self.window.active_view(): user_env = self.window.active_view().settings().get('build_env') if user_env: merged_env.update(user_env) # Change to the working dir, rather than spawning the process with it, # so that emitted working dir relative path names make sense if working_dir != "": os.chdir(working_dir) err_type = OSError if os.name == "nt": err_type = WindowsError try: # Forward kwargs to AsyncProcess self.proc = standard_exec.AsyncProcess(cmd, merged_env, self, **kwargs) except err_type as e: self.append_data(None, str(e) + "\n") self.append_data(None, "[cmd: " + str(cmd) + "]\n") self.append_data(None, "[dir: " + str(os.getcwdu()) + "]\n") if "PATH" in merged_env: self.append_data(None, "[path: " + str(merged_env["PATH"]) + "]\n") else: self.append_data(None, "[path: " + str(os.environ["PATH"]) + "]\n") if not self.quiet: self.append_data(None, "[Finished]") -
kaste revised this gist
Dec 5, 2013 . 1 changed file with 44 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,44 @@ [ { "caption": "Preferences", "mnemonic": "n", "id": "preferences", "children": [ { "caption": "Package Settings", "mnemonic": "P", "id": "package-settings", "children": [ { "caption": "PyTest Runner", "children": [ // { // "command": "open_file", // "args": {"file": "${packages}/SublimeOnSaveBuild/README.md"}, // "caption": "README" // }, // { "caption": "-" }, { "command": "open_file", "args": {"file": "${packages}/PyTest/PyTest.sublime-settings"}, "caption": "Settings – Default" }, { "command": "open_file", "args": {"file": "${packages}/User/PyTest.sublime-settings"}, "caption": "Settings – User" }, { "command": "open_file_settings", "caption": "Settings – Syntax Specific – User" } ] } ] } ] } ] -
kaste revised this gist
Dec 5, 2013 . 1 changed file with 10 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,10 @@ [ {"caption": "PyTest: Set and Run", "command": "run_pytest", "args": {"rerun": false}}, {"caption": "PyTest: Overview", "command": "run_pytest", "args": {"options": "--tb=line --lf"}}, {"caption": "PyTest: Re-Run last test", "command": "run_pytest", "args": {"rerun": true}}, {"caption": "PyTest: Clear markers", "command": "pytest_set_markers"} ] -
kaste revised this gist
Dec 5, 2013 . 1 changed file with 255 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,255 @@ import sublime import sublime_plugin import sys import os import functools class TemporaryStorage(object): settings = {} markers = [] LastRun = TemporaryStorage() class Settings(object): def __init__(self, name): self.name = name @property def global_(self): return sublime.load_settings(self.name + '.sublime-settings') @property def user(self): try: return (sublime.active_window().active_view() .settings().get(self.name, {})) except: return {} def get(self, key, default=None): return self.user.get(key, self.global_.get(key, default)) Settings = Settings(__name__) class PytestSetAndRunCommand(sublime_plugin.WindowCommand): def run(self, options=None): """""" settings = self.get_settings() if options: settings['options'] = options else: settings['options'] = Settings.get('first') self.window.run_command("pytest_run", settings) LastRun.settings = settings def get_settings(self): rv = {} for key in ['pytest', 'working_dir', 'file_regex']: rv[key] = Settings.get(key) view = self.window.active_view() env = environment(view) try: filename = env['file_base'] if "_test" in filename or "test_" in filename: rv['target'] = env['file'] else: rv['target'] = Settings.get('tests_dir').format(**env) except KeyError: rv['target'] = Settings.get('tests_dir').format(**env) return rv class PytestRerunCommand(sublime_plugin.WindowCommand): def run(self, options=None): """""" settings = LastRun.settings if not settings: self.window.run_command("pytest_set_and_run") return if options: settings['options'] = options else: settings['options'] = Settings.get("then") self.window.run_command("pytest_run", settings) def environment(view): window = view.window() rv = {} filename = view.file_name() if filename: rv['file'] = filename rv['file_path'] = os.path.dirname(filename) rv['file_base'] = os.path.basename(filename) if window and window.folders(): rv['project_path'] = window.folders()[0] elif filename: rv['project_path'] = rv['file_path'] if 'project_path' in rv: rv['project_base'] = os.path.basename(rv['project_path']) return rv class PytestRunCommand(sublime_plugin.WindowCommand): def run(self, **kwargs): """ kwargs: pytest, options, target, working_dir, file_regex """ args = self.make_args(kwargs) sublime.status_message("Running %s" % args['cmd'][0]) save = Settings.get('save_before_test') if save is True: av = self.window.active_view() if av and av.is_dirty(): self.window.run_command("save") elif save == 'all': selfs.window.run_command("save_all") output_view = Settings.get('output') if output_view == 'panel': self.window.run_command("test_exec", args) if Settings.get('hide_panel_unless_failures'): self.window.run_command("hide_panel", {"panel": "output.exec"}) elif output_view == 'view': args['title'] = "Test Results" self.window.run_command("test_xexec", args) def make_args(self, kwargs): env = environment(self.window.active_view()) for key in ['pytest', 'target', 'working_dir']: kwargs[key] = kwargs[key].format(**env) command = "{pytest} {options} {target}".format(**kwargs) return { "file_regex": kwargs['file_regex'], "cmd": [command], "shell": True, "working_dir": kwargs['working_dir'], "quiet": True } def annotate_view(view, markers): filename = view.file_name() if not filename: return view.erase_regions('PyTestRunner') regions = [] for marker in markers: fn, line, h = marker if sys.platform == 'win32': # we have a cygwin like path e.g. "/c/users" instead of "c:\" fn = os.path.normpath(fn) fn = fn[2:] filename = os.path.splitdrive(filename)[1] if fn == filename: region = view.full_line(view.text_point(line-1, h)) regions.append(region) view.add_regions('PyTestRunner', regions, 'markup.deleted.diff', 'bookmark', sublime.DRAW_OUTLINED) class PytestSetMarkersCommand(sublime_plugin.WindowCommand): def run(self, markers=[]): LastRun.markers = markers # immediately paint the visible tabs window = sublime.active_window() views = [window.active_view_in_group(group) for group in range(window.num_groups())] # print markers for view in views: annotate_view(view, markers) class PytestMarkCurrentViewCommand(sublime_plugin.EventListener): def on_activated(self, view): markers = LastRun.markers # print markers annotate_view(view, markers) standard_exec = __import__('exec') import xexec class TestExecCommand(standard_exec.ExecCommand): def run(self, **kw): self.dots = "" return super(TestExecCommand, self).run(**kw) def finish(self, proc): super(TestExecCommand, self).finish(proc) sublime.status_message("Ran %s tests." % len(self.dots)) markers = self.output_view.find_all_results() # we can't serialize a tuple in the settings, so we listify each marker markers = [list(marker) for marker in markers] sublime.active_window().run_command("pytest_set_markers", {"markers": markers}) def append_dots(self, dot): self.dots += dot sublime.status_message("Testing " + self.dots[-400:]) if dot in 'FX': sublime.active_window().run_command( "show_panel", {"panel": "output.exec"}) def on_data(self, proc, data): # print ">>", proc, ">>", data if data in '.FxXs': sublime.set_timeout(functools.partial(self.append_dots, data), 0) super(TestExecCommand, self).on_data(proc, data) class TestXexecCommand(xexec.ExecCommand): def finish(self, proc): super(TestXexecCommand, self).finish(proc) markers = self.output_view.find_all_results() # we can't serialize a tuple in the settings, so we listify each marker markers = [list(marker) for marker in markers] sublime.active_window().run_command("pytest_set_markers", {"markers": markers}) -
kaste revised this gist
Dec 5, 2013 . 1 changed file with 38 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,38 @@ { // point to your py.test executable // usually use the one from your virtualenv // e.g. "~/venvs/{project_base}/scripts/py.test" "pytest": "py.test", "options": "--tb=long --lf", // the options for the first run (t.i.not a re-run) // I like to have a "--tb=line" here so I get an overview, probably I just // have a couple of failures pointing to the same line "first": "--tb=line", // the options to use on consecutive calls "then": "--tb=short", // usually your project_path (which is the first folder in your project // settings) "working_dir": "{project_path}", // where your tests are located // usually below your project_path so use a relative path // e.g. "tests" "foo/tests" "tests_dir": "", // false | true | 'all' // if true saves the current view only "save_before_test": true, // determines the kind of the output view. Either 'panel' or 'view' "output": "panel", "hide_panel_unless_failures": true, "file_regex": "^(.*):([0-9]+):" } -
kaste created this gist
Dec 5, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,31 @@ # py.test plugin for the sublime text editor The plugin basically runs (and re-runs) some given tests, and annotates your files using the tracebacks. # common workflow You usually set up at least two keyboard shortcuts. { "keys": ["ctrl+t"], "command": "run_pytest", "args": {"rerun": true}}, { "keys": ["ctrl+shift+t"], "command": "run_pytest", "args": {"rerun": false}} With that given, hit `ctrl+shift+t` while you're in a test and the file will be run. `ctrl-t` will re-run the command at any time. If you `ctrl+shift+t` while not editing a test, **all** tests will be run. Again `ctrl+t` will re-run the last command. By default, the output panel will only show up if there are actually any failures. The traceback will be annotated in your source files. # install Manually download/clone from github and put it in your Packages directory. At least **look** at the global settings. You usually have to edit the `pytest` setting to point at your py.test from your current virtualenv (the default is to run your global py.test which is usually *not* what you want). E.g. "pytest": "~/venvs/{project_base}/bin/py.test" OR: "pytest": ".env\\Scripts\\py.test" OR even: "pytest": "venv/path/to/python -m pytest" The plugin will expand {project_path}, {project_base}, {file}, {file_path} and {file_base}.