Skip to content

Commit 0c10828

Browse files
mbehrlichjelbourn
authored andcommitted
feat(google-maps): Add MapPolyline component (#17512)
1 parent 7f70c21 commit 0c10828

File tree

8 files changed

+457
-2
lines changed

8 files changed

+457
-2
lines changed

src/dev-app/google-map/google-map-demo.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,19 @@
1313
[options]="markerOptions"
1414
(mapClick)="clickMarker(marker)"></map-marker>
1515
<map-info-window>Testing 1 2 3</map-info-window>
16+
<map-polyline *ngIf="isPolylineDisplayed" [options]="polylineOptions"></map-polyline>
1617
</google-map>
1718

1819
<p><label>Latitude:</label> {{display?.lat}}</p>
1920
<p><label>Longitude:</label> {{display?.lng}}</p>
21+
22+
<div>
23+
<label for="polyline-checkbox">Toggle Polyline</label>
24+
<input id="polyline-checkbox" type="checkbox" (click)="togglePolylineDisplay()">
25+
</div>
26+
<div>
27+
<label for="editable-polyline-checkbox">Toggle Editable Polyline</label>
28+
<input id="editable-polyline-checkbox" type="checkbox" (click)="toggleEditablePolyline()">
29+
</div>
30+
2031
</div>

src/dev-app/google-map/google-map-demo.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import {Component, ViewChild} from '@angular/core';
1010
import {MapInfoWindow, MapMarker} from '@angular/google-maps';
1111

12+
const POLYLINE_PATH: google.maps.LatLngLiteral[] =
13+
[{lat: 25, lng: 26}, {lat: 26, lng: 27}, {lat: 30, lng: 34}];
14+
1215
/** Demo Component for @angular/google-maps/map */
1316
@Component({
1417
selector: 'google-map-demo',
@@ -23,6 +26,9 @@ export class GoogleMapDemo {
2326
markerPositions: google.maps.LatLngLiteral[] = [];
2427
zoom = 4;
2528
display?: google.maps.LatLngLiteral;
29+
isPolylineDisplayed = false;
30+
polylineOptions:
31+
google.maps.PolylineOptions = {path: POLYLINE_PATH, strokeColor: 'grey', strokeOpacity: 0.8};
2632

2733
handleClick(event: google.maps.MouseEvent) {
2834
this.markerPositions.push(event.latLng.toJSON());
@@ -39,4 +45,12 @@ export class GoogleMapDemo {
3945
handleRightclick() {
4046
this.markerPositions.pop();
4147
}
48+
49+
togglePolylineDisplay() {
50+
this.isPolylineDisplayed = !this.isPolylineDisplayed;
51+
}
52+
53+
toggleEditablePolyline() {
54+
this.polylineOptions = {...this.polylineOptions, editable: !this.polylineOptions.editable};
55+
}
4256
}

src/google-maps/google-maps-module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ import {NgModule} from '@angular/core';
1111
import {GoogleMap} from './google-map/google-map';
1212
import {MapInfoWindow} from './map-info-window/map-info-window';
1313
import {MapMarker} from './map-marker/map-marker';
14+
import {MapPolyline} from './map-polyline/map-polyline';
1415

1516
const COMPONENTS = [
1617
GoogleMap,
1718
MapInfoWindow,
1819
MapMarker,
20+
MapPolyline,
1921
];
2022

2123
@NgModule({
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import {Component} from '@angular/core';
2+
import {async, TestBed} from '@angular/core/testing';
3+
import {By} from '@angular/platform-browser';
4+
5+
import {DEFAULT_OPTIONS, UpdatedGoogleMap} from '../google-map/google-map';
6+
import {GoogleMapsModule} from '../google-maps-module';
7+
import {
8+
createMapConstructorSpy,
9+
createMapSpy,
10+
createPolylineConstructorSpy,
11+
createPolylineSpy,
12+
TestingWindow,
13+
} from '../testing/fake-google-map-utils';
14+
15+
import {MapPolyline} from './map-polyline';
16+
17+
describe('MapPolyline', () => {
18+
let mapSpy: jasmine.SpyObj<UpdatedGoogleMap>;
19+
let polylinePath: google.maps.LatLngLiteral[];
20+
let polylineOptions: google.maps.PolylineOptions;
21+
22+
beforeEach(async(() => {
23+
polylinePath = [{ lat: 25, lng: 26 }, { lat: 26, lng: 27 }, { lat: 30, lng: 34 }];
24+
polylineOptions = {
25+
path: polylinePath,
26+
strokeColor: 'grey',
27+
strokeOpacity: 0.8
28+
};
29+
TestBed.configureTestingModule({
30+
imports: [GoogleMapsModule],
31+
declarations: [TestApp],
32+
});
33+
}));
34+
35+
beforeEach(() => {
36+
TestBed.compileComponents();
37+
38+
mapSpy = createMapSpy(DEFAULT_OPTIONS);
39+
createMapConstructorSpy(mapSpy).and.callThrough();
40+
});
41+
42+
afterEach(() => {
43+
const testingWindow: TestingWindow = window;
44+
delete testingWindow.google;
45+
});
46+
47+
it('initializes a Google Map Polyline', () => {
48+
const polylineSpy = createPolylineSpy({});
49+
const polylineConstructorSpy = createPolylineConstructorSpy(polylineSpy).and.callThrough();
50+
51+
const fixture = TestBed.createComponent(TestApp);
52+
fixture.detectChanges();
53+
54+
expect(polylineConstructorSpy).toHaveBeenCalledWith({path: undefined});
55+
expect(polylineSpy.setMap).toHaveBeenCalledWith(mapSpy);
56+
});
57+
58+
it('sets path from input', () => {
59+
const path: google.maps.LatLngLiteral[] = [{lat: 3, lng: 5}];
60+
const options: google.maps.PolylineOptions = {path};
61+
const polylineSpy = createPolylineSpy(options);
62+
const polylineConstructorSpy = createPolylineConstructorSpy(polylineSpy).and.callThrough();
63+
64+
const fixture = TestBed.createComponent(TestApp);
65+
fixture.componentInstance.path = path;
66+
fixture.detectChanges();
67+
68+
expect(polylineConstructorSpy).toHaveBeenCalledWith(options);
69+
});
70+
71+
it('gives precedence to path input over options', () => {
72+
const path: google.maps.LatLngLiteral[] = [{lat: 3, lng: 5}];
73+
const expectedOptions: google.maps.PolylineOptions = {...polylineOptions, path};
74+
const polylineSpy = createPolylineSpy(expectedOptions);
75+
const polylineConstructorSpy = createPolylineConstructorSpy(polylineSpy).and.callThrough();
76+
77+
const fixture = TestBed.createComponent(TestApp);
78+
fixture.componentInstance.options = polylineOptions;
79+
fixture.componentInstance.path = path;
80+
fixture.detectChanges();
81+
82+
expect(polylineConstructorSpy).toHaveBeenCalledWith(expectedOptions);
83+
});
84+
85+
it('exposes methods that provide information about the Polyline', () => {
86+
const polylineSpy = createPolylineSpy(polylineOptions);
87+
createPolylineConstructorSpy(polylineSpy).and.callThrough();
88+
89+
const fixture = TestBed.createComponent(TestApp);
90+
const polylineComponent = fixture.debugElement.query(By.directive(
91+
MapPolyline))!.injector.get<MapPolyline>(MapPolyline);
92+
fixture.detectChanges();
93+
94+
polylineSpy.getDraggable.and.returnValue(true);
95+
expect(polylineComponent.getDraggable()).toBe(true);
96+
97+
polylineSpy.getEditable.and.returnValue(true);
98+
expect(polylineComponent.getEditable()).toBe(true);
99+
100+
polylineComponent.getPath();
101+
expect(polylineSpy.getPath).toHaveBeenCalled();
102+
103+
polylineSpy.getVisible.and.returnValue(true);
104+
expect(polylineComponent.getVisible()).toBe(true);
105+
});
106+
107+
it('initializes Polyline event handlers', () => {
108+
const polylineSpy = createPolylineSpy(polylineOptions);
109+
createPolylineConstructorSpy(polylineSpy).and.callThrough();
110+
111+
const fixture = TestBed.createComponent(TestApp);
112+
fixture.detectChanges();
113+
114+
expect(polylineSpy.addListener).toHaveBeenCalledWith('click', jasmine.any(Function));
115+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('dblclick', jasmine.any(Function));
116+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('drag', jasmine.any(Function));
117+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('dragend', jasmine.any(Function));
118+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('dragstart', jasmine.any(Function));
119+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('mousedown', jasmine.any(Function));
120+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('mousemove', jasmine.any(Function));
121+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('mouseout', jasmine.any(Function));
122+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('mouseover', jasmine.any(Function));
123+
expect(polylineSpy.addListener).not.toHaveBeenCalledWith('mouseup', jasmine.any(Function));
124+
expect(polylineSpy.addListener).toHaveBeenCalledWith('rightclick', jasmine.any(Function));
125+
});
126+
});
127+
128+
@Component({
129+
selector: 'test-app',
130+
template: `<google-map>
131+
<map-polyline [options]="options"
132+
[path]="path"
133+
(polylineClick)="handleClick()"
134+
(polylineRightclick)="handleRightclick()">
135+
</map-polyline>
136+
</google-map>`,
137+
})
138+
class TestApp {
139+
options?: google.maps.PolylineOptions;
140+
path?: google.maps.LatLngLiteral[];
141+
142+
handleClick() {}
143+
144+
handleRightclick() {}
145+
}

0 commit comments

Comments
 (0)