def test_file_read_and_write(jpg_with_external_annotations,
                             jpg_with_internal_annotations):
    with FileForTests(jpg_with_external_annotations, "r") as f:
        assert ({
            "sambrose": {
                "Property": [[metadata_objects.Property("key", "value"), None]]
            }
        } == f.annotations)

    with FileForTests(jpg_with_internal_annotations, "r") as f:
        assert ({
            "sambrose": {
                "Property": [[metadata_objects.Property("key", "value"), None]]
            }
        } == f.annotations)

    assert (not os.path.exists(jpg_with_internal_annotations + ".xmp"))

    with FileForTests(jpg_with_internal_annotations, "w") as f:
        assert ({
            "sambrose": {
                "Property": [[metadata_objects.Property("key", "value"), None]]
            }
        } == f.annotations)

    assert (os.path.exists(jpg_with_internal_annotations + ".xmp"))
def test_qidata_object_extra():
	qidata_object = ObjectForTests()

	# If we start by adding an annotation, everything should be fine
	qidata_object.addAnnotation("jdoe", metadata_objects.Property(key="test", value="0"), None)
	assert(
	  dict(
	    jdoe=dict(
	      Property=[[metadata_objects.Property(key="test", value="0"), None]],
	    ),
	  ) == qidata_object.annotations
	)
	def __init__(self):
		self._annotations = dict(
		  jdoe=dict(
		    Property=[
		      [metadata_objects.Property(key="prop", value="11"), 0]
		    ]
		  ),
		)
def test_read_only_qidata_object():
	qidata_object = ReadOnlyObjectForTests()

	# Make sure "add" and "remove" cannot be used
	a=metadata_objects.Property(key="another_prop", value="10")
	with pytest.raises(ReadOnlyException):
		qidata_object.addAnnotation("jdoe", a, None)
	with pytest.raises(ReadOnlyException):
		qidata_object.removeAnnotation("jdoe", a, None)
def test_qidata_file(jpg_file_path):
    # Open file in "w" mode and add annotation
    a = metadata_objects.Property(key="prop", value="10")
    f = FileForTests(jpg_file_path, "w")
    f.addAnnotation("jdoe", a, None)
    f.addAnnotation("jdoe", a, 1)
    f.close()

    # Make sure that once the file is closed, we can't do any special operation
    with pytest.raises(ClosedFileException):
        f.cancelChanges()

    with pytest.raises(ClosedFileException):
        f.addAnnotation("jdoe", a, 1)

    # Open file with context manager in "r" mode and check annotation is there
    with FileForTests(jpg_file_path, "r") as f:
        assert (dict(jdoe=dict(Property=[
            [metadata_objects.Property(key="prop", value="10"), None],
            [metadata_objects.Property(key="prop", value="10"), 1],
        ], ), ) == f.annotations)

    # Remove all annotations, but then cancel everythin by reloading
    f = FileForTests(jpg_file_path, "w")
    f.removeAnnotation("jdoe", a, None)
    f.removeAnnotation("jdoe", a, 1)
    f.cancelChanges()
    assert (dict(jdoe=dict(Property=[
        [metadata_objects.Property(key="prop", value="10"), None],
        [metadata_objects.Property(key="prop", value="10"), 1],
    ], ), ) == f.annotations)
    f.close()

    # Test properties
    f = FileForTests(jpg_file_path, "r")
    assert (jpg_file_path == f.name)
    assert (not f.closed)
    f.close()
    assert (f.closed)
def test_read_only_cannot_be_modified():
	qidata_object = ReadOnlyObjectWithAnnotationsForTests()

	jdoe_annotations = qidata_object.getAnnotations("jdoe", "Property")
	assert(1 == len(jdoe_annotations))
	jdoe_prop = jdoe_annotations[0][0]
	jdoe_prop.key = "better_key"
	assert(
	  dict(
	    jdoe=dict(
	      Property=[
	        [metadata_objects.Property(key="prop", value="11"), 0]
	      ]
	    ),
	  ) == qidata_object.annotations
	)
