View Javadoc
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   }