Browse Source

Android: ContainerStack support in Layout-Factory

Amit Davidi 7 years ago
parent
commit
1774dfeb82

+ 1
- 1
android/app/build.gradle View File

63
     // required for robolectric
63
     // required for robolectric
64
     testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
64
     testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
65
 
65
 
66
-//    testCompile 'org.mockito:mockito-core:2.+'
66
+    testCompile 'org.mockito:mockito-core:2.+'
67
 }
67
 }

+ 4
- 9
android/app/src/main/AndroidManifest.xml View File

3
 
3
 
4
     <application>
4
     <application>
5
         <activity android:name=".controllers.NavigationActivity"/>
5
         <activity android:name=".controllers.NavigationActivity"/>
6
-        <!--<activity-->
7
-            <!--android:name=".controllers.PortraitNavigationActivity"-->
8
-            <!--android:screenOrientation="portrait" />-->
9
-        <!--<activity-->
10
-            <!--android:name=".controllers.LandscapeNavigationActivity"-->
11
-            <!--android:screenOrientation="landscape" />-->
12
-        <!--<activity-->
13
-            <!--android:name="com.facebook.react.devsupport.DevSettingsActivity"-->
14
-            <!--android:exported="false" />-->
6
+
7
+        <!--<activity
8
+            android:name="com.facebook.react.devsupport.DevSettingsActivity"
9
+            android:exported="false" />-->
15
     </application>
10
     </application>
16
 </manifest>
11
 </manifest>

+ 28
- 11
android/app/src/main/java/com/reactnativenavigation/layout/LayoutFactory.java View File

11
         View createRootView(String id, String name);
11
         View createRootView(String id, String name);
12
     }
12
     }
13
 
13
 
14
+    public static class LayoutNode {
15
+        public String id;
16
+        public String type;
17
+        public Map<String, Object> data;
18
+        public List<LayoutNode> children;
19
+
20
+        public LayoutNode() {
21
+        }
22
+
23
+        public LayoutNode(String id, String type, Map<String, Object> data) {
24
+            this.id = id;
25
+            this.type = type;
26
+            this.data = data;
27
+        }
28
+    }
29
+
14
     private Activity activity;
30
     private Activity activity;
15
     private RootViewCreator rootViewCreator;
31
     private RootViewCreator rootViewCreator;
16
 
32
 
19
         this.rootViewCreator = rootViewCreator;
35
         this.rootViewCreator = rootViewCreator;
20
     }
36
     }
21
 
37
 
22
-    public View create(Map<String, Object> node) {
23
-        String id = (String) node.get("id");
24
-        String type = (String) node.get("type");
25
-
26
-        switch (type) {
38
+    public View create(LayoutNode node) {
39
+        switch (node.type) {
27
             case "Container":
40
             case "Container":
28
-                String name = (String) ((Map<String, Object>)node.get("data")).get("name");
29
-                return new Container(activity, rootViewCreator, id, name);
41
+                String name = (String) node.data.get("name");
42
+                return new Container(activity, rootViewCreator, node.id, name);
30
 
43
 
31
             case "ContainerStack":
44
             case "ContainerStack":
32
                 ContainerStack containerStack = new ContainerStack(activity);
45
                 ContainerStack containerStack = new ContainerStack(activity);
33
-                List<Map<String, Object>> children = (List<Map<String, Object>>) node.get("children");
34
-                Map<String, Object> inner = children.get(0);
35
-                containerStack.addView(create(inner));
46
+                List<LayoutNode> children = node.children;
47
+                addChildrenNodes(containerStack, children);
36
                 return containerStack;
48
                 return containerStack;
37
-
38
         }
49
         }
39
 
50
 
40
         return null;
51
         return null;
41
 //        return rootViewCreator.createRootView(id, name);
52
 //        return rootViewCreator.createRootView(id, name);
42
     }
53
     }
54
+
55
+    private void addChildrenNodes(ContainerStack containerStack, List<LayoutNode> children) {
56
+        for (LayoutNode child : children) {
57
+            containerStack.addView(create(child));
58
+        }
59
+    }
43
 }
60
 }

+ 90
- 63
android/app/src/test/java/com/reactnativenavigation/LayoutFactoryTest.java View File

7
 import com.reactnativenavigation.layout.Container;
7
 import com.reactnativenavigation.layout.Container;
8
 import com.reactnativenavigation.layout.ContainerStack;
8
 import com.reactnativenavigation.layout.ContainerStack;
9
 import com.reactnativenavigation.layout.LayoutFactory;
9
 import com.reactnativenavigation.layout.LayoutFactory;
