Repository: aazuspan/eerepr (language: python)

Issue:
Check for unused cached test data
Whenever a new Earth Engine object is retrieved by `tests.test_html.load_info`, it is saved in the `tests/data/data.json` cache. If an old test is removed or an unused object is accidentally committed, the cache could get out of sync with the tests. 

It would be easy enough to fix this just by resetting the cache, but the ideal solution for long term maintenance would be to check that each object is actually used by the tests and either warn the user or delete any objects that aren't used. This may be tricky, especially in cases where a user runs a subset of tests, but it's worth poking around to see if there's a simple solution for this.
Check for unused cached test data
Whenever a new Earth Engine object is retrieved by `tests.test_html.load_info`, it is saved in the `tests/data/data.json` cache. If an old test is removed or an unused object is accidentally committed, the cache could get out of sync with the tests. 

It would be easy enough to fix this just by resetting the cache, but the ideal solution for long term maintenance would be to check that each object is actually used by the tests and either warn the user or delete any objects that aren't used. This may be tricky, especially in cases where a user runs a subset of tests, but it's worth poking around to see if there's a simple solution for this.


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index f794d2f..2fdc256 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,6 @@ __pycache__/
 htmlcov/
 dist/
 *.egg-info/
-.tox/
\ No newline at end of file
+.tox/
+
+tests/data/
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3a012eb..b3aa822 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -58,20 +58,23 @@ hatch run test:all -k feature
 
 ### Building New Tests
 
-New features should have unit tests. To avoid having to use `getInfo` every time a test is run against a client-side Earth Engine object, `eerepr` uses a caching function `tests.test_html.load_info` to load data. This function takes an Earth Engine object and either 1) retrieves it from the local cache in `tests/data/data.json` if it has been used before, or 2) retrieves it from the server and adds it to the cache. Objects in the cache use their serialized form as an identifying key.
+New features should have unit tests. If your test needs to use `getInfo` to retrieve data from an Earth Engine object, you'll need to use the caching system described below.
 
-To demonstrate, let's write a new dummy test that uses a custom `ee.Image`.
+Using `getInfo` to retrieve data from an Earth Engine object can be slow and network-dependent. To speed up tests, `eerepr` uses a caching function `tests.cache.get_info` to load data. This function takes an Earth Engine object and either 1) retrieves its info from a local cache file if it has been used before, or 2) retrieves it from the server and adds it to the cache. The cache directory and file (`tests/data/data.json`) will be created automatically the first time tests are run.
+
+To demonstrate, let's write a new dummy test that checks the properties of a custom `ee.Image`.
 
 ```python
-from tests.test_html import load_info
+from tests.cache import get_info
 
 def test_my_image():
     img = ee.Image.constant(42).set("custom_property", ["a", "b", "c"])
-    info = load_info(img)
+    # Use `get_info` instead of `img.getInfo` to utilize the cache
+    info = get_info(img)
 
-    assert info
+    assert "custom_property" in info["properties"]
 ```
 
 The first time the test is run, `getInfo` will be used to retrieve the image metadata and store it in `tests/data/data.json`. Subsequent runs will pull the data directly from the cache.
 
-When you add a new test, be sure to commit the updated data cache.
\ No newline at end of file
+Caches are kept locally and are not version-controlled, so there's no need to commit newly added objects.
\ No newline at end of file


