mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-12-26 01:53:13 +08:00
fix(tests): Clean up after ReactTestUtils, wipe ComponentRegistry between specs
Summary: Why does message-list have default participants? No other packages do Component registry warns if mixin component name not found Clear the component registry between tests and wipe React elements inserted into DOM Everything should have a displayName, even you ComposerView Stub all ComponentRegistry dependencies, always Test Plan: Run all the tests at the same time Reviewers: evan Reviewed By: evan Differential Revision: https://review.inboxapp.com/D1201
This commit is contained in:
parent
b97f607a6e
commit
651f105740
9 changed files with 79 additions and 42 deletions
|
@ -18,6 +18,7 @@ ParticipantsTextField = require './participants-text-field.cjsx'
|
|||
# simulate the effect of the parent re-rendering us
|
||||
module.exports =
|
||||
ComposerView = React.createClass
|
||||
displayName: 'ComposerView'
|
||||
|
||||
getInitialState: ->
|
||||
state = @getComponentRegistryState()
|
||||
|
|
|
@ -29,7 +29,7 @@ textFieldStub = (className) ->
|
|||
focus: ->
|
||||
|
||||
draftStoreProxyStub = (localId) ->
|
||||
listen: -> # noop
|
||||
listen: -> ->
|
||||
draft: -> new Message()
|
||||
changes:
|
||||
add: ->
|
||||
|
|
|
@ -2,8 +2,6 @@ _ = require 'underscore-plus'
|
|||
React = require 'react'
|
||||
MessageItem = require "./message-item.cjsx"
|
||||
|
||||
ThreadParticipants = require "./thread-participants.cjsx"
|
||||
|
||||
{Actions, ThreadStore, MessageStore, ComponentRegistry} = require("inbox-exports")
|
||||
|
||||
module.exports =
|
||||
|
@ -80,13 +78,9 @@ MessageList = React.createClass
|
|||
<div className="message-list-headers">
|
||||
<h2>{@state.current_thread.subject}</h2>
|
||||
|
||||
{if Participants?
|
||||
<Participants clickable={true}
|
||||
context={'primary'}
|
||||
participants={@_threadParticipants()}/>
|
||||
else
|
||||
<ThreadParticipants thread_participants={@_threadParticipants()} />
|
||||
}
|
||||
<Participants clickable={true}
|
||||
context={'primary'}
|
||||
participants={@_threadParticipants()}/>
|
||||
|
||||
{for MessageListHeader in MessageListHeaders
|
||||
<MessageListHeader thread={@state.current_thread} />
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
_ = require 'underscore-plus'
|
||||
React = require "react"
|
||||
|
||||
module.exports =
|
||||
ThreadParticipants = React.createClass
|
||||
displayName: 'ThreadParticipants'
|
||||
|
||||
render: ->
|
||||
<div className="participants thread-participants">
|
||||
{@_formattedParticipants()}
|
||||
</div>
|
||||
|
||||
_formattedParticipants: ->
|
||||
contacts = @props.thread_participants ? []
|
||||
_.map(contacts, (c) -> c.displayName()).join(", ")
|
|
@ -16,6 +16,18 @@ TestUtils = React.addons.TestUtils
|
|||
InboxTestUtils,
|
||||
ComponentRegistry} = require "inbox-exports"
|
||||
|
||||
ComposerItem = React.createClass
|
||||
render: -> <div></div>
|
||||
focus: ->
|
||||
|
||||
AttachmentItem = React.createClass
|
||||
render: -> <div></div>
|
||||
focus: ->
|
||||
|
||||
ParticipantsItem = React.createClass
|
||||
render: -> <div></div>
|
||||
focus: ->
|
||||
|
||||
MessageItem = proxyquire("../lib/message-item.cjsx", {
|
||||
"./email-frame": React.createClass({render: -> <div></div>})
|
||||
})
|
||||
|
@ -24,15 +36,7 @@ MessageList = proxyquire("../lib/message-list.cjsx", {
|
|||
"./message-item.cjsx": MessageItem
|
||||
})
|
||||
|
||||
ComposerItem = React.createClass
|
||||
render: -> <div></div>
|
||||
focus: ->
|
||||
ComponentRegistry.register
|
||||
name: 'Composer'
|
||||
view: ComposerItem
|
||||
|
||||
MessageParticipants = require "../lib/message-participants.cjsx"
|
||||
ThreadParticipants = require "../lib/thread-participants.cjsx"
|
||||
|
||||
me = new Namespace(
|
||||
"name": "User One",
|
||||
|
@ -175,14 +179,22 @@ test_thread = (new Thread).fromJSON({
|
|||
})
|
||||
|
||||
describe "MessageList", ->
|
||||
_resetMessageStore = ->
|
||||
beforeEach ->
|
||||
ComponentRegistry.register
|
||||
name: 'Composer'
|
||||
view: ComposerItem
|
||||
ComponentRegistry.register
|
||||
name: 'Participants'
|
||||
view: ParticipantsItem
|
||||
ComponentRegistry.register
|
||||
name: 'AttachmentComponent'
|
||||
view: AttachmentItem
|
||||
|
||||
MessageStore._items = []
|
||||
MessageStore._threadId = null
|
||||
spyOn(MessageStore, "itemLocalIds").andCallFake ->
|
||||
{"666": "666"}
|
||||
|
||||
beforeEach ->
|
||||
_resetMessageStore()
|
||||
@message_list = TestUtils.renderIntoDocument(<MessageList />)
|
||||
@message_list_node = @message_list.getDOMNode()
|
||||
|
||||
|
@ -218,7 +230,7 @@ describe "MessageList", ->
|
|||
|
||||
it "displays the thread participants on the page", ->
|
||||
items = TestUtils.scryRenderedComponentsWithType(@message_list,
|
||||
ThreadParticipants)
|
||||
ParticipantsItem)
|
||||
expect(items.length).toBe 1
|
||||
|
||||
it "focuses new composers when a draft is added", ->
|
||||
|
|
|
@ -11,7 +11,8 @@ ReactTestUtils = _.extend ReactTestUtils, require("jasmine-react-helpers")
|
|||
ThreadStore,
|
||||
DatabaseStore,
|
||||
InboxTestUtils,
|
||||
NamespaceStore} = require "inbox-exports"
|
||||
NamespaceStore,
|
||||
ComponentRegistry} = require "inbox-exports"
|
||||
|
||||
ThreadListColumn = require("../lib/thread-list-column")
|
||||
|
||||
|
@ -21,6 +22,9 @@ ThreadListNarrowItem = require("../lib/thread-list-narrow-item.cjsx")
|
|||
ThreadListTabular = require("../lib/thread-list-tabular.cjsx")
|
||||
ThreadListTabularItem = require("../lib/thread-list-tabular-item.cjsx")
|
||||
|
||||
ParticipantsItem = React.createClass
|
||||
render: -> <div></div>
|
||||
|
||||
me = new Namespace(
|
||||
"name": "User One",
|
||||
"email": "user1@inboxapp.com"
|
||||
|
@ -218,6 +222,10 @@ describe "ThreadListTabular", ->
|
|||
|
||||
ThreadStore._resetInstanceVars()
|
||||
|
||||
ComponentRegistry.register
|
||||
name: 'Participants'
|
||||
view: ParticipantsItem
|
||||
|
||||
@thread_list = ReactTestUtils.renderIntoDocument(
|
||||
<ThreadListTabular />
|
||||
)
|
||||
|
@ -300,6 +308,10 @@ describe "ThreadListNarrow", ->
|
|||
new Promise (resolve, reject) -> resolve(test_threads())
|
||||
ThreadStore._resetInstanceVars()
|
||||
|
||||
ComponentRegistry.register
|
||||
name: 'Participants'
|
||||
view: ParticipantsItem
|
||||
|
||||
@thread_list = ReactTestUtils.renderIntoDocument(
|
||||
<ThreadListNarrow />
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ Attributes = require '../../src/flux/attributes'
|
|||
{isTempId} = require '../../src/flux/models/utils'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
fdescribe "Model", ->
|
||||
describe "Model", ->
|
||||
describe "constructor", ->
|
||||
it "should accept a hash of attributes and assign them to the new Model", ->
|
||||
attrs =
|
||||
|
|
|
@ -21,6 +21,7 @@ clipboard = require 'clipboard'
|
|||
|
||||
NamespaceStore = require "../src/flux/stores/namespace-store"
|
||||
Contact = require '../src/flux/models/contact'
|
||||
{ComponentRegistry} = require "inbox-exports"
|
||||
|
||||
atom.themes.loadBaseStylesheets()
|
||||
atom.themes.requireStylesheet '../static/jasmine'
|
||||
|
@ -65,8 +66,35 @@ if specDirectory
|
|||
|
||||
isCoreSpec = specDirectory == fs.realpathSync(__dirname)
|
||||
|
||||
# Override React.addons.TestUtils.renderIntoDocument so that
|
||||
# we can remove all the created elements after the test completes.
|
||||
React = require "react/addons"
|
||||
ReactTestUtils = React.addons.TestUtils
|
||||
ReactTestUtils.scryRenderedDOMComponentsWithAttr = (root, attrName, attrValue) ->
|
||||
ReactTestUtils.findAllInRenderedTree root, (inst) ->
|
||||
inst.props[attrName] and (!attrValue or inst.props[attrName] is attrValue)
|
||||
|
||||
ReactTestUtils.findRenderedDOMComponentWithAttr = (root, attrName, attrValue) ->
|
||||
all = ReactTestUtils.scryRenderedDOMComponentsWithAttr(root, attrName, attrValue)
|
||||
if all.length is not 1
|
||||
throw new Error("Did not find exactly one match for data attribute: #{attrName} with value: #{attrValue}")
|
||||
all[0]
|
||||
|
||||
ReactElementContainers = []
|
||||
ReactTestUtils.renderIntoDocument = (element) ->
|
||||
container = document.createElement('div')
|
||||
ReactElementContainers.push(container)
|
||||
React.render(element, container)
|
||||
|
||||
ReactTestUtils.unmountAll = ->
|
||||
for container in ReactElementContainers
|
||||
React.unmountComponentAtNode(container)
|
||||
ReactElementContainers = []
|
||||
|
||||
beforeEach ->
|
||||
Grim.clearDeprecations() if isCoreSpec
|
||||
ComponentRegistry._clear()
|
||||
|
||||
$.fx.off = true
|
||||
documentTitle = null
|
||||
atom.workspace = new Workspace()
|
||||
|
@ -146,6 +174,8 @@ afterEach ->
|
|||
|
||||
$('#jasmine-content').empty() unless window.debugContent
|
||||
|
||||
ReactTestUtils.unmountAll()
|
||||
|
||||
jasmine.unspy(atom, 'saveSync')
|
||||
ensureNoPathSubscriptions()
|
||||
waits(0) # yield to ui thread to make screen update more frequently
|
||||
|
|
|
@ -16,17 +16,20 @@ getViewsByName = (components) ->
|
|||
[registered, requested] = component.split " as "
|
||||
requested ?= registered
|
||||
state[requested] = ComponentRegistry.findViewByName registered
|
||||
if not state[requested]?
|
||||
console.log("""Warning: No component found for #{requested} in
|
||||
#{@constructor.displayName}. Loaded: #{Object.keys(registry)}""")
|
||||
state
|
||||
|
||||
Mixin =
|
||||
getInitialState: ->
|
||||
getViewsByName(@components)
|
||||
getViewsByName.apply(@, [@components])
|
||||
|
||||
componentWillMount: ->
|
||||
@_componentUnlistener = ComponentRegistry.listen (event) =>
|
||||
@_componentUnlistener = ComponentRegistry.listen =>
|
||||
@setState getViewsByName(@components)
|
||||
|
||||
componentDidUnmount: ->
|
||||
componentWillUnmount: ->
|
||||
@_componentUnlistener()
|
||||
|
||||
# Internal representation of components
|
||||
|
|
Loading…
Reference in a new issue