From 784f1ab1bf284c5a5444f8174ce4d325a385eab3 Mon Sep 17 00:00:00 2001 From: jquense Date: Sun, 20 Dec 2015 20:24:43 -0500 Subject: [PATCH] [added] state(), prop(), and context() methods --- src/element.js | 21 ++++++++++++++++++- src/instance.js | 35 +++++++++++++++++++++++++++++--- test/shallow.js | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 4 deletions(-) diff --git a/src/element.js b/src/element.js index 9ba04c3..cabaf10 100644 --- a/src/element.js +++ b/src/element.js @@ -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'; @@ -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); @@ -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 + }, } }) diff --git a/src/instance.js b/src/instance.js index e835749..4f2d652 100644 --- a/src/instance.js +++ b/src/instance.js @@ -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'; @@ -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; @@ -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'; @@ -78,7 +107,7 @@ Object.assign($.fn, { .filter(selector) }, - trigger(event, data){ + trigger(event, data) { data = data || {} if (event.substr(0, 2) === 'on' ) diff --git a/test/shallow.js b/test/shallow.js index c5fc707..42c5472 100644 --- a/test/shallow.js +++ b/test/shallow.js @@ -85,6 +85,22 @@ describe('Shallow rendering', ()=> { instance.children().length.should.equal(3) }) + it('should get props', ()=>{ + let counter = $() + + counter.shallowRender().prop('className').should.equal(0) + }) + + it('should get state', ()=>{ + let counter = $() + + counter.shallowRender().state().should.eql({ + count: 0 + }); + + counter.shallowRender().state('count').should.equal(0) + }) + it('should maintain state between renders', ()=>{ let counter = $() @@ -93,6 +109,44 @@ describe('Shallow rendering', ()=> { counter.shallowRender().context.props.className.should.equal(1) }) + it('should update', ()=>{ + let 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 = $().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 ( +
+ this.setState({ called: true })} /> +
+ ) + } + }) + + let root = $().shallowRender(); + + root.find('span').trigger('click') + count.should.equal(1) + root.state().should.eql({ called: true }) + }) + describe('querying', ()=> { let FancyList = props =>
    {props.children}
let List = ()=> (