diff --git a/.gitignore b/.gitignore index 4616626..c3b1d76 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ # Python egg metadata, regenrated from source files in setuptools /*.egg-info +.cache/ +.coverage diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..df0e7ed --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +sudo: false + +language: python + +python: + - "3.5" + - "3.6" + +before_install: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh + - bash miniconda.sh -b -p $HOME/miniconda + - export PATH="$HOME/miniconda/bin:$PATH" + +install: + - conda install --yes python=$TRAVIS_PYTHON_VERSION --file requirements/conda_requirements.txt + - pip install -r requirements/pypi_requirements.txt + - pip install -r requirements/test_requirements.txt + - python setup.py install + +script: pytest --pep8 --cov=./ + +notifications: + email: false + +after_success: + - codecov diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..ff4e4e6 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,24 @@ +codecov: + branch: master + +coverage: + precision: 2 + round: down + range: "50...100" + + status: + project: + default: + target: auto + threshold: null + branches: null + + patch: + default: + target: auto + branches: null + +comment: + layout: "header, diff, changes, sunburst, uncovered" + branches: null + behavior: default diff --git a/requirements/conda_requirements.txt b/requirements/conda_requirements.txt new file mode 100644 index 0000000..f23634b --- /dev/null +++ b/requirements/conda_requirements.txt @@ -0,0 +1,3 @@ +numpy +scipy +matplotlib diff --git a/requirements/pypi_requirements.txt b/requirements/pypi_requirements.txt new file mode 100644 index 0000000..5d2f211 --- /dev/null +++ b/requirements/pypi_requirements.txt @@ -0,0 +1,2 @@ +gitpython +tqdm diff --git a/requirements/rtd_requirements.txt b/requirements/rtd_requirements.txt new file mode 100644 index 0000000..a2954e3 --- /dev/null +++ b/requirements/rtd_requirements.txt @@ -0,0 +1 @@ +numpydoc diff --git a/requirements/test_requirements.txt b/requirements/test_requirements.txt new file mode 100644 index 0000000..e965d4f --- /dev/null +++ b/requirements/test_requirements.txt @@ -0,0 +1,8 @@ +codecov +coverage +pep8 +pytest +pytest-cache +pytest-cov +pytest-pep8 +gitpython diff --git a/test/unit/test_RandomWalk.py b/test/unit/test_RandomWalk.py new file mode 100644 index 0000000..8ae6976 --- /dev/null +++ b/test/unit/test_RandomWalk.py @@ -0,0 +1,83 @@ +import porespy as ps +import pytrax as pt +import scipy as sp +import os +import matplotlib.pyplot as plt + + +class SimulationTest(): + def setup_class(self): + self.l = 100 + self.im = ps.generators.overlapping_spheres(shape=[self.l, self.l], + radius=5, + porosity=0.5) + self.blobs = ps.generators.blobs([self.l, self.l, self.l]) + self.rw = pt.RandomWalk(self.blobs) + self.blobs_2d = ps.generators.blobs([self.l, self.l]).astype(int) + self.rw_2d = pt.RandomWalk(self.blobs_2d, seed=True) + + def test_random_walk(self): + self.rw.run(nt=1000, nw=100, stride=1) + assert sp.shape(self.rw.real_coords) == (1000, 100, 3) + + def test_plot_msd(self): + self.rw.plot_msd() + pass + + def test_random_walk_2d(self): + self.rw_2d.run(nt=1000, nw=100, same_start=True, stride=100) + assert sp.shape(self.rw_2d.real_coords) == (10, 100, 2) + + def test_plot_walk_2d(self): + self.rw_2d.plot_walk_2d(data='w') + assert hasattr(self.rw_2d, 'im_big') + assert sp.sum(self.rw_2d.im_big > self.rw_2d.nw) == 0 + plt.close('all') + + def test_export(self): + cwd = os.getcwd() + self.rw_2d.export_walk(sub='temp', image=self.rw_2d.im, sample=10) + subdir = os.path.join(cwd, 'temp') + assert os.path.exists(subdir) + file_list = os.listdir(subdir) + # 10 coordinate files based on the stride and number of steps + image + assert len(file_list) == 11 + # Delete all files and folder + for file in file_list: + fp = os.path.join(subdir, file) + os.remove(fp) + os.rmdir(subdir) + + def test_seed(self): + # rw_2d was initialized with seed = True, this should mean running it + # repeatedly produces the same movements + self.rw_2d.run(nt=1000, nw=100, same_start=True) + temp_coords = self.rw_2d.real_coords.copy() + self.rw_2d.run(nt=1000, nw=100, same_start=True) + assert sp.allclose(self.rw_2d.real_coords, temp_coords) + + def test_axial_density_plot(self): + self.rw.axial_density_plot(time=0, axis=0) + plt.close('all') + + def test_rw_analytics(self): + w_list = [10, 100] + t_list = [10, 100] + self.rw_2d.run_analytics(w_list, t_list, fname='test.csv') + cwd = os.getcwd() + fpath = os.path.join(cwd, 'test.csv') + assert os.path.exists(fpath) + os.remove(fpath) + plt.close('all') + +if __name__ == '__main__': + t = SimulationTest() + t.setup_class() + t.test_random_walk() + t.test_plot_msd() + t.test_random_walk_2d() + t.test_plot_walk_2d() + t.test_export() + t.test_seed() + t.test_axial_density_plot() + t.test_rw_analytics()