it('must reject update if selection is not on an edge', () => {
      var helloBlock = getHelloBlock();
      var props = getProps(helloBlock);

      var container = document.createElement('div');
      ReactDOM.render(
        <DraftEditorBlock {...props} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(1);

      // Move selection state to some other block.
      var nonEdgeSelection = props.selection.merge({
        anchorKey: 'z',
        focusKey: 'z',
      });

      var newProps = {...props, selection: nonEdgeSelection};

      // Render again with selection now moved elsewhere and the contents
      // unchanged.
      ReactDOM.render(
        <DraftEditorBlock {...newProps} />,
        container
      );

      // No new leaf renders.
      expect(mockLeafRender.mock.calls.length).toBe(1);
    });
    it('must allow update when `block` has changed', () => {
      var helloBlock = getHelloBlock();
      var props = getProps(helloBlock);

      var container = document.createElement('div');
      ReactDOM.render(
        <DraftEditorBlock {...props} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(1);

      var updatedHelloBlock = helloBlock.set('text', 'hxllo');
      var nextProps = getProps(updatedHelloBlock);

      expect(updatedHelloBlock).not.toBe(helloBlock);
      expect(props.block).not.toBe(nextProps.block);

      ReactDOM.render(
        <DraftEditorBlock {...nextProps} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(2);
    });
Example #3
0
  it('should reorder keyed text nodes', function() {
    spyOn(console, 'error');

    var container = document.createElement('div');
    ReactDOM.render(
      <div>{new Map([['a', 'alpha'], ['b', 'beta']])}</div>,
      container
    );

    var childNodes = container.firstChild.childNodes;
    var alpha1 = childNodes[0];
    var alpha2 = childNodes[1];
    var alpha3 = childNodes[2];
    var beta1 = childNodes[3];
    var beta2 = childNodes[4];
    var beta3 = childNodes[5];

    ReactDOM.render(
      <div>{new Map([['b', 'beta'], ['a', 'alpha']])}</div>,
      container
    );

    childNodes = container.firstChild.childNodes;
    expect(childNodes[0]).toBe(beta1);
    expect(childNodes[1]).toBe(beta2);
    expect(childNodes[2]).toBe(beta3);
    expect(childNodes[3]).toBe(alpha1);
    expect(childNodes[4]).toBe(alpha2);
    expect(childNodes[5]).toBe(alpha3);

    // Using Maps as children gives a single warning
    expect(console.error.calls.count()).toBe(1);
  });
  it('should destroy a react root upon request', function() {
    var mainContainerDiv = document.createElement('div');
    document.body.appendChild(mainContainerDiv);

    var instanceOne = (
      <div className="firstReactDiv">
      </div>
    );
    var firstRootDiv = document.createElement('div');
    mainContainerDiv.appendChild(firstRootDiv);
    ReactDOM.render(instanceOne, firstRootDiv);

    var instanceTwo = (
      <div className="secondReactDiv">
      </div>
    );
    var secondRootDiv = document.createElement('div');
    mainContainerDiv.appendChild(secondRootDiv);
    ReactDOM.render(instanceTwo, secondRootDiv);

    // Test that two react roots are rendered in isolation
    expect(firstRootDiv.firstChild.className).toBe('firstReactDiv');
    expect(secondRootDiv.firstChild.className).toBe('secondReactDiv');

    // Test that after unmounting each, they are no longer in the document.
    ReactDOM.unmountComponentAtNode(firstRootDiv);
    expect(firstRootDiv.firstChild).toBeNull();
    ReactDOM.unmountComponentAtNode(secondRootDiv);
    expect(secondRootDiv.firstChild).toBeNull();
  });
Example #5
0
  it('should not crash in node cache when unmounting', function() {
    var Component = React.createClass({
      render: function() {
        // Add refs to some nodes so that they get traversed and cached
        return (
          <div ref="a">
            <div ref="b">b</div>
            {this.props.showC && <div>c</div>}
          </div>
        );
      },
    });

    var container = document.createElement('container');

    ReactDOM.render(<div><Component showC={false} /></div>, container);

    // Right now, A and B are in the cache. When we add C, it won't get added to
    // the cache (assuming markup-string mode).
    ReactDOM.render(<div><Component showC={true} /></div>, container);

    // Remove A, B, and C. Unmounting C shouldn't cause B to get recached.
    ReactDOM.render(<div></div>, container);

    // Add them back -- this shouldn't cause a cached node collision.
    ReactDOM.render(<div><Component showC={true} /></div>, container);

    ReactDOM.unmountComponentAtNode(container);
  });
Example #6
0
  it('findDOMNode should find dom element after an update from null', () => {
    function Bar({ flag }) {
      if (flag) {
        return <span>A</span>;
      }
      return null;
    }
    class MyNode extends React.Component {
      render() {
        return <Bar flag={this.props.flag} />;
      }
    }

    var container = document.createElement('div');

    var myNodeA = ReactDOM.render(<MyNode />, container);
    var a = ReactDOM.findDOMNode(myNodeA);
    expect(a).toBe(null);

    var myNodeB = ReactDOM.render(<MyNode flag={true} />, container);
    expect(myNodeA === myNodeB).toBe(true);

    var b = ReactDOM.findDOMNode(myNodeB);
    expect(b.tagName).toBe('SPAN');
  });
Example #7
0
  it('should reuse markup if rendering to the same target twice', function() {
    var container = document.createElement('container');
    var instance1 = ReactDOM.render(<div />, container);
    var instance2 = ReactDOM.render(<div />, container);

    expect(instance1 === instance2).toBe(true);
  });
  it('should reset internal state if removed then readded', function() {
    // Test basics.
    var props = {
      usernameToStatus: {
        jcw: 'jcwStatus',
      },
    };

    var container = document.createElement('div');
    var parentInstance = ReactDOM.render(
      <FriendsStatusDisplay {...props} />,
      container
    );
    var statusDisplays = parentInstance.getStatusDisplays();
    var startingInternalState = statusDisplays.jcw.getInternalState();

    // Now remove the child.
    ReactDOM.render(
      <FriendsStatusDisplay />,
      container
    );
    statusDisplays = parentInstance.getStatusDisplays();
    expect(statusDisplays.jcw).toBeFalsy();

    // Now reset the props that cause there to be a child
    ReactDOM.render(
      <FriendsStatusDisplay {...props} />,
      container
    );
    statusDisplays = parentInstance.getStatusDisplays();
    expect(statusDisplays.jcw).toBeTruthy();
    expect(statusDisplays.jcw.getInternalState())
        .toNotBe(startingInternalState);
  });
Example #9
0
 value: function() {
   shadowRoot = this.createShadowRoot();
   ReactDOM.render(<div>Hi, from within a WC!</div>, shadowRoot);
   expect(shadowRoot.firstChild.tagName).toBe('DIV');
   ReactDOM.render(<span>Hi, from within a WC!</span>, shadowRoot);
   expect(shadowRoot.firstChild.tagName).toBe('SPAN');
 },
function testPropsSequenceWithPreparedChildren(sequence, prepareChildren) {
  var container = document.createElement('div');
  var parentInstance = ReactDOM.render(
    <FriendsStatusDisplay
      {...sequence[0]}
      prepareChildren={prepareChildren}
    />,
    container
  );
  var statusDisplays = parentInstance.getStatusDisplays();
  var lastInternalStates = getInternalStateByUserName(statusDisplays);
  verifyStatuses(statusDisplays, sequence[0]);

  for (var i = 1; i < sequence.length; i++) {
    ReactDOM.render(
      <FriendsStatusDisplay
        {...sequence[i]}
        prepareChildren={prepareChildren}
      />,
      container
    );
    statusDisplays = parentInstance.getStatusDisplays();
    verifyStatuses(statusDisplays, sequence[i]);
    verifyStatesPreserved(lastInternalStates, statusDisplays);
    verifyDomOrderingAccurate(container, statusDisplays);

    lastInternalStates = getInternalStateByUserName(statusDisplays);
  }
}
test('must allow update when `tree` has changed', () => {
  const helloBlock = getHelloBlock();
  const props = getProps(helloBlock);

  const container = document.createElement('div');
  ReactDOM.render(<DraftEditorBlock {...props} />, container);

  expect(mockLeafRender.mock.calls.length).toMatchSnapshot();

  mockGetDecorations.mockReturnValue(
    Immutable.List.of('x', 'x', null, null, null),
  );
  const decorator = new Decorator();

  const newTree = BlockTree.generate(
    ContentState.createFromText(helloBlock.getText()),
    helloBlock,
    decorator,
  );
  const nextProps = {...props, tree: newTree, decorator};

  expect(props.tree !== nextProps.tree).toMatchSnapshot();

  ReactDOM.render(<DraftEditorBlock {...nextProps} />, container);

  expect(mockLeafRender.mock.calls.length).toMatchSnapshot();
});
    it('must allow update when `tree` has changed', () => {
      var helloBlock = getHelloBlock();
      var props = getProps(helloBlock);

      var container = document.createElement('div');
      ReactDOM.render(
        <DraftEditorBlock {...props} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(1);

      mockGetDecorations.mockReturnValue(
        Immutable.List.of('x', 'x', null, null, null)
      );
      var decorator = new Decorator();

      var newTree = BlockTree.generate(helloBlock, decorator);
      var nextProps = {...props, tree: newTree, decorator};

      expect(props.tree).not.toBe(nextProps.tree);

      ReactDOM.render(
        <DraftEditorBlock {...nextProps} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(3);
    });
    it('must allow update when forcing selection', () => {
      var helloBlock = getHelloBlock();
      var props = getProps(helloBlock);

      var container = document.createElement('div');
      ReactDOM.render(
        <DraftEditorBlock {...props} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(1);

      // The default selection state in this test is on a selection edge.
      var nextProps = {
        ...props,
        forceSelection: true,
      };

      ReactDOM.render(
        <DraftEditorBlock {...nextProps} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(2);
    });
  it('does not update static content', () => {
    var mockRender = jest.genMockFunction().mockReturnValue(<div />);
    var MyComponent = React.createClass({render: mockRender});

    ReactDOM.render(<StaticContainer><MyComponent /></StaticContainer>, container);

    expect(mockRender.mock.calls.length).toBe(1);

    ReactDOM.render(<StaticContainer><MyComponent /></StaticContainer>, container);

    expect(mockRender.mock.calls.length).toBe(1);
  });
test('must reject update if conditions are not met', () => {
  const helloBlock = getHelloBlock();
  const props = getProps(helloBlock);

  const container = document.createElement('div');
  ReactDOM.render(<DraftEditorBlock {...props} />, container);

  expect(mockLeafRender.mock.calls.length).toMatchSnapshot();

  // Render again with the exact same props as before.
  ReactDOM.render(<DraftEditorBlock {...props} />, container);

  // No new leaf renders.
  expect(mockLeafRender.mock.calls.length).toMatchSnapshot();
});
 it('is `stale` if force fetching when data is fulfillable', () => {
   ReactDOM.render(
     <RelayRenderer
       Container={MockContainer}
       queryConfig={queryConfig}
       forceFetch={true}
       render={render}
     />,
     container
   );
   expect(request => request.resolve({stale: true})).toRenderWithArgs({
     done: false,
     error: null,
     props: {},
     stale: true,
   });
   expect(request => request.resolve({stale: false})).toRenderWithArgs({
     done: false,
     error: null,
     props: {},
     stale: false,
   });
   expect(request => request.succeed()).toRenderWithArgs({
     done: true,
     error: null,
     props: {},
     stale: false,
   });
 });
test('must allow update when `direction` has changed', () => {
  const helloBlock = getHelloBlock();
  const props = getProps(helloBlock);

  const container = document.createElement('div');
  ReactDOM.render(<DraftEditorBlock {...props} />, container);

  expect(mockLeafRender.mock.calls.length).toMatchSnapshot();

  const nextProps = {...props, direction: UnicodeBidiDirection.RTL};
  expect(props.direction !== nextProps.direction).toMatchSnapshot();

  ReactDOM.render(<DraftEditorBlock {...nextProps} />, container);

  expect(mockLeafRender.mock.calls.length).toMatchSnapshot();
});
Example #18
0
  it('should call a callback argument when the same element is re-rendered', () => {
    class Foo extends React.Component {
      render() {
        return <div>Foo</div>;
      }
    }
    const element = <Foo />;

    // mounting phase
    let called = false;
    ReactDOM.render(
      element,
      container,
      () => called = true
    );
    expect(called).toEqual(true);

    // updating phase
    called = false;
    ReactDOM.unstable_batchedUpdates(() => {
      ReactDOM.render(
        element,
        container,
        () => called = true
      );
    });
    expect(called).toEqual(true);
  });
Example #19
0
  it('throws in render() if the update callback is not a function', function() {
    function Foo() {
      this.a = 1;
      this.b = 2;
    }

    class A extends React.Component {
      state = {};

      render() {
        return <div />;
      }
    }

    var myDiv = document.createElement('div');
    ReactDOM.render(<A />, myDiv);

    expect(() => ReactDOM.render(<A />, myDiv, 'no')).toThrowError(
      'ReactDOM.render(...): Expected the last optional `callback` argument ' +
      'to be a function. Instead received: string.'
    );
    expect(() => ReactDOM.render(<A />, myDiv, {})).toThrowError(
      'ReactDOM.render(...): Expected the last optional `callback` argument ' +
      'to be a function. Instead received: Object.'
    );
    expect(() => ReactDOM.render(<A />, myDiv, new Foo())).toThrowError(
      'ReactDOM.render(...): Expected the last optional `callback` argument ' +
      'to be a function. Instead received: Foo (keys: a, b).'
    );
  });
 toRenderWithArgs: () => ({
   compare(elementOrReadyState, expected) {
     const render = jest.fn(() => <div />);
     const element = ReactTestUtils.isElement(elementOrReadyState) ?
       React.cloneElement(elementOrReadyState, {render}) :
       <RelayReadyStateRenderer
         {...defaultProps}
         readyState={elementOrReadyState}
         render={render}
       />;
     ReactDOM.render(element, container);
     const actual = render.mock.calls[0][0];
     const pass = jasmine.matchersUtil.equals(
       actual,
       jasmine.objectContaining(expected)
     );
     return {
       get message() {
         const not = pass ? ' not' : '';
         return (
           `Expected ${ppReactElement(elementOrReadyState)}${not} ` +
           `to render with arguments ${jasmine.pp(expected)}. ` +
           `Instead, it rendered with arguments ${jasmine.pp(actual)}.`
         );
       },
       pass,
     };
   },
 }),
    it('sets environment and query config on the React context', () => {
      class TestComponent extends React.Component {
        static contextTypes = {
          relay: Relay.PropTypes.Environment,
          route: Relay.PropTypes.QueryConfig.isRequired,
        };
        render() {
          this.props.onRenderContext(this.context);
          return null;
        }
      }

      const onRenderContext = jest.fn();
      const container = document.createElement('div');
      ReactDOM.render(
        <RelayReadyStateRenderer
          {...defaultProps}
          readyState={defaultReadyState}
          render={() => <TestComponent onRenderContext={onRenderContext} />}
        />,
        container
      );
      expect(onRenderContext).toBeCalledWith({
        relay: defaultProps.environment,
        route: defaultProps.queryConfig,
      });
    });
export function build(id, url, page = 1) {
  component = ReactDOM.render(
    <FeedItemList url={url} page={page}/>,
    document.getElementById(id)
  );
  component.loadFeedItem(page)
}
Example #23
0
 ReactDOM.unstable_batchedUpdates(() => {
   ReactDOM.render(
     element,
     container,
     () => called = true
   );
 });
Example #24
0
    it('finds the first child even when first child renders null', () => {
      class NullComponent extends React.Component {
        render() {
          return null;
        }
      }

      class Fragment extends React.Component {
        render() {
          return [
            <NullComponent />,
            <div />,
            <span />,
          ];
        }
      }

      let instance = null;
      ReactDOM.render(
        <Fragment ref={ref => instance = ref} />,
        container
      );

      expect(container.childNodes.length).toBe(2);

      const firstNode = ReactDOM.findDOMNode(instance);
      expect(firstNode).toBe(container.firstChild);
      expect(firstNode.tagName).toBe('DIV');
    });
Example #25
0
    it('finds the first child even when fragment is nested', () => {
      class Wrapper extends React.Component {
        render() {
          return this.props.children;
        }
      }

      class Fragment extends React.Component {
        render() {
          return [
            <Wrapper><div /></Wrapper>,
            <span />,
          ];
        }
      }

      let instance = null;
      ReactDOM.render(
        <Fragment ref={ref => instance = ref} />,
        container
      );

      expect(container.childNodes.length).toBe(2);

      const firstNode = ReactDOM.findDOMNode(instance);
      expect(firstNode).toBe(container.firstChild);
      expect(firstNode.tagName).toBe('DIV');
    });
    it('must split apart styled spans', () => {
      var helloBlock = getHelloBlock();
      var characters = helloBlock.getCharacterList();
      var newChars = characters.slice(0, 2).map(ch => {
        return CharacterMetadata.applyStyle(ch, 'BOLD');
      }).concat(characters.slice(2));

      helloBlock = helloBlock.set('characterList', Immutable.List(newChars));
      var props = getProps(helloBlock);

      var container = document.createElement('div');
      var block = ReactDOM.render(
        <DraftEditorBlock {...props} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(2);

      var rendered = reactComponentExpect(block)
        .expectRenderedChild()
        .toBeComponentOfType('div');

      let child = rendered.expectRenderedChildAt(0);
      child.toBeComponentOfType(DraftEditorLeaf);
      arePropsEqual(child, {offsetKey: 'a-0-0', styleSet: BOLD});

      child = rendered.expectRenderedChildAt(1);
      child.toBeComponentOfType(DraftEditorLeaf);
      arePropsEqual(child, {offsetKey: 'a-0-1', styleSet: NONE});
    });
    it('must split apart two decorators', () => {
      var helloBlock = getHelloBlock();

      mockGetDecorations.mockReturnValue(
        Immutable.List.of('x', 'x', 'y', 'y', 'y')
      );

      var decorator = new Decorator();
      var props = getProps(helloBlock, decorator);

      var container = document.createElement('div');
      var block = ReactDOM.render(
        <DraftEditorBlock {...props} />,
        container
      );

      expect(mockLeafRender.mock.calls.length).toBe(2);

      var rendered = reactComponentExpect(block)
        .expectRenderedChild()
        .toBeComponentOfType('div');

      rendered
        .expectRenderedChildAt(0)
        .scalarPropsEqual({offsetKey: 'a-0-0'})
        .toBeComponentOfType(DecoratorSpan);

      rendered
        .expectRenderedChildAt(1)
        .scalarPropsEqual({offsetKey: 'a-1-0'})
        .toBeComponentOfType(DecoratorSpan);
    });
Example #28
0
    it('should render nested portals', () => {
      var portalContainer1 = document.createElement('div');
      var portalContainer2 = document.createElement('div');
      var portalContainer3 = document.createElement('div');

      ReactDOM.render([
        <div>normal[0]</div>,
        ReactDOM.unstable_createPortal([
          <div>portal1[0]</div>,
          ReactDOM.unstable_createPortal(
            <div>portal2[0]</div>,
            portalContainer2
          ),
          ReactDOM.unstable_createPortal(
            <div>portal3[0]</div>,
            portalContainer3
          ),
          <div>portal1[1]</div>,
        ], portalContainer1),
        <div>normal[1]</div>,
      ], container);
      expect(portalContainer1.innerHTML).toBe('<div>portal1[0]</div><div>portal1[1]</div>');
      expect(portalContainer2.innerHTML).toBe('<div>portal2[0]</div>');
      expect(portalContainer3.innerHTML).toBe('<div>portal3[0]</div>');
      expect(container.innerHTML).toBe('<div>normal[0]</div><div>normal[1]</div>');

      ReactDOM.unmountComponentAtNode(container);
      expect(portalContainer1.innerHTML).toBe('');
      expect(portalContainer2.innerHTML).toBe('');
      expect(portalContainer3.innerHTML).toBe('');
      expect(container.innerHTML).toBe('');
    });
  beforeEach(() => {
    onReadyStateChange = jest.fn();
    ReactDOM.render(
      <RelayRenderer
        Container={MockContainer}
        queryConfig={queryConfig}
        environment={environment}
        onReadyStateChange={onReadyStateChange}
      />,
      container,
    );
    const defaultState = {
      aborted: false,
      done: false,
      error: null,
      mounted: true,
      ready: false,
      stale: false,
    };
    expect.extend({
      toTriggerReadyStateChanges(requestCallback, expected) {
        const request = environment.primeCache.mock.requests[0];
        requestCallback(request);
        jest.runAllTimers();

        expect(onReadyStateChange.mock.calls.map(args => args[0])).toEqual(
          expected.map(deltaState => ({...defaultState, ...deltaState})),
        );
        return {
          pass: true,
        };
      },
    });
  });
Example #30
0
    it('should bubble events from the portal to the parent', () => {
      var portalContainer = document.createElement('div');

      var ops = [];
      var portal = null;

      ReactDOM.render(
        <div onClick={() => ops.push('parent clicked')}>
          {ReactDOM.unstable_createPortal(
            <div onClick={() => ops.push('portal clicked')} ref={n => portal = n}>
              portal
            </div>,
            portalContainer
          )}
        </div>,
        container
      );

      expect(portal.tagName).toBe('DIV');

      var fakeNativeEvent = {};
      ReactTestUtils.simulateNativeEventOnNode(
        'topClick',
        portal,
        fakeNativeEvent
      );

      expect(ops).toEqual([
        'portal clicked',
        'parent clicked',
      ]);
    });