* Copyright (c) 2025 Huawei Technologies Co., Ltd.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {TestSuite} from '@rnoh/testerino';
import React, {useState} from 'react';
import {
View,
registerViewConfig,
ReactNativeViewAttributes,
TouchableOpacity,
} from 'react-native';
import {Button, TestCase} from '../components';
let _PropsDisplayer: typeof View | undefined;
function getPropsDisplayer() {
if (!_PropsDisplayer) {
try {
_PropsDisplayer = registerViewConfig('PropsDisplayer', () => {
return {
uiViewClassName: 'PropsDisplayer',
bubblingEventTypes: {},
directEventTypes: {},
validAttributes: {
...ReactNativeViewAttributes.UIView,
},
};
});
} catch (error) {
if (
error instanceof Error &&
error.message.includes('Tried to register two views')
) {
_PropsDisplayer = View;
} else {
throw error;
}
}
}
return _PropsDisplayer ?? View;
}
export function RenderingTest() {
const PropsDisplayer = getPropsDisplayer();
return (
<TestSuite name="Rendering">
<TestCase.Example itShould="change the rectangle's color every second">
<Timeout
ms={1000}
renderItem={refreshKey => (
<Rectangle
backgroundColor={refreshKey % 2 === 0 ? 'red' : 'green'}
/>
)}
/>
</TestCase.Example>
<TestCase.Example itShould="show and hide rectangle every second">
<Timeout
ms={1000}
renderItem={refreshKey => (
<View style={{height: 64}}>
{refreshKey % 2 === 0 ? (
<Rectangle backgroundColor={'red'} />
) : null}
</View>
)}
/>
</TestCase.Example>
<TestCase.Example itShould="display green view over blue after pressing">
<RenderOrderExample />
</TestCase.Example>
<TestCase.Example itShould="display all props after pressing the button, not only the recently updated one">
<Timeout
ms={0}
renderItem={refreshColor => {
return (
<View style={{padding: 64, width: '100%', height: 1500}}>
<PropsDisplayer
style={{
backgroundColor: refreshColor % 2 ? 'red' : 'blue',
opacity: 0.9,
borderWidth: 4,
borderTopWidth: 4,
borderColor: 'orange',
borderTopColor: 'red',
borderRadius: 4,
borderBottomRightRadius: 8,
transform: [{translateX: 1}],
pointerEvents: 'auto',
shadowOffset: {width: 0, height: 0},
shadowOpacity: 0.9,
shadowRadius: 9,
flexDirection: 'row',
overflow: 'hidden',
backfaceVisibility: 'visible',
width: '100%',
height: '100%',
}}
/>
</View>
);
}}
/>
</TestCase.Example>
</TestSuite>
);
}
function Rectangle({backgroundColor}: {backgroundColor: string}) {
return (
<View
style={{
width: 64,
height: 64,
backgroundColor,
}}
/>
);
}
function Timeout({
renderItem,
ms,
}: {
renderItem: (refreshKey: number) => any;
ms: number;
}) {
const [refreshKey, setRefreshKey] = useState(0);
return (
<React.Fragment>
<Button
label="Run"
onPress={() => setTimeout(() => setRefreshKey(prev => (prev += 1)), ms)}
/>
{renderItem(refreshKey)}
</React.Fragment>
);
}
function RenderOrderExample() {
const [show, setShow] = React.useState(false);
return (
<TouchableOpacity
style={{
backgroundColor: 'red',
height: 100,
width: 100,
}}
onPress={() => {
setShow(s => !s);
}}>
{show ? (
<View
style={{
position: 'absolute',
backgroundColor: 'blue',
height: 90,
width: 90,
}}
/>
) : null}
<View style={{backgroundColor: 'green', width: 80, height: 80}} />
</TouchableOpacity>
);
}