@finos/legend-studio
Version:
206 lines (186 loc) • 6.35 kB
text/typescript
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
type AtomicTest,
type Testable,
type TestAssertion,
type TestResult,
TestPassed,
AtomicTestId,
RunTestsTestableInput,
TestSuite,
} from '@finos/legend-graph';
import {
type GeneratorFn,
assertErrorThrown,
assertTrue,
guaranteeNonNullable,
ActionState,
addUniqueEntry,
deleteEntry,
} from '@finos/legend-shared';
import { action, makeObservable, observable } from 'mobx';
import type { EditorStore } from '../../../EditorStore.js';
import { atomicTest_addAssertion } from '../../../graphModifier/Testable_GraphModifierHelper.js';
import { createEmptyEqualToJsonAssertion } from '../../../shared/testable/TestableUtils.js';
import { TESTABLE_RESULT } from '../../../sidebar-state/testable/GlobalTestRunnerState.js';
import {
TestAssertionEditorState,
TEST_ASSERTION_TAB,
} from './TestAssertionState.js';
export class TestableTestResultState {
readonly editorStore: EditorStore;
readonly testState: TestableTestEditorState;
result: TestResult | undefined;
constructor(testState: TestableTestEditorState, editorStore: EditorStore) {
makeObservable(this, {
result: observable,
setResult: action,
});
this.editorStore = editorStore;
this.testState = testState;
}
setResult(val: TestResult | undefined): void {
this.result = val;
}
}
export enum TESTABLE_TEST_TAB {
SETUP = 'SETUP',
ASSERTIONS = 'ASSERTIONS',
}
export class TestableTestEditorState {
readonly editorStore: EditorStore;
testable: Testable;
test: AtomicTest;
selectedAsertionState: TestAssertionEditorState | undefined;
assertionEditorStates: TestAssertionEditorState[] = [];
selectedTab = TESTABLE_TEST_TAB.ASSERTIONS;
assertionToRename: TestAssertion | undefined;
runningTestAction = ActionState.create();
testResultState: TestableTestResultState;
isReadOnly: boolean;
constructor(
testable: Testable,
test: AtomicTest,
isReadOnly: boolean,
editorStore: EditorStore,
) {
this.editorStore = editorStore;
this.test = test;
this.testable = testable;
this.testResultState = new TestableTestResultState(this, this.editorStore);
this.assertionEditorStates = test.assertions.map(
(assertion) =>
new TestAssertionEditorState(this.editorStore, assertion, this),
);
this.selectedAsertionState = this.assertionEditorStates[0];
this.isReadOnly = isReadOnly;
}
setSelectedTab(val: TESTABLE_TEST_TAB): void {
this.selectedTab = val;
}
setAssertionToRename(assertion: TestAssertion | undefined): void {
this.assertionToRename = assertion;
}
addAssertion(): void {
const assertion = createEmptyEqualToJsonAssertion(this.test);
atomicTest_addAssertion(this.test, assertion);
const assertionState = new TestAssertionEditorState(
this.editorStore,
assertion,
this,
);
addUniqueEntry(this.assertionEditorStates, assertionState);
this.selectedAsertionState = assertionState;
this.resetResult();
}
deleteAssertion(assertionState: TestAssertionEditorState): void {
deleteEntry(this.test.assertions, assertionState.assertion);
deleteEntry(this.assertionEditorStates, assertionState);
if (this.selectedAsertionState === assertionState) {
this.selectedAsertionState = this.assertionEditorStates[0];
}
}
openAssertion(val: TestAssertion): void {
const state = this.assertionEditorStates.find((a) => a.assertion === val);
if (state) {
this.selectedAsertionState = state;
}
}
*runTest(): GeneratorFn<void> {
try {
this.resetResult();
this.runningTestAction.inProgress();
const input = new RunTestsTestableInput(this.testable);
const suite =
this.test.__parent instanceof TestSuite
? this.test.__parent
: undefined;
input.unitTestIds.push(new AtomicTestId(suite, this.test));
const testResults =
(yield this.editorStore.graphManagerState.graphManager.runTests(
[input],
this.editorStore.graphManagerState.graph,
)) as TestResult[];
const result = guaranteeNonNullable(testResults[0]);
assertTrue(
result.testable === this.testable &&
result.atomicTestId.atomicTest === this.test,
'Unexpected test result',
);
this.handleTestResult(result);
this.runningTestAction.complete();
} catch (error) {
assertErrorThrown(error);
this.editorStore.applicationStore.notifyError(
`Error running test: ${error.message}`,
);
this.runningTestAction.fail();
}
}
resetResult(): void {
this.testResultState.setResult(undefined);
this.assertionEditorStates.forEach((assertionState) =>
assertionState.assertionResultState.setTestResult(undefined),
);
}
handleTestResult(testResult: TestResult): void {
this.testResultState.setResult(testResult);
this.assertionEditorStates.forEach((assertionState) => {
assertionState.assertionResultState.setTestResult(testResult);
assertionState.setSelectedTab(TEST_ASSERTION_TAB.ASSERTION_RESULT);
});
}
get assertionCount(): number {
return this.assertionEditorStates.length;
}
get assertionPassed(): number {
if (this.testResultState.result instanceof TestPassed) {
return this.assertionCount;
}
return this.assertionEditorStates.filter(
(state) => state.assertionResultState.result === TESTABLE_RESULT.PASSED,
).length;
}
get assertionFailed(): number {
if (this.testResultState.result instanceof TestPassed) {
return 0;
}
return this.assertionEditorStates.filter(
(state) => state.assertionResultState.result !== TESTABLE_RESULT.PASSED,
).length;
}
}