This react library converts plain text tweets into real tweets. The library is responsible for parsing the tweets and handles transform mention (@monAmiTweetos), hashtags (#RTplz) and URLs inserted in the tweet in functional URLs. This library was created based on jquery-tweet-parser

Install react-tweet-parser

npm install react-tweet-parser --save

Import TweetParser

import TweetParser from 'react-tweet-parser';

Properties 

  1. urlClass - CSS class for URL
  2. userClass - CSS class for user links
  3. hashtagClass - CSS class for twitter user links
  4. target - link target attribute value (exp : _blank)
  5. searchWithHashtags - It will give q parameter 
  6. parseUsers - Parser users boolean flag 
  7. parseUrls - Parse urls boolean flag
  8. parseHashtags - Parse hashtags boolean flag

Usage

Use TweetParser component like below
<TweetParser
         urlClass = {"myUrlClass"}
         userClass = {"myUserClass"}
        >plain tweet text</TweetParser>

Read More
By including this component, you can create GIF preview like facebook.  Lets see how to use this library.

GIF images consists of many frames, so size of GIF image is more as compared to normal image. Its not recommended to load GIF images first and its better to maintain one normal preview image for every GIF image. You can use first frame of GIF image as preview image. Click here to see my on-line tool for generating first frame of GIF image

Concept

Click here to read concept of GIF Preview  

Using npm

npm install react-gif-preview --save

Import Tubular component and styles

import gifStyles from '../../node_modules/react-gif-preview/lib/react-gif-preview.css';
import GifPreview from 'react-gif-preview';

Usage

Here we have 2 properties src, gifSrc. Pass Preview image URL as src parameter and pass GIF image URL as gifSrc parameter. 
<GifPreview src="...sample_first_frame.png"  gifSrc="...sample_giphy.gif"/>
Read More
You can share GIF images by using URL directly, but its not possible to share blog post with GIF preview on facebook. Here I will give a trick to share GIF image from your blog post on facebook.
Lets take an example.

GIF image

Observe below GIF Image. This GIF image cannot be shared on facebook by sharing this article. We should provide another preview image for this GIF image. 

Providing Preview Image

Click here to create Facebook Style GIF Preview Image - Online. Download the image as shown in that tool and upload to your blog post.

When you share this article on facebook, you will see above preview image. User thinks it is GIF image, once user clicks on it it will redirect to your blog.

Sharing through page

If you are sharing blog posts through Facebook page, you can directly upload preview image over there. 
Click on plus icon and upload above GIF preview image.  
Read More
By including this component, you can make youtube video as HTML page background. This is created based jquery-tubular plugin. Lets see how to use this library.

Using npm

npm install react-tubular --save

Import Tubular component

import Tubular from 'react-tubular';

Usage

Here you can pass ration, youtube video id, mute, repeat, width, z-index of the wrapper, volume increase or decrease range, video starting point.
<Tubular
    ratio = {16/9} // usually either 4/3 or 16/9 -- tweak as needed
    videoId = {'ZCAnLxRvNNc'} // toy robot in space is a good default, no?
    mute = {true}
    repeat = {true}
    width = {window.innerWidth}
    wrapperZIndex = { -1 }
    increaseVolumeBy = { 10 }
    start = { 0 }
    ref={(ref)=>{this.tubular = ref}}/>

Functions

Tubular component provides some functions, which we can call by using ref. Observe below example which calls playVideo, pauseVideo, mute, decreaseVolume, increaseVolume functions
import React from 'react';
import Tubular from 'react-tubular';

export default class App extends React.Component {

  constructor(props) {
    super(props);
    this.playVideo = this.playVideo.bind(this);
    this.pauseVideo = this.pauseVideo.bind(this);
    this.mute = this.mute.bind(this);
    this.decreaseVolume = this.decreaseVolume.bind(this);
    this.increaseVolume = this.increaseVolume.bind(this);
  }

  playVideo() {
    this.tubular.playVideo();
  }

  pauseVideo() {
    this.tubular.pauseVideo();
  }

  mute() {
    this.tubular.mute();
  }

  decreaseVolume() {
    this.tubular.decreaseVolume();
  }

  increaseVolume() {
    this.tubular.increaseVolume();
  }

  render() {
    return (
      <div>
        <h1>It Works </h1>
        <p>This React project just works with react-tubular</p>
        <h2>Actions</h2>

        <button onClick={this.playVideo}>Play video</button>
        <button onClick={this.pauseVideo}>Pause video</button>
        <button onClick={this.mute}>Mute video</button>
        <button onClick={this.decreaseVolume}>Decrease Volume</button>
        <button onClick={this.increaseVolume}>Increase Volume</button>

        <Tubular
            ratio = {16/9} // usually either 4/3 or 16/9 -- tweak as needed
            videoId = {'ZCAnLxRvNNc'} // toy robot in space is a good default, no?
            mute = {true}
            repeat = {true}
            width = {window.innerWidth}
            wrapperZIndex = { -1 }
            increaseVolumeBy = { 10 }
            start = { 0 }
            ref={(ref)=>{this.tubular = ref}}/>

      </div>
    )
  }
}
Read More
This is the child article of ReactTestUtils - Tutorial. In this article, I will explain how to write test cases for React-Redux apps.

Redux apps maintains common state for all components, so one component state might be depend on action in other component. So you should better test whole application with Provider and Store than testing each and every component.

Example

Lets take a Todo example.  You can find source of this example here

Testing Flow

  1. Enter test 'Sample task' in input field
  2. Click enter
  3. Check Todo Item is added or not
  4. Click on check box of that Todo Item
  5. Check whether todo task is completed or not

Setup 

Create store using reducers. Render the App component with Provider and store. This is basic setup to test Redux applications.
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import expect from 'expect';
import reducer from '../reducers'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from '../containers/App'

const store = createStore(reducer)

describe('root', function () {

  it('renders without problems', function () {
    var root = TestUtils.renderIntoDocument(<Provider store={store}>
      <App />
    </Provider>);
    expect(root).toExist();
  });

});

Test Flow

The above described test flow can be found below. 
it('Todo lifecycle test', function () {
    var root = TestUtils.renderIntoDocument(<Provider store={store}>
      <App/>
    </Provider>);
    var compArr = TestUtils.findRenderedComponentWithType(root, TodoTextInput);

    // change input text value
    var inputElm = TestUtils.findRenderedDOMComponentWithTag(compArr, 'input');
    inputElm.value = 'some task';
    TestUtils.Simulate.change(inputElm);

    // press enter
    TestUtils.Simulate.keyDown(inputElm, {which : 13});

    // find ToDo Items and verify the value
    var todoItems = TestUtils.scryRenderedComponentsWithType(root, TodoItem);
    expect(todoItems[0].props.todo.text).toEqual('some task');

    // check the todo item
    var checkbox = TestUtils.findRenderedDOMComponentWithTag(todoItems[0], 'input');
    checkbox.checked = true;
    TestUtils.Simulate.change(checkbox);

    // check todo completion
    expect(todoItems[0].props.todo.completed).toEqual(true);
});
Read More
This is the child article of ReactTestUtils - Tutorial. In this article, I will explain how to Verify Function Calls with examples.

Example

Here we pass clickFunc and dblClickFunc as properties, now we have to check whether these functions were called or not.
import React from 'react';

class FuncComponent  extends React.Component {

    constructor(props) {
        super(props);
        this.dblClickEventFunc = this.dblClickEventFunc.bind(this);
    }

    dblClickEventFunc() {
        this.props.dblClickFunc('this is some sample arg value');
    }

    render () {
   return <div>
      <div id="clickEventDiv" onClick={this.props.clickFunc}>
      </div>
      <div id="dblClickEventDiv" onDoubleClick={this.dblClickEventFunc}>
      </div>
    </div>;
    }

}

FuncComponent.propTypes = {
  clickFunc:React.PropTypes.func,
  dblClickFunc:React.PropTypes.func
}

FuncComponent.defaultProps = {

}

export default FuncComponent;

Verify Function Call

Here done callback has to be called at end of the test.  Whenever you simulate the click event, clickFunction will be called. clickFunction will call done callback function, so the test will end with success message 
it('function call on click test', (done) => {
    let clickFunction = () => {
      done();
    };
    let instance = ReactTestUtils.renderIntoDocument(
      <FuncComponent clickFunc={clickFunction}/>
    );
    let clickDiv = scryRenderedDOMComponentsWithId(instance, "clickEventDiv");
    ReactTestUtils.Simulate.click(clickDiv[0]);
});

Verify Function Argument

Whenever you simulate double click event,  dblClickFunction will be called with argument. Here we are checking that argument value in dblClickFunction, then calling done callback function.
it('function argument verification on double click test', (done) => {
    let dblClickFunction = (arg) => {
      expect(arg).toEqual('this is some sample arg value');
      done();
    };
    let instance = ReactTestUtils.renderIntoDocument(
      <FuncComponent dblClickFunc={dblClickFunction}/>
    );
    let clickDiv = scryRenderedDOMComponentsWithId(instance, "dblClickEventDiv");
    ReactTestUtils.Simulate.doubleClick(clickDiv[0]);
});
Read More
This is the child article of ReactTestUtils - Tutorial. In this article, I will explain how to Check Class Name and Tag with examples.

Example

In this example state, properties defined. Input field is having myInput class
import React from 'react';
import SubRoot from './sub-root'

class Root extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      name: 'sample name'
    };
  }

  render() {
    return (
      <div>
        <h1>Hello World!!</h1>

        <p>
          Please input your name here:
          <input className="myInput"
            onChange={this.handleChange}
            value={this.state.name}
          />
        </p>
        <SubRoot/>
        <p>Hello, {this.state.name} </p>
      </div>
    );
  }

  handleChange(e) {
    var newName = e.target.value();

    this.setState({
      name: newName
    });
  }
}

