package com.bytedance.scene; import android.arch.lifecycle.LifecycleObserver; import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.util.Pair; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import com.bytedance.scene.group.GroupScene; import com.bytedance.scene.navigation.NavigationScene; import com.bytedance.scene.utlity.ViewIdGenerator; import com.bytedance.scene.view.SceneContextThemeWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import static org.junit.Assert.*; @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) public class SceneTests { @Test public void testNonNullArguments() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; Bundle bundle = new Bundle(); scene.setArguments(bundle); assertSame(bundle, scene.requireArguments()); assertSame(bundle, scene.getArguments()); } @Test(expected = IllegalStateException.class) public void testRequireArgumentsException() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireArguments(); } @Test public void testRequireViewAfterOnCreateView() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); assertNotNull(scene.getView()); assertNotNull(scene.requireView()); } @Test(expected = IllegalStateException.class) public void testRequireViewExceptionBeforeOnCreateView() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireView(); } @Test(expected = IllegalStateException.class) public void testRequireParentSceneExceptionBeforeAttach() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireParentScene(); } @Test public void testRequireParentSceneAfterAttach() { GroupScene scene = new GroupScene() { @NonNull @Override public ViewGroup onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new FrameLayout(requireSceneContext()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); Scene childScene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireView().setId(ViewIdGenerator.generateViewId()); scene.add(scene.requireView().getId(), childScene, "TAG"); assertNotNull(childScene.getParentScene()); assertNotNull(childScene.requireParentScene()); assertSame(scene, childScene.requireParentScene()); } @Test(expected = IllegalStateException.class) public void testRootSceneRequireParentSceneException() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); assertNull(scene.getNavigationScene().getParentScene()); scene.getNavigationScene().requireParentScene(); } @Test(expected = IllegalStateException.class) public void testRequireNavigationSceneExceptionBeforeAttach() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireNavigationScene(); } @Test(expected = IllegalStateException.class) public void testRequireNavigationSceneExceptionOnRootNavigationScene() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; NavigationScene navigationScene = NavigationSourceUtility.createFromSceneLifecycleManager(scene); navigationScene.requireNavigationScene(); } @Test public void testRequireNavigationSceneAfterAttach() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); Scene childScene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; assertNotNull(scene.getNavigationScene()); assertNotNull(scene.requireNavigationScene()); assertSame(pair.second, scene.requireNavigationScene()); } @Test(expected = IllegalStateException.class) public void testRootSceneRequireNavigationSceneException() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); assertNull(scene.requireNavigationScene().getNavigationScene()); scene.requireNavigationScene().requireNavigationScene(); } @Test(expected = IllegalStateException.class) public void testRequireActivityBeforeOnAttach() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireActivity(); } @Test(expected = IllegalStateException.class) public void testRequireSceneContextBeforeOnAttach() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireSceneContext(); } @Test(expected = IllegalStateException.class) public void testRequireApplicationContextBeforeOnAttach() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.requireApplicationContext(); } @Test(expected = IllegalStateException.class) public void testGetLayoutInflaterBeforeOnAttach() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.getLayoutInflater(); } @Test(expected = IllegalStateException.class) public void testGetScopeBeforeOnCreate() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.getScope(); } @Test public void testExecuteNowOrScheduleAtNextResume() { final AtomicBoolean mValue = new AtomicBoolean(false); Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); executeNowOrScheduleAtNextResume(new Runnable() { @Override public void run() { mValue.set(true); } }); assertFalse(mValue.get()); } @Override public void onResume() { super.onResume(); assertTrue(mValue.get()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); assertTrue(mValue.get()); final AtomicBoolean second = new AtomicBoolean(); scene.executeNowOrScheduleAtNextResume(new Runnable() { @Override public void run() { second.set(true); } }); assertTrue(second.get()); } @Test public void test_LAYOUT_INFLATER_SERVICE() { final AtomicReference<View> reference = new AtomicReference<>(); Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); reference.set(getView()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); SceneLifecycleManager manager = pair.first; manager.onStart(); manager.onResume(); assertNotNull(reference.get().getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)); } @Test public void test_LAYOUT_INFLATER_SERVICE_WhenThemeSet() { final AtomicReference<View> reference = new AtomicReference<>(); Scene scene = new Scene() { @Override public void onAttach() { super.onAttach(); setTheme(android.R.style.Theme); } @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); reference.set(getView()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); SceneLifecycleManager manager = pair.first; manager.onStart(); manager.onResume(); assertNotNull(reference.get().getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)); } @Test public void test_LAYOUT_INFLATER_SERVICE_afterOnDestroyView() { final AtomicReference<View> reference = new AtomicReference<>(); Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); reference.set(getView()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); SceneLifecycleManager manager = pair.first; manager.onStart(); manager.onResume(); manager.onPause(); manager.onStop(); manager.onDestroyView(); assertNotNull(reference.get().getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)); } @Test public void test_LAYOUT_INFLATER_SERVICE_afterOnDestroyViewWhenThemeSet() { final AtomicReference<View> reference = new AtomicReference<>(); Scene scene = new Scene() { @Override public void onAttach() { super.onAttach(); setTheme(android.R.style.Theme); } @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); reference.set(getView()); } }; Pair<SceneLifecycleManager<NavigationScene>, NavigationScene> pair = NavigationSourceUtility.createFromInitSceneLifecycleManager(scene); SceneLifecycleManager manager = pair.first; manager.onStart(); manager.onResume(); manager.onPause(); manager.onStop(); manager.onDestroyView(); assertNotNull(reference.get().getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)); } @Test public void testFindViewById() { final int id = ViewIdGenerator.generateViewId(); final AtomicReference<View> reference = new AtomicReference<>(); Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { View view = new View(requireSceneContext()); view.setId(id); reference.set(view); return view; } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); assertNotNull(scene.findViewById(id)); assertSame(reference.get(), scene.findViewById(id)); assertNull(scene.findViewById(ViewIdGenerator.generateViewId())); } @Test public void testFindViewByIdBeforeOnCreateView() { final int id = ViewIdGenerator.generateViewId(); Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { View view = new View(requireSceneContext()); view.setId(id); return view; } }; assertNull(scene.findViewById(id)); } @Test(expected = IllegalArgumentException.class) public void testRequireViewById() { final int id = ViewIdGenerator.generateViewId(); final AtomicReference<View> reference = new AtomicReference<>(); Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { View view = new View(requireSceneContext()); reference.set(view); return view; } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); scene.requireViewById(id); } @Test public void testGetString() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); assertNotNull(scene.getString(android.R.string.cancel)); } @Test public void testGetStringFormatArgs() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); assertNotNull(scene.getString(TestResources.getString(scene, "ut_get_string"), "Value")); assertEquals("UnitTestGetStringValue", scene.getString(TestResources.getString(scene, "ut_get_string"), "Value")); } @Test public void testGetText() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); assertNotNull(scene.getText(android.R.string.cancel)); } @Test public void testFixSceneReuseLifecycleAdapterReset() { final int id = ViewIdGenerator.generateViewId(); GroupScene groupScene = new GroupScene() { @NonNull @Override public ViewGroup onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { FrameLayout layout = new FrameLayout(requireSceneContext()); layout.setId(id); return layout; } }; NavigationSourceUtility.createFromSceneLifecycleManager(groupScene); Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; scene.getLifecycle().addObserver(new LifecycleObserver() { }); groupScene.add(id, scene, "TAG"); groupScene.remove(scene); groupScene.add(id, scene, "TAG"); } @Test public void testViewContext() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireActivity()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); assertSame(scene.requireActivity(), scene.getView().getContext()); Scene scene2 = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(new SceneContextThemeWrapper(requireActivity(), requireActivity().getTheme())); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene2); Scene scene3 = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(new SceneContextThemeWrapper(requireSceneContext(), requireSceneContext().getTheme()) { //subclass of ContextWrapper }); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene3); Scene scene4 = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireApplicationContext()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene4); } @Test public void testViewSceneContext() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { return new View(requireSceneContext()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); assertSame(scene.requireSceneContext(), scene.getView().getContext()); } @Test(expected = IllegalArgumentException.class) public void testViewContextThemeException() { Scene scene = new Scene() { @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedInstanceState) { setTheme(android.R.style.Theme_Light); return new View(requireActivity()); } }; NavigationSourceUtility.createFromSceneLifecycleManager(scene); } }