Skip to content

Commit

Permalink
feat: Add test metadata to the nodes (#437)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdneo authored Jan 8, 2021
1 parent 95ff1ba commit 0ec8146
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,9 @@ private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IP

IClasspathEntry resolvedClasspathEntry = fragmentRoot.getResolvedClasspathEntry();
if (resolvedClasspathEntry != null) {
Map<String, String> attributes = new HashMap<>();
for (IClasspathAttribute attribute : resolvedClasspathEntry.getExtraAttributes()) {
attributes.put(attribute.getName(), attribute.getValue());
node.setMetaDataValue(attribute.getName(), attribute.getValue());
}
node.setAttributes(attributes);
}

children.add(node);
Expand Down
23 changes: 23 additions & 0 deletions src/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { Uri, window, workspace, WorkspaceFolder } from "vscode";
import { setUserError } from "vscode-extension-telemetry-wrapper";
import { INodeData } from "./java/nodeData";
import { languageServerApiManager } from "./languageServerApi/languageServerApiManager";
import { Settings } from "./settings";

Expand Down Expand Up @@ -95,3 +96,25 @@ const identifierRegExp: RegExp = /^([a-zA-Z_$][a-zA-Z\d_$]*)$/;
export function isJavaIdentifier(identifier: string): boolean {
return identifierRegExp.test(identifier);
}

export function isTest(nodeData: INodeData | undefined): boolean {
if (!nodeData) {
return false;
}

if (nodeData.metaData?.test === "true") {
return true;
}

const mavenScope: string = nodeData.metaData?.["maven.scope"] || "";
if (mavenScope.toLocaleLowerCase().includes("test")) {
return true;
}

const gradleScope: string = nodeData.metaData?.gradle_scope || "";
if (gradleScope.toLocaleLowerCase().includes("test")) {
return true;
}

return false;
}
17 changes: 12 additions & 5 deletions src/views/PrimaryTypeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Commands } from "../commands";
import { Explorer } from "../constants";
import { INodeData, TypeKind } from "../java/nodeData";
import { Settings } from "../settings";
import { isTest } from "../utility";
import { DataNode } from "./dataNode";
import { DocumentSymbolNode } from "./documentSymbolNode";
import { ExplorerNode } from "./explorerNode";
Expand All @@ -15,7 +16,7 @@ export class PrimaryTypeNode extends DataNode {

public static K_TYPE_KIND = "TypeKind";

constructor(nodeData: INodeData, parent: DataNode) {
constructor(nodeData: INodeData, parent: DataNode, protected _rootNode?: DataNode) {
super(nodeData, parent);
}

Expand Down Expand Up @@ -91,15 +92,21 @@ export class PrimaryTypeNode extends DataNode {
}

protected get contextValue(): string {
const context = Explorer.ContextValueType.Type;
let contextValue: string = Explorer.ContextValueType.Type;
const type = this.nodeData.metaData?.[PrimaryTypeNode.K_TYPE_KIND];

if (type === TypeKind.Enum) {
return `${context}+enum`;
contextValue += "+enum";
} else if (type === TypeKind.Interface) {
return `${context}+interface`;
contextValue += "+interface";
} else {
return `${context}+class`;
contextValue += "+class";
}

if (isTest(this._rootNode?.nodeData)) {
contextValue += "+test";
}

return contextValue;
}
}
2 changes: 1 addition & 1 deletion src/views/hierarchicalPackageNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class HierarchicalPackageNode extends PackageNode {
result.push(new HierarchicalPackageNode(nodeData, this, this._project, this._rootNode));
} else if (nodeData.kind === NodeKind.PrimaryType) {
if (nodeData.metaData && nodeData.metaData[PrimaryTypeNode.K_TYPE_KIND]) {
result.push(new PrimaryTypeNode(nodeData, this));
result.push(new PrimaryTypeNode(nodeData, this, this._rootNode));
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/views/hierarchicalPackageRootNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class HierarchicalPackageRootNode extends PackageRootNode {
result.push(new FolderNode(data, this, this._project, this));
} else if (data.kind === NodeKind.PrimaryType) {
if (data.metaData && data.metaData[PrimaryTypeNode.K_TYPE_KIND]) {
result.push(new PrimaryTypeNode(data, this));
result.push(new PrimaryTypeNode(data, this, this));
}
}
});
Expand Down
13 changes: 9 additions & 4 deletions src/views/packageNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Explorer } from "../constants";
import { Jdtls } from "../java/jdtls";
import { INodeData, NodeKind } from "../java/nodeData";
import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData";
import { isTest } from "../utility";
import { DataNode } from "./dataNode";
import { ExplorerNode } from "./explorerNode";
import { FileNode } from "./fileNode";
Expand Down Expand Up @@ -34,7 +35,7 @@ export class PackageNode extends DataNode {
result.push(new FileNode(nodeData, this));
} else if (nodeData.kind === NodeKind.PrimaryType) {
if (nodeData.metaData && nodeData.metaData[PrimaryTypeNode.K_TYPE_KIND]) {
result.push(new PrimaryTypeNode(nodeData, this));
result.push(new PrimaryTypeNode(nodeData, this, this._rootNode));
}
}
});
Expand All @@ -48,11 +49,15 @@ export class PackageNode extends DataNode {

protected get contextValue(): string | undefined {
const parentData = <IPackageRootNodeData> this._rootNode.nodeData;
let contextValue: string = Explorer.ContextValueType.Package;
if (parentData.entryKind === PackageRootKind.K_SOURCE || parentData.kind === NodeKind.Project) {
return `${Explorer.ContextValueType.Package}+source`;
contextValue += "+source";
} else if (parentData.entryKind === PackageRootKind.K_BINARY) {
return `${Explorer.ContextValueType.Package}+binary`;
contextValue += "+binary";
}
return undefined;
if (isTest(parentData)) {
contextValue += "+test";
}
return contextValue;
}
}
25 changes: 17 additions & 8 deletions src/views/packageRootNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Jdtls } from "../java/jdtls";
import { INodeData, NodeKind } from "../java/nodeData";
import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData";
import { Settings } from "../settings";
import { isTest } from "../utility";
import { ContainerNode } from "./containerNode";
import { DataNode } from "./dataNode";
import { ExplorerNode } from "./explorerNode";
Expand Down Expand Up @@ -45,7 +46,7 @@ export class PackageRootNode extends DataNode {
result.push(new FolderNode(data, this, this._project, this));
} else if (data.kind === NodeKind.PrimaryType) {
if (data.metaData && data.metaData[PrimaryTypeNode.K_TYPE_KIND]) {
result.push(new PrimaryTypeNode(data, this));
result.push(new PrimaryTypeNode(data, this, this));
}
}
});
Expand All @@ -64,20 +65,28 @@ export class PackageRootNode extends DataNode {

protected get contextValue(): string {
const data = <IPackageRootNodeData>this.nodeData;
let contextValue: string;
if (data.entryKind === PackageRootKind.K_BINARY) {
let contextValue: string = Explorer.ContextValueType.Jar;
contextValue = Explorer.ContextValueType.Jar;
const parent = <ContainerNode>this.getParent();
if (parent.path?.startsWith("REFERENCED_LIBRARIES_PATH")) {
contextValue += "+referencedLibrary";
}
return contextValue;
} else if (resourceRoots.includes(this._nodeData.name)) {
// APIs in JDT does not have a consistent result telling whether a package root
// is a source root or resource root, so we hard code some common resources root
// here as a workaround.
return `${Explorer.ContextValueType.PackageRoot}+resource`;
} else {
return `${Explorer.ContextValueType.PackageRoot}+source`;
contextValue = Explorer.ContextValueType.PackageRoot;
if (isTest(data)) {
contextValue += "+test";
}
if (resourceRoots.includes(this._nodeData.name)) {
// APIs in JDT does not have a consistent result telling whether a package root
// is a source root or resource root, so we hard code some common resources root
// here as a workaround.
contextValue += "+resource";
} else {
contextValue += "+source";
}
return contextValue;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/views/projectNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class ProjectNode extends DataNode {
// For invisible project with empty named package root with a default package,
// types will be the project node's children
if (data.metaData && data.metaData[PrimaryTypeNode.K_TYPE_KIND]) {
result.push(new PrimaryTypeNode(data, this));
result.push(new PrimaryTypeNode(data, this, undefined));
}
}
});
Expand Down
88 changes: 67 additions & 21 deletions test/suite/contextValue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,78 +8,99 @@ import { ContainerNode, FileNode, FolderNode, INodeData, NodeKind, PackageNode,

// tslint:disable: only-arrow-functions
// tslint:disable: no-object-literal-type-assertion

/**
* This suite is to test the context value of different nodes in the explorer,
* Users can register their commands to the nodes by writing RegExp to match the metadata.
* More details, please see: https://github.com/microsoft/vscode-java-dependency/wiki/Register-Command-onto-the-Nodes-of-Project-View
*/
suite("Context Value Tests", () => {

test("test workspace node", async function() {
assert.equal((await workspace.getTreeItem()).contextValue, "java:workspaceFolder+uri");
assert.ok(/java:workspaceFolder(?=.*?\b\+uri\b)/.test((await workspace.getTreeItem()).contextValue || ""));
});

test("test Maven project node", async function() {
assert.equal((await mavenProject.getTreeItem()).contextValue, "java:project+java+maven+uri");
assert.ok(/java:project(?=.*?\b\+java\b)(?=.*?\b\+maven\b)(?=.*?\b\+uri\b)/.test((await mavenProject.getTreeItem()).contextValue || ""));
});

test("test Gradle project node", async function() {
assert.equal((await gradleProject.getTreeItem()).contextValue, "java:project+java+gradle+uri");
assert.ok(/java:project(?=.*?\b\+java\b)(?=.*?\b\+gradle\b)(?=.*?\b\+uri\b)/.test((await gradleProject.getTreeItem()).contextValue || ""));
});

test("test JRE container node", async function() {
assert.equal((await jreContainer.getTreeItem()).contextValue, "java:container+jre+uri");
assert.ok(/java:container(?=.*?\b\+jre\b)(?=.*?\b\+uri\b)/.test((await jreContainer.getTreeItem()).contextValue || ""));
});

test("test Maven container node", async function() {
assert.equal((await mavenContainer.getTreeItem()).contextValue, "java:container+maven+uri");
assert.ok(/java:container(?=.*?\b\+maven\b)(?=.*?\b\+uri\b)/.test((await mavenContainer.getTreeItem()).contextValue || ""));
});

test("test Gradle container node", async function() {
assert.equal((await gradleContainer.getTreeItem()).contextValue, "java:container+gradle+uri");
assert.ok(/java:container(?=.*?\b\+gradle\b)(?=.*?\b\+uri\b)/.test((await gradleContainer.getTreeItem()).contextValue || ""));
});

test("test Referenced Libraries container node", async function() {
assert.equal((await referencedLibrariesContainer.getTreeItem()).contextValue, "java:container+referencedLibrary+uri");
assert.ok(/java:container(?=.*?\b\+referencedLibrary\b)(?=.*?\b\+uri\b)/
.test((await referencedLibrariesContainer.getTreeItem()).contextValue || ""));
});

test("test source root node", async function() {
assert.equal((await sourceRoot.getTreeItem()).contextValue, "java:packageRoot+source+uri");
assert.ok(/java:packageRoot(?=.*?\b\+source\b)(?=.*?\b\+uri\b)/.test((await sourceRoot.getTreeItem()).contextValue || ""));
});

test("test test-source root node", async function() {
assert.ok(/java:packageRoot(?=.*?\b\+source\b)(?=.*?\b\+uri\b)(?=.*?\b\+test\b)/
.test((await testSourceRoot.getTreeItem()).contextValue || ""));
});

test("test resource root node", async function() {
assert.equal((await resourceRoot.getTreeItem()).contextValue, "java:packageRoot+resource+uri");
assert.ok(/java:packageRoot(?=.*?\b\+resource\b)(?=.*?\b\+uri\b)/.test((await resourceRoot.getTreeItem()).contextValue || ""));
});

test("test dependency jar node", async function() {
assert.equal((await dependencyJar.getTreeItem()).contextValue, "java:jar+uri");
assert.ok(/java:jar(?=.*?\b\+uri\b)/.test((await dependencyJar.getTreeItem()).contextValue || ""));
});

test("test referenced library jar node", async function() {
assert.equal((await referencedLibraryJar.getTreeItem()).contextValue, "java:jar+referencedLibrary+uri");
assert.ok(/java:jar(?=.*?\b\+referencedLibrary\b)(?=.*?\b\+uri\b)/.test((await referencedLibraryJar.getTreeItem()).contextValue || ""));
});

test("test source package node", async function() {
assert.ok(/java:package(?=.*?\b\+source\b)(?=.*?\b\+uri\b)/.test((await sourcePackage.getTreeItem()).contextValue || ""));
});

test("test source package node", async function() {
assert.equal((await sourcePackage.getTreeItem()).contextValue, "java:package+source+uri");
assert.ok(/java:package(?=.*?\b\+source\b)(?=.*?\b\+test\b)(?=.*?\b\+uri\b)/
.test((await testSourcePackage.getTreeItem()).contextValue || ""));
});

test("test binary package node", async function() {
assert.equal((await binaryPackage.getTreeItem()).contextValue, "java:package+binary+uri");
assert.ok(/java:package(?=.*?\b\+binary\b)(?=.*?\b\+uri\b)/.test((await binaryPackage.getTreeItem()).contextValue || ""));
});

test("test file node", async function() {
assert.equal((await file.getTreeItem()).contextValue, "java:file+uri");
assert.ok(/java:file(?=.*?\b\+uri\b)/.test((await file.getTreeItem()).contextValue || ""));
});

test("test class type node", async function() {
assert.equal((await classType.getTreeItem()).contextValue, "java:type+class+uri");
assert.ok(/java:type(?=.*?\b\+class\b)(?=.*?\b\+uri\b)/.test((await classType.getTreeItem()).contextValue || ""));
});

test("test test-class type node", async function() {
assert.ok(/java:type(?=.*?\b\+class\b)(?=.*?\b\+test\b)(?=.*?\b\+uri\b)/.test((await testClassType.getTreeItem()).contextValue || ""));
});

test("test enum type node", async function() {
assert.equal((await enumType.getTreeItem()).contextValue, "java:type+enum+uri");
assert.ok(/java:type(?=.*?\b\+enum\b)(?=.*?\b\+uri\b)/.test((await enumType.getTreeItem()).contextValue || ""));
});

test("test interface type node", async function() {
assert.equal((await interfaceType.getTreeItem()).contextValue, "java:type+interface+uri");
assert.ok(/java:type(?=.*?\b\+interface\b)(?=.*?\b\+uri\b)/.test((await interfaceType.getTreeItem()).contextValue || ""));
});

test("test folder node", async function() {
assert.equal((await folder.getTreeItem()).contextValue, "java:folder+uri");
assert.ok(/java:folder(?=.*?\b\+uri\b)/.test((await folder.getTreeItem()).contextValue || ""));
});
});

Expand Down Expand Up @@ -143,6 +164,16 @@ const sourceRoot: PackageRootNode = new PackageRootNode({
entryKind: PackageRootKind.K_SOURCE,
} as INodeData, mavenContainer, mavenProject);

const testSourceRoot: PackageRootNode = new PackageRootNode({
name: "src/main/java",
uri: Uri.file(__dirname).toString(),
kind: NodeKind.PackageRoot,
entryKind: PackageRootKind.K_SOURCE,
metaData: {
test: "true",
},
} as INodeData, mavenContainer, mavenProject);

const resourceRoot: PackageRootNode = new PackageRootNode({
name: "src/main/resources",
uri: Uri.file(__dirname).toString(),
Expand Down Expand Up @@ -170,6 +201,12 @@ const sourcePackage: PackageNode = new PackageNode({
kind: NodeKind.Package,
}, sourceRoot, mavenProject, sourceRoot);

const testSourcePackage: PackageNode = new PackageNode({
name: "com.microsoft.java",
uri: Uri.file(__dirname).toString(),
kind: NodeKind.Package,
}, testSourceRoot, mavenProject, testSourceRoot);

const binaryPackage: PackageNode = new PackageNode({
name: "junit",
uri: Uri.file(__dirname).toString(),
Expand All @@ -189,7 +226,16 @@ const classType: PrimaryTypeNode = new PrimaryTypeNode({
metaData: {
TypeKind: TypeKind.Class,
},
}, sourcePackage);
}, sourcePackage, sourceRoot);

const testClassType: PrimaryTypeNode = new PrimaryTypeNode({
name: "App",
uri: Uri.file(__dirname).toString(),
kind: NodeKind.PrimaryType,
metaData: {
TypeKind: TypeKind.Class,
},
}, testSourcePackage, testSourceRoot);

const enumType: PrimaryTypeNode = new PrimaryTypeNode({
name: "LanguageServerMode",
Expand All @@ -198,7 +244,7 @@ const enumType: PrimaryTypeNode = new PrimaryTypeNode({
metaData: {
TypeKind: TypeKind.Enum,
},
}, sourcePackage);
}, sourcePackage, sourceRoot);

const interfaceType: PrimaryTypeNode = new PrimaryTypeNode({
name: "Controller",
Expand All @@ -207,7 +253,7 @@ const interfaceType: PrimaryTypeNode = new PrimaryTypeNode({
metaData: {
TypeKind: TypeKind.Interface,
},
}, sourcePackage);
}, sourcePackage, sourceRoot);

const folder: FolderNode = new FolderNode({
name: "static",
Expand Down
3 changes: 2 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"log",
"error"
],
"no-namespace": false
"no-namespace": false,
"prefer-conditional-expression": false
}
}

0 comments on commit 0ec8146

Please sign in to comment.