export default Root;

Verify Class name

Get className property of the element.
it('check className', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    var inputElm = TestUtils.findRenderedDOMComponentWithClass(root, 'myInput');
    expect(inputElm.className.match(/\bmyInput\b/)).toExist();
});

Verify Property Value 

Get props of the element
it('check properties', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    var subRoot = TestUtils.findRenderedComponentWithType(root, SubRoot);
    expect(subRoot.props.myProp).toEqual("my prop value");
});

Verify State Value

Get state of the element
it('check state', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    var rootElm = TestUtils.findRenderedComponentWithType(root, Root);
    expect(rootElm.state.name).toEqual("sample name");
});
Read More
This is the child article of ReactTestUtils - Tutorial. In this article, I will explain how to Check Component or Element Type. Here we can verify

Verify DOM Component

General HTML components are DOM Components. It can be verified with isDOMComponent function. Below example finds element with h1 tag. isDOMComponent function returns true 
it('Verify Dom Component', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    var rootElm = TestUtils.findRenderedDOMComponentWithTag(root, 'h1');
    expect(TestUtils.isElement(rootElm)).toEqual(false);
    expect(TestUtils.isDOMComponent(rootElm)).toEqual(true);
    expect(TestUtils.isCompositeComponent(rootElm)).toEqual(false);
});

