rails-assets-enzyme 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a2c7dd53db462ee9f020ae0e6804788737dc4d33
4
+ data.tar.gz: 152794407dc2405b920646ebc5c675c0183711ee
5
+ SHA512:
6
+ metadata.gz: bc5b396ced19648aeb68cbfd563768fa816e7643bba93a428c413b7465e9517777598bcd3d4205c6d8b48d56cc6092c5053972a50d39cbb30cec53262b655678
7
+ data.tar.gz: 70ee5a89eb4d5be6e86596793410f3a05504480ec0084c7a488c91ae69bf4a29919b48ff218681ace6e43f8597e717bf59491c83d40b9b7acb2aaca553d8b761
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Franze Jr.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Rails::Assets::Enzyme
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rails-assets-enzyme'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rails-assets-enzyme
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/rails-assets-enzyme/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,9 @@
1
+ require "rails/assets/enzyme/version"
2
+
3
+ module Rails
4
+ module Assets
5
+ module Enzyme
6
+ # Your code goes here...
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Rails
2
+ module Assets
3
+ module Enzyme
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,133 @@
1
+ import {
2
+ childrenOfNode,
3
+ } from './ShallowTraversal';
4
+ import {
5
+ renderedChildrenOfInst,
6
+ } from './MountedTraversal';
7
+ import {
8
+ isDOMComponent,
9
+ isCompositeComponent,
10
+ isElement,
11
+ } from './react-compat';
12
+ import {
13
+ internalInstance,
14
+ propsOfNode,
15
+ } from './Utils';
16
+ import without from 'lodash/without';
17
+ import escape from 'lodash/escape';
18
+ import compact from 'lodash/compact';
19
+ import { REACT013 } from './version';
20
+ import objectValues from 'object.values';
21
+
22
+ export function typeName(node) {
23
+ return typeof node.type === 'function'
24
+ ? (node.type.displayName || node.type.name || 'Component')
25
+ : node.type;
26
+ }
27
+
28
+ export function spaces(n) {
29
+ return Array(n + 1).join(' ');
30
+ }
31
+
32
+ export function indent(depth, string) {
33
+ return string.split('\n').map(x => `${spaces(depth)}${x}`).join('\n');
34
+ }
35
+
36
+ function propString(prop) {
37
+ switch (typeof prop) {
38
+ case 'function':
39
+ return '{[Function]}';
40
+ case 'string':
41
+ return `"${prop}"`;
42
+ case 'number':
43
+ case 'boolean':
44
+ return `{${prop}}`;
45
+ case 'object':
46
+ return '{{...}}';
47
+ default:
48
+ return `{[${typeof prop}]}`;
49
+ }
50
+ }
51
+
52
+ function propsString(node) {
53
+ const props = propsOfNode(node);
54
+ const keys = without(Object.keys(props), 'children');
55
+ return keys.map(key => `${key}=${propString(props[key])}`).join(' ');
56
+ }
57
+
58
+ export function debugNode(node, indentLength = 2) {
59
+ if (typeof node === 'string' || typeof node === 'number') return escape(node);
60
+ if (!node) return '';
61
+
62
+ const children = compact(childrenOfNode(node).map(n => debugNode(n, indentLength)));
63
+ const type = typeName(node);
64
+ const props = propsString(node);
65
+ const beforeProps = props ? ' ' : '';
66
+ const nodeClose = children.length ? `</${type}>` : '/>';
67
+ const afterProps = children.length
68
+ ? '>'
69
+ : ' ';
70
+ const childrenIndented = children.length
71
+ ? `\n${children.map(x => indent(indentLength, x)).join('\n')}\n`
72
+ : '';
73
+ return `<${type}${beforeProps}${props}${afterProps}${childrenIndented}${nodeClose}`;
74
+ }
75
+
76
+ export function debugNodes(nodes) {
77
+ return nodes.map(debugNode).join('\n\n\n');
78
+ }
79
+
80
+ export function debugInst(inst, indentLength = 2) {
81
+ if (typeof inst === 'string' || typeof inst === 'number') return escape(inst);
82
+ if (!inst) return '';
83
+
84
+ if (!inst.getPublicInstance) {
85
+ const internal = internalInstance(inst);
86
+ return debugInst(internal, indentLength);
87
+ }
88
+ const publicInst = inst.getPublicInstance();
89
+
90
+ if (typeof publicInst === 'string' || typeof publicInst === 'number') return escape(publicInst);
91
+ if (!publicInst && !inst._renderedComponent) return '';
92
+
93
+ // do stuff with publicInst
94
+ const currentElement = inst._currentElement;
95
+ const type = typeName(currentElement);
96
+ const props = propsString(currentElement);
97
+ const children = [];
98
+ if (isDOMComponent(publicInst)) {
99
+ const renderedChildren = renderedChildrenOfInst(inst);
100
+ if (!renderedChildren) {
101
+ children.push(...childrenOfNode(currentElement));
102
+ } else {
103
+ children.push(...objectValues(renderedChildren));
104
+ }
105
+ } else if (
106
+ !REACT013 &&
107
+ isElement(currentElement) &&
108
+ typeof currentElement.type === 'function'
109
+ ) {
110
+ children.push(inst._renderedComponent);
111
+ } else if (
112
+ REACT013 &&
113
+ isCompositeComponent(publicInst)
114
+ ) {
115
+ children.push(inst._renderedComponent);
116
+ }
117
+
118
+ const childrenStrs = compact(children.map(n => debugInst(n, indentLength)));
119
+
120
+ const beforeProps = props ? ' ' : '';
121
+ const nodeClose = childrenStrs.length ? `</${type}>` : '/>';
122
+ const afterProps = childrenStrs.length
123
+ ? '>'
124
+ : ' ';
125
+ const childrenIndented = childrenStrs.length
126
+ ? `\n${childrenStrs.map(x => indent(indentLength + 2, x)).join('\n')}\n`
127
+ : '';
128
+ return `<${type}${beforeProps}${props}${afterProps}${childrenIndented}${nodeClose}`;
129
+ }
130
+
131
+ export function debugInsts(insts) {
132
+ return insts.map(debugInst).join('\n\n\n');
133
+ }
@@ -0,0 +1,305 @@
1
+ import isEmpty from 'lodash/isEmpty';
2
+ import isSubset from 'is-subset';
3
+ import {
4
+ internalInstance,
5
+ coercePropValue,
6
+ nodeEqual,
7
+ propsOfNode,
8
+ isFunctionalComponent,
9
+ isSimpleSelector,
10
+ splitSelector,
11
+ selectorError,
12
+ selectorType,
13
+ isCompoundSelector,
14
+ AND,
15
+ SELECTOR,
16
+ nodeHasType,
17
+ } from './Utils';
18
+ import {
19
+ isDOMComponent,
20
+ isCompositeComponent,
21
+ isCompositeComponentWithType,
22
+ isElement,
23
+ findDOMNode,
24
+ } from './react-compat';
25
+ import { REACT013 } from './version';
26
+
27
+ export function getNode(inst) {
28
+ if (!inst || inst._store || typeof inst === 'string') {
29
+ return inst;
30
+ }
31
+ if (inst._currentElement) {
32
+ return inst._currentElement;
33
+ }
34
+ if (internalInstance(inst)) {
35
+ return internalInstance(inst)._currentElement;
36
+ }
37
+ if (inst._reactInternalInstance) {
38
+ return inst._reactInternalInstance._currentElement;
39
+ }
40
+ if (inst._reactInternalComponent) {
41
+ return inst._reactInternalComponent._currentElement;
42
+ }
43
+ return inst;
44
+ }
45
+
46
+ export function instEqual(a, b) {
47
+ return nodeEqual(getNode(a), getNode(b));
48
+ }
49
+
50
+ export function instHasClassName(inst, className) {
51
+ if (!isDOMComponent(inst)) {
52
+ return false;
53
+ }
54
+ let classes = findDOMNode(inst).className || '';
55
+ classes = classes.replace(/\s/g, ' ');
56
+ return ` ${classes} `.indexOf(` ${className} `) > -1;
57
+ }
58
+
59
+ export function instHasId(inst, id) {
60
+ if (!isDOMComponent(inst)) return false;
61
+ const instId = findDOMNode(inst).id || '';
62
+ return instId === id;
63
+ }
64
+
65
+ function isFunctionalComponentWithType(inst, func) {
66
+ return isFunctionalComponent(inst) && getNode(inst).type === func;
67
+ }
68
+
69
+ export function instHasType(inst, type) {
70
+ switch (typeof type) {
71
+ case 'string':
72
+ return nodeHasType(getNode(inst), type);
73
+ case 'function':
74
+ return isCompositeComponentWithType(inst, type) ||
75
+ isFunctionalComponentWithType(inst, type);
76
+ default:
77
+ return false;
78
+ }
79
+ }
80
+
81
+ export function instHasProperty(inst, propKey, stringifiedPropValue) {
82
+ if (!isDOMComponent(inst)) return false;
83
+ const node = getNode(inst);
84
+ const nodeProps = propsOfNode(node);
85
+ const descriptor = Object.getOwnPropertyDescriptor(nodeProps, propKey);
86
+ if (descriptor && descriptor.get) {
87
+ return false;
88
+ }
89
+ const nodePropValue = nodeProps[propKey];
90
+
91
+ const propValue = coercePropValue(propKey, stringifiedPropValue);
92
+
93
+ // intentionally not matching node props that are undefined
94
+ if (nodePropValue === undefined) {
95
+ return false;
96
+ }
97
+
98
+ if (propValue) {
99
+ return nodePropValue === propValue;
100
+ }
101
+
102
+ return nodeProps.hasOwnProperty(propKey);
103
+ }
104
+
105
+ // called with private inst
106
+ export function renderedChildrenOfInst(inst) {
107
+ return REACT013
108
+ ? inst._renderedComponent._renderedChildren
109
+ : inst._renderedChildren;
110
+ }
111
+
112
+ // called with a private instance
113
+ export function childrenOfInstInternal(inst) {
114
+ if (!inst) {
115
+ return [];
116
+ }
117
+ if (!inst.getPublicInstance) {
118
+ const internal = internalInstance(inst);
119
+ return childrenOfInstInternal(internal);
120
+ }
121
+
122
+ const publicInst = inst.getPublicInstance();
123
+ const currentElement = inst._currentElement;
124
+ if (isDOMComponent(publicInst)) {
125
+ const children = [];
126
+ const renderedChildren = renderedChildrenOfInst(inst);
127
+ let key;
128
+ for (key in renderedChildren) {
129
+ if (!renderedChildren.hasOwnProperty(key)) {
130
+ continue;
131
+ }
132
+ if (REACT013 && !renderedChildren[key].getPublicInstance) {
133
+ continue;
134
+ }
135
+ if (!REACT013 && typeof renderedChildren[key]._currentElement.type === 'function') {
136
+ children.push(renderedChildren[key]._instance);
137
+ continue;
138
+ }
139
+ children.push(renderedChildren[key].getPublicInstance());
140
+ }
141
+ return children;
142
+ } else if (
143
+ !REACT013 &&
144
+ isElement(currentElement) &&
145
+ typeof currentElement.type === 'function'
146
+ ) {
147
+ return childrenOfInstInternal(inst._renderedComponent);
148
+ } else if (
149
+ REACT013 &&
150
+ isCompositeComponent(publicInst)
151
+ ) {
152
+ return childrenOfInstInternal(inst._renderedComponent);
153
+ }
154
+ return [];
155
+ }
156
+
157
+ export function internalInstanceOrComponent(node) {
158
+ if (REACT013) {
159
+ return node;
160
+ } else if (node._reactInternalComponent) {
161
+ return node._reactInternalComponent;
162
+ } else if (node._reactInternalInstance) {
163
+ return node._reactInternalInstance;
164
+ }
165
+ return node;
166
+ }
167
+
168
+ export function childrenOfInst(node) {
169
+ return childrenOfInstInternal(internalInstanceOrComponent(node));
170
+ }
171
+
172
+ export function pathToNode(node, root) {
173
+ const queue = [root];
174
+ const path = [];
175
+
176
+ while (queue.length) {
177
+ const current = queue.pop();
178
+ const children = childrenOfInst(current);
179
+
180
+ if (current === node) return path;
181
+
182
+ path.push(current);
183
+
184
+ if (children.length === 0) {
185
+ // leaf node. if it isn't the node we are looking for, we pop.
186
+ path.pop();
187
+ }
188
+ queue.push.apply(queue, children);
189
+ }
190
+
191
+ return null;
192
+ }
193
+
194
+ export function parentsOfInst(inst, root) {
195
+ return pathToNode(inst, root).reverse();
196
+ }
197
+
198
+ export function instMatchesObjectProps(inst, props) {
199
+ if (!isDOMComponent(inst)) return false;
200
+ const node = getNode(inst);
201
+ return isSubset(propsOfNode(node), props);
202
+ }
203
+
204
+ export function buildInstPredicate(selector) {
205
+ switch (typeof selector) {
206
+ case 'function':
207
+ // selector is a component constructor
208
+ return inst => instHasType(inst, selector);
209
+
210
+ case 'string':
211
+ if (!isSimpleSelector(selector)) {
212
+ throw selectorError(selector);
213
+ }
214
+ if (isCompoundSelector.test(selector)) {
215
+ return AND(splitSelector(selector).map(buildInstPredicate));
216
+ }
217
+
218
+ switch (selectorType(selector)) {
219
+ case SELECTOR.CLASS_TYPE:
220
+ return inst => instHasClassName(inst, selector.substr(1));
221
+ case SELECTOR.ID_TYPE:
222
+ return inst => instHasId(inst, selector.substr(1));
223
+ case SELECTOR.PROP_TYPE: {
224
+ const propKey = selector.split(/\[([a-zA-Z\-\:]*?)(=|\])/)[1];
225
+ const propValue = selector.split(/=(.*?)]/)[1];
226
+
227
+ return node => instHasProperty(node, propKey, propValue);
228
+ }
229
+ default:
230
+ // selector is a string. match to DOM tag or constructor displayName
231
+ return inst => instHasType(inst, selector);
232
+ }
233
+
234
+ case 'object':
235
+ if (!Array.isArray(selector) && selector !== null && !isEmpty(selector)) {
236
+ return node => instMatchesObjectProps(node, selector);
237
+ }
238
+ throw new TypeError(
239
+ 'Enzyme::Selector does not support an array, null, or empty object as a selector'
240
+ );
241
+
242
+ default:
243
+ throw new TypeError('Enzyme::Selector expects a string, object, or Component Constructor');
244
+ }
245
+ }
246
+
247
+ // This function should be called with an "internal instance". Nevertheless, if it is
248
+ // called with a "public instance" instead, the function will call itself with the
249
+ // internal instance and return the proper result.
250
+ function findAllInRenderedTreeInternal(inst, test) {
251
+ if (!inst) {
252
+ return [];
253
+ }
254
+
255
+ if (!inst.getPublicInstance) {
256
+ const internal = internalInstance(inst);
257
+ return findAllInRenderedTreeInternal(internal, test);
258
+ }
259
+ const publicInst = inst.getPublicInstance() || inst._instance;
260
+ let ret = test(publicInst) ? [publicInst] : [];
261
+ const currentElement = inst._currentElement;
262
+ if (isDOMComponent(publicInst)) {
263
+ const renderedChildren = renderedChildrenOfInst(inst);
264
+ let key;
265
+ for (key in renderedChildren) {
266
+ if (!renderedChildren.hasOwnProperty(key)) {
267
+ continue;
268
+ }
269
+ if (REACT013 && !renderedChildren[key].getPublicInstance) {
270
+ continue;
271
+ }
272
+ ret = ret.concat(
273
+ findAllInRenderedTreeInternal(renderedChildren[key], test)
274
+ );
275
+ }
276
+ } else if (
277
+ !REACT013 &&
278
+ isElement(currentElement) &&
279
+ typeof currentElement.type === 'function'
280
+ ) {
281
+ ret = ret.concat(
282
+ findAllInRenderedTreeInternal(
283
+ inst._renderedComponent,
284
+ test
285
+ )
286
+ );
287
+ } else if (
288
+ REACT013 &&
289
+ isCompositeComponent(publicInst)
290
+ ) {
291
+ ret = ret.concat(
292
+ findAllInRenderedTreeInternal(
293
+ inst._renderedComponent,
294
+ test
295
+ )
296
+ );
297
+ }
298
+ return ret;
299
+ }
300
+
301
+ // This function could be called with a number of different things technically, so we need to
302
+ // pass the *right* thing to our internal helper.
303
+ export function treeFilter(node, test) {
304
+ return findAllInRenderedTreeInternal(internalInstanceOrComponent(node), test);
305
+ }