Skip to content

Commit 1693f24

Browse files
👷 Add typecheck to CI and pre-commit (#33)
1 parent 6d297e9 commit 1693f24

4 files changed

Lines changed: 106 additions & 42 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,15 @@ on:
77
branches: [main]
88

99
jobs:
10-
lint:
10+
ci:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v4
1414
- uses: oven-sh/setup-bun@v2
15-
- run: bun install
15+
with:
16+
cache: bun
17+
- run: bun ci
1618
- run: bun run lint
17-
18-
build:
19-
runs-on: ubuntu-latest
20-
steps:
21-
- uses: actions/checkout@v4
22-
- uses: oven-sh/setup-bun@v2
23-
- run: bun install
19+
- run: bun run typecheck
2420
- run: bun run compile
25-
26-
test:
27-
runs-on: ubuntu-latest
28-
steps:
29-
- uses: actions/checkout@v4
30-
- uses: oven-sh/setup-bun@v2
31-
- run: bun install
3221
- run: xvfb-run -a bun run test:coverage

‎.husky/pre-commit‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
bun run typecheck
12
bunx lint-staged

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@
277277
"test": "bun run compile && vscode-test",
278278
"test:coverage": "bash scripts/test-coverage.sh",
279279
"test:web": "bun run compile && bunx @vscode/test-web --extensionDevelopmentPath=. --browserType=none",
280+
"typecheck": "tsc --noEmit",
280281
"prepare": "husky"
281282
},
282283
"devDependencies": {

‎src/test/cloud/controller.test.ts‎

Lines changed: 99 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ suite("cloud/cloudController", () => {
415415

416416
await deps.controller.initialize()
417417

418-
// Explicitly wait for status bar update since it's fire-and-forget
419-
await deps.controller["statusBarManager"].update()
418+
// Trigger status bar update via refreshAll
419+
await deps.controller.refreshAll()
420420

421421
assert.strictEqual(deps.statusBar.text, "$(warning) FastAPI Cloud")
422422
assert.ok(warnStub.calledOnce)
@@ -488,7 +488,8 @@ suite("cloud/cloudController", () => {
488488
newWorkspace,
489489
),
490490
)
491-
assert.strictEqual(deps.controller["workspaceStates"].size, 1)
491+
// Verify state was set by checking that getApp was called (indicates refresh happened)
492+
assert.ok((deps.apiService.getApp as sinon.SinonStub).calledOnce)
492493

493494
dispose(deps)
494495
})
@@ -515,11 +516,33 @@ suite("cloud/cloudController", () => {
515516
sinon.stub(deps.apiService, "getApp").resolves(testApp)
516517
sinon.stub(deps.apiService, "getTeam").resolves(testTeam)
517518

519+
// Set up active editor to point to workspace
520+
const activeEditor = {
521+
document: { uri: vscode.Uri.file("/tmp/workspace/file.py") },
522+
}
523+
Object.defineProperty(vscode.window, "activeTextEditor", {
524+
value: activeEditor,
525+
configurable: true,
526+
})
527+
sinon
528+
.stub(vscode.workspace, "getWorkspaceFolder")
529+
.returns(workspaceFolder)
530+
518531
await deps.controller.initialize()
519-
assert.strictEqual(deps.controller["workspaceStates"].size, 1)
532+
533+
assert.strictEqual(deps.statusBar.text, "$(cloud) test-app")
520534

521535
deps.controller.removeWorkspaceFolder(workspace)
522-
assert.strictEqual(deps.controller["workspaceStates"].size, 0)
536+
537+
// Verify state was deleted by showing menu - should show setup menu (not_configured)
538+
const quickPickStub = sinon
539+
.stub(vscode.window, "showQuickPick")
540+
.resolves(undefined)
541+
await deps.controller.showMenu()
542+
543+
const items = quickPickStub.firstCall.args[0] as any[]
544+
assert.ok(items.some((i: any) => i.id === "link"))
545+
assert.ok(items.some((i: any) => i.id === "create"))
523546

524547
dispose(deps)
525548
})
@@ -554,7 +577,11 @@ suite("cloud/cloudController", () => {
554577

555578
await deps.controller.refreshAll()
556579

557-
assert.strictEqual(deps.controller["workspaceStates"].size, 2)
580+
// Verify both workspaces were refreshed by checking getApp was called twice
581+
assert.strictEqual(
582+
(deps.apiService.getApp as sinon.SinonStub).callCount,
583+
2,
584+
)
558585

559586
dispose(deps)
560587
})
@@ -609,15 +636,29 @@ suite("cloud/cloudController", () => {
609636
configurable: true,
610637
})
611638

639+
const activeEditor = {
640+
document: { uri: vscode.Uri.file("/tmp/workspace/file.py") },
641+
}
642+
Object.defineProperty(vscode.window, "activeTextEditor", {
643+
value: activeEditor,
644+
configurable: true,
645+
})
646+
sinon
647+
.stub(vscode.workspace, "getWorkspaceFolder")
648+
.returns(workspaceFolder)
649+
612650
sinon
613651
.stub(vscode.authentication, "getSession")
614652
.rejects(new Error("Auth error"))
615653
sinon.stub(deps.configService, "startWatching")
616654

617655
await deps.controller.initialize()
618656

619-
const state = deps.controller["getState"](workspace)
620-
assert.strictEqual(state.status, "not_configured")
657+
// Verify state is not_configured by checking status bar shows sign-in
658+
assert.strictEqual(
659+
deps.statusBar.text,
660+
"$(cloud) Sign into FastAPI Cloud",
661+
)
621662

622663
dispose(deps)
623664
})
@@ -632,6 +673,17 @@ suite("cloud/cloudController", () => {
632673
configurable: true,
633674
})
634675