Verify Composite Component

User defined React element is Composite component. Here SubRoot is user defined React element, It can be verified using isCompositeComponent
it('Verify Composite Type', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    var rootElm = TestUtils.findRenderedComponentWithType(root, SubRoot);

    expect(TestUtils.isElement(rootElm)).toEqual(false);
    expect(TestUtils.isDOMComponent(rootElm)).toEqual(false);

    expect(TestUtils.isCompositeComponent(rootElm)).toEqual(true);
    expect(TestUtils.isCompositeComponentWithType(rootElm, SubRoot)).toEqual(true);
});

Read More
This is the child article of ReactTestUtils - Tutorial. In this article, I will explain how to find element with examples.

Example

This is sample example.
import React from 'react';
import SubRoot from './sub-root'

class Root extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      name: ''
    };
  }

  render() {
    return (
      <div>
        <h1>Hello World!!</h1>

        <p>
          Please input your name here:
          <input className="myInput"
            onChange={this.handleChange}
            value={this.state.name}
          />
        </p>
        <SubRoot/>
        <p>Hello, {this.state.name} </p>
      </div>
    );
  }

  handleChange(e) {
    var newName = e.target.value();

    this.setState({
      name: newName
    });
  }
}

export default Root;

By Tag

scryRenderedDOMComponentsWithTag 

Finds all DOM elements of components in the rendered tree that are DOM components with the tag name matching tagName.

findRenderedDOMComponentWithTag

Like scryRenderedDOMComponentsWithTag but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one.
it('find element with tag', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    // scryRenderedDOMComponentsWithTag
    var spanElm = TestUtils.scryRenderedDOMComponentsWithTag(root, 'span');
    expect(spanElm.length).toEqual(0);
    var h1Elm = TestUtils.scryRenderedDOMComponentsWithTag(root, 'h1');
    expect(h1Elm.length).toEqual(1);
    // findRenderedDOMComponentWithTag
    var h1Elm = TestUtils.findRenderedDOMComponentWithTag(root, 'h1');
    expect(h1Elm).toExist();
});

