Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explore gxformat2 schema support #52

Merged
merged 50 commits into from
Oct 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9dcda94
Add yaml loader for webpack
davelopez Jul 3, 2022
385e097
Add gxformat2 v19_09 schema
davelopez Jul 3, 2022
e52ea6f
Add `getPathFromNode` to NodeManager
davelopez Jul 18, 2022
82dd4a8
Add `getNodeFromOffset` to YamlDocument
davelopez Jul 18, 2022
be95abe
WIP: explore schema parsing (experimental)
davelopez Jul 18, 2022
84f27a0
Add hover service for gxformat2 schema
davelopez Jul 18, 2022
242d521
Fix hover provider content rendering
davelopez Jul 18, 2022
6c7a365
WIP: continue exploring schema parsing
davelopez Jul 20, 2022
f735194
Add more sample workflows for testing
davelopez Jul 21, 2022
379c63c
Add load support for yaml in jest tests
davelopez Jul 21, 2022
3a2ea2f
Fix jest config for debugging
davelopez Jul 22, 2022
afc7e73
Add experimental SchemaNodeResolver
davelopez Jul 22, 2022
eb15c16
Add some tests for schema handling
davelopez Jul 22, 2022
c482143
Cleanup schema imports
davelopez Jul 22, 2022
0a6e12e
Refactor hoverService
davelopez Jul 22, 2022
7dd6c2c
Define root node in schema definitions
davelopez Jul 24, 2022
641fe70
Refactor NodeManager.getNodeFromOffset
davelopez Jul 24, 2022
ce622c2
Adapt NodeManager.getPathFromNode
davelopez Jul 24, 2022
34344be
Fix debug hover information
davelopez Jul 25, 2022
eb3ff4e
Refactor YAMLDocument `getNodeFromOffset`
davelopez Jul 28, 2022
c9a5635
Add tests for `getNodeFromOffset`
davelopez Jul 31, 2022
282f8f1
Add basic completion service
davelopez Jul 31, 2022
88f2adc
Add typeName to all schema field types
davelopez Aug 26, 2022
4ba147a
Implement basic schema validation service
davelopez Aug 26, 2022
c4c7c6f
Add schema validation to workflow validation
davelopez Aug 26, 2022
bbad6cb
Support specialization in schema types
davelopez Aug 27, 2022
4371f12
Skip validation on simple matching types
davelopez Aug 27, 2022
64ff315
Add mapping type matching
davelopez Aug 28, 2022
8779648
Refactor schema validation service
davelopez Aug 30, 2022
8adf724
Change toString in ASTNodeImpl to display internalNode
davelopez Sep 2, 2022
9aac84c
Add WorkflowValidationService
davelopez Sep 2, 2022
bbce6c8
Refactor validation services
davelopez Sep 3, 2022
df74ec5
Refactor schema loader
davelopez Sep 4, 2022
a45cc52
Fix unit tests after adding specialization support
davelopez Sep 4, 2022
47c8d4c
Remove unused children property
davelopez Sep 5, 2022
d92175e
Add support for multi type array definitions in schema
davelopez Sep 6, 2022
8441e31
Add some unit tests for schema definitions
davelopez Sep 6, 2022
e26f71e
Fix array with single type matching
davelopez Sep 7, 2022
695323b
Add support for enums symbol extensions
davelopez Sep 21, 2022
1da7935
Add support for primitives and objects detection
davelopez Oct 3, 2022
b382704
Add more tests for schema definitions
davelopez Oct 3, 2022
f3df284
Split e2e tests
davelopez Oct 3, 2022
5eccc95
Move schema tests to integration
davelopez Oct 3, 2022
65f7bb9
Setup jest to detect all kinds of tests
davelopez Oct 3, 2022
544b85c
Reduce a bit e2e tests execution time
davelopez Oct 3, 2022
1397b7b
Fix getNodeFromOffset in some contexts
davelopez Oct 4, 2022
c6c0dc5
Enhance auto-completion
davelopez Oct 4, 2022
ab87e96
Slightly increase activation wait time in e2e tests
davelopez Oct 4, 2022
0d49a9a
Add getAllPropertyNodesByName to NodeManager
davelopez Oct 7, 2022
4829c80
Validate subworkflows steps too
davelopez Oct 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions client/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html

/* eslint-disable @typescript-eslint/no-var-requires */
const { compilerOptions } = require("./tsconfig.json");

