Daniel Zlotin преди 7 години
родител
ревизия
47140086ba
променени са 25 файла, в които са добавени 1000 реда и са изтрити 1000 реда
  1. 14
    14
      android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java
  2. 14
    14
      android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java
  3. 4
    4
      android/app/src/main/java/com/reactnativenavigation/layout/Container.java
  4. 23
    23
      android/app/src/main/java/com/reactnativenavigation/layout/ContainerStackLayout.java
  5. 1
    1
      android/app/src/main/java/com/reactnativenavigation/layout/Layout.java
  6. 94
    94
      android/app/src/main/java/com/reactnativenavigation/layout/LayoutFactory.java
  7. 15
    15
      android/app/src/main/java/com/reactnativenavigation/layout/LayoutNode.java
  8. 23
    23
      android/app/src/main/java/com/reactnativenavigation/layout/SideMenuLayout.java
  9. 2
    2
      android/app/src/main/java/com/reactnativenavigation/layout/StackLayout.java
  10. 39
    39
      android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabs.java
  11. 3
    3
      android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabsCreator.java
  12. 65
    65
      android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabsLayout.java
  13. 14
    14
      android/app/src/main/java/com/reactnativenavigation/react/NavigationEventEmitter.java
  14. 105
    105
      android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java
  15. 14
    14
      android/app/src/main/java/com/reactnativenavigation/react/NavigationPackage.java
  16. 14
    14
      android/app/src/main/java/com/reactnativenavigation/react/NavigationReactNativeHost.java
  17. 17
    17
      android/app/src/main/java/com/reactnativenavigation/react/ReactDevPermission.java
  18. 35
    35
      android/app/src/main/java/com/reactnativenavigation/utils/ReflectionUtils.java
  19. 7
    7
      android/app/src/main/java/com/reactnativenavigation/utils/UiThread.java
  20. 19
    19
      android/app/src/main/java/com/reactnativenavigation/utils/ViewIdGenerator.java
  21. 30
    30
      android/app/src/test/java/com/reactnativenavigation/EnvironmentTest.java
  22. 8
    8
      android/app/src/test/java/com/reactnativenavigation/NavigationActivityTest.java
  23. 114
    114
      android/app/src/test/java/com/reactnativenavigation/layout/BottomTabsContainerTest.java
  24. 314
    314
      android/app/src/test/java/com/reactnativenavigation/layout/LayoutFactoryTest.java
  25. 12
    12
      android/app/src/test/java/com/reactnativenavigation/layout/TestUtils.java

+ 14
- 14
android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java Целия файл

@@ -7,21 +7,21 @@ import android.view.View;
7 7
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
8 8
 
9 9
 public class NavigationActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
10
-    private View contentView;
10
+	private View contentView;
11 11
 
12
-    @Override
13
-    public void setContentView(View contentView) {
14
-        super.setContentView(contentView);
15
-        this.contentView = contentView;
16
-    }
12
+	@Override
13
+	public void setContentView(View contentView) {
14
+		super.setContentView(contentView);
15
+		this.contentView = contentView;
16
+	}
17 17
 
18
-    @Nullable
19
-    public View getContentView() {
20
-        return contentView;
21
-    }
18
+	@Nullable
19
+	public View getContentView() {
20
+		return contentView;
21
+	}
22 22
 
23
-    @Override
24
-    public void invokeDefaultOnBackPressed() {
25
-        onBackPressed();
26
-    }
23
+	@Override
24
+	public void invokeDefaultOnBackPressed() {
25
+		onBackPressed();
26
+	}
27 27
 }

+ 14
- 14
android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java Целия файл

@@ -8,21 +8,21 @@ import com.reactnativenavigation.controllers.NavigationActivityLifecycleHandler;
8 8
 import com.reactnativenavigation.react.NavigationReactNativeHost;
9 9
 
10 10
 public abstract class NavigationApplication extends Application implements ReactApplication {
11
-    public static NavigationApplication instance;
12
-    private ReactNativeHost host;
11
+	public static NavigationApplication instance;
12
+	private ReactNativeHost host;
13 13
 
14
-    @Override
15
-    public void onCreate() {
16
-        super.onCreate();
17
-        instance = this;
18
-        host = new NavigationReactNativeHost(this);
19
-        registerActivityLifecycleCallbacks(new NavigationActivityLifecycleHandler(host.getReactInstanceManager()));
20
-    }
14
+	@Override
15
+	public void onCreate() {
16
+		super.onCreate();
17
+		instance = this;
18
+		host = new NavigationReactNativeHost(this);
19
+		registerActivityLifecycleCallbacks(new NavigationActivityLifecycleHandler(host.getReactInstanceManager()));
20
+	}
21 21
 
22
-    @Override
23
-    public ReactNativeHost getReactNativeHost() {
24
-        return host;
25
-    }
22
+	@Override
23
+	public ReactNativeHost getReactNativeHost() {
24
+		return host;
25
+	}
26 26
 
27
-    public abstract boolean isDebug();
27
+	public abstract boolean isDebug();
28 28
 }

+ 4
- 4
android/app/src/main/java/com/reactnativenavigation/layout/Container.java Целия файл

@@ -4,8 +4,8 @@ import android.content.Context;
4 4
 import android.widget.FrameLayout;
5 5
 
6 6
 public class Container extends FrameLayout {
7
-    public Container(Context context, LayoutFactory.ReactRootViewCreator reactRootViewCreator, String id, String name) {
8
-        super(context);
9
-        addView(reactRootViewCreator.create(id, name));
10
-    }
7
+	public Container(Context context, LayoutFactory.ReactRootViewCreator reactRootViewCreator, String id, String name) {
8
+		super(context);
9
+		addView(reactRootViewCreator.create(id, name));
10
+	}
11 11
 }

+ 23
- 23
android/app/src/main/java/com/reactnativenavigation/layout/ContainerStackLayout.java Целия файл

@@ -8,27 +8,27 @@ import java.util.Stack;
8 8
 
9 9
 public class ContainerStackLayout extends FrameLayout implements StackLayout {
10 10
 
11
-    private Stack<View> backStack = new Stack<>();
12
-
13
-    public ContainerStackLayout(Context context) {
14
-        super(context);
15
-    }
16
-
17
-    @Override
18
-    public void push(View view) {
19
-        addView(view);
20
-        backStack.push(getChildAt(0));
21
-        removeView(getChildAt(0));
22
-    }
23
-
24
-    @Override
25
-    public void pop() {
26
-        addView(backStack.pop());
27
-        removeView(getChildAt(0));
28
-    }
29
-
30
-    @Override
31
-    public View asView() {
32
-        return this;
33
-    }
11
+	private Stack<View> backStack = new Stack<>();
12
+
13
+	public ContainerStackLayout(Context context) {
14
+		super(context);
15
+	}
16
+
17
+	@Override
18
+	public void push(View view) {
19
+		addView(view);
20
+		backStack.push(getChildAt(0));
21
+		removeView(getChildAt(0));
22
+	}
23
+
24
+	@Override
25
+	public void pop() {
26
+		addView(backStack.pop());
27
+		removeView(getChildAt(0));
28
+	}
29
+
30
+	@Override
31
+	public View asView() {
32
+		return this;
33
+	}
34 34
 }

+ 1
- 1
android/app/src/main/java/com/reactnativenavigation/layout/Layout.java Целия файл

@@ -3,5 +3,5 @@ package com.reactnativenavigation.layout;
3 3
 import android.view.View;
4 4
 
5 5
 public interface Layout {
6
-    public View asView();
6
+	public View asView();
7 7
 }

+ 94
- 94
android/app/src/main/java/com/reactnativenavigation/layout/LayoutFactory.java Целия файл

@@ -14,98 +14,98 @@ import java.util.List;
14 14
 
