Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving Test coverage #365

Merged
merged 18 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion tests/containers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
"""Test the kml classes."""


from fastkml import kml
from fastkml import kml, containers, features
from tests.base import Lxml
from tests.base import StdLibrary
import pytest


class TestStdLibrary(StdLibrary):
Expand Down Expand Up @@ -65,6 +66,38 @@ def test_document_boolean_visibility_invalid(self) -> None:
assert d.features[0].visibility is None
assert d.features[0].isopen

def test_container_creation(self) -> None:
container = containers._Container(
ns="ns",
id="id",
target_id="target_id",
name="name"
)
assert container.ns == "ns"
assert container.name == "name"

def test_container_feature_append(self) -> None:
container = containers._Container(
ns="ns",
id="id",
target_id="target_id",
name="name"
)
feature = features._Feature(name="new_feature")
container.append(feature)
assert feature in container.features
with pytest.raises(ValueError, match="Cannot append self"):
container.append(container)

def test_document_container_get_style_url(self) -> None:
document = containers.Document(
name="Document",
ns="ns",
style_url="www.styleurl.com"
)
assert document.get_style_by_url(style_url="www.styleurl.com") is None
Comment on lines +92 to +98
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Expand test coverage for get_style_by_url method

The current test verifies that get_style_by_url returns None for a valid style_url. However, it's unclear if this is the expected behavior. Consider the following improvements:

  1. Clarify why get_style_by_url returns None for a valid style_url. Is this the intended behavior?
  2. Add a test case for an invalid style_url to ensure the method behaves correctly in both scenarios.
  3. If possible, add a test case where get_style_by_url returns a non-None value to demonstrate when it successfully retrieves a style.

Here's a suggested improvement:

def test_document_container_get_style_url(self) -> None:
    document = containers.Document(
        name="Document",
        ns="ns",
        style_url="www.styleurl.com"
    )
    # Assuming None is the correct return value for a valid but non-existent style
    assert document.get_style_by_url(style_url="www.styleurl.com") is None
    
    # Test with an invalid style_url
    assert document.get_style_by_url(style_url="invalid_url") is None
    
    # If possible, add a test case where get_style_by_url returns a non-None value
    # This might require setting up a style in the document first
    # document.styles.append(some_style)
    # assert document.get_style_by_url(style_url="some_style_url") is not None




class TestLxml(Lxml, TestStdLibrary):
"""Test with lxml."""
20 changes: 20 additions & 0 deletions tests/geometries/boundaries_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

"""Test the Outer and Inner Boundary classes."""

import pytest
from fastkml.exceptions import GeometryError
import pygeoif.geometry as geo

from fastkml.geometry import Coordinates
Expand Down Expand Up @@ -73,6 +75,24 @@ def test_inner_boundary(self) -> None:
"</kml:coordinates></kml:LinearRing></kml:innerBoundaryIs>"
)

def _test_boundary_geometry_error(self, boundary_class):
p = geo.Point(1, 2)
coords = ((1, 2), (2, 0), (0, 0), (1, 2))

with pytest.raises(GeometryError):
boundary_class(
kml_geometry=LinearRing(kml_coordinates=Coordinates(coords=coords)),
geometry=p
)

def test_outer_boundary_geometry_error(self):
"""Test that OuterBoundaryIs raises GeometryError with invalid geometry."""
self._test_boundary_geometry_error(OuterBoundaryIs)

def test_inner_boundary_geometry_error(self):
"""Test that InnerBoundaryIs raises GeometryError with invalid geometry."""
self._test_boundary_geometry_error(InnerBoundaryIs)