By Class

scryRenderedDOMComponentsWithClass

Finds all DOM elements of components in the rendered tree that are DOM components with the class name matching className.

findRenderedDOMComponentWithClass

Like scryRenderedDOMComponentsWithClass() but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one.
it('find element with class', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    // scryRenderedDOMComponentsWithClass
    var inputElmArr = TestUtils.scryRenderedDOMComponentsWithClass(root, 'myInput');
    expect(inputElmArr.length).toEqual(1);
    // findRenderedDOMComponentsWithClass
    var inputElm = TestUtils.findRenderedDOMComponentWithClass(root, 'myInput');
    expect(inputElm).toExist();
});

By Component

scryRenderedComponentsWithType

Finds all instances of components with type equal to componentClass.

findRenderedComponentWithType

Same as scryRenderedComponentsWithType() but expects there to be one result and returns that one result, or throws exception if there is any other number of matches besides one.
it('find element by Component', function () {
it('find element by Component', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    // scryRenderedComponentsWithType
    var compArr = TestUtils.scryRenderedComponentsWithType(root, SubRoot);
    expect(compArr.length).toEqual(1);
    // findRenderedComponentsWithType
    var comp = TestUtils.findRenderedComponentWithType(root, SubRoot);
    expect(comp).toExist();
});

By Id

There is no function to get React element by Id. We can use findAllInRenderedTree to Component by Id. 
function scryRenderedDOMComponentsWithId(tree, id) {
  return TestUtils.findAllInRenderedTree(tree, function(inst) {
    return TestUtils.isDOMComponent(inst) && inst.id === id;
  });
}
Read More
This is the child article of ReactTestUtils - Tutorial. In this article, I will explain how to Simulate events - Click, Change, Key Up, Mouse Over etc.

Example

Observe below example component. This component handles click,  double click, mouse over, change events.
import React from 'react';

class EventComponent  extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            clickClass:'',
            dblClickClass:'',
            mouseOverEventClass:'',
            inputVal:''
        }
        this.clickEventFunc = this.clickEventFunc.bind(this);
        this.dblClickEventFunc = this.dblClickEventFunc.bind(this);
        this.onChange = this.onChange.bind(this);
        this.mouseOverEventFunc = this.mouseOverEventFunc.bind(this);
    }

    clickEventFunc() {
        this.setState({
            clickClass:'click-class'
        });
    }

    dblClickEventFunc() {
        this.setState({
            dblClickClass:'dblclick-class'
        });
    }

    mouseOverEventFunc() {
        this.setState({
            mouseOverEventClass:'mouseover-class'
        });
    }

    onChange(event) {
        this.setState({
            inputVal:event.target.value
        });
    }

    render () {
        return <div>
      <div id="clickEventDiv" className={this.state.clickClass} onClick={this.clickEventFunc}>
      </div>
      <div id="dblClickEventDiv" className={this.state.dblClickClass} onDoubleClick={this.dblClickEventFunc}>
      </div>
      <div id="mouseOverEventDiv" className={this.state.mouseOverEventClass} onMouseOver={this.mouseOverEventFunc}>
      </div>
            <input id="inputElm" value={this.state.inputVal} onChange={this.onChange}></input>
    </div>;
    }

}

EventComponent.propTypes = {

}

EventComponent.defaultProps = {

}

export default EventComponent;

Find Component by ID

This is small utility function which we use to find element by Id
function scryRenderedDOMComponentsWithId(tree, id) {
  return ReactTestUtils.findAllInRenderedTree(tree, function(inst) {
    return ReactTestUtils.isDOMComponent(inst) && inst.id === id;
  });
}

Click Event

When we click on the clickEventDiv component, click-class will be added. This test case verifies the class
it('click event test', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <EventComponent/>
    );
    let clickDiv = scryRenderedDOMComponentsWithId(instance, "clickEventDiv");
    ReactTestUtils.Simulate.click(clickDiv[0]);
    expect(clickDiv[0].className.match(/\bclick-class\b/)).toExist();
});

Double Click Event

When we double click on the dbClickEventDiv component, dblclick-class will be added. This test case verifies the class
  it('double click event test', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <EventComponent/>
    );
    let dbClickDiv = scryRenderedDOMComponentsWithId(instance, "dblClickEventDiv");
    ReactTestUtils.Simulate.doubleClick(dbClickDiv[0]);
    expect(dbClickDiv[0].className.match(/\bdblclick-class\b/)).toExist();
});

