Skip to content

Commit 43cf0da

Browse files
AndreasArvidssonpre-commit-ci-lite[bot]pokey
authored
Scope tests (#2053)
Started implementing a new scope handler test representation ``` [Content] const name = "Hello world"; ^^^^^^^^^^^^^ ``` Originally I was thinking of doing `^` for each character. That worked fine until @pokey asked the question about empty ranges which we actually has in a few places. So I switch to a multiline representation of `[---]` where the empty range would be `[]`. ``` [Content] function myFunk() { [------------------- } -] ``` I do wonder if we want to start multiline ranges above the source code and end it below. Makes it so the code is actually inside the range endings. ``` [Content] [------------------- function myFunk() { } -] ``` Relevant issues #1524 #2010 ## Checklist - [x] I have added [tests](https://www.cursorless.org/docs/contributing/test-case-recorder/) - [ ] I have updated the [docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and [cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet) - [-] I have not broken the cheatsheet --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Pokey Rule <[email protected]>
1 parent 740e3ef commit 43cf0da

32 files changed

+1344
-1
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ repos:
4040
# tests use strings with trailing white space to represent the final
4141
# document contents. For example
4242
# packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/languages/ruby/changeCondition.yml
43-
exclude: ^packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/.*/[^/]*\.yml$|/generated/|^patches/
43+
exclude: ^packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/.*/[^/]*\.yml$|\.scope$|/generated/|^patches/
4444
- repo: local
4545
hooks:
4646
- id: eslint

packages/common/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,7 @@ export * from "./types/TestCaseFixture";
9494
export * from "./util/getEnvironmentVariableStrict";
9595
export * from "./util/CompositeKeyDefaultMap";
9696
export * from "./util/toPlainObject";
97+
export * from "./scopeSupportFacets/scopeSupportFacets.types";
98+
export * from "./scopeSupportFacets/scopeSupportFacetInfos";
99+
export * from "./scopeSupportFacets/textualScopeSupportFacetInfos";
100+
export * from "./scopeSupportFacets/getLanguageScopeSupport";
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { htmlScopeSupport } from "./html";
2+
import { javascriptScopeSupport } from "./javascript";
3+
import { LanguageScopeSupportFacetMap } from "./scopeSupportFacets.types";
4+
5+
export function getLanguageScopeSupport(
6+
languageId: string,
7+
): LanguageScopeSupportFacetMap {
8+
switch (languageId) {
9+
case "javascript":
10+
return javascriptScopeSupport;
11+
case "html":
12+
return htmlScopeSupport;
13+
}
14+
throw Error(`Unsupported language: '${languageId}'`);
15+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {
2+
LanguageScopeSupportFacetMap,
3+
ScopeSupportFacetLevel,
4+
} from "./scopeSupportFacets.types";
5+
6+
const { supported, notApplicable } = ScopeSupportFacetLevel;
7+
8+
export const htmlScopeSupport: LanguageScopeSupportFacetMap = {
9+
["key.attribute"]: supported,
10+
["tags"]: supported,
11+
12+
namedFunction: notApplicable,
13+
["name.assignment"]: notApplicable,
14+
["key.mapPair"]: notApplicable,
15+
["key.mapPair.iteration"]: notApplicable,
16+
["value.mapPair"]: notApplicable,
17+
["value.mapPair.iteration"]: notApplicable,
18+
["value.assignment"]: notApplicable,
19+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {
2+
LanguageScopeSupportFacetMap,
3+
ScopeSupportFacetLevel,
4+
} from "./scopeSupportFacets.types";
5+
6+
const { supported, notApplicable } = ScopeSupportFacetLevel;
7+
8+
export const javascriptScopeSupport: LanguageScopeSupportFacetMap = {
9+
namedFunction: supported,
10+
["name.assignment"]: supported,
11+
["key.mapPair"]: supported,
12+
["key.mapPair.iteration"]: supported,
13+
["value.mapPair"]: supported,
14+
["value.mapPair.iteration"]: supported,
15+
["value.assignment"]: supported,
16+
17+
["key.attribute"]: notApplicable,
18+
["tags"]: notApplicable,
19+
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import {
2+
ScopeSupportFacet,
3+
ScopeSupportFacetInfo,
4+
} from "./scopeSupportFacets.types";
5+
6+
export const scopeSupportFacetInfos: Record<
7+
ScopeSupportFacet,
8+
ScopeSupportFacetInfo
9+
> = {
10+
namedFunction: {
11+
description: "A named function",
12+
scopeType: "namedFunction",
13+
},
14+
["name.assignment"]: {
15+
description: "Name(LHS) of an assignment",
16+
scopeType: "name",
17+
},
18+
["key.attribute"]: {
19+
description: "Key(LHS) of an attribute",
20+
scopeType: "collectionKey",
21+
},
22+
["key.mapPair"]: {
23+
description: "Key(LHS) of a map pair",
24+
scopeType: "collectionKey",
25+
},
26+
["key.mapPair.iteration"]: {
27+
description: "Iteration of map pair keys",
28+
scopeType: "collectionKey",
29+
isIteration: true,
30+
},
31+
["value.assignment"]: {
32+
description: "Value(RHS) of an assignment",
33+
scopeType: "value",
34+
},
35+
["value.mapPair"]: {
36+
description: "Key(RHS) of a map pair",
37+
scopeType: "value",
38+
},
39+
["value.mapPair.iteration"]: {
40+
description: "Iteration of map pair values",
41+
scopeType: "value",
42+
isIteration: true,
43+
},
44+
["tags"]: {
45+
description: "Both tags in an xml element",
46+
scopeType: "xmlBothTags",
47+
},
48+
};
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { SimpleScopeTypeType } from "../types/command/PartialTargetDescriptor.types";
2+
3+
const scopeSupportFacets = [
4+
// "list",
5+
// "list.interior",
6+
// "map",
7+
// "map.interior",
8+
// "collectionKey",
9+
"namedFunction",
10+
// "namedFunction.interior",
11+
// "functionName",
12+
// "anonymousFunction",
13+
// "anonymousFunction.interior",
14+
"name.assignment",
15+
"key.attribute",
16+
"key.mapPair",
17+
"key.mapPair.iteration",
18+
"value.assignment",
19+
"value.mapPair",
20+
"value.mapPair.iteration",
21+
// "value.assignment.removal",
22+
// "value.return",
23+
// "value.return.removal",
24+
// "value.collectionItem",
25+
// "value.collectionItem.removal",
26+
// "statement",
27+
// "ifStatement",
28+
// "condition.if",
29+
// "condition.while",
30+
// "condition.doWhile",
31+
// "condition.for",
32+
// "condition.ternary",
33+
// "branch",
34+
// "comment.line",
35+
// "comment.block",
36+
// "string.singleLine",
37+
// "string.multiLine",
38+
// "textFragment",
39+
// "functionCall",
40+
// "functionCallee",
41+
// "argumentOrParameter.argument",
42+
// "argumentOrParameter.argument.removal",
43+
// "argumentOrParameter.parameter",
44+
// "argumentOrParameter.parameter.removal",
45+
// "class",
46+
// "class.interior",
47+
// "className",
48+
// "type",
49+
"tags",
50+
] as const;
51+
52+
const textualScopeSupportFacets = [
53+
"character",
54+
"word",
55+
"token",
56+
"line",
57+
"paragraph",
58+
"document",
59+
] as const;
60+
61+
export interface ScopeSupportFacetInfo {
62+
readonly description: string;
63+
readonly scopeType: SimpleScopeTypeType;
64+
readonly isIteration?: boolean;
65+
}
66+
67+
export enum ScopeSupportFacetLevel {
68+
supported,
69+
unsupported,
70+
notApplicable,
71+
}
72+
73+
export type ScopeSupportFacet = (typeof scopeSupportFacets)[number];
74+
75+
export type TextualScopeSupportFacet =
76+
(typeof textualScopeSupportFacets)[number];
77+
78+
export type LanguageScopeSupportFacetMap = Partial<
79+
Record<ScopeSupportFacet, ScopeSupportFacetLevel>
80+
>;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {
2+
ScopeSupportFacetInfo,
3+
TextualScopeSupportFacet,
4+
} from "./scopeSupportFacets.types";
5+
6+
export const textualScopeSupportFacetInfos: Record<
7+
TextualScopeSupportFacet,
8+
ScopeSupportFacetInfo
9+
> = {
10+
character: {
11+
description: "A single character in the document",
12+
scopeType: "character",
13+
},
14+
word: {
15+
description: "A single word in a token",
16+
scopeType: "word",
17+
},
18+
token: {
19+
description: "A single token in the document",
20+
scopeType: "token",
21+
},
22+
line: {
23+
description: "A single line in the document",
24+
scopeType: "line",
25+
},
26+
paragraph: {
27+
description:
28+
"A single paragraph(contiguous block of lines) in the document",
29+
scopeType: "paragraph",
30+
},
31+
document: {
32+
description: "The entire document",
33+
scopeType: "document",
34+
},
35+
};

packages/common/src/testUtil/getFixturePaths.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ export function getRecordedTestsDirPath() {
2121
return path.join(getFixturesPath(), "recorded");
2222
}
2323

24+
export function getScopeTestsDirPath() {
25+
return path.join(getFixturesPath(), "scopes");
26+
}
27+
2428
export function getRecordedTestPaths() {
2529
const directory = getRecordedTestsDirPath();
2630
const relativeDir = path.dirname(directory);
@@ -34,3 +38,17 @@ export function getRecordedTestPaths() {
3438
path: p,
3539
}));
3640
}
41+
42+
export function getScopeTestPaths() {
43+
const directory = getScopeTestsDirPath();
44+
const relativeDir = path.dirname(directory);
45+
46+
return walkFilesSync(directory)
47+
.filter((p) => p.endsWith(".scope"))
48+
.map((p) => ({
49+
path: p,
50+
name: path.relative(relativeDir, p.substring(0, p.lastIndexOf("."))),
51+
languageId: path.dirname(path.relative(directory, p)).split(path.sep)[0],
52+
facet: path.basename(p).match(/([a-zA-Z.]+)\d*\.scope/)![1],
53+
}));
54+
}

packages/common/src/types/ScopeProvider.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,13 @@ export interface ScopeRanges {
178178
*/
179179
export interface TargetRanges {
180180
contentRange: Range;
181+
removalRange: Range;
181182
removalHighlightRange: GeneralizedRange;
183+
leadingDelimiter: TargetRanges | undefined;
184+
trailingDelimiter: TargetRanges | undefined;
185+
interior: TargetRanges[] | undefined;
186+
boundary: TargetRanges[] | undefined;
187+
insertionDelimiter: string;
182188
}
183189

184190
/**

0 commit comments

Comments
 (0)