Static type analysis

This commit is contained in:
Joel Collins 2020-11-30 13:36:45 +00:00
parent 3aebb8bead
commit 7866ec0f47
63 changed files with 1825 additions and 2722 deletions

View file

@ -0,0 +1,232 @@
import datetime
import io
import os
import uuid
from collections import OrderedDict
import piexif
from PIL import Image, ImageChops
from openflexure_microscope.captures import THUMBNAIL_SIZE, CaptureObject
from openflexure_microscope.captures.capture import (
build_captures_from_exif,
capture_from_path,
)
IN_DIR = "tests/images/"
OUT_DIR = "tests/images/out/"
def generate_small_image():
# Create a dummy image to serve in the stream
image = Image.new("RGB", (20, 20), color=(0, 0, 0))
return image
def generate_small_thumbnail():
# Create a dummy image to serve in the stream
image = Image.new("RGB", (20, 20), color=(0, 0, 0))
image.thumbnail(THUMBNAIL_SIZE)
return image
def generate_small_capture(filename: str):
out = os.path.join(OUT_DIR, filename)
obj = CaptureObject(out)
generate_small_image().save(obj, format="JPEG")
return obj
def check_valid_capture(obj: CaptureObject):
assert isinstance(obj.time, datetime.datetime)
assert isinstance(obj.id, uuid.UUID)
assert isinstance(obj.annotations, dict)
assert isinstance(obj.tags, list)
assert obj.file
assert obj.format
assert obj.basename
assert obj.filefolder
assert obj.name
def check_valid_openflexure_metadata(d: dict):
assert "image" in d
assert d["image"].get("id")
assert d["image"].get("name")
assert d["image"].get("time")
assert d["image"].get("format")
assert isinstance(d["image"].get("tags"), list)
assert isinstance(d["image"].get("annotations"), dict)
def test_new_capture_object():
obj = generate_small_capture("capture0.jpg")
check_valid_capture(obj)
def test_initial_metadata():
obj = generate_small_capture("capture1.jpg")
data = obj.read_full_metadata()
check_valid_openflexure_metadata(data)
def test_tags():
obj = generate_small_capture("capture2.jpg")
obj.put_tags(["foo", "bar"])
assert obj.read_full_metadata()["image"]["tags"] == ["foo", "bar"]
obj.delete_tag("foo")
assert obj.read_full_metadata()["image"]["tags"] == ["bar"]
# Delete nonexistent tag, should change nothing
obj.delete_tag("foo")
assert obj.read_full_metadata()["image"]["tags"] == ["bar"]
def test_annotations():
obj = generate_small_capture("capture3.jpg")
obj.put_annotations({"foo": "zoo", "bar": "zar"})
assert obj.read_full_metadata()["image"]["annotations"] == {
"foo": "zoo",
"bar": "zar",
}
obj.delete_annotation("foo")
assert obj.read_full_metadata()["image"]["annotations"] == {"bar": "zar"}
# Delete nonexistent annotation, should change nothing
obj.delete_annotation("foo")
assert obj.read_full_metadata()["image"]["annotations"] == {"bar": "zar"}
def test_put_metadata():
obj = generate_small_capture("capture4.jpg")
obj.put_metadata({"foo": {"bar": "zar"}})
assert obj.read_full_metadata()["foo"] == {"bar": "zar"}
def test_put_and_save():
obj = generate_small_capture("capture_all.jpg")
obj.put_and_save(
tags=["foo", "bar"],
annotations={"foo": "zoo", "bar": "zar"},
metadata={"foo": {"bar": "zar"}},
)
full_metadata = obj.read_full_metadata()
assert full_metadata["image"]["tags"] == ["foo", "bar"]
assert full_metadata["image"]["annotations"] == {"foo": "zoo", "bar": "zar"}
assert full_metadata["foo"] == {"bar": "zar"}
def test_capture_from_path_this_version():
"""Tests reloading a capture object from a file created in the working server version
"""
def _check_metadata(data: dict):
assert data["image"]["tags"] == ["foo", "bar"]
assert data["image"]["annotations"] == {"foo": "zoo", "bar": "zar"}
assert data["foo"] == {"bar": "zar"}
# Create the capture file
obj_in = generate_small_capture("capture_reload.jpg")
obj_in.put_and_save(
tags=["foo", "bar"],
annotations={"foo": "zoo", "bar": "zar"},
metadata={"foo": {"bar": "zar"}},
)
full_metadata_in = obj_in.read_full_metadata()
check_valid_openflexure_metadata(full_metadata_in)
_check_metadata(full_metadata_in)
# Reload the capture file
obj = capture_from_path(os.path.join(OUT_DIR, "capture_reload.jpg"))
check_valid_capture(obj)
full_metadata = obj.read_full_metadata()
check_valid_openflexure_metadata(full_metadata)
_check_metadata(full_metadata)
def test_capture_from_path_v280():
"""Tests reloading a capture object from a file created in server v2.8.0
"""
obj = capture_from_path(os.path.join(IN_DIR, "capture_v280.jpg"))
check_valid_capture(obj)
full_metadata = obj.read_full_metadata()
check_valid_openflexure_metadata(full_metadata)
assert full_metadata["image"]["tags"] == ["foo", "bar"]
assert full_metadata["image"]["annotations"] == {"foo": "zoo", "bar": "zar"}
assert full_metadata["foo"] == {"bar": "zar"}
def test_build_captures_from_exif():
# Load the whole tests captures directory
objs = build_captures_from_exif(IN_DIR)
# Make sure we have a valid, populated OrderedDict
assert isinstance(objs, OrderedDict)
assert len(objs) > 0
# Check each reloaded capture
for obj in objs.values():
check_valid_capture(obj)
def test_data():
# Get a reference PIL image
ref_data = generate_small_image()
# Generate a capture with the same image data as our reference
obj = generate_small_capture("capture5.jpg")
# Pull the capture data out
obj_data = Image.open(obj.data)
# Compare the images
diff = ImageChops.difference(obj_data, ref_data)
assert not diff.getbbox()
def test_binary():
# Get a reference PIL image
ref_data = generate_small_image()
# Generate a capture with the same image data as our reference
obj = generate_small_capture("capture6.jpg")
# Pull the capture data out
obj_data = Image.open(io.BytesIO(obj.binary))
# Compare the images
diff = ImageChops.difference(obj_data, ref_data)
assert not diff.getbbox()
def test_thumbnail():
# Get a reference PIL image
ref_thumb = generate_small_thumbnail()
# Generate a capture with the same image data as our reference
obj = generate_small_capture("capture7.jpg")
# Pull the generated thumbnail out
obj_thumb = Image.open(obj.thumbnail)
# Compare the images
diff = ImageChops.difference(obj_thumb, ref_thumb)
assert not diff.getbbox()
# Assert thumbnail was saved to capture file EXIF data
exif_dict = piexif.load(obj.file)
thumbnail = exif_dict.pop("thumbnail")
assert thumbnail
# Compare the images
diff = ImageChops.difference(Image.open(io.BytesIO(thumbnail)), ref_thumb)
def test_delete():
# Generate a capture with the same image data as our reference
obj = generate_small_capture("capture_del.jpg")
assert os.path.isfile(obj.file)
obj.delete()
assert not os.path.isfile(obj.file)