module.exports = {
preset: "ts-jest",
globals: {
"ts-jest": {
tsconfig: "../tsconfig.json",
tsconfig: compilerOptions,
},
},
// The glob patterns Jest uses to detect test files
testMatch: ["**/__tests__/*.+(ts|tsx|js)", "**/unit/*.test.ts"],
testMatch: ["**/__tests__/*.+(ts|tsx|js)", "**/*.test.ts"],

// An array of file extensions your modules use
moduleFileExtensions: ["ts", "tsx", "js"],
Expand Down
74 changes: 0 additions & 74 deletions client/tests/e2e/suite/extension.e2e.ts

This file was deleted.

73 changes: 73 additions & 0 deletions client/tests/e2e/suite/extension.ga.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as vscode from "vscode";
import * as path from "path";
import * as assert from "assert";
import { beforeEach } from "mocha";
import {
activateAndOpenInEditor,
getDocUri,
closeAllEditors,
openDocument,
sleep,
assertDiagnostics,
updateSettings,
resetSettings,
waitForDiagnostics,
} from "./helpers";

suite("Native (JSON) Workflows", () => {
teardown(closeAllEditors);
suite("Commands Tests", () => {
test("Clean workflow command removes non-essential properties", async () => {
const dirtyDocUri = getDocUri(path.join("json", "clean", "wf_01_dirty.ga"));
const cleanDocUri = getDocUri(path.join("json", "clean", "wf_01_clean.ga"));
const { document } = await activateAndOpenInEditor(dirtyDocUri);
await sleep(500); // Wait for extension to fully activate... yes Windows CI I'm looking at you...
const dirtyDoc = document.getText();
await vscode.commands.executeCommand("galaxy-workflows.cleanWorkflow");
await sleep(500); // Wait for command to apply changes
const actualCleanJson = document.getText();
assert.notEqual(dirtyDoc, actualCleanJson);
const expectedCleanDocument = await openDocument(cleanDocUri);
const expectedCleanJson = expectedCleanDocument.getText();
assert.strictEqual(actualCleanJson, expectedCleanJson);
});
});

suite("Validation Tests", () => {
beforeEach(async () => {
await resetSettings();
});
test("Changing validation profile shows custom diagnostics", async () => {
const docUri = getDocUri(path.join("json", "validation", "test_wf_03.ga"));
await activateAndOpenInEditor(docUri);
await assertDiagnostics(docUri, []); // Expect no issues

// Change to stricter validation profile
await updateSettings("validation.profile", "iwc");
await waitForDiagnostics(docUri);
await assertDiagnostics(docUri, [
{
message: 'Missing property "release".',
range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 1)),
severity: vscode.DiagnosticSeverity.Error,
},
{
message: "Missing label in workflow output.",
range: new vscode.Range(new vscode.Position(16, 16), new vscode.Position(19, 17)),
severity: vscode.DiagnosticSeverity.Error,
},
{
message: "Missing label in workflow output.",
range: new vscode.Range(new vscode.Position(20, 16), new vscode.Position(23, 17)),
severity: vscode.DiagnosticSeverity.Error,
},
]);

await resetSettings();
await waitForDiagnostics(docUri);
await assertDiagnostics(docUri, []); // Expect no issues
});
});
});
45 changes: 45 additions & 0 deletions client/tests/e2e/suite/extension.gxformat2.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as vscode from "vscode";
import * as path from "path";
import * as assert from "assert";
import { beforeEach } from "mocha";
import {
activateAndOpenInEditor,
getDocUri,
closeAllEditors,
assertDiagnostics,
resetSettings,
waitForDiagnostics,
} from "./helpers";

suite("Format2 (YAML) Workflows", () => {
teardown(closeAllEditors);
suite("Validation Tests", () => {
beforeEach(async () => {
await resetSettings();
});
test("Missing required fields return diagnostics", async () => {
const docUri = getDocUri(path.join("yaml", "validation", "test_wf_00.gxwf.yml"));
await activateAndOpenInEditor(docUri);
await waitForDiagnostics(docUri);
await assertDiagnostics(docUri, [
{
message: "The 'steps' field is required.",
range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 21)),
severity: vscode.DiagnosticSeverity.Error,
},
{
message: "The 'inputs' field is required.",
range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 21)),
severity: vscode.DiagnosticSeverity.Error,
},
{
message: "The 'outputs' field is required.",
range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 21)),
severity: vscode.DiagnosticSeverity.Error,
},
]);
});
});
});
15 changes: 13 additions & 2 deletions client/tests/e2e/suite/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,24 @@ export async function openDocument(docUri: vscode.Uri): Promise<vscode.TextDocum
export async function activateAndOpenInEditor(docUri: vscode.Uri): Promise<DocumentEditor> {
await activate();
const documentEditor = await openDocumentInEditor(docUri);
await sleep(2000); // Wait for server activation
return documentEditor;
}

export async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}

export async function waitForDiagnostics(docUri: vscode.Uri, timeoutInMilliseconds = 2000): Promise<void> {
const waitMilliseconds = 100;
let waitTimeout = timeoutInMilliseconds;
let diagnostics = vscode.languages.getDiagnostics(docUri);
while (waitTimeout > 0 && !diagnostics.length) {
await sleep(waitMilliseconds);
waitTimeout -= waitMilliseconds;
diagnostics = vscode.languages.getDiagnostics(docUri);
}
}

export const getDocPath = (filePath: string): string => {
return path.resolve(__dirname, path.join("..", "..", "..", "..", "test-data", filePath));
};
Expand Down Expand Up @@ -92,5 +102,6 @@ export async function updateSettings(setting: string, value: unknown): Promise<v
export async function resetSettings(): Promise<void> {
const configuration = vscode.workspace.getConfiguration("galaxyWorkflows");
await configuration.update("cleaning.cleanableProperties", undefined, true);
return configuration.update("validation.profile", undefined, true);
await configuration.update("validation.profile", undefined, true);
return sleep(500); // Wait for settings to be applied
}
15 changes: 12 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html

/* eslint-disable @typescript-eslint/no-var-requires */
const { pathsToModuleNameMapper } = require("ts-jest");
const { compilerOptions } = require("./tsconfig.json");

module.exports = {
preset: "ts-jest",
globals: {
"ts-jest": {
tsconfig: "tsconfig.json",
tsconfig: compilerOptions,
},
},
// The glob patterns Jest uses to detect test files
testMatch: ["**/__tests__/*.+(ts|tsx|js)", "**/unit/*.test.ts"],
testMatch: ["**/__tests__/*.+(ts|tsx|js)", "**/*.test.ts"],

// An array of file extensions your modules use
moduleFileExtensions: ["ts", "tsx", "js"],
moduleFileExtensions: ["ts", "tsx", "js", "yaml"],
transform: {
// ... other transforms ...
"\\.yaml$": "jest-transform-yaml",
},
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: "<rootDir>/" }),
};
Loading