Skip to content

Commit de2c011

Browse files
nabramovitznorman-abramovitz
authored andcommitted
Make specs + test-infra type-check under strict; retire dead test-runner types (#5446)
The app strict flip also made specs strict, but nothing in the gate type-checks specs (vitest transpiles via esbuild; ng build excludes them), and vestigial karma->vitest `types` entries (jasmine/jasminewd2/karma, vitest/globals) caused a tsc config-error short-circuit that MASKED the whole surface. Unmask it and make specs genuinely strict-clean. Config / tooling: - Drop dead jasmine/jasminewd2/karma from the base `types`; repair the broken (unused) entity-catalog-test-helpers (this.vi -> vi, drop jasmine.Spy). - Add `@test-framework/*` path mapping (core->cloud-foundry->store fallback) and `@stratosui/core/*` / `@stratosui/store/*` deep-subpath mappings so tsc/IDE resolve test imports the way the vitest aliases already do. - tsconfig.app.json: exclude `*.spec.ts` + config files (matches ng build's scope; app config should not type-check tests). - tsconfig.spec.json: drop the non-resolving `vitest/globals` (globals:false -> specs import explicitly); exclude config files + non-test demo packages (example-extensions, desktop-extensions). Specs (52 files): fix ~230 strict-null / implicit-any / missing-vitest-import findings. Real guards and faithful mock types; `!` only for fixture values the test itself seeds, each with a // strict: comment. Test intent and assertions preserved. Verified: tsc -p app = 0, tsc -p spec = 0, ng build clean, full vitest 2604 passed / 0 failed, eslint 0 errors.
1 parent 5dcb837 commit de2c011

55 files changed

Lines changed: 466 additions & 209 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/frontend/packages/cf-autoscaler/src/core/autoscaler-helpers/autoscaler-transform-metric.spec.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { describe, it, expect } from 'vitest';
2+
import { PaginationResponse } from '../../../../cloud-foundry/src/store/types/cf-api.types';
3+
import { AppAutoscalerMetricData } from '../../store/app-autoscaler.types';
24
import {
35
isEqual,
46
} from './autoscaler-util';
@@ -29,12 +31,11 @@ describe('Autoscaler Transform Metric Helper', () => {
2931
});
3032
it('buildMetricData', () => {
3133
const metricName = 'throughput';
32-
const data = {
34+
const data: PaginationResponse<AppAutoscalerMetricData> = {
3335
total_results: 12,
3436
total_pages: 1,
35-
page: 1,
36-
prev_url: null as string | null,
37-
next_url: null as string | null,
37+
prev_url: '',
38+
next_url: '',
3839
resources: [
3940
{
4041
app_id: '2bd98ff4-99f4-422a-a037-172298277c8b',

src/frontend/packages/cloud-foundry/src/features/applications/application-delete/app-routes-picker.component.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const routeA: StRoute = {
2525
path: '',
2626
domainGuid: 'd-1',
2727
spaceGuid: 's-1',
28+
cnsiGuid: 'cnsi-1',
2829
createdAt: '',
2930
updatedAt: '',
3031
};
@@ -36,6 +37,7 @@ const routeB: StRoute = {
3637
path: '/api',
3738
domainGuid: 'd-1',
3839
spaceGuid: 's-1',
40+
cnsiGuid: 'cnsi-1',
3941
createdAt: '',
4042
updatedAt: '',
4143
};

src/frontend/packages/cloud-foundry/src/features/applications/application/application-tabs-base/application-tabs-base.component.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ describe('ApplicationTabsBaseComponent', () => {
6969
RawPath: '',
7070
ForceQuery: false,
7171
RawQuery: '',
72-
Fragment: '',
73-
RawFragment: ''
72+
Fragment: ''
7473
},
7574
authorization_endpoint: '',
7675
token_endpoint: '',
@@ -86,7 +85,8 @@ describe('ApplicationTabsBaseComponent', () => {
8685
sso_allowed: false,
8786
sub_type: '',
8887
metadata: {},
89-
logged_in_as_admin: false
88+
metricsAvailable: false,
89+
creator: { name: 'test-user', admin: false, system: false }
9090
};
9191

9292
const endpointsMap: WritableSignal<Map<string, EndpointModel>> = signal(

src/frontend/packages/cloud-foundry/src/features/applications/applications.routes.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { describe, it, expect } from 'vitest';
12
import { Route } from '@angular/router';
23

34
import { APPLICATIONS_ROUTES } from './applications.routes';

src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-step2-1/deploy-application-step2-1.component.spec.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,18 @@ describe('DeployApplicationStep21Component', () => {
4949

5050
it('onNext pins the selected commit SHA when not deploying latest HEAD', () => {
5151
(component as unknown as { selectedCommitSubject: { next(c: GitCommit): void } }).selectedCommitSubject.next(commit);
52-
component.onNext();
52+
// strict: onNext's impl is a zero-arg arrow that ignores the stepper's
53+
// (index, step) contract args; call it via its real runtime shape.
54+
(component.onNext as () => unknown)();
5355
expect(deployData.setDeployCommit).toHaveBeenCalledWith('abc123def456');
5456
});
5557

5658
it('onNext sends an empty commit (deploy latest HEAD) when that option is chosen', () => {
5759
// Even with a commit still selected underneath, latest-HEAD wins and unpins.
5860
(component as unknown as { selectedCommitSubject: { next(c: GitCommit): void } }).selectedCommitSubject.next(commit);
5961
(component as unknown as { useLatestHeadSubject: { next(v: boolean): void } }).useLatestHeadSubject.next(true);
60-
component.onNext();
62+
// strict: see above — onNext ignores the (index, step) contract args.
63+
(component.onNext as () => unknown)();
6164
expect(deployData.setDeployCommit).toHaveBeenCalledWith('');
6265
});
6366
});

src/frontend/packages/cloud-foundry/src/features/applications/deploy-application/deploy-application-step2/deploy-application-step2.component.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ describe('DeployApplicationStep2Component', () => {
215215
// setupForGit's other upstream collaborators just enough to reach the
216216
// suggestedRepos$ assignment where the tap callback is registered.
217217
const valueChanges = new Subject<Record<string, string | undefined>>();
218-
(component as unknown as { sourceSelectionForm: { valueChanges: Subject<unknown> } }).sourceSelectionForm = {
218+
(component as unknown as {
219+
sourceSelectionForm: { valueChanges: Subject<Record<string, string | undefined>> };
220+
}).sourceSelectionForm = {
219221
valueChanges,
220222
};
221223
// updateSuggestedRepositories is called inside switchMap; stub it to

src/frontend/packages/cloud-foundry/src/features/applications/edit-application/edit-application.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest';
44

55
import { TabNavService } from '@stratosui/core';
66
import { STORE_TEST_PROVIDERS } from '@stratosui/store/testing';
7-
import { ApplicationStateService } from '@stratosui/shared';
7+
import { ApplicationStateService } from '../../../shared/services/application-state.service';
88
import { generateTestApplicationServiceProvider } from '@test-framework/application-service-helper';
99
import { ApplicationEnvVarsHelper } from '../application/application-tabs-base/tabs/build-tab/application-env-vars.service';
1010
import { EditApplicationComponent } from './edit-application.component';

src/frontend/packages/cloud-foundry/src/features/cf/add-space/create-space-step/create-space-step.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {
1313
EntityCatalogHelpers,
1414
} from '@stratosui/store';
1515
import { STORE_TEST_PROVIDERS, testSCFEndpointGuid, populateStoreWithTestEndpoint } from '@stratosui/store/testing';
16-
import { generateTestCfEndpointServiceProvider, ActiveRouteCfOrgSpace } from "@test-framework/cloud-foundry-endpoint-service.helper";
16+
import { generateTestCfEndpointServiceProvider } from "@test-framework/cloud-foundry-endpoint-service.helper";
17+
import { ActiveRouteCfOrgSpace } from "../../cf-page.types";
1718
import { generateCFEntities } from '@stratosui/cloud-foundry';
1819
import { CreateSpaceStepComponent } from "./create-space-step.component";
1920

src/frontend/packages/cloud-foundry/src/features/cf/users/invite-users/invite-users-create/invite-users-create.component.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ describe('InviteUsersCreateComponent', () => {
111111
} as any);
112112

113113
// Drive the same code path the wizard uses on submit.
114-
await firstValueFrom(component.onNext());
114+
// strict: onNext's impl ignores the stepper's (index, step) contract
115+
// args; call it via its real runtime shape.
116+
await firstValueFrom((component.onNext as () => ReturnType<typeof component.onNext>)());
115117

116118
expect(markStale).toHaveBeenCalledWith(testSCFEndpointGuid);
117119
});

src/frontend/packages/cloud-foundry/src/features/cf/users/manage-users/cf-roles.service.spec.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ describe('CfRolesService', () => {
9090
expect(first.entityRequestInfo.fetching).toBe(true);
9191
expect(first.entity).toBeNull();
9292
expect(second.entityRequestInfo.fetching).toBe(false);
93-
expect(second.entity.metadata.guid).toBe('org-1');
94-
expect(second.entity.entity.name).toBe('My Org');
93+
// strict: the loaded emission (fetching=false) always carries a non-null entity
94+
expect(second.entity!.metadata.guid).toBe('org-1');
95+
expect(second.entity!.entity.name).toBe('My Org');
9596
});
9697

9798
it('fetchOrgs hits the native list endpoint with per_page paging', () => {
@@ -147,7 +148,8 @@ describe('CfRolesService', () => {
147148
expect(org.permissions.users).toBe(true);
148149
expect(org.permissions.auditors).toBe(false);
149150

150-
const space = org.spaces['space-1'];
151+
// strict: this user has a space-1 role under org-1, so spaces is populated
152+
const space = org.spaces!['space-1'];
151153
expect(space.spaceGuid).toBe('space-1');
152154
expect(space.name).toBe('My Space');
153155
expect(space.permissions.developers).toBe(true);
@@ -173,8 +175,9 @@ describe('CfRolesService', () => {
173175
expect(Object.keys(roles)).toEqual(['user-9']);
174176
const org = roles['user-9']['org-2'];
175177
expect(org).toBeTruthy();
176-
expect(org.spaces['space-2'].permissions.auditors).toBe(true);
177-
expect(org.spaces['space-2'].name).toBe('Space Two');
178+
// strict: the space-only role auto-creates org-2 with a populated spaces map
179+
expect(org.spaces!['space-2'].permissions.auditors).toBe(true);
180+
expect(org.spaces!['space-2'].name).toBe('Space Two');
178181
});
179182

180183
it('populateRoles drains all org pages so names beyond the first page still resolve', async () => {

0 commit comments

Comments
 (0)