Skip to content

Commit

Permalink
Allow patterns in file paths (#51)
Browse files Browse the repository at this point in the history
* Add resolution function to common

* Use resolution function in assertion and case

* Add unit tests

* Update CHANGELOG

* Update version

* Address linter

* Clearer error message and remove assert

* Update tests to include unit test for resolve_single_path function

* Remove parenthesis

* Remove unnecessary str

* Update test to instantiate NFTestAssert
  • Loading branch information
yashpatel6 authored Jan 5, 2024
1 parent d096b96 commit 39f1119
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 5 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

---

## [1.0.0] - 2023-10-23
### Added
- Support for patterns in expected and actual file paths

---

## [1.0.0-rc.4] - 2023-10-04
### Changed
- Wrap all NextFlow output with real-time line-by-line log statements
Expand Down
12 changes: 8 additions & 4 deletions nftest/NFTestAssert.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
import os
import selectors
import subprocess as sp
from pathlib import Path
from subprocess import PIPE
from typing import Callable
from logging import getLogger, DEBUG, ERROR

from nftest.common import calculate_checksum
from nftest.common import calculate_checksum, resolve_single_path
from nftest.NFTestENV import NFTestENV


Expand All @@ -19,13 +18,18 @@ def __init__(self, actual:str, expect:str, method:str='md5', script:str=None):
""" Constructor """
self._env = NFTestENV()
self._logger = getLogger('NFTest')
self.actual = Path(actual)
self.expect = Path(expect)
self.actual = actual
self.expect = expect
self.method = method
self.script = script

self.startup_time = datetime.datetime.now(tz=datetime.timezone.utc)

def identify_assertion_files(self) -> None:
""" Resolve actual and expected paths """
self.actual = resolve_single_path(self.actual)
self.expect = resolve_single_path(self.expect)

def assert_exists(self) -> None:
"Assert that the expected and actual files exist."
if not self.actual.exists():
Expand Down
1 change: 1 addition & 0 deletions nftest/NFTestCase.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def test(self):
return
for ass in self.asserts:
try:
ass.identify_assertion_files()
ass.assert_exists()
ass.assert_updated()
ass.assert_expected()
Expand Down
2 changes: 1 addition & 1 deletion nftest/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
""" nftest module """

__version__ = '1.0.0-rc.4'
__version__ = '1.0.0'
9 changes: 9 additions & 0 deletions nftest/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ def remove_nextflow_logs() -> None:
else:
os.remove(file)

def resolve_single_path(path:str) -> Path:
""" Resolve wildcards in path and ensure only a single path is identified """
expanded_paths = glob.glob(path)
if 1 != len(expanded_paths):
raise ValueError(f"Path `{path}` resolved to 0 or more than 1 file: {expanded_paths}." \
" Assertion failed.")

return Path(expanded_paths[0])

def calculate_checksum(path:Path) -> str:
""" Calculate checksum recursively.
Args:
Expand Down
31 changes: 31 additions & 0 deletions test/unit/test_NFTestAssert.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,34 @@ def test_assert_expected(mock_assert):
mock_assert.return_value.get_assert_method = lambda: lambda x, y: False
with pytest.raises(AssertionError):
NFTestAssert.assert_expected(mock_assert())

@pytest.mark.parametrize(
'glob_return_value,case_pass',
[
([], False),
(['a', 'b'], False),
(['a'], True)
]
)
@mock.patch('glob.glob')
@mock.patch('nftest.NFTestAssert.NFTestENV')
@mock.patch('logging.getLogger')
def test_identify_assertions_files(
mock_getlogger,
mock_env,
mock_glob,
glob_return_value,
case_pass):
''' Tests for proper file identification '''

mock_glob.return_value = glob_return_value
mock_env.return_value = None
mock_getlogger.return_value = lambda x: None

test_assert = NFTestAssert('', '')

if case_pass:
test_assert.identify_assertion_files()
else:
with pytest.raises(ValueError):
test_assert.identify_assertion_files()
27 changes: 27 additions & 0 deletions test/unit/test_common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# pylint: disable=W0212
''' Test module for common functions '''

import mock
import pytest

from nftest.common import resolve_single_path

@pytest.mark.parametrize(
'glob_return_value,case_pass',
[
([], False),
(['a', 'b'], False),
(['a'], True)
]
)
@mock.patch('glob.glob')
def test_resolve_single_path(mock_glob, glob_return_value, case_pass):
''' Tests for proper file identification '''
test_path = '/some/path'
mock_glob.return_value = glob_return_value

if case_pass:
resolve_single_path(test_path)
else:
with pytest.raises(ValueError):
resolve_single_path(test_path)

0 comments on commit 39f1119

Please sign in to comment.