Skip to content

Commit

Permalink
Merge pull request #2777 from zowe/feat/fs-provider
Browse files Browse the repository at this point in the history
feat(v3): FileSystemProvider implementation for Data Sets, USS and Jobs
  • Loading branch information
JillieBeanSim authored Apr 19, 2024
2 parents 77a78fd + 3eac1a3 commit 505e6c4
Show file tree
Hide file tree
Showing 136 changed files with 10,206 additions and 6,472 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ testProfileData.ts
results
*.log
npm-shrinkwrap.json
tsconfig.tsbuildinfo
**/*.tsbuildinfo
vscode-extension-for-zowe*.vsix
.vscode/settings.json
.vscode/*.env
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"devDependencies": {
"@types/jest": "^29.2.3",
"@types/mocha": "^10.0.1",
"@types/node": "^14.18.12",
"@types/node": "^18.19.14",
"@types/vscode": "^1.73.0",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
Expand Down
10 changes: 10 additions & 0 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t
- The new `getJobsByParameters` API is meant to replace `getJobsByOwnerAndPrefix`, and it adds new capabilities such as querying by status and limiting the amount of returned jobs.
- **Breaking:** Removed string as a return type of the `uploadFromBuffer` method, since the z/OSMF API has been fixed to return a response object that includes an etag. [#2785](https://github.com/zowe/zowe-explorer-vscode/issues/2785)
- Added `Commands` value to the `PersistenceSchemaEnum` enum for storing MVS, TSO, and USS command history. [#2788](https://github.com/zowe/zowe-explorer-vscode/issues/2788)
- Changed the type for the options parameter in the `getContents` function (`MainframeInteraction.IUss` and `MainframeInteraction.IMvs` interfaces) from `zosfiles.IDownloadOptions` to `zosfiles.IDownloadSingleOptions`. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- The type was changed to match the function's intended behavior (to get the contents of a **single** resource).
- Added the `getEncoding` optional function to the `IZoweDatasetTreeNode` and `IZoweUSSTreeNode` interfaces. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- **Breaking:** Removed the `encoding` property from the `IZoweUSSTreeNode` interface in favor of the new `getEncoding` function. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- Added an optional function `nodeDataChanged` to the `IZoweTree` interface to signal an event when a tree node needs updated. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- Added the optional `vscode.DragAndDropController` interface to the `IZoweTree` interface to allow Zowe tree views to support drag and drop. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- Added a `ZoweScheme` enum to expose the core FileSystemProvider schemes for USS files, data sets and jobs. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- Added optional function `move` to the `MainframeInteraction.IUss` interface to move USS folders/files from one path to another. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- Added the `buildUniqueSpoolName` function to build spool names for Zowe resource URIs and VS Code editor tabs. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)
- Added the `isNodeInEditor` function to determine whether a tree node is open in the editor. [#2207](https://github.com/zowe/zowe-explorer-vscode/issues/2207)

### Bug fixes

Expand Down
138 changes: 138 additions & 0 deletions packages/zowe-explorer-api/__mocks__/mockUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/**
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*
*/

// Used for the MockedProperty class (polyfills for Symbol.{asyncDispose, dispose})
require("disposablestack/auto");

// Idea is borrowed from: https://github.com/kulshekhar/ts-jest/blob/master/src/util/testing.ts
export const mocked = <T extends (..._args: any[]) => any>(fn: T): jest.Mock<ReturnType<T>> => fn as any;

enum MockedValueType {
Primitive,
Ref,
Function,
}

/**
* _Please use this when possible instead of Object.defineProperty!_
*
* A safer approach to "mocking" the value for a property that cannot be easily mocked using Jest.\
* Uses TypeScript 5.2's Explicit Resource Management to restore the original value for the given object and property key.
*/
export class MockedProperty {
#key: PropertyKey;
#val: any;
#valType: MockedValueType;
#objRef: any;
#originalDescriptor?: PropertyDescriptor;

private initValueType() {
if (typeof this.#val === "function" || jest.isMockFunction(this.#val)) {
this.#valType = MockedValueType.Function;
} else if (typeof this.#val === "object" || Array.isArray(this.#val)) {
this.#valType = MockedValueType.Ref;
} else {
this.#valType = MockedValueType.Primitive;
}
}

constructor(object: any, key: PropertyKey, descriptor?: PropertyDescriptor, value?: any) {
if (object == null) {
throw new Error("Null or undefined object passed to MockedProperty");
}
this.#objRef = object;
this.#originalDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(object, key);

if (!value) {
this.#val = jest.fn();
this.#valType = MockedValueType.Function;
Object.defineProperty(object, key, {
value: this.#val,
configurable: true,
});
return;
}

const isValFn = typeof value === "function";

if (isValFn || (typeof descriptor?.value === "function" && value == null)) {
// wrap provided function around a Jest function, if needed
this.#val = jest.isMockFunction(value) ? value : jest.fn().mockImplementation(value);
} else {
this.#val = value;
}

this.initValueType();

Object.defineProperty(object, key, {
value: this.#val,
configurable: true,
});
}

[Symbol.dispose](): void {
const isObjValid = this.#objRef != null;
if (isObjValid && !this.#originalDescriptor) {
// didn't exist to begin with, just delete it
delete this.#objRef[this.#key];
return;
}

if (this.#valType === MockedValueType.Function && jest.isMockFunction(this.#val)) {
this.#val.mockRestore();
}

if (isObjValid) {
Object.defineProperty(this.#objRef, this.#key, this.#originalDescriptor!);
}
}

public get mock() {
if (!jest.isMockFunction(this.#val)) {
throw Error("MockedValue.mock called, but mocked value is not a Jest function");
}

return this.#val;
}

public get value() {
return this.#val;
}

public valueAs<T>() {
return this.#val as T;
}
}

export function isMockedProperty(val: any): val is MockedProperty {
return "Symbol.dispose" in val;
}

export class MockCollection {
#obj: Record<string, MockedProperty | unknown>;

constructor(obj: Record<string, unknown>) {
this.#obj = obj;
}

[Symbol.dispose](): void {
for (const k of Object.keys(this.#obj)) {
const property = this.#obj[k];
if (isMockedProperty(property)) {
property[Symbol.dispose]();
}
}
}

public dispose() {
this[Symbol.dispose]();
}
}
Loading

0 comments on commit 505e6c4

Please sign in to comment.