@zthun/romulator-web 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/dist/assets/index-CtJiKvl7.js +52645 -0
- package/dist/favicon.ico +0 -0
- package/dist/index.html +12 -0
- package/dist/png/romulator-256x256.png +0 -0
- package/dist/systems/uk/megadrive-256x256.png +0 -0
- package/dist/systems/us/megadrive-256x256.png +0 -0
- package/dist/systems/us/nes-256x256.png +0 -0
- package/dist/systems/us/snes-256x256.png +0 -0
- package/index.html +12 -0
- package/package.json +48 -0
- package/public/favicon.ico +0 -0
- package/public/png/romulator-256x256.png +0 -0
- package/public/systems/uk/megadrive-256x256.png +0 -0
- package/public/systems/us/megadrive-256x256.png +0 -0
- package/public/systems/us/nes-256x256.png +0 -0
- package/public/systems/us/snes-256x256.png +0 -0
- package/src/app/app-avatar.tsx +8 -0
- package/src/app/app-title.tsx +10 -0
- package/src/app/app.tsx +41 -0
- package/src/environment/environment-service.mts +19 -0
- package/src/environment/environment.mts +29 -0
- package/src/index.tsx +14 -0
- package/src/menu/menu.cm.mts +60 -0
- package/src/menu/menu.spec.tsx +115 -0
- package/src/menu/menu.tsx +130 -0
- package/src/settings/setting-page.cm.mts +22 -0
- package/src/settings/setting-page.spec.tsx +154 -0
- package/src/settings/setting-page.tsx +83 -0
- package/src/settings/settings-page.cm.mts +18 -0
- package/src/settings/settings-page.spec.tsx +99 -0
- package/src/settings/settings-page.tsx +82 -0
- package/src/settings/settings-service.mts +38 -0
- package/src/systems/system-avatar-card.cm.mts +17 -0
- package/src/systems/system-avatar-card.tsx +41 -0
- package/src/systems/system-page.cm.mts +33 -0
- package/src/systems/system-page.spec.tsx +127 -0
- package/src/systems/system-page.tsx +48 -0
- package/src/systems/systems-page.cm.mts +39 -0
- package/src/systems/systems-page.spec.tsx +81 -0
- package/src/systems/systems-page.tsx +48 -0
- package/src/systems/systems-service.mts +65 -0
- package/src/systems/systems-service.spec.ts +144 -0
- package/tsconfig.json +10 -0
- package/vite.config.mts +9 -0
- package/vitest.config.mts +9 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useFashionTheme,
|
|
3
|
+
useParams,
|
|
4
|
+
ZAlert,
|
|
5
|
+
ZBreadcrumbsLocation,
|
|
6
|
+
ZStack,
|
|
7
|
+
ZSuspenseProgress,
|
|
8
|
+
} from "@zthun/fashion-boutique";
|
|
9
|
+
import { ZSizeFixed } from "@zthun/fashion-tailor";
|
|
10
|
+
import { cssJoinDefined, firstDefined } from "@zthun/helpful-fn";
|
|
11
|
+
import { isStateErrored, isStateLoading } from "@zthun/helpful-react";
|
|
12
|
+
import { ZRomulatorSystemAvatarCard } from "./system-avatar-card.js";
|
|
13
|
+
import { useSystem } from "./systems-service.mjs";
|
|
14
|
+
|
|
15
|
+
export function ZRomulatorSystemPage() {
|
|
16
|
+
const { id } = useParams();
|
|
17
|
+
const { error } = useFashionTheme();
|
|
18
|
+
const [system] = useSystem(firstDefined("", id));
|
|
19
|
+
|
|
20
|
+
const renderSystemInformation = () => {
|
|
21
|
+
if (isStateLoading(system)) {
|
|
22
|
+
return <ZSuspenseProgress height={ZSizeFixed.Large} />;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (isStateErrored(system)) {
|
|
26
|
+
return (
|
|
27
|
+
<ZAlert
|
|
28
|
+
fashion={error}
|
|
29
|
+
heading="Cannot load System"
|
|
30
|
+
message={system.message}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return <ZRomulatorSystemAvatarCard system={system} />;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<ZStack
|
|
40
|
+
gap={ZSizeFixed.Medium}
|
|
41
|
+
className={cssJoinDefined("ZRomulatorSystemPage-root")}
|
|
42
|
+
>
|
|
43
|
+
<ZBreadcrumbsLocation />
|
|
44
|
+
|
|
45
|
+
{renderSystemInformation()}
|
|
46
|
+
</ZStack>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ZCircusBy, ZCircusComponentModel } from "@zthun/cirque";
|
|
2
|
+
import {
|
|
3
|
+
ZButtonComponentModel,
|
|
4
|
+
ZGridViewComponentModel,
|
|
5
|
+
} from "@zthun/fashion-boutique";
|
|
6
|
+
import { required } from "@zthun/helpful-fn";
|
|
7
|
+
import { ZRomulatorSystemAvatarCardComponentModel } from "./system-avatar-card.cm.mjs";
|
|
8
|
+
|
|
9
|
+
export class ZRomulatorSystemsPageComponentModel extends ZCircusComponentModel {
|
|
10
|
+
public static readonly Selector = ".ZRomulatorSystemsPage-root";
|
|
11
|
+
|
|
12
|
+
public grid(): Promise<ZGridViewComponentModel> {
|
|
13
|
+
return Promise.resolve(new ZGridViewComponentModel(this.driver));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async system(
|
|
17
|
+
id: string,
|
|
18
|
+
): Promise<ZRomulatorSystemAvatarCardComponentModel | null> {
|
|
19
|
+
const grid = await this.grid();
|
|
20
|
+
return ZCircusBy.optional(
|
|
21
|
+
grid.driver,
|
|
22
|
+
ZRomulatorSystemAvatarCardComponentModel,
|
|
23
|
+
id,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public async systems(): Promise<ZRomulatorSystemAvatarCardComponentModel[]> {
|
|
28
|
+
const grid = await this.grid();
|
|
29
|
+
return ZCircusBy.all(grid.driver, ZRomulatorSystemAvatarCardComponentModel);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public async more(id: string): Promise<ZButtonComponentModel> {
|
|
33
|
+
const system = await this.system(id);
|
|
34
|
+
const card = await system?.card();
|
|
35
|
+
const footer = await required(card?.footer());
|
|
36
|
+
|
|
37
|
+
return ZCircusBy.first(footer, ZButtonComponentModel, "more");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { IZCircusDriver, IZCircusSetup } from "@zthun/cirque";
|
|
2
|
+
import { ZCircusBy } from "@zthun/cirque";
|
|
3
|
+
import { ZCircusSetupRenderer } from "@zthun/cirque-du-react";
|
|
4
|
+
import { ZTestRouter } from "@zthun/fashion-boutique";
|
|
5
|
+
import { ZDataSourceStatic } from "@zthun/helpful-query";
|
|
6
|
+
import { ZRomulatorSystemBuilder } from "@zthun/romulator-client";
|
|
7
|
+
import type { MemoryHistory } from "history";
|
|
8
|
+
import { createMemoryHistory } from "history";
|
|
9
|
+
import type { Mocked } from "vitest";
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
11
|
+
import { mock } from "vitest-mock-extended";
|
|
12
|
+
import { ZRomulatorSystemsPageComponentModel } from "./systems-page.cm.mjs";
|
|
13
|
+
import { ZRomulatorSystemsPage } from "./systems-page.js";
|
|
14
|
+
import type { IZRomulatorSystemsService } from "./systems-service.mjs";
|
|
15
|
+
import { ZRomulatorSystemsServiceContext } from "./systems-service.mjs";
|
|
16
|
+
|
|
17
|
+
describe("ZRomulatorSystemsPage", () => {
|
|
18
|
+
const nes = new ZRomulatorSystemBuilder().id("nes").build();
|
|
19
|
+
const snes = new ZRomulatorSystemBuilder().id("snes").build();
|
|
20
|
+
const systems = [nes, snes];
|
|
21
|
+
|
|
22
|
+
let _systemsService: Mocked<IZRomulatorSystemsService>;
|
|
23
|
+
let _renderer: IZCircusSetup | undefined;
|
|
24
|
+
let _driver: IZCircusDriver | undefined;
|
|
25
|
+
let _history: MemoryHistory;
|
|
26
|
+
|
|
27
|
+
afterEach(async () => {
|
|
28
|
+
await _driver?.destroy?.call(_driver);
|
|
29
|
+
await _renderer?.destroy?.call(_renderer);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
const source = new ZDataSourceStatic(systems);
|
|
34
|
+
|
|
35
|
+
_systemsService = mock<IZRomulatorSystemsService>();
|
|
36
|
+
_systemsService.retrieve.mockImplementation(source.retrieve.bind(source));
|
|
37
|
+
_systemsService.count.mockImplementation(source.count.bind(source));
|
|
38
|
+
|
|
39
|
+
_history = createMemoryHistory();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const createTestTarget = async () => {
|
|
43
|
+
const element = (
|
|
44
|
+
<ZTestRouter navigator={_history} location={_history.location}>
|
|
45
|
+
<ZRomulatorSystemsServiceContext value={_systemsService}>
|
|
46
|
+
<ZRomulatorSystemsPage />
|
|
47
|
+
</ZRomulatorSystemsServiceContext>
|
|
48
|
+
</ZTestRouter>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
_renderer = new ZCircusSetupRenderer(element);
|
|
52
|
+
_driver = await _renderer.setup();
|
|
53
|
+
|
|
54
|
+
return ZCircusBy.first(_driver, ZRomulatorSystemsPageComponentModel);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
it("should render all systems", async () => {
|
|
58
|
+
// Arrange.
|
|
59
|
+
const target = await createTestTarget();
|
|
60
|
+
const expected = systems.map((s) => s.id);
|
|
61
|
+
|
|
62
|
+
// Act.
|
|
63
|
+
const cards = await target.systems();
|
|
64
|
+
const actual = await Promise.all(cards.map((s) => s.id()));
|
|
65
|
+
|
|
66
|
+
// Assert.
|
|
67
|
+
expect(actual).toEqual(expected);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should navigate me to the system page when I click on the navigate button", async () => {
|
|
71
|
+
// Arrange.
|
|
72
|
+
const target = await createTestTarget();
|
|
73
|
+
|
|
74
|
+
// Act.
|
|
75
|
+
const more = await target.more(nes.id);
|
|
76
|
+
await more.click();
|
|
77
|
+
|
|
78
|
+
// Assert.
|
|
79
|
+
expect(_history.location.pathname).toEqual(`/systems/${nes.id}`);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useFashionTheme,
|
|
3
|
+
useNavigate,
|
|
4
|
+
ZButton,
|
|
5
|
+
ZGridView,
|
|
6
|
+
} from "@zthun/fashion-boutique";
|
|
7
|
+
import { ZSizeFixed, ZSizeVaried } from "@zthun/fashion-tailor";
|
|
8
|
+
import { ZRomulatorSystemAvatarCard } from "./system-avatar-card.js";
|
|
9
|
+
import { useSystemsService } from "./systems-service.mjs";
|
|
10
|
+
|
|
11
|
+
export function ZRomulatorSystemsPage() {
|
|
12
|
+
const { secondary } = useFashionTheme();
|
|
13
|
+
const navigate = useNavigate();
|
|
14
|
+
const source = useSystemsService();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<ZGridView
|
|
18
|
+
className="ZRomulatorSystemsPage-root"
|
|
19
|
+
GridProps={{
|
|
20
|
+
columns: {
|
|
21
|
+
xl: "1fr 1fr 1fr 1fr",
|
|
22
|
+
lg: "1fr 1fr 1fr",
|
|
23
|
+
md: "1fr 1fr",
|
|
24
|
+
sm: "1fr",
|
|
25
|
+
},
|
|
26
|
+
gap: ZSizeFixed.Medium,
|
|
27
|
+
}}
|
|
28
|
+
dataSource={source}
|
|
29
|
+
renderItem={(s) => (
|
|
30
|
+
<ZRomulatorSystemAvatarCard
|
|
31
|
+
key={s.id}
|
|
32
|
+
system={s}
|
|
33
|
+
CardProps={{
|
|
34
|
+
footer: (
|
|
35
|
+
<ZButton
|
|
36
|
+
fashion={secondary}
|
|
37
|
+
label="More"
|
|
38
|
+
name="more"
|
|
39
|
+
width={ZSizeVaried.Full}
|
|
40
|
+
onClick={() => navigate(`/systems/${s.id}`)}
|
|
41
|
+
/>
|
|
42
|
+
),
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
)}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ZLazy } from "@zthun/helpful-fn";
|
|
2
|
+
import type { IZDataRequest, IZDataSource } from "@zthun/helpful-query";
|
|
3
|
+
import { useAsyncState } from "@zthun/helpful-react";
|
|
4
|
+
import type { IZRomulatorSystem } from "@zthun/romulator-client";
|
|
5
|
+
import type { IZHttpService } from "@zthun/webigail-http";
|
|
6
|
+
import { ZHttpService } from "@zthun/webigail-http";
|
|
7
|
+
import type { IZRestfulGet, IZRestfulService } from "@zthun/webigail-rest";
|
|
8
|
+
import { ZRestfulService } from "@zthun/webigail-rest";
|
|
9
|
+
import { ZUrlBuilder } from "@zthun/webigail-url";
|
|
10
|
+
import { createContext, useContext } from "react";
|
|
11
|
+
import { ZRomulatorEnvironmentService } from "../environment/environment-service.mjs";
|
|
12
|
+
|
|
13
|
+
export interface IZRomulatorSystemsService
|
|
14
|
+
extends IZRestfulGet<IZRomulatorSystem>,
|
|
15
|
+
IZDataSource<IZRomulatorSystem> {}
|
|
16
|
+
|
|
17
|
+
export class ZRomulatorSystemsService implements IZRomulatorSystemsService {
|
|
18
|
+
private _rest: ZLazy<IZRestfulService<IZRomulatorSystem>>;
|
|
19
|
+
|
|
20
|
+
public async endpoint() {
|
|
21
|
+
const env = await this._env.read();
|
|
22
|
+
return new ZUrlBuilder().parse(env.api).append("systems").build();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public constructor(
|
|
26
|
+
_http: IZHttpService,
|
|
27
|
+
private readonly _env: ZRomulatorEnvironmentService,
|
|
28
|
+
) {
|
|
29
|
+
this._rest = new ZLazy(async () =>
|
|
30
|
+
Promise.resolve(new ZRestfulService(_http, await this.endpoint())),
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public async retrieve(request: IZDataRequest): Promise<IZRomulatorSystem[]> {
|
|
35
|
+
return (await this._rest.get()).retrieve(request);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public async count(request: IZDataRequest): Promise<number> {
|
|
39
|
+
return (await this._rest.get()).count(request);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public async get(id: string): Promise<IZRomulatorSystem> {
|
|
43
|
+
return (await this._rest.get()).get(id);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createDefaultSystemsService(): IZRomulatorSystemsService {
|
|
48
|
+
return new ZRomulatorSystemsService(
|
|
49
|
+
new ZHttpService(),
|
|
50
|
+
new ZRomulatorEnvironmentService(),
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const ZRomulatorSystemsServiceContext = createContext(
|
|
55
|
+
createDefaultSystemsService(),
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export const useSystemsService = () =>
|
|
59
|
+
useContext(ZRomulatorSystemsServiceContext);
|
|
60
|
+
|
|
61
|
+
export const useSystem = (id: string) => {
|
|
62
|
+
const service = useSystemsService();
|
|
63
|
+
|
|
64
|
+
return useAsyncState(() => service.get(id), [id]);
|
|
65
|
+
};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { IZCircusSetup } from "@zthun/cirque";
|
|
2
|
+
import type { IZCircusReactHook } from "@zthun/cirque-du-react";
|
|
3
|
+
import { ZCircusSetupHook } from "@zthun/cirque-du-react";
|
|
4
|
+
import { ZDataRequestBuilder, ZPageBuilder } from "@zthun/helpful-query";
|
|
5
|
+
import type { IZRomulatorSystem } from "@zthun/romulator-client";
|
|
6
|
+
import { ZRomulatorSystemBuilder } from "@zthun/romulator-client";
|
|
7
|
+
import {
|
|
8
|
+
ZHttpMethod,
|
|
9
|
+
ZHttpResultBuilder,
|
|
10
|
+
ZHttpServiceMock,
|
|
11
|
+
} from "@zthun/webigail-http";
|
|
12
|
+
import { ZRestfulUrlBuilder } from "@zthun/webigail-rest";
|
|
13
|
+
import { ZUrlBuilder } from "@zthun/webigail-url";
|
|
14
|
+
import type { Mocked } from "vitest";
|
|
15
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
16
|
+
import { mock } from "vitest-mock-extended";
|
|
17
|
+
import type { IZRomulatorEnvironmentService } from "../environment/environment-service.mjs";
|
|
18
|
+
import { ZRomulatorEnvironmentBuilder } from "../environment/environment.mjs";
|
|
19
|
+
import type { IZRomulatorSystemsService } from "./systems-service.mjs";
|
|
20
|
+
import {
|
|
21
|
+
useSystemsService,
|
|
22
|
+
ZRomulatorSystemsService,
|
|
23
|
+
} from "./systems-service.mjs";
|
|
24
|
+
|
|
25
|
+
describe("SystemsService", () => {
|
|
26
|
+
let _http: ZHttpServiceMock;
|
|
27
|
+
let _env: Mocked<IZRomulatorEnvironmentService>;
|
|
28
|
+
|
|
29
|
+
const nes = new ZRomulatorSystemBuilder().id("nes").build();
|
|
30
|
+
const snes = new ZRomulatorSystemBuilder().id("snes").build();
|
|
31
|
+
const systems = [nes, snes];
|
|
32
|
+
|
|
33
|
+
beforeEach(async () => {
|
|
34
|
+
_http = new ZHttpServiceMock();
|
|
35
|
+
_env = mock<IZRomulatorEnvironmentService>();
|
|
36
|
+
_env.read.mockResolvedValue(new ZRomulatorEnvironmentBuilder().build());
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const createTestTarget = () => new ZRomulatorSystemsService(_http, _env);
|
|
40
|
+
|
|
41
|
+
describe("Read", () => {
|
|
42
|
+
it("should retrieve a list of systems", async () => {
|
|
43
|
+
// Arrange.
|
|
44
|
+
const target = createTestTarget();
|
|
45
|
+
const request = new ZDataRequestBuilder().build();
|
|
46
|
+
|
|
47
|
+
_http.set(
|
|
48
|
+
await target.endpoint(),
|
|
49
|
+
ZHttpMethod.Get,
|
|
50
|
+
new ZHttpResultBuilder(
|
|
51
|
+
new ZPageBuilder<IZRomulatorSystem>().all(systems).build(),
|
|
52
|
+
).build(),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// Act.
|
|
56
|
+
const actual = await target.retrieve(request);
|
|
57
|
+
|
|
58
|
+
// Assert.
|
|
59
|
+
expect(actual).toEqual(systems);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should retrieve a single system by id", async () => {
|
|
63
|
+
// Arrange.
|
|
64
|
+
const target = createTestTarget();
|
|
65
|
+
|
|
66
|
+
_http.set(
|
|
67
|
+
new ZUrlBuilder()
|
|
68
|
+
.parse(await target.endpoint())
|
|
69
|
+
.append(nes.id)
|
|
70
|
+
.build(),
|
|
71
|
+
ZHttpMethod.Get,
|
|
72
|
+
new ZHttpResultBuilder(nes).build(),
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
_http.set(
|
|
76
|
+
new ZUrlBuilder()
|
|
77
|
+
.parse(await target.endpoint())
|
|
78
|
+
.append(snes.id)
|
|
79
|
+
.build(),
|
|
80
|
+
ZHttpMethod.Get,
|
|
81
|
+
new ZHttpResultBuilder(snes).build(),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Act.
|
|
85
|
+
const _nes = await target.get(nes.id);
|
|
86
|
+
const _snes = await target.get(snes.id);
|
|
87
|
+
|
|
88
|
+
// Assert.
|
|
89
|
+
expect(_nes).toEqual(nes);
|
|
90
|
+
expect(_snes).toEqual(snes);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe("Count", () => {
|
|
95
|
+
it("should count the number of systems", async () => {
|
|
96
|
+
// Arrange.
|
|
97
|
+
const target = createTestTarget();
|
|
98
|
+
|
|
99
|
+
_http.set(
|
|
100
|
+
new ZRestfulUrlBuilder(await target.endpoint()).count().build(),
|
|
101
|
+
ZHttpMethod.Get,
|
|
102
|
+
new ZHttpResultBuilder(
|
|
103
|
+
new ZPageBuilder<IZRomulatorSystem>()
|
|
104
|
+
.data([nes])
|
|
105
|
+
.count(systems.length)
|
|
106
|
+
.build(),
|
|
107
|
+
).build(),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Act.
|
|
111
|
+
const actual = await target.count(new ZDataRequestBuilder().build());
|
|
112
|
+
|
|
113
|
+
// Assert.
|
|
114
|
+
expect(actual).toEqual(systems.length);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("useSystemsService", () => {
|
|
120
|
+
let _hook: IZCircusSetup<
|
|
121
|
+
IZCircusReactHook<IZRomulatorSystemsService, unknown>
|
|
122
|
+
>;
|
|
123
|
+
|
|
124
|
+
const createTestTarget = () => {
|
|
125
|
+
_hook = new ZCircusSetupHook(() => useSystemsService());
|
|
126
|
+
|
|
127
|
+
return _hook?.setup();
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
afterEach(async () => {
|
|
131
|
+
await _hook?.destroy?.call(_hook);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should have a default implementation", async () => {
|
|
135
|
+
// Arrange.
|
|
136
|
+
const target = await createTestTarget();
|
|
137
|
+
|
|
138
|
+
// Act.
|
|
139
|
+
const actual = await target.current();
|
|
140
|
+
|
|
141
|
+
// Assert.
|
|
142
|
+
expect(actual).toBeInstanceOf(ZRomulatorSystemsService);
|
|
143
|
+
});
|
|
144
|
+
});
|
package/tsconfig.json
ADDED
package/vite.config.mts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ZViteConfigBuilder,
|
|
3
|
+
ZViteServerBuilder,
|
|
4
|
+
} from "@zthun/janitor-build-config/vite";
|
|
5
|
+
import { defineConfig } from "vite";
|
|
6
|
+
|
|
7
|
+
const server = new ZViteServerBuilder().dev().build();
|
|
8
|
+
const config = new ZViteConfigBuilder().react().server(server).lodash().build();
|
|
9
|
+
export default defineConfig(config);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ZViteConfigBuilder,
|
|
3
|
+
ZViteTestBuilder,
|
|
4
|
+
} from "@zthun/janitor-build-config/vite";
|
|
5
|
+
import { defineConfig } from "vite";
|
|
6
|
+
|
|
7
|
+
const test = new ZViteTestBuilder().browser().build();
|
|
8
|
+
const config = new ZViteConfigBuilder().test(test).build();
|
|
9
|
+
export default defineConfig(config);
|