Test patch:
diff --git a/tests/cache.py b/tests/cache.py
new file mode 100644
index 0000000..9d70573
--- /dev/null
+++ b/tests/cache.py
@@ -0,0 +1,36 @@
+import json
+import os
+
+CACHE_DIR = "./tests/data/"
+CACHE_PATH = CACHE_DIR + "data.json"
+
+
+def get_info(obj):
+    """Load client-side info for an Earth Engine object.
+
+    Info is retrieved (if available) from a local JSON file using the serialized
+    object as the key. If the data does not exist locally, it is loaded from Earth
+    Engine servers and stored for future use.
+    """
+    serialized = obj.serialize()
+
+    if not os.path.isdir("./tests/data"):
+        os.mkdir("./tests/data")
+
+    try:
+        with open("./tests/data/data.json") as src:
+            existing_data = json.load(src)
+
+    # File is missing or unreadable
+    except (FileNotFoundError, json.JSONDecodeError):
+        existing_data = {}
+        with open("./tests/data/data.json", "w") as dst:
+            json.dump(existing_data, dst)
+
+    # File exists, but info does not
+    if serialized not in existing_data:
+        with open("./tests/data/data.json", "w") as dst:
+            existing_data[serialized] = obj.getInfo()
+            json.dump(existing_data, dst, indent=2)
+
+    return existing_data[serialized]
diff --git a/tests/data/data.json b/tests/data/data.json
deleted file mode 100644
index 91e5c5e..0000000
--- a/tests/data/data.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"Element.set\", \"arguments\": {\"key\": {\"constantValue\": \"system:id\"}, \"object\": {\"functionInvocationValue\": {\"functionName\": \"Image.constant\", \"arguments\": {\"value\": {\"constantValue\": 0}}}}, \"value\": {\"constantValue\": \"foo\"}}}}}}": {"type": "Image", "bands": [{"id": "constant", "data_type": {"type": "PixelType", "precision": "int", "min": 0, "max": 0}, "crs": "EPSG:4326", "crs_transform": [1, 0, 0, 0, 1, 0]}], "id": "foo"}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"Element.set\", \"arguments\": {\"key\": {\"constantValue\": \"test_prop\"}, \"object\": {\"functionInvocationValue\": {\"functionName\": \"ImageCollection.fromImages\", \"arguments\": {\"images\": {\"arrayValue\": {\"values\": [{\"functionInvocationValue\": {\"functionName\": \"Image.constant\", \"arguments\": {\"value\": {\"constantValue\": 0}}}}, {\"functionInvocationValue\": {\"functionName\": \"Image.constant\", \"arguments\": {\"value\": {\"constantValue\": 1}}}}]}}}}}, \"value\": {\"constantValue\": 42}}}}}}": {"type": "ImageCollection", "bands": [], "properties": {"test_prop": 42}, "features": [{"type": "Image", "bands": [{"id": "constant", "data_type": {"type": "PixelType", "precision": "int", "min": 0, "max": 0}, "crs": "EPSG:4326", "crs_transform": [1, 0, 0, 0, 1, 0]}], "properties": {"system:index": "0"}}, {"type": "Image", "bands": [{"id": "constant", "data_type": {"type": "PixelType", "precision": "int", "min": 1, "max": 1}, "crs": "EPSG:4326", "crs_transform": [1, 0, 0, 0, 1, 0]}], "properties": {"system:index": "1"}}]}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"Feature\", \"arguments\": {\"geometry\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.Point\", \"arguments\": {\"coordinates\": {\"constantValue\": [0, 0]}}}}, \"metadata\": {\"constantValue\": {\"foo\": \"bar\"}}}}}}}": {"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "properties": {"foo": "bar"}}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"Feature\", \"arguments\": {}}}}}": {"type": "Feature", "geometry": null, "properties": {}}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"Collection\", \"arguments\": {\"features\": {\"arrayValue\": {\"values\": [{\"functionInvocationValue\": {\"functionName\": \"Feature\", \"arguments\": {\"geometry\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.Point\", \"arguments\": {\"coordinates\": {\"constantValue\": [0, 0]}}}}, \"metadata\": {\"constantValue\": {\"foo\": \"bar\"}}}}}]}}}}}}}": {"type": "FeatureCollection", "columns": {"foo": "String", "system:index": "String"}, "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [0, 0]}, "id": "0", "properties": {"foo": "bar"}}]}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"Date\", \"arguments\": {\"value\": {\"constantValue\": \"2021-03-27T14:01:07\"}}}}}}": {"type": "Date", "value": 1616853667000}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"Filter.equals\", \"arguments\": {\"leftField\": {\"constantValue\": \"foo\"}, \"rightValue\": {\"constantValue\": \"bar\"}}}}}}": {"type": "Filter.eq", "rightValue": "bar", "leftField": "foo"}, "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": {\"foo\": \"bar\"}}}}": {"foo": "bar"}, "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": [1, 2, 3, 4]}}}": [1, 2, 3, 4], "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"List.sequence\", \"arguments\": {\"end\": {\"constantValue\": 20}, \"start\": {\"constantValue\": 0}, \"step\": {\"constantValue\": 1}}}}}}": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": \"13th Warrior is an underrated movie\"}}}": "13th Warrior is an underrated movie", "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": 42}}}": 42, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.Point\", \"arguments\": {\"coordinates\": {\"constantValue\": [1.112312, 2]}}}}}}": {"type": "Point", "coordinates": [1.112312, 2]}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.MultiPoint\", \"arguments\": {\"coordinates\": {\"constantValue\": [[1, 1], [2, 2]]}}}}}}": {"type": "MultiPoint", "coordinates": [[1, 1], [2, 2]]}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.LineString\", \"arguments\": {\"coordinates\": {\"constantValue\": [[1, 1], [2, 2], [3, 3]]}}}}}}": {"type": "LineString", "coordinates": [[1, 1], [2, 2], [3, 3]]}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.MultiLineString\", \"arguments\": {\"coordinates\": {\"constantValue\": [[[0, 0], [1, 1]]]}}}}}}": {"type": "MultiLineString", "coordinates": [[[0, 0], [1, 1]]]}, "{\"result\": \"0\", \"values\": {\"1\": {\"constantValue\": [0, 0]}, \"0\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.Polygon\", \"arguments\": {\"coordinates\": {\"arrayValue\": {\"values\": [{\"arrayValue\": {\"values\": [{\"valueReference\": \"1\"}, {\"constantValue\": [1, 1]}, {\"constantValue\": [2, 2]}, {\"valueReference\": \"1\"}]}}]}}, \"evenOdd\": {\"constantValue\": true}}}}}}": {"type": "Polygon", "coordinates": [[[0, 0], [1, 1], [2, 2], [0, 0]]]}, "{\"result\": \"0\", \"values\": {\"1\": {\"constantValue\": [0, 0]}, \"2\": {\"constantValue\": [4, 6]}, \"0\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.MultiPolygon\", \"arguments\": {\"coordinates\": {\"arrayValue\": {\"values\": [{\"arrayValue\": {\"values\": [{\"arrayValue\": {\"values\": [{\"valueReference\": \"1\"}, {\"constantValue\": [1, 1]}, {\"constantValue\": [2, 2]}, {\"valueReference\": \"1\"}]}}, {\"arrayValue\": {\"values\": [{\"valueReference\": \"2\"}, {\"constantValue\": [3, 2]}, {\"constantValue\": [1, 2]}, {\"valueReference\": \"2\"}]}}]}}]}}, \"evenOdd\": {\"constantValue\": true}}}}}}": {"type": "MultiPolygon", "coordinates": [[[[0, 0], [1, 1], [2, 2], [0, 0]], [[4, 6], [3, 2], [1, 2], [4, 6]]]]}, "{\"result\": \"0\", \"values\": {\"1\": {\"constantValue\": [0, 0]}, \"0\": {\"functionInvocationValue\": {\"functionName\": \"GeometryConstructors.LinearRing\", \"arguments\": {\"coordinates\": {\"arrayValue\": {\"values\": [{\"valueReference\": \"1\"}, {\"constantValue\": [1, 1]}, {\"constantValue\": [2, 2]}, {\"valueReference\": \"1\"}]}}}}}}}": {"type": "LinearRing", "coordinates": [[0, 0], [1, 1], [2, 2], [0, 0]]}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"DateRange\", \"arguments\": {\"end\": {\"constantValue\": \"2022-03-01T14:32:11\"}, \"start\": {\"constantValue\": \"2020-01-01T21:01:10\"}}}}}}": {"type": "DateRange", "dates": [1577912470000, 1646145131000]}, "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": {\"id\": \"bar\", \"type\": \"Foo\"}}}}": {"id": "bar", "type": "Foo"}, "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": {\"crs\": \"EPSG:32610\", \"data_type\": {\"max\": 65535, \"min\": 0, \"precision\": \"int\", \"type\": \"PixelType\"}, \"dimensions\": [1830, 1830], \"id\": \"B1\"}}}}": {"crs": "EPSG:32610", "data_type": {"max": 65535, "min": 0, "precision": "int", "type": "PixelType"}, "dimensions": [1830, 1830], "id": "B1"}, "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": {\"data_type\": {\"max\": 65535, \"min\": 0, \"precision\": \"int\", \"type\": \"PixelType\"}, \"id\": \"B1\"}}}}": {"data_type": {"max": 65535, "min": 0, "precision": "int", "type": "PixelType"}, "id": "B1"}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.float\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "float"}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.double\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "double"}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.int8\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "int", "min": -128, "max": 127}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.uint8\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "int", "min": 0, "max": 255}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.int16\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "int", "min": -32768, "max": 32767}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.uint16\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "int", "min": 0, "max": 65535}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.int32\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "int", "min": -2147483648, "max": 2147483647}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.uint32\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "int", "min": 0, "max": 4294967295}, "{\"result\": \"0\", \"values\": {\"0\": {\"functionInvocationValue\": {\"functionName\": \"PixelType\", \"arguments\": {\"precision\": {\"functionInvocationValue\": {\"functionName\": \"PixelType.int64\", \"arguments\": {}}}}}}}}": {"type": "PixelType", "precision": "int", "min": -9.223372036854776e+18, "max": 9.223372036854776e+18}, "{\"result\": \"0\", \"values\": {\"0\": {\"constantValue\": {\"max\": 255, \"min\": 10, \"precision\": \"int\", \"type\": \"PixelType\"}}}}": {"max": 255, "min": 10, "precision": "int", "type": "PixelType"}}
\ No newline at end of file
diff --git a/tests/test_html.py b/tests/test_html.py
index eabb743..ce633de 100644
--- a/tests/test_html.py
+++ b/tests/test_html.py
@@ -1,45 +1,12 @@
-import json
-import os
-
 import ee
 
 from eerepr.html import convert_to_html