15 15
 public class LayoutFactory {
16 16
 
17
-    public interface ReactRootViewCreator {
18
-        View create(String id, String name);
19
-    }
20
-
21
-    private final Activity activity;
22
-    private final ReactRootViewCreator reactRootViewCreator;
23
-    private final BottomTabsCreator bottomTabsCreator; // TODO: revisit this, may not be needed
24
-
25
-    public LayoutFactory(Activity activity, ReactRootViewCreator reactRootViewCreator, BottomTabsCreator bottomTabsCreator) {
26
-        this.activity = activity;
27
-        this.reactRootViewCreator = reactRootViewCreator;
28
-        this.bottomTabsCreator = bottomTabsCreator;
29
-    }
30
-
31
-    public View create(LayoutNode node) {
32
-        switch (node.type) {
33
-            case "Container":
34
-                return createContainerView(node);
35
-            case "ContainerStack":
36
-                return createContainerStackView(node);
37
-            case "BottomTabs":
38
-                return createBottomTabs(node);
39
-            case "SideMenuRoot":
40
-                return createSideMenuRoot(node);
41
-            case "SideMenuCenter":
42
-                return createSideMenuContent(node);
43
-            case "SideMenuLeft":
44
-                return createSideMenuLeft(node);
45
-            case "SideMenuRight":
46
-                return createSideMenuRight(node);
47
-            default:
48
-                throw new IllegalArgumentException("Invalid node type: "+node.type);
49
-        }
50
-    }
51
-
52
-    private View createSideMenuRoot(LayoutNode node) {
53
-        SideMenuLayout sideMenuLayout = new SideMenuLayout(activity);
54
-        for (LayoutNode child : node.children) {
55
-            sideMenuLayout.addView(create(child));
56
-        }
57
-        return sideMenuLayout;
58
-    }
59
-
60
-    private View createSideMenuContent(LayoutNode node) {
61
-        return create(node.children.get(0));
62
-    }
63
-
64
-    private View createSideMenuLeft(LayoutNode node) {
65
-        View view = create(node.children.get(0));
66
-        view.setId(ViewIdGenerator.generate());
67
-        DrawerLayout.LayoutParams lp = new DrawerLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
68
-        lp.gravity = Gravity.LEFT;
69
-        view.setLayoutParams(lp);
70
-        return view;
71
-    }
72
-
73
-    private View createSideMenuRight(LayoutNode node) {
74
-        View view = create(node.children.get(0));
75
-        view.setId(ViewIdGenerator.generate());
76
-        DrawerLayout.LayoutParams lp = new DrawerLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
77
-        lp.gravity = Gravity.RIGHT;
78
-        view.setLayoutParams(lp);
79
-        return view;
80
-    }
81
-
82
-    private View createContainerView(LayoutNode node) {
83
-        final String name = (String) node.data.get("name");
84
-        Container container = new Container(activity, reactRootViewCreator, node.id, name);
85
-        container.setId(ViewIdGenerator.generate());
86
-        return container;
87
-
88
-    }
89
-
90
-    private View createContainerStackView(LayoutNode node) {
91
-        final ContainerStackLayout containerStack = new ContainerStackLayout(activity);
92
-        containerStack.setId(ViewIdGenerator.generate());
93
-        addChildrenNodes(containerStack, node.children);
94
-        return containerStack;
95
-    }
96
-
97
-    private View createBottomTabs(LayoutNode node) {
98
-        final BottomTabsLayout tabsContainer = new BottomTabsLayout(activity, bottomTabsCreator.create());
99
-        for (int i = 0; i < node.children.size(); i++) {
100
-            final View tabContent = create(node.children.get(i));
101
-            tabsContainer.addTabContent("#" + i, tabContent);
102
-        }
103
-        return tabsContainer;
104
-    }
105
-
106
-    private void addChildrenNodes(ContainerStackLayout containerStack, List<LayoutNode> children) {
107
-        for (LayoutNode child : children) {
108
-            containerStack.addView(create(child));
109
-        }
110
-    }
17
+	public interface ReactRootViewCreator {
18
+		View create(String id, String name);
19
+	}
20
+
21
+	private final Activity activity;
22
+	private final ReactRootViewCreator reactRootViewCreator;
23
+	private final BottomTabsCreator bottomTabsCreator; // TODO: revisit this, may not be needed
24
+
25
+	public LayoutFactory(Activity activity, ReactRootViewCreator reactRootViewCreator, BottomTabsCreator bottomTabsCreator) {
26
+		this.activity = activity;
27
+		this.reactRootViewCreator = reactRootViewCreator;
28
+		this.bottomTabsCreator = bottomTabsCreator;
29
+	}
30
+
31
+	public View create(LayoutNode node) {
32
+		switch (node.type) {
33
+			case "Container":
34
+				return createContainerView(node);
35
+			case "ContainerStack":
36
+				return createContainerStackView(node);
37
+			case "BottomTabs":
38
+				return createBottomTabs(node);
39
+			case "SideMenuRoot":
40
+				return createSideMenuRoot(node);
41
+			case "SideMenuCenter":
42
+				return createSideMenuContent(node);
43
+			case "SideMenuLeft":
44
+				return createSideMenuLeft(node);
45
+			case "SideMenuRight":
46
+				return createSideMenuRight(node);
47
+			default:
48
+				throw new IllegalArgumentException("Invalid node type: " + node.type);
49
+		}
50
+	}
51
+
52
+	private View createSideMenuRoot(LayoutNode node) {
53
+		SideMenuLayout sideMenuLayout = new SideMenuLayout(activity);
54
+		for (LayoutNode child : node.children) {
55
+			sideMenuLayout.addView(create(child));
56
+		}
57
+		return sideMenuLayout;
58
+	}
59
+
60
+	private View createSideMenuContent(LayoutNode node) {
61
+		return create(node.children.get(0));
62
+	}
63
+
64
+	private View createSideMenuLeft(LayoutNode node) {
65
+		View view = create(node.children.get(0));
66
+		view.setId(ViewIdGenerator.generate());
67
+		DrawerLayout.LayoutParams lp = new DrawerLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
68
+		lp.gravity = Gravity.LEFT;
69
+		view.setLayoutParams(lp);
70
+		return view;
71
+	}
72
+
73
+	private View createSideMenuRight(LayoutNode node) {
74
+		View view = create(node.children.get(0));
75
+		view.setId(ViewIdGenerator.generate());
76
+		DrawerLayout.LayoutParams lp = new DrawerLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
77
+		lp.gravity = Gravity.RIGHT;
78
+		view.setLayoutParams(lp);
79
+		return view;
80
+	}
81
+
82
+	private View createContainerView(LayoutNode node) {
83
+		final String name = (String) node.data.get("name");
84
+		Container container = new Container(activity, reactRootViewCreator, node.id, name);
85
+		container.setId(ViewIdGenerator.generate());
86
+		return container;
87
+
88
+	}
89
+
90
+	private View createContainerStackView(LayoutNode node) {
91
+		final ContainerStackLayout containerStack = new ContainerStackLayout(activity);
92
+		containerStack.setId(ViewIdGenerator.generate());
93
+		addChildrenNodes(containerStack, node.children);
94
+		return containerStack;
95
+	}
96
+
97
+	private View createBottomTabs(LayoutNode node) {
98
+		final BottomTabsLayout tabsContainer = new BottomTabsLayout(activity, bottomTabsCreator.create());
99
+		for (int i = 0; i < node.children.size(); i++) {
100
+			final View tabContent = create(node.children.get(i));
101
+			tabsContainer.addTabContent("#" + i, tabContent);
102
+		}
103
+		return tabsContainer;
104
+	}
105
+
106
+	private void addChildrenNodes(ContainerStackLayout containerStack, List<LayoutNode> children) {
107
+		for (LayoutNode child : children) {
108
+			containerStack.addView(create(child));
109
+		}
110
+	}
111 111
 }

+ 15
- 15
android/app/src/main/java/com/reactnativenavigation/layout/LayoutNode.java Целия файл

@@ -4,22 +4,22 @@ import java.util.List;
4 4
 import java.util.Map;
5 5
 
6 6
 public class LayoutNode {
7
-    public String id;
8
-    public String type;
9
-    public Map<String, Object> data;
10
-    public List<LayoutNode> children;
7
+	public String id;
8
+	public String type;
9
+	public Map<String, Object> data;
10
+	public List<LayoutNode> children;
11 11
 
12
-    public LayoutNode() {
13
-    }
12
+	public LayoutNode() {
13
+	}
14 14
 
15
-    public LayoutNode(String type, List<LayoutNode> children) {
16
-        this.type = type;
17
-        this.children = children;
18
-    }
15
+	public LayoutNode(String type, List<LayoutNode> children) {
16
+		this.type = type;
17
+		this.children = children;
18
+	}
19 19
 
20
-    public LayoutNode(String id, String type, Map<String, Object> data) {
21
-        this.id = id;
22
-        this.type = type;
23
-        this.data = data;
24
-    }
20
+	public LayoutNode(String id, String type, Map<String, Object> data) {
21
+		this.id = id;
22
+		this.type = type;
23
+		this.data = data;
24
+	}
25 25
 }

+ 23
- 23
android/app/src/main/java/com/reactnativenavigation/layout/SideMenuLayout.java Целия файл

@@ -5,32 +5,32 @@ import android.support.v4.widget.DrawerLayout;
5 5
 import android.view.View;
6 6
 
7 7
 public class SideMenuLayout extends DrawerLayout implements StackLayout {
8
-    private StackLayout stackLayout;
8
+	private StackLayout stackLayout;
9 9
 
10
-    public SideMenuLayout(Context context) {
11
-        super(context);
12
-    }
10
+	public SideMenuLayout(Context context) {
11
+		super(context);
12
+	}
13 13
 
14
-    @Override
15
-    public void addView(View child) {
16
-        super.addView(child);
17
-        if (child instanceof StackLayout) {
18
-            stackLayout = (StackLayout) child;
19
-        }
20
-    }
14
+	@Override
15
+	public void addView(View child) {
16
+		super.addView(child);
17
+		if (child instanceof StackLayout) {
18
+			stackLayout = (StackLayout) child;
19
+		}
20
+	}
21 21
 
22
-    @Override
23
-    public void push(View view) {
24
-        stackLayout.push(view);
25
-    }
22
+	@Override
23
+	public void push(View view) {
24
+		stackLayout.push(view);
25
+	}
26 26
 
27
-    @Override
28
-    public void pop() {
29
-        stackLayout.pop();
30
-    }
27
+	@Override
28
+	public void pop() {
29
+		stackLayout.pop();
30
+	}
31 31
 
32
-    @Override
33
-    public View asView() {
34
-        return this;
35
-    }
32
+	@Override
33
+	public View asView() {
34
+		return this;
35
+	}
36 36
 }

+ 2
- 2
android/app/src/main/java/com/reactnativenavigation/layout/StackLayout.java Целия файл

@@ -3,7 +3,7 @@ package com.reactnativenavigation.layout;
3 3
 import android.view.View;
4 4
 
5 5
 public interface StackLayout extends Layout {
6
-    public void push(View view);
6
+	public void push(View view);
7 7
 
8
-    public void pop();
8
+	public void pop();
9 9
 }

+ 39
- 39
android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabs.java Целия файл

@@ -13,52 +13,52 @@ import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM;
13 13
 
14 14
 public class BottomTabs implements BottomNavigationView.OnNavigationItemSelectedListener {
15 15
 
16
-    interface BottomTabsSelectionListener {
17
-        void onTabSelected(int index);
18
-    }
16
+	interface BottomTabsSelectionListener {
17
+		void onTabSelected(int index);
18
+	}
19 19
 
20
-    private BottomNavigationView bottomNavigationView;
21
-    private BottomTabsSelectionListener listener;
20
+	private BottomNavigationView bottomNavigationView;
21
+	private BottomTabsSelectionListener listener;
22 22
 
23
-    public void attach(RelativeLayout parentLayout) {
24
-        createBottomNavigation(parentLayout);
25
-        addBottomNavigationToParent(parentLayout);
26
-    }
23
+	public void attach(RelativeLayout parentLayout) {
24
+		createBottomNavigation(parentLayout);
25
+		addBottomNavigationToParent(parentLayout);
26
+	}
27 27
 
28
-    public void setSelectionListener(BottomTabsSelectionListener listener) {
29
-        this.listener = listener;
30
-    }
28
+	public void setSelectionListener(BottomTabsSelectionListener listener) {
29
+		this.listener = listener;
30
+	}
31 31
 
32
-    public void add(String label) {
33
-        int tabId = size();
34
-        bottomNavigationView.getMenu().add(0, tabId, Menu.NONE, label);
35
-    }
32
+	public void add(String label) {
33
+		int tabId = size();
34
+		bottomNavigationView.getMenu().add(0, tabId, Menu.NONE, label);
35
+	}
36 36
 
37
-    public int size() {
38
-        return bottomNavigationView.getMenu().size();
39
-    }
37
+	public int size() {
38
+		return bottomNavigationView.getMenu().size();
39
+	}
40 40
 
41
-    int getViewId() {
42
-        return bottomNavigationView.getId();
43
-    }
41
+	int getViewId() {
42
+		return bottomNavigationView.getId();
43
+	}
44 44
 
45
-    @Override
46
-    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
47
-        listener.onTabSelected(item.getItemId());
48
-        return true;
49
-    }
45
+	@Override
46
+	public boolean onNavigationItemSelected(@NonNull MenuItem item) {
47
+		listener.onTabSelected(item.getItemId());
48
+		return true;
49
+	}
50 50
 
51
-    private void createBottomNavigation(RelativeLayout parentLayout) {
52
-        bottomNavigationView = new BottomNavigationView(parentLayout.getContext());
53
-        bottomNavigationView.setId(generateViewId());
54
-        bottomNavigationView.setBackgroundColor(Color.DKGRAY);
55
-        bottomNavigationView.setOnNavigationItemSelectedListener(this);
56
-    }
51
+	private void createBottomNavigation(RelativeLayout parentLayout) {
52
+		bottomNavigationView = new BottomNavigationView(parentLayout.getContext());
53
+		bottomNavigationView.setId(generateViewId());
54
+		bottomNavigationView.setBackgroundColor(Color.DKGRAY);
55
+		bottomNavigationView.setOnNavigationItemSelectedListener(this);
56
+	}
57 57
 
58
-    private void addBottomNavigationToParent(RelativeLayout parentLayout) {
59
-        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
60
-        lp.addRule(ALIGN_PARENT_BOTTOM);
61
-        bottomNavigationView.setLayoutParams(lp);
62
-        parentLayout.addView(bottomNavigationView, lp);
63
-    }
58
+	private void addBottomNavigationToParent(RelativeLayout parentLayout) {
59
+		LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
60
+		lp.addRule(ALIGN_PARENT_BOTTOM);
61
+		bottomNavigationView.setLayoutParams(lp);
62
+		parentLayout.addView(bottomNavigationView, lp);
63
+	}
64 64
 }

+ 3
- 3
android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabsCreator.java Целия файл

@@ -2,7 +2,7 @@ package com.reactnativenavigation.layout.bottomtabs;
2 2
 
