UNPKG

6.82 kBJavaScriptView Raw
1/* eslint-disable no-undef */
2
3import React from 'react'
4import ReactWrapper from 'enzyme/build/ReactWrapper'
5import { createWaitForElement } from '@oskarer/enzyme-wait'
6import Enzyme, { mount } from 'enzyme'
7import Adapter from 'enzyme-adapter-react-16'
8import TestRenderer from 'react-test-renderer'
9import isArray from 'lodash/isArray'
10
11const DEPRECATED = process.env.DEPRECATED
12
13init()
14
15function init () {
16 Enzyme.configure({ adapter: new Adapter() })
17
18 ReactWrapper.prototype.waitFor = function (selector) {
19 return createWaitForElement(selector)(this)
20 }
21}
22
23export function unmount () {
24 if (globalEnzymeNode && globalEnzymeNode.unmount) {
25 globalEnzymeNode.unmount()
26 globalEnzymeNode = undefined
27 }
28 if (globalTestRenderer && globalTestRenderer.unmount) {
29 globalTestRenderer.unmount()
30 globalTestRenderer = undefined
31 }
32}
33
34export function convertToOldSubscribeParams (fn) {
35 return (...args) => {
36 let data = fn(...args)
37 let res = {}
38 for (let key in data) {
39 if (data[key] == null) continue
40 if (data[key].__subscriptionType) {
41 res[key] = data[key].params
42 } else {
43 throw new Error('No __subscriptionType specified')
44 }
45 }
46 return res
47 }
48}
49
50export function convertToHooksSubscribeParams (fn) {
51 return (...args) => {
52 let { items: { __subscriptionType: type, params } } = fn(...args)
53 let useFn
54 switch (type) {
55 case 'Doc':
56 useFn = useDoc
57 break
58 case 'Query':
59 case 'QueryExtra':
60 useFn = useQuery
61 break
62 case 'Local':
63 useFn = useLocal
64 break
65 case 'Value':
66 useFn = useValue
67 break
68 case 'Api':
69 useFn = useApi
70 break
71 default:
72 throw new Error('Unknown useFn type: ' + type)
73 }
74 if (!isArray(params)) params = [params]
75 return useFn(...params)
76 }
77}
78
79export async function initSimple (initialProps, subscribeFn) {
80 if (typeof initialProps === 'function') {
81 subscribeFn = initialProps
82 initialProps = {}
83 }
84 if (DEPRECATED) subscribeFn = convertToOldSubscribeParams(subscribeFn)
85 let Subscribed = subscribe(subscribeFn)(Simple())
86 let w = mount(<Subscribed {...initialProps} />)
87 globalEnzymeNode = w
88 await w.waitFor('.Simple')
89 w.getItems = function () {
90 return getSimpleItems(this)
91 }
92 Object.defineProperty(w, 'items', {
93 get: function () {
94 return this.getItems()
95 }
96 })
97 w.nextRender = function (...args) {
98 return nextRender(this, ...args)
99 }
100 return w
101}
102
103export function getSimpleItems (w) {
104 let text = w.find('.Simple').text()
105 if (!text) return []
106 return text.split(',')
107}
108
109export async function initComplex (initialProps, subscribeFn) {
110 if (typeof initialProps === 'function') {
111 subscribeFn = initialProps
112 initialProps = {}
113 }
114 if (DEPRECATED) subscribeFn = convertToOldSubscribeParams(subscribeFn)
115 let Subscribed = subscribe(subscribeFn)(Complex())
116 let w = mount(<Subscribed {...initialProps} />)
117 globalEnzymeNode = w
118
119 await w.waitFor('.Complex')
120 w.getItems = function () {
121 return getComplexItems(this)
122 }
123 Object.defineProperty(w, 'items', {
124 get: function () {
125 return this.getItems()
126 }
127 })
128 w.nextRender = function (...args) {
129 return nextRender(this, ...args)
130 }
131 return w
132}
133
134export function getComplexItems (w) {
135 let res = []
136 for (let i = 0; i < 10; i++) {
137 let el = w.find(`.items${i}`)
138 if (!el.exists()) break
139 let text = el.text()
140 let value
141 if (!text) {
142 value = []
143 } else {
144 value = text.split(',')
145 }
146 res.push(value)
147 }
148 return res
149}
150
151export async function tInitHooksComplex (initialProps = {}) {
152 let Component = HooksComplex()
153 globalTestRenderer = TestRenderer.create(<Component {...initialProps} />)
154 let t = globalTestRenderer
155 t.getItems = function () {
156 return tGetHooksComplexItems(this)
157 }
158 Object.defineProperty(t, 'items', {
159 get: function () {
160 return this.getItems()
161 }
162 })
163 t.nextRender = function (...args) {
164 return tNextRender(this, ...args)
165 }
166 return t
167}
168
169export function tGetHooksComplexItems (t) {
170 let res = {}
171 t.root.findAllByProps({ className: 'items' }).forEach(node => {
172 let name = node.props.title
173 let text = (node.children && node.children[0]) || ''
174 res[name] = text.split(',')
175 })
176 return res
177}
178
179export async function tInitHooksSimple (initialProps, useFn) {
180 if (typeof initialProps === 'function') {
181 useFn = initialProps
182 initialProps = {}
183 }
184 let Component = HooksSimple(useFn)
185 globalTestRenderer = TestRenderer.create(<Component {...initialProps} />)
186 let t = globalTestRenderer
187 t.getItems = function () {
188 return tGetSimpleItems(this)
189 }
190 Object.defineProperty(t, 'items', {
191 get: function () {
192 return this.getItems()
193 }
194 })
195 t.nextRender = function (...args) {
196 return tNextRender(this, ...args)
197 }
198 t.setProps = function (props = {}) {
199 t.update(<Component {...props} />)
200 }
201 return t
202}
203
204export function tGetSimpleItems (t) {
205 let node = t.root.findByProps({ className: 'items' })
206 let text = (node.children && node.children[0]) || ''
207 return text.split(',').filter(Boolean)
208}
209
210export async function tNextRender (t, count = 1, fn, params) {
211 if (typeof count === 'function') {
212 params = fn
213 fn = count
214 count = 1
215 }
216 if (fn && typeof fn !== 'function') {
217 params = fn
218 fn = undefined
219 }
220 if (count && typeof count !== 'number') {
221 params = count
222 count = 1
223 }
224 let { index } = params || {}
225 if (index == null) {
226 let currentRender = t.root.findByProps({ className: 'root' }).props.title
227 if (!currentRender) throw new Error("Component didn't render")
228 currentRender = ~~currentRender
229 index = currentRender + count
230 }
231 let selector = { className: 'root', title: '' + index }
232 typeof DEBUG !== 'undefined' && console.log('wait for:', selector)
233 if (fn) fn()
234 let found = false
235 while (!found) {
236 try {
237 t.root.findByProps(selector)
238 found = true
239 } catch (e) {
240 await new Promise(resolve => setTimeout(resolve, 10))
241 }
242 }
243}
244
245export async function nextRender (w, count = 1, fn, params) {
246 if (typeof count === 'function') {
247 params = fn
248 fn = count
249 count = 1
250 }
251 if (fn && typeof fn !== 'function') {
252 params = fn
253 fn = undefined
254 }
255 if (count && typeof count !== 'number') {
256 params = count
257 count = 1
258 }
259 let { index } = params || {}
260 if (index == null) {
261 let currentRender = w.html().match(/RENDER-(\d+)/)[1]
262 if (!currentRender) throw new Error("Component didn't render")
263 currentRender = ~~currentRender
264 index = currentRender + count
265 }
266 let selector = `.RENDER-${index}`
267 typeof DEBUG !== 'undefined' && console.log('wait for:', selector)
268 if (fn) fn()
269 await w.waitFor(selector)
270}