Skip to content

Commit

Permalink
SinglefileData: add support for pathlib.Path for file argument (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
greschd authored Nov 18, 2020
1 parent f04dbf1 commit 1c48d71
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 135 deletions.
3 changes: 2 additions & 1 deletion aiida/orm/nodes/data/singlefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import inspect
import os
import warnings
import pathlib

from aiida.common import exceptions
from aiida.common.warnings import AiidaDeprecationWarning
Expand Down Expand Up @@ -102,7 +103,7 @@ def set_file(self, file, filename=None):
"""
# pylint: disable=redefined-builtin

if isinstance(file, str):
if isinstance(file, (str, pathlib.Path)):
is_filelike = False

key = os.path.basename(file)
Expand Down
312 changes: 178 additions & 134 deletions tests/orm/data/test_singlefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,151 +10,195 @@
"""Tests for the `SinglefileData` class."""

import os
import tempfile
import io
import tempfile
import pathlib

from aiida.backends.testbase import AiidaTestCase
from aiida.orm import SinglefileData, load_node


class TestSinglefileData(AiidaTestCase):
"""Tests for the `SinglefileData` class."""

def test_reload_singlefile_data(self):
"""Test writing and reloading a `SinglefileData` instance."""
content_original = 'some text ABCDE'

with tempfile.NamedTemporaryFile(mode='w+') as handle:
filepath = handle.name
basename = os.path.basename(filepath)
handle.write(content_original)
handle.flush()
node = SinglefileData(file=filepath)

uuid = node.uuid

with node.open() as handle:
content_written = handle.read()

self.assertEqual(node.list_object_names(), [basename])
self.assertEqual(content_written, content_original)

node.store()

with node.open() as handle:
content_stored = handle.read()

self.assertEqual(content_stored, content_original)
self.assertEqual(node.list_object_names(), [basename])

node_loaded = load_node(uuid)
self.assertTrue(isinstance(node_loaded, SinglefileData))

with node.open() as handle:
content_loaded = handle.read()

self.assertEqual(content_loaded, content_original)
self.assertEqual(node_loaded.list_object_names(), [basename])

with node_loaded.open() as handle:
self.assertEqual(handle.read(), content_original)

def test_construct_from_filelike(self):
"""Test constructing an instance from filelike instead of filepath."""
content_original = 'some testing text\nwith a newline'

with tempfile.NamedTemporaryFile(mode='wb+') as handle:
basename = os.path.basename(handle.name)
handle.write(content_original.encode('utf-8'))
handle.flush()
handle.seek(0)
node = SinglefileData(file=handle)

with node.open() as handle:
content_stored = handle.read()

self.assertEqual(content_stored, content_original)
self.assertEqual(node.list_object_names(), [basename])

node.store()

with node.open() as handle:
content_stored = handle.read()

self.assertEqual(content_stored, content_original)
self.assertEqual(node.list_object_names(), [basename])

def test_construct_from_string(self):
"""Test constructing an instance from a string."""
content_original = 'some testing text\nwith a newline'

with io.BytesIO(content_original.encode('utf-8')) as handle:
node = SinglefileData(file=handle)

with node.open() as handle:
content_stored = handle.read()

self.assertEqual(content_stored, content_original)
self.assertEqual(node.list_object_names(), [SinglefileData.DEFAULT_FILENAME])

node.store()

with node.open() as handle:
content_stored = handle.read()

self.assertEqual(content_stored, content_original)
self.assertEqual(node.list_object_names(), [SinglefileData.DEFAULT_FILENAME])

def test_construct_with_filename(self):
"""Test constructing an instance, providing a filename."""
content_original = 'some testing text\nwith a newline'
filename = 'myfile.txt'
import pytest

# test creating from string
with io.BytesIO(content_original.encode('utf-8')) as handle:
node = SinglefileData(file=handle, filename=filename)
from aiida.orm import SinglefileData, load_node

with node.open() as handle:
content_stored = handle.read()

self.assertEqual(content_stored, content_original)
self.assertEqual(node.list_object_names(), [filename])
@pytest.fixture
def check_singlefile_content():
"""Fixture to check the content of a SinglefileData.
# test creating from file
with tempfile.NamedTemporaryFile(mode='wb+') as handle:
handle.write(content_original.encode('utf-8'))
handle.flush()
handle.seek(0)
node = SinglefileData(file=handle, filename=filename)
Checks the content of a SinglefileData node against the given
reference content and filename.
"""

with node.open() as handle:
content_stored = handle.read()
def inner(node, content_reference, filename, open_mode='r'):
with node.open(mode=open_mode) as handle:
assert handle.read() == content_reference

self.assertEqual(content_stored, content_original)
self.assertEqual(node.list_object_names(), [filename])
assert node.list_object_names() == [filename]

def test_binary_file(self):
"""Test that the constructor accepts binary files."""
byte_array = [120, 3, 255, 0, 100]
content_binary = bytearray(byte_array)
return inner

with tempfile.NamedTemporaryFile(mode='wb+') as handle:
basename = os.path.basename(handle.name)
handle.write(bytearray(content_binary))
handle.flush()
handle.seek(0)
node = SinglefileData(handle.name)

with node.open(mode='rb') as handle:
content_stored = handle.read()
@pytest.fixture
def check_singlefile_content_with_store(check_singlefile_content): # pylint: disable=redefined-outer-name
"""Fixture to check the content of a SinglefileData before and after .store().
self.assertEqual(content_stored, content_binary)
self.assertEqual(node.list_object_names(), [basename])
Checks the content of a SinglefileData node against the given reference
content and filename twice, before and after calling .store().
"""

def inner(node, content_reference, filename, open_mode='r'):
check_singlefile_content(
node=node,
content_reference=content_reference,
filename=filename,
open_mode=open_mode,
)
node.store()

with node.open(mode='rb') as handle:
content_stored = handle.read()

self.assertEqual(content_stored, content_binary)
self.assertEqual(node.list_object_names(), [basename])
check_singlefile_content(
node=node,
content_reference=content_reference,
filename=filename,
open_mode=open_mode,
)

return inner


def test_reload_singlefile_data(
clear_database_before_test, # pylint: disable=unused-argument
check_singlefile_content_with_store, # pylint: disable=redefined-outer-name
check_singlefile_content # pylint: disable=redefined-outer-name
):
"""Test writing and reloading a `SinglefileData` instance."""
content_original = 'some text ABCDE'

with tempfile.NamedTemporaryFile(mode='w+') as handle:
filepath = handle.name
basename = os.path.basename(filepath)
handle.write(content_original)
handle.flush()
node = SinglefileData(file=filepath)

check_singlefile_content_with_store(
node=node,
content_reference=content_original,
filename=basename,
)

node_loaded = load_node(node.uuid)
assert isinstance(node_loaded, SinglefileData)

check_singlefile_content(
node=node,
content_reference=content_original,
filename=basename,
)
check_singlefile_content(
node=node_loaded,
content_reference=content_original,
filename=basename,
)


def test_construct_from_filelike(
clear_database_before_test, # pylint: disable=unused-argument
check_singlefile_content_with_store # pylint: disable=redefined-outer-name
):
"""Test constructing an instance from filelike instead of filepath."""
content_original = 'some testing text\nwith a newline'

with tempfile.NamedTemporaryFile(mode='wb+') as handle:
basename = os.path.basename(handle.name)
handle.write(content_original.encode('utf-8'))
handle.flush()
handle.seek(0)
node = SinglefileData(file=handle)

check_singlefile_content_with_store(
node=node,
content_reference=content_original,
filename=basename,
)


def test_construct_from_string(
clear_database_before_test, # pylint: disable=unused-argument
check_singlefile_content_with_store # pylint: disable=redefined-outer-name
):
"""Test constructing an instance from a string."""
content_original = 'some testing text\nwith a newline'

with io.BytesIO(content_original.encode('utf-8')) as handle:
node = SinglefileData(file=handle)

check_singlefile_content_with_store(
node=node,
content_reference=content_original,
filename=SinglefileData.DEFAULT_FILENAME,
)


def test_construct_with_path(
clear_database_before_test, # pylint: disable=unused-argument
check_singlefile_content_with_store # pylint: disable=redefined-outer-name
):
"""Test constructing an instance from a pathlib.Path."""
content_original = 'please report to the ministry of silly walks'

with tempfile.NamedTemporaryFile(mode='w+') as handle:
filepath = pathlib.Path(handle.name).resolve()
filename = filepath.name
handle.write(content_original)
handle.flush()
node = SinglefileData(file=filepath)

check_singlefile_content_with_store(
node=node,
content_reference=content_original,
filename=filename,
)


def test_construct_with_filename(
clear_database_before_test, # pylint: disable=unused-argument
check_singlefile_content # pylint: disable=redefined-outer-name
):
"""Test constructing an instance, providing a filename."""
content_original = 'some testing text\nwith a newline'
filename = 'myfile.txt'

# test creating from string
with io.BytesIO(content_original.encode('utf-8')) as handle:
node = SinglefileData(file=handle, filename=filename)

check_singlefile_content(node=node, content_reference=content_original, filename=filename)

# test creating from file
with tempfile.NamedTemporaryFile(mode='wb+') as handle:
handle.write(content_original.encode('utf-8'))
handle.flush()
handle.seek(0)
node = SinglefileData(file=handle, filename=filename)

check_singlefile_content(node=node, content_reference=content_original, filename=filename)


def test_binary_file(
clear_database_before_test, # pylint: disable=unused-argument
check_singlefile_content_with_store # pylint: disable=redefined-outer-name
):
"""Test that the constructor accepts binary files."""
byte_array = [120, 3, 255, 0, 100]
content_binary = bytearray(byte_array)

with tempfile.NamedTemporaryFile(mode='wb+') as handle:
basename = os.path.basename(handle.name)
handle.write(bytearray(content_binary))
handle.flush()
handle.seek(0)
node = SinglefileData(handle.name)

check_singlefile_content_with_store(
node=node,
content_reference=content_binary,
filename=basename,
open_mode='rb',
)

0 comments on commit 1c48d71

Please sign in to comment.