-
-
-def load_info(obj):
-    """Load client-side info for an Earth Engine object.
-
-    Info is retrieved (if available) from a local JSON file using the serialized
-    object as the key. If the data does not exist locally, it is loaded from Earth
-    Engine servers and stored for future use.
-    """
-    serialized = obj.serialize()
-
-    if not os.path.isdir("./tests/data"):
-        os.mkdir("./tests/data")
-
-    try:
-        with open("./tests/data/data.json") as src:
-            existing_data = json.load(src)
-
-    # File is missing or unreadable
-    except (FileNotFoundError, json.JSONDecodeError):
-        existing_data = {}
-        with open("./tests/data/data.json", "w") as dst:
-            json.dump(existing_data, dst)
-
-    # File exists, but info does not
-    if serialized not in existing_data:
-        with open("./tests/data/data.json", "w") as dst:
-            existing_data[serialized] = obj.getInfo()
-            json.dump(existing_data, dst)
-
-    return existing_data[serialized]
+from tests.cache import get_info
 
 
 def test_image():
     obj = ee.Image.constant(0).set("system:id", "foo")
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
     assert "Image foo (1 band)" in rep
     assert "bands: List (1 element)" in rep
@@ -53,7 +20,7 @@ def test_imagecollection():
             ee.Image.constant(1),
         ]
     ).set("test_prop", 42)
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "ImageCollection (2 elements)" in rep
@@ -63,7 +30,7 @@ def test_imagecollection():
 
 def test_feature():
     obj = ee.Feature(geom=ee.Geometry.Point([0, 0]), opt_properties={"foo": "bar"})
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Feature (Point, 1 property)" in rep
@@ -71,7 +38,7 @@ def test_feature():
 
 def test_empty_feature():
     obj = ee.Feature(None)
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Feature (0 properties)" in rep
@@ -80,7 +47,7 @@ def test_empty_feature():
 def test_featurecollection():
     feat = ee.Feature(geom=ee.Geometry.Point([0, 0]), opt_properties={"foo": "bar"})
     obj = ee.FeatureCollection([feat])
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "FeatureCollection (1 element, 2 columns)" in rep
@@ -88,7 +55,7 @@ def test_featurecollection():
 
 def test_date():
     obj = ee.Date("2021-03-27T14:01:07")
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Date" in rep
@@ -97,7 +64,7 @@ def test_date():
 
 def test_filter():
     obj = ee.Filter.eq("foo", "bar")
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Filter.eq" in rep
@@ -105,7 +72,7 @@ def test_filter():
 
 def test_dict():
     obj = ee.Dictionary({"foo": "bar"})
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Object (1 property)" in rep
@@ -113,19 +80,19 @@ def test_dict():
 
 def test_list():
     short_obj = ee.List([1, 2, 3, 4])