10
+import com.reactnativenavigation.layout.LayoutFactory.LayoutNode;
10
 
11
 
11
 import org.junit.Before;
12
 import org.junit.Before;
12
 import org.junit.Test;
13
 import org.junit.Test;
15
 import org.robolectric.RobolectricTestRunner;
16
 import org.robolectric.RobolectricTestRunner;
16
 
17
 
17
 import java.util.ArrayList;
18
 import java.util.ArrayList;
19
+import java.util.Arrays;
18
 import java.util.HashMap;
20
 import java.util.HashMap;
19
 import java.util.List;
21
 import java.util.List;
20
 import java.util.Map;
22
 import java.util.Map;
21
-import java.util.concurrent.atomic.AtomicReference;
22
 
23
 
23
 import static org.assertj.core.api.Java6Assertions.assertThat;
24
 import static org.assertj.core.api.Java6Assertions.assertThat;
25
+import static org.mockito.ArgumentMatchers.eq;
26
+import static org.mockito.Mockito.mock;
27
+import static org.mockito.Mockito.when;
24
 
28
 
25
 
29
 
26
 @RunWith(RobolectricTestRunner.class)
30
 @RunWith(RobolectricTestRunner.class)
27
 public class LayoutFactoryTest {
31
 public class LayoutFactoryTest {
32
+
33
+    private final static String VIEW_ID = "myUniqueId";
34
+    private final static String VIEW_NAME = "myName";
35
+
36
+    private final static String OTHER_VIEW_ID = "anotherUniqueId";
37
+    private final static String OTHER_VIEW_NAME = "anotherName";
38
+
39
+    private View mockView;
40
+    private LayoutFactory.RootViewCreator rootViewCreator;
41
+
28
     @Before
42
     @Before
29
     public void setUp() {
43
     public void setUp() {
30
-
44
+        mockView = new View(Robolectric.setupActivity(Activity.class));
45
+        rootViewCreator = mock(LayoutFactory.RootViewCreator.class);
31
     }
46
     }
32
 
47
 
33
     @Test
48
     @Test
34
     public void returnsContainerThatHoldsTheRootView() {
49
     public void returnsContainerThatHoldsTheRootView() {
35
-        final AtomicReference<String> idRef = new AtomicReference<>();
36
-        final AtomicReference<String> nameRef = new AtomicReference<>();
37
-        final AtomicReference<View> viewRef = new AtomicReference<>();
38
-
39
-        LayoutFactory.RootViewCreator rootViewCreator = new LayoutFactory.RootViewCreator() {
40
-            @Override
41
-            public View createRootView(String id, String name) {
42
-                idRef.set(id);
43
-                nameRef.set(name);
44
-                viewRef.set(new View(Robolectric.setupActivity(Activity.class)));
45
-                return viewRef.get();
46
-            }
47
-        };
48
-
49
-        Map<String, Object> node = new HashMap() {{
50
-            Map<String, Object> data = new HashMap<>();
51
-            data.put("name", "MyName");
52
-            put("id", "myUniqueId");
53
-            put("data", data);
54
-            put("type", "Container");
55
-        }};
56
-
57
-        ViewGroup result =
58
-                (ViewGroup) new LayoutFactory(Robolectric.buildActivity(Activity.class).get(), rootViewCreator).create(node);
50
+        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
51
+        final LayoutNode node = createContainerNode();
52
+
53
+        final ViewGroup result = (ViewGroup) createLayoutFactory().create(node);
54
+
59
         assertThat(result).isInstanceOf(Container.class);
55
         assertThat(result).isInstanceOf(Container.class);
60
-        assertThat(result.getChildCount()).isEqualTo(1);
61
-        assertThat(result.getChildAt(0)).isEqualTo(viewRef.get());
56
+        assertViewChildren(result, mockView);
62
     }
57
     }
63
 
58
 
64
-
65
     @Test
59
     @Test
66
     public void returnsContainerStack() {
60
     public void returnsContainerStack() {
67
-        final AtomicReference<String> idRef = new AtomicReference<>();
68
-        final AtomicReference<String> nameRef = new AtomicReference<>();
69
-        final AtomicReference<View> viewRef = new AtomicReference<>();
70
-
71
-        LayoutFactory.RootViewCreator rootViewCreator = new LayoutFactory.RootViewCreator() {
72
-            @Override
73
-            public View createRootView(String id, String name) {
74
-                idRef.set(id);
75
-                nameRef.set(name);
76
-                viewRef.set(new View(Robolectric.setupActivity(Activity.class)));
77
-                return viewRef.get();
78
-            }
79
-        };
80
-
81
-        Map<String, Object> node = new HashMap() {{
82
-            Map<String, Object> data = new HashMap<>();
83
-            data.put("name", "MyName");
84
-            put("id", "myUniqueId");
85
-            put("data", data);
86
-            put("type", "Container");
87
-        }};
88
-
89
-        HashMap<String, Object> outerNode = new HashMap<>();
90
-        outerNode.put("type", "ContainerStack");
91
-        List<Map<String, Object>> children = new ArrayList<>();
92
-        children.add(node);
93
-        outerNode.put("children", children);
94
-
95
-        ViewGroup result =
96
-                (ViewGroup) new LayoutFactory(Robolectric.buildActivity(Activity.class).get(), rootViewCreator).create(outerNode);
61
+        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
62
+        final LayoutNode node = createContainerNode();
63
+        final LayoutNode outerNode = getContainerStackNode(node);
64
+
65
+        final ViewGroup result = (ViewGroup) createLayoutFactory().create(outerNode);
66
+
67
+        assertThat(result).isInstanceOf(ContainerStack.class);
68
+        ViewGroup container = (ViewGroup) assertViewChildrenCount(result, 1).get(0);
69
+        assertViewChildren(container, mockView);
70
+    }
71
+
72
+    @Test
73
+    public void returnsContainerStackWithMultipleViews() {
74
+        final View mockView1 = mock(View.class);
75
+        final View mockView2 = mock(View.class);
76
+        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView1);
77
+        when(rootViewCreator.createRootView(eq(OTHER_VIEW_ID), eq(OTHER_VIEW_NAME))).thenReturn(mockView2);
78
+
79
+        final LayoutNode node1 = createContainerNode(VIEW_ID, VIEW_NAME);
80
+        final LayoutNode node2 = createContainerNode(OTHER_VIEW_ID, OTHER_VIEW_NAME);
81
+        final LayoutNode outerNode = getContainerStackNode(Arrays.asList(node1, node2));
82
+
83
+        final ViewGroup result = (ViewGroup) createLayoutFactory().create(outerNode);
84
+
97
         assertThat(result).isInstanceOf(ContainerStack.class);
85
         assertThat(result).isInstanceOf(ContainerStack.class);
98
-        assertThat(result.getChildCount()).isEqualTo(1);
99
-        ViewGroup container = (ViewGroup) result.getChildAt(0);
100
-        assertThat(container.getChildCount()).isEqualTo(1);
101
-        assertThat(container.getChildAt(0)).isEqualTo(viewRef.get());
86
+        List<View> containers = assertViewChildrenCount(result, 2);
87
+        ViewGroup container1 = (ViewGroup) containers.get(0);
88
+        ViewGroup container2 = (ViewGroup) containers.get(1);
89
+        assertViewChildren(container1, mockView1);
90
+        assertViewChildren(container2, mockView2);
91
+    }
92
+
93
+    private LayoutFactory createLayoutFactory() {
94
+        return new LayoutFactory(Robolectric.buildActivity(Activity.class).get(), rootViewCreator);
95
+    }
96
+
97
+    private LayoutNode getContainerStackNode(LayoutNode innerNode) {
98
+        return getContainerStackNode(Arrays.asList(innerNode));
99
+    }
100
+
101
+    private LayoutNode getContainerStackNode(List<LayoutNode> children) {
102
+        LayoutNode outerNode = new LayoutNode();
103
+        outerNode.type = "ContainerStack";
104
+        outerNode.children = children;
105
+        return outerNode;
106
+    }
107
+
108
+    private LayoutNode createContainerNode() {
109
+        return createContainerNode(VIEW_ID, VIEW_NAME);
110
+    }
111
+
112
+    private LayoutNode createContainerNode(final String id, final String name) {
113
+        return new LayoutNode(id, "Container", new HashMap<String, Object>() {{ put("name", name); }});
114
+    }
115
+
116
+    private List<View> assertViewChildrenCount(ViewGroup view, int count) {
117
+        assertThat(view.getChildCount()).isEqualTo(count);
118
+
119
+        final List<View> children = new ArrayList<>(count);
120
+        for (int i = 0; i < count; i++) {
121
+            children.add(view.getChildAt(i));
122
+        }
123
+        return children;
124
+    }
125
+
126
+    private void assertViewChildren(ViewGroup view, View... children) {
127
+        final List<View> childViews = assertViewChildrenCount(view, children.length);
128
+        assertThat(childViews).isEqualTo(Arrays.asList(children));
102
     }
129
     }
103
 }
130
 }