diff --git a/.travis.yml b/.travis.yml
index 719c104..39ada59 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,5 +39,5 @@ after_success:
   - coverage report -m
   - which coveralls
   - coveralls
-  - source deactivate
+  - conda deactivate
   - conda env remove -y -n $PY_ENV
diff --git a/src/spec2nexus/_requirements.py b/src/spec2nexus/_requirements.py
index 657df11..8f3e57a 100644
--- a/src/spec2nexus/_requirements.py
+++ b/src/spec2nexus/_requirements.py
@@ -8,7 +8,7 @@
 # The full license is in the file LICENSE.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
-
+REQUIREMENTS = "requirements.txt"
 
 def learn_requirements():
     """
@@ -16,12 +16,10 @@ def learn_requirements():
     
     ALL packages & version restrictions stated in requirements.txt
     """
-    req_file = 'requirements.txt'
-    reqs = []
-
     import os
     path = os.path.dirname(__file__)
-    req_file = os.path.join(path, '..', req_file)
+    req_file = os.path.join(path, '..', '..', REQUIREMENTS)
+    reqs = []
     if not os.path.exists(req_file):
         # not needed with installed package
         return reqs
diff --git a/src/spec2nexus/eznx.py b/src/spec2nexus/eznx.py
index 4ddd362..cc1ee90 100644
--- a/src/spec2nexus/eznx.py
+++ b/src/spec2nexus/eznx.py
@@ -143,7 +143,8 @@ def makeDataset(parent, name, data = None, **attr):
     :return: h5py dataset object
     '''
     if data is None:
-        obj = parent.create_dataset(name)
+        obj = parent.create_dataset(name, data="")
+        attr["NOTE"] = "no data supplied, value set to empty string"
     else:
         # storing-a-list-of-strings-to-a-hdf5-dataset-from-python
         # https://stackoverflow.com/questions/23220513/
@@ -167,12 +168,11 @@ def write_dataset(parent, name, data, **attr):
     :param obj data: the information to be written
     :param dict attr: optional dictionary of attributes
     """
-    try:
-        dset = parent[name]
-        dset[:] = data
-        addAttributes(dset, **attr)
-    except (KeyError, TypeError):
-        dset = makeDataset(parent, name, data, **attr)
+    if name in parent:
+        # dataset already exists
+        # delete it, any links to it may break
+        del parent[name]
+    dset = makeDataset(parent, name, data, **attr)
     return dset
 
 
@@ -236,10 +236,9 @@ def read_nexus_field(parent, dataset_name, astype=None):
     :param str dataset_name: name of the dataset (NeXus field) to be read
     :param obj astype: option to return as different data type
     """
-    try:
-        dataset = parent[dataset_name]
-    except KeyError:
+    if dataset_name not in parent:
         return None
+    dataset = parent[dataset_name]
     dtype = dataset.dtype
     if astype is not None:
         dtype = astype
diff --git a/src/spec2nexus/plugins/uxml.xsd b/src/spec2nexus/plugins/uxml.xsd
index 2a87e4f..97d2328 100644
--- a/src/spec2nexus/plugins/uxml.xsd
+++ b/src/spec2nexus/plugins/uxml.xsd
@@ -4,7 +4,7 @@
   <!-- 
   #UXML: XML Schema for UXML structured metadata
 
-#-----------------------------------------------------------------------------
+##############################################################################
 # :author:    Pete R. Jemian
 # :email:     prjemian@gmail.com
 # :copyright: (c) 2014-2019, Pete R. Jemian
@@ -12,7 +12,7 @@
 # Distributed under the terms of the Creative Commons Attribution 4.0 International Public License.
 #
 # The full license is in the file LICENSE.txt, distributed with this software.
-#-----------------------------------------------------------------------------
+##############################################################################
    -->
 
   <xs:element name="UXML">
diff --git a/src/spec2nexus/writer.py b/src/spec2nexus/writer.py
index 5bd6b50..911df40 100644
--- a/src/spec2nexus/writer.py
+++ b/src/spec2nexus/writer.py
@@ -181,24 +181,30 @@ class Writer(object):
             signal, axes = self.oneD(nxdata, scan)
 
         # these locations suggested to NIAC, easier to parse than attached to dataset!
-        if len(signal) == 0:
-            pass
+        # if len(signal) == 0:
+        #     pass
         
         # Syntax of axes attribute (http://wiki.nexusformat.org/2014_axes_and_uncertainties):
         #  @axes="H:K"       INCOREECT
         #  @axes="H", "K"    CORRECT
         if axes.find(':') >= 0:
-            axes = axes.split(':')
+            def fixer(s):
+                # h5py requires list of strings to be encoded
+                # see: https://stackoverflow.com/questions/23220513/storing-a-list-of-strings-to-a-hdf5-dataset-from-python
+                return s.encode("ascii", "ignore")
+            axes = list(map(fixer, axes.split(":")))
         eznx.addAttributes(nxdata, signal=signal, axes=axes)
-        #eznx.addAttributes(nxdata[signal], signal=1, axes=axes)    # deprecated now
-        # assume here that "axis_name" has rank=1
-        # TODO: test that scan.data[axis_name] has rank=1
         indices = [0,]     # 0-based reference
         if isinstance(axes, str):
             eznx.addAttributes(nxdata, **{axes+'_indices': indices})
         else:
             for axis_name in axes:
-                eznx.addAttributes(nxdata, **{axis_name+'_indices': indices})
+                axis_name = axis_name.decode("utf-8") 
+                # assume here that "axis_name" has rank=1
+                # if scan.data[axis_name] != 1:
+                #     pass    # TODO: and do what?
+                k = "%s%s" % (axis_name, '_indices')
+                eznx.addAttributes(nxdata, **{k: indices})
     
     def oneD(self, nxdata, scan):
         """*internal*: generic data parser for 1-D column data, returns signal and axis"""
@@ -284,8 +290,8 @@ class Writer(object):
                 if label not in nxdata:
                     axis = np.array( scan.data.get(label) )
                     self.write_ds(nxdata, label, utils.reshape_data(axis, data_shape))
-                else:
-                    pass
+                # else:
+                #     pass
 
             signal = utils.clean_name(scan.column_last)
             axes = ':'.join([label1, label2])

eznx: expand unit tests
More code could be tested in the eznx module.  See https://coveralls.io/builds/23443404/source?filename=src/spec2nexus/eznx.py
diff --git a/tests/test_eznx.py b/tests/test_eznx.py
index 541df11..92d22b8 100644
--- a/tests/test_eznx.py
+++ b/tests/test_eznx.py
@@ -13,6 +13,7 @@ unit tests for the writer module
 #-----------------------------------------------------------------------------
 
 import h5py
+import numpy
 import os
 import shutil
 import sys
@@ -44,8 +45,6 @@ class TestEznx(unittest.TestCase):
             shutil.rmtree(self.tempdir, ignore_errors=True)
 
     def test_example(self):
-        self.assertTrue(True, "trivial assertion - always True")
-        
         root = eznx.makeFile('test.h5', creator='eznx', default='entry')
         nxentry = eznx.makeGroup(root, 'entry', 'NXentry', default='data')
         ds = eznx.write_dataset(nxentry, 'title', 'simple test data')
@@ -110,6 +109,101 @@ class TestEznx(unittest.TestCase):
             self.assertEqual(len(tth), 4)
             self.assertEqual(tth[2], [10.0, 10.1, 10.2, 10.3][2])
 
+    def test_create_dataset_None(self):
+        root = eznx.makeFile('test.h5', creator='eznx', default='entry')
+        nxentry = eznx.makeGroup(root, 'entry', 'NXentry', default='data')
+        ds = eznx.makeDataset(nxentry, "data_is_None", None)
+
+        with h5py.File("test.h5", "r") as hp:
+            root = hp["/"]
+            nxentry = root["entry"]
+            self.assertTrue("data_is_None" in nxentry)
+
+            ds = nxentry["data_is_None"]
+            value = ds[()]        # ds.value deprecated in h5py
+            self.assertEqual(len(value), 0)
+            self.assertEqual(value, "")
+            self.assertTrue("NOTE" in ds.attrs)
+            note =  "no data supplied, value set to empty string"
+            self.assertEqual(ds.attrs["NOTE"],  note)
+
+    def test_write_dataset_existing(self):
+        root = eznx.makeFile('test.h5', creator='eznx', default='entry')
+        nxentry = eznx.makeGroup(root, 'entry', 'NXentry', default='data')
+        eznx.write_dataset(nxentry, "text", "some text")
+        eznx.write_dataset(nxentry, "text", "replacement text")
+
+        with h5py.File("test.h5", "r") as hp:
+            root = hp["/"]
+            nxentry = root["entry"]
+            self.assertTrue("text" in nxentry)
+            value = eznx.read_nexus_field(nxentry, "text", astype=str)
+            self.assertEqual(value, "replacement text")
+
+    def test_makeExternalLink(self):
+        external = eznx.makeFile('external.h5', creator='eznx', default='entry')
+        eznx.write_dataset(external, "text", "some text")
+
+        root = eznx.makeFile('test.h5', creator='eznx', default='entry')
+        nxentry = eznx.makeGroup(root, 'entry', 'NXentry', default='data')
+        eznx.makeExternalLink(root, 'external.h5', "/text", nxentry.name + "/external_text")
+
+        # check the external file first
+        with h5py.File("external.h5", "r") as hp:
+            root = hp["/"]
+            self.assertTrue("text" in root)
+            ds = root["text"]
+            value = ds[()]        # ds.value deprecated in h5py
+            self.assertEqual(value, [b"some text"])
+
+        # check the file with the external link
+        with h5py.File("test.h5", "r") as hp:
+            root = hp["/"]
+            nxentry = root["entry"]
+            self.assertTrue("external_text" in nxentry)
+            value = eznx.read_nexus_field(nxentry, "external_text")
+            self.assertEqual(value, b"some text")
+            value = eznx.read_nexus_field(nxentry, "external_text", astype=str)
+            self.assertEqual(value, "some text")
+
+    def test_read_nexus_field_alternatives(self):
+        root = eznx.makeFile('test.h5', creator='eznx', default='entry')
+        nxentry = eznx.makeGroup(root, 'entry', 'NXentry', default='data')
+        eznx.write_dataset(nxentry, "text", "some text")
+        eznx.write_dataset(nxentry, "number", 42)
+        eznx.write_dataset(nxentry, "array", [[1,2,3], [4,5,6]])
+
+        # check the file with the external link
+        with h5py.File("test.h5", "r") as hp:
+            root = hp["/"]
+            nxentry = root["entry"]
+            
+            value = eznx.read_nexus_field(nxentry, "key_error")
+            self.assertEqual(value, None)
+            
+            value = eznx.read_nexus_field(nxentry, "text")
+            self.assertEqual(value, b"some text")
+            value = eznx.read_nexus_field(nxentry, "text", astype=str)
+            self.assertEqual(value, "some text")
+            
+            value = eznx.read_nexus_field(nxentry, "number")
+            self.assertEqual(value, 42)
+            value = eznx.read_nexus_field(nxentry, "number", astype=float)
+            self.assertEqual(value, 42)
+            value = eznx.read_nexus_field(nxentry, "number", astype=str)
+            self.assertEqual(value, "42")
+            
+            ds = nxentry["array"]
+            value = ds[()]        # ds.value deprecated in h5py
+            expected = numpy.array([[1,2,3], [4,5,6]])
+            self.assertTrue((value == expected).any())
+
+            with self.assertRaises(RuntimeError) as context:
+                value = eznx.read_nexus_field(nxentry, "array")
+            received = str(context.exception)
+            expected = "unexpected 2-D data"
+            self.assertTrue(received.startswith(expected))
+
 
 def suite(*args, **kw):
     test_list = [
diff --git a/tests/test_requirements.py b/tests/test_requirements.py
new file mode 100644
index 0000000..2a1cc90
--- /dev/null
+++ b/tests/test_requirements.py
@@ -0,0 +1,54 @@
+'''
+unit tests for the _requirements module
+'''
+
+#-----------------------------------------------------------------------------
+# :author:    Pete R. Jemian
+# :email:     prjemian@gmail.com
+# :copyright: (c) 2014-2019, Pete R. Jemian
+#
+# Distributed under the terms of the Creative Commons Attribution 4.0 International Public License.
+#
+# The full license is in the file LICENSE.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+import os, sys
+import numpy
+import unittest
+from builtins import isinstance
+
+_test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+_path = os.path.abspath(os.path.join(_test_path, 'src'))
+
+sys.path.insert(0, _path)
+sys.path.insert(0, _test_path)
+
+from spec2nexus import _requirements
+
+import tests.common
+
+
+class Test(unittest.TestCase):
+
+    def test_learn_requirements(self):
+        reqs = _requirements.learn_requirements()
+        self.assertTrue(isinstance(reqs, list))
+        self.assertGreater(len(reqs), 0)
+        self.assertEqual(len(reqs), 5)
+        self.assertTrue("h5py" in reqs)
+        self.assertTrue("numpy" in reqs)
+
+
+def suite(*args, **kw):
+    test_suite = unittest.TestSuite()
+    test_list = [
+        Test,
+        ]
+    for test_case in test_list:
+        test_suite.addTest(unittest.makeSuite(test_case))
+    return test_suite
+
+
+if __name__ == "__main__":
+    runner=unittest.TextTestRunner()
+    runner.run(suite())
diff --git a/tests/test_uxml.py b/tests/test_uxml.py
index b1ea735..67033ea 100644
--- a/tests/test_uxml.py
+++ b/tests/test_uxml.py
@@ -191,52 +191,52 @@ class TestData_3(unittest.TestCase):
 		
 		# text that UXML group defined as expected
 		self.assertTrue(os.path.exists(self.hname))
-		h5_file = h5py.File(self.hname)
-		self.assertTrue("S1" in h5_file)
-		nxentry = h5_file["/S1"]
-		self.assertTrue("UXML" in nxentry)
-		uxml = nxentry["UXML"]
-		self.assertTrue("NX_class" in uxml.attrs)
-		self.assertEqual(uxml.attrs["NX_class"], "NXnote")
-		
-		# spot-check a couple items
-		# group: attenuator_set
-		self.assertTrue("attenuator_set" in uxml)
-		group = uxml["attenuator_set"]
-		prefix = group.attrs.get("prefix")
-		description = group.attrs.get("description")
-		unique_id = group.attrs.get("unique_id")
-		self.assertEqual(prefix, "33idd:filter:")
-		self.assertEqual(description, "33-ID-D Filters")
-		self.assertEqual(unique_id, None)
-		
-		# <dataset name="corrdet_counter">corrdet</dataset>
-		self.assertTrue("corrdet_counter" in group)
-		ds = group["corrdet_counter"]
-		# http://docs.h5py.org/en/stable/whatsnew/2.1.html?highlight=dataset#dataset-value-property-is-now-deprecated
-		value = ds[()]		# ds.value deprecated in h5py
-		self.assertEqual(value, [b"corrdet"])
-		
-		# <dataset name="wait_time" type="float" units="s">0.500</dataset>
-		self.assertTrue("wait_time" in group)
-		ds = group["wait_time"]
-		attrs = dict(ds.attrs)
-		self.assertEqual(ds.attrs.get("units"), "s")
-		value = ds[()]		# ds.value deprecated in h5py
-		self.assertEqual(value, numpy.array([.5]))
-
-		# <hardlink name="attenuator1" target_id="33idd:filter:Fi1:"/>
-		self.assertTrue("attenuator1" in group)
-		attenuator1 = group["attenuator1"]
-		target = attenuator1.attrs.get("target")
-		self.assertNotEqual(target, attenuator1.name)
-		self.assertEqual(target, uxml["attenuator1"].name)
-
-		addr = "/S1/UXML/ad_file_info/file_format"
-		self.assertTrue(addr in h5_file)
-		ds = h5_file[addr]
-		value = ds[()]		# ds.value deprecated in h5py
-		self.assertEqual(value, [b"TIFF"])
+		with h5py.File(self.hname) as h5_file:
+			self.assertTrue("S1" in h5_file)
+			nxentry = h5_file["/S1"]
+			self.assertTrue("UXML" in nxentry)
+			uxml = nxentry["UXML"]
+			self.assertTrue("NX_class" in uxml.attrs)
+			self.assertEqual(uxml.attrs["NX_class"], "NXnote")
+			
+			# spot-check a couple items
+			# group: attenuator_set
+			self.assertTrue("attenuator_set" in uxml)
+			group = uxml["attenuator_set"]
+			prefix = group.attrs.get("prefix")
+			description = group.attrs.get("description")
+			unique_id = group.attrs.get("unique_id")
+			self.assertEqual(prefix, "33idd:filter:")
+			self.assertEqual(description, "33-ID-D Filters")
+			self.assertEqual(unique_id, None)
+			
+			# <dataset name="corrdet_counter">corrdet</dataset>
+			self.assertTrue("corrdet_counter" in group)
+			ds = group["corrdet_counter"]
+			# http://docs.h5py.org/en/stable/whatsnew/2.1.html?highlight=dataset#dataset-value-property-is-now-deprecated
+			value = ds[()]		# ds.value deprecated in h5py
+			self.assertEqual(value, [b"corrdet"])
+			
+			# <dataset name="wait_time" type="float" units="s">0.500</dataset>
+			self.assertTrue("wait_time" in group)
+			ds = group["wait_time"]
+			attrs = dict(ds.attrs)
+			self.assertEqual(ds.attrs.get("units"), "s")
+			value = ds[()]		# ds.value deprecated in h5py
+			self.assertEqual(value, numpy.array([.5]))
+	
+			# <hardlink name="attenuator1" target_id="33idd:filter:Fi1:"/>
+			self.assertTrue("attenuator1" in group)
+			attenuator1 = group["attenuator1"]
+			target = attenuator1.attrs.get("target")
+			self.assertNotEqual(target, attenuator1.name)
+			self.assertEqual(target, uxml["attenuator1"].name)
+	
+			addr = "/S1/UXML/ad_file_info/file_format"
+			self.assertTrue(addr in h5_file)
+			ds = h5_file[addr]
+			value = ds[()]		# ds.value deprecated in h5py
+			self.assertEqual(value, [b"TIFF"])
 
 
 class TestData_4(unittest.TestCase):
@@ -262,15 +262,15 @@ class TestData_4(unittest.TestCase):
 		# the ONLY structural difference between test_3.spec 
 		# and test_4.spec is the presence of this hardlink
 		self.assertTrue(os.path.exists(self.hname))
-		h5_file = h5py.File(self.hname)
-		source = h5_file["/S1/UXML/ad_detector/beam_center_x"]
-		link = h5_file["/S1/UXML/beam_center_x"]
-		target = source.attrs.get("target")
-
-		self.assertNotEqual(source.name, link.name)
-		self.assertNotEqual(target, None)
-		self.assertEqual(target, source.name)
-		self.assertEqual(target, link.attrs.get("target"))
+		with h5py.File(self.hname) as h5_file:
+			source = h5_file["/S1/UXML/ad_detector/beam_center_x"]
+			link = h5_file["/S1/UXML/beam_center_x"]
+			target = source.attrs.get("target")
+	
+			self.assertNotEqual(source.name, link.name)
+			self.assertNotEqual(target, None)
+			self.assertEqual(target, source.name)
+			self.assertEqual(target, link.attrs.get("target"))
 
 
 def suite(*args, **kw):
diff --git a/tests/test_writer.py b/tests/test_writer.py
index 133963e..07ed492 100644
--- a/tests/test_writer.py
+++ b/tests/test_writer.py
@@ -12,7 +12,11 @@ unit tests for the writer module
 # The full license is in the file LICENSE.txt, distributed with this software.
 #-----------------------------------------------------------------------------
 
-import os, sys
+import h5py
+import os
+import shutil
+import sys
+import tempfile
 import unittest
 
 _test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
@@ -48,20 +52,99 @@ class TestWriter(unittest.TestCase):
         out = writer.Writer(spec_data)
         scan_list = [1, 5, 7]
         out.save(self.hname, scan_list)
-        # TODO: make tests of other things in the Writer
+
         dd = out.root_attributes()
         self.assertTrue(isinstance(dd, dict))
+        
+        # TODO: test writer's various functions and methods
+
+        # test file written by Writer
+        with h5py.File(self.hname, "r") as hp:
+            root = hp["/"]
+            default = root.attrs.get("default")
+            self.assertNotEqual(default, None)
+            self.assertTrue(default in root)
+            nxentry = root[default]
+
+            default = nxentry.attrs.get("default")
+            self.assertNotEqual(default, None)
+            self.assertTrue(default in nxentry)
+            nxdata = nxentry[default]
+
+            signal = nxdata.attrs.get("signal")
+            self.assertNotEqual(signal, None)
+            self.assertTrue(signal in nxdata)
+
+
+class TestMeshes(unittest.TestCase):
+
+    def setUp(self):
+        self._owd = os.getcwd()
+        self.tempdir = tempfile.mkdtemp()
+        os.chdir(self.tempdir)
+
+    def tearDown(self):
+        if os.path.exists(self._owd):
+            os.chdir(self._owd)
+        if os.path.exists(self.tempdir):
+            shutil.rmtree(self.tempdir, ignore_errors=True)
+
+    def test_save_data_mesh(self):
+        #S 22  mesh  eta 57 57.1 10  chi 90.9 91 10  1
+        fname = os.path.join(_path, "spec2nexus", 'data', '33id_spec.dat')
+        hname = "test.h5"
+        spec_data = spec.SpecDataFile(fname)
+        out = writer.Writer(spec_data)
+        out.save(hname, [22])
+  
+        with h5py.File(hname, "r") as hp:
+            root = hp["/"]
+            nxdata = root["/S22/data"]
+            signal = nxdata.attrs["signal"]
+            self.assertEqual(nxdata[signal][()].shape, (11, 11))
+
+            ds = nxdata["_mca_"]
+            self.assertEqual(ds[()].shape, (11, 11, 91))
+            self.assertEqual(ds.attrs["axes"], "eta:chi:_mca_channel_")
+            self.assertEqual(ds.attrs["spec_name"], "_mca_")
+            self.assertEqual(ds.attrs["units"], "counts")
+
+    def test_save_data_hklmesh(self):
+        #S 17  hklmesh  H 1.9 2.1 100  K 1.9 2.1 100  -800000
+        fname = os.path.join(_path, "spec2nexus", 'data', '33bm_spec.dat')
+        hname = "test.h5"
+        spec_data = spec.SpecDataFile(fname)
+        out = writer.Writer(spec_data)
+        out.save(hname, [17])
+  
+        with h5py.File(hname, "r") as hp:
+            root = hp["/"]
+            nxdata = root["/S17/data"]
+            signal = nxdata.attrs["signal"]
+            axes = nxdata.attrs["axes"]
+            self.assertEqual(axes[0], b"H")
+            self.assertEqual(axes[1], b"K")
+
+    def test_save_data_hklscan(self):
+        #S 104 hklscan -0.0500048 -0.0500048 0.05 0.2 12.0002 12.0002 30 2
+        fname = os.path.join(_path, "spec2nexus", 'data', '33id_spec.dat')
+        hname = "test.h5"
+        spec_data = spec.SpecDataFile(fname)
+        out = writer.Writer(spec_data)
 
-#     sys.argv.append(os.path.join('data', 'APS_spec_data.dat'))
-#     sys.argv.append(os.path.join('data', '33id_spec.dat'))
-#     sys.argv.append(os.path.join('data', '33bm_spec.dat'))
-#     sys.argv.append(os.path.join('data', 'lmn40.spe'))
+        with self.assertRaises(NotImplementedError) as context:
+            out.save(hname, [104])
+        received = str(context.exception)
+        expected = "hklscan save_data() not yet implemented"
+        self.assertTrue(received.startswith(expected))
+        # FIXME:
 
 
 def suite(*args, **kw):
     test_suite = unittest.TestSuite()
     test_list = [
         TestWriter,
+        TestMeshes,
         ]
     for test_case in test_list:
         test_suite.addTest(unittest.makeSuite(test_case))

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi @ file:///croot/certifi_1671487769961/work/certifi
cycler==0.11.0
exceptiongroup==1.2.2
fonttools==4.38.0
h5py==3.8.0
importlib-metadata==6.7.0
iniconfig==2.0.0
kiwisolver==1.4.5
lxml==5.3.1
matplotlib==3.5.3
numpy==1.21.6
packaging==24.0
Pillow==9.5.0
pluggy==1.2.0
pyparsing==3.1.4
pytest==7.4.4
python-dateutil==2.9.0.post0
six==1.17.0
-e git+https://github.com/prjemian/spec2nexus.git@3d459fce6ae01fa6c7b70402e7286c15d2fd0df3#egg=spec2nexus
tomli==2.0.1
typing_extensions==4.7.1
zipp==3.15.0

name: spec2nexus
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cycler==0.11.0
      - exceptiongroup==1.2.2
      - fonttools==4.38.0
      - h5py==3.8.0
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - kiwisolver==1.4.5
      - lxml==5.3.1
      - matplotlib==3.5.3
      - numpy==1.21.6
      - packaging==24.0
      - pillow==9.5.0
      - pluggy==1.2.0
      - pyparsing==3.1.4
      - pytest==7.4.4
      - python-dateutil==2.9.0.post0
      - six==1.17.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - zipp==3.15.0
prefix: /opt/conda/envs/spec2nexus

tests/test_requirements.py::Test::test_learn_requirements tests/test_uxml.py::TestPlugin::test_postprocess tests/test_uxml.py::TestPlugin::test_writer
tests/test_eznx.py::TestEznx::test_create_dataset_None tests/test_eznx.py::TestEznx::test_example tests/test_eznx.py::TestEznx::test_makeExternalLink tests/test_eznx.py::TestEznx::test_read_nexus_field_alternatives tests/test_eznx.py::TestEznx::test_write_dataset_existing tests/test_uxml.py::TestData_error::testName tests/test_uxml.py::TestData_3::test_contents tests/test_uxml.py::TestData_4::test_contents tests/test_writer.py::TestWriter::testWriter tests/test_writer.py::TestMeshes::test_save_data_hklmesh tests/test_writer.py::TestMeshes::test_save_data_hklscan tests/test_writer.py::TestMeshes::test_save_data_mesh
tests/test_uxml.py::TestPlugin::test_parse tests/test_uxml.py::TestPlugin::test_process
src/spec2nexus/_requirements.py src/spec2nexus/eznx.py .travis.yml src/spec2nexus/writer.py src/spec2nexus/plugins/uxml.xsd
src/spec2nexus/_requirements.py src/spec2nexus/eznx.py .travis.yml src/spec2nexus/writer.py src/spec2nexus/plugins/uxml.xsd