Skip to content

Community Middleware

Nick Stefan edited this page Jan 18, 2016 · 11 revisions
  1. TestMethod
  2. findSelector
  3. findComponent

Setting up your legit tests to always use certain middleware is easy:

import TestUtils from 'legit-tests/no-dom';

import {TestMethod} from '../custom/middleware';

function Test(component, options={}){
    return TestUtils(component, options)
    .mixin({
        TestMethod
    });
}

export default Test;
export { Test };

###TestMethod Call and test React methods

  • .testMethod('myMethod', function(myMethod){ ... })
  • .testMethod('getInitialState', function(getInitialState){ ... })

The method is passed to the callback already bound to the component instance.

.testMethod('myMethod', function(myMethod){ 
    expect( myMethod() ).to.be('returned value'); 
})

src:

import _ from 'lodash';
function TestMethod(methodName, fn){
    var bound = _.bind(this.component.type.prototype[methodName], this.component);
    fn(bound);
}

###findSelector

it('should be able to use CSS selectors!', function(){
  Test(<ComponentVideo data={data}/>)
  .findSelector('span#bob.single-theater-container[data-bob-thing]')
  .test(function(){
    expect(this.elements['span#bob.single-theater-container[data-bob-thing]']).to.be.ok;
  });
});
/*
 * For now only handles things like:
 *     'span#bob.single-theater-container[data-bob-thing]'
 * CANNOT handle
 *     'span#bob .single-theater-container[data-bob-thing]'
 * CANNOT handle
 *     'span#bob > .single-theater-container[data-bob-thing]'
 */

import * as ReactTestUtils from 'react-addons-test-utils';
import _ from 'lodash';

function findSelector(selector, fn){
    var self = this;
    var foundElements = [];
    var tokens = selector.split(/(?=\.)|(?=#)|(?=\[)/);

    tokens
    .forEach(function(subselector, key, collection){
        var els;
        switch (subselector[0]){
            // class
            case '.':
                els = ReactTestUtils.scryRenderedDOMComponentsWithClass(self.instance, subselector.slice(1));
                foundElements.push( Array.isArray(els) ? els : [els] );
                break;

            // id
            case '#':
                els = ReactTestUtils.findAllInRenderedTree(self.instance, function(component){
                    if (component.id === subselector.slice(1)){
                        return true;
                    }
                });
                foundElements.push( Array.isArray(els) ? els : [els] );
                break;

            // data attribute
            case '[':
                els = ReactTestUtils.findAllInRenderedTree(self.instance, function(component){
                    if (component.getAttribute) {
                        return component.getAttribute(subselector.slice(1,-1));
                    }
                });
                foundElements.push( Array.isArray(els) ? els : [els] );
                break;

            // tag
            default:
                els = ReactTestUtils.scryRenderedDOMComponentsWithTag(self.instance, subselector);
                foundElements.push( Array.isArray(els) ? els : [els] );
                break;
        }
    });

    var elements = _.intersection.apply(_, foundElements);

    if (Array.isArray(elements) && elements.length === 1) {
        this.elements[selector] = elements[0];
    } else {
        this.elements[selector] = elements;
    }
}

###findComponent

Usage

            Test(<ComponentPage data={data} />)
            .findComponent(ComponentForm)
            .test(function(){
                var state = this.components['ComponentForm'][0].state;
                expect(state).to.equal({stuff: 'stuff'});
            });

Source

function findComponent(component){
    this.components = this.components || {};
    this.components[ component.displayName ] = ReactTestUtils.scryRenderedComponentsWithType(this.instance, component);
}
Clone this wiki locally