def test_specialized_qidatafile(file_name, class_, datatype, valid_locs,
                                invalid_locs):
    with qidata.open(conftest.sandboxed(file_name), "r") as _f:
        assert (isinstance(_f, class_))
        assert (datatype == _f.type)

    with qidata.open(conftest.sandboxed(file_name), "w") as _f:
        a = metadata_objects.Property(key="prop", value="10")
        _f.addAnnotation("jdoe", a, None)
        for invalid_loc in invalid_locs:
            with pytest.raises(Exception) as e:
                _f.addAnnotation("jdoe", a, invalid_loc)
            assert ('Location %s is invalid' %
                    str(invalid_loc) == e.value.message)

        for valid_loc in valid_locs:
            _f.addAnnotation("jdoe", a, valid_loc)
def test_qidata_object():
	qidata_object = ObjectForTests()

	# Annotations should be empty
	assert(dict() == qidata_object.annotations)

	# They should stay empty when modifying the returned dict
	annotations = qidata_object.annotations
	annotations["test"] = 0
	assert(dict() == qidata_object.annotations)

	# Annotation is not settable
	with pytest.raises(AttributeError):
		qidata_object.annotations = annotations

	# But it is still possible to add annotations
	qidata_object.addAnnotation(
	  "jdoe",
	  metadata_objects.Property(key="test", value="0"),
	  None
	)
	assert(
	  dict(
	    jdoe=dict(
	      Property=[[metadata_objects.Property(key="test", value="0"), None]],
	    ),
	  ) == qidata_object.annotations
	)
	assert(["jdoe"] == qidata_object.annotators)

	# However, only real metadata can be passed
	with pytest.raises(TypeError):
		qidata_object.addAnnotation("jdoe", FakeAnnotation(), None)

	with pytest.raises(TypeError):
		qidata_object.addAnnotation("jdoe", Property(), None)

	with pytest.raises(TypeError):
		qidata_object.addAnnotation("jdoe", AnotherFakeAnnotation(), None)

	# Make sure Context, TimeStamp and Transform cannot be added, as they are
	# reserved for special purposes
	with pytest.raises(TypeError):
		qidata_object.addAnnotation("jdoe", metadata_objects.Context(), None)

	with pytest.raises(TypeError):
		qidata_object.addAnnotation("jdoe", metadata_objects.Transform(), None)

	with pytest.raises(TypeError):
		qidata_object.addAnnotation("jdoe", metadata_objects.TimeStamp(), None)

	# And the given location must be validated by our object
	with pytest.raises(Exception):
		qidata_object.addAnnotation(
		  "jdoe",
		  metadata_objects.Property(key="test", value="0"),
		  -1
		)

	# Once added, we can still modify an annotation by changing the one on our
	# side
	a=metadata_objects.Property(key="another_prop", value="10")
	qidata_object.addAnnotation("jdoe", a, None)
	assert(
	  dict(
	    jdoe=dict(
	      Property=[
	        [metadata_objects.Property(key="test", value="0"), None],
	        [metadata_objects.Property(key="another_prop", value="10"), None]
	      ],
	    ),
	  ) == qidata_object.annotations
	)
	a.value = 11
	assert(
	  dict(
	    jdoe=dict(
	      Property=[
	        [metadata_objects.Property(key="test", value="0"), None],
	        [metadata_objects.Property(key="another_prop", value="11"), None]
	      ],
	    ),
	  ) == qidata_object.annotations
	)

	# And it can also be removed
	qidata_object.removeAnnotation("jdoe",a)
	assert(
	  dict(
	    jdoe=dict(
	      Property=[
	        [metadata_objects.Property(key="test", value="0"), None],
	      ],
	    ),
	  ) == qidata_object.annotations
	)

	# Add the same annotation multiple times, at different locations
	qidata_object.addAnnotation("jdoe", a, 0)
	qidata_object.addAnnotation("jdoe", a, 1)
	qidata_object.addAnnotation("jdoe", a, 0)
	qidata_object.addAnnotation("jdoe", a, None)
	assert(
	  dict(
	    jdoe=dict(
	      Property=[
	        [metadata_objects.Property(key="test", value="0"), None],
	        [metadata_objects.Property(key="another_prop", value="11"), 0],
	        [metadata_objects.Property(key="another_prop", value="11"), 1],
	        [metadata_objects.Property(key="another_prop", value="11"), 0],
	        [metadata_objects.Property(key="another_prop", value="11"), None],
	      ],
	    ),
	  ) == qidata_object.annotations
	)
	qidata_object.removeAnnotation("jdoe",a)
	assert(
	  dict(
	    jdoe=dict(
	      Property=[
	        [metadata_objects.Property(key="test", value="0"), None],
	        [metadata_objects.Property(key="another_prop", value="11"), 0],
	        [metadata_objects.Property(key="another_prop", value="11"), 1],
	        [metadata_objects.Property(key="another_prop", value="11"), 0],
	      ],
	    ),
	  ) == qidata_object.annotations
	)
	qidata_object.removeAnnotation("jdoe",a)
	assert(
	  dict(
	    jdoe=dict(
	      Property=[
	        [metadata_objects.Property(key="test", value="0"), None],
	        [metadata_objects.Property(key="another_prop", value="11"), 1],
	        [metadata_objects.Property(key="another_prop", value="11"), 0],
	      ],
	    ),
	  ) == qidata_object.annotations
	)

	# Trying to remove stuff at the wrong location raises
	with pytest.raises(ValueError):
		qidata_object.removeAnnotation(
		  "jdoe",
		  metadata_objects.Property(key="test", value="0"),
		  0
		)
	with pytest.raises(ValueError):
		qidata_object.removeAnnotation("jdoe",a,2)

	# Trying to remove other things raises exceptions
	with pytest.raises(TypeError):
		qidata_object.removeAnnotation("jdoe",FakeAnnotation())

	with pytest.raises(TypeError):
		qidata_object.removeAnnotation("jdoe",Property())

	with pytest.raises(ValueError):
		qidata_object.removeAnnotation("jsmith",a)

	# When the last object is removed, empty sections are removed
	qidata_object.removeAnnotation("jdoe",a)
	qidata_object.removeAnnotation(
	  "jdoe",
	  metadata_objects.Property(key="test", value="0")
	)
	qidata_object.removeAnnotation("jdoe",a)
	assert(
	  dict() == qidata_object.annotations
	)
	qidata_object.addAnnotation("jdoe", a, 0)
	qidata_object.removeAnnotation("jdoe", a, 0)
	assert(
	  dict() == qidata_object.annotations
	)

	b=metadata_objects.Object("qrcode", "10", 1)
	qidata_object.addAnnotation("jdoe", b, 0)
	with pytest.raises(ValueError):
		qidata_object.removeAnnotation("jdoe", a, 0)
	qidata_object.addAnnotation("jdoe", a, 0)

	assert(
	  dict(
	    jdoe=dict(
	      Object=[
	        [b, 0],
	      ],
	      Property=[
	        [a, 0]
	      ]
	    ),
	  ) == qidata_object.annotations
	)

	assert([] == qidata_object.getAnnotations("jsmith"))
	assert([] == qidata_object.getAnnotations("jdoe", "Face"))

	with pytest.raises(TypeError):
		qidata_object.getAnnotations("jdoe", "Toto")

	jdoe_annotations = qidata_object.getAnnotations("jdoe")
	assert(2 == len(jdoe_annotations))
	jdoe_annotations = qidata_object.getAnnotations("jdoe", "Property")
	assert(1 == len(jdoe_annotations))
	jdoe_prop = jdoe_annotations[0][0]
	jdoe_prop.key = "better_key"
	print qidata_object
	assert(
	  dict(
	    jdoe=dict(
	      Object=[
	        [b, 0],
	      ],
	      Property=[
	        [metadata_objects.Property(key="better_key", value="11"), 0]
	      ]
	    ),
	  ) == qidata_object.annotations
	)