|  | @@ -1,6 +1,7 @@
 | 
	
		
			
			| 1 | 1 |  package com.reactnativenavigation;
 | 
	
		
			
			| 2 | 2 |  
 | 
	
		
			
			| 3 | 3 |  import android.app.Activity;
 | 
	
		
			
			|  | 4 | +import android.support.v7.app.AppCompatActivity;
 | 
	
		
			
			| 4 | 5 |  import android.view.View;
 | 
	
		
			
			| 5 | 6 |  import android.view.ViewGroup;
 | 
	
		
			
			| 6 | 7 |  
 | 
	
	
		
			
			|  | @@ -8,6 +9,9 @@ import com.reactnativenavigation.layout.Container;
 | 
	
		
			
			| 8 | 9 |  import com.reactnativenavigation.layout.ContainerStack;
 | 
	
		
			
			| 9 | 10 |  import com.reactnativenavigation.layout.LayoutFactory;
 | 
	
		
			
			| 10 | 11 |  import com.reactnativenavigation.layout.LayoutNode;
 | 
	
		
			
			|  | 12 | +import com.reactnativenavigation.layout.bottomtabs.BottomTabs;
 | 
	
		
			
			|  | 13 | +import com.reactnativenavigation.layout.bottomtabs.BottomTabsContainer;
 | 
	
		
			
			|  | 14 | +import com.reactnativenavigation.layout.bottomtabs.BottomTabsCreator;
 | 
	
		
			
			| 11 | 15 |  
 | 
	
		
			
			| 12 | 16 |  import org.junit.Before;
 | 
	
		
			
			| 13 | 17 |  import org.junit.Test;
 | 
	
	
		
			
			|  | @@ -15,17 +19,17 @@ import org.junit.runner.RunWith;
 | 
	
		
			
			| 15 | 19 |  import org.robolectric.Robolectric;
 | 
	
		
			
			| 16 | 20 |  import org.robolectric.RobolectricTestRunner;
 | 
	
		
			
			| 17 | 21 |  
 | 
	
		
			
			| 18 |  | -import java.util.ArrayList;
 | 
	
		
			
			| 19 | 22 |  import java.util.Arrays;
 | 
	
		
			
			|  | 23 | +import java.util.Collections;
 | 
	
		
			
			| 20 | 24 |  import java.util.HashMap;
 | 
	
		
			
			| 21 | 25 |  import java.util.List;
 | 
	
		
			
			| 22 | 26 |  
 | 
	
		
			
			| 23 | 27 |  import static org.assertj.core.api.Java6Assertions.assertThat;
 | 
	
		
			
			| 24 | 28 |  import static org.mockito.ArgumentMatchers.eq;
 | 
	
		
			
			| 25 | 29 |  import static org.mockito.Mockito.mock;
 | 
	
		
			
			|  | 30 | +import static org.mockito.Mockito.verify;
 | 
	
		
			
			| 26 | 31 |  import static org.mockito.Mockito.when;
 | 
	
		
			
			| 27 | 32 |  
 | 
	
		
			
			| 28 |  | -
 | 
	
		
			
			| 29 | 33 |  @RunWith(RobolectricTestRunner.class)
 | 
	
		
			
			| 30 | 34 |  public class LayoutFactoryTest {
 | 
	
		
			
			| 31 | 35 |  
 | 
	
	
		
			
			|  | @@ -35,95 +39,145 @@ public class LayoutFactoryTest {
 | 
	
		
			
			| 35 | 39 |      private final static String OTHER_VIEW_ID = "anotherUniqueId";
 | 
	
		
			
			| 36 | 40 |      private final static String OTHER_VIEW_NAME = "anotherName";
 | 
	
		
			
			| 37 | 41 |  
 | 
	
		
			
			|  | 42 | +    private Activity activity;
 | 
	
		
			
			| 38 | 43 |      private View mockView;
 | 
	
		
			
			|  | 44 | +    private View otherMockView;
 | 
	
		
			
			| 39 | 45 |      private LayoutFactory.RootViewCreator rootViewCreator;
 | 
	
		
			
			| 40 | 46 |  
 | 
	
		
			
			| 41 | 47 |      @Before
 | 
	
		
			
			| 42 | 48 |      public void setUp() {
 | 
	
		
			
			| 43 |  | -        mockView = new View(Robolectric.setupActivity(Activity.class));
 | 
	
		
			
			|  | 49 | +        activity = Robolectric.buildActivity(AppCompatActivity.class).get();
 | 
	
		
			
			|  | 50 | +        mockView = new View(activity);
 | 
	
		
			
			|  | 51 | +        otherMockView = new View(activity);
 | 
	
		
			
			| 44 | 52 |          rootViewCreator = mock(LayoutFactory.RootViewCreator.class);
 | 
	
		
			
			| 45 | 53 |      }
 | 
	
		
			
			| 46 | 54 |  
 | 
	
		
			
			| 47 | 55 |      @Test
 | 
	
		
			
			| 48 |  | -    public void returnsContainerThatHoldsTheRootView() {
 | 
	
		
			
			|  | 56 | +    public void returnsContainerThatHoldsTheRootView() throws Exception {
 | 
	
		
			
			| 49 | 57 |          when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
 | 
	
		
			
			| 50 | 58 |          final LayoutNode node = createContainerNode();
 | 
	
		
			
			| 51 | 59 |  
 | 
	
		
			
			| 52 | 60 |          final ViewGroup result = (ViewGroup) createLayoutFactory().create(node);
 | 
	
		
			
			| 53 | 61 |  
 | 
	
		
			
			| 54 | 62 |          assertThat(result).isInstanceOf(Container.class);
 | 
	
		
			
			| 55 |  | -        assertViewChildren(result, mockView);
 | 
	
		
			
			|  | 63 | +        TestUtils.assertViewChildren(result, mockView);
 | 
	
		
			
			| 56 | 64 |      }
 | 
	
		
			
			| 57 | 65 |  
 | 
	
		
			
			| 58 | 66 |      @Test
 | 
	
		
			
			| 59 |  | -    public void returnsContainerStack() {
 | 
	
		
			
			|  | 67 | +    public void returnsContainerStack() throws Exception {
 | 
	
		
			
			| 60 | 68 |          when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
 | 
	
		
			
			| 61 |  | -        final LayoutNode node = createContainerNode();
 | 
	
		
			
			| 62 |  | -        final LayoutNode outerNode = getContainerStackNode(node);
 | 
	
		
			
			|  | 69 | +        final LayoutNode containerNode = createContainerNode();
 | 
	
		
			
			|  | 70 | +        final LayoutNode stackNode = createContainerStackNode(containerNode);
 | 
	
		
			
			| 63 | 71 |  
 | 
	
		
			
			| 64 |  | -        final ViewGroup result = (ViewGroup) createLayoutFactory().create(outerNode);
 | 
	
		
			
			|  | 72 | +        final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
 | 
	
		
			
			| 65 | 73 |  
 | 
	
		
			
			| 66 | 74 |          assertThat(result).isInstanceOf(ContainerStack.class);
 | 
	
		
			
			| 67 |  | -        ViewGroup container = (ViewGroup) assertViewChildrenCount(result, 1).get(0);
 | 
	
		
			
			| 68 |  | -        assertViewChildren(container, mockView);
 | 
	
		
			
			|  | 75 | +        ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(result, 1).get(0);
 | 
	
		
			
			|  | 76 | +        TestUtils.assertViewChildren(container, mockView);
 | 
	
		
			
			| 69 | 77 |      }
 | 
	
		
			
			| 70 | 78 |  
 | 
	
		
			
			| 71 | 79 |      @Test
 | 
	
		
			
			| 72 |  | -    public void returnsContainerStackWithMultipleViews() {
 | 
	
		
			
			|  | 80 | +    public void returnsContainerStackWithMultipleViews() throws Exception {
 | 
	
		
			
			| 73 | 81 |          final View mockView1 = mock(View.class);
 | 
	
		
			
			| 74 | 82 |          final View mockView2 = mock(View.class);
 | 
	
		
			
			| 75 | 83 |          when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView1);
 | 
	
		
			
			| 76 | 84 |          when(rootViewCreator.createRootView(eq(OTHER_VIEW_ID), eq(OTHER_VIEW_NAME))).thenReturn(mockView2);
 | 
	
		
			
			| 77 | 85 |  
 | 
	
		
			
			| 78 |  | -        final LayoutNode node1 = createContainerNode(VIEW_ID, VIEW_NAME);
 | 
	
		
			
			| 79 |  | -        final LayoutNode node2 = createContainerNode(OTHER_VIEW_ID, OTHER_VIEW_NAME);
 | 
	
		
			
			| 80 |  | -        final LayoutNode outerNode = getContainerStackNode(Arrays.asList(node1, node2));
 | 
	
		
			
			|  | 86 | +        final LayoutNode containerNode1 = createContainerNode(VIEW_ID, VIEW_NAME);
 | 
	
		
			
			|  | 87 | +        final LayoutNode containerNode2 = createContainerNode(OTHER_VIEW_ID, OTHER_VIEW_NAME);
 | 
	
		
			
			|  | 88 | +        final LayoutNode stackNode = createContainerStackNode(containerNode1, containerNode2);
 | 
	
		
			
			| 81 | 89 |  
 | 
	
		
			
			| 82 |  | -        final ViewGroup result = (ViewGroup) createLayoutFactory().create(outerNode);
 | 
	
		
			
			|  | 90 | +        final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
 | 
	
		
			
			| 83 | 91 |  
 | 
	
		
			
			| 84 | 92 |          assertThat(result).isInstanceOf(ContainerStack.class);
 | 
	
		
			
			| 85 |  | -        List<View> containers = assertViewChildrenCount(result, 2);
 | 
	
		
			
			|  | 93 | +        List<View> containers = TestUtils.assertViewChildrenCount(result, 2);
 | 
	
		
			
			| 86 | 94 |          ViewGroup container1 = (ViewGroup) containers.get(0);
 | 
	
		
			
			| 87 | 95 |          ViewGroup container2 = (ViewGroup) containers.get(1);
 | 
	
		
			
			| 88 |  | -        assertViewChildren(container1, mockView1);
 | 
	
		
			
			| 89 |  | -        assertViewChildren(container2, mockView2);
 | 
	
		
			
			|  | 96 | +        TestUtils.assertViewChildren(container1, mockView1);
 | 
	
		
			
			|  | 97 | +        TestUtils.assertViewChildren(container2, mockView2);
 | 
	
		
			
			| 90 | 98 |      }
 | 
	
		
			
			| 91 | 99 |  
 | 
	
		
			
			| 92 |  | -    private LayoutFactory createLayoutFactory() {
 | 
	
		
			
			| 93 |  | -        return new LayoutFactory(Robolectric.buildActivity(Activity.class).get(), rootViewCreator);
 | 
	
		
			
			|  | 100 | +    @Test
 | 
	
		
			
			|  | 101 | +    public void returnsSingleTabContent() throws Exception {
 | 
	
		
			
			|  | 102 | +        BottomTabs bottomTabsMock = mock(BottomTabs.class);
 | 
	
		
			
			|  | 103 | +        when(bottomTabsMock.size()).thenReturn(0);
 | 
	
		
			
			|  | 104 | +
 | 
	
		
			
			|  | 105 | +        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
 | 
	
		
			
			|  | 106 | +        final LayoutNode containerNode = createContainerNode();
 | 
	
		
			
			|  | 107 | +        final LayoutNode tabNode = createTabNode(containerNode);
 | 
	
		
			
			|  | 108 | +
 | 
	
		
			
			|  | 109 | +        final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
 | 
	
		
			
			|  | 110 | +
 | 
	
		
			
			|  | 111 | +        verify(bottomTabsMock).add("#0");
 | 
	
		
			
			|  | 112 | +
 | 
	
		
			
			|  | 113 | +        assertThat(result).isInstanceOf(BottomTabsContainer.class);
 | 
	
		
			
			|  | 114 | +        Container container = (Container) TestUtils.assertViewChildrenCount((BottomTabsContainer) result, 1).get(0);
 | 
	
		
			
			|  | 115 | +        View view = TestUtils.assertViewChildrenCount(container, 1).get(0);
 | 
	
		
			
			|  | 116 | +        assertThat(view).isEqualTo(mockView);
 | 
	
		
			
			| 94 | 117 |      }
 | 
	
		
			
			| 95 | 118 |  
 | 
	
		
			
			| 96 |  | -    private LayoutNode createContainerNode() {
 | 
	
		
			
			| 97 |  | -        return createContainerNode(VIEW_ID, VIEW_NAME);
 | 
	
		
			
			|  | 119 | +    @Test
 | 
	
		
			
			|  | 120 | +    public void returnsTwoTabContent() throws Exception {
 | 
	
		
			
			|  | 121 | +        BottomTabs bottomTabsMock = mock(BottomTabs.class);
 | 
	
		
			
			|  | 122 | +        when(bottomTabsMock.size()).thenReturn(0, 1);
 | 
	
		
			
			|  | 123 | +
 | 
	
		
			
			|  | 124 | +        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
 | 
	
		
			
			|  | 125 | +        final LayoutNode firstTabRootNode = createContainerNode(VIEW_ID, VIEW_NAME);
 | 
	
		
			
			|  | 126 | +
 | 
	
		
			
			|  | 127 | +        when(rootViewCreator.createRootView(eq(OTHER_VIEW_ID), eq(OTHER_VIEW_NAME))).thenReturn(otherMockView);
 | 
	
		
			
			|  | 128 | +        final LayoutNode secondTabRootNode = createContainerStackNode(createContainerNode(OTHER_VIEW_ID, OTHER_VIEW_NAME));
 | 
	
		
			
			|  | 129 | +
 | 
	
		
			
			|  | 130 | +        final LayoutNode tabNode = createTabNode(firstTabRootNode, secondTabRootNode);
 | 
	
		
			
			|  | 131 | +
 | 
	
		
			
			|  | 132 | +        final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
 | 
	
		
			
			|  | 133 | +
 | 
	
		
			
			|  | 134 | +        assertThat(result).isInstanceOf(BottomTabsContainer.class);
 | 
	
		
			
			|  | 135 | +        verify(bottomTabsMock).add(eq("#0"));
 | 
	
		
			
			|  | 136 | +        verify(bottomTabsMock).add(eq("#1"));
 | 
	
		
			
			| 98 | 137 |      }
 | 
	
		
			
			| 99 | 138 |  
 | 
	
		
			
			| 100 |  | -    private LayoutNode createContainerNode(final String id, final String name) {
 | 
	
		
			
			| 101 |  | -        return new LayoutNode(id, "Container", new HashMap<String, Object>() {{ put("name", name); }});
 | 
	
		
			
			|  | 139 | +
 | 
	
		
			
			|  | 140 | +    @Test(expected = IllegalArgumentException.class)
 | 
	
		
			
			|  | 141 | +    public void throwsExceptionForUnknownType() throws Exception {
 | 
	
		
			
			|  | 142 | +        when(rootViewCreator.createRootView(eq(VIEW_ID), eq(VIEW_NAME))).thenReturn(mockView);
 | 
	
		
			
			|  | 143 | +        final LayoutNode node = new LayoutNode(VIEW_ID, "***unknownType***", Collections.<String, Object>emptyMap());
 | 
	
		
			
			|  | 144 | +
 | 
	
		
			
			|  | 145 | +        createLayoutFactory().create(node);
 | 
	
		
			
			| 102 | 146 |      }
 | 
	
		
			
			| 103 | 147 |  
 | 
	
		
			
			| 104 |  | -    private LayoutNode getContainerStackNode(LayoutNode innerNode) {
 | 
	
		
			
			| 105 |  | -        return getContainerStackNode(Arrays.asList(innerNode));
 | 
	
		
			
			|  | 148 | +    private LayoutFactory createLayoutFactory() {
 | 
	
		
			
			|  | 149 | +        return createLayoutFactory(null);
 | 
	
		
			
			| 106 | 150 |      }
 | 
	
		
			
			| 107 | 151 |  
 | 
	
		
			
			| 108 |  | -    private LayoutNode getContainerStackNode(List<LayoutNode> children) {
 | 
	
		
			
			| 109 |  | -        LayoutNode outerNode = new LayoutNode();
 | 
	
		
			
			| 110 |  | -        outerNode.type = "ContainerStack";
 | 
	
		
			
			| 111 |  | -        outerNode.children = children;
 | 
	
		
			
			| 112 |  | -        return outerNode;
 | 
	
		
			
			|  | 152 | +    private LayoutFactory createLayoutFactory(BottomTabs bottomTabs) {
 | 
	
		
			
			|  | 153 | +        BottomTabsCreator bottomTabsCreator = null;
 | 
	
		
			
			|  | 154 | +        if (bottomTabs != null) {
 | 
	
		
			
			|  | 155 | +            bottomTabsCreator = mock(BottomTabsCreator.class);
 | 
	
		
			
			|  | 156 | +            when(bottomTabsCreator.create()).thenReturn(bottomTabs);
 | 
	
		
			
			|  | 157 | +        }
 | 
	
		
			
			|  | 158 | +
 | 
	
		
			
			|  | 159 | +        return new LayoutFactory(activity, rootViewCreator, bottomTabsCreator);
 | 
	
		
			
			| 113 | 160 |      }
 | 
	
		
			
			| 114 | 161 |  
 | 
	
		
			
			| 115 |  | -    private List<View> assertViewChildrenCount(ViewGroup view, int count) {
 | 
	
		
			
			| 116 |  | -        assertThat(view.getChildCount()).isEqualTo(count);
 | 
	
		
			
			|  | 162 | +    private LayoutNode createContainerNode() {
 | 
	
		
			
			|  | 163 | +        return createContainerNode(VIEW_ID, VIEW_NAME);
 | 
	
		
			
			|  | 164 | +    }
 | 
	
		
			
			| 117 | 165 |  
 | 
	
		
			
			| 118 |  | -        final List<View> children = new ArrayList<>(count);
 | 
	
		
			
			| 119 |  | -        for (int i = 0; i < count; i++) {
 | 
	
		
			
			| 120 |  | -            children.add(view.getChildAt(i));
 | 
	
		
			
			| 121 |  | -        }
 | 
	
		
			
			| 122 |  | -        return children;
 | 
	
		
			
			|  | 166 | +    private LayoutNode createContainerNode(final String id, final String name) {
 | 
	
		
			
			|  | 167 | +        return new LayoutNode(id, "Container", new HashMap<String, Object>() {{ put("name", name); }});
 | 
	
		
			
			|  | 168 | +    }
 | 
	
		
			
			|  | 169 | +
 | 
	
		
			
			|  | 170 | +    private LayoutNode createContainerStackNode(LayoutNode... children) {
 | 
	
		
			
			|  | 171 | +        LayoutNode node = new LayoutNode();
 | 
	
		
			
			|  | 172 | +        node.type = "ContainerStack";
 | 
	
		
			
			|  | 173 | +        node.children = Arrays.asList(children);
 | 
	
		
			
			|  | 174 | +        return node;
 | 
	
		
			
			| 123 | 175 |      }
 | 
	
		
			
			| 124 | 176 |  
 | 
	
		
			
			| 125 |  | -    private void assertViewChildren(ViewGroup view, View... children) {
 | 
	
		
			
			| 126 |  | -        final List<View> childViews = assertViewChildrenCount(view, children.length);
 | 
	
		
			
			| 127 |  | -        assertThat(childViews).isEqualTo(Arrays.asList(children));
 | 
	
		
			
			|  | 177 | +    private LayoutNode createTabNode(LayoutNode... children) {
 | 
	
		
			
			|  | 178 | +        LayoutNode node = new LayoutNode();
 | 
	
		
			
			|  | 179 | +        node.type = "BottomTabs";
 | 
	
		
			
			|  | 180 | +        node.children = Arrays.asList(children);
 | 
	
		
			
			|  | 181 | +        return node;
 | 
	
		
			
			| 128 | 182 |      }
 | 
	
		
			
			| 129 | 183 |  }
 |