Browse Source

state: change architecture and add get subjects (without property fill)

Bastien Sevajol 5 years ago
parent
commit
9467daf9de

+ 86 - 33
opencombat/state.py View File

@@ -1,8 +1,7 @@
1 1
 # coding: utf-8
2 2
 import importlib
3 3
 import typing
4
-from io import StringIO
5
-import sys
4
+from _elementtree import Element
6 5
 
7 6
 from lxml import etree
8 7
 
@@ -11,22 +10,73 @@ from synergine2.log import get_logger
11 10
 from synergine2.simulation import Subject
12 11
 
13 12
 from opencombat.exception import StateLoadError
13
+from opencombat.simulation.base import TileStrategySimulation
14
+from opencombat.util import get_class_from_string_path
15
+
16
+
17
+class State(object):
18
+    def __init__(
19
+        self,
20
+        config: Config,
21
+        state_root: Element,
22
+        simulation: TileStrategySimulation,
23
+    ) -> None:
24
+        self._config = config
25
+        self._state_root = state_root
26
+        self._subjects = None  # type: typing.List[Subject]
27
+        self._simulation = simulation
28
+
29
+    @property
30
+    def subjects(self) -> typing.List[Subject]:
31
+        if self._subjects is None:
32
+            self._subjects = self._get_subjects()
33
+
34
+        return self._subjects
35
+
36
+    def _get_subjects(self) -> typing.List[Subject]:
37
+        subjects = []
38
+        subject_elements = self._state_root.find('subjects').findall('subject')
39
+
40
+        for subject_element in subject_elements:
41
+            subject_class_path = subject_element.find('type').text
42
+            subject_class = get_class_from_string_path(
43
+                self._config,
44
+                subject_class_path,
45
+            )
46
+            subject = subject_class(self._config, self._simulation)
47
+
48
+            # TODO BS 2018-06-13: Fill subject with property
49
+            subjects.append(subject)
50
+
51
+        return subjects
14 52
 
15 53
 
16 54
 class StateLoader(object):
17 55
     def __init__(
18 56
         self,
19 57
         config: Config,
20
-        state_file_path: str,
58
+        simulation: TileStrategySimulation,
21 59
     ) -> None:
22
-        self.logger = get_logger('StateLoader', config)
23
-        self.config = config
24
-        self.state_file_path = state_file_path
25
-        self._validate()
60
+        self._logger = get_logger('StateLoader', config)
61
+        self._config = config
62
+        self._simulation = simulation
63
+
64
+    def get_state(
65
+        self,
66
+        state_file_path: str,
67
+    ) -> State:
68
+        return State(
69
+            self._config,
70
+            self._validate_and_return_state_element(state_file_path),
71
+            self._simulation,
72
+        )
26 73
 
27
-    def _validate(self) -> None:
74
+    def _validate_and_return_state_element(
75
+        self,
76
+        state_file_path: str,
77
+    ) -> Element:
28 78
         # open and read schema file
