1 /*
2 * *************************************************************************************************************************************************************
3 *
4 * SteelBlue: DCI User Interfaces
5 * http://tidalwave.it/projects/steelblue
6 *
7 * Copyright (C) 2015 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
8 *
9 * *************************************************************************************************************************************************************
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18 *
19 * *************************************************************************************************************************************************************
20 *
21 * git clone https://bitbucket.org/tidalwave/steelblue-src
22 * git clone https://github.com/tidalwave-it/steelblue-src
23 *
24 * *************************************************************************************************************************************************************
25 */
26 package it.tidalwave.ui.core.role.spi;
27
28 import javax.annotation.CheckForNull;
29 import jakarta.annotation.Nonnull;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.List;
33 import java.util.Optional;
34 import it.tidalwave.util.As;
35 import it.tidalwave.util.Id;
36 import it.tidalwave.util.RoleFactory;
37 import it.tidalwave.role.Identifiable;
38 import it.tidalwave.role.SimpleComposite;
39 import it.tidalwave.role.spi.SystemRoleFactory;
40 import it.tidalwave.ui.core.role.PresentationModel;
41 import lombok.Getter;
42 import lombok.RequiredArgsConstructor;
43 import lombok.extern.slf4j.Slf4j;
44 import org.testng.annotations.BeforeMethod;
45 import org.testng.annotations.Test;
46 import static java.util.Collections.emptyList;
47 import static it.tidalwave.util.Parameters.r;
48 import static it.tidalwave.ui.core.role.PresentationModel._SimpleCompositeOfPresentationModel_;
49 import static org.testng.Assert.*;
50 import static org.hamcrest.CoreMatchers.*;
51 import static org.hamcrest.MatcherAssert.assertThat;
52
53 /***************************************************************************************************************************************************************
54 *
55 * @author Fabrizio Giudici
56 *
57 **************************************************************************************************************************************************************/
58 @Slf4j
59 public class SimpleCompositePresentableTest
60 {
61 /***********************************************************************************************************************************************************
62 *
63 **********************************************************************************************************************************************************/
64 public static class MockDatum implements As, Identifiable
65 {
66 @Getter @Nonnull
67 private final Id id;
68
69 @CheckForNull
70 private SimpleComposite<MockDatum> composite;
71
72 @Getter
73 private List<MockDatum> children = new ArrayList<>();
74
75 public MockDatum (@Nonnull final String id)
76 {
77 this.id = new Id(id);
78 }
79
80 @Nonnull
81 public MockDatum withChildren (@Nonnull final MockDatum ... children)
82 {
83 return withChildren(List.of(children));
84 }
85
86 @Nonnull
87 public MockDatum withChildren (@Nonnull final List<MockDatum> children)
88 {
89 composite = SimpleComposite.ofCloned(this.children = children);
90 return this;
91 }
92
93 @Override @Nonnull
94 public <T> Optional<T> maybeAs (@Nonnull final Class<? extends T> roleType)
95 {
96 return roleType.equals(SimpleComposite.class) && (composite != null)
97 ? Optional.of(roleType.cast(composite))
98 : Optional.empty();
99 }
100
101 @Override @Nonnull
102 public <T> Collection<T> asMany (@Nonnull final Class<? extends T> roleType)
103 {
104 if (roleType.equals(SimpleComposite.class) && (composite != null))
105 {
106 return new ArrayList<>(List.of(roleType.cast(composite)));
107 }
108
109 return new ArrayList<>();
110 }
111
112 @Override @Nonnull
113 public String toString()
114 {
115 return String.format("MockDatum(%s)", id);
116 }
117 }
118
119 /***********************************************************************************************************************************************************
120 *
121 **********************************************************************************************************************************************************/
122 static class MockRole1
123 {
124 }
125
126 /***********************************************************************************************************************************************************
127 *
128 **********************************************************************************************************************************************************/
129 @Getter @RequiredArgsConstructor
130 static class MockRole2
131 {
132 @Nonnull
133 private final MockDatum datum;
134 }
135
136 /***********************************************************************************************************************************************************
137 *
138 **********************************************************************************************************************************************************/
139 static class MockRoleFactory implements RoleFactory<MockDatum, MockRole2>
140 {
141 @Override @Nonnull
142 public Optional<MockRole2> createRoleFor (@Nonnull final MockDatum datum)
143 {
144 return Optional.of(new MockRole2(datum));
145 }
146 }
147
148 /***********************************************************************************************************************************************************
149 *
150 **********************************************************************************************************************************************************/
151 @BeforeMethod
152 public void setup()
153 {
154 SystemRoleFactory.reset();
155 }
156
157 /***********************************************************************************************************************************************************
158 *
159 **********************************************************************************************************************************************************/
160 @Test
161 public void must_create_a_PresentationModel_containing_the_proper_children()
162 {
163 // given
164 final var c1 = new MockDatum("c1");
165 final var c2 = new MockDatum("c2");
166 final var c3 = new MockDatum("c3");
167
168 final var b1 = new MockDatum("b1").withChildren(c1, c2, c3);
169 final var b2 = new MockDatum("b2");
170 final var b3 = new MockDatum("b3");
171
172 final var a = new MockDatum("a").withChildren(b1, b2, b3);
173
174 final var underTest = new SimpleCompositePresentable(a, new DefaultPresentationModelFactory());
175 final var role1 = new MockRole1();
176 final var roleFactory = new MockRoleFactory();
177 // when
178 final var pm = underTest.createPresentationModel(r(role1, roleFactory));
179 // then
180 assertProperPresentationModel("", pm, a);
181 }
182
183 /***********************************************************************************************************************************************************
184 *
185 **********************************************************************************************************************************************************/
186 private void assertProperPresentationModel (@Nonnull final String indent,
187 @Nonnull final PresentationModel pm,
188 @Nonnull final MockDatum datum)
189 {
190 log.debug("assertProperPresentationModel() - {} {}, {}", indent, pm, datum);
191 pm.as(MockRole1.class); // must not throw AsException
192 final var role = pm.as(MockRole2.class); // must not throw AsException
193
194 assertThat(role.getDatum(), is(sameInstance(datum)));
195
196 final var childrenPm = pm.maybeAs(_SimpleCompositeOfPresentationModel_)
197 .map(c -> c.findChildren().results())
198 .orElse(emptyList());
199 final var notPMs = new ArrayList<>(childrenPm);
200 notPMs.removeIf(object -> object instanceof PresentationModel);
201
202 if (!notPMs.isEmpty())
203 {
204 fail("Unexpected objects that are not PresentationModel: " + notPMs);
205 }
206
207 final var childrenData = datum.getChildren();
208
209 assertThat(childrenPm.size(), is(childrenData.size()));
210
211 for (var i = 0; i < childrenPm.size(); i++)
212 {
213 assertProperPresentationModel(indent + " ", childrenPm.get(i), childrenData.get(i));
214 }
215 }
216 }