1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.compose.testutils 18 19 import androidx.compose.runtime.Composable 20 import androidx.compose.ui.UiComposable 21 22 /** 23 * To be implemented to provide a test case that is then executed by [ComposeTestRule] or can be 24 * used in benchmarks. 25 */ 26 interface ComposeTestCase { 27 /** 28 * This method is guaranteed to be called only once per class lifetime. In case a benchmark 29 * needs to measure initial composition / measure / layout / draw it re-creates this class every 30 * time it needs to call Content again. This ensures that any setup you do in this class is not 31 * shared between multiple calls of this method. So the init method is a good place to setup / 32 * clean your caches. 33 */ Contentnull34 @Composable fun Content() 35 } 36 37 /** To be implemented to provide a test case that is then executed in benchmarks. */ 38 // TODO(b/185389423): Make this to be an interface once the compiler gets fixed. 39 abstract class LayeredComposeTestCase : ComposeTestCase { 40 /** 41 * This method is guaranteed to be called only once per class lifetime. In case a benchmark 42 * needs to measure initial composition / measure / layout / draw it re-creates this class every 43 * time it needs to call emitContent again. This ensures that any setup you do in this class is 44 * not shared between multiple calls of this method. So the init method is a good place to setup 45 * / clean your caches. 46 */ 47 @Composable 48 override fun Content() { 49 ContentWrappers { MeasuredContent() } 50 } 51 52 /** 53 * This method should emit content that is supposed to be measured. Any other helper containers, 54 * CompositionLocals and themes should be set in [ContentWrappers]. 55 * 56 * The lifecycle rules for this method are same as for [Content] 57 */ 58 @Composable abstract fun MeasuredContent() 59 60 /** 61 * Receives the result of [MeasuredContent]. 62 * 63 * In "first" benchmarks this method's content is set up before the content from 64 * [MeasuredContent] gets introduced to be measured. This helps to avoid measuring helper 65 * containers or CompositionLocal setups. 66 * 67 * The lifecycle rules for this method are same as for [Content] 68 */ 69 @Composable 70 @UiComposable 71 open fun ContentWrappers(content: @Composable () -> Unit) { 72 content() 73 } 74 } 75