29
-        schema_file_path = self.config.get(
79
+        schema_file_path = self._config.get(
30 80
             'global.state_schema',
31 81
             'opencombat/state.xsd',
32 82
         )
@@ -34,32 +84,32 @@ class StateLoader(object):
34 84
             schema_to_check = schema_file.read()
35 85
 
36 86
         # open and read xml file
37
-        with open(self.state_file_path, 'r') as xml_file:
87
+        with open(state_file_path, 'r') as xml_file:
38 88
             xml_to_check = xml_file.read()
39 89
 
40
-        xmlschema_doc = etree.parse(StringIO(schema_to_check))
90
+        xmlschema_doc = etree.fromstring(schema_to_check.encode('utf-8'))
41 91
         xmlschema = etree.XMLSchema(xmlschema_doc)
42 92
 
43 93
         try:
44
-            doc = etree.parse(StringIO(xml_to_check))
94
+            doc = etree.fromstring(xml_to_check.encode('utf-8'))
45 95
         # check for file IO error
46 96
         except IOError as exc:
47
-            self.logger.error(exc)
97
+            self._logger.error(exc)
48 98
             raise StateLoadError('Invalid File "{}": {}'.format(
49
-                self.state_file_path,
99
+                state_file_path,
50 100
                 str(exc),
51 101
             ))
52 102
         # check for XML syntax errors
53 103
         except etree.XMLSyntaxError as exc:
54
-            self.logger.error(exc)
104
+            self._logger.error(exc)
55 105
             raise StateLoadError('XML Syntax Error in "{}": {}'.format(
56
-                self.state_file_path,
106
+                state_file_path,
57 107
                 str(exc.error_log),
58 108
             ))
59 109
         except Exception as exc:
60
-            self.logger.error(exc)
110
+            self._logger.error(exc)
61 111
             raise StateLoadError('Unknown error with "{}": {}'.format(
62
-                self.state_file_path,
112
+                state_file_path,
63 113
                 str(exc),
64 114
             ))
65 115
 
@@ -67,44 +117,47 @@ class StateLoader(object):
67 117
         try:
68 118
             xmlschema.assertValid(doc)
69 119
         except etree.DocumentInvalid as exc:
70
-            self.logger.error(exc)
120
+            self._logger.error(exc)
71 121
             raise StateLoadError(
72 122
                 'Schema validation error with "{}": {}'.format(
73
-                    self.state_file_path,
123
+                    state_file_path,
74 124
                     str(exc),
75 125
                 )
76 126
             )
77 127
         except Exception as exc:
78
-            self.logger.error(exc)
128
+            self._logger.error(exc)
79 129
             raise StateLoadError(
80 130
                 'Unknown validation error with "{}": {}'.format(
81
-                    self.state_file_path,
131
+                    state_file_path,
82 132
                     str(exc),
83 133
                 )
84 134
             )
85 135
 
86
-    def get_subjects(self) -> typing.List[Subject]:
87
-        raise NotImplementedError('TODO')
136
+        return doc
88 137
 
89 138
 
90 139
 class StateLoaderBuilder(object):
91 140
     def __init__(
92 141
         self,
93 142
         config: Config,
143
+        simulation: TileStrategySimulation,
94 144
     ) -> None:
95
-        self.logger = get_logger('StateLoader', config)
96
-        self.config = config
145
+        self._logger = get_logger('StateLoader', config)
146
+        self._config = config
147
+        self._simulation = simulation
97 148
 
98 149
     def get_state_loader(
99 150
         self,
100
-        state_file_path: str,
101 151
     ) -> StateLoader:
102
-        class_address = self.config.get(
152
+        class_address = self._config.resolve(
103 153
             'global.state_loader',
104 154
             'opencombat.state.StateLoader',
105 155
         )
106
-        module_address = '.'.join(class_address.split('.')[:-1])
107
-        class_name = class_address.split('.')[-1]
108
-        module_ = importlib.import_module(module_address)
109
-        state_loader_class = getattr(module_, class_name)
110
-        return state_loader_class(self.config, state_file_path)
156
+        state_loader_class = get_class_from_string_path(
157
+            self._config,
158
+            class_address,
159
+        )
160
+        return state_loader_class(
161
+            self._config,
162
+            self._simulation,
163
+        )

+ 15 - 0
opencombat/util.py View File

@@ -0,0 +1,15 @@
1
+# coding: utf-8
2
+import importlib
3
+
4
+
5
+def get_class_from_string_path(config, string_path: str) -> type:
6
+    """
7
+    Return class matching with given path, eg "mymodule.MyClass"
8
+    :param config: config object
9
+    :param string_path: class path, eg "mymodule.MyClass"
10
+    :return: imported class
11
+    """
12
+    module_address = '.'.join(string_path.split('.')[:-1])
13
+    class_name = string_path.split('.')[-1]
14
+    module_ = importlib.import_module(module_address)
15
+    return getattr(module_, class_name)

+ 6 - 0
tests/fixtures/main.py View File

@@ -1,6 +1,7 @@
1 1
 # coding: utf-8
2 2
 import pytest
3 3
 from synergine2.config import Config
4
+from opencombat.simulation.base import TileStrategySimulation
4 5
 
5 6
 
6 7
 @pytest.fixture()
@@ -8,3 +9,8 @@ def config() -> Config:
8 9
     config_ = Config()
9 10
     config_.load_yaml('test_config.yaml')
10 11
     return config_
12
+
13
+
14
+@pytest.fixture
15
+def simulation(config) -> TileStrategySimulation:
16
+    return TileStrategySimulation(config, 'tests/fixtures/map_a/map_a.tmx')

BIN
tests/fixtures/map_a/background.png View File


BIN
tests/fixtures/map_a/interiors.png View File


+ 128 - 0
tests/fixtures/map_a/map_a.tmx View File

@@ -0,0 +1,128 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<map version="1.0" tiledversion="1.1.5" orientation="orthogonal" renderorder="right-down" width="25" height="25" tilewidth="8" tileheight="8" infinite="0" nextobjectid="1">
3
+ <tileset firstgid="1" source="../../../maps/shared/tilesets/trees.tsx"/>
4
+ <tileset firstgid="82" source="../../../maps/shared/tilesets/terrain.tsx"/>
5
+ <tileset firstgid="131" source="../../../maps/shared/tilesets/interiors.tsx"/>
6
+ <layer name="ground" width="25" height="25">
7
+  <data encoding="csv">
8
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
10
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
11
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
12
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
13
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
14
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
15
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
17
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
18
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
19
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
20
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
22
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
23
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
24
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
25
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
27
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
28
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
29
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
30
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
31
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
32
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
33
+</data>
34
+ </layer>
35
+ <layer name="interiors" width="25" height="25">
36
+  <data encoding="csv">
37
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
38
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
39
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
40
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
41
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
42
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
43
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
44
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
45
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
46
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
47
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
48
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
49
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
50
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
51
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
52
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
53
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
54
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
56
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
57
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
58
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
59
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
60
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
61
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
62
+</data>
63
+ </layer>
64
+ <layer name="terrain" width="25" height="25">
65
+  <data encoding="csv">
66
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
67
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
68
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
69
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
71
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
73
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
74
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
75
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
76
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
78
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
79
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
81
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
82
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
83
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
84
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
85
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
86
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
87
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
89
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
90
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
91
+</data>
92
+ </layer>
93
+ <layer name="top" width="25" height="25">
94
+  <data encoding="csv">
95
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
96
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
97
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
98
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
99
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
100
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
102
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
103
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
104
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
105
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
106
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
107
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
108
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
109
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
110
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
111
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
112
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
113
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
114
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
115
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
116
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
117
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
118
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
119
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
120
+</data>
121
+ </layer>
122
+ <imagelayer name="interior">
123
+  <image source="interiors.png" width="200" height="200"/>
124
+ </imagelayer>
125
+ <imagelayer name="background">
126
+  <image source="background.png" width="200" height="200"/>
127
+ </imagelayer>
128
+</map>

+ 1 - 0
tests/fixtures/state_empty.xml View File

@@ -0,0 +1 @@
1
+<?xml version="1.0" encoding="UTF-8"?>

+ 22 - 0
tests/fixtures/state_error_schema.xml View File

@@ -0,0 +1,22 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<state type="before_battle">
3
+    <map>
4
+        <name>001</name>
5
+    </map>
6
+    <subjects>
7
+        <subject>
8
+            <type>opencombat.simulation.subject.ManSubject</type>
9
+            <position>1,1</position>
10
+            <direction>90</direction>
11
+            <mode>standup</mode>
12
+            <side>URSS</side>
13
+        </subject>
14
+        <subjectFOO>
15
+            <type>opencombat.simulation.subject.ManSubject</type>
16
+            <position>10,10</position>
17
+            <direction>270</direction>
18
+            <mode>hiding</mode>
19
+            <side>DE</side>
20
+        </subjectFOO>
21
+    </subjects>
22
+</state>

+ 22 - 0
tests/fixtures/state_ok.xml View File

@@ -0,0 +1,22 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<state type="before_battle">
3
+    <map>
4
+        <name>001</name>
5
+    </map>
6
+    <subjects>
7
+        <subject>
8
+            <type>opencombat.simulation.subject.ManSubject</type>
9
+            <position>1,1</position>
10
+            <direction>90</direction>
11
+            <mode>standup</mode>
12
+            <side>URSS</side>
13
+        </subject>
14
+        <subject>
15
+            <type>opencombat.simulation.subject.ManSubject</type>
16
+            <position>10,10</position>
17
+            <direction>270</direction>
18
+            <mode>hiding</mode>
19
+            <side>DE</side>
20
+        </subject>
21
+    </subjects>
22
+</state>

+ 57 - 0
tests/test_state.py View File

@@ -0,0 +1,57 @@
1
+# coding: utf-8
2
+import pytest
3
+from synergine2.config import Config
4
+
5
+from opencombat.exception import StateLoadError
6
+from opencombat.state import StateLoaderBuilder, StateLoader
7
+
8
+
9
+class MyStateLoader(StateLoader):
10
+    pass
11
+
12
+
13
+@pytest.fixture
14
+def state_loader(config, simulation):
15
+    return StateLoader(config, simulation)
16
+
17
+
18
+def test_state_loader_builder__ok__nominal_case(
19
+    simulation,
20
+):
21
+    config = Config({
22
+        'global': {
23
+            'state_loader': 'tests.test_state.MyStateLoader',
24
+        }
25
+    })
26
+    builder = StateLoaderBuilder(config, simulation)
27
+    state_loader = builder.get_state_loader()
28
+    assert type(state_loader) == MyStateLoader
29
+
30
+
31
+def test_state_loader__ok__load_state(
32
+    state_loader,
33
+):
34
+    assert state_loader.get_state('tests/fixtures/state_ok.xml')
35
+
36
+
37
+def test_state_loader__error__state_empty(
38
+    state_loader,
39
+):
40
+    with pytest.raises(StateLoadError):
41
+        assert state_loader.get_state('tests/fixtures/state_empty.xml')
42
+
43
+
44
+def test_state_loader__error__state_invalid(
45
+    state_loader,
46
+):
47
+    with pytest.raises(StateLoadError):
48
+        assert state_loader.get_state(
49
+            'tests/fixtures/state_error_schema.xml',
50
+        )
51
+
52
+
53
+def test_state__ok__subjects(
54
+    state_loader,
55
+):
56
+    state = state_loader.get_state('tests/fixtures/state_ok.xml')
57
+    assert 2 == len(state.subjects)