Skip to content

Commit ccaff50

Browse files
committed
Merge pull request #112 from modocache/line-offsets
[Tests] Automatically substitute [[@line]] numbers
2 parents 1bb2e9e + 82edc2b commit ccaff50

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

Tests/Functional/Asynchronous/Misuse/main.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@
1414
// CHECK: Test Suite 'MisuseTestCase' started at \d+:\d+:\d+\.\d+
1515
class MisuseTestCase: XCTestCase {
1616
// CHECK: Test Case 'MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails' started at \d+:\d+:\d+\.\d+
17-
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:21: error: MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails : Failed due to unwaited expectations.
17+
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:[[@LINE+4]]: error: MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails : Failed due to unwaited expectations.
1818
// CHECK: Test Case 'MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails' failed \(\d+\.\d+ seconds\).
1919
func test_whenExpectationsAreMade_butNotWaitedFor_fails() {
2020
self.expectation(withDescription: "the first expectation")
2121
self.expectation(withDescription: "the second expectation (the file and line number for this one are included in the failure message")
2222
}
2323

2424
// CHECK: Test Case 'MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails' started at \d+:\d+:\d+\.\d+
25-
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:28: error: MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails : API violation - call made to wait without any expectations having been set.
25+
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:[[@LINE+3]]: error: MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails : API violation - call made to wait without any expectations having been set.
2626
// CHECK: Test Case 'MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails' failed \(\d+\.\d+ seconds\).
2727
func test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails() {
2828
self.waitForExpectations(withTimeout: 0.1)
2929
}
3030

3131
// CHECK: Test Case 'MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails' started at \d+:\d+:\d+\.\d+
32-
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:38: error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
33-
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:48: error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
32+
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:[[@LINE+6]]: error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
33+
// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:[[@LINE+15]]: error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
3434
// CHECK: Test Case 'MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails' failed \(\d+\.\d+ seconds\).
3535
func test_whenExpectationIsFulfilledMultipleTimes_fails() {
3636
let expectation = self.expectation(withDescription: "rob")

Tests/Functional/xctest_checker/tests/test_compare.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,10 @@ def test_can_explicitly_match_leading_and_trailing_whitespace(self):
8787
expected = _tmpfile('c: foo\nc: ^ bar \nc: baz $\n')
8888
compare.compare(actual, expected, check_prefix='c:')
8989

90+
def test_line_number_substitution(self):
91+
actual = _tmpfile('beep 1\nboop 5\n')
92+
expected = _tmpfile('c: beep [[@LINE]]\nc: boop [[@LINE+3]]')
93+
compare.compare(actual, expected, check_prefix='c: ')
94+
9095
if __name__ == "__main__":
9196
unittest.main()

Tests/Functional/xctest_checker/xctest_checker/compare.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import re
1212

1313
from .error import XCTestCheckerError
14+
from .line import replace_offsets
1415

1516

1617
def _actual_lines(path):
@@ -40,7 +41,8 @@ def _expected_lines_and_line_numbers(path, check_prefix):
4041

4142
components = line.split(check_prefix)
4243
if len(components) == 2:
43-
yield components[1].strip(), line_number
44+
yield (replace_offsets(components[1].strip(), line_number),
45+
line_number)
4446
elif len(components) > 2:
4547
# Include a newline, then the file name and line number in the
4648
# exception in order to have it appear as an inline failure in
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# xctest_checker/line.py - Replaces [[@LINE]] with line numbers -*- python -*-
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See http://swift.org/LICENSE.txt for license information
9+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
11+
import re
12+
13+
14+
def replace_offsets(line, line_number):
15+
"""
16+
Replace all line directives in the given line with the given line number.
17+
18+
Line directives come in two forms:
19+
1. "[[@LINE]]", with no offset.
20+
2. "[[@LINE+10]]" or "[[@LINE-3]]", with a positive or negative offset.
21+
"""
22+
pattern = re.compile(r'\[\[@LINE(?P<offset>[+-]\d+)?\]\]')
23+
24+
result = line
25+
for match in pattern.finditer(line):
26+
offset_string = match.groupdict()['offset']
27+
if offset_string is None:
28+
offset_string = '0'
29+
try:
30+
offset = int(offset_string)
31+
except ValueError:
32+
# Re-raise the error, but with a friendlier explanation of what
33+
# went wrong.
34+
raise ValueError(
35+
'Invalid line offset: "{}". Line offsets must be numerical, '
36+
'such as "[[@LINE+10]]" or "[[@LINE-2]]"'.format(
37+
match.group()))
38+
result = result.replace(match.group(), str(line_number + offset))
39+
40+
return result
41+

0 commit comments

Comments
 (0)