3 3
 public class BottomTabsCreator {
4 4
 
5
-    public BottomTabs create() {
6
-        return new BottomTabs();
7
-    }
5
+	public BottomTabs create() {
6
+		return new BottomTabs();
7
+	}
8 8
 }

+ 65
- 65
android/app/src/main/java/com/reactnativenavigation/layout/bottomtabs/BottomTabsLayout.java Целия файл

@@ -11,69 +11,69 @@ import java.util.List;
11 11
 
12 12
 public class BottomTabsLayout extends RelativeLayout implements BottomTabs.BottomTabsSelectionListener, StackLayout {
13 13
 
14
-    private List<StackLayout> tabsContent;
15
-    private BottomTabs bottomTabs;
16
-    private int currentTab;
17
-
18
-    public BottomTabsLayout(Activity activity, BottomTabs bottomTabs) {
19
-        super(activity);
20
-        initBottomTabs(bottomTabs);
21
-    }
22
-
23
-    public void addTabContent(String label, View tabContent) {
24
-        if (tabsContent.size() == 5) {
25
-            throw new TooManyTabsException();
26
-        }
27
-        bottomTabs.add(label);
28
-        attachTabContent(tabContent);
29
-        tabsContent.add((StackLayout) tabContent);
30
-
31
-        if (tabsContent.size() > 1) {
32
-            tabContent.setVisibility(View.GONE);
33
-        }
34
-    }
35
-
36
-    @Override
37
-    public void onTabSelected(int index) {
38
-        hideTab(currentTab);
39
-        currentTab = index;
40
-        showTab(currentTab);
41
-    }
42
-
43
-    private void initBottomTabs(BottomTabs bottomTabs) {
44
-        this.bottomTabs = bottomTabs;
45
-        this.bottomTabs.attach(this);
46
-        this.bottomTabs.setSelectionListener(this);
47
-
48
-        tabsContent = new ArrayList<>();
49
-    }
50
-
51
-    private void attachTabContent(View tabContent) {
52
-        LayoutParams tabParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
53
-        tabParams.addRule(ABOVE, bottomTabs.getViewId());
54
-        addView(tabContent, tabParams);
55
-    }
56
-
57
-    private void showTab(int tabId) {
58
-        tabsContent.get(tabId).asView().setVisibility(View.VISIBLE);
59
-    }
60
-
61
-    private void hideTab(int tabId) {
62
-        tabsContent.get(tabId).asView().setVisibility(View.GONE);
63
-    }
64
-
65
-    @Override
66
-    public void push(View view) {
67
-        tabsContent.get(currentTab).push(view);
68
-    }
69
-
70
-    @Override
71
-    public void pop() {
72
-        tabsContent.get(currentTab).pop();
73
-    }
74
-
75
-    @Override
76
-    public View asView() {
77
-        return this;
78
-    }
14
+	private List<StackLayout> tabsContent;
15
+	private BottomTabs bottomTabs;
16
+	private int currentTab;
17
+
18
+	public BottomTabsLayout(Activity activity, BottomTabs bottomTabs) {
19
+		super(activity);
20
+		initBottomTabs(bottomTabs);
21
+	}
22
+
23
+	public void addTabContent(String label, View tabContent) {
24
+		if (tabsContent.size() == 5) {
25
+			throw new TooManyTabsException();
26
+		}
27
+		bottomTabs.add(label);
28
+		attachTabContent(tabContent);
29
+		tabsContent.add((StackLayout) tabContent);
30
+
31
+		if (tabsContent.size() > 1) {
32
+			tabContent.setVisibility(View.GONE);
33
+		}
34
+	}
35
+
36
+	@Override
37
+	public void onTabSelected(int index) {
38
+		hideTab(currentTab);
39
+		currentTab = index;
40
+		showTab(currentTab);
41
+	}
42
+
43
+	private void initBottomTabs(BottomTabs bottomTabs) {
44
+		this.bottomTabs = bottomTabs;
45
+		this.bottomTabs.attach(this);
46
+		this.bottomTabs.setSelectionListener(this);
47
+
48
+		tabsContent = new ArrayList<>();
49
+	}
50
+
51
+	private void attachTabContent(View tabContent) {
52
+		LayoutParams tabParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
53
+		tabParams.addRule(ABOVE, bottomTabs.getViewId());
54
+		addView(tabContent, tabParams);
55
+	}
56
+
57
+	private void showTab(int tabId) {
58
+		tabsContent.get(tabId).asView().setVisibility(View.VISIBLE);
59
+	}
60
+
61
+	private void hideTab(int tabId) {
62
+		tabsContent.get(tabId).asView().setVisibility(View.GONE);
63
+	}
64
+
65
+	@Override
66
+	public void push(View view) {
67
+		tabsContent.get(currentTab).push(view);
68
+	}
69
+
70
+	@Override
71
+	public void pop() {
72
+		tabsContent.get(currentTab).pop();
73
+	}
74
+
75
+	@Override
76
+	public View asView() {
77
+		return this;
78
+	}
79 79
 }

+ 14
- 14
android/app/src/main/java/com/reactnativenavigation/react/NavigationEventEmitter.java Целия файл

@@ -8,22 +8,22 @@ import static com.facebook.react.modules.core.DeviceEventManagerModule.RCTDevice
8 8
 
9 9
 public class NavigationEventEmitter {
10 10
 
11
-    public static NavigationEventEmitter emit(ReactContext context) {
12
-        return new NavigationEventEmitter(context);
13
-    }
11
+	public static NavigationEventEmitter emit(ReactContext context) {
12
+		return new NavigationEventEmitter(context);
13
+	}
14 14
 
15
-    private final RCTDeviceEventEmitter emitter;
15
+	private final RCTDeviceEventEmitter emitter;
16 16
 
17
-    private NavigationEventEmitter(ReactContext reactContext) {
18
-        this.emitter = reactContext.getJSModule(RCTDeviceEventEmitter.class);
19
-    }
17
+	private NavigationEventEmitter(ReactContext reactContext) {
18
+		this.emitter = reactContext.getJSModule(RCTDeviceEventEmitter.class);
19
+	}
20 20
 
21
-    public void appLaunched() {
22
-        emit("RNN.appLaunched");
23
-    }
21
+	public void appLaunched() {
22
+		emit("RNN.appLaunched");
23
+	}
24 24
 
25
-    private void emit(String eventName) {
26
-        WritableMap data = Arguments.createMap();
27
-        emitter.emit(eventName, data);
28
-    }
25
+	private void emit(String eventName) {
26
+		WritableMap data = Arguments.createMap();
27
+		emitter.emit(eventName, data);
28
+	}
29 29
 }

+ 105
- 105
android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java Целия файл

@@ -23,109 +23,109 @@ import java.util.HashMap;
23 23
 import java.util.Map;
24 24
 
25 25
 public class NavigationModule extends ReactContextBaseJavaModule {
26
-    private static final String NAME = "RNNBridgeModule";
27
-
28
-    public NavigationModule(ReactApplicationContext reactContext) {
29
-        super(reactContext);
30
-    }
31
-
32
-    @Override
33
-    public String getName() {
34
-        return NAME;
35
-    }
36
-
37
-    @ReactMethod
38
-    public void setRoot(final ReadableMap layoutTree) {
39
-        if (getCurrentActivity() == null) return;
40
-
41
-        UiThread.post(new Runnable() {
42
-            @Override
43
-            public void run() {
44
-                LayoutFactory factory =
45
-                        new LayoutFactory(getCurrentActivity(), new LayoutFactory.ReactRootViewCreator() {
46
-                            @Override
47
-                            public View create(String id, String name) {
48
-                                ReactRootView rootView = new ReactRootView(getCurrentActivity());
49
-                                Bundle opts = new Bundle();
50
-                                opts.putString("id", id);
51
-                                rootView.startReactApplication(NavigationApplication.instance.getReactNativeHost().getReactInstanceManager(), name, opts);
52
-                                return rootView;
53
-                            }
54
-                        }, new BottomTabsCreator());
55
-
56
-                final LayoutNode layoutTreeRoot = readableMapToLayoutNode(layoutTree);
57
-                final View rootView = factory.create(layoutTreeRoot);
58
-                getCurrentActivity().setContentView(rootView);
59
-            }
60
-        });
61
-    }
62
-
63
-    @ReactMethod
64
-    public void push(String onContainerId, final ReadableMap layout) {
65
-        if (getCurrentActivity() == null) return;
66
-
67
-        UiThread.post(new Runnable() {
68
-            @Override
69
-            public void run() {
70
-                LayoutFactory factory =
71
-                        new LayoutFactory(getCurrentActivity(), new LayoutFactory.ReactRootViewCreator() {
72
-                            @Override
73
-                            public View create(String id, String name) {
74
-                                ReactRootView rootView = new ReactRootView(getCurrentActivity());
75
-                                Bundle opts = new Bundle();
76
-                                opts.putString("id", id);
77
-                                rootView.startReactApplication(NavigationApplication.instance.getReactNativeHost().getReactInstanceManager(), name, opts);
78
-                                return rootView;
79
-                            }
80
-                        }, new BottomTabsCreator());
81
-                final LayoutNode layoutNode = readableMapToLayoutNode(layout);
82
-                final View rootView = factory.create(layoutNode);
83
-                ((StackLayout) ((NavigationActivity) getCurrentActivity()).getContentView()).push(rootView);
84
-            }
85
-        });
86
-    }
87
-
88
-    @ReactMethod
89
-    public void pop(String onContainerId) {
90
-        if (getCurrentActivity() == null) return;
91
-
92
-        UiThread.post(new Runnable() {
93
-            @Override
94
-            public void run() {
95
-                ((StackLayout) ((NavigationActivity) getCurrentActivity()).getContentView()).pop();
96
-            }
97
-        });
98
-    }
99
-
100
-    private LayoutNode readableMapToLayoutNode(ReadableMap readableMap) {
101
-        final LayoutNode layoutNode = new LayoutNode();
102
-        layoutNode.id = readableMap.getString("id");
103
-        layoutNode.type = readableMap.getString("type");
104
-        layoutNode.data = readableMapToJavaMap(readableMap.getMap("data"));
105
-
106
-        ReadableArray childrenNodes = readableMap.getArray("children");
107
-        layoutNode.children = new ArrayList<>(childrenNodes.size());
108
-        for (int i = 0; i < childrenNodes.size(); i++) {
109
-            ReadableMap child = childrenNodes.getMap(i);
110
-            layoutNode.children.add(readableMapToLayoutNode(child));
111
-        }
112
-
113
-        return layoutNode;
114
-    }
115
-
116
-    private Map<String, Object> readableMapToJavaMap(ReadableMap readableMap) {
117
-        final Map<String, Object> map = new HashMap<>();
118
-        for (ReadableMapKeySetIterator it = readableMap.keySetIterator(); it.hasNextKey(); ) {
119
-            final String key = it.nextKey();
120
-            switch (readableMap.getType(key)) {
121
-                case String:
122
-                    map.put(key, readableMap.getString(key));
123
-                    break;
124
-                case Map:
125
-                    map.put(key, readableMapToJavaMap(readableMap.getMap(key)));
126
-                    break;
127
-            }
128
-        }
129
-        return map;
130
-    }
26
+	private static final String NAME = "RNNBridgeModule";
27
+
28
+	public NavigationModule(ReactApplicationContext reactContext) {
29
+		super(reactContext);
30
+	}
31
+
32
+	@Override
33
+	public String getName() {
34
+		return NAME;
35
+	}
36
+
37
+	@ReactMethod
38
+	public void setRoot(final ReadableMap layoutTree) {
39
+		if (getCurrentActivity() == null) return;
40
+
41
+		UiThread.post(new Runnable() {
42
+			@Override
43
+			public void run() {
44
+				LayoutFactory factory =
45
+						new LayoutFactory(getCurrentActivity(), new LayoutFactory.ReactRootViewCreator() {
46
+							@Override
47
+							public View create(String id, String name) {
48
+								ReactRootView rootView = new ReactRootView(getCurrentActivity());
49
+								Bundle opts = new Bundle();
50
+								opts.putString("id", id);
51
+								rootView.startReactApplication(NavigationApplication.instance.getReactNativeHost().getReactInstanceManager(), name, opts);
52
+								return rootView;
53
+							}
54
+						}, new BottomTabsCreator());
55
+
56
+				final LayoutNode layoutTreeRoot = readableMapToLayoutNode(layoutTree);
57
+				final View rootView = factory.create(layoutTreeRoot);
58
+				getCurrentActivity().setContentView(rootView);
59
+			}
60
+		});
61
+	}
62
+
63
+	@ReactMethod
64
+	public void push(String onContainerId, final ReadableMap layout) {
65
+		if (getCurrentActivity() == null) return;
66
+
67
+		UiThread.post(new Runnable() {
68
+			@Override
69
+			public void run() {
70
+				LayoutFactory factory =
71
+						new LayoutFactory(getCurrentActivity(), new LayoutFactory.ReactRootViewCreator() {
72
+							@Override
73
+							public View create(String id, String name) {
74
+								ReactRootView rootView = new ReactRootView(getCurrentActivity());
75
+								Bundle opts = new Bundle();
76
+								opts.putString("id", id);
77
+								rootView.startReactApplication(NavigationApplication.instance.getReactNativeHost().getReactInstanceManager(), name, opts);
78
+								return rootView;
79
+							}
80
+						}, new BottomTabsCreator());
81
+				final LayoutNode layoutNode = readableMapToLayoutNode(layout);
82
+				final View rootView = factory.create(layoutNode);
83
+				((StackLayout) ((NavigationActivity) getCurrentActivity()).getContentView()).push(rootView);
84
+			}
85
+		});
86
+	}
87
+
88
+	@ReactMethod
89
+	public void pop(String onContainerId) {
90
+		if (getCurrentActivity() == null) return;
91
+
92
+		UiThread.post(new Runnable() {
93
+			@Override
94
+			public void run() {
95
+				((StackLayout) ((NavigationActivity) getCurrentActivity()).getContentView()).pop();
96
+			}
97
+		});
98
+	}
99
+
100
+	private LayoutNode readableMapToLayoutNode(ReadableMap readableMap) {
101
+		final LayoutNode layoutNode = new LayoutNode();
102
+		layoutNode.id = readableMap.getString("id");
103
+		layoutNode.type = readableMap.getString("type");
104
+		layoutNode.data = readableMapToJavaMap(readableMap.getMap("data"));
105
+
106
+		ReadableArray childrenNodes = readableMap.getArray("children");
107
+		layoutNode.children = new ArrayList<>(childrenNodes.size());
108
+		for (int i = 0; i < childrenNodes.size(); i++) {
109
+			ReadableMap child = childrenNodes.getMap(i);
110
+			layoutNode.children.add(readableMapToLayoutNode(child));
111
+		}
112
+
113
+		return layoutNode;
114
+	}
115
+
116
+	private Map<String, Object> readableMapToJavaMap(ReadableMap readableMap) {
117
+		final Map<String, Object> map = new HashMap<>();
118
+		for (ReadableMapKeySetIterator it = readableMap.keySetIterator(); it.hasNextKey(); ) {
119
+			final String key = it.nextKey();
120
+			switch (readableMap.getType(key)) {
121
+				case String:
122
+					map.put(key, readableMap.getString(key));
123
+					break;
124
+				case Map:
125
+					map.put(key, readableMapToJavaMap(readableMap.getMap(key)));
126
+					break;
127
+			}
128
+		}
129
+		return map;
130
+	}
131 131
 }

