Skip to content

Commit e0cef5a

Browse files
cleanup: Simplify test build & runner logic. (#151)
1 parent 0e21b96 commit e0cef5a

File tree

8 files changed

+73
-44
lines changed

8 files changed

+73
-44
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ jobs:
4141
with:
4242
name: ci-build-log
4343
path: log
44-
- name: "🏋️‍♂️ Run unit tests"
45-
run: ./bazel test //test/scip:unit_tests --config=dbg
46-
- name: "🏋️‍♂️ Run snapshot tests"
44+
- name: "🏋️‍♂️ Run tests"
4745
run: ./bazel test //test/scip --config=dbg
4846
# Repo tests are kinda' broken right now because the bundle cache step needs synchronization
4947
#

docs/scip-ruby/CONTRIBUTING.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,25 +154,32 @@ There are currently 3 kinds of tests:
154154
to test via snapshots.
155155
- Repo/Integration tests: These try to index an OSS repo using scip-ruby.
156156

157-
To run snapshot tests, which are self-contained:
157+
Here are some example test invocations:
158158

159159
```
160-
./bazel test //test/scip --config=dbg
161-
```
160+
# Run both snapshot tests and unit tests
161+
./bazel test --config=dbg //test/scip
162162
163-
Updating snapshots:
163+
# Run only unit tests
164+
./bazel test --config=dbg //test/scip:unit_tests
164165
165-
```
166-
./bazel test //test/scip:update --config=dbg
166+
# Run a specific snapshot test, e.g. 'testdata/alias.rb'
167+
./bazel test --config=dbg //test/scip:alias
167168
```
168169

169-
You can run unit tests using:
170+
You can add `--test_output=errors` to see diffs for snapshot mismatches.
171+
172+
Snapshot outputs can be easily updated:
170173

171174
```
172-
./bazel test //test/scip:unit_tests --config=dbg
175+
# Update all snapshots
176+
./bazel test --config=dbg //test/scip:update
177+
178+
# Update snapshot for a single test
179+
./bazel test --config=dbg //test/scip:update_alias
173180
```
174181

175-
WARNING: Repo tests are kinda' broken right now; they're disabled
182+
Repo tests are kinda' broken right now; they're disabled
176183
in CI (see ci.yml), and may or may not work on your machine.
177184

178185
If you want to run repo tests, first complete the
@@ -258,7 +265,7 @@ to the root and run:
258265
```
259266

260267
Alternately, it may be useful to create a `tmp.rb`
261-
file under the `test/scip/snapshots/` directory
268+
file under the `test/scip/testdata/` directory
262269
(it will be gitignored) and run:
263270

264271
```bash

test/scip/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
load(":scip_test.bzl", "scip_test_suite")
22

33
scip_test_suite(
4-
multifile_paths = glob(["testdata/multifile/*/*"]),
4+
multifile_paths = glob(["testdata/multifile/**"]),
55
paths = glob(
66
["testdata/*"],
77
exclude_directories = 1,

test/scip/scip_test.bzl

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
def basename(p):
22
return p.rpartition("/")[-1]
33

4-
def dirname(p):
5-
return p.rpartition("/")[0]
4+
def ancestor_path(p, parent):
5+
"""Extract components of p until the second-last component is parent."""
6+
before, middle, after = p.rpartition(parent + "/")
7+
child, _, _ = after.partition("/")
8+
return before + middle + child
69

710
def split_extension(p):
811
(before, _, ext) = p.rpartition(".")
@@ -11,30 +14,30 @@ def split_extension(p):
1114
return (before, ext)
1215

1316
def scip_test_suite(paths, multifile_paths):
14-
tests = []
17+
tests = scip_unit_tests()
1518
updates = []
19+
1620
for path in paths:
1721
names = scip_test(path)
1822
if names:
1923
tests.append(names[0])
2024
updates.append(names[1])
2125

22-
file_groups = {}
26+
multifile_groups = {}
2327
for p in multifile_paths:
24-
d = dirname(p)
25-
if d in file_groups:
26-
file_groups[d].append(p)
28+
d = ancestor_path(p, parent = "multifile")
29+
if d in multifile_groups:
30+
multifile_groups[d].append(p)
2731
else:
28-
file_groups[d] = [p]
32+
multifile_groups[d] = [p]
2933

30-
tests.append(scip_unit_tests())
31-
for dir, files in file_groups.items():
34+
for dir, files in multifile_groups.items():
3235
names = scip_multifile_test(dir, files)
3336
tests.append(names[0])
3437
updates.append(names[1])
3538

3639
native.test_suite(
37-
name = "scip",
40+
name = "scip", # both unit tests and snapshot tests
3841
tests = tests,
3942
)
4043
native.test_suite(
@@ -48,23 +51,23 @@ def scip_unit_tests():
4851
native.sh_test(
4952
name = "unit_tests",
5053
srcs = ["scip_test_runner.sh"],
51-
args = ["only_unit_tests"],
54+
args = ["--only-unit-tests"],
5255
data = ["//test:scip_test_runner"],
5356
size = "small",
5457
)
55-
return "unit_tests"
58+
return ["unit_tests"]
5659

5760
def scip_test(path):
5861
if not path.endswith(".rb") or path.endswith(".snapshot.rb"):
5962
return None
6063
test_name = basename(path)[:-3]
6164
snapshot_path = path[:-3] + ".snapshot.rb"
62-
args = ["$(location {})".format(path), "--output=$(location {})".format(snapshot_path)]
65+
args = ["--input=$(location {})".format(path), "--output=$(location {})".format(snapshot_path)]
6366
data = [path, snapshot_path, "//test:scip_test_runner"]
6467
return _make_test(test_name, args, data)
6568

6669
def scip_multifile_test(dir, filepaths):
67-
args = ["$(location {})".format(dir), "--output=$(location {})".format(dir)]
70+
args = ["--input=$(location {})".format(dir), "--output=$(location {})".format(dir)]
6871
data = ["//test:scip_test_runner", "//test/scip:{}".format(dir)]
6972
for filepath in filepaths:
7073
path_without_ext, ext = split_extension(filepath)
@@ -73,10 +76,10 @@ def scip_multifile_test(dir, filepaths):
7376
if not filepath.endswith("scip-ruby-args.rb"): # Special file for reading Gem-level args.
7477
data.append(path_without_ext + ".snapshot." + ext)
7578
if not dir.startswith("testdata/multifile/"):
76-
fail("Expected directory to be under multifile/")
79+
fail("Expected directory to be under multifile/ but found: " + dir)
7780
dir = dir[len("testdata/multifile/"):]
7881
if "/" in dir:
79-
fail("Expected directory to be 1-level deep under multifile/")
82+
fail("Expected test root directory to be 1-level deep under multifile/ but found: " + dir)
8083

8184
test_name = "multifile_" + dir
8285
return _make_test(test_name, args, data)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# typed: true
2+
3+
require 'upstream'
4+
5+
def f()
6+
g()
7+
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{"path": "downstream.rb", "gem": "my_downstream_gem@1"}
2+
{"gem": "my_upstream_gem@1", "path": "upstream.rb"}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# typed: true
2+
3+
def g()
4+
puts 'Hello'
5+
end

test/scip_test_runner.cc

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,11 @@ void formatSnapshot(const scip::Document &document, FormatOptions options, std::
234234
return isSCIPRangeLess(occ1.range(), occ2.range());
235235
});
236236
auto formatSymbol = [](const std::string &symbol) -> string {
237-
// Strip out repeating information and placeholder names.
238-
return absl::StrReplaceAll(symbol, {{"scip-ruby gem ", ""}, {"placeholder_name placeholder_version", "[..]"}});
237+
// Strip out repeating information for cleaner snapshots.
238+
return absl::StrReplaceAll(symbol, {
239+
{"scip-ruby gem ", ""}, // indexer prefix
240+
{"placeholder_name placeholder_version", "[..]"}, // test placeholder
241+
});
239242
};
240243
size_t occ_i = 0;
241244
std::ifstream input(document.relative_path());
@@ -569,27 +572,31 @@ bool ends_with(const std::string &s, const std::string &suffix) {
569572

570573
int main(int argc, char *argv[]) {
571574
cxxopts::Options options("test_corpus_scip", "SCIP test corpus for Sorbet typechecker");
572-
options.allow_unrecognised_options().add_options()("output", "path to output file or directory",
573-
cxxopts::value<std::string>()->default_value(""), "path")(
574-
"update-snapshots", "should the snapshot files be overwritten if there are changes");
575+
options.allow_unrecognised_options();
576+
options.add_options()("input", "path to input file to directory", cxxopts::value<std::string>());
577+
options.add_options()("output", "path to output file or directory", cxxopts::value<std::string>());
578+
options.add_options()("update-snapshots", "should the snapshot files be overwritten if there are changes");
579+
options.add_options()("only-unit-tests", "only run unit tests, skip snapshot tests");
575580
auto res = options.parse(argc, argv);
581+
576582
auto unmatched = res.unmatched();
583+
if (!unmatched.empty()) {
584+
fmt::print(stderr, "error: unexpected arguments passed to test runner {}",
585+
sorbet::scip_indexer::showVec(unmatched, [](auto &s) { return s; }));
586+
return 1;
587+
}
577588

578-
if (unmatched.size() == 1 && unmatched.front() == "only_unit_tests") {
589+
if (res.count("only-unit-tests") > 0) {
579590
sorbet::test::onlyRunUnitTests = true;
580591
doctest::Context context(argc, argv);
581592
return context.run();
582593
}
583594

584-
if (unmatched.size() != 1) {
585-
std::fprintf(stderr, "error: runner expected single input file with .rb extension or folder");
586-
return 1;
587-
}
588-
595+
ENFORCE(res.count("input") == 1);
596+
ENFORCE(res.count("output") == 1);
589597
sorbet::test::update = res.count("update-snapshots") > 0;
590-
sorbet::test::inputFileOrDir = unmatched[0];
598+
sorbet::test::inputFileOrDir = res["input"].as<std::string>();
591599
sorbet::test::outputFileOrDir = res["output"].as<std::string>();
592-
593600
doctest::Context context(argc, argv);
594601
return context.run();
595602
}

0 commit comments

Comments
 (0)