Skip to content

Commit 18ea90b

Browse files
committed
Update testing on save/load json/yaml
1 parent b865e16 commit 18ea90b

File tree

8 files changed

+131
-6
lines changed

8 files changed

+131
-6
lines changed

examples/test/test.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,39 @@ A model....
2424
</tr>
2525

2626

27+
<tr>
28+
<td><b>float_like_optional2</b></td>
29+
<td>int</td>
30+
<td><i>name also says it all...</i></td>
31+
</tr>
32+
33+
34+
<tr>
35+
<td><b>mid</b></td>
36+
<td><a href="#midclassnoid">MidClassNoId</a></td>
37+
<td><i></i></td>
38+
</tr>
39+
40+
41+
</table>
42+
43+
## MidClassNoId
44+
A model....
45+
46+
### Allowed parameters
47+
<table>
48+
<tr>
49+
<td><b>int_val</b></td>
50+
<td>int</td>
51+
<td><i>name says it all...</i></td>
52+
</tr>
53+
54+
55+
<tr>
56+
<td><b>str_val</b></td>
57+
<td>int</td>
58+
<td><i>name says it all...</i></td>
59+
</tr>
60+
61+
2762
</table>

examples/test/test.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import modelspec
22
from modelspec import field, instance_of, optional
33
from modelspec.base_types import Base
4+
from modelspec.utils import load_json
45
from typing import List
56

67
# Example testing multiple options...
@@ -17,6 +18,20 @@ def convert2float(x: Any) -> float:
1718
return None
1819

1920

21+
@modelspec.define
22+
class MidClassNoId(Base):
23+
"""
24+
A model....
25+
26+
Args:
27+
int_val: name says it all...
28+
str_val: name says it all...
29+
"""
30+
31+
int_val: int = field(default=None, validator=instance_of(int))
32+
str_val: int = field(default=None, validator=optional(instance_of(str)))
33+
34+
2035
@modelspec.define
2136
class TopClass(Base):
2237
"""
@@ -26,6 +41,7 @@ class TopClass(Base):
2641
id: The unique id of the thing
2742
float_like_req: name says it all...
2843
float_like_optional: name also says it all...
44+
float_like_optional2: name also says it all...
2945
"""
3046

3147
id: str = field(validator=instance_of(str))
@@ -35,19 +51,37 @@ class TopClass(Base):
3551
float_like_optional: int = field(
3652
default=None, validator=optional(instance_of(float)), converter=convert2float
3753
)
54+
float_like_optional2: int = field(
55+
default=None, validator=optional(instance_of(float)), converter=convert2float
56+
)
57+
58+
mid: MidClassNoId = field(
59+
default=None, validator=optional(instance_of(MidClassNoId))
60+
)
3861

3962

4063
tc = TopClass(
41-
id="MyTest", float_like_req="03"
64+
id="MyTest", float_like_req="04"
4265
) # a string which can be converted to a float...
4366

4467
# tc.float_like_req = 2.01
45-
tc.float_like_optional = 43
68+
tc.float_like_optional = 44
69+
tc.float_like_optional2 = 66
70+
# tc.mid = MidClassNoId(int_val=4, str_val="three")
4671

4772

4873
print(tc)
4974

5075
tc.to_yaml_file("test_instance.yaml")
76+
tc.to_json_file("test_instance.json")
77+
tc.to_xml_file("test_instance.xml")
78+
79+
str_b4 = str(tc)
80+
81+
str_json_after = TopClass.from_json_file("test_instance.json")
82+
print(str_json_after)
83+
str_yaml_after = TopClass.from_yaml_file("test_instance.yaml")
84+
print(str_yaml_after)
5185

5286
doc_md = tc.generate_documentation(format="markdown")
5387

examples/test/test.specification.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,18 @@ TopClass:
1010
float_like_optional:
1111
type: int
1212
description: name also says it all...
13+
float_like_optional2:
14+
type: int
15+
description: name also says it all...
16+
mid:
17+
type: MidClassNoId
18+
description: ''
19+
MidClassNoId:
20+
definition: A model....
21+
allowed_parameters:
22+
int_val:
23+
type: int
24+
description: name says it all...
25+
str_val:
26+
type: int
27+
description: name says it all...

