├── .gitignore ├── messages.txt ├── RubyTest.last-run ├── ruby_tests.png ├── Widget.sublime-settings ├── repositories.json ├── RubyTest.sublime-settings ├── messages └── install.txt ├── package-metadata.json ├── Main.sublime-menu ├── Context.sublime-menu ├── Default.sublime-commands ├── Default (Linux).sublime-keymap ├── Default (Windows).sublime-keymap ├── Default (OSX).sublime-keymap ├── README.md ├── TestConsole.tmTheme ├── TestConsole.tmLanguage └── run_ruby_test.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.cache 2 | *.pyc -------------------------------------------------------------------------------- /messages.txt: -------------------------------------------------------------------------------- 1 | { 2 | "install": "messages/install.txt" 3 | } -------------------------------------------------------------------------------- /RubyTest.last-run: -------------------------------------------------------------------------------- 1 | { 2 | "last_test_run": "", 3 | "last_test_file": "" 4 | } -------------------------------------------------------------------------------- /ruby_tests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/sublime-text-2-ruby-tests/master/ruby_tests.png -------------------------------------------------------------------------------- /Widget.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "syntax": "Packages/RubyTest/TestConsole.tmLanguage", 3 | "color_scheme": "Packages/RubyTest/TestConsole.tmTheme" 4 | } 5 | -------------------------------------------------------------------------------- /repositories.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "1.0.0", 3 | "repositories": [ 4 | "https://github.com/maltize/sublime-text-2-ruby-tests" 5 | ], 6 | "package_name_map": { 7 | "sublime-text-2-ruby-tests": "RubyTest" 8 | } 9 | } -------------------------------------------------------------------------------- /RubyTest.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "ruby_unit_exec": "ruby -Itest", 3 | "ruby_cucumber_exec": "cucumber --no-color", 4 | "ruby_rspec_exec": "rspec", 5 | 6 | "ruby_unit_folder": "test", 7 | "ruby_cucumber_folder": "features", 8 | "ruby_rspec_folder": "spec" 9 | } 10 | -------------------------------------------------------------------------------- /messages/install.txt: -------------------------------------------------------------------------------- 1 | Congratulation! You have installed awesome plugin for running ruby tests! 2 | Documentation can be found on https://github.com/maltize/sublime-text-2-ruby-tests. 3 | Also feel free to report issues/suggestions there. 4 | 5 | Have fun ! 6 | Maciej Gajek & Grzegorz Smajdor -------------------------------------------------------------------------------- /package-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "https://github.com/maltize/sublime-text-2-ruby-tests", 3 | "version": "1.0.0", 4 | "description": "Sublime Text 2 plugin for running ruby tests! (Unit, RSpec, Cucumber)", 5 | "author": "Maciej Gajek & Grzegorz Smajdor", 6 | "homepage": "https://github.com/maltize/sublime-text-2-ruby-tests" 7 | } -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "tools", 4 | "children": 5 | [ 6 | { 7 | "caption": "RubyTest", 8 | "children": 9 | [ 10 | { "caption": "Run single test / scenario / spec", "command": "run_single_ruby_test" }, 11 | { "caption": "Run all tests / feature / full spec", "command": "run_all_ruby_test" }, 12 | { "caption": "Run last tests / feature / spec", "command": "run_last_ruby_test" }, 13 | { "caption": "-" }, 14 | { "caption": "Show test panel", "command": "show_test_panel" }, 15 | { "caption": "-" }, 16 | { "caption": "Verify ruby syntax", "command": "verify_ruby_file" }, 17 | { "caption": "Switch Between Code and Test", "command": "switch_between_code_and_test" }, 18 | { "caption": "-" } 19 | ] 20 | } 21 | ] 22 | } 23 | ] -------------------------------------------------------------------------------- /Context.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { "caption": "-" }, 3 | { 4 | "caption": "RubyTest", 5 | "children": 6 | [ 7 | { "caption": "Run single test / scenario / spec", "command": "run_single_ruby_test" }, 8 | { "caption": "Run all tests / feature / full spec", "command": "run_all_ruby_test" }, 9 | { "caption": "Run last test(s) / feature / spec", "command": "run_last_ruby_test" }, 10 | { "caption": "-" }, 11 | { "caption": "Show test panel", "command": "show_test_panel" }, 12 | { "caption": "-" }, 13 | { "caption": "Verify ruby syntax", "command": "verify_ruby_file" }, 14 | { "caption": "-" }, 15 | { "caption": "Refactoring", "children": [ 16 | { "caption": "Extract Local Variable", "command": "ruby_extract_variable" } 17 | ]}, 18 | { "caption": "-" }, 19 | { "caption": "Switch Between Code and Test", "command": "switch_between_code_and_test" } 20 | ] 21 | } 22 | ] -------------------------------------------------------------------------------- /Default.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { "caption": "RubyTest: Run Single Test", "command": "run_single_ruby_test" }, 3 | { "caption": "RubyTest: Run All Ruby Tests", "command": "run_all_ruby_test" }, 4 | { "caption": "RubyTest: Run Last Ruby Test", "command": "run_last_ruby_test" }, 5 | { "caption": "RubyTest: Show Test Panel", "command": "show_test_panel" }, 6 | { "caption": "RubyTest: Verify Syntax", "command": "verify_ruby_file" }, 7 | { "caption": "RubyTest: Generate Rails Migration", "command": "ruby_rails_generate", "args" : {"type" : "migration"} }, 8 | { "caption": "RubyTest: Generate Rails Model", "command": "ruby_rails_generate", "args" : {"type" : "model"} }, 9 | { "caption": "RubyTest: Generate Rails Controller", "command": "ruby_rails_generate", "args" : {"type" : "controller"} }, 10 | { "caption": "RubyTest: Extract Local Variable", "command": "ruby_extract_variable" }, 11 | { "caption": "RubyTest: Switch between code and test", "command": "switch_between_code_and_test" } 12 | ] -------------------------------------------------------------------------------- /Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+shift+r"], "command": "run_single_ruby_test" }, // single test 3 | { "keys": ["ctrl+shift+t"], "command": "run_all_ruby_test" }, // test file 4 | { "keys": ["ctrl+shift+e"], "command": "run_last_ruby_test" }, // test file 5 | 6 | { "keys": ["ctrl+shift+x"], "command": "show_test_panel" }, // show test panel 7 | 8 | { "keys": ["alt+shift+v"], "command": "verify_ruby_file" }, // verify ruby syntax 9 | { "keys": ["ctrl+period"], "command": "switch_between_code_and_test", "args": {"split_view": false}, "context" : [ 10 | { "key": "selector", "operator": "equal", "operand": "source.ruby", "match_all": true } 11 | ]}, // switch between code and test in single view 12 | { "keys": ["ctrl+period"], "command": "switch_between_code_and_test", "args": {"split_view": true}, "context" : [ 13 | { "key": "selector", "operator": "equal", "operand": "source.ruby", "match_all": true } 14 | ]} // switch between code and test in split view 15 | ] -------------------------------------------------------------------------------- /Default (Windows).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+shift+r"], "command": "run_single_ruby_test" }, // single test 3 | { "keys": ["ctrl+shift+t"], "command": "run_all_ruby_test" }, // test file 4 | { "keys": ["ctrl+shift+e"], "command": "run_last_ruby_test" }, // test file 5 | 6 | { "keys": ["ctrl+shift+x"], "command": "show_test_panel" }, // show test panel 7 | 8 | { "keys": ["alt+shift+v"], "command": "verify_ruby_file" }, // verify ruby syntax 9 | { "keys": ["ctrl+period"], "command": "switch_between_code_and_test", "args": {"split_view": false}, "context" : [ 10 | { "key": "selector", "operator": "equal", "operand": "source.ruby", "match_all": true } 11 | ]}, // switch between code and test in single view 12 | { "keys": ["ctrl+period"], "command": "switch_between_code_and_test", "args": {"split_view": true}, "context" : [ 13 | { "key": "selector", "operator": "equal", "operand": "source.ruby", "match_all": true } 14 | ]} // switch between code and test in split view 15 | ] -------------------------------------------------------------------------------- /Default (OSX).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["super+shift+r"], "command": "run_single_ruby_test" }, // single test 3 | { "keys": ["super+shift+t"], "command": "run_all_ruby_test" }, // test file 4 | { "keys": ["super+shift+e"], "command": "run_last_ruby_test" }, // test file 5 | 6 | { "keys": ["super+shift+x"], "command": "show_test_panel" }, // show test panel 7 | 8 | { "keys": ["alt+shift+v"], "command": "verify_ruby_file" }, // verify ruby syntax 9 | { "keys": ["super+period"], "command": "switch_between_code_and_test", "args": {"split_view": false}, "context" : [ 10 | { "key": "selector", "operator": "equal", "operand": "source.ruby", "match_all": true } 11 | ]}, // switch between code and test in single mode 12 | { "keys": ["super+ctrl+period"], "command": "switch_between_code_and_test", "args": {"split_view": true}, "context" : [ 13 | { "key": "selector", "operator": "equal", "operand": "source.ruby", "match_all": true } 14 | ]} // switch between code and test in split view 15 | ] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sublime Text 2 Ruby Tests 2 | ========================= 3 | 4 | Overview 5 | -------- 6 | Running: 7 | 8 | - ruby unit tests (all tests from file / single test) 9 | - cucumber tests (feature / scenario) 10 | - rspec (full spec, single spec) 11 | 12 | Maciej Gajek & Grzegorz Smajdor (https://github.com/gs) project. 13 | 14 | Installation 15 | ------------ 16 | 17 | Go to your Sublime Text 2 `Packages` directory 18 | 19 | - OS X: ~/Library/Application Support/Sublime Text 2/Packages/ 20 | - Windows: %APPDATA%/Sublime Text 2/Packages/ 21 | - Linux: ~/.Sublime Text 2/Packages/ 22 | 23 | and clone the repository using the command below: 24 | 25 | git clone https://github.com/maltize/sublime-text-2-ruby-tests.git RubyTest 26 | 27 | Settings 28 | -------- 29 | 30 | You can specify different binary for each type of test to use. 31 | 32 | Make a copy of RubyTest.sublime-settings to Packages/User and make your changes. 33 | 34 | Usage 35 | ----- 36 | 37 | - Run single ruby test: Command-Shift-R 38 | - Run all ruby tests from current file: Command-Shift-T 39 | - Run last ruby test(s): Command-Shift-E 40 | - Show test panel: Command-Shift-X 41 | - Check RB, ERB file syntax: Alt-Shift-V 42 | - Switching between code and test: 43 | - Single View: Command-. 44 | - Split View: Command+Ctrl+. 45 | Keys: 46 | 'Command' (OSX) 47 | 'Ctrl' (Linux / Windows) 48 | 49 | ![ruby_tests screenshot](https://github.com/maltize/sublime-text-2-ruby-tests/raw/master/ruby_tests.png) 50 | 51 | Note 52 | ---- 53 | If you having trouble running tests try to run Sublime Text 2 from command line. 54 | 55 | This is a work in progress so expect bugs. 56 | Please open an issue at https://github.com/maltize/sublime-text-2-ruby-tests if you discover a problem or would like to see a feature/change implemented. -------------------------------------------------------------------------------- /TestConsole.tmTheme: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | TestConsoleTheme 7 | settings 8 | 9 | 10 | settings 11 | 12 | background 13 | #000000 14 | caret 15 | #A7A7A7 16 | foreground 17 | #F8F8F8 18 | invisibles 19 | #CAE2FB3D 20 | lineHighlight 21 | #FFFFFF0D 22 | selection 23 | #DDF0FF33 24 | 25 | 26 | 27 | name 28 | Test 29 | scope 30 | test.pass 31 | settings 32 | 33 | foreground 34 | #00FF00 35 | 36 | 37 | 38 | name 39 | Test 40 | scope 41 | test.error 42 | settings 43 | 44 | foreground 45 | #FF0000 46 | 47 | 48 | 49 | name 50 | Test 51 | scope 52 | test.fail 53 | settings 54 | 55 | foreground 56 | #FF1493 57 | 58 | 59 | 60 | uuid 61 | 72174d10-bb12-11e0-962b-112233445577 62 | 63 | 64 | -------------------------------------------------------------------------------- /TestConsole.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleUUID 6 | 72174d10-bb12-11e0-962b-112233445566 7 | name 8 | TestConsole 9 | patterns 10 | 11 | 12 | comment 13 | test pass 14 | match 15 | (^|\s)\d+ (tests|assertions|examples?) 16 | name 17 | test.pass 18 | 19 | 20 | comment 21 | test error 22 | match 23 | (\d+ errors)|(\d+\) Error:) 24 | name 25 | test.error 26 | 27 | 28 | comment 29 | test fail 30 | match 31 | (\d+ failures?)|(\d+\) Failure:) 32 | name 33 | test.fail 34 | 35 | 36 | comment 37 | dots painting 38 | begin 39 | Started 40 | patterns 41 | 42 | 43 | match 44 | \.+ 45 | name 46 | test.pass 47 | 48 | 49 | match 50 | E+ 51 | name 52 | test.error 53 | 54 | 55 | match 56 | F+ 57 | name 58 | test.fail 59 | 60 | 61 | end 62 | Finished 63 | 64 | 65 | comment 66 | color syntax response 67 | match 68 | Syntax OK 69 | name 70 | test.pass 71 | 72 | 73 | scopeName 74 | tests.ruby 75 | uuid 76 | 72174d10-bb12-11e0-962b-112233445566 77 | 78 | 79 | -------------------------------------------------------------------------------- /run_ruby_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import thread 4 | import subprocess 5 | import functools 6 | import time 7 | import sublime 8 | import sublime_plugin 9 | 10 | class AsyncProcess(object): 11 | def __init__(self, cmd, listener): 12 | self.cmd = cmd 13 | self.listener = listener 14 | print "DEBUG_EXEC: " + self.cmd 15 | self.proc = subprocess.Popen([self.cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 16 | if self.proc.stdout: 17 | thread.start_new_thread(self.read_stdout, ()) 18 | if self.proc.stderr: 19 | thread.start_new_thread(self.read_stderr, ()) 20 | 21 | def read_stdout(self): 22 | while True: 23 | data = os.read(self.proc.stdout.fileno(), 2**15) 24 | if data != "": 25 | sublime.set_timeout(functools.partial(self.listener.append_data, self.proc, data), 0) 26 | else: 27 | self.proc.stdout.close() 28 | self.listener.is_running = False 29 | break 30 | 31 | def read_stderr(self): 32 | while True: 33 | data = os.read(self.proc.stderr.fileno(), 2**15) 34 | if data != "": 35 | sublime.set_timeout(functools.partial(self.listener.append_data, self.proc, data), 0) 36 | else: 37 | self.proc.stderr.close() 38 | self.listener.is_running = False 39 | break 40 | 41 | class StatusProcess(object): 42 | def __init__(self, msg, listener): 43 | self.msg = msg 44 | self.listener = listener 45 | thread.start_new_thread(self.run_thread, ()) 46 | 47 | def run_thread(self): 48 | progress = "" 49 | while True: 50 | if self.listener.is_running: 51 | if len(progress) >= 10: 52 | progress = "" 53 | progress += "." 54 | sublime.set_timeout(functools.partial(self.listener.update_status, self.msg, progress), 0) 55 | time.sleep(1) 56 | else: 57 | break 58 | 59 | def wrap_in_cd(path, command): 60 | return "cd '" + path + "' && " + command 61 | 62 | class BaseRubyTask(sublime_plugin.TextCommand): 63 | def load_config(self): 64 | s = sublime.load_settings("RubyTest.sublime-settings") 65 | global RUBY_UNIT; RUBY_UNIT = s.get("ruby_unit_exec") 66 | global CUCUMBER_UNIT; CUCUMBER_UNIT = s.get("ruby_cucumber_exec") 67 | global RSPEC_UNIT; RSPEC_UNIT = s.get("ruby_rspec_exec") 68 | global RUBY_UNIT_FOLDER; RUBY_UNIT_FOLDER = s.get("ruby_unit_folder") 69 | global CUCUMBER_UNIT_FOLDER; CUCUMBER_UNIT_FOLDER = s.get("ruby_cucumber_folder") 70 | global RSPEC_UNIT_FOLDER; RSPEC_UNIT_FOLDER = s.get("ruby_rspec_folder") 71 | 72 | def save_test_run(self, ex, file_name): 73 | s = sublime.load_settings("RubyTest.last-run") 74 | s.set("last_test_run", ex) 75 | s.set("last_test_file", file_name) 76 | 77 | sublime.save_settings("RubyTest.last-run") 78 | 79 | def window(self): 80 | return self.view.window() 81 | 82 | def show_tests_panel(self): 83 | if not hasattr(self, 'output_view'): 84 | self.output_view = self.window().get_output_panel("tests") 85 | self.clear_test_view() 86 | self.window().run_command("show_panel", {"panel": "output.tests"}) 87 | 88 | def clear_test_view(self): 89 | self.output_view.set_read_only(False) 90 | edit = self.output_view.begin_edit() 91 | self.output_view.erase(edit, sublime.Region(0, self.output_view.size())) 92 | self.output_view.end_edit(edit) 93 | self.output_view.set_read_only(True) 94 | 95 | def append_data(self, proc, data): 96 | str = data.decode("utf-8") 97 | str = str.replace('\r\n', '\n').replace('\r', '\n') 98 | 99 | selection_was_at_end = (len(self.output_view.sel()) == 1 100 | and self.output_view.sel()[0] 101 | == sublime.Region(self.output_view.size())) 102 | self.output_view.set_read_only(False) 103 | edit = self.output_view.begin_edit() 104 | self.output_view.insert(edit, self.output_view.size(), str) 105 | if selection_was_at_end: 106 | self.output_view.show(self.output_view.size()) 107 | self.output_view.end_edit(edit) 108 | self.output_view.set_read_only(True) 109 | 110 | def start_async(self, caption, executable): 111 | self.is_running = True 112 | self.proc = AsyncProcess(executable, self) 113 | StatusProcess(caption, self) 114 | 115 | def update_status(self, msg, progress): 116 | sublime.status_message(msg + " " + progress) 117 | 118 | class BaseFile(object): 119 | def __init__(self, file_name): self.folder_name, self.file_name = os.path.split(file_name) 120 | def verify_syntax_command(self): return None 121 | def possible_alternate_files(self): return [] 122 | def run_all_tests_command(self): return None 123 | def run_from_project_root(self, partition_folder, command, options = ""): 124 | folder_name, test_folder, file_name = os.path.join(self.folder_name, self.file_name).partition(partition_folder) 125 | return wrap_in_cd(folder_name, command + " " + test_folder + file_name + options) 126 | def get_current_line_number(self, view): 127 | char_under_cursor = view.sel()[0].a 128 | return view.rowcol(char_under_cursor)[0] + 1 129 | def features(self): return [] 130 | 131 | class AnonymousFile(BaseFile): 132 | def __init__(self): 133 | True 134 | 135 | class RubyFile(BaseFile): 136 | def verify_syntax_command(self): return wrap_in_cd(self.folder_name, "ruby -c " + self.file_name) 137 | def possible_alternate_files(self): return [self.file_name.replace(".rb", "_spec.rb"), self.file_name.replace(".rb", "_test.rb"), self.file_name.replace(".rb", ".feature")] 138 | def features(self): return ["verify_syntax", "switch_to_test", "rails_generate", "extract_variable"] 139 | 140 | class UnitFile(RubyFile): 141 | def possible_alternate_files(self): return [self.file_name.replace("_test.rb", ".rb")] 142 | def run_all_tests_command(self): return self.run_from_project_root(RUBY_UNIT_FOLDER, RUBY_UNIT) 143 | def run_single_test_command(self, view): 144 | region = view.sel()[0] 145 | line_region = view.line(region) 146 | text_string = view.substr(sublime.Region(region.begin() - 2000, line_region.end())) 147 | text_string = text_string.replace("\n", "\\N") 148 | text_string = text_string[::-1] 149 | match_obj = re.search('\s?([a-zA-Z_\d]+tset)\s+fed', text_string) # 1st search for 'def test_name' 150 | if not match_obj: 151 | match_obj = re.search('\s?([\"\'][a-zA-Z_\s\d]+[\"\']\s+tset)', text_string) # 2nd search for 'test "name"' 152 | if not match_obj: 153 | sublime.error_message("No test name!") 154 | return 155 | test_name = match_obj.group(1)[::-1] 156 | test_name = test_name.replace("\"", "").replace(" ", "_") # if test name in 2nd format 157 | return self.run_from_project_root(RUBY_UNIT_FOLDER, RUBY_UNIT, " -n " + test_name) 158 | def features(self): return super(BaseRubyTask.UnitFile, self).features() + ["run_test"] 159 | 160 | class CucumberFile(BaseFile): 161 | def possible_alternate_files(self): return [self.file_name.replace(".feature", ".rb")] 162 | def run_all_tests_command(self): return self.run_from_project_root(CUCUMBER_UNIT_FOLDER, CUCUMBER_UNIT) 163 | def run_single_test_command(self, view): return self.run_from_project_root(CUCUMBER_UNIT_FOLDER, CUCUMBER_UNIT, " -l " + str(self.get_current_line_number(view))) 164 | def features(self): return ["run_test"] 165 | 166 | class RSpecFile(RubyFile): 167 | def possible_alternate_files(self): return [self.file_name.replace("_spec.rb", ".rb")] 168 | def run_all_tests_command(self): return self.run_from_project_root(RSPEC_UNIT_FOLDER, RSPEC_UNIT) 169 | def run_single_test_command(self, view): return self.run_from_project_root(RSPEC_UNIT_FOLDER, RSPEC_UNIT, " -l " + str(self.get_current_line_number(view))) 170 | def features(self): return super(BaseRubyTask.RSpecFile, self).features() + ["run_test"] 171 | 172 | class ErbFile(BaseFile): 173 | def verify_syntax_command(self): return wrap_in_cd(self.folder_name, "erb -xT - " + self.file_name + " | ruby -c") 174 | def can_verify_syntax(self): return True 175 | def features(self): return ["verify_syntax"] 176 | 177 | def file_type(self, file_name = None): 178 | file_name = file_name or self.view.file_name() 179 | if not file_name: return BaseRubyTask.AnonymousFile() 180 | if re.search('\w+\_test.rb', file_name): 181 | return BaseRubyTask.UnitFile(file_name) 182 | elif re.search('\w+\_spec.rb', file_name): 183 | return BaseRubyTask.RSpecFile(file_name) 184 | elif re.search('\w+\.feature', file_name): 185 | return BaseRubyTask.CucumberFile(file_name) 186 | elif re.search('\w+\.rb', file_name): 187 | return BaseRubyTask.RubyFile(file_name) 188 | elif re.search('\w+\.erb', file_name): 189 | return BaseRubyTask.ErbFile(file_name) 190 | else: 191 | return BaseRubyTask.BaseFile(file_name) 192 | 193 | class RunSingleRubyTest(BaseRubyTask): 194 | def is_enabled(self): return 'run_test' in self.file_type().features() 195 | def run(self, args): 196 | self.load_config() 197 | file = self.file_type() 198 | command = file.run_single_test_command(self.view) 199 | if command: 200 | self.save_test_run(command, file.file_name) 201 | self.show_tests_panel() 202 | self.is_running = True 203 | self.proc = AsyncProcess(command, self) 204 | StatusProcess("Starting tests from file " + file.file_name, self) 205 | 206 | class RunAllRubyTest(BaseRubyTask): 207 | def is_enabled(self): return 'run_test' in self.file_type().features() 208 | def run(self, args): 209 | self.load_config() 210 | view = self.view 211 | folder_name, file_name = os.path.split(view.file_name()) 212 | file = self.file_type(view.file_name()) 213 | command = file.run_all_tests_command() 214 | if command: 215 | self.show_tests_panel() 216 | self.save_test_run(command, file_name) 217 | self.is_running = True 218 | self.proc = AsyncProcess(command, self) 219 | StatusProcess("Starting tests from file " + file.file_name, self) 220 | else: 221 | sublime.error_message("Only *_test.rb, *_spec.rb, *.feature files supported!") 222 | 223 | 224 | class RunLastRubyTest(BaseRubyTask): 225 | def load_last_run(self): 226 | s = sublime.load_settings("RubyTest.last-run") 227 | global LAST_TEST_RUN; LAST_TEST_RUN = s.get("last_test_run") 228 | global LAST_TEST_FILE; LAST_TEST_FILE = s.get("last_test_file") 229 | 230 | def run(self, args): 231 | self.load_last_run() 232 | self.show_tests_panel() 233 | self.is_running = True 234 | self.proc = AsyncProcess(LAST_TEST_RUN, self) 235 | StatusProcess("Starting tests from file " + LAST_TEST_FILE, self) 236 | 237 | class ShowTestPanel(BaseRubyTask): 238 | def run(self, args): 239 | self.window().run_command("show_panel", {"panel": "output.tests"}) 240 | 241 | class VerifyRubyFile(BaseRubyTask): 242 | def is_enabled(self): return 'verify_syntax' in self.file_type().features() 243 | def run(self, args): 244 | file = self.file_type() 245 | command = file.verify_syntax_command() 246 | if command: 247 | self.show_tests_panel() 248 | self.start_async("Checking syntax of : " + file.file_name, command) 249 | else: 250 | sublime.error_message("Only .rb or .erb files supported!") 251 | 252 | class SwitchBetweenCodeAndTest(BaseRubyTask): 253 | def is_enabled(self): return 'switch_to_test' in self.file_type().features() 254 | def run(self, args, split_view): 255 | possible_alternates = self.file_type().possible_alternate_files() 256 | alternates = self.project_files(lambda file: file in possible_alternates) 257 | if alternates: 258 | if split_view: 259 | self.window().run_command('set_layout', { 260 | "cols": [0.0, 0.5, 1.0], 261 | "rows": [0.0, 1.0], 262 | "cells": [[0, 0, 1, 1], [1, 0, 2, 1]] 263 | }) 264 | self.window().focus_group(1) 265 | self.window().open_file(alternates.pop()) 266 | else: 267 | sublime.error_message("could not find " + str(possible_alternates)) 268 | 269 | def walk(self, directory, ignored_directories = []): 270 | ignored_directories = ['.git', 'vendor'] # Move this into config 271 | for dir, dirnames, files in os.walk(directory): 272 | dirnames[:] = [dirname for dirname in dirnames if dirname not in ignored_directories] 273 | yield dir, dirnames, files 274 | 275 | def project_files(self, file_matcher): 276 | directories = self.window().folders() 277 | return [os.path.join(dirname, file) for directory in directories for dirname, _, files in self.walk(directory) for file in filter(file_matcher, files)] 278 | 279 | class RubyRunShell(BaseRubyTask): 280 | def run(self, args, command, caption = "Running shell command"): 281 | self.show_tests_panel() 282 | self.start_async(caption, wrap_in_cd(self.window().folders()[0], command)) 283 | 284 | class RubyRailsGenerate(BaseRubyTask): 285 | def is_enabled(self): return 'rails_generate' in self.file_type().features() 286 | 287 | def run(self, args, type = "migration"): 288 | self.window().show_input_panel("rails generate", type + " ", lambda s: self.generate(s), None, None) 289 | 290 | def generate(self, argument): 291 | command = "rails generate " + argument 292 | self.view.run_command("ruby_run_shell", {"command": command, "caption": "Generating" + argument}) 293 | 294 | class RubyExtractVariable(BaseRubyTask): 295 | def is_enabled(self): return 'extract_variable' in self.file_type().features() 296 | def run(self, args): 297 | for selection in self.view.sel(): 298 | self.window().show_input_panel("Variable Name: ", '', lambda name: self.generate(selection, name), None, None) 299 | 300 | def generate(self, selection, name): 301 | extracted = self.view.substr(selection) 302 | line = self.view.line(selection) 303 | white_space = re.match("\s*", self.view.substr(line)).group() 304 | edit = self.view.begin_edit() 305 | try: 306 | self.view.replace(edit, selection, name) 307 | self.view.insert(edit, line.begin(), white_space + name + " = " + extracted + "\n") 308 | finally: 309 | self.view.end_edit(edit) --------------------------------------------------------------------------------