Skip to content

Commit f0bf728

Browse files
ehussJayflux
authored andcommitted
Add Travis and AppVeyor. (#246)
Includes changes: - Change Clippy to default to run on Rust nightly. - Various changes to make tests more robust.
1 parent bf887dd commit f0bf728

11 files changed

+191
-25
lines changed

.travis.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
env:
2+
global:
3+
- PACKAGE="Rust Enhanced"
4+
- SUBLIME_TEXT_VERSION="3"
5+
6+
language: rust
7+
8+
matrix:
9+
include:
10+
- os: linux
11+
rust: stable
12+
13+
- os: osx
14+
rust: stable
15+
16+
- os: linux
17+
rust: beta
18+
19+
- os: osx
20+
rust: beta
21+
22+
- os: linux
23+
rust: nightly
24+
25+
- os: osx
26+
rust: nightly
27+
28+
29+
before_install:
30+
- curl -OL https://raw.githubusercontent.com/SublimeText/UnitTesting/master/sbin/travis.sh
31+
32+
# enable gui, see https://docs.travis-ci.com/user/gui-and-headless-browsers
33+
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
34+
export DISPLAY=:99.0;
35+
sh -e /etc/init.d/xvfb start;
36+
fi
37+
38+
39+
install:
40+
# Install Sublime and Sublime Unittesting.
41+
- sh travis.sh bootstrap
42+
# Install Package Control, needed for dependencies.
43+
- sh travis.sh install_package_control
44+
45+
# Ensure nightly is installed to run no-trans, benchmarks, and Clippy.
46+
- rustup install nightly
47+
# Install Rust packages needed by integration tests.
48+
- cargo +nightly install clippy || export RE_SKIP_CLIPPY=1
49+
- cargo install cargo-script
50+
51+
52+
script:
53+
- sh travis.sh run_syntax_tests
54+
- sh travis.sh run_tests

appveyor.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
environment:
2+
global:
3+
PACKAGE: "Rust Enhanced"
4+
SUBLIME_TEXT_VERSION : "3"
5+
6+
matrix:
7+
- RUST_VERSION: stable
8+
- RUST_VERSION: beta
9+
- RUST_VERSION: nightly
10+
11+
12+
install:
13+
- ps: appveyor DownloadFile "https://raw.githubusercontent.com/SublimeText/UnitTesting/master/sbin/appveyor.ps1"
14+
# Install Sublime and Sublime Unittesting.
15+
- ps: .\appveyor.ps1 "bootstrap" -verbose
16+
- ps: .\appveyor.ps1 "install_package_control" -verbose
17+
# Install rust.
18+
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
19+
- rustup-init.exe -y --default-toolchain %RUST_VERSION%
20+
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
21+
# Ensure nightly is installed to run no-trans, benchmarks, and Clippy.
22+
- rustup install nightly
23+
# Install Rust packages needed by integration tests.
24+
- cargo +nightly install clippy || set RE_SKIP_CLIPPY=1
25+
- cargo install cargo-script
26+
- rustc -Vv
27+
28+
build: off
29+
30+
test_script:
31+
- ps: .\appveyor.ps1 "run_syntax_tests" -verbose
32+
- ps: .\appveyor.ps1 "run_tests" -verbose

cargo_build.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,7 @@ class CargoCurrentFile(sublime_plugin.WindowCommand):
423423
what = None
424424

425425
def run(self):
426-
print('current file')
427426
def _test_file(target):
428-
print('target is %r' % target)
429427
self.window.run_command('cargo_exec', args={
430428
'command': self.what,
431429
'settings': {

rust/cargo_settings.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@
125125
}
126126

127127

128+
CARGO_BUILD_DEFAULTS = {
129+
'variants': {
130+
'clippy': {
131+
'toolchain': 'nightly',
132+
}
133+
}
134+
}
135+
136+
128137
class CargoSettings(object):
129138

130139
"""Interface to Cargo project settings stored in `sublime-project`
@@ -146,9 +155,11 @@ def load(self):
146155
self.re_settings = sublime.load_settings('RustEnhanced.sublime-settings')
147156

148157
def get_global_default(self, key, default=None):
158+
internal_default = CARGO_BUILD_DEFAULTS.get('defaults', {})\
159+
.get(key, default)
149160
return self.re_settings.get('cargo_build', {})\
150161
.get('defaults', {})\
151-
.get(key, default)
162+
.get(key, internal_default)
152163

153164
def set_global_default(self, key, value):
154165
cb = self.re_settings.get('cargo_build', {})
@@ -169,10 +180,13 @@ def set_project_default(self, key, value):
169180
self._set_project_data()
170181

171182
def get_global_variant(self, variant, key, default=None):
183+
internal_default = CARGO_BUILD_DEFAULTS.get('variants', {})\
184+
.get(variant, {})\
185+
.get(key, default)
172186
return self.re_settings.get('cargo_build', {})\
173187
.get('variants', {})\
174188
.get(variant, {})\
175-
.get(key, default)
189+
.get(key, internal_default)
176190

177191
def set_global_variant(self, variant, key, value):
178192
cb = self.re_settings.get('cargo_build', {})

rust/rust_proc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ def _cleanup(self):
324324
self.proc.stdout.close()
325325
rc = self.proc.wait()
326326
with PROCS_LOCK:
327-
p = PROCS[self.window.id()]
327+
p = PROCS.get(self.window.id())
328328
if p is self:
329329
del PROCS[self.window.id()]
330330
return rc

tests/rust_test_common.py

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import sys
44
import os
55
import unittest
6+
import subprocess
67
import threading
78
import time
89
# Used for debugging.
@@ -45,9 +46,25 @@ def setUp(self):
4546
window = sublime.active_window()
4647
# Clear any rust project settings.
4748
data = window.project_data()
49+
if not data:
50+
data = {}
51+
# Ensure any user settings don't interfere with the test.
4852
if 'cargo_build' in data.get('settings', {}):
4953
del data['settings']['cargo_build']
50-
window.set_project_data(data)
54+
# When the tests run automatically, they are not part of a sublime
55+
# project. However, various tests depend on checking relative paths,
56+
# so ensure that `folders` is set.
57+
#
58+
# Set `folder_exclude_patterns` to prevent the Rust build directory
59+
# from being recognized by Sublime. I have a suspicion this causes
60+
# spurious errors on Windows because Sublime may be indexing the
61+
# files, preventing `cargo clean` from being able to remove them.
62+
if 'folders' not in data:
63+
data['folders'] = [{
64+
'path': plugin_path,
65+
'folder_exclude_patterns': ['target'],
66+
}]
67+
window.set_project_data(data)
5168
plugin.cargo_build.ON_LOAD_MESSAGES_ENABLED = False
5269

5370
# Override settings.
@@ -75,12 +92,18 @@ def tearDown(self):
7592
self._restore_settings()
7693
plugin.cargo_build.ON_LOAD_MESSAGES_ENABLED = True
7794

78-
def _get_rust_thread(self):
79-
"""Waits for a rust thread to get started and returns it."""
80-
for n in range(500):
95+
def _get_rust_thread(self, previous_thread=None):
96+
"""Waits for a rust thread to get started and returns it.
97+
98+
:param previous_thread: If set, it will avoid returning this thread.
99+
Use this when there is a thread currently running, and you want to
100+
make sure you get the next thread that starts.
101+
"""
102+
for n in range(1000):
81103
t = rust_thread.THREADS.get(sublime.active_window().id())
82104
if t:
83-
return t
105+
if previous_thread is None or previous_thread != t:
106+
return t
84107
time.sleep(0.01)
85108
raise AssertionError('Rust thread never started.')
86109

@@ -151,11 +174,23 @@ def _cargo_clean(self, view_or_path):
151174
else:
152175
path = view_or_path
153176
window = sublime.active_window()
154-
rust_proc.check_output(window,
155-
'cargo clean'.split(),
156-
path)
177+
try:
178+
rust_proc.check_output(window,
179+
'cargo clean'.split(),
180+
path)
181+
except subprocess.CalledProcessError as e:
182+
print('Cargo clean failure')
183+
print(e.output)
184+
raise
157185
messages.clear_messages(window)
158186

187+
def _skip_clippy(self):
188+
if 'RE_SKIP_CLIPPY' in os.environ:
189+
print('Skipping Clippy test.')
190+
return True
191+
else:
192+
return False
193+
159194

160195
class AlteredSetting(object):
161196

tests/test_cargo_build.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ def _test_document(self, view):
304304

305305
def test_clippy(self):
306306
"""Test "Clippy" variant."""
307+
if self._skip_clippy():
308+
return
307309
self._with_open_file('tests/error-tests/examples/clippy_ex.rs',
308310
self._test_clippy)
309311

@@ -412,8 +414,6 @@ def _test_build_env(self, view):
412414
def test_auto_build(self):
413415
"""Test "auto" build."""
414416
tests = [
415-
# This should probably automatically use nightly?
416-
('benches/bench1.rs', r'may not be used on the (stable|beta) release channel'),
417417
('examples/ex1.rs', r'(?m)^ex1$'),
418418
('src/bin/bin1.rs', r'(?m)^bin1$'),
419419
('src/altmain.rs', r'(?m)^altmain$'),
@@ -422,6 +422,18 @@ def test_auto_build(self):
422422
('src/main.rs', r'(?m)^Hello$'),
423423
('tests/test1.rs', r'(?m)^test sample_test1 \.\.\. ok$'),
424424
]
425+
rustc_version = util.get_rustc_version(sublime.active_window(),
426+
plugin_path)
427+
if 'nightly' in rustc_version:
428+
# Benches are allowed to run on nightly.
429+
tests.append(
430+
('benches/bench1.rs',
431+
r'\[Running: cargo bench --bench bench1'))
432+
else:
433+
tests.append(
434+
('benches/bench1.rs',
435+
r'may not be used on the (stable|beta) release channel'))
436+
425437
for path, pattern in tests:
426438
self._with_open_file('tests/multi-targets/' + path,
427439
self._test_auto_build, pattern=pattern)

tests/test_context.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,14 @@ def _test_rust_list_messages2(self, view):
152152
]
153153
self.quick_panel_index = 2
154154
window.run_command('rust_list_messages')
155-
new_view = window.active_view()
156155
expected_path = os.path.normpath(
157156
os.path.join(plugin_path, 'tests/message-order/examples/warning2.rs'))
158-
self.assertEqual(new_view.file_name(), expected_path)
157+
# Give Sublime some time to switch views.
158+
for n in range(5):
159+
new_view = window.active_view()
160+
if new_view.file_name() == expected_path:
161+
break
162+
time.sleep(0.5)
163+
else:
164+
self.assertEqual(new_view.file_name(), expected_path)
159165
new_view.run_command('close_file')

tests/test_interrupt.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ def _test_slow_check(self, view):
8787

8888
def test_build_cancel(self):
8989
"""Test manually canceling a build."""
90-
# So it doesn't hide the UnitTest output panel.
9190
self._with_open_file('tests/slow-build/src/lib.rs',
9291
self._test_build_cancel)
9392

@@ -101,6 +100,7 @@ def _test_build_cancel(self, view):
101100
window.run_command('rust_cancel')
102101
# Sleep long enough to make sure the build didn't continue running.
103102
time.sleep(4)
103+
t.join()
104104
self.assertEqual(self.terminated, [t])
105105
# Start, but no end.
106106
self.assertEqual(self._files(), [pattern + '-start-1'])
@@ -119,6 +119,7 @@ def _test_syntax_check_cancel(self, view):
119119
view.window().run_command('rust_cancel')
120120
# Sleep long enough to make sure the build didn't continue running.
121121
time.sleep(4)
122+
t.join()
122123
self.assertEqual(self.terminated, [t])
123124
# Start, but no end.
124125
self.assertEqual(self._files(), [pattern + '-start-1'])
@@ -140,6 +141,8 @@ def _test_syntax_check_while_build(self, view):
140141
# This thread will silently exit without running.
141142
check_t.start()
142143
time.sleep(4)
144+
check_t.join()
145+
build_t.join()
143146
self.assertEqual(self.terminated, [])
144147
self.assertEqual(self._files(),
145148
[pattern + '-start-1',
@@ -158,9 +161,11 @@ def _test_build_while_syntax_check(self, view):
158161
self._wait_for_start()
159162
# Should silently kill the syntax check thread.
160163
self._run_build()
161-
build_t = self._get_rust_thread()
164+
build_t = self._get_rust_thread(previous_thread=check_t)
162165
self._wrap_terminate(build_t)
163166
time.sleep(4)
167+
build_t.join()
168+
check_t.join()
164169
self.assertEqual(self.terminated, [check_t])
165170
self.assertEqual(self._files(),
166171
[pattern + '-start-1',
@@ -176,12 +181,17 @@ def _test_build_with_save(self, view):
176181
self._cargo_clean(view)
177182
# Trigger on_save for syntax checking.
178183
view.run_command('save')
184+
on_save_thread = self._get_rust_thread()
185+
self._wrap_terminate(on_save_thread)
179186
# Doing this immediately afterwards should cancel the syntax check
180187
# before it gets a chance to do much.
181188
self._run_build()
182-
build_t = self._get_rust_thread()
189+
build_t = self._get_rust_thread(previous_thread=on_save_thread)
183190
self._wrap_terminate(build_t)
184-
time.sleep(5)
191+
# Wait for threads to finish.
192+
on_save_thread.join()
193+
build_t.join()
194+
self.assertEqual(self.terminated, [on_save_thread])
185195
self.assertEqual(self._files(),
186196
[pattern + '-start-1',
187197
pattern + '-end-1'])
@@ -210,13 +220,15 @@ def ok_cancel_dialog(msg, ok_title=None):
210220
self._wrap_terminate(build_t)
211221
# Start a second build.
212222
self._run_build()
213-
time.sleep(1)
223+
next_build_t = self._get_rust_thread(previous_thread=build_t)
224+
build_t.join()
214225
self.assertEqual(self.terminated, [build_t])
215226
# Start again, but hit cancel.
216227
ok_value = False
217228
self._run_build()
218229
time.sleep(4)
219-
# Should not have interrupted.
230+
next_build_t.join()
231+
# Should not have interrupted next_build_t.
220232
self.assertEqual(self.terminated, [build_t])
221233
self.assertEqual(self._files(),
222234
[pattern + '-start-1',
@@ -226,7 +238,7 @@ def ok_cancel_dialog(msg, ok_title=None):
226238
sublime.ok_cancel_dialog = orig_ok_cancel_dialog
227239

228240
def _wait_for_start(self):
229-
for _ in range(50):
241+
for _ in range(100):
230242
time.sleep(0.1)
231243
if self._files() == [pattern + '-start-1']:
232244
break

tests/test_syntax_check.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ def test_messages(self):
153153

154154
def test_clippy_messages(self):
155155
"""Test clippy messages."""
156+
if self._skip_clippy():
157+
return
156158
to_test = [
157159
'tests/error-tests/examples/clippy_ex.rs',
158160
]

unittesting.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"async": true
2+
"async": true,
3+
"capture_console": true
34
}

0 commit comments

Comments
 (0)