+ 14
- 14
android/app/src/main/java/com/reactnativenavigation/react/NavigationPackage.java Целия файл

@@ -12,20 +12,20 @@ import java.util.List;
12 12
 
13 13
 public class NavigationPackage implements ReactPackage {
14 14
 
15
-    @Override
16
-    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
17
-        return Arrays.<NativeModule>asList(
18
-                new NavigationModule(reactContext)
19
-        );
20
-    }
15
+	@Override
16
+	public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
17
+		return Arrays.<NativeModule>asList(
18
+				new NavigationModule(reactContext)
19
+		);
20
+	}
21 21
 
22
-    @Override
23
-    public List<Class<? extends JavaScriptModule>> createJSModules() {
24
-        return Collections.emptyList();
25
-    }
22
+	@Override
23
+	public List<Class<? extends JavaScriptModule>> createJSModules() {
24
+		return Collections.emptyList();
25
+	}
26 26
 
27
-    @Override
28
-    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
29
-        return Collections.emptyList();
30
-    }
27
+	@Override
28
+	public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
29
+		return Collections.emptyList();
30
+	}
31 31
 }

+ 14
- 14
android/app/src/main/java/com/reactnativenavigation/react/NavigationReactNativeHost.java Целия файл

@@ -9,20 +9,20 @@ import java.util.Arrays;
9 9
 import java.util.List;
10 10
 
11 11
 public class NavigationReactNativeHost extends ReactNativeHost {
12
-    public NavigationReactNativeHost(NavigationApplication application) {
13
-        super(application);
14
-    }
12
+	public NavigationReactNativeHost(NavigationApplication application) {
13
+		super(application);
14
+	}
15 15
 
16
-    @Override
17
-    public boolean getUseDeveloperSupport() {
18
-        return NavigationApplication.instance.isDebug();
19
-    }
16
+	@Override
17
+	public boolean getUseDeveloperSupport() {
18
+		return NavigationApplication.instance.isDebug();
19
+	}
20 20
 
21
-    @Override
22
-    protected List<ReactPackage> getPackages() {
23
-        return Arrays.asList(
24
-                new MainReactPackage(),
25
-                new NavigationPackage()
26
-        );
27
-    }
21
+	@Override
22
+	protected List<ReactPackage> getPackages() {
23
+		return Arrays.asList(
24
+				new MainReactPackage(),
25
+				new NavigationPackage()
26
+		);
27
+	}
28 28
 }

+ 17
- 17
android/app/src/main/java/com/reactnativenavigation/react/ReactDevPermission.java Целия файл

@@ -13,22 +13,22 @@ import com.reactnativenavigation.NavigationApplication;
13 13
 
14 14
 public class ReactDevPermission {
15 15
 
16
-    public static boolean shouldAskPermission() {
17
-        return NavigationApplication.instance.isDebug() &&
18
-                Build.VERSION.SDK_INT >= 23 &&
19
-                !Settings.canDrawOverlays(NavigationApplication.instance);
20
-    }
16
+	public static boolean shouldAskPermission() {
17
+		return NavigationApplication.instance.isDebug() &&
18
+				Build.VERSION.SDK_INT >= 23 &&
19
+				!Settings.canDrawOverlays(NavigationApplication.instance);
20
+	}
21 21
 
22
-    @TargetApi(23)
23
-    public static void askPermission(Context context) {
24
-        if (shouldAskPermission()) {
25
-            Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
26
-            context.startActivity(serviceIntent);
27
-            String msg = "Overlay permissions needs to be granted in order for react native apps to run in dev mode";
28
-            Log.w(ReactConstants.TAG, "======================================\n\n");
29
-            Log.w(ReactConstants.TAG, msg);
30
-            Log.w(ReactConstants.TAG, "\n\n======================================");
31
-            Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
32
-        }
33
-    }
22
+	@TargetApi(23)
23
+	public static void askPermission(Context context) {
24
+		if (shouldAskPermission()) {
25
+			Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
26
+			context.startActivity(serviceIntent);
27
+			String msg = "Overlay permissions needs to be granted in order for react native apps to run in dev mode";
28
+			Log.w(ReactConstants.TAG, "======================================\n\n");
29
+			Log.w(ReactConstants.TAG, msg);
30
+			Log.w(ReactConstants.TAG, "\n\n======================================");
31
+			Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
32
+		}
33
+	}
34 34
 }

+ 35
- 35
android/app/src/main/java/com/reactnativenavigation/utils/ReflectionUtils.java Целия файл

@@ -6,41 +6,41 @@ import java.lang.reflect.Field;
6 6
 
7 7
 public class ReflectionUtils {
8 8
 
9
-    public static void setField(Object obj, String name, Object value) {
10
-        try {
11
-            Field field = getField(obj.getClass(), name);
12
-            if (field == null) {
13
-                return;
14
-            }
15
-            field.setAccessible(true);
16
-            field.set(obj, value);
17
-        } catch (Exception e) {
18
-            e.printStackTrace();
19
-        }
20
-    }
9
+	public static void setField(Object obj, String name, Object value) {
10
+		try {
11
+			Field field = getField(obj.getClass(), name);
12
+			if (field == null) {
13
+				return;
14
+			}
15
+			field.setAccessible(true);
16
+			field.set(obj, value);
17
+		} catch (Exception e) {
18
+			e.printStackTrace();
19
+		}
20
+	}
21 21
 
22
-    @Nullable
23
-    public static Object getDeclaredField(Object obj, String fieldName) {
24
-        try {
25
-            Field f = getField(obj.getClass(), fieldName);
26
-            if (f == null) {
27
-                return null;
28
-            }
29
-            f.setAccessible(true);
30
-            return f.get(obj);
31
-        } catch (Exception e) {
32
-            e.printStackTrace();
33
-        }
34
-        return null;
35
-    }
22
+	@Nullable
23
+	public static Object getDeclaredField(Object obj, String fieldName) {
24
+		try {
25
+			Field f = getField(obj.getClass(), fieldName);
26
+			if (f == null) {
27
+				return null;
28
+			}
29
+			f.setAccessible(true);
30
+			return f.get(obj);
31
+		} catch (Exception e) {
32
+			e.printStackTrace();
33
+		}
34
+		return null;
35
+	}
36 36
 
37
-    private static Field getField(Class clazz, String name) {
38
-        try {
39
-            return clazz.getDeclaredField(name);
40
-        } catch (NoSuchFieldException nsfe) {
41
-            return getField(clazz.getSuperclass(), name);
42
-        } catch (Exception e) {
43
-            return null;
44
-        }
45
-    }
37
+	private static Field getField(Class clazz, String name) {
38
+		try {
39
+			return clazz.getDeclaredField(name);
40
+		} catch (NoSuchFieldException nsfe) {
41
+			return getField(clazz.getSuperclass(), name);
42
+		} catch (Exception e) {
43
+			return null;
44
+		}
45
+	}
46 46
 }

+ 7
- 7
android/app/src/main/java/com/reactnativenavigation/utils/UiThread.java Целия файл

@@ -4,13 +4,13 @@ import android.os.Handler;
4 4
 import android.os.Looper;
5 5
 