Mouse Over Event

When we double click on the mouseOverEventDiv component, mouseover-class will be added. This test case verifies the class
it('mouser over event test', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <EventComponent/>
    );
    let mOverDiv = scryRenderedDOMComponentsWithId(instance, "mouseOverEventDiv");
    ReactTestUtils.Simulate.mouseOver(mOverDiv[0]);
    expect(mOverDiv[0].className.match(/\bmouseover-class\b/)).toExist();
});

Change Event

When we change the input value of inputElm component, inputVal state variable changes. This test case verifies the state variable
it('change event test', () => {
    let instance = ReactTestUtils.renderIntoDocument(
      <EventComponent/>
    );
    let inputElm = scryRenderedDOMComponentsWithId(instance, "inputElm");
    inputElm[0].value = 'some value';
    ReactTestUtils.Simulate.change(inputElm[0]);
    expect(instance.state.inputVal).toEqual("some value");
});
Read More
Initially I thought Enzyme is the better alternative for React test utils, But I am wrong. While testing react application with enzyme, I got so many issues.

Issues I faced

  1. Enzyme not able to wrapper which renders the out of that wrapper (Ex. React modal dialog and popover ). Discussion link - https://github.com/airbnb/enzyme/issues/252
  2. Testing redux apps with Enzyme giving me many errors. Rending Redux component with multiple children redux components is not working as expected. Redux team also getting these issues. Discussion link - https://github.com/reactjs/redux/issues/1481
  3. Javascript functions like new Blob() is failing in Enzyme
Finally I back to React test utils. 

Setup

I have done setup with webpack and karma. You can find project repository on Github.  Clone it and test it. 
git clone https://github.com/SodhanaLibrary/react-test-utils-examples.git
npm install
npm test

Writing First Unit Test Case

Import TestUtils from react-addons-test-utils
import React from 'react';
import TestUtils from 'react-addons-test-utils';
import expect from 'expect';
import Root from '../root';

describe('root', function () {
  it('renders without problems', function () {
    var root = TestUtils.renderIntoDocument(<Root/>);
    expect(root).toExist();
  });
});

Render Component

There are 2 types of rendering 
  1. Rendering into document. This requires DOM
  2. Shallow rendering. This doesn't require DOM  

renderIntoDocument

Pass React component to renderIntoDocument function 
var root = TestUtils.renderIntoDocument(<Root/>);
expect(root).toExist();

Shallow Render

This type of rendering will render one level deep
var shallowRenderer = TestUtils.createRenderer();
shallowRenderer.render(<Root/>);
expect(shallowRenderer.getRenderOutput()).toExist();

Tutorials

Find below tutorials with examples
  1. Find Element By Component, Class, Tag, Id - Click here
  2. Check Class Name, Properties and State - Click here
  3. Check Component or Element Type - Click here
  4. Simulate events - Click, Change, Mouse Over etc - Click here
  5. Verify Function Calls - Click here
  6. Redux apps test cases - Click here
Read More
I just went to google trends and just compared these three JS libraries and the results are stunning. AngularJS and ReactJS gaining momentum over jQuery. When is the last time you worked on jQuery ?. I worked on jQuery project almost 2 years back. From last 2 years, I am working with Angular and React.

Google Trends

Google trends comparison among AngularJS, React, jQuery

Reddit Subscribers

Reddit is similar minded peoples network. Lets see how many subscribers for each JS framework (library)
Angular2 - 5798 subscribers
AngularJS - 18,187 subscribers
ReactJS - 16,380 subscribers
jQuery - 15,320 subscribers
ReactJS and AngularJS are having more followers than jQuery.

Why jQuery losing ?

Now trend is moving towards single page web applications, hybrid apps. jQuery is not good for both. AngularJS and ReactJS gives good performance for  single page web applications, hybrid apps. Building feature in jQuery really takes more time than building in React or Angular. 
For example, take scenario Search JSON Data functionality. I have implemented this functionality in both jQuery and AngularJS
In both examples, lines of jQuery code is almost 3 times more than Angular code. Its clear that it will eat developers time. 

Conclusion

Its better invest some time in learning ReactJS and AngularJS. jQuery always great. After learning javascript, its better to learn jQuery then learn Angular and React. Front-end developer with React and Angular experience adds much value to resume. 
Read More

Blogroll

Follow this blog by Email

Popular Posts