'use strict';
let React;
let ReactFabric;
let createReactNativeComponentClass;
let View;
let Text;
let JSResourceReferenceImpl;
let ReactNativeFlightRelayServer;
let ReactNativeFlightRelayClient;
describe('ReactFlightNativeRelay', () => {
beforeEach(() => {
jest.resetModules();
require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager');
React = require('react');
ReactFabric = require('react-native-renderer/fabric');
createReactNativeComponentClass =
require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface')
.ReactNativeViewConfigRegistry.register;
View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {},
uiViewClassName: 'RCTView',
}));
Text = createReactNativeComponentClass('RCTText', () => ({
validAttributes: {},
uiViewClassName: 'RCTText',
}));
ReactNativeFlightRelayServer = require('react-server-native-relay/server');
ReactNativeFlightRelayClient = require('react-server-native-relay');
JSResourceReferenceImpl = require('JSResourceReferenceImpl');
});
function readThrough(data) {
const response = ReactNativeFlightRelayClient.createResponse();
for (let i = 0; i < data.length; i++) {
const chunk = data[i];
ReactNativeFlightRelayClient.resolveRow(response, chunk);
}
ReactNativeFlightRelayClient.close(response);
const promise = ReactNativeFlightRelayClient.getRoot(response);
let model;
let error;
promise.then(
m => (model = m),
e => (error = e),
);
if (error) {
throw error;
}
return model;
}
it('can render a Server Component', () => {
function Bar({text}) {
return <Text>{text.toUpperCase()}</Text>;
}
function Foo() {
return {
bar: (
<View>
<Bar text="a" /> <Bar text="b" />
</View>
),
};
}
const transport = [];
ReactNativeFlightRelayServer.render(
{
foo: <Foo />,
},
transport,
);
const model = readThrough(transport);
expect(model).toMatchSnapshot();
});
it('can render a Client Component using a module reference and render there', () => {
function UserClient(props) {
return (
<Text>
{props.greeting}, {props.name}
</Text>
);
}
const User = new JSResourceReferenceImpl(UserClient);
function Greeting({firstName, lastName}) {
return <User greeting="Hello" name={firstName + ' ' + lastName} />;
}
const model = {
greeting: <Greeting firstName="Seb" lastName="Smith" />,
};
const transport = [];
ReactNativeFlightRelayServer.render(model, transport);
const modelClient = readThrough(transport);
ReactFabric.render(modelClient.greeting, 1);
expect(
nativeFabricUIManager.__dumpHierarchyForJestTestsOnly(),
).toMatchSnapshot();
});
it('should warn in DEV if a class instance polyfill is passed to a host component', () => {
function Bar() {}
function Foo() {}
Foo.prototype = Object.create(Bar.prototype);
Foo.prototype.constructor = Foo;
Foo.prototype.method = function () {};
expect(() => {
const transport = [];
ReactNativeFlightRelayServer.render(
<input value={new Foo()} />,
transport,
);
readThrough(transport);
}).toErrorDev(
'Only plain objects can be passed to Client Components from Server Components. ',
{withoutStack: true},
);
});
});