-    short_info = load_info(short_obj)
+    short_info = get_info(short_obj)
     short_rep = convert_to_html(short_info)
     assert "[1, 2, 3, 4]" in short_rep
 
     long_obj = ee.List.sequence(0, 20, 1)
-    long_info = load_info(long_obj)
+    long_info = get_info(long_obj)
     long_rep = convert_to_html(long_info)
     assert "List (21 elements)" in long_rep
 
 
 def test_string():
     obj = ee.String("13th Warrior is an underrated movie")
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "13th Warrior is an underrated movie" in rep
@@ -133,7 +100,7 @@ def test_string():
 
 def test_number():
     obj = ee.Number(42)
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "42" in rep
@@ -141,7 +108,7 @@ def test_number():
 
 def test_point():
     obj = ee.Geometry.Point([1.112312, 2])
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Point (1.11, 2.00)" in rep
@@ -149,7 +116,7 @@ def test_point():
 
 def test_multipoint():
     obj = ee.Geometry.MultiPoint([[1, 1], [2, 2]])
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "MultiPoint (2 vertices)" in rep
@@ -157,7 +124,7 @@ def test_multipoint():
 
 def test_linestring():
     obj = ee.Geometry.LineString([[1, 1], [2, 2], [3, 3]])
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "LineString (3 vertices)" in rep
@@ -165,7 +132,7 @@ def test_linestring():
 
 def test_multilinestring():
     obj = ee.Geometry.MultiLineString([[[0, 0], [1, 1]]])
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "MultiLineString" in rep
@@ -173,7 +140,7 @@ def test_multilinestring():
 
 def test_polygon():
     obj = ee.Geometry.Polygon([[0, 0], [1, 1], [2, 2], [0, 0]])
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Polygon (4 vertices)" in rep
@@ -186,7 +153,7 @@ def test_multipolygon():
             [[4, 6], [3, 2], [1, 2], [4, 6]],
         ]
     )
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "MultiPolygon (8 vertices)" in rep
@@ -194,7 +161,7 @@ def test_multipolygon():
 
 def test_linearring():
     obj = ee.Geometry.LinearRing([[0, 0], [1, 1], [2, 2], [0, 0]])
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "LinearRing (4 vertices)" in rep
@@ -202,7 +169,7 @@ def test_linearring():
 
 def test_daterange():
     obj = ee.DateRange("2020-01-01T21:01:10", "2022-03-01T14:32:11")
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "DateRange [2020-01-01 21:01:10, 2022-03-01 14:32:11]" in rep
@@ -210,7 +177,7 @@ def test_daterange():
 
 def test_typed_obj():
     obj = ee.Dictionary({"type": "Foo", "id": "bar"})
