test: custom jest assertion for coordinate/bounds validation (#303)

This commit is contained in:
Peter Johnson
2021-10-12 12:42:55 +02:00
committed by GitHub
parent 14d9670bfa
commit f14dc0dd22
12 changed files with 111 additions and 41 deletions

View File

@@ -15,6 +15,7 @@ module.exports = {
}, },
automock: false, automock: false,
setupFiles: ['./jest.setup.js'], setupFiles: ['./jest.setup.js'],
setupFilesAfterEnv: ['./jest.extend.js'],
globals: { globals: {
'ts-jest': { 'ts-jest': {
tsConfig: { tsConfig: {

100
jest.extend.js Normal file
View File

@@ -0,0 +1,100 @@
function toBeValidCoordinate(coord) {
// coordinate must have two dimensions
if (!Array.isArray(coord) || coord.length !== 2) {
return {
pass: false,
message: `coordinate must have two dimensions`,
};
}
// coordinate dimensions must be valid numbers
if (
typeof coord[0] !== 'number' ||
isNaN(coord[0]) ||
typeof coord[1] !== 'number' ||
isNaN(coord[1])
) {
return {
pass: false,
message: `coordinate dimensions must be valid numbers`,
};
}
// coordinate valid
return {
pass: true,
message: `coordinate valid`,
};
}
function toBeValidBounds(bounds) {
// null bounds are valid
if (bounds === null) {
return {
pass: true,
message: `null bounds are valid`,
};
}
// bounds must be a coordinate pair
if (!Array.isArray(bounds) || bounds.length !== 2) {
return {
pass: false,
message: `bounds must be a coordinate pair`,
};
}
// validate south-west
const validateSW = toBeValidCoordinate(bounds[0]);
if (!validateSW.pass) {
return validateSW;
}
// validate north-east
const validateNE = toBeValidCoordinate(bounds[1]);
if (!validateNE.pass) {
return validateNE;
}
// corners
const [south, west] = bounds[0];
const [north, east] = bounds[1];
// bounds represents a point
// note: this is not really a valid bounds but we will allow it
if (south === north && west === east) {
return {
pass: true,
message: `bounds represents a point`,
};
}
// west should be less than or equal to east
// @note: this is not the strictly case for bounds which cross the antimeridian
if (west > east) {
return {
pass: false,
message: `west should be less than or equal to east`,
};
}
// south should be less than or equal to north
// @note: this is not the strictly case for bounds which cross a pole
if (south > north) {
return {
pass: false,
message: `south should be less than or equal to north`,
};
}
// bounds valid
return {
pass: true,
message: `bounds valid`,
};
}
expect.extend({
toBeValidCoordinate,
toBeValidBounds,
});

View File

@@ -15,5 +15,6 @@ describe('AlgoliaProvider', () => {
expect(result.label).toBeTruthy(); expect(result.label).toBeTruthy();
expect(result.x).toEqual(fixtures.hits[0]._geoloc.lng); expect(result.x).toEqual(fixtures.hits[0]._geoloc.lng);
expect(result.y).toEqual(fixtures.hits[0]._geoloc.lat); expect(result.y).toEqual(fixtures.hits[0]._geoloc.lat);
expect(result.bounds).toBeValidBounds();
}); });
}); });

View File

@@ -56,10 +56,7 @@ describe('BingProvider', () => {
expect(result.y).toEqual( expect(result.y).toEqual(
fixtures.resourceSets[0].resources[0].point.coordinates[0], fixtures.resourceSets[0].resources[0].point.coordinates[0],
); );
expect(result.bounds[0][0]).toBeGreaterThan(result.bounds[0][1]); expect(result.bounds).toBeValidBounds();
expect(result.bounds[1][0]).toBeGreaterThan(result.bounds[1][1]);
expect(result.bounds[0][0]).toBeLessThan(result.bounds[1][0]);
expect(result.bounds[0][1]).toBeLessThan(result.bounds[1][1]);
}); });
test.skip('Can get localized results', async () => { test.skip('Can get localized results', async () => {

View File

@@ -15,9 +15,6 @@ describe('EsriProvider', () => {
expect(result.label).toBeTruthy(); expect(result.label).toBeTruthy();
expect(result.x).toEqual(fixtures.locations[0].feature.geometry.x); expect(result.x).toEqual(fixtures.locations[0].feature.geometry.x);
expect(result.y).toEqual(fixtures.locations[0].feature.geometry.y); expect(result.y).toEqual(fixtures.locations[0].feature.geometry.y);
expect(result.bounds[0][0]).toBeGreaterThan(result.bounds[0][1]); expect(result.bounds).toBeValidBounds();
expect(result.bounds[1][0]).toBeGreaterThan(result.bounds[1][1]);
expect(result.bounds[0][0]).toBeLessThan(result.bounds[1][0]);
expect(result.bounds[0][1]).toBeLessThan(result.bounds[1][1]);
}); });
}); });

View File

