Skip to content
This repository has been archived by the owner on Sep 20, 2018. It is now read-only.

Commit

Permalink
[added] state(), prop(), and context() methods
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed Dec 21, 2015
1 parent a9a2e50 commit 784f1ab
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 4 deletions.
21 changes: 20 additions & 1 deletion src/element.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { isValidElement, cloneElement } from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from'react-addons-test-utils';
import warning from 'warning';
import createQueryCollection from './QueryCollection';
import iQuery from './instance'
import * as utils from './utils';
Expand Down Expand Up @@ -84,6 +85,11 @@ Object.assign(eQuery.fn, {

if (!this.renderer)
this.renderer = ReactTestUtils.createRenderer()
else {
warning(renderWarned,
'Calling `shallowRender` to update a collection is deprecated, use `update()` instead')
renderWarned = true;
}

this.renderer.render(element);

Expand All @@ -107,12 +113,25 @@ Object.assign(eQuery.fn, {
.filter(selector)
},

text(){
text() {
let isText = el => typeof el === 'string';

return this.get().reduce((str, element)=> {
return str + utils.traverse(element, isText).join('')
}, '')
},

prop(key) {
return key ? this[0].props[key] : this[0].props;
},

state(key) {
assertRoot(this, 'Only "root" rendered elements can have state')

let state = this._instance().state;

return key && state ? state[key] : state
},
}

})
Expand Down
35 changes: 32 additions & 3 deletions src/instance.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ReactUpdateQueue from 'react/lib/ReactUpdateQueue';
import ReactInstanceMap from 'react/lib/ReactInstanceMap';
import ReactTestUtils from'react-addons-test-utils';

Expand Down Expand Up @@ -44,7 +45,7 @@ Object.assign($.fn, {
return $(this._subjects().reduce(cb, initial), this)
},

unmount(){
unmount() {
let inBody = this._mountPoint.parentNode
, nextContext = this.context._currentElement;

Expand All @@ -58,10 +59,38 @@ Object.assign($.fn, {
return eQuery(nextContext)
},

dom(){
dom() {
return unwrap(this._map($.dom))
},

element() {
return eQuery(this._subjects().map(
inst => React.cloneElement(inst._currentElement)))
},

prop(key, value, cb) {
if (typeof key === 'string') {
if (arguments.length === 1)
return this._privateInstances[0].props[key];
else
key = { [key]: value }
}

this._subjects(inst => {
ReactUpdateQueue.enqueueSetPropsInternal(inst, props)
if (cb)
ReactUpdateQueue.enqueueCallbackInternal(inst, cb)
})
},

state(key) {
return this._privateInstances[0].state[key];
},

context(key) {
return this._privateInstances[0].context[key];
},

text(){
let isText = el => typeof el === 'string';

Expand All @@ -78,7 +107,7 @@ Object.assign($.fn, {
.filter(selector)
},

trigger(event, data){
trigger(event, data) {
data = data || {}

if (event.substr(0, 2) === 'on' )
Expand Down
54 changes: 54 additions & 0 deletions test/shallow.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ describe('Shallow rendering', ()=> {
instance.children().length.should.equal(3)
})

it('should get props', ()=>{
let counter = $(<Counter/>)

counter.shallowRender().prop('className').should.equal(0)
})

it('should get state', ()=>{
let counter = $(<Counter/>)

counter.shallowRender().state().should.eql({
count: 0
});

counter.shallowRender().state('count').should.equal(0)
})

it('should maintain state between renders', ()=>{
let counter = $(<Counter/>)

Expand All @@ -93,6 +109,44 @@ describe('Shallow rendering', ()=> {
counter.shallowRender().context.props.className.should.equal(1)
})

it('should update', ()=>{
let counter = $(<Counter/>).shallowRender()

counter.prop('className').should.equal(0)
counterRef.increment()
counter.update()
counter.prop('className').should.equal(1)
})

it('should throw when updating none root elements', ()=> {
let counter = $(<List/>).shallowRender()

;(() => counter.find('ul').update())
.should.throw('You can only preform this action on a "root" element.')
})

it('should update root collections', ()=> {
let count = 0;
let Component = React.createClass({
componentDidUpdate(){
count++
},
render() {
return (
<div>
<span onClick={() => this.setState({ called: true })} />
</div>
)
}
})

let root = $(<Component />).shallowRender();

root.find('span').trigger('click')
count.should.equal(1)
root.state().should.eql({ called: true })
})

describe('querying', ()=> {
let FancyList = props => <ul className='fancy-list'>{props.children}</ul>
let List = ()=> (
Expand Down

0 comments on commit 784f1ab

Please sign in to comment.