6 6
 public class UiThread {
7
-    private static final Handler handler = new Handler(Looper.getMainLooper());
7
+	private static final Handler handler = new Handler(Looper.getMainLooper());
8 8
 
9
-    public static void post(Runnable runnable) {
10
-        handler.post(runnable);
11
-    }
9
+	public static void post(Runnable runnable) {
10
+		handler.post(runnable);
11
+	}
12 12
 
13
-    public static void postDelayed(Runnable runnable, long millis) {
14
-        handler.postDelayed(runnable, millis);
15
-    }
13
+	public static void postDelayed(Runnable runnable, long millis) {
14
+		handler.postDelayed(runnable, millis);
15
+	}
16 16
 }

+ 19
- 19
android/app/src/main/java/com/reactnativenavigation/utils/ViewIdGenerator.java Целия файл

@@ -6,25 +6,25 @@ import android.view.View;
6 6
 import java.util.concurrent.atomic.AtomicInteger;
7 7
 
8 8
 public class ViewIdGenerator {
9
-    private static final AtomicInteger viewId = new AtomicInteger(1);
9
+	private static final AtomicInteger viewId = new AtomicInteger(1);
10 10
 
11
-    public static int generate() {
12
-        if (Build.VERSION.SDK_INT >= 17) {
13
-            return View.generateViewId();
14
-        } else {
15
-            return compatGenerateViewId();
16
-        }
17
-    }
11
+	public static int generate() {
12
+		if (Build.VERSION.SDK_INT >= 17) {
13
+			return View.generateViewId();
14
+		} else {
15
+			return compatGenerateViewId();
16
+		}
17
+	}
18 18
 
19
-    private static int compatGenerateViewId() {
20
-        while (true) {
21
-            final int result = viewId.get();
22
-            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
23
-            int newValue = result + 1;
24
-            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
25
-            if (viewId.compareAndSet(result, newValue)) {
26
-                return result;
27
-            }
28
-        }
29
-    }
19
+	private static int compatGenerateViewId() {
20
+		while (true) {
21
+			final int result = viewId.get();
22
+			// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
23
+			int newValue = result + 1;
24
+			if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
25
+			if (viewId.compareAndSet(result, newValue)) {
26
+				return result;
27
+			}
28
+		}
29
+	}
30 30
 }

+ 30
- 30
android/app/src/test/java/com/reactnativenavigation/EnvironmentTest.java Целия файл

@@ -12,34 +12,34 @@ import org.robolectric.RuntimeEnvironment;
12 12
 import static org.assertj.core.api.Java6Assertions.assertThat;
13 13
 
14 14
 public class EnvironmentTest extends BaseTest {
15
-    @Test
16
-    public void assertJ() {
17
-        assertThat(1 + 2).isEqualTo(3).isGreaterThan(2).isLessThan(4).isNotNegative().isPositive().isNotZero();
18
-    }
19
-
20
-    @Test
21
-    public void react() {
22
-        assertThat(ReactConstants.TAG).isNotEmpty();
23
-    }
24
-
25
-    @Test
26
-    public void supportV7AppCompat() {
27
-        assertThat(AppCompatActivity.class).isNotNull();
28
-    }
29
-
30
-    @Test
31
-    public void supportDesign() {
32
-        assertThat(FloatingActionButton.class).isNotNull();
33
-    }
34
-
35
-    @Test
36
-    public void androidR() {
37
-        assertThat(R.string.app_name).isNotZero();
38
-    }
39
-
40
-    @Test
41
-    public void ableToLoadApplication() throws Exception {
42
-        assertThat(RuntimeEnvironment.application).isNotNull();
43
-        assertThat(Robolectric.setupActivity(NavigationActivity.class)).isNotNull();
44
-    }
15
+	@Test
16
+	public void assertJ() {
17
+		assertThat(1 + 2).isEqualTo(3).isGreaterThan(2).isLessThan(4).isNotNegative().isPositive().isNotZero();
18
+	}
19
+
20
+	@Test
21
+	public void react() {
22
+		assertThat(ReactConstants.TAG).isNotEmpty();
23
+	}
24
+
25
+	@Test
26
+	public void supportV7AppCompat() {
27
+		assertThat(AppCompatActivity.class).isNotNull();
28
+	}
29
+
30
+	@Test
31
+	public void supportDesign() {
32
+		assertThat(FloatingActionButton.class).isNotNull();
33
+	}
34
+
35
+	@Test
36
+	public void androidR() {
37
+		assertThat(R.string.app_name).isNotZero();
38
+	}
39
+
40
+	@Test
41
+	public void ableToLoadApplication() throws Exception {
42
+		assertThat(RuntimeEnvironment.application).isNotNull();
43
+		assertThat(Robolectric.setupActivity(NavigationActivity.class)).isNotNull();
44
+	}
45 45
 }

+ 8
- 8
android/app/src/test/java/com/reactnativenavigation/NavigationActivityTest.java Целия файл

@@ -8,12 +8,12 @@ import org.robolectric.Robolectric;
8 8
 import static org.assertj.core.api.Java6Assertions.assertThat;
9 9
 
10 10
 public class NavigationActivityTest extends BaseTest {
11
-    @Test
12
-    public void holdsContentView() throws Exception {
13
-        NavigationActivity activity = Robolectric.setupActivity(NavigationActivity.class);
14
-        assertThat(activity.getContentView()).isNull();
15
-        View view = new View(activity);
16
-        activity.setContentView(view);
17
-        assertThat(activity.getContentView()).isSameAs(view);
18
-    }
11
+	@Test
12
+	public void holdsContentView() throws Exception {
13
+		NavigationActivity activity = Robolectric.setupActivity(NavigationActivity.class);
14
+		assertThat(activity.getContentView()).isNull();
15
+		View view = new View(activity);
16
+		activity.setContentView(view);
17
+		assertThat(activity.getContentView()).isSameAs(view);
18
+	}
19 19
 }

+ 114
- 114
android/app/src/test/java/com/reactnativenavigation/layout/BottomTabsContainerTest.java Целия файл

@@ -18,118 +18,118 @@ import static org.mockito.Mockito.verify;
18 18
 
19 19
 public class BottomTabsContainerTest extends BaseTest {
20 20
 
21
-    private static final String TAB_NAME = "myTab";
22
-    private static final String OTHER_TAB_NAME = "myOtherTab";
23
-
24
-    private BottomTabs bottomTabs;
25
-    private Activity activity;
26
-
27
-    @Before
28
-    public void setUp() throws Exception {
29
-        bottomTabs = mock(BottomTabs.class);
30
-        activity = Robolectric.buildActivity(Activity.class).get();
31
-    }
32
-
33
-    @Test
34
-    public void addsTabToBottomTabs() throws Exception {
35
-        ContainerStackLayout tabContent = new ContainerStackLayout(activity);
36
-
37
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
38
-        bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
39
-
40
-        verify(bottomTabs).add(TAB_NAME);
41
-    }
42
-
43
-    @Test
44
-    public void addsTabContentToLayout() throws Exception {
45
-        ContainerStackLayout stackLayout = new ContainerStackLayout(activity);
46
-
47
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
48
-        bottomTabsContainer.addTabContent(TAB_NAME, stackLayout);
49
-
50
-        verify(bottomTabs).attach(bottomTabsContainer);
51
-        TestUtils.assertViewChildren(bottomTabsContainer, stackLayout);
52
-    }
53
-
54
-    @Test
55
-    public void addsTwoTabsContentToLayout() throws Exception {
56
-        View tabContent = new ContainerStackLayout(activity);
57
-        View otherTabContent = new ContainerStackLayout(activity);
58
-
59
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
60
-        bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
61
-        bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
62
-
63
-        TestUtils.assertViewChildren(bottomTabsContainer, tabContent, otherTabContent);
64
-    }
65
-
66
-    @Test(expected = TooManyTabsException.class)
67
-    public void throwsExceptionWhenMoreThenFiveTabs() throws Exception {
68
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
69
-        for (int i = 0; i < 6; i++) {
70
-            ContainerStackLayout content = new ContainerStackLayout(activity);
71
-            bottomTabsContainer.addTabContent("#" + i, content);
72
-        }
73
-    }
74
-
75
-    @Test
76
-    public void addFiveTabs() throws Exception {
77
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
78
-        for (int i = 0; i < 5; i++) {
79
-            ContainerStackLayout content = new ContainerStackLayout(activity);
80
-            bottomTabsContainer.addTabContent("#" + i, content);
81
-        }
82
-    }
83
-
84
-    @Test
85
-    public void onlyFirstTabShouldBeVisible() throws Exception {
86
-        ContainerStackLayout tabContent = new ContainerStackLayout(activity);
87
-        ContainerStackLayout otherTabContent = new ContainerStackLayout(activity);
88
-
89
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
90
-        bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
91
-        bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
92
-
93
-        assertThat(tabContent.getVisibility()).isEqualTo(View.VISIBLE);
94
-        assertThat(otherTabContent.getVisibility()).isEqualTo(View.GONE);
95
-    }
96
-
97
-    @Test
98
-    public void listensToTabsSwitchingEvents() throws Exception {
99
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
100
-        verify(bottomTabs).setSelectionListener(bottomTabsContainer);
101
-    }
102
-
103
-    @Test
104
-    public void switchesBetweenFirstAndSecondTabs() throws Exception {
105
-        ContainerStackLayout tabContent = new ContainerStackLayout(activity);
106
-        ContainerStackLayout otherTabContent = new ContainerStackLayout(activity);
107
-
108
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
109
-        bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
110
-        bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
111
-        bottomTabsContainer.onTabSelected(1);
112
-
113
-        assertThat(tabContent.getVisibility()).isEqualTo(View.GONE);
114
-        assertThat(otherTabContent.getVisibility()).isEqualTo(View.VISIBLE);
115
-    }
116
-
117
-    @Test
118
-    public void switchesBetweenSecondAndFirstTabs() throws Exception {
119
-        ContainerStackLayout tabContent = new ContainerStackLayout(activity);
120
-        ContainerStackLayout otherTabContent = new ContainerStackLayout(activity);
121
-
122
-        BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
123
-        bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
124
-        bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
125
-        bottomTabsContainer.onTabSelected(1);
126
-        bottomTabsContainer.onTabSelected(0);
127
-
128
-        assertThat(tabContent.getVisibility()).isEqualTo(View.VISIBLE);
129
-        assertThat(otherTabContent.getVisibility()).isEqualTo(View.GONE);
130
-    }
131
-
132
-    private BottomTabsLayout createBottomTabsContainer() {
133
-        return new BottomTabsLayout(activity, bottomTabs);
134
-    }
21
+	private static final String TAB_NAME = "myTab";
22
+	private static final String OTHER_TAB_NAME = "myOtherTab";
23
+
24
+	private BottomTabs bottomTabs;
25
+	private Activity activity;
26
+
27
+	@Before
28
+	public void setUp() throws Exception {
29
+		bottomTabs = mock(BottomTabs.class);
30
+		activity = Robolectric.buildActivity(Activity.class).get();
31
+	}
32
+
33
+	@Test
34
+	public void addsTabToBottomTabs() throws Exception {
35
+		ContainerStackLayout tabContent = new ContainerStackLayout(activity);
36
+
37
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
38
+		bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
39
+
40
+		verify(bottomTabs).add(TAB_NAME);
41
+	}
42
+
43
+	@Test
44
+	public void addsTabContentToLayout() throws Exception {
45
+		ContainerStackLayout stackLayout = new ContainerStackLayout(activity);
46
+
47
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
48
+		bottomTabsContainer.addTabContent(TAB_NAME, stackLayout);
49
+
50
+		verify(bottomTabs).attach(bottomTabsContainer);
51
+		TestUtils.assertViewChildren(bottomTabsContainer, stackLayout);
52
+	}
53
+
54
+	@Test
55
+	public void addsTwoTabsContentToLayout() throws Exception {
56
+		View tabContent = new ContainerStackLayout(activity);
57
+		View otherTabContent = new ContainerStackLayout(activity);
58
+
59
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
60
+		bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
61
+		bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
62
+
63
+		TestUtils.assertViewChildren(bottomTabsContainer, tabContent, otherTabContent);
64
+	}
65
+
66
+	@Test(expected = TooManyTabsException.class)
67
+	public void throwsExceptionWhenMoreThenFiveTabs() throws Exception {
68
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
69
+		for (int i = 0; i < 6; i++) {
70
+			ContainerStackLayout content = new ContainerStackLayout(activity);
71
+			bottomTabsContainer.addTabContent("#" + i, content);
72
+		}
73
+	}
74
+
75
+	@Test
76
+	public void addFiveTabs() throws Exception {
77
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
78
+		for (int i = 0; i < 5; i++) {
79
+			ContainerStackLayout content = new ContainerStackLayout(activity);
80
+			bottomTabsContainer.addTabContent("#" + i, content);
81
+		}
82
+	}
83
+
84
+	@Test
85
+	public void onlyFirstTabShouldBeVisible() throws Exception {
86
+		ContainerStackLayout tabContent = new ContainerStackLayout(activity);
87
+		ContainerStackLayout otherTabContent = new ContainerStackLayout(activity);
88
+
89
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
90
+		bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
91
+		bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
92
+
93
+		assertThat(tabContent.getVisibility()).isEqualTo(View.VISIBLE);
94
+		assertThat(otherTabContent.getVisibility()).isEqualTo(View.GONE);
95
+	}
96
+
97
+	@Test
98
+	public void listensToTabsSwitchingEvents() throws Exception {
99
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
100
+		verify(bottomTabs).setSelectionListener(bottomTabsContainer);
101
+	}
102
+
103
+	@Test
104
+	public void switchesBetweenFirstAndSecondTabs() throws Exception {
105
+		ContainerStackLayout tabContent = new ContainerStackLayout(activity);
106
+		ContainerStackLayout otherTabContent = new ContainerStackLayout(activity);
107
+
108
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
109
+		bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
110
+		bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
111
+		bottomTabsContainer.onTabSelected(1);
112
+
113
+		assertThat(tabContent.getVisibility()).isEqualTo(View.GONE);
114
+		assertThat(otherTabContent.getVisibility()).isEqualTo(View.VISIBLE);
115
+	}
116
+
117
+	@Test
118
+	public void switchesBetweenSecondAndFirstTabs() throws Exception {
119
+		ContainerStackLayout tabContent = new ContainerStackLayout(activity);
120
+		ContainerStackLayout otherTabContent = new ContainerStackLayout(activity);
121
+
122
+		BottomTabsLayout bottomTabsContainer = createBottomTabsContainer();
123
+		bottomTabsContainer.addTabContent(TAB_NAME, tabContent);
124
+		bottomTabsContainer.addTabContent(OTHER_TAB_NAME, otherTabContent);
125
+		bottomTabsContainer.onTabSelected(1);
126
+		bottomTabsContainer.onTabSelected(0);
127
+
128
+		assertThat(tabContent.getVisibility()).isEqualTo(View.VISIBLE);
129
+		assertThat(otherTabContent.getVisibility()).isEqualTo(View.GONE);
130
+	}
131
+
132
+	private BottomTabsLayout createBottomTabsContainer() {
133
+		return new BottomTabsLayout(activity, bottomTabs);
134
+	}
135 135
 }