@@ -17,14 +17,7 @@ describe('GeocodeEarthProvider', function () {
expect(result.label).toBeTruthy(); expect(result.label).toBeTruthy();
expect(result.x).toEqual(+feat.geometry.coordinates[0]); expect(result.x).toEqual(+feat.geometry.coordinates[0]);
expect(result.y).toEqual(+feat.geometry.coordinates[1]); expect(result.y).toEqual(+feat.geometry.coordinates[1]);
expect(result.bounds).toBeValidBounds();
// bounding box range checks
if (feat.bbox) {
expect(result.bounds[0][0]).toBeLessThan(result.bounds[1][0]); // south less than north
expect(result.bounds[0][1]).toBeLessThan(result.bounds[1][1]); // west less than east
} else {
expect(result.bounds).toBeFalsy();
}
}); });
}); });
}); });

View File

@@ -19,10 +19,7 @@ describe('GoogleProvider', () => {
expect(result.label).toBeTruthy(); expect(result.label).toBeTruthy();
expect(result.x).toEqual(fixtures.results[0].geometry.location.lng); expect(result.x).toEqual(fixtures.results[0].geometry.location.lng);
expect(result.y).toEqual(fixtures.results[0].geometry.location.lat); expect(result.y).toEqual(fixtures.results[0].geometry.location.lat);
expect(result.bounds[0][0]).toBeGreaterThan(result.bounds[0][1]); expect(result.bounds).toBeValidBounds();
expect(result.bounds[1][0]).toBeGreaterThan(result.bounds[1][1]);
expect(result.bounds[0][0]).toBeLessThan(result.bounds[1][0]);
expect(result.bounds[0][1]).toBeLessThan(result.bounds[1][1]);
}); });
test.skip('Can get localized results', async () => { test.skip('Can get localized results', async () => {

View File

@@ -20,6 +20,6 @@ describe('HereProvider', () => {
expect(result.x).toEqual(+fixtures.items[0].position.lng); expect(result.x).toEqual(+fixtures.items[0].position.lng);
expect(result.y).toEqual(+fixtures.items[0].position.lat); expect(result.y).toEqual(+fixtures.items[0].position.lat);
// here provider doesn't return bounds :( // here provider doesn't return bounds :(
expect(result.bounds).toBeFalsy(); expect(result.bounds).toBeValidBounds();
}); });
}); });

View File

@@ -19,10 +19,7 @@ describe('LocationIQProvider', () => {
expect(result.label).toBeTruthy(); expect(result.label).toBeTruthy();
expect(result.x).toEqual(+fixtures[0].lon); expect(result.x).toEqual(+fixtures[0].lon);
expect(result.y).toEqual(+fixtures[0].lat); expect(result.y).toEqual(+fixtures[0].lat);
expect(result.bounds[0][0]).toBeGreaterThan(result.bounds[0][1]); expect(result.bounds).toBeValidBounds();
expect(result.bounds[1][0]).toBeGreaterThan(result.bounds[1][1]);
expect(result.bounds[0][0]).toBeLessThan(result.bounds[1][0]);
expect(result.bounds[0][1]).toBeLessThan(result.bounds[1][1]);
}); });
test.skip('Can get localized results', async () => { test.skip('Can get localized results', async () => {

View File

@@ -13,10 +13,7 @@ test.skip('Can fetch results with OpenCage', async () => {
t.truthy(result.label); t.truthy(result.label);
t.true(result.x > 5 && result.x < 6); t.true(result.x > 5 && result.x < 6);
t.true(result.y > 50 && result.y < 55); t.true(result.y > 50 && result.y < 55);
t.true(result.bounds[0][0] > result.bounds[0][1]); expect(result.bounds).toBeValidBounds();
t.true(result.bounds[1][0] > result.bounds[1][1]);
t.true(result.bounds[0][0] < result.bounds[1][0]);
t.true(result.bounds[0][1] < result.bounds[1][1]);
}); });
test.skip('Can get localized results', async () => { test.skip('Can get localized results', async () => {

View File

@@ -15,10 +15,7 @@ describe('OpenStreetMapProvider', function () {
expect(result.label).toBeTruthy(); expect(result.label).toBeTruthy();
expect(result.x).toEqual(+fixtures[0].lon); expect(result.x).toEqual(+fixtures[0].lon);
expect(result.y).toEqual(+fixtures[0].lat); expect(result.y).toEqual(+fixtures[0].lat);
expect(result.bounds[0][0]).toBeGreaterThan(result.bounds[0][1]); expect(result.bounds).toBeValidBounds();
expect(result.bounds[1][0]).toBeGreaterThan(result.bounds[1][1]);
expect(result.bounds[0][0]).toBeLessThan(result.bounds[1][0]);
expect(result.bounds[0][1]).toBeLessThan(result.bounds[1][1]);
}); });
test.skip('Can get localized results', async () => { test.skip('Can get localized results', async () => {

View File

@@ -17,14 +17,7 @@ describe('PeliasProvider', function () {
expect(result.label).toBeTruthy(); expect(result.label).toBeTruthy();
expect(result.x).toEqual(+feat.geometry.coordinates[0]); expect(result.x).toEqual(+feat.geometry.coordinates[0]);
expect(result.y).toEqual(+feat.geometry.coordinates[1]); expect(result.y).toEqual(+feat.geometry.coordinates[1]);
expect(result.bounds).toBeValidBounds();
// bounding box range checks
if (feat.bbox) {
expect(result.bounds[0][0]).toBeLessThan(result.bounds[1][0]); // south less than north
expect(result.bounds[0][1]).toBeLessThan(result.bounds[1][1]); // west less than east
} else {
expect(result.bounds).toBeFalsy();
}
}); });
}); });
}); });