def test_read_inner_boundary_multiple_linestrings(self) -> None:
"""
Test the from_string method.
Expand Down
71 changes: 71 additions & 0 deletions tests/geometries/functions_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from unittest.mock import Mock, patch
import pytest
from fastkml.exceptions import KMLParseError, KMLWriteError
from fastkml.geometry import handle_invalid_geometry_error
from fastkml.geometry import coordinates_subelement
from tests.base import StdLibrary


class TestGeometryFunctions(StdLibrary):
"""Test functions in Geometry"""

@patch('fastkml.config.etree.tostring')
def test_handle_invalid_geometry_error_true(self, mock_to_string) -> None:
mock_element = Mock()
with pytest.raises(KMLParseError):
handle_invalid_geometry_error(
error=ValueError,
element=mock_element,
strict=True
)

@patch('fastkml.config.etree.tostring')
def test_handle_invalid_geometry_error_false(self, mock_to_string) -> None:
mock_element = Mock()
assert handle_invalid_geometry_error(
error=ValueError,
element=mock_element,
strict=False
) is None

def test_coordinates_subelement_exception(self) -> None:
obj = Mock()
setattr(obj,
'coordinates',
[(1.123456, 2.654321, 3.111111, 4.222222)]
)

element = Mock()

precision = None
attr_name = 'coordinates'

with pytest.raises(KMLWriteError):
coordinates_subelement(
obj=obj,
attr_name=attr_name,
node_name=None,
element=element,
precision=precision,
verbosity=None,
default=None
)

def test_coordinates_subelement_getattr(self) -> None:
obj = Mock()
setattr(obj, 'coordinates', [(1.123456, 2.654321), (3.123456, 4.654321)])

element = Mock()

precision = 4
attr_name = 'coordinates'

assert coordinates_subelement(
obj=None,
attr_name=attr_name,
node_name=None,
element=element,
precision=precision,
verbosity=None,
default=None
) is None
Comment on lines +54 to +71
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix discrepancy between setup and function call.

There's an important issue in this test that needs to be addressed. The test sets up a mock object with valid 2D coordinates, but then passes None as the obj parameter in the coordinates_subelement call. This means the test is not actually using the mock object with the valid coordinates you've set up.

To fix this, replace:

assert coordinates_subelement(
    obj=None,
    # ... other arguments ...
) is None

with:

assert coordinates_subelement(
    obj=obj,
    # ... other arguments ...
) is None

This change ensures that the test actually uses the mock object with the valid coordinates you've set up, making the test more effective and meaningful.

12 changes: 10 additions & 2 deletions tests/geometries/linestring_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

from fastkml import exceptions
from fastkml.enums import Verbosity
from fastkml.exceptions import KMLParseError
from fastkml.geometry import LineString
from fastkml.exceptions import GeometryError, KMLParseError
from fastkml.geometry import Coordinates, LineString
from tests.base import Lxml
from tests.base import StdLibrary

Expand All @@ -38,6 +38,14 @@ def test_init(self) -> None:
assert line_string.altitude_mode is None
assert line_string.extrude is None

def test_geometry_error(self) -> None:
"""Test GeometryError."""
p = geo.Point(1, 2)
q = Coordinates(ns="ns")

with pytest.raises(GeometryError):
LineString(geometry=p, kml_coordinates=q)

def test_to_string(self) -> None:
"""Test the to_string method."""
ls = geo.LineString(((1, 2), (2, 0)))
Expand Down
12 changes: 11 additions & 1 deletion tests/geometries/multigeometry_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""Test the geometry classes."""
import pytest
from fastkml.exceptions import GeometryError
import pygeoif.geometry as geo

from fastkml.enums import Verbosity
from fastkml.geometry import MultiGeometry
from fastkml.geometry import Coordinates, MultiGeometry
from tests.base import Lxml
from tests.base import StdLibrary

Expand Down Expand Up @@ -295,6 +297,14 @@ def test_multi_geometries_verbose(self) -> None:
assert xml.count("extrude>0<") == 13
assert xml.count("altitudeMode>clampToGround<") == 13

def test_geometry_error(self) -> None:
"""Test GeometryError."""
p = geo.Point(1, 2)
q = Coordinates(ns="ns")

with pytest.raises(GeometryError):
MultiGeometry(geometry=p, kml_geometries=q)

def test_multi_geometries_read(self) -> None:
xml = (
'<MultiGeometry xmlns="http://www.opengis.net/kml/2.2">'
Expand Down
12 changes: 11 additions & 1 deletion tests/geometries/point_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
import pytest

from fastkml.enums import Verbosity
from fastkml.exceptions import KMLParseError
from fastkml.exceptions import GeometryError, KMLParseError
from fastkml.geometry import Point
from fastkml.geometry import Coordinates
from tests.base import Lxml
from tests.base import StdLibrary

Expand All @@ -39,6 +40,15 @@ def test_init(self) -> None:
assert point.altitude_mode is None
assert point.extrude is None

def test_geometry_error(self) -> None:
"""Test GeometryError."""
p = geo.Point(1, 2)
q = Coordinates(ns="ns")

with pytest.raises(GeometryError):
Point(geometry=p, kml_coordinates=q)


def test_to_string_2d(self) -> None:
"""Test the to_string method."""
p = geo.Point(1, 2)
Expand Down
10 changes: 10 additions & 0 deletions tests/geometries/polygon_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

"""Test the geometry classes."""

import pytest
from fastkml.exceptions import GeometryError
import pygeoif.geometry as geo

from fastkml.enums import AltitudeMode
Expand Down Expand Up @@ -127,6 +129,14 @@ def test_to_string_verbose_none(self) -> None:

assert "extrude>0</" in polygon.to_string(verbosity=Verbosity.verbose)

def test_geometry_error(self) -> None:
"""Test GeometryError."""
poly = geo.Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
ob = OuterBoundaryIs(ns="")

with pytest.raises(GeometryError):
Polygon(geometry=poly, outer_boundary=ob)

def test_from_string_exterior_only(self) -> None:
"""Test exterior only."""
doc = """<kml:Polygon xmlns:kml="http://www.opengis.net/kml/2.2">
Expand Down
9 changes: 9 additions & 0 deletions tests/gx_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ def test_track(self) -> None:
"coordinates": ((0.0, 0.0), (1.0, 1.0)),
}

def test_track_etree_element(self) -> None:
g = Track()

g.etree_element()

assert g.track_items == []

def test_multitrack(self) -> None:
doc = """
<gx:MultiTrack xmlns:kml="http://www.opengis.net/kml/2.2"
Expand Down Expand Up @@ -330,6 +337,8 @@ def test_from_multilinestring(self) -> None:

mt = MultiTrack(geometry=lines, ns="")

assert bool(mt)

assert (
mt.to_string()
== MultiTrack(
Expand Down
Loading
Loading