+ 314
- 314
android/app/src/test/java/com/reactnativenavigation/layout/LayoutFactoryTest.java Целия файл

@@ -27,318 +27,318 @@ import static org.mockito.Mockito.when;
27 27
 
28 28
 public class LayoutFactoryTest extends BaseTest {
29 29
 
30
-    private final static String NODE_ID = "myUniqueId";
31
-    private final static String REACT_ROOT_VIEW_KEY = "myName";
32
-
33
-    private final static String OTHER_NODE_ID = "anotherUniqueId";
34
-    private final static String OTHER_REACT_ROOT_VIEW_KEY = "anotherName";
35
-
36
-    private Activity activity;
37
-    private View mockView;
38
-    private View otherMockView;
39
-    private LayoutFactory.ReactRootViewCreator reactRootViewCreator;
40
-
41
-    @Before
42
-    public void setUp() {
43
-        activity = Robolectric.buildActivity(AppCompatActivity.class).get();
44
-        mockView = new View(activity);
45
-        otherMockView = new View(activity);
46
-        reactRootViewCreator = mock(LayoutFactory.ReactRootViewCreator.class);
47
-    }
48
-
49
-    @Test
50
-    public void returnsContainerThatHoldsTheRootView() throws Exception {
51
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
52
-        final LayoutNode node = createContainerNode();
53
-
54
-        final ViewGroup result = (ViewGroup) createLayoutFactory().create(node);
55
-
56
-        assertThat(result).isInstanceOf(Container.class);
57
-        TestUtils.assertViewChildren(result, mockView);
58
-    }
59
-
60
-    @Test
61
-    public void returnsContainerStack() throws Exception {
62
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
63
-        final LayoutNode containerNode = createContainerNode();
64
-        final LayoutNode stackNode = createContainerStackNode(containerNode);
65
-
66
-        final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
67
-
68
-        assertThat(result).isInstanceOf(ContainerStackLayout.class);
69
-        ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(result, 1).get(0);
70
-        TestUtils.assertViewChildren(container, mockView);
71
-    }
72
-
73
-    @Test
74
-    public void returnsContainerStackWithMultipleViews() throws Exception {
75
-        final View mockView1 = mock(View.class);
76
-        final View mockView2 = mock(View.class);
77
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView1);
78
-        when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(mockView2);
79
-
80
-        final LayoutNode containerNode1 = createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY);
81
-        final LayoutNode containerNode2 = createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY);
82
-        final LayoutNode stackNode = createContainerStackNode(containerNode1, containerNode2);
83
-
84
-        final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
85
-
86
-        assertThat(result).isInstanceOf(ContainerStackLayout.class);
87
-        List<View> containers = TestUtils.assertViewChildrenCount(result, 2);
88
-        ViewGroup container1 = (ViewGroup) containers.get(0);
89
-        ViewGroup container2 = (ViewGroup) containers.get(1);
90
-        TestUtils.assertViewChildren(container1, mockView1);
91
-        TestUtils.assertViewChildren(container2, mockView2);
92
-    }
93
-
94
-    @Test
95
-    public void returnsSideMenuRoot() throws Exception {
96
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
97
-        final LayoutNode containerNode = createSideMenuContainerNode(Arrays.asList(createContainerNode()));
98
-        final ViewGroup result = (ViewGroup) createLayoutFactory().create(containerNode);
99
-        assertThat(result).isInstanceOf(SideMenuLayout.class);
100
-    }
101
-
102
-    @Test
103
-    public void hasContentContainer() throws Exception {
104
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
105
-        LayoutNode contentContainer = createContainerNode();
106
-        final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(contentContainer));
107
-        final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
108
-        assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
109
-    }
110
-
111
-    @Test
112
-    public void hasLeftMenu() throws Exception {
113
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
114
-        LayoutNode sideMenuLeft = createSideMenuLeftNode();
115
-        final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(sideMenuLeft));
116
-        final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
117
-        assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
118
-    }
119
-
120
-    @Test
121
-    public void hasRightMenu() throws Exception {
122
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
123
-        LayoutNode sideMenuRight = createSideMenuRightNode();
124
-        final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(sideMenuRight));
125
-        final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
126
-        assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
127
-    }
128
-
129
-    @Test
130
-    public void returnsSingleTabContent() throws Exception {
131
-        BottomTabs bottomTabsMock = mock(BottomTabs.class);
132
-        when(bottomTabsMock.size()).thenReturn(0);
133
-
134
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
135
-        final LayoutNode containerNode = createContainerStackNode(createContainerNode());
136
-        final LayoutNode tabNode = createBottomTabNode(containerNode);
137
-
138
-        final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
139
-
140
-        verify(bottomTabsMock).add("#0");
141
-
142
-        assertThat(result).isInstanceOf(BottomTabsLayout.class);
143
-        ViewGroup containerStack = (ViewGroup) TestUtils.assertViewChildrenCount((BottomTabsLayout) result, 1).get(0);
144
-        Container container = (Container) TestUtils.assertViewChildrenCount(containerStack, 1).get(0);
145
-        View view = TestUtils.assertViewChildrenCount(container, 1).get(0);
146
-        assertThat(view).isEqualTo(mockView);
147
-    }
148
-
149
-    @Test
150
-    public void returnsTwoTabContent() throws Exception {
151
-        BottomTabs bottomTabsMock = mock(BottomTabs.class);
152
-        when(bottomTabsMock.size()).thenReturn(0, 1);
153
-
154
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
155
-        final LayoutNode firstTabRootNode = createContainerStackNode(createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY));
156
-
157
-        when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(otherMockView);
158
-        final LayoutNode secondTabRootNode = createContainerStackNode(createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY));
159
-
160
-        final LayoutNode tabNode = createBottomTabNode(firstTabRootNode, secondTabRootNode);
161
-
162
-        final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
163
-
164
-        assertThat(result).isInstanceOf(BottomTabsLayout.class);
165
-        verify(bottomTabsMock).add(eq("#0"));
166
-        verify(bottomTabsMock).add(eq("#1"));
167
-    }
168
-
169
-    @Test
170
-    public void pushScreenToFirstBottomTab() {
171
-        BottomTabs bottomTabsMock = mock(BottomTabs.class);
172
-        when(bottomTabsMock.size()).thenReturn(0, 1);
173
-
174
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
175
-        final LayoutNode firstTabContainerStack = createContainerStackNode(createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY));
176
-
177
-        final LayoutNode tabNode = createBottomTabNode(firstTabContainerStack);
178
-        final BottomTabsLayout bottomTabsContainer = (BottomTabsLayout) createLayoutFactory(bottomTabsMock).create(tabNode);
179
-        verify(bottomTabsMock).add(eq("#0"));
180
-
181
-        View pushedReactView = new View(activity);
182
-        when(reactRootViewCreator.create(eq("pushedReactViewId"), eq("pushedReactViewKey"))).thenReturn(pushedReactView);
183
-        View view = createLayoutFactory().create(createContainerNode("pushedReactViewId", "pushedReactViewKey"));
184
-        bottomTabsContainer.push(view);
185
-
186
-        ViewGroup containerStack = (ViewGroup) TestUtils.assertViewChildrenCount(bottomTabsContainer, 1).get(0);
187
-        ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(containerStack, 1).get(0);
188
-        View result = TestUtils.assertViewChildrenCount(container, 1).get(0);
189
-        assertThat(result).isEqualTo(pushedReactView);
190
-    }
191
-
192
-    @Test
193
-    public void popScreenFromFirstBottomTab() {
194
-        BottomTabs bottomTabsMock = mock(BottomTabs.class);
195
-        when(bottomTabsMock.size()).thenReturn(0, 1);
196
-
197
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
198
-        final LayoutNode firstTabContainerStack = createContainerStackNode(createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY));
199
-
200
-        final LayoutNode tabNode = createBottomTabNode(firstTabContainerStack);
201
-        final BottomTabsLayout bottomTabsContainer = (BottomTabsLayout) createLayoutFactory(bottomTabsMock).create(tabNode);
202
-        verify(bottomTabsMock).add(eq("#0"));
203
-
204
-        pushContainer(bottomTabsContainer, "pushedReactViewId", "pushedReactViewKey", new View(activity));
205
-
206
-        bottomTabsContainer.pop();
207
-
208
-        ViewGroup containerStack = (ViewGroup) TestUtils.assertViewChildrenCount(bottomTabsContainer, 1).get(0);
209
-        ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(containerStack, 1).get(0);
210
-        View result = TestUtils.assertViewChildrenCount(container, 1).get(0);
211
-        assertThat(result).isEqualTo(mockView);
212
-    }
213
-
214
-    @Test
215
-    public void pushScreenToScreenStackLayout() throws Exception {
216
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
217
-        final LayoutNode container = createContainerNode();
218
-        final LayoutNode stackNode = createContainerStackNode(container);
219
-        final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
220
-
221
-        when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(otherMockView);
222
-        final LayoutNode pushedContainer = createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY);
223
-        containerStackLayout.push(createLayoutFactory().create(pushedContainer));
224
-
225
-        ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
226
-        assertThat(result.getChildAt(0)).isEqualTo(otherMockView);
227
-    }
228
-
229
-    @Test
230
-    public void pushTwoScreensToStackLayout() throws Exception {
231
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
232
-        final LayoutNode container = createContainerNode();
233
-        final LayoutNode stackNode = createContainerStackNode(container);
234
-        final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
235
-
236
-        View first = new View(activity);
237
-        pushContainer(containerStackLayout, OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY, first);
238
-
239
-        View second = new View(activity);
240
-        pushContainer(containerStackLayout, "secondPushedScreenId", "secondPushedScreenKey", second);
241
-
242
-        ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
243
-        assertThat(result.getChildAt(0)).isEqualTo(second);
244
-    }
245
-
246
-    @Test
247
-    public void popTwoScreensFromStackLayout() throws Exception {
248
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
249
-        final LayoutNode container = createContainerNode();
250
-        final LayoutNode stackNode = createContainerStackNode(container);
251
-        final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
252
-
253
-        pushContainer(containerStackLayout, OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY, new View(activity));
254
-        pushContainer(containerStackLayout, "secondPushedScreenId", "secondPushedScreenKey", new View(activity));
255
-
256
-        containerStackLayout.pop();
257
-        containerStackLayout.pop();
258
-
259
-        ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
260
-        assertThat(result.getChildAt(0)).isEqualTo(mockView);
261
-    }
262
-
263
-    private void pushContainer(ContainerStackLayout containerStackLayout, String screenId, String reactRootViewKey, View rootView) {
264
-        when(reactRootViewCreator.create(eq(screenId), eq(reactRootViewKey))).thenReturn(rootView);
265
-        View pushedContainer = createLayoutFactory().create(createContainerNode(screenId, reactRootViewKey));
266
-        containerStackLayout.push(pushedContainer);
267
-    }
268
-
269
-    private void pushContainer(BottomTabsLayout containerStackLayout, String screenId, String reactRootViewKey, View rootView) {
270
-        when(reactRootViewCreator.create(eq(screenId), eq(reactRootViewKey))).thenReturn(rootView);
271
-        View pushedContainer = createLayoutFactory().create(createContainerNode(screenId, reactRootViewKey));
272
-        containerStackLayout.push(pushedContainer);
273
-    }
274
-
275
-    @Test
276
-    public void popScreenFromScreenStackLayout() {
277
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
278
-        final LayoutNode container = createContainerNode();
279
-        final LayoutNode stackNode = createContainerStackNode(container);
280
-        final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
281
-
282
-        when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(otherMockView);
283
-        final LayoutNode pushedContainer = createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY);
284
-        containerStackLayout.push(createLayoutFactory().create(pushedContainer));
285
-
286
-        containerStackLayout.pop();
287
-        ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
288
-        assertThat(result.getChildAt(0)).isEqualTo(mockView);
289
-    }
290
-
291
-    @Test(expected = IllegalArgumentException.class)
292
-    public void throwsExceptionForUnknownType() throws Exception {
293
-        when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
294
-        final LayoutNode node = new LayoutNode(NODE_ID, "***unknownType***", Collections.<String, Object>emptyMap());
295
-
296
-        createLayoutFactory().create(node);
297
-    }
298
-
299
-    private LayoutFactory createLayoutFactory() {
300
-        return createLayoutFactory(null);
301
-    }
302
-
303
-    private LayoutFactory createLayoutFactory(BottomTabs bottomTabs) {
304
-        BottomTabsCreator bottomTabsCreator = null;
305
-        if (bottomTabs != null) {
306
-            bottomTabsCreator = mock(BottomTabsCreator.class);
307
-            when(bottomTabsCreator.create()).thenReturn(bottomTabs);
308
-        }
309
-
310
-        return new LayoutFactory(activity, reactRootViewCreator, bottomTabsCreator);
311
-    }
312
-
313
-    private LayoutNode createContainerNode() {
314
-        return createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY);
315
-    }
316
-
317
-    private LayoutNode createSideMenuLeftNode() {
318
-        List<LayoutNode> children = Arrays.asList(createContainerNode());
319
-        return new LayoutNode("SideMenuLeft", children);
320
-    }
321
-
322
-    private LayoutNode createSideMenuRightNode() {
323
-        List<LayoutNode> children = Arrays.asList(createContainerNode());
324
-        return new LayoutNode("SideMenuRight", children);
325
-    }
326
-
327
-    private LayoutNode createContainerNode(final String id, final String name) {
328
-        return new LayoutNode(id, "Container", new HashMap<String, Object>() {{
329
-            put("name", name);
330
-        }});
331
-    }
332
-
333
-    private LayoutNode createSideMenuContainerNode(List<LayoutNode> children) {
334
-        return new LayoutNode("SideMenuRoot", children);
335
-    }
336
-
337
-    private LayoutNode createContainerStackNode(LayoutNode... children) {
338
-        return new LayoutNode("ContainerStack", Arrays.asList(children));
339
-    }
340
-
341
-    private LayoutNode createBottomTabNode(LayoutNode... children) {
342
-        return new LayoutNode("BottomTabs", Arrays.asList(children));
343
-    }
30
+	private final static String NODE_ID = "myUniqueId";
31
+	private final static String REACT_ROOT_VIEW_KEY = "myName";
32
+
33
+	private final static String OTHER_NODE_ID = "anotherUniqueId";
34
+	private final static String OTHER_REACT_ROOT_VIEW_KEY = "anotherName";
35
+
36
+	private Activity activity;
37
+	private View mockView;
38
+	private View otherMockView;
39
+	private LayoutFactory.ReactRootViewCreator reactRootViewCreator;
40
+
41
+	@Before
42
+	public void setUp() {
43
+		activity = Robolectric.buildActivity(AppCompatActivity.class).get();
44
+		mockView = new View(activity);
45
+		otherMockView = new View(activity);
46
+		reactRootViewCreator = mock(LayoutFactory.ReactRootViewCreator.class);
47
+	}
48
+
49
+	@Test
50
+	public void returnsContainerThatHoldsTheRootView() throws Exception {
51
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
52
+		final LayoutNode node = createContainerNode();
53
+
54
+		final ViewGroup result = (ViewGroup) createLayoutFactory().create(node);
55
+
56
+		assertThat(result).isInstanceOf(Container.class);
57
+		TestUtils.assertViewChildren(result, mockView);
58
+	}
59
+
60
+	@Test
61
+	public void returnsContainerStack() throws Exception {
62
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
63
+		final LayoutNode containerNode = createContainerNode();
64
+		final LayoutNode stackNode = createContainerStackNode(containerNode);
65
+
66
+		final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
67
+
68
+		assertThat(result).isInstanceOf(ContainerStackLayout.class);
69
+		ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(result, 1).get(0);
70
+		TestUtils.assertViewChildren(container, mockView);
71
+	}
72
+
73
+	@Test
74
+	public void returnsContainerStackWithMultipleViews() throws Exception {
75
+		final View mockView1 = mock(View.class);
76
+		final View mockView2 = mock(View.class);
77
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView1);
78
+		when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(mockView2);
79
+
80
+		final LayoutNode containerNode1 = createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY);
81
+		final LayoutNode containerNode2 = createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY);
82
+		final LayoutNode stackNode = createContainerStackNode(containerNode1, containerNode2);
83
+
84
+		final ViewGroup result = (ViewGroup) createLayoutFactory().create(stackNode);
85
+
86
+		assertThat(result).isInstanceOf(ContainerStackLayout.class);
87
+		List<View> containers = TestUtils.assertViewChildrenCount(result, 2);
88
+		ViewGroup container1 = (ViewGroup) containers.get(0);
89
+		ViewGroup container2 = (ViewGroup) containers.get(1);
90
+		TestUtils.assertViewChildren(container1, mockView1);
91
+		TestUtils.assertViewChildren(container2, mockView2);
92
+	}
93
+
94
+	@Test
95
+	public void returnsSideMenuRoot() throws Exception {
96
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
97
+		final LayoutNode containerNode = createSideMenuContainerNode(Arrays.asList(createContainerNode()));
98
+		final ViewGroup result = (ViewGroup) createLayoutFactory().create(containerNode);
99
+		assertThat(result).isInstanceOf(SideMenuLayout.class);
100
+	}
101
+
102
+	@Test
103
+	public void hasContentContainer() throws Exception {
104
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
105
+		LayoutNode contentContainer = createContainerNode();
106
+		final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(contentContainer));
107
+		final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
108
+		assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
109
+	}
110
+
111
+	@Test
112
+	public void hasLeftMenu() throws Exception {
113
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
114
+		LayoutNode sideMenuLeft = createSideMenuLeftNode();
115
+		final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(sideMenuLeft));
116
+		final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
117
+		assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
118
+	}
119
+
120
+	@Test
121
+	public void hasRightMenu() throws Exception {
122
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
123
+		LayoutNode sideMenuRight = createSideMenuRightNode();
124
+		final LayoutNode sideMenu = createSideMenuContainerNode(Arrays.asList(sideMenuRight));
125
+		final ViewGroup result = (ViewGroup) createLayoutFactory().create(sideMenu);
126
+		assertThat(result.getChildAt(0)).isInstanceOf(Container.class);
127
+	}
128
+
129
+	@Test
130
+	public void returnsSingleTabContent() throws Exception {
131
+		BottomTabs bottomTabsMock = mock(BottomTabs.class);
132
+		when(bottomTabsMock.size()).thenReturn(0);
133
+
134
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
135
+		final LayoutNode containerNode = createContainerStackNode(createContainerNode());
136
+		final LayoutNode tabNode = createBottomTabNode(containerNode);
137
+
138
+		final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
139
+
140
+		verify(bottomTabsMock).add("#0");
141
+
142
+		assertThat(result).isInstanceOf(BottomTabsLayout.class);
143
+		ViewGroup containerStack = (ViewGroup) TestUtils.assertViewChildrenCount((BottomTabsLayout) result, 1).get(0);
144
+		Container container = (Container) TestUtils.assertViewChildrenCount(containerStack, 1).get(0);
145
+		View view = TestUtils.assertViewChildrenCount(container, 1).get(0);
146
+		assertThat(view).isEqualTo(mockView);
147
+	}
148
+
149
+	@Test
150
+	public void returnsTwoTabContent() throws Exception {
151
+		BottomTabs bottomTabsMock = mock(BottomTabs.class);
152
+		when(bottomTabsMock.size()).thenReturn(0, 1);
153
+
154
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
155
+		final LayoutNode firstTabRootNode = createContainerStackNode(createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY));
156
+
157
+		when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(otherMockView);
158
+		final LayoutNode secondTabRootNode = createContainerStackNode(createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY));
159
+
160
+		final LayoutNode tabNode = createBottomTabNode(firstTabRootNode, secondTabRootNode);
161
+
162
+		final View result = createLayoutFactory(bottomTabsMock).create(tabNode);
163
+
164
+		assertThat(result).isInstanceOf(BottomTabsLayout.class);
165
+		verify(bottomTabsMock).add(eq("#0"));
166
+		verify(bottomTabsMock).add(eq("#1"));
167
+	}
168
+
169
+	@Test
170
+	public void pushScreenToFirstBottomTab() {
171
+		BottomTabs bottomTabsMock = mock(BottomTabs.class);
172
+		when(bottomTabsMock.size()).thenReturn(0, 1);
173
+
174
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
175
+		final LayoutNode firstTabContainerStack = createContainerStackNode(createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY));
176
+
177
+		final LayoutNode tabNode = createBottomTabNode(firstTabContainerStack);
178
+		final BottomTabsLayout bottomTabsContainer = (BottomTabsLayout) createLayoutFactory(bottomTabsMock).create(tabNode);
179
+		verify(bottomTabsMock).add(eq("#0"));
180
+
181
+		View pushedReactView = new View(activity);
182
+		when(reactRootViewCreator.create(eq("pushedReactViewId"), eq("pushedReactViewKey"))).thenReturn(pushedReactView);
183
+		View view = createLayoutFactory().create(createContainerNode("pushedReactViewId", "pushedReactViewKey"));
184
+		bottomTabsContainer.push(view);
185
+
186
+		ViewGroup containerStack = (ViewGroup) TestUtils.assertViewChildrenCount(bottomTabsContainer, 1).get(0);
187
+		ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(containerStack, 1).get(0);
188
+		View result = TestUtils.assertViewChildrenCount(container, 1).get(0);
189
+		assertThat(result).isEqualTo(pushedReactView);
190
+	}
191
+
192
+	@Test
193
+	public void popScreenFromFirstBottomTab() {
194
+		BottomTabs bottomTabsMock = mock(BottomTabs.class);
195
+		when(bottomTabsMock.size()).thenReturn(0, 1);
196
+
197
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
198
+		final LayoutNode firstTabContainerStack = createContainerStackNode(createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY));
199
+
200
+		final LayoutNode tabNode = createBottomTabNode(firstTabContainerStack);
201
+		final BottomTabsLayout bottomTabsContainer = (BottomTabsLayout) createLayoutFactory(bottomTabsMock).create(tabNode);
202
+		verify(bottomTabsMock).add(eq("#0"));
203
+
204
+		pushContainer(bottomTabsContainer, "pushedReactViewId", "pushedReactViewKey", new View(activity));
205
+
206
+		bottomTabsContainer.pop();
207
+
208
+		ViewGroup containerStack = (ViewGroup) TestUtils.assertViewChildrenCount(bottomTabsContainer, 1).get(0);
209
+		ViewGroup container = (ViewGroup) TestUtils.assertViewChildrenCount(containerStack, 1).get(0);
210
+		View result = TestUtils.assertViewChildrenCount(container, 1).get(0);
211
+		assertThat(result).isEqualTo(mockView);
212
+	}
213
+
214
+	@Test
215
+	public void pushScreenToScreenStackLayout() throws Exception {
216
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
217
+		final LayoutNode container = createContainerNode();
218
+		final LayoutNode stackNode = createContainerStackNode(container);
219
+		final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
220
+
221
+		when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(otherMockView);
222
+		final LayoutNode pushedContainer = createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY);
223
+		containerStackLayout.push(createLayoutFactory().create(pushedContainer));
224
+
225
+		ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
226
+		assertThat(result.getChildAt(0)).isEqualTo(otherMockView);
227
+	}
228
+
229
+	@Test
230
+	public void pushTwoScreensToStackLayout() throws Exception {
231
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
232
+		final LayoutNode container = createContainerNode();
233
+		final LayoutNode stackNode = createContainerStackNode(container);
234
+		final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
235
+
236
+		View first = new View(activity);
237
+		pushContainer(containerStackLayout, OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY, first);
238
+
239
+		View second = new View(activity);
240
+		pushContainer(containerStackLayout, "secondPushedScreenId", "secondPushedScreenKey", second);
241
+
242
+		ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
243
+		assertThat(result.getChildAt(0)).isEqualTo(second);
244
+	}
245
+
246
+	@Test
247
+	public void popTwoScreensFromStackLayout() throws Exception {
248
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
249
+		final LayoutNode container = createContainerNode();
250
+		final LayoutNode stackNode = createContainerStackNode(container);
251
+		final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
252
+
253
+		pushContainer(containerStackLayout, OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY, new View(activity));
254
+		pushContainer(containerStackLayout, "secondPushedScreenId", "secondPushedScreenKey", new View(activity));
255
+
256
+		containerStackLayout.pop();
257
+		containerStackLayout.pop();
258
+
259
+		ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
260
+		assertThat(result.getChildAt(0)).isEqualTo(mockView);
261
+	}
262
+
263
+	private void pushContainer(ContainerStackLayout containerStackLayout, String screenId, String reactRootViewKey, View rootView) {
264
+		when(reactRootViewCreator.create(eq(screenId), eq(reactRootViewKey))).thenReturn(rootView);
265
+		View pushedContainer = createLayoutFactory().create(createContainerNode(screenId, reactRootViewKey));
266
+		containerStackLayout.push(pushedContainer);
267
+	}
268
+
269
+	private void pushContainer(BottomTabsLayout containerStackLayout, String screenId, String reactRootViewKey, View rootView) {
270
+		when(reactRootViewCreator.create(eq(screenId), eq(reactRootViewKey))).thenReturn(rootView);
271
+		View pushedContainer = createLayoutFactory().create(createContainerNode(screenId, reactRootViewKey));
272
+		containerStackLayout.push(pushedContainer);
273
+	}
274
+
275
+	@Test
276
+	public void popScreenFromScreenStackLayout() {
277
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
278
+		final LayoutNode container = createContainerNode();
279
+		final LayoutNode stackNode = createContainerStackNode(container);
280
+		final ContainerStackLayout containerStackLayout = (ContainerStackLayout) createLayoutFactory().create(stackNode);
281
+
282
+		when(reactRootViewCreator.create(eq(OTHER_NODE_ID), eq(OTHER_REACT_ROOT_VIEW_KEY))).thenReturn(otherMockView);
283
+		final LayoutNode pushedContainer = createContainerNode(OTHER_NODE_ID, OTHER_REACT_ROOT_VIEW_KEY);
284
+		containerStackLayout.push(createLayoutFactory().create(pushedContainer));
285
+
286
+		containerStackLayout.pop();
287
+		ViewGroup result = (ViewGroup) TestUtils.assertViewChildrenCount(containerStackLayout, 1).get(0);
288
+		assertThat(result.getChildAt(0)).isEqualTo(mockView);
289
+	}
290
+
291
+	@Test(expected = IllegalArgumentException.class)
292
+	public void throwsExceptionForUnknownType() throws Exception {
293
+		when(reactRootViewCreator.create(eq(NODE_ID), eq(REACT_ROOT_VIEW_KEY))).thenReturn(mockView);
294
+		final LayoutNode node = new LayoutNode(NODE_ID, "***unknownType***", Collections.<String, Object>emptyMap());
295
+
296
+		createLayoutFactory().create(node);
297
+	}
298
+
299
+	private LayoutFactory createLayoutFactory() {
300
+		return createLayoutFactory(null);
301
+	}
302
+
303
+	private LayoutFactory createLayoutFactory(BottomTabs bottomTabs) {
304
+		BottomTabsCreator bottomTabsCreator = null;
305
+		if (bottomTabs != null) {
306
+			bottomTabsCreator = mock(BottomTabsCreator.class);
307
+			when(bottomTabsCreator.create()).thenReturn(bottomTabs);
308
+		}
309
+
310
+		return new LayoutFactory(activity, reactRootViewCreator, bottomTabsCreator);
311
+	}
312
+
313
+	private LayoutNode createContainerNode() {
314
+		return createContainerNode(NODE_ID, REACT_ROOT_VIEW_KEY);
315
+	}
316
+
317
+	private LayoutNode createSideMenuLeftNode() {
318
+		List<LayoutNode> children = Arrays.asList(createContainerNode());
319
+		return new LayoutNode("SideMenuLeft", children);
320
+	}
321
+
322
+	private LayoutNode createSideMenuRightNode() {
323
+		List<LayoutNode> children = Arrays.asList(createContainerNode());
324
+		return new LayoutNode("SideMenuRight", children);
325
+	}
326
+
327
+	private LayoutNode createContainerNode(final String id, final String name) {
328
+		return new LayoutNode(id, "Container", new HashMap<String, Object>() {{
329
+			put("name", name);
330
+		}});
331
+	}
332
+
333
+	private LayoutNode createSideMenuContainerNode(List<LayoutNode> children) {
334
+		return new LayoutNode("SideMenuRoot", children);
335
+	}
336
+
337
+	private LayoutNode createContainerStackNode(LayoutNode... children) {
338
+		return new LayoutNode("ContainerStack", Arrays.asList(children));
339
+	}
340
+
341
+	private LayoutNode createBottomTabNode(LayoutNode... children) {
342
+		return new LayoutNode("BottomTabs", Arrays.asList(children));
343
+	}
344 344
 }

