It seems problematic to allow arbitary non-lowercase attribute on HTML nodes. Because the server has no ability to keep them case sensitive (HTML isn't). So they will end up different on the client.

We should probably warn if the attribute is not a known one *and* is not lowercase.
var nodeValueSetter = jest.fn();
      Object.defineProperty(node, 'checked', {
        get: function() {
          return nodeValue;
        },
        set: nodeValueSetter.mockImplementation(function(newValue) {
          nodeValue = newValue;
        }),
      });
      ReactDOM.render(<div checked={true} />, container);
      expect(nodeValueSetter.mock.calls.length).toBe(0);
      ReactDOM.render(<div />, container);
      expect(nodeValueSetter.mock.calls.length).toBe(1);
      ReactDOM.render(<div checked={false} />, container);
      expect(nodeValueSetter.mock.calls.length).toBe(2);
      ReactDOM.render(<div checked={true} />, container);
      expect(nodeValueSetter.mock.calls.length).toBe(3);
    });
    it('should ignore attribute whitelist for elements with the "is" attribute', () => {
      var container = document.createElement('div');
      ReactDOM.render(<button is="test" cowabunga="chevynova" />, container);
      expect(container.firstChild.hasAttribute('cowabunga')).toBe(true);
    });
    it('should warn about non-string "is" attribute', () => {
      spyOn(console, 'error');
      var container = document.createElement('div');
      ReactDOM.render(<button is={function() {}} />, container);
      expectDev(console.error.calls.count()).toBe(1);
      expectDev(console.error.calls.argsFor(0)[0]).toContain(
        'Received a `function` for string attribute `is`. If this is expected, cast ' +