Skip to content

Commit

Permalink
feat(toBeMultiLineStringGeometry): add new matcher
Browse files Browse the repository at this point in the history
Verifies an object is a valid GeoJSON MultiLineString Geometry.
Fixes some API typos in
lineStringGeometry and multiPointGeometry.

Resolves: #12
  • Loading branch information
M-Scott-Lassiter committed May 28, 2022
1 parent ee5de52 commit 3d3a15e
Show file tree
Hide file tree
Showing 14 changed files with 630 additions and 9 deletions.
1 change: 1 addition & 0 deletions .cz-config.js
Expand Up @@ -8,6 +8,7 @@ const coordinateMatchers = [
{ name: 'isValidBoundingBox' },
{ name: 'isValidCoordinate' },
{ name: 'toBeLineStringGeometry' },
{ name: 'toBeMultiLineStringGeometry' },
{ name: 'toBeMultiPointGeometry' },
{ name: 'toBePointGeometry' }
]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -158,7 +158,7 @@ _1.0.0_
- [x] toBePointGeometry
- [x] toBeMultiPointGeometry
- [x] toBeLineStringGeometry
- [ ] toBeMultiLineStringGeometry
- [x] toBeMultiLineStringGeometry
- [ ] toBePolygonGeometry
- [ ] toBeMultiPolygonGeometry
- [ ] toBeAnyGeometry
Expand Down
1 change: 1 addition & 0 deletions src/core.js
Expand Up @@ -14,6 +14,7 @@ exports.coordinates = {

exports.geometries = {
lineStringGeometry: require('./core/geometries/lineStringGeometry'),
multiLineStringGeometry: require('./core/geometries/multiLineStringGeometry'),
multiPointGeometry: require('./core/geometries/multiPointGeometry'),
pointGeometry: require('./core/geometries/pointGeometry')
}
6 changes: 3 additions & 3 deletions src/core/geometries/lineStringGeometry.js
Expand Up @@ -3,15 +3,15 @@ const { validCoordinate } = require('../coordinates/validCoordinate')
/**
* Verifies an object is a valid GeoJSON LineString Geometry. This geometry requires a
* 'type' property that must equal "LineString", and a 'coordinates' property that contains
* an array of two or more valid WGS-84 GeoJSON coordinate(s). The coordinates may be an empty array,
* an array of two or more valid WGS-84 GeoJSON coordinates. The coordinates may be an empty array,
* but may not be an array of empty arrays.
*
* Foreign members are allowed with the exceptions thrown below.
*
* @memberof Core.Geometries
* @see https://github.com/M-Scott-Lassiter/jest-geojson/issues/11
* @param {object} geometryObject a GeoJSON Multi Point Geometry object
* @returns {boolean} True if a valid GeoJSON Multi Point Geometry. If invalid, it will throw an error.
* @param {object} geometryObject a GeoJSON LineString Geometry object
* @returns {boolean} True if a valid GeoJSON LineString Geometry. If invalid, it will throw an error.
* @throws {Error} Argument not an object
* @throws {Error} Must have a type property with value 'LineString'
* @throws {Error} forbidden from having a property 'geometry', 'properties', or 'features'
Expand Down
104 changes: 104 additions & 0 deletions src/core/geometries/multiLineStringGeometry.js
@@ -0,0 +1,104 @@
const { validCoordinate } = require('../coordinates/validCoordinate')

/**
* Verifies an object is a valid GeoJSON MultiLineString Geometry. This geometry requires a
* 'type' property that must equal "MultiLineString", and a 'coordinates' property that contains
* an array of linestring arrays (i.e. each linestring array containing at least two or more valid
* WGS-84 GeoJSON coordinates).
*
* The coordinates may be an empty array, but may not be an array of empty arrays.
*
* Foreign members are allowed with the exceptions thrown below.
*
* @memberof Core.Geometries
* @see https://github.com/M-Scott-Lassiter/jest-geojson/issues/12
* @param {object} geometryObject a GeoJSON MultiLineString Geometry object
* @returns {boolean} True if a valid GeoJSON MultiLineString Geometry. If invalid, it will throw an error.
* @throws {Error} Argument not an object
* @throws {Error} Must have a type property with value 'MultiLineString'
* @throws {Error} forbidden from having a property 'geometry', 'properties', or 'features'
* @example
* const multiLineString = {
"type": "MultiLineString",
"coordinates": [
[
[100.0, 0.0],
[101.0, 1.0]
],
[
[102.0, 2.0],
[103.0, 3.0]
]
]
}
const multiLineStringOneCoordinate = {
"type": "MultiLineString",
"coordinates": [
[
[100.0, 0.0]
]
]
}
const point = {
type: "Point",
coordinates: [100.0, 0.0]
}
console.log(multiLineStringGeometry(multiLineString)) // true
console.log(multiLineStringGeometry(point)) // throws error
console.log(multiLineStringGeometry(multiLineStringOneCoordinate)) // throws error
*/
function multiLineStringGeometry(geometryObject) {
if (
typeof geometryObject !== 'object' ||
Array.isArray(geometryObject) ||
geometryObject === null
) {
throw new Error('Argument must be a GeoJSON MultiLineString Geometry object.')
}

if (!('coordinates' in geometryObject)) {
throw new Error(`GeoJSON MultiLineString Geometry must contain a 'coordinates' property.`)
}

if (geometryObject.type !== 'MultiLineString') {
throw new Error(`Must have a type property with value 'MultiLineString'`)
}

if ('geometry' in geometryObject) {
throw new Error(
`GeoJSON MultiLineString Geometry objects are forbidden from having a property 'geometry'.`
)
}

if ('properties' in geometryObject) {
throw new Error(
`GeoJSON MultiLineString Geometry objects are forbidden from having a property 'properties'.`
)
}

if ('features' in geometryObject) {
throw new Error(
`GeoJSON MultiLineString Geometry objects are forbidden from having a property 'features'.`
)
}

// // // Geometry objects are allowed to have empty arrays as coordinates, however validCoordinate may not.
// // If coordinates is an empty array, we're done. Otherwise, check for coordinate validity.
// if (!Array.isArray(geometryObject.coordinates) && geometryObject.coordinates.length !== 1) {
// throw new Error('Coordinates property must be an array of valid GeoJSON coordinates')
// }

for (let i = 0; i < geometryObject.coordinates.length; i++) {
if (geometryObject.coordinates[i].length === 1) {
throw new Error('Coordinates array must contain two or more valid GeoJSON coordinates')
}
for (let j = 0; j < geometryObject.coordinates[i].length; j++) {
validCoordinate(geometryObject.coordinates[i][j])
}
}

return true
}

exports.multiLineStringGeometry = multiLineStringGeometry
7 changes: 4 additions & 3 deletions src/core/geometries/multiPointGeometry.js
Expand Up @@ -3,14 +3,15 @@ const { validCoordinate } = require('../coordinates/validCoordinate')
/**
* Verifies an object is a valid GeoJSON MultiPoint Geometry. This geometry requires a
* 'type' property that must equal "MultiPoint", and a 'coordinates' property that contains
* an array of valid WGS-84 GeoJSON coordinate(s). The coordinates may be an empty array.
* a single coordinate or an array of valid WGS-84 GeoJSON coordinates.
* The coordinates may be an empty array.
*
* Foreign members are allowed with the exceptions thrown below.
*
* @memberof Core.Geometries
* @see https://github.com/M-Scott-Lassiter/jest-geojson/issues/10
* @param {object} geometryObject a GeoJSON Multi Point Geometry object
* @returns {boolean} True if a valid GeoJSON Multi Point Geometry. If invalid, it will throw an error.
* @param {object} geometryObject a GeoJSON MultiPoint Geometry object
* @returns {boolean} True if a valid GeoJSON MultiPoint Geometry. If invalid, it will throw an error.
* @throws {Error} Argument not an object
* @throws {Error} Must have a type property with value 'MultiPoint'
* @throws {Error} forbidden from having a property 'geometry', 'properties', or 'features'
Expand Down
2 changes: 2 additions & 0 deletions src/matchers.js
Expand Up @@ -24,6 +24,8 @@ exports.coordinates = {
exports.geometries = {
toBeLineStringGeometry: require('./matchers/geometries/toBeLineStringGeometry')
.toBeLineStringGeometry,
toBeMultiLineStringGeometry: require('./matchers/geometries/toBeMultiLineStringGeometry')
.toBeMultiLineStringGeometry,
toBeMultiPointGeometry: require('./matchers/geometries/toBeMultiPointGeometry')
.toBeMultiPointGeometry,
toBePointGeometry: require('./matchers/geometries/toBePointGeometry').toBePointGeometry
Expand Down
2 changes: 1 addition & 1 deletion src/matchers/geometries/toBeLineStringGeometry.js
Expand Up @@ -11,7 +11,7 @@ const { lineStringGeometry } = require('../../core/geometries/lineStringGeometry
*
* @memberof Matchers.Geometries
* @see https://github.com/M-Scott-Lassiter/jest-geojson/issues/11
* @param {object} geometryObject a GeoJSON MultiPoint Geometry object
* @param {object} geometryObject a GeoJSON LineString Geometry object
* @example
const linestring = {
"type": "LineString",
Expand Down
83 changes: 83 additions & 0 deletions src/matchers/geometries/toBeMultiLineStringGeometry.js
@@ -0,0 +1,83 @@
const { multiLineStringGeometry } = require('../../core/geometries/multiLineStringGeometry')

// eslint-disable-next-line jsdoc/require-returns
/**
* Verifies an object is a valid GeoJSON MultiLineString Geometry. This geometry requires a
* 'type' property that must equal "MultiLineString", and a 'coordinates' property that contains
* an array of linestring arrays (i.e. each linestring array containing at least two or more valid
* WGS-84 GeoJSON coordinates).
*
* The coordinates may be an empty array, but may not be an array of empty arrays.
*
* Foreign members are allowed with the exception of 'geometry', 'properties', or 'features'.
*
* @memberof Matchers.Geometries
* @see https://github.com/M-Scott-Lassiter/jest-geojson/issues/12
* @param {object} geometryObject a GeoJSON MultiLineString Geometry object
* @example
const multiLineString = {
"type": "MultiLineString",
"coordinates": [
[
[100.0, 0.0],
[101.0, 1.0]
],
[
[102.0, 2.0],
[103.0, 3.0]
]
]
}
const multiLineStringOneCoordinate = {
"type": "MultiLineString",
"coordinates": [
[
[100.0, 0.0]
]
]
}
const point = {
type: "Point",
coordinates: [100.0, 0.0]
}
expect(multiLineString).toBeMultiLineStringGeometry()
expect(point).not.toBeMultiLineStringGeometry()
expect(multiLineStringOneCoordinate).not.toBeMultiLineStringGeometry()
*/
function toBeMultiLineStringGeometry(geometryObject) {
const { printReceived, matcherHint } = this.utils
const passMessage =
// eslint-disable-next-line prefer-template
matcherHint('.not.toBeMultiLineStringGeometry', 'GeometryObject', '') +
'\n\n' +
`Expected input to not be a valid GeoJSON MultiLineString geometry.\n\n` +
`Received: ${printReceived(geometryObject)}`

/**
* Combines a custom error message with built in Jest tools to provide a more descriptive error
* meessage to the end user.
*
* @param {string} errorMessage Error message text to return to the user
* @returns {string} Concatenated Jest test result string
*/
function failMessage(errorMessage) {
return (
// eslint-disable-next-line prefer-template, no-unused-expressions
matcherHint('.toBeMultiLineStringGeometry', 'GeometryObject', '') +
'\n\n' +
`${errorMessage}\n\n` +
`Received: ${printReceived(geometryObject)}`
)
}

try {
multiLineStringGeometry(geometryObject)
} catch (err) {
return { pass: false, message: () => failMessage(err.message) }
}
return { pass: true, message: () => passMessage }
}

exports.toBeMultiLineStringGeometry = toBeMultiLineStringGeometry
4 changes: 4 additions & 0 deletions tests/core.test.js
Expand Up @@ -35,6 +35,10 @@ describe('Geometry Functions Exported', () => {
expect('lineStringGeometry' in core.geometries).toBeTruthy()
})

test('multiLineStringGeometry', () => {
expect('multiLineStringGeometry' in core.geometries).toBeTruthy()
})

test('multiPointGeometry', () => {
expect('multiPointGeometry' in core.geometries).toBeTruthy()
})
Expand Down
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Error Snapshot Testing. Throws error: expect({type: 'MultiLineString', coordinates: [[[0, 0], [1, 1]]]}).not.toBeMultiLineStringGeometry 1`] = `
"expect(GeometryObject).not.toBeMultiLineStringGeometry()
Expected input to not be a valid GeoJSON MultiLineString geometry.
Received: {\\"coordinates\\": [[[0, 0], [1, 1]]], \\"type\\": \\"MultiLineString\\"}"
`;

exports[`Error Snapshot Testing. Throws error: expect(false).toBeMultiLineStringGeometry() 1`] = `
"expect(GeometryObject).toBeMultiLineStringGeometry()
Argument must be a GeoJSON MultiLineString Geometry object.
Received: false"
`;
2 changes: 1 addition & 1 deletion tests/geometries/toBeLineStringGeometry.test.js
Expand Up @@ -21,7 +21,7 @@ const invalidInputValues = [
'[0, 0]',
'[[0, 0], [0, 0]]',
JSON.stringify({
type: 'Point',
type: 'LineString',
coordinates: [
[25, 90],
[2, 2]
Expand Down

0 comments on commit 3d3a15e

Please sign in to comment.