+ 12
- 12
android/app/src/test/java/com/reactnativenavigation/layout/TestUtils.java Целия файл

@@ -10,18 +10,18 @@ import java.util.List;
10 10
 import static org.assertj.core.api.Java6Assertions.assertThat;
11 11
 
12 12
 public class TestUtils {
13
-    public static List<View> assertViewChildrenCount(ViewGroup view, int count) {
14
-        assertThat(view.getChildCount()).isEqualTo(count);
13
+	public static List<View> assertViewChildrenCount(ViewGroup view, int count) {
14
+		assertThat(view.getChildCount()).isEqualTo(count);
15 15
 
16
-        final List<View> children = new ArrayList<>(count);
17
-        for (int i = 0; i < count; i++) {
18
-            children.add(view.getChildAt(i));
19
-        }
20
-        return children;
21
-    }
16
+		final List<View> children = new ArrayList<>(count);
17
+		for (int i = 0; i < count; i++) {
18
+			children.add(view.getChildAt(i));
19
+		}
20
+		return children;
21
+	}
22 22
 
23
-    public static void assertViewChildren(ViewGroup view, View... children) {
24
-        final List<View> childViews = assertViewChildrenCount(view, children.length);
25
-        assertThat(childViews).isEqualTo(Arrays.asList(children));
26
-    }
23
+	public static void assertViewChildren(ViewGroup view, View... children) {
24
+		final List<View> childViews = assertViewChildrenCount(view, children.length);
25
+		assertThat(childViews).isEqualTo(Arrays.asList(children));
26
+	}
27 27
 }