Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test improvements #97

Merged
merged 12 commits into from
Jan 19, 2024
5 changes: 3 additions & 2 deletions application/frontend/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ module.exports = function (config) {
require('karma-coverage'),
require('karma-jasmine-html-reporter'),
require('karma-webpack'),
require('@angular-devkit/build-angular/plugins/karma')
require('@angular-devkit/build-angular/plugins/karma'),
require('karma-spec-reporter')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
Expand All @@ -44,7 +45,7 @@ module.exports = function (config) {
},
]
},
reporters: ['coverage', 'progress', 'kjhtml'],
reporters: ['coverage', 'progress', 'kjhtml', 'spec'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
Expand Down
7,640 changes: 4,912 additions & 2,728 deletions application/frontend/package-lock.json

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions application/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular/service-worker": "13.3.12",
"@angular-devkit/build-angular": "13.3.11",
"@angular-eslint/builder": "~13.3.0",
"@angular-eslint/eslint-plugin": "~13.3.0",
Expand All @@ -73,8 +72,9 @@
"@angular/cli": "13.3.10",
"@angular/compiler-cli": "13.3.12",
"@angular/language-service": "13.3.12",
"@angular/service-worker": "13.3.12",
"@types/google.maps": "^3.50.5",
"@types/jasmine": "~3.3.8",
"@types/jasmine": "^5.1.4",
"@types/jasminewd2": "~2.0.3",
"@types/lodash": "^4.14.168",
"@types/long": "^4.0.0",
Expand All @@ -85,14 +85,15 @@
"eslint": "^8.2.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-deprecation": "^1.3.2",
"jasmine-core": "~4.0.0",
"jasmine-core": "^5.1.1",
"jasmine-marbles": "^0.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.3.16",
"karma-coverage": "~2.2.0",
"karma": "^6.4.2",
"karma-chrome-launcher": "~3.1.0",
"karma-jasmine": "~4.0.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^1.5.0",
"karma-spec-reporter": "^0.0.36",
"karma-webpack": "~5.0.0",
"prettier": "2.7.0",
"protractor": "~7.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* https://opensource.org/licenses/MIT.
*/

import { Component } from '@angular/core';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { MatIconRegistry } from '@angular/material/icon';
Expand All @@ -22,13 +22,31 @@ import { FormMapService, VehicleLayer } from '../../services';
import { PlacesService } from '../../services/places.service';
import { BaseEditVehicleDialogComponent } from './base-edit-vehicle-dialog.component';
import { provideMockStore } from '@ngrx/store/testing';
import { FormGroup } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { DurationMinSecFormComponent } from 'src/app/shared/components/duration-min-sec-form/duration-min-sec-form.component';

@Component({
selector: 'app-form-map',
template: '',
})
class MockFormMapComponent {}

@Component({
selector: 'app-duration-min-sec-form',
template: '',
})
class MockAppDurationMinSecFormComponent {
@Input() appearance = 'legacy';
@Input() parentFormGroup: FormGroup;
@Input() errorStateMatcher: ErrorStateMatcher;
@Input() labelName: string;
@Input() showUnset: boolean;
@Input() isUnset: boolean;
@Input() fieldName: string;
@Output() unsetEvent = new EventEmitter<{ field: string }>();
}

describe('BaseEditVehicleDialogComponent', () => {
let component: BaseEditVehicleDialogComponent;
let fixture: ComponentFixture<BaseEditVehicleDialogComponent>;
Expand All @@ -54,6 +72,9 @@ describe('BaseEditVehicleDialogComponent', () => {
.overrideProvider(FormMapService, { useValue: new MockMapService() })
.overrideProvider(PlacesService, { useValue: placesService })
.overrideProvider(VehicleLayer, { useValue: new MockMarkersLayerService() })
.overrideProvider(DurationMinSecFormComponent, {
useValue: MockAppDurationMinSecFormComponent,
})
.compileComponents();

fixture = TestBed.createComponent(BaseEditVehicleDialogComponent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,20 @@ import { MainNavComponent } from './main-nav.component';
template: '',
})
class MockBaseMainNavComponent {
@Input() allowExperimentalFeatures: boolean;
@Input() disabled: boolean;
@Input() hasSolution: boolean;
@Input() isSolutionStale: boolean;
@Input() isSolutionIllegal: boolean;
@Input() selectedShipmentCount: number;
@Input() selectedVehicleCount: number;
@Input() selectedVehicleOperatorCount: number;
@Input() solving: boolean;
@Input() page: Page;
@Output() shipmentsClick = new EventEmitter();
@Output() solutionClick = new EventEmitter();
@Output() vehiclesClick = new EventEmitter();
@Output() vehicleOperatorsClick = new EventEmitter();
}

describe('MainNavComponent', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ import { MaterialModule } from 'src/app/material';
template: '',
})
class MockBaseEditShipmentDialogComponent {
@Input() abbreviations: { [unit: string]: string };
@Input() bulkEdit: boolean;
@Input() bulkNumber: number;
@Input() scenarioCapacities: Set<string>;
@Input() scenarioDemands: Set<string>;
@Input() disabled = false;
@Input() shipment: Shipment;
@Input() vehicles: Dictionary<Vehicle>;
@Input() abbreviations: { [unit: string]: string };
@Input() appearance: string;
@Input() scenarioCapacities: Set<string>;
@Input() scenarioDemands: Set<string>;
@Input() scenarioShipmentTypes: Set<string>;
/**
* Ids used to map vehicle to index
* @remarks
Expand All @@ -54,6 +56,7 @@ class MockBaseEditShipmentDialogComponent {
@Input() pickup?: Visit;
@Input() delivery?: Visit;
@Input() visitTags?: string[];
@Input() visitTypes?: string[];
@Input() visitCategory?: VisitCategory;
@Input() nextVisitRequestId = 0;
@Input() timezoneOffset = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import ShipmentModelSelectors from '../../selectors/shipment-model.selectors';
})
class MockBaseEditVehicleDialogComponent {
@Input() abbreviations: { [unit: string]: string };
@Input() allowExperimentalFeatures: boolean;
@Input() appearance: string;
@Input() bulkEdit: boolean;
@Input() bulkNumber: number;
Expand All @@ -46,10 +47,17 @@ class MockBaseEditVehicleDialogComponent {
@Input() nextVehicleId: number;
@Input() scenarioBounds?: google.maps.LatLngBounds;
@Input() visitTags?: string[];
@Input() visitTypes?: string[];
@Input() operatorTypes?: Set<string>;
@Input() existingOperatorTypes?: Set<string>;
@Input() timezoneOffset?: number;
@Input() vehicle: Vehicle;
@Output() cancel = new EventEmitter<void>();
@Output() save = new EventEmitter<{ timeThresholds: TimeThreshold[]; vehicle: Vehicle }>();
@Output() save = new EventEmitter<{
timeThresholds: TimeThreshold[];
vehicle: Vehicle;
unsetFields: string[];
}>();
}

describe('PreSolveEditVehicleDialogComponent', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,31 @@
*/

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
import { MatIconRegistry } from '@angular/material/icon';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { provideMockStore } from '@ngrx/store/testing';
import { MaterialModule } from 'src/app/material';
import { FakeMatIconRegistry } from 'src/test/material-fakes';
import { PreSolveShipmentModelSettingsComponent } from './pre-solve-shipment-model-settings.component';
import ShipmentModelSelectors from '../../selectors/shipment-model.selectors';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core';

@Component({
selector: 'app-duration-min-sec-form',
template: '',
})
class MockAppDurationMinSecFormComponent {
@Input() appearance = 'legacy';
@Input() parentFormGroup: FormGroup;
@Input() errorStateMatcher: ErrorStateMatcher;
@Input() labelName: string;
@Input() showUnset: boolean;
@Input() isUnset: boolean;
@Input() fieldName: string;
@Output() unsetEvent = new EventEmitter<{ field: string }>();
}

describe('PreSolveShipmentModelSettingsComponent', () => {
let component: PreSolveShipmentModelSettingsComponent;
Expand All @@ -24,7 +41,7 @@ describe('PreSolveShipmentModelSettingsComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ReactiveFormsModule, MaterialModule, NoopAnimationsModule],
declarations: [PreSolveShipmentModelSettingsComponent],
declarations: [PreSolveShipmentModelSettingsComponent, MockAppDurationMinSecFormComponent],
providers: [
provideMockStore({
selectors: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { VehicleOperatorsKpisComponent } from './vehicle-operators-kpis.componen
template: '',
})
class MockBaseVehicleOperatorsKpisComponent {
@Input() vehicleOperatorsKpis: VehicleOperatorsKpis;
@Input() vehicleOperatorKpis: VehicleOperatorsKpis;
@Input() unitAbbreviations: { [unit: string]: string };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,19 @@ import { createSelector } from '@ngrx/store';
template: '',
})
class MockBaseVisitRequestInfoWindowComponent {
@Input() savePending: boolean;
@Input() shipment: Shipment;
@Input() visitRequest: VisitRequest;
@Input() visit?: Visit;
@Input() vehicle?: Vehicle;
@Input() timezoneOffset = 0;
@Input() postSolve = false;
@Input() navigation = false;
@Input() vehicles: Vehicle[];
@Output() shipmentClick = new EventEmitter<Shipment>();
@Output() vehicleClick = new EventEmitter<Vehicle>();
@Output() visitClick = new EventEmitter<Visit>();
@Output() vehicleAssignmentChange = new EventEmitter<Vehicle>();
}

describe('VisitRequestInfoWindowComponent', () => {
Expand Down
12 changes: 10 additions & 2 deletions application/frontend/src/app/core/effects/download.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import { hot } from 'jasmine-marbles';
import { Observable, of } from 'rxjs';
import { download, downloadFailure, downloadSuccess } from '../actions/download.actions';
import * as fromDownload from '../selectors/download.selectors';
import { FileService } from '../services';
import { FileService, MessageService } from '../services';
import { DownloadEffects } from './download.effects';
import { MatSnackBar } from '@angular/material/snack-bar';
import * as fromUI from '../selectors/ui.selectors';

describe('DownloadEffects', () => {
let actions$: Observable<any>;
Expand All @@ -44,8 +45,15 @@ describe('DownloadEffects', () => {
useValue: jasmine.createSpyObj('matDialog', ['getDialogById', 'open']),
},
{ provide: FileService, useValue: fileService },
{
provide: MessageService,
useValue: jasmine.createSpyObj('messageService', ['error'], { messages: [] }),
},
provideMockStore({
selectors: [{ selector: fromDownload.selectDownload, value: null }],
selectors: [
{ selector: fromDownload.selectDownload, value: null },
{ selector: fromUI.selectModal, value: null },
],
}),
provideMockActions(() => actions$),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Timeline,
ChangedVisits,
Vehicle,
PointOfInterestTimelineOverlapBegin,
} from 'src/app/core/models';
import * as fromConfig from 'src/app/core/selectors/config.selectors';
import * as fromPointOfInterest from 'src/app/core/selectors/point-of-interest.selectors';
Expand All @@ -46,6 +47,7 @@ class MockBaseRoutesRowComponent {
@Input() isDragging: boolean;
@Input() route: ShipmentRoute;
@Input() vehicle: Vehicle;
@Input() vehicleOperator: string;
@Input() shipmentCount: number;
@Input() selected = false;
@Input() timeline: Timeline;
Expand All @@ -60,11 +62,13 @@ class MockBaseRoutesRowComponent {
@Input() changedVisits: ChangedVisits;
@Output() selectedChange = new EventEmitter<boolean>();
@Output() dragStart = new EventEmitter<PointOfInterestStartDrag>();
@Output() timelineEnter = new EventEmitter<number>();
@Output() timelineEnter = new EventEmitter<PointOfInterestTimelineOverlapBegin>();
@Output() timelineLeave = new EventEmitter<number>();
@Output() pointOfInterestClick = new EventEmitter<PointOfInterestClick>();
@Output() editVehicle = new EventEmitter<number>();
@Output() viewMetadata = new EventEmitter<number>();
@Output() mouseEnterVisit = new EventEmitter<number>();
@Output() mouseExitVisit = new EventEmitter();
}

describe('RoutesRowComponent', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@ import { RouteMetadata } from '../../models';
import { BaseRoutesMetadataTableComponent } from './base-routes-metadata-table.component';
import { provideMockStore } from '@ngrx/store/testing';
import { selectAllowExperimentalFeatures } from '../../../core/selectors/config.selectors';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { TableComponent } from 'src/app/shared/components';

@Component({
selector: 'app-table',
template: '',
})
class MockTableComponent<T = any> {
@Input() mouseOverActive: boolean;
@Input() dataSource: DataSource<T>;
@Input() itemsSelected: { [id: number]: boolean } = {};
@Input() columnsToDisplay: string[];
@Input() totalSelectableItems = 0;
@Input() itemSize = 49;
@Input() selectDisabled = false;
@Output() selectAll = new EventEmitter<void>();
@Output() deselectAll = new EventEmitter<void>();
@Output() selectedChange = new EventEmitter<{ id: number; selected: boolean }>();
@Output() mouseEnterRow = new EventEmitter<any>();
@Output() mouseExitRow = new EventEmitter<any>();
@Input() itemsDisabled: { [id: number]: boolean } = {};
}

describe('BaseRoutesMetadataTableComponent', () => {
let component: BaseRoutesMetadataTableComponent;
Expand All @@ -35,6 +57,7 @@ describe('BaseRoutesMetadataTableComponent', () => {
],
})
.overrideProvider(MatIconRegistry, { useFactory: () => new FakeMatIconRegistry() })
.overrideProvider(TableComponent, { useValue: new MockTableComponent() })
.compileComponents();

dataSource = jasmine.createSpyObj('dataSource', ['attach', 'connect', 'disconnect']);
Expand Down
Loading
Loading