Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
it('serves index.html on / route with template vars replaced', async () => {
const res = await request('http://127.0.0.1:9005/');
const source = readFileSync(
require.resolve('../../../shared/static/index.html'),
'utf8'
);
expect(res).toEqual(
replaceKeys(source, {
__PLAYGROUND_OPTS__: JSON.stringify({
platform: 'web',
projectKey: mockRootPath,
loaderUri: '/_loader.html',
webpackConfigType: 'custom', // <<< This is relevant in this test
deps: {
'html-webpack-plugin': true
}
})
})
);
});
it('serves index.html on / route with template vars replaced', async () => {
const res = await request('http://127.0.0.1:9006/');
const source = readFileSync(
require.resolve('../../../shared/static/index.html'),
'utf8'
);
expect(res).toEqual(
replaceKeys(source, {
__PLAYGROUND_OPTS__: JSON.stringify({
platform: 'web',
projectKey: mockRootPath,
loaderUri: '/_loader.html',
webpackConfigType: 'custom', // <<< This is relevant in this test
deps: {
'html-webpack-plugin': true
}
})
})
);
});
// @flow
import { uuid } from 'react-cosmos-shared2/util';
import { runTests, mount } from '../testHelpers';
const rendererId = uuid();
const fixtures = { first: null, second: null };
const decorators = {};
runTests(mockConnect => {
it('renders blank state message', async () => {
await mockConnect(async ({ getElement }) => {
await mount(
getElement({ rendererId, fixtures, decorators }),
async renderer => {
expect(renderer.toJSON()).toEqual('No fixture loaded.');
}
);
});
});
it('posts ready response on mount', async () => {
return false;
}
// Fixture state for this instance is populated on mount, so a transition
// to an empty state means that this instance is expected to reset
if (!next) {
return true;
}
// If the fixture state for this instance has just been populated, we need
// to compare its values against the default values, otherwise an additional
// render cycle will be always run on init
const prevKey = prev ? prev.renderKey : DEFAULT_RENDER_KEY;
const prevValues = prev
? prev.values
: extractValuesFromObject(children.props);
if (next.renderKey !== prevKey) {
return true;
}
// Because serialized fixture state changes are received remotely, a change
// in one fixtureState.props instance will change the identity of all
// fixtureState.props instances. So the only way to avoid useless re-renders
// is to check if any value from the fixture state props changed.
return !areValuesEqual(next.values, prevValues);
}
if (!elRef) {
delete elRefs.current[elPath];
return;
}
// Only track instances with state
const { state } = elRef;
if (!state) {
return;
}
elRefs.current[elPath] = elRef;
setInitialState(initialStates.current, elPath, elRef);
const elementId = { decoratorId, elPath };
const fsClassState = findFixtureStateClassState(
lastFixtureState.current,
elementId
);
if (!fsClassState) {
setFixtureState(prevFs => ({
...prevFs,
classState: createFixtureStateClassState({
fixtureState: prevFs,
elementId,
values: createValues(state),
componentName: getComponentName(
elRef.constructor as React.ComponentType
)
})
}));
} else {
elPaths.forEach(elPath => {
const elementId = { decoratorId, elPath };
// Component fixture state can be provided before the fixture mounts (eg.
// a previous snapshot of a fixture state or the current fixture state
// from another renderer)
const fsClassState = findFixtureStateClassState(fixtureState, elementId);
if (!fsClassState) {
if (initialStates.current[elPath]) {
const { state } = initialStates.current[elPath];
const elRef = elRefs.current[elPath];
if (!isEqual(elRef.state, state)) {
replaceState(elRef, state);
}
setFixtureState(prevFs => ({
...prevFs,
classState: createFixtureStateClassState({
fixtureState: prevFs,
elementId,
values: createValues(state),
componentName: getComponentName(
// 1. Element type is stateless
// 2. Element type is a class, but doesn't have state. An instance exists
// but has been discarded because of its lack of state.
// 3. Element instance unmounted and is about to remount. When this
// happens, the new instance will be handled when its ref fires again.
if (!elRef) {
return;
}
// The child's state can be out of sync with the fixture state for two
// reasons:
// 1. The child's state changed internally
// 2. The fixture state changed
// Here we're interested in the second scenario. In the first scenario
// we want to let the component state override the fixture state.
const prevFsClassState = findFixtureStateClassState(
prevFixtureState.current,
elementId
);
if (prevFsClassState && !isEqual(prevFsClassState, fsClassState)) {
return replaceState(
elRef,
extendWithValues(elRef.state, fsClassState.values)
);
}
}
});
}, [
export function findElementPaths(
node: React.ReactNode,
curPath: string = ''
): string[] {
if (Array.isArray(node)) {
return flatten(
node.map((child, idx) => findElementPaths(child, `${curPath}[${idx}]`))
);
}
if (!isReactElement(node)) {
// At this point the node can be null, boolean, string, number, Portal, etc.
// https://github.com/facebook/flow/blob/172d28f542f49bbc1e765131c9dfb9e31780f3a2/lib/react.js#L13-L20
return [];
}
const { children } = node.props;
const childElPaths =
// Props of elements returned by render functions can't be read here
typeof children !== 'function'
? findElementPaths(children, getChildrenPath(curPath))
: [];
// Ignore Fragment elements, but include their children
return node.type === Fragment ? childElPaths : [curPath, ...childElPaths];
}
elPaths.forEach(elPath => {
const childEl = getExpectedElementAtPath(fixture, elPath);
const elementId = { decoratorId, elPath };
// Component fixture state can be provided before the fixture mounts (eg.
// a previous snapshot of a fixture state or the current fixture state
// from another renderer)
if (!findFixtureStateProps(fixtureState, elementId)) {
const componentName = getComponentName(childEl.type);
setFixtureState(prevFs => ({
...prevFs,
props: createFixtureStateProps({
fixtureState: prevFs,
elementId,
values: createValues(childEl.props),
componentName
})
}));
} else if (
!areNodesEqual(
childEl,
getElementAtPath(prevFixtureRef.current, elPath)
)
) {
return elPaths.reduce((extendedFixture, elPath): React.ReactNode => {
const elementId = { decoratorId, elPath };
const fsProps = findFixtureStateProps(fixtureState, elementId);
return setElementAtPath(extendedFixture, elPath, element => {
if (!fsProps || componentTypeChanged(fsProps.componentName)) {
return {
...element,
key: getElRenderKey(elPath, DEFAULT_RENDER_KEY)
};
}
// Prevent overriding child elements with outdated "children" prop values
// stored in fixture state
// See https://github.com/react-cosmos/react-cosmos/pull/920 for context
const originalProps = element.props;
const extendedProps = extendWithValues(originalProps, fsProps.values);
// HACK alert: Editing React Element by hand