├── .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 | 
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)
--------------------------------------------------------------------------------