676+
const activeEditor = {
677+
document: { uri: vscode.Uri.file("/tmp/workspace/file.py") },
678+
}
679+
Object.defineProperty(vscode.window, "activeTextEditor", {
680+
value: activeEditor,
681+
configurable: true,
682+
})
683+
sinon
684+
.stub(vscode.workspace, "getWorkspaceFolder")
685+
.returns(workspaceFolder)
686+
635687
sinon
636688
.stub(vscode.authentication, "getSession")
637689
.resolves(mockSession as any)
@@ -642,8 +694,8 @@ suite("cloud/cloudController", () => {
642694

643695
await deps.controller.initialize()
644696

645-
const state = deps.controller["getState"](workspace)
646-
assert.strictEqual(state.status, "error")
697+
// Verify state is error by checking status bar shows setup (error state shows setup)
698+
assert.strictEqual(deps.statusBar.text, "$(cloud) Set up FastAPI Cloud")
647699

648700
dispose(deps)
649701
})
@@ -679,13 +731,7 @@ suite("cloud/cloudController", () => {
679731
await deps.controller.initialize()
680732
assert.strictEqual(warnStub.callCount, 1)
681733

682-
// Manually mark warning as shown
683-
deps.controller["setState"](workspace, {
684-
status: "not_found",
685-
warningShown: true,
686-
})
687-
688-
// Second refresh - should NOT show warning again
734+
// Second refresh - warning was dismissed (resolved undefined), so should NOT show again
689735
await deps.controller.refresh(workspace)
690736
assert.strictEqual(warnStub.callCount, 1) // Still 1, not 2
691737

@@ -753,6 +799,17 @@ suite("cloud/cloudController", () => {
753799
configurable: true,
754800
})
755801

802+
const activeEditor = {
803+
document: { uri: vscode.Uri.file("/tmp/workspace/file.py") },
804+
}
805+
Object.defineProperty(vscode.window, "activeTextEditor", {
806+
value: activeEditor,
807+
configurable: true,
808+
})
809+
sinon
810+
.stub(vscode.workspace, "getWorkspaceFolder")
811+
.returns(workspaceFolder)
812+
756813
sinon
757814
.stub(vscode.authentication, "getSession")
758815
.resolves(mockSession as any)
@@ -772,8 +829,8 @@ suite("cloud/cloudController", () => {
772829

773830
await deps.controller.createAndLinkProject(workspace)
774831

775-
const state = deps.controller["getState"](workspace)
776-
assert.strictEqual(state.status, "linked")
832+
// Verify state is linked by checking status bar shows app slug
833+
assert.strictEqual(deps.statusBar.text, "$(cloud) test-app")
777834

778835
dispose(deps)
779836
})
@@ -859,7 +916,7 @@ suite("cloud/cloudController", () => {
859916
.withArgs(editor1.document.uri)
860917
.returns(workspaceFolder1)
861918

862-
await deps.controller["statusBarManager"].update()
919+
await deps.controller.refreshAll()
863920
assert.strictEqual(deps.statusBar.text, "$(cloud) test-app")
864921

865922
// Switch to workspace2 file
@@ -874,7 +931,7 @@ suite("cloud/cloudController", () => {
874931
.withArgs(editor2.document.uri)
875932
.returns(workspaceFolder2)
876933

877-
await deps.controller["statusBarManager"].update()
934+
await deps.controller.refreshAll()
878935
assert.strictEqual(deps.statusBar.text, "$(cloud) test-app-2")
879936

880937
dispose(deps)
@@ -925,7 +982,7 @@ suite("cloud/cloudController", () => {
925982
.withArgs(editor1.document.uri)
926983
.returns(workspaceFolder1)
927984

928-
await deps.controller["statusBarManager"].update()
985+
await deps.controller.refreshAll()
929986
assert.strictEqual(deps.statusBar.text, "$(cloud) test-app")
930987

931988
// workspace2 file shows setup
@@ -940,7 +997,7 @@ suite("cloud/cloudController", () => {
940997
.withArgs(editor2.document.uri)
941998
.returns(workspaceFolder2)
942999

943-
await deps.controller["statusBarManager"].update()
1000+
await deps.controller.refreshAll()
9441001
assert.strictEqual(deps.statusBar.text, "$(cloud) Set up FastAPI Cloud")
9451002

9461003
dispose(deps)
@@ -1166,6 +1223,18 @@ suite("cloud/cloudController", () => {
11661223
configurable: true,
11671224
})
11681225

1226+
// Set up active editor
1227+
const editor1 = {
1228+
document: { uri: vscode.Uri.file("/tmp/workspace1/file.py") },
1229+
}
1230+
Object.defineProperty(vscode.window, "activeTextEditor", {
1231+
value: editor1,
1232+
configurable: true,
1233+
})
1234+
sinon
1235+
.stub(vscode.workspace, "getWorkspaceFolder")
1236+
.returns(workspaceFolder1)
1237+
11691238
const getSessionStub = sinon.stub(vscode.authentication, "getSession")
11701239
getSessionStub.resolves(mockSession as any)
11711240

@@ -1178,7 +1247,8 @@ suite("cloud/cloudController", () => {
11781247

11791248
await deps.controller.initialize()
11801249

1181-
assert.strictEqual(deps.controller["workspaceStates"].size, 2)
1250+
// Verify workspaces are linked by checking status bar shows app
1251+
assert.strictEqual(deps.statusBar.text, "$(cloud) test-app")
11821252

11831253
sinon
11841254
.stub(vscode.window, "showWarningMessage")
@@ -1190,8 +1260,11 @@ suite("cloud/cloudController", () => {
11901260

11911261
await deps.controller.signOut()
11921262

1193-
// All workspace states should be cleared
1194-
assert.strictEqual(deps.controller["workspaceStates"].size, 0)
1263+
// All workspace states should be cleared - status bar shows sign-in
1264+
assert.strictEqual(
1265+
deps.statusBar.text,
1266+
"$(cloud) Sign into FastAPI Cloud",
1267+
)
11951268

11961269
dispose(deps)
11971270
})

0 commit comments

Comments
 (0)