1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.core.metapath.item.node;
28
29 import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
30 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
31
32 import org.hamcrest.Description;
33 import org.jmock.Expectations;
34 import org.jmock.Mockery;
35 import org.jmock.api.Action;
36 import org.jmock.api.Invocation;
37
38 import java.net.URI;
39 import java.util.LinkedHashMap;
40 import java.util.LinkedList;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.UUID;
44 import java.util.concurrent.atomic.AtomicInteger;
45 import java.util.stream.Stream;
46
47 import edu.umd.cs.findbugs.annotations.NonNull;
48 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
49
50
51 @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT")
52 public class MockNodeItemFactory {
53
54 @NonNull
55 private final Mockery context;
56
57 @SuppressWarnings("exports")
58 public MockNodeItemFactory(@NonNull Mockery ctx) {
59 this.context = ctx;
60 }
61
62 protected Mockery getContext() {
63 return context;
64 }
65
66 @SuppressWarnings("null")
67 @NonNull
68 protected <T extends INodeItem> T newMock(@NonNull Class<T> clazz, @NonNull String name) {
69 String mockName = new StringBuilder()
70 .append(clazz.getSimpleName())
71 .append('-')
72 .append(name)
73 .append('-')
74 .append(UUID.randomUUID().toString())
75 .toString();
76 return getContext().mock(clazz, mockName);
77 }
78
79 public IDocumentNodeItem document(@NonNull URI documentURI, @NonNull String name,
80 @NonNull List<IFlagNodeItem> flags,
81 @NonNull List<IModelNodeItem<?, ?>> modelItems) {
82 IDocumentNodeItem document = newMock(IDocumentNodeItem.class, name);
83 IRootAssemblyNodeItem root = newMock(IRootAssemblyNodeItem.class, name);
84
85 getContext().checking(new Expectations() {
86 {
87 allowing(document).modelItems();
88 will(returnValue(Stream.of(root)));
89 allowing(document).getDocumentUri();
90 will(returnValue(documentURI));
91 allowing(document).getNodeItem();
92 will(returnValue(document));
93 allowing(document).getParentNodeItem();
94 will(returnValue(null));
95 allowing(document).ancestorOrSelf();
96 will(returnValue(Stream.of(document)));
97
98 allowing(root).getName();
99 will(returnValue(name));
100 allowing(root).getNodeItem();
101 will(returnValue(root));
102 allowing(root).getDocumentNodeItem();
103 will(returnValue(document));
104 }
105 });
106
107 handleChildren(document, CollectionUtil.emptyList(), CollectionUtil.singletonList(root));
108 handleChildren(root, flags, modelItems);
109
110 return document;
111 }
112
113 @SuppressWarnings("null")
114 protected <T extends INodeItem> void handleChildren(
115 @NonNull T item,
116 @NonNull List<IFlagNodeItem> flags,
117 @NonNull List<IModelNodeItem<?, ?>> modelItems) {
118 getContext().checking(new Expectations() {
119 {
120 allowing(item).getFlags();
121 will(returnValue(flags));
122 flags.forEach(flag -> {
123
124 allowing(item).getFlagByName(with(equal(flag.getName())));
125 will(returnValue(flag));
126
127 allowing(flag).getParentNodeItem();
128 will(returnValue(item));
129 });
130
131 Map<String, List<IModelNodeItem<?, ?>>> modelItemsMap = toModelItemsMap(modelItems);
132 allowing(item).getModelItems();
133 will(returnValue(modelItemsMap.values()));
134 modelItemsMap.entrySet().forEach(entry -> {
135 allowing(item).getModelItemsByName(with(equal(entry.getKey())));
136 will(returnValue(entry.getValue()));
137
138 AtomicInteger position = new AtomicInteger(1);
139 entry.getValue().forEach(modelItem -> {
140
141
142 allowing(modelItem).getParentNodeItem();
143 will(returnValue(item));
144
145
146 allowing(modelItem).getPosition();
147 will(returnValue(position.getAndIncrement()));
148 });
149 });
150
151 allowing(item).modelItems();
152 will(new Action() {
153
154 @Override
155 public void describeTo(Description description) {
156 description.appendText("returns stream");
157 }
158
159 @Override
160 public Object invoke(Invocation invocation) {
161 return modelItemsMap.values().stream()
162 .flatMap(children -> children.stream());
163 }
164 });
165 }
166 });
167 }
168
169 @SuppressWarnings("static-method")
170 @NonNull
171 private Map<String, List<IModelNodeItem<?, ?>>>
172 toModelItemsMap(@NonNull List<IModelNodeItem<?, ?>> modelItems) {
173
174 Map<String, List<IModelNodeItem<?, ?>>> retval = new LinkedHashMap<>();
175 for (IModelNodeItem<?, ?> item : modelItems) {
176 String name = item.getName();
177 List<IModelNodeItem<?, ?>> namedItems = retval.get(name);
178 if (namedItems == null) {
179 namedItems = new LinkedList<>();
180 retval.put(name, namedItems);
181 }
182 namedItems.add(item);
183 }
184 return CollectionUtil.unmodifiableMap(retval);
185 }
186
187 @NonNull
188 public IFlagNodeItem flag(@NonNull String name, @NonNull IAnyAtomicItem value) {
189 IFlagNodeItem retval = newMock(IFlagNodeItem.class, name);
190
191 getContext().checking(new Expectations() {
192 {
193 allowing(retval).getName();
194 will(returnValue(name));
195
196 allowing(retval).hasValue();
197 will(returnValue(true));
198
199 allowing(retval).toAtomicItem();
200 will(returnValue(value));
201
202 allowing(retval).getNodeItem();
203 will(returnValue(retval));
204 }
205 });
206
207 handleChildren(retval, CollectionUtil.emptyList(), CollectionUtil.emptyList());
208
209 return retval;
210 }
211
212 @NonNull
213 public IFieldNodeItem field(@NonNull String name, @NonNull IAnyAtomicItem value) {
214 return field(name, value, CollectionUtil.emptyList());
215 }
216
217 @NonNull
218 public IFieldNodeItem field(@NonNull String name, @NonNull IAnyAtomicItem value,
219 @NonNull List<IFlagNodeItem> flags) {
220 IFieldNodeItem retval = newMock(IFieldNodeItem.class, name);
221
222 getContext().checking(new Expectations() {
223 {
224 allowing(retval).getName();
225 will(returnValue(name));
226
227 allowing(retval).hasValue();
228 will(returnValue(true));
229
230 allowing(retval).toAtomicItem();
231 will(returnValue(value));
232
233 allowing(retval).getNodeItem();
234 will(returnValue(retval));
235 }
236 });
237
238 handleChildren(retval, flags, CollectionUtil.emptyList());
239 return retval;
240 }
241
242 @NonNull
243 public IAssemblyNodeItem assembly(@NonNull String name, @NonNull List<IFlagNodeItem> flags,
244 @NonNull List<IModelNodeItem<?, ?>> modelItems) {
245 IAssemblyNodeItem retval = newMock(IAssemblyNodeItem.class, name);
246
247 getContext().checking(new Expectations() {
248 {
249 allowing(retval).getName();
250 will(returnValue(name));
251
252 allowing(retval).getNodeItem();
253 will(returnValue(retval));
254 }
255 });
256
257 handleChildren(retval, flags, modelItems);
258
259 return retval;
260 }
261
262 }