examples/test/test_instance.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"MyTest": {
3+
"float_like_req": 4.0,
4+
"float_like_optional": 44.0,
5+
"float_like_optional2": 66.0
6+
}
7+
}

examples/test/test_instance.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" ?>
2+
<TopClass id="MyTest" float_like_req="4.0" float_like_optional="44.0" float_like_optional2="66.0" mid="None"/>

examples/test/test_instance.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
MyTest:
2-
float_like_req: 3.0
3-
float_like_optional: 43.0
2+
float_like_req: 4.0
3+
float_like_optional: 44.0
4+
float_like_optional2: 66.0

src/modelspec/base_types.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,26 @@ def from_dict(cls, d: Dict[str, Any]) -> "Base":
156156
else:
157157
return converter.structure(d, cls)
158158

159+
@classmethod
160+
def from_yaml(cls, yaml_str: str) -> "Base":
161+
"""Instantiate an modelspec object from a YAML string"""
162+
return cls.from_dict(yaml.load(yaml_str, Loader=yaml.SafeLoader))
163+
164+
@classmethod
165+
def from_yaml_file(cls, yaml_file: str) -> "Base":
166+
"""Instantiate an modelspec object from a file containing YAML"""
167+
return cls.from_dict(yaml.load(yaml_str, Loader=yaml.SafeLoader))
168+
159169
@classmethod
160170
def from_json(cls, json_str: str) -> "Base":
161171
"""Instantiate an modelspec object from a JSON string"""
162172
return cls.from_dict(json.loads(json_str))
163173

174+
@classmethod
175+
def from_json_file(cls, json_file: str) -> "Base":
176+
"""Instantiate an modelspec object from a file containing JSON"""
177+
return cls.from_dict(json.load(json_file))
178+
164179
@classmethod
165180
def from_bson(cls, bson_str: str) -> "Base":
166181
"""Instantiate an modelspec object from a BSON string"""

tests/test_base.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ def test_save_load_json(tmp_path):
162162
# net.id = net.id+'_yaml'
163163
net.to_yaml_file(filenamey)
164164

165-
# filenamex = str(Path(tmp_path) / f"{net.id}.xml")
166-
# net.to_xml_file(filenamex)
165+
filenamex = str(Path(tmp_path) / f"{net.id}.xml")
166+
net.to_xml_file(filenamex)
167167

168168
from modelspec.utils import load_json, load_yaml, load_xml
169169

@@ -173,12 +173,24 @@ def test_save_load_json(tmp_path):
173173

174174
str_netj = str(netj)
175175

176+
netj2 = NewNetwork.from_json(net.to_json())
177+
str_netj2 = str(netj2)
178+
179+
netj3 = NewNetwork.from_json_file(filenamej)
180+
str_netj3 = str(netj3)
181+
176182
datay = load_yaml(filenamey)
177183
print_v("Loaded network specification from %s" % filenamey)
178184

179185
nety = NewNetwork.from_dict(datay)
180186
str_nety = str(nety)
181187

188+
nety2 = NewNetwork.from_yaml(net.to_yaml() + " ")
189+
str_nety2 = str(nety2)
190+
191+
nety3 = NewNetwork.from_yaml_file(filenamey)
192+
str_nety3 = str(nety3)
193+
182194
# datax = load_xml(filenamex)
183195
# print_v("Loaded network specification from %s" % filenamex)
184196

@@ -201,6 +213,8 @@ def test_save_load_json(tmp_path):
201213
) # Order not preserved in py2, just test len
202214
else:
203215
assert str_orig == str_netj
216+
assert str_orig == str_netj2
217+
assert str_orig == str_netj3
204218

205219
print("Test YAML..")
206220
if sys.version_info[0] == 2:
@@ -209,6 +223,8 @@ def test_save_load_json(tmp_path):
209223
) # Order not preserved in py2, just test len
210224
else:
211225
assert str_orig == str_nety
226+
assert str_orig == str_nety2
227+
assert str_orig == str_nety3
212228

213229
# print("Test XML..")
214230
# if sys.version_info[0] == 2:

0 commit comments

Comments
 (0)