From cefddd674204402299f569bfbb2df21287a2c8e9 Mon Sep 17 00:00:00 2001 From: M-Scott-Lassiter Date: Wed, 8 Jun 2022 08:07:28 -0700 Subject: [PATCH] feat(toHaveStringID): add new matcher Checks if a GeoJSON Feature has a string ID. Passes if the Feature object has any string ID (no argument provided), or if the ID exactly matches the optional argument (single string or RegExp provided), or any value within an array of any combination of strings or RegExp. The test fails if the object does not have an ID, or if it has an ID that does not match the SearchID. Passing a number type to SearchID will not pass the test, even if the ID exactly matches. Resolves: #37 --- .cz-config.js | 3 +- README.md | 2 +- docs/Core.BoundingBoxes.html | 3 + docs/Core.Coordinates.html | 3 + docs/Core.FeatureCollections.html | 3 + docs/Core.Features.html | 3 + docs/Core.Geometries.html | 3 + docs/Core.Utilities.html | 3 + docs/Core.html | 3 + docs/Matchers.BoundingBoxes.html | 3 + docs/Matchers.Coordinates.html | 3 + docs/Matchers.FeatureCollections.html | 3 + docs/Matchers.Features.html | 142 ++++++ docs/Matchers.Functional.html | 3 + docs/Matchers.Geometries.html | 3 + docs/Matchers.html | 3 + ...e_boundingBoxes_valid2DBoundingBox.js.html | 3 + ...e_boundingBoxes_valid3DBoundingBox.js.html | 3 + ...ore_boundingBoxes_validBoundingBox.js.html | 3 + ...core_coordinates_valid2DCoordinate.js.html | 3 + ...core_coordinates_valid3DCoordinate.js.html | 3 + docs/core_coordinates_validCoordinate.js.html | 3 + ...atureCollections_featureCollection.js.html | 3 + docs/core_features_feature.js.html | 3 + docs/core_features_hasID.js.html | 3 + docs/core_geometries_anyGeometry.js.html | 3 + ...core_geometries_geometryCollection.js.html | 3 + ...core_geometries_lineStringGeometry.js.html | 3 + ...geometries_multiLineStringGeometry.js.html | 3 + ...core_geometries_multiPointGeometry.js.html | 3 + ...re_geometries_multiPolygonGeometry.js.html | 3 + docs/core_geometries_pointGeometry.js.html | 3 + docs/core_geometries_polygonGeometry.js.html | 3 + ...utilities_commonGeometryValidation.js.html | 3 + docs/core_utilities_validGeoJSON.js.html | 3 + docs/index.html | 12 +- ...boundingBoxes_isValid2DBoundingBox.js.html | 3 + ...boundingBoxes_isValid3DBoundingBox.js.html | 3 + ...s_boundingBoxes_isValidBoundingBox.js.html | 3 + ...rs_coordinates_isValid2DCoordinate.js.html | 3 + ...rs_coordinates_isValid3DCoordinate.js.html | 3 + ...hers_coordinates_isValidCoordinate.js.html | 3 + ...eCollections_toBeFeatureCollection.js.html | 3 + docs/matchers_features_toBeFeature.js.html | 3 + docs/matchers_features_toHaveID.js.html | 3 + docs/matchers_features_toHaveStringID.js.html | 426 ++++++++++++++++++ ...tchers_functional_toBeValidGeoJSON.js.html | 3 + ...atchers_geometries_toBeAnyGeometry.js.html | 3 + ..._geometries_toBeGeometryCollection.js.html | 3 + ..._geometries_toBeLineStringGeometry.js.html | 3 + ...etries_toBeMultiLineStringGeometry.js.html | 3 + ..._geometries_toBeMultiPointGeometry.js.html | 3 + ...eometries_toBeMultiPolygonGeometry.js.html | 3 + ...chers_geometries_toBePointGeometry.js.html | 3 + ...ers_geometries_toBePolygonGeometry.js.html | 3 + docs/typedefinitions.js.html | 3 + src/matchers.js | 3 +- src/matchers/features/toHaveStringID.js | 110 +++++ .../__snapshots__/toHaveStringID.test.js.snap | 57 +++ tests/features/toHaveStringID.test.js | 251 +++++++++++ tests/matchers.test.js | 4 + 61 files changed, 1158 insertions(+), 5 deletions(-) create mode 100644 docs/matchers_features_toHaveStringID.js.html create mode 100644 src/matchers/features/toHaveStringID.js create mode 100644 tests/features/__snapshots__/toHaveStringID.test.js.snap create mode 100644 tests/features/toHaveStringID.test.js diff --git a/.cz-config.js b/.cz-config.js index 51e675c..39b9ddc 100644 --- a/.cz-config.js +++ b/.cz-config.js @@ -18,7 +18,8 @@ const allMatchers = [ { name: 'toBePointGeometry' }, { name: 'toBePolygonGeometry' }, { name: 'toBeValidGeoJSON' }, - { name: 'toHaveID' } + { name: 'toHaveID' }, + { name: 'toHaveStringID' } ] const documentationScopes = [ diff --git a/README.md b/README.md index 2f42168..28b7526 100644 --- a/README.md +++ b/README.md @@ -157,12 +157,12 @@ _Future_ - [toBeFeature](https://m-scott-lassiter.github.io/jest-geojson/Matchers.Features.html#.toBeFeature) - [toHaveID](https://m-scott-lassiter.github.io/jest-geojson/Matchers.Features.html#.toHaveID) +- [toHaveStringID](https://m-scott-lassiter.github.io/jest-geojson/Matchers.Features.html#.toHaveStringID) --- _Future_ -- [ ] toHaveStringID - [ ] toHaveNumericID - [ ] toHaveProperties (array of [property, optional values]) diff --git a/docs/Core.BoundingBoxes.html b/docs/Core.BoundingBoxes.html index 51ebfdc..67cb299 100644 --- a/docs/Core.BoundingBoxes.html +++ b/docs/Core.BoundingBoxes.html @@ -224,6 +224,9 @@

Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Core.Coordinates.html b/docs/Core.Coordinates.html index f856c6a..581250a 100644 --- a/docs/Core.Coordinates.html +++ b/docs/Core.Coordinates.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Core.FeatureCollections.html b/docs/Core.FeatureCollections.html index e21829e..ca5b375 100644 --- a/docs/Core.FeatureCollections.html +++ b/docs/Core.FeatureCollections.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Core.Features.html b/docs/Core.Features.html index e85ee59..57f1b95 100644 --- a/docs/Core.Features.html +++ b/docs/Core.Features.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Core.Geometries.html b/docs/Core.Geometries.html index 678f892..44d8791 100644 --- a/docs/Core.Geometries.html +++ b/docs/Core.Geometries.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Core.Utilities.html b/docs/Core.Utilities.html index 6cbd22c..82431d7 100644 --- a/docs/Core.Utilities.html +++ b/docs/Core.Utilities.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Core.html b/docs/Core.html index 23b74d9..1e0ddd4 100644 --- a/docs/Core.html +++ b/docs/Core.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Matchers.BoundingBoxes.html b/docs/Matchers.BoundingBoxes.html index 007af95..3de0ef8 100644 --- a/docs/Matchers.BoundingBoxes.html +++ b/docs/Matchers.BoundingBoxes.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Matchers.Coordinates.html b/docs/Matchers.Coordinates.html index 70b8e95..63fb374 100644 --- a/docs/Matchers.Coordinates.html +++ b/docs/Matchers.Coordinates.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Matchers.FeatureCollections.html b/docs/Matchers.FeatureCollections.html index 66c449e..4369d38 100644 --- a/docs/Matchers.FeatureCollections.html +++ b/docs/Matchers.FeatureCollections.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Matchers.Features.html b/docs/Matchers.Features.html index a3f6952..b3f0199 100644 --- a/docs/Matchers.Features.html +++ b/docs/Matchers.Features.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • @@ -584,6 +587,145 @@
    Parameters:
    + +

    + (static) toHaveStringID(featureObject, SearchIDopt) +

    + +
    +
    Source:
    +
    + +
    + +
    See:
    +
    + +
    +
    + +
    + Checks if a GeoJSON Feature has a string ID. Passes if the Feature object + has any string ID (no argument provided), or if the ID exactly matches the + optional argument (single string or RegExp provided), or any value within an + array of any combination of strings or RegExp. The test fails if the object + does not have an ID, or if it has an ID that does not match the SearchID. + Passing a number type to SearchID will not pass the test, even if the ID + exactly matches. +
    + +
    Examples
    + +
    const testFeature = {
    +    type: 'Feature',
    +    id: 'f1',
    +    geometry: {...},
    +    properties: {...}
    +}
    +
    +test('Feature Has an ID', () => {
    +    expect(testFeature).toHaveStringID()
    +    expect(testFeature).toHaveStringID([])
    +    expect(testFeature).toHaveStringID('f1')
    +    expect(testFeature).toHaveStringID(['1', 'F', 'F12', /[a-z]+[0-9]+/])
    +
    +    expect(testFeature).not.toHaveStringID('f2')
    +    expect(testFeature).not.toHaveStringID([1, 'F', 'F12', /SomeID/])
    +})
    + +
    const testFeatureNoID = {
    +    type: 'Feature',
    +    geometry: {...},
    +    properties: {...}
    +}
    +const testFeatureNumID = {
    +    type: 'Feature',
    +    id: 2,
    +    geometry: {...},
    +    properties: {...}
    +}
    +
    +test('Feature Does not Have an ID', () => {
    +    expect(testFeature).not.toHaveStringID('f2')
    +    expect(testFeature).not.toHaveStringID([1, 'F', 'F12', /SomeID/])
    +
    +    expect(testFeatureNoID).not.toHaveStringID()
    +    expect(testFeatureNumID).not.toHaveStringID()
    +    expect(testFeatureNumID).not.toHaveStringID(2)
    +})
    + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDescription
    featureObject + object + any GeoJSON Feature object
    SearchID + string + | + + RegExp + | + + Array.<string> + | + + Array.<RegExp> + <optional>
    + Specific value or array of possible values to search for. +
    diff --git a/docs/Matchers.Functional.html b/docs/Matchers.Functional.html index 8d72843..33f6f34 100644 --- a/docs/Matchers.Functional.html +++ b/docs/Matchers.Functional.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Matchers.Geometries.html b/docs/Matchers.Geometries.html index d235dab..f73c5b6 100644 --- a/docs/Matchers.Geometries.html +++ b/docs/Matchers.Geometries.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/Matchers.html b/docs/Matchers.html index 017697c..21367c2 100644 --- a/docs/Matchers.html +++ b/docs/Matchers.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_boundingBoxes_valid2DBoundingBox.js.html b/docs/core_boundingBoxes_valid2DBoundingBox.js.html index f144648..63220fd 100644 --- a/docs/core_boundingBoxes_valid2DBoundingBox.js.html +++ b/docs/core_boundingBoxes_valid2DBoundingBox.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_boundingBoxes_valid3DBoundingBox.js.html b/docs/core_boundingBoxes_valid3DBoundingBox.js.html index 73d2551..1e636e6 100644 --- a/docs/core_boundingBoxes_valid3DBoundingBox.js.html +++ b/docs/core_boundingBoxes_valid3DBoundingBox.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_boundingBoxes_validBoundingBox.js.html b/docs/core_boundingBoxes_validBoundingBox.js.html index aaa70f1..f9e7f56 100644 --- a/docs/core_boundingBoxes_validBoundingBox.js.html +++ b/docs/core_boundingBoxes_validBoundingBox.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_coordinates_valid2DCoordinate.js.html b/docs/core_coordinates_valid2DCoordinate.js.html index fe83120..400b968 100644 --- a/docs/core_coordinates_valid2DCoordinate.js.html +++ b/docs/core_coordinates_valid2DCoordinate.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_coordinates_valid3DCoordinate.js.html b/docs/core_coordinates_valid3DCoordinate.js.html index a7e2625..9f1b77b 100644 --- a/docs/core_coordinates_valid3DCoordinate.js.html +++ b/docs/core_coordinates_valid3DCoordinate.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_coordinates_validCoordinate.js.html b/docs/core_coordinates_validCoordinate.js.html index fdda15f..2343e5d 100644 --- a/docs/core_coordinates_validCoordinate.js.html +++ b/docs/core_coordinates_validCoordinate.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_featureCollections_featureCollection.js.html b/docs/core_featureCollections_featureCollection.js.html index 102ffc3..4c083c3 100644 --- a/docs/core_featureCollections_featureCollection.js.html +++ b/docs/core_featureCollections_featureCollection.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_features_feature.js.html b/docs/core_features_feature.js.html index cc53b19..225de50 100644 --- a/docs/core_features_feature.js.html +++ b/docs/core_features_feature.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_features_hasID.js.html b/docs/core_features_hasID.js.html index d57f0f4..f873c8e 100644 --- a/docs/core_features_hasID.js.html +++ b/docs/core_features_hasID.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_anyGeometry.js.html b/docs/core_geometries_anyGeometry.js.html index b4a81d5..e09a8c5 100644 --- a/docs/core_geometries_anyGeometry.js.html +++ b/docs/core_geometries_anyGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_geometryCollection.js.html b/docs/core_geometries_geometryCollection.js.html index 5691ade..658fbad 100644 --- a/docs/core_geometries_geometryCollection.js.html +++ b/docs/core_geometries_geometryCollection.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_lineStringGeometry.js.html b/docs/core_geometries_lineStringGeometry.js.html index ad7a9cf..ba0eb08 100644 --- a/docs/core_geometries_lineStringGeometry.js.html +++ b/docs/core_geometries_lineStringGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_multiLineStringGeometry.js.html b/docs/core_geometries_multiLineStringGeometry.js.html index 5bc064c..18cea69 100644 --- a/docs/core_geometries_multiLineStringGeometry.js.html +++ b/docs/core_geometries_multiLineStringGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_multiPointGeometry.js.html b/docs/core_geometries_multiPointGeometry.js.html index fac0a76..5f84caa 100644 --- a/docs/core_geometries_multiPointGeometry.js.html +++ b/docs/core_geometries_multiPointGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_multiPolygonGeometry.js.html b/docs/core_geometries_multiPolygonGeometry.js.html index 7988a25..46bf07a 100644 --- a/docs/core_geometries_multiPolygonGeometry.js.html +++ b/docs/core_geometries_multiPolygonGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_pointGeometry.js.html b/docs/core_geometries_pointGeometry.js.html index 79548b1..057cbd4 100644 --- a/docs/core_geometries_pointGeometry.js.html +++ b/docs/core_geometries_pointGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_geometries_polygonGeometry.js.html b/docs/core_geometries_polygonGeometry.js.html index 7e5ae72..ee1c32d 100644 --- a/docs/core_geometries_polygonGeometry.js.html +++ b/docs/core_geometries_polygonGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_utilities_commonGeometryValidation.js.html b/docs/core_utilities_commonGeometryValidation.js.html index c01b88a..afae021 100644 --- a/docs/core_utilities_commonGeometryValidation.js.html +++ b/docs/core_utilities_commonGeometryValidation.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/core_utilities_validGeoJSON.js.html b/docs/core_utilities_validGeoJSON.js.html index b59b91b..7af8705 100644 --- a/docs/core_utilities_validGeoJSON.js.html +++ b/docs/core_utilities_validGeoJSON.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/index.html b/docs/index.html index 410eb37..cce1b6d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • @@ -293,7 +296,7 @@

    Jest-GeoJSON - GeoJSON Validation Matchers for Jest @@ -630,11 +633,16 @@

    Features

    >toHaveID
  • +
  • + toHaveStringID +

  • Future

    diff --git a/docs/matchers_boundingBoxes_isValid2DBoundingBox.js.html b/docs/matchers_boundingBoxes_isValid2DBoundingBox.js.html index 94173b4..e02f440 100644 --- a/docs/matchers_boundingBoxes_isValid2DBoundingBox.js.html +++ b/docs/matchers_boundingBoxes_isValid2DBoundingBox.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_boundingBoxes_isValid3DBoundingBox.js.html b/docs/matchers_boundingBoxes_isValid3DBoundingBox.js.html index 0cfde4d..b046e3e 100644 --- a/docs/matchers_boundingBoxes_isValid3DBoundingBox.js.html +++ b/docs/matchers_boundingBoxes_isValid3DBoundingBox.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_boundingBoxes_isValidBoundingBox.js.html b/docs/matchers_boundingBoxes_isValidBoundingBox.js.html index 18534b8..bf498f5 100644 --- a/docs/matchers_boundingBoxes_isValidBoundingBox.js.html +++ b/docs/matchers_boundingBoxes_isValidBoundingBox.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_coordinates_isValid2DCoordinate.js.html b/docs/matchers_coordinates_isValid2DCoordinate.js.html index 47d9544..cc0f4a7 100644 --- a/docs/matchers_coordinates_isValid2DCoordinate.js.html +++ b/docs/matchers_coordinates_isValid2DCoordinate.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_coordinates_isValid3DCoordinate.js.html b/docs/matchers_coordinates_isValid3DCoordinate.js.html index 00f7413..86a5a24 100644 --- a/docs/matchers_coordinates_isValid3DCoordinate.js.html +++ b/docs/matchers_coordinates_isValid3DCoordinate.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_coordinates_isValidCoordinate.js.html b/docs/matchers_coordinates_isValidCoordinate.js.html index 5de338a..67243a7 100644 --- a/docs/matchers_coordinates_isValidCoordinate.js.html +++ b/docs/matchers_coordinates_isValidCoordinate.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_featureCollections_toBeFeatureCollection.js.html b/docs/matchers_featureCollections_toBeFeatureCollection.js.html index 0da8535..995d22d 100644 --- a/docs/matchers_featureCollections_toBeFeatureCollection.js.html +++ b/docs/matchers_featureCollections_toBeFeatureCollection.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_features_toBeFeature.js.html b/docs/matchers_features_toBeFeature.js.html index 15a43cb..aece9d9 100644 --- a/docs/matchers_features_toBeFeature.js.html +++ b/docs/matchers_features_toBeFeature.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_features_toHaveID.js.html b/docs/matchers_features_toHaveID.js.html index 69bc4fd..cad2204 100644 --- a/docs/matchers_features_toHaveID.js.html +++ b/docs/matchers_features_toHaveID.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_features_toHaveStringID.js.html b/docs/matchers_features_toHaveStringID.js.html new file mode 100644 index 0000000..36f1a47 --- /dev/null +++ b/docs/matchers_features_toHaveStringID.js.html @@ -0,0 +1,426 @@ + + + + + matchers/features/toHaveStringID.js - Jest-GeoJSON + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    matchers/features/toHaveStringID.js

    + +
    +
    +
    const { hasID } = require('../../core/features/hasID')
    +
    +// eslint-disable-next-line jsdoc/require-returns
    +/**
    + * Checks if a GeoJSON Feature has a string ID. Passes if the Feature object has any string ID (no argument provided), or
    + * if the ID exactly matches the optional argument (single string or RegExp provided), or any value
    + * within an array of any combination of strings or RegExp.
    + *
    + * The test fails if the object does not have an ID, or if it has an ID that does not match the SearchID.
    + *
    + * Passing a number type to SearchID will not pass the test, even if the ID exactly matches.
    + *
    + * @memberof Matchers.Features
    + * @see https://github.com/M-Scott-Lassiter/jest-geojson/issues/37
    + * @param {object} featureObject any GeoJSON Feature object
    + * @param {string|RegExp|string[]|RegExp[]} [SearchID] Specific value or array of possible values
    + * to search for.
    + * @example
    + * const testFeature = {
    + *     type: 'Feature',
    + *     id: 'f1',
    + *     geometry: {...},
    + *     properties: {...}
    + * }
    + *
    + * test('Feature Has an ID', () => {
    + *     expect(testFeature).toHaveStringID()
    + *     expect(testFeature).toHaveStringID([])
    + *     expect(testFeature).toHaveStringID('f1')
    + *     expect(testFeature).toHaveStringID(['1', 'F', 'F12', /[a-z]+[0-9]+/])
    + *
    + *     expect(testFeature).not.toHaveStringID('f2')
    + *     expect(testFeature).not.toHaveStringID([1, 'F', 'F12', /SomeID/])
    + * })
    + * @example
    + * const testFeatureNoID = {
    + *     type: 'Feature',
    + *     geometry: {...},
    + *     properties: {...}
    + * }
    + * const testFeatureNumID = {
    + *     type: 'Feature',
    + *     id: 2,
    + *     geometry: {...},
    + *     properties: {...}
    + * }
    + *
    + * test('Feature Does not Have an ID', () => {
    + *     expect(testFeature).not.toHaveStringID('f2')
    + *     expect(testFeature).not.toHaveStringID([1, 'F', 'F12', /SomeID/])
    + *
    + *     expect(testFeatureNoID).not.toHaveStringID()
    + *     expect(testFeatureNumID).not.toHaveStringID()
    + *     expect(testFeatureNumID).not.toHaveStringID(2)
    + * })
    + */
    +function toHaveStringID(featureObject, SearchID) {
    +    const { printReceived, matcherHint } = this.utils
    +    const optionalIDMessage = () => {
    +        if (SearchID !== undefined && SearchID?.length !== 0) {
    +            return ` of ${SearchID}`
    +        }
    +        return ''
    +    }
    +    const passMessage =
    +        // eslint-disable-next-line prefer-template
    +        matcherHint('.not.toHaveStringID', 'FeatureObject', 'SearchID') +
    +        '\n\n' +
    +        `Expected input to not be a valid GeoJSON Feature object with string type ID` +
    +        optionalIDMessage() +
    +        `.\n\n` +
    +        `Received:  ${printReceived(featureObject)}`
    +
    +    /**
    +     * 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('.toHaveStringID', 'FeatureObject', 'SearchID') +
    +            '\n\n' +
    +            `${errorMessage}\n\n` +
    +            `Received:  ${printReceived(featureObject)}`
    +        )
    +    }
    +
    +    let idIsPresent
    +    // Provide error handling in case of invalid inputs to the matcher
    +    try {
    +        idIsPresent = hasID(featureObject, SearchID)
    +
    +        if (typeof featureObject.id === 'number') {
    +            throw new Error('ID is a number, expected a string.')
    +        }
    +    } catch (err) {
    +        return { pass: false, message: () => failMessage(err.message) }
    +    }
    +
    +    // Input was valid, now return either pass or fail
    +    if (idIsPresent) {
    +        return { pass: true, message: () => passMessage }
    +    }
    +    return { pass: false, message: () => failMessage(`Did not find the ID ${SearchID}.`) }
    +}
    +
    +exports.toHaveStringID = toHaveStringID
    +
    +
    +
    +
    + +
    + + + + + + + + + + diff --git a/docs/matchers_functional_toBeValidGeoJSON.js.html b/docs/matchers_functional_toBeValidGeoJSON.js.html index ef3876b..7eb9537 100644 --- a/docs/matchers_functional_toBeValidGeoJSON.js.html +++ b/docs/matchers_functional_toBeValidGeoJSON.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBeAnyGeometry.js.html b/docs/matchers_geometries_toBeAnyGeometry.js.html index 6813b0f..0cc188e 100644 --- a/docs/matchers_geometries_toBeAnyGeometry.js.html +++ b/docs/matchers_geometries_toBeAnyGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBeGeometryCollection.js.html b/docs/matchers_geometries_toBeGeometryCollection.js.html index dd156f9..7b64445 100644 --- a/docs/matchers_geometries_toBeGeometryCollection.js.html +++ b/docs/matchers_geometries_toBeGeometryCollection.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBeLineStringGeometry.js.html b/docs/matchers_geometries_toBeLineStringGeometry.js.html index 2fde671..07abc94 100644 --- a/docs/matchers_geometries_toBeLineStringGeometry.js.html +++ b/docs/matchers_geometries_toBeLineStringGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBeMultiLineStringGeometry.js.html b/docs/matchers_geometries_toBeMultiLineStringGeometry.js.html index 39c0346..dba790c 100644 --- a/docs/matchers_geometries_toBeMultiLineStringGeometry.js.html +++ b/docs/matchers_geometries_toBeMultiLineStringGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBeMultiPointGeometry.js.html b/docs/matchers_geometries_toBeMultiPointGeometry.js.html index 08deada..65cfe15 100644 --- a/docs/matchers_geometries_toBeMultiPointGeometry.js.html +++ b/docs/matchers_geometries_toBeMultiPointGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBeMultiPolygonGeometry.js.html b/docs/matchers_geometries_toBeMultiPolygonGeometry.js.html index 68e7ad1..9d0358d 100644 --- a/docs/matchers_geometries_toBeMultiPolygonGeometry.js.html +++ b/docs/matchers_geometries_toBeMultiPolygonGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBePointGeometry.js.html b/docs/matchers_geometries_toBePointGeometry.js.html index 4a33703..0379b56 100644 --- a/docs/matchers_geometries_toBePointGeometry.js.html +++ b/docs/matchers_geometries_toBePointGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/matchers_geometries_toBePolygonGeometry.js.html b/docs/matchers_geometries_toBePolygonGeometry.js.html index 718b908..74c97f7 100644 --- a/docs/matchers_geometries_toBePolygonGeometry.js.html +++ b/docs/matchers_geometries_toBePolygonGeometry.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/docs/typedefinitions.js.html b/docs/typedefinitions.js.html index bdeb200..7046cf2 100644 --- a/docs/typedefinitions.js.html +++ b/docs/typedefinitions.js.html @@ -224,6 +224,9 @@

    Namespaces

  • toHaveID
  • +
  • + toHaveStringID +
  • diff --git a/src/matchers.js b/src/matchers.js index 1b568c4..3f8a784 100644 --- a/src/matchers.js +++ b/src/matchers.js @@ -24,7 +24,8 @@ exports.featureCollections = { exports.features = { toBeFeature: require('./matchers/features/toBeFeature').toBeFeature, - toHaveID: require('./matchers/features/toHaveID').toHaveID + toHaveID: require('./matchers/features/toHaveID').toHaveID, + toHaveStringID: require('./matchers/features/toHaveStringID').toHaveStringID } exports.functional = { diff --git a/src/matchers/features/toHaveStringID.js b/src/matchers/features/toHaveStringID.js new file mode 100644 index 0000000..6132801 --- /dev/null +++ b/src/matchers/features/toHaveStringID.js @@ -0,0 +1,110 @@ +const { hasID } = require('../../core/features/hasID') + +// eslint-disable-next-line jsdoc/require-returns +/** + * Checks if a GeoJSON Feature has a string ID. Passes if the Feature object has any string ID (no argument provided), or + * if the ID exactly matches the optional argument (single string or RegExp provided), or any value + * within an array of any combination of strings or RegExp. + * + * The test fails if the object does not have an ID, or if it has an ID that does not match the SearchID. + * + * Passing a number type to SearchID will not pass the test, even if the ID exactly matches. + * + * @memberof Matchers.Features + * @see https://github.com/M-Scott-Lassiter/jest-geojson/issues/37 + * @param {object} featureObject any GeoJSON Feature object + * @param {string|RegExp|string[]|RegExp[]} [SearchID] Specific value or array of possible values + * to search for. + * @example + * const testFeature = { + * type: 'Feature', + * id: 'f1', + * geometry: {...}, + * properties: {...} + * } + * + * test('Feature Has an ID', () => { + * expect(testFeature).toHaveStringID() + * expect(testFeature).toHaveStringID([]) + * expect(testFeature).toHaveStringID('f1') + * expect(testFeature).toHaveStringID(['1', 'F', 'F12', /[a-z]+[0-9]+/]) + * + * expect(testFeature).not.toHaveStringID('f2') + * expect(testFeature).not.toHaveStringID([1, 'F', 'F12', /SomeID/]) + * }) + * @example + * const testFeatureNoID = { + * type: 'Feature', + * geometry: {...}, + * properties: {...} + * } + * const testFeatureNumID = { + * type: 'Feature', + * id: 2, + * geometry: {...}, + * properties: {...} + * } + * + * test('Feature Does not Have an ID', () => { + * expect(testFeature).not.toHaveStringID('f2') + * expect(testFeature).not.toHaveStringID([1, 'F', 'F12', /SomeID/]) + * + * expect(testFeatureNoID).not.toHaveStringID() + * expect(testFeatureNumID).not.toHaveStringID() + * expect(testFeatureNumID).not.toHaveStringID(2) + * }) + */ +function toHaveStringID(featureObject, SearchID) { + const { printReceived, matcherHint } = this.utils + const optionalIDMessage = () => { + if (SearchID !== undefined && SearchID?.length !== 0) { + return ` of ${SearchID}` + } + return '' + } + const passMessage = + // eslint-disable-next-line prefer-template + matcherHint('.not.toHaveStringID', 'FeatureObject', 'SearchID') + + '\n\n' + + `Expected input to not be a valid GeoJSON Feature object with string type ID` + + optionalIDMessage() + + `.\n\n` + + `Received: ${printReceived(featureObject)}` + + /** + * 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('.toHaveStringID', 'FeatureObject', 'SearchID') + + '\n\n' + + `${errorMessage}\n\n` + + `Received: ${printReceived(featureObject)}` + ) + } + + let idIsPresent + // Provide error handling in case of invalid inputs to the matcher + try { + idIsPresent = hasID(featureObject, SearchID) + + if (typeof featureObject.id === 'number') { + throw new Error('ID is a number, expected a string.') + } + } catch (err) { + return { pass: false, message: () => failMessage(err.message) } + } + + // Input was valid, now return either pass or fail + if (idIsPresent) { + return { pass: true, message: () => passMessage } + } + return { pass: false, message: () => failMessage(`Did not find the ID ${SearchID}.`) } +} + +exports.toHaveStringID = toHaveStringID diff --git a/tests/features/__snapshots__/toHaveStringID.test.js.snap b/tests/features/__snapshots__/toHaveStringID.test.js.snap new file mode 100644 index 0000000..0886146 --- /dev/null +++ b/tests/features/__snapshots__/toHaveStringID.test.js.snap @@ -0,0 +1,57 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Error Snapshot Testing. Throws error: ID Present, Empty Array Search 1`] = ` +"expect(FeatureObject).not.toHaveStringID(SearchID) + +Expected input to not be a valid GeoJSON Feature object with string type ID. + +Received: {\\"geometry\\": null, \\"id\\": \\"22\\", \\"properties\\": null, \\"type\\": \\"Feature\\"}" +`; + +exports[`Error Snapshot Testing. Throws error: ID Present, Search for Wrong ID 1`] = ` +"expect(FeatureObject).toHaveStringID(SearchID) + +Did not find the ID 21. + +Received: {\\"geometry\\": null, \\"id\\": \\"22\\", \\"properties\\": null, \\"type\\": \\"Feature\\"}" +`; + +exports[`Error Snapshot Testing. Throws error: Invalid input to matcher 1`] = ` +"expect(FeatureObject).toHaveStringID(SearchID) + +Must have a type property with value 'Feature' + +Received: {\\"coordinates\\": [[101, 0], [102, 1]], \\"type\\": \\"LineString\\"}" +`; + +exports[`Error Snapshot Testing. Throws error: No ID Is Present 1`] = ` +"expect(FeatureObject).toHaveStringID(SearchID) + +Feature does not have an \\"id\\" member. + +Received: {\\"geometry\\": null, \\"properties\\": null, \\"type\\": \\"Feature\\"}" +`; + +exports[`Error Snapshot Testing. Throws error: Non-string search ID 1`] = ` +"expect(FeatureObject).toHaveStringID(SearchID) + +Did not find the ID 1. + +Received: {\\"geometry\\": {\\"coordinates\\": [[[100, 0], [101, 0], [101, 1], [100, 1], [100, 0]]], \\"type\\": \\"Polygon\\"}, \\"id\\": \\"Test\\", \\"properties\\": null, \\"type\\": \\"Feature\\"}" +`; + +exports[`Error Snapshot Testing. Throws error: Numeric ID 1`] = ` +"expect(FeatureObject).toHaveStringID(SearchID) + +ID is a number, expected a string. + +Received: {\\"geometry\\": null, \\"id\\": 22, \\"properties\\": null, \\"type\\": \\"Feature\\"}" +`; + +exports[`Error Snapshot Testing. Throws error: Valid use case passes 1`] = ` +"expect(FeatureObject).not.toHaveStringID(SearchID) + +Expected input to not be a valid GeoJSON Feature object with string type ID. + +Received: {\\"geometry\\": {\\"coordinates\\": [[[100, 0], [101, 0], [101, 1], [100, 1], [100, 0]]], \\"type\\": \\"Polygon\\"}, \\"id\\": \\"#1 Test\\", \\"properties\\": null, \\"type\\": \\"Feature\\"}" +`; diff --git a/tests/features/toHaveStringID.test.js b/tests/features/toHaveStringID.test.js new file mode 100644 index 0000000..5134192 --- /dev/null +++ b/tests/features/toHaveStringID.test.js @@ -0,0 +1,251 @@ +const { goodGeometry, badGeometry, nestedGeometryCollection } = require('../geometries/data') + +const validIDs = ['1', 'Test 123', 'Random ID String', ''] +const invalidSearchIDs = [ + 0, + -200, + 200, + Infinity, + -Infinity, + NaN, + null, + true, + false, + { someProp: 'I am not GeoJSON', id: 4 }, + {}, + goodGeometry.lineString, + goodGeometry.multiLineString, + goodGeometry.multiPoint, + goodGeometry.multiPolygon, + goodGeometry.point, + goodGeometry.polygon, + nestedGeometryCollection, + badGeometry.lineString, + badGeometry.multiLineString, + badGeometry.multiPoint, + badGeometry.multiPolygon, + badGeometry.point, + badGeometry.polygon, + badGeometry.geometryCollection, + badGeometry.unrecognized +] +const invalidInputValues = [ + ...invalidSearchIDs, + undefined, + '', + 'Random Feature', + JSON.stringify({ + type: 'Feature', + geometry: null, + properties: null + }) +] + +describe('Valid Use Cases', () => { + describe('Expect to pass with good features and IDs', () => { + const testFeature = { + type: 'Feature', + geometry: goodGeometry.polygon, + properties: null, + id: null + } + + describe('No Specific Callout: expect(testFeature).toHaveStringID()', () => { + test.each(validIDs)('ID: %p', (input) => { + testFeature.id = input + expect(testFeature).toHaveStringID() + }) + }) + + describe('Specific Callout', () => { + test.each(validIDs)('expect(testFeature).toHaveStringID(%p)', (input) => { + testFeature.id = input + expect(testFeature).toHaveStringID(input) + }) + }) + + describe('Specific Callout in Single Array Element', () => { + test.each(validIDs)('expect(testFeature).toHaveStringID([%p])', (input) => { + testFeature.id = input + expect(testFeature).toHaveStringID([input]) + }) + }) + + describe('Specific Callout RegExp', () => { + test.each(validIDs)('expect(testFeature).toHaveStringID(/%p/)', (input) => { + testFeature.id = input + expect(testFeature).toHaveStringID(new RegExp(input)) + }) + }) + + describe('Specific Callout RegExp in Single Array Element', () => { + test.each(validIDs)('expect(testFeature).toHaveStringID([/%p/])', (input) => { + testFeature.id = input + expect(testFeature).toHaveStringID([new RegExp(input)]) + }) + }) + }) + + describe('Expect to pass Multiple Array Value Checking for Numeric ID', () => { + const searchArray = [ + [['1', '#719', 'TestID', 'Some String']], + [['A String ID', /Some/, '2']], + [[/SomeString/, /123/, /\bString\b/]], + [[/72[0-9]/, /\bString\b/, /71[0-9]/, /Some/, 'Some String']] + ] + + test.each(searchArray)('ID Search Array: %p', (input) => { + const testFeature = { + type: 'Feature', + geometry: goodGeometry.polygon, + properties: null, + id: 'Some String' + } + expect(testFeature).toHaveStringID(input) + }) + + test('Empty Array for Optional Argument. ID: %p', () => { + const testFeature = { + type: 'Feature', + geometry: null, + properties: null, + id: 'Test ID' + } + expect(testFeature).toHaveStringID([]) + }) + }) +}) + +describe('Invalid Use Cases', () => { + describe('Expect to fail with bad inputs:', () => { + test.each(invalidInputValues)('expect(%p).not.toHaveStringID()', (badInput) => { + expect(badInput).not.toHaveStringID() + }) + }) + + test('Fails when provided invalid feature', () => { + const testFeature = { + type: 'Feature', + properties: null + } + expect(testFeature).not.toHaveStringID() + }) + + test('Missing ID, searchID is empty array.', () => { + const testFeature = { + type: 'Feature', + geometry: null, + properties: null + } + expect(testFeature).not.toHaveStringID([]) + }) + + describe('Known good Feature with ID That Does Not Match:', () => { + test.each(validIDs)('ID: %p', (input) => { + const testFeature = { + type: 'Feature', + geometry: goodGeometry.polygon, + properties: null, + id: input + } + const badID = `${input}ExtraString` + + expect(testFeature).not.toHaveStringID(badID) + expect(testFeature).not.toHaveStringID([badID]) + expect(testFeature).not.toHaveStringID(new RegExp(badID)) + expect(testFeature).not.toHaveStringID([new RegExp(badID)]) + }) + }) + + describe('Expect to fail with non-string ID:', () => { + test.each(invalidSearchIDs)('expect(testFeature).not.toHaveStringID(%p)', (badInput) => { + const testFeature = { + type: 'Feature', + geometry: goodGeometry.polygon, + properties: null, + id: badInput + } + + expect(testFeature).not.toHaveStringID(badInput) + expect(testFeature).not.toHaveStringID([badInput]) + expect(testFeature).not.toHaveStringID(new RegExp(badInput)) + expect(testFeature).not.toHaveStringID([new RegExp(badInput)]) + }) + }) + + test('Fails when no ID provided to valid feature', () => { + const testFeature = { + type: 'Feature', + geometry: null, + properties: null + } + expect(testFeature).not.toHaveStringID() + }) +}) + +describe('Error Snapshot Testing. Throws error:', () => { + test('Valid use case passes', () => { + const testFeature = { + type: 'Feature', + geometry: goodGeometry.polygon, + properties: null, + id: '#1 Test' + } + expect(() => expect(testFeature).not.toHaveStringID()).toThrowErrorMatchingSnapshot() + }) + + test('Invalid input to matcher', () => { + expect(() => + expect(goodGeometry.lineString).toHaveStringID() + ).toThrowErrorMatchingSnapshot() + }) + + test('Non-string search ID', () => { + const testFeature = { + type: 'Feature', + geometry: goodGeometry.polygon, + properties: null, + id: 'Test' + } + expect(() => expect(testFeature).toHaveStringID(1)).toThrowErrorMatchingSnapshot() + }) + + test('No ID Is Present', () => { + const testFeature = { + type: 'Feature', + geometry: null, + properties: null + } + expect(() => expect(testFeature).toHaveStringID()).toThrowErrorMatchingSnapshot() + }) + + test('ID Present, Empty Array Search', () => { + const testFeature = { + type: 'Feature', + geometry: null, + properties: null, + id: '22' + } + expect(() => expect(testFeature).not.toHaveStringID([])).toThrowErrorMatchingSnapshot() + }) + + test('ID Present, Search for Wrong ID', () => { + const testFeature = { + type: 'Feature', + geometry: null, + properties: null, + id: '22' + } + expect(() => expect(testFeature).toHaveStringID(['21'])).toThrowErrorMatchingSnapshot() + }) + + test('Numeric ID', () => { + const testFeature = { + type: 'Feature', + geometry: null, + properties: null, + id: 22 + } + expect(() => expect(testFeature).toHaveStringID(22)).toThrowErrorMatchingSnapshot() + }) +}) diff --git a/tests/matchers.test.js b/tests/matchers.test.js index 984aaf2..609f2c4 100644 --- a/tests/matchers.test.js +++ b/tests/matchers.test.js @@ -44,6 +44,10 @@ describe('Feature Matchers Exported', () => { test('toHaveID', () => { expect('toHaveID' in matchers.features).toBeTruthy() }) + + test('toHaveStringID', () => { + expect('toHaveStringID' in matchers.features).toBeTruthy() + }) }) describe('Functional Matchers Exported', () => {