From 78508b673cc328b339816b890a26bd0fe3354ff0 Mon Sep 17 00:00:00 2001
From: James Graham <J.A.Graham@soton.ac.uk>
Date: Wed, 11 May 2016 12:40:26 +0100
Subject: [PATCH] Investigating JSON config files

---
 pycgtool/parsers/json.py  | 38 ++++++++++++++++++++++++++++++++++++++
 test/data/twice.json      | 15 +++++++++++++++
 test/data/water.json      |  7 +++++++
 test/test_parsers_json.py | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 93 insertions(+)
 create mode 100644 pycgtool/parsers/json.py
 create mode 100644 test/data/twice.json
 create mode 100644 test/data/water.json
 create mode 100644 test/test_parsers_json.py

diff --git a/pycgtool/parsers/json.py b/pycgtool/parsers/json.py
new file mode 100644
index 0000000..ca6efe8
--- /dev/null
+++ b/pycgtool/parsers/json.py
@@ -0,0 +1,38 @@
+import json
+
+
+class DuplicateSectionError(Exception):
+    """
+    Exception used to indicate that a section has appeared twice in a file.
+    """
+    def __repr__(self):
+        return "Section {0} appears twice in file {1}.".format(*self.args)
+
+
+class Record(dict):
+    def __setattr__(self, key, value):
+        self[key] = value
+
+    def __getattr__(self, item):
+        return self[item]
+
+
+class CFG:
+    def __init__(self, filename):
+        with open(filename) as f:
+            try:
+                self._json = json.load(f, object_hook=Record)
+            except ValueError:
+                raise DuplicateSectionError()
+
+    def __getitem__(self, item):
+        return Record(self._json[item])
+
+    def __contains__(self, item):
+        return item in self._json
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        pass
diff --git a/test/data/twice.json b/test/data/twice.json
new file mode 100644
index 0000000..8f67dec
--- /dev/null
+++ b/test/data/twice.json
@@ -0,0 +1,15 @@
+{"SOL":{
+   "beads":[
+        {"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
+   ],
+   "bonds":[
+   ]
+}}
+
+{"SOL":{
+   "beads":[
+        {"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
+   ],
+   "bonds":[
+   ]
+}}
diff --git a/test/data/water.json b/test/data/water.json
new file mode 100644
index 0000000..b9597be
--- /dev/null
+++ b/test/data/water.json
@@ -0,0 +1,7 @@
+{"SOL":{
+   "beads":[
+        {"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
+   ],
+   "bonds":[
+   ]
+}}
diff --git a/test/test_parsers_json.py b/test/test_parsers_json.py
new file mode 100644
index 0000000..c7aebaf
--- /dev/null
+++ b/test/test_parsers_json.py
@@ -0,0 +1,33 @@
+import unittest
+
+from pycgtool.parsers.json import CFG, DuplicateSectionError
+
+
+class TestParsersJson(unittest.TestCase):
+    def test_cfg_with(self):
+        with CFG("test/data/water.json"):
+            pass
+
+    def test_cfg_get_section(self):
+        with CFG("test/data/water.json") as cfg:
+            self.assertTrue("SOL" in cfg)
+            self.assertEqual(1, len(cfg["SOL"].beads))
+            bead = cfg["SOL"].beads[0]
+            self.assertEqual("W", bead.name)
+            self.assertEqual("P4", bead.type)
+            self.assertEqual(["OW", "HW1", "HW2"], bead.atoms)
+            self.assertEqual(0, len(cfg["SOL"].bonds))
+
+    def test_cfg_duplicate_error(self):
+        with self.assertRaises(DuplicateSectionError):
+            CFG("test/data/twice.json")
+
+    @unittest.expectedFailure
+    def test_include_file(self):
+        with CFG("test/data/martini.json") as cfg:
+            self.assertTrue("DOPC" in cfg)
+            self.assertTrue("GLY" in cfg)
+
+
+if __name__ == '__main__':
+    unittest.main()
-- 
GitLab