UNPKG

5.39 kBJavaScriptView Raw
1// Copyright IBM Corp. 2014,2019. All Rights Reserved.
2// Node module: loopback-datasource-juggler
3// This file is licensed under the MIT License.
4// License text available at https://opensource.org/licenses/MIT
5
6'use strict';
7
8require('should');
9
10const GeoPoint = require('../lib/geo').GeoPoint;
11const nearFilter = require('../lib/geo').nearFilter;
12const geoFilter = require('../lib/geo').filter;
13const DELTA = 0.0000001;
14
15describe('GeoPoint', function() {
16 describe('constructor', function() {
17 it('should support a valid array', function() {
18 const point = new GeoPoint([-34, 150]);
19
20 point.lat.should.equal(-34);
21 point.lng.should.equal(150);
22 });
23
24 it('should support a valid object', function() {
25 const point = new GeoPoint({lat: -34, lng: 150});
26
27 point.lat.should.equal(-34);
28 point.lng.should.equal(150);
29 });
30
31 it('should support valid string geo coordinates', function() {
32 const point = new GeoPoint('-34,150');
33
34 point.lat.should.equal(-34);
35 point.lng.should.equal(150);
36 });
37
38 it('should support coordinates as inline parameters', function() {
39 const point = new GeoPoint(-34, 150);
40
41 point.lat.should.equal(-34);
42 point.lng.should.equal(150);
43 });
44
45 it('should reject invalid parameters', function() {
46 /* jshint -W024 */
47 let fn = function() {
48 new GeoPoint('150,-34');
49 };
50 fn.should.throw();
51
52 fn = function() {
53 new GeoPoint('invalid_string');
54 };
55 fn.should.throw();
56
57 fn = function() {
58 new GeoPoint([150, -34]);
59 };
60 fn.should.throw();
61
62 fn = function() {
63 new GeoPoint({
64 lat: 150,
65 lng: null,
66 });
67 };
68 fn.should.throw();
69
70 fn = function() {
71 new GeoPoint(150, -34);
72 };
73 fn.should.throw();
74
75 fn = function() {
76 new GeoPoint();
77 };
78 fn.should.throw();
79 });
80 });
81
82 describe('toString()', function() {
83 it('should return a string in the form "lat,lng"', function() {
84 const point = new GeoPoint({lat: -34, lng: 150});
85 point.toString().should.equal('-34,150');
86 });
87 });
88
89 describe('distance calculation between two points', function() {
90 const here = new GeoPoint({lat: 40.77492964101182, lng: -73.90950187151662});
91 const there = new GeoPoint({lat: 40.7753227, lng: -73.909217});
92
93 it('should return value in miles by default', function() {
94 const distance = GeoPoint.distanceBetween(here, there);
95 distance.should.be.a.Number;
96 distance.should.be.approximately(0.03097916611592679, DELTA);
97 });
98
99 it('should return value using specified unit', function() {
100 /* Supported units:
101 * - `radians`
102 * - `kilometers`
103 * - `meters`
104 * - `miles`
105 * - `feet`
106 * - `degrees`
107 */
108
109 let distance = here.distanceTo(there, {type: 'radians'});
110 distance.should.be.a.Number;
111 distance.should.be.approximately(0.000007825491914348416, DELTA);
112
113 distance = here.distanceTo(there, {type: 'kilometers'});
114 distance.should.be.a.Number;
115 distance.should.be.approximately(0.04985613511367009, DELTA);
116
117 distance = here.distanceTo(there, {type: 'meters'});
118 distance.should.be.a.Number;
119 distance.should.be.approximately(49.856135113670085, DELTA);
120
121 distance = here.distanceTo(there, {type: 'miles'});
122 distance.should.be.a.Number;
123 distance.should.be.approximately(0.03097916611592679, DELTA);
124
125 distance = here.distanceTo(there, {type: 'feet'});
126 distance.should.be.a.Number;
127 distance.should.be.approximately(163.56999709209347, DELTA);
128
129 distance = here.distanceTo(there, {type: 'degrees'});
130 distance.should.be.a.Number;
131 distance.should.be.approximately(0.0004483676593058972, DELTA);
132 });
133 });
134
135 describe('nearFilter()', function() {
136 it('should return a filter includes minDistance if where contains minDistance option', function() {
137 const where = {
138 location: {
139 near: {
140 lat: 40.77492964101182,
141 lng: -73.90950187151662,
142 },
143 minDistance: 100,
144 },
145 };
146 const filter = nearFilter(where);
147 filter[0].key.should.equal('location');
148 filter[0].should.have.properties({
149 key: 'location',
150 near: {
151 lat: 40.77492964101182,
152 lng: -73.90950187151662,
153 },
154 minDistance: 100,
155 });
156 });
157 });
158
159 describe('filter()', function() {
160 it('should be able to filter geo points via minDistance', function() {
161 const points = [{
162 location: {
163 lat: 30.283552,
164 lng: 120.126048,
165 },
166 }, {
167 location: {
168 lat: 30.380307,
169 lng: 119.979445,
170 },
171 }, {
172 location: {
173 lat: 30.229896,
174 lng: 119.744592,
175 },
176 }, {
177 location: {
178 lat: 30.250863,
179 lng: 120.129498,
180 },
181 }, {
182 location: {
183 lat: 31.244209,
184 lng: 121.483687,
185 },
186 }];
187 const filter = [{
188 key: 'location',
189 near: {
190 lat: 30.278562,
191 lng: 120.139846,
192 },
193 unit: 'meters',
194 minDistance: 10000,
195 }];
196 const results = geoFilter(points, filter);
197 results.length.should.be.equal(3);
198 });
199 });
200});