Skip to content

Commit 537aef0

Browse files
author
Oleksandr Dzhychko
committed
fix(vue-model-api): expose errors in references correctly
1 parent edfe638 commit 537aef0

File tree

4 files changed

+79
-51
lines changed

4 files changed

+79
-51
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { watchEffect } from "vue";
2+
import { useModelClient } from "./useModelClient";
3+
4+
test("test client connection error is exposed", (done) => {
5+
const { error } = useModelClient("anURL", () => {
6+
return Promise.reject("A connection error.");
7+
});
8+
watchEffect(() => {
9+
if (error.value !== null) {
10+
expect(error.value).toBe("A connection error.");
11+
done();
12+
}
13+
});
14+
});

vue-model-api/src/useModelClient.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ type ClientJS = org.modelix.model.client2.ClientJS;
1919
* Defaults to connecting directly to the modelix model server under the given URL.
2020
*
2121
* @returns {Object} values Wrapper around diffrent returned values.
22-
* @returns {Ref<ClientJS>} values.client Reactive reference to a client.
22+
* @returns {Ref<ClientJS | null>} values.client Reactive reference to a client.
2323
* @returns {() => void} values.dispose A function to manually dispose the client.
2424
* @returns {Ref<unknown>} values.error Reactive reference to a client connection error.
2525
*/
2626
export function useModelClient(
2727
url: MaybeRefOrGetter<string>,
2828
getClient: (url: string) => Promise<ClientJS> = connectClient,
29-
) {
29+
): {
30+
client: Ref<ClientJS | null>;
31+
dispose: () => void;
32+
error: Ref<unknown>;
33+
} {
3034
let client: ClientJS | null = null;
3135
const clientRef: Ref<ClientJS | null> = shallowRef(client);
3236
const errorRef: Ref<unknown> = shallowRef(null);
@@ -52,7 +56,7 @@ export function useModelClient(
5256
}
5357
},
5458
(reason, isResultOfLastStartedPromise) => {
55-
if (!isResultOfLastStartedPromise) {
59+
if (isResultOfLastStartedPromise) {
5660
errorRef.value = reason;
5761
}
5862
},

vue-model-api/src/useRootNode.test.ts

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,63 +9,69 @@ type ClientJS = org.modelix.model.client2.ClientJS;
99
type ChangeJS = org.modelix.model.client2.ChangeJS;
1010
const { loadModelsFromJson } = org.modelix.model.client2;
1111

12-
const root = {
13-
root: {},
14-
};
15-
16-
function getClient(_url: string): Promise<ClientJS> {
17-
return Promise.resolve(new TestClientJS() as unknown as ClientJS);
18-
}
12+
test("test branch connects", (done) => {
13+
class SuccessfulBranchJS {
14+
public rootNode: INodeJS;
1915

20-
class TestBranchJS implements BranchJS {
21-
public disposed = false;
22-
public rootNode: INodeJS;
16+
constructor(branchId: string, changeCallback: (change: ChangeJS) => void) {
17+
const root = {
18+
root: {},
19+
};
2320

24-
constructor(branchId: string, changeCallback: (change: ChangeJS) => void) {
25-
this.rootNode = loadModelsFromJson([JSON.stringify(root)], changeCallback);
26-
this.rootNode.setPropertyValue("branchId", branchId);
21+
this.rootNode = loadModelsFromJson(
22+
[JSON.stringify(root)],
23+
changeCallback,
24+
);
25+
this.rootNode.setPropertyValue("branchId", branchId);
26+
}
2727
}
2828

29-
dispose(): void {
30-
this.disposed = true;
29+
class SuccessfulClientJS {
30+
connectBranch(
31+
_repositoryId: string,
32+
branchId: string,
33+
changeCallback: (change: ChangeJS) => void,
34+
): Promise<BranchJS> {
35+
return Promise.resolve(
36+
new SuccessfulBranchJS(branchId, changeCallback) as BranchJS,
37+
);
38+
}
3139
}
3240

33-
// @ts-ignore It is fine to be undefined, because we do not pass it back to Kotlin code.
34-
__doNotUseOrImplementIt: undefined;
35-
}
41+
const { client } = useModelClient("anURL", () =>
42+
Promise.resolve(new SuccessfulClientJS() as ClientJS),
43+
);
3644

37-
class TestClientJS implements ClientJS {
38-
public disposed = false;
45+
const { rootNode } = useRootNode(client, "aRepository", "aBranch");
3946

40-
dispose(): void {
41-
this.disposed = true;
42-
}
43-
connectBranch(
44-
_repositoryId: string,
45-
branchId: string,
46-
changeCallback: (change: ChangeJS) => void,
47-
): Promise<BranchJS> {
48-
return Promise.resolve(
49-
new TestBranchJS(branchId, changeCallback) as unknown as BranchJS,
50-
);
51-
}
52-
fetchBranches(_repositoryId: string): Promise<string[]> {
53-
throw new Error("Method not implemented.");
54-
}
55-
fetchRepositories(): Promise<string[]> {
56-
throw new Error("Method not implemented.");
47+
watchEffect(() => {
48+
if (rootNode.value !== null) {
49+
expect(rootNode.value.getPropertyValue("branchId")).toBe("aBranch");
50+
done();
51+
}
52+
});
53+
});
54+
55+
test("test branch connection error is exposed", (done) => {
56+
class FailingClientJS {
57+
connectBranch(
58+
_repositoryId: string,
59+
_branchId: string,
60+
_changeCallback: (change: ChangeJS) => void,
61+
): Promise<BranchJS> {
62+
return Promise.reject("Could not connect branch.");
63+
}
5764
}
5865

59-
// @ts-ignore It is fine to be undefined, because we do not pass it back to Kotlin code.
60-
__doNotUseOrImplementIt: undefined;
61-
}
66+
const { client } = useModelClient("anURL", () =>
67+
Promise.resolve(new FailingClientJS() as ClientJS),
68+
);
69+
70+
const { error } = useRootNode(client, "aRepository", "aBranch");
6271

63-
test("test branch connects", (done) => {
64-
const { client } = useModelClient("anURL", getClient);
65-
const { rootNode } = useRootNode(client, "aRepository", "aBranch");
6672
watchEffect(() => {
67-
if (rootNode.value !== null) {
68-
expect(rootNode.value.getPropertyValue("branchId")).toBe("aBranch");
73+
if (error.value !== null) {
74+
expect(error.value).toBe("Could not connect branch.");
6975
done();
7076
}
7177
});

vue-model-api/src/useRootNode.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,19 @@ type ChangeJS = org.modelix.model.client2.ChangeJS;
2525
* @param branchId - Reactive reference of a branchId in the repository of the model server.
2626
*
2727
* @returns {Object} values Wrapper around diffrent returned values.
28-
* @returns {Ref<ClientJS>} values.rootNode Reactive reference to a reactive root node.
28+
* @returns {Ref<INodeJS | null>} values.rootNode Reactive reference to a reactive root node.
2929
* @returns {() => void} values.dispose A function to manually dispose the root node.
3030
* @returns {Ref<unknown>} values.error Reactive reference to a connection error.
3131
*/
3232
export function useRootNode(
3333
client: MaybeRefOrGetter<ClientJS | null>,
3434
repositoryId: MaybeRefOrGetter<string | null>,
3535
branchId: MaybeRefOrGetter<string | null>,
36-
) {
36+
): {
37+
rootNode: Ref<INodeJS | null>;
38+
dispose: () => void;
39+
error: Ref<unknown>;
40+
} {
3741
let branch: BranchJS | null = null;
3842
const rootNodeRef: Ref<INodeJS | null> = shallowRef(null);
3943
const errorRef: Ref<unknown> = shallowRef(null);
@@ -83,7 +87,7 @@ export function useRootNode(
8387
}
8488
},
8589
(reason, isResultOfLastStartedPromise) => {
86-
if (!isResultOfLastStartedPromise) {
90+
if (isResultOfLastStartedPromise) {
8791
errorRef.value = reason;
8892
}
8993
},

0 commit comments

Comments
 (0)