-    info = load_info(obj)
+    info = get_info(obj)
     rep = convert_to_html(info)
 
     assert "Foo bar" in rep
@@ -230,7 +197,7 @@ def test_band():
             "crs": crs,
         }
     )
-    band1_info = load_info(band1)
+    band1_info = get_info(band1)
     band1_rep = convert_to_html(band1_info)
     assert '"B1", unsigned int16, EPSG:32610, 1830x1830 px' in band1_rep
 
@@ -240,21 +207,21 @@ def test_band():
             "data_type": data_type,
         }
     )
-    band2_info = load_info(band2)
+    band2_info = get_info(band2)
     band2_rep = convert_to_html(band2_info)
     assert '"B1", unsigned int16' in band2_rep
 
 
 def test_pixel_types():
-    assert "float" in convert_to_html(load_info(ee.PixelType.float()))
-    assert "double" in convert_to_html(load_info(ee.PixelType.double()))
-    assert "signed int8" in convert_to_html(load_info(ee.PixelType.int8()))
-    assert "unsigned int8" in convert_to_html(load_info(ee.PixelType.uint8()))
-    assert "signed int16" in convert_to_html(load_info(ee.PixelType.int16()))
-    assert "unsigned int16" in convert_to_html(load_info(ee.PixelType.uint16()))
-    assert "signed int32" in convert_to_html(load_info(ee.PixelType.int32()))
-    assert "unsigned int32" in convert_to_html(load_info(ee.PixelType.uint32()))
-    assert "signed int64" in convert_to_html(load_info(ee.PixelType.int64()))
+    assert "float" in convert_to_html(get_info(ee.PixelType.float()))
+    assert "double" in convert_to_html(get_info(ee.PixelType.double()))
+    assert "signed int8" in convert_to_html(get_info(ee.PixelType.int8()))
+    assert "unsigned int8" in convert_to_html(get_info(ee.PixelType.uint8()))
+    assert "signed int16" in convert_to_html(get_info(ee.PixelType.int16()))
+    assert "unsigned int16" in convert_to_html(get_info(ee.PixelType.uint16()))
+    assert "signed int32" in convert_to_html(get_info(ee.PixelType.int32()))
+    assert "unsigned int32" in convert_to_html(get_info(ee.PixelType.uint32()))
+    assert "signed int64" in convert_to_html(get_info(ee.PixelType.int64()))
 
     custom_type = dict(type="PixelType", min=10, max=255, precision="int")
-    assert "int ∈ [10, 255]" in convert_to_html(load_info(ee.Dictionary(custom_type)))
+    assert "int ∈ [10, 255]" in convert_to_html(get_info(ee.Dictionary(custom_type)))