Showing 2 of 5 files from the diff.
@@ -167,12 +167,58 @@
Loading
167 | 167 | ||
168 | 168 | exports.isObject = isObject; |
|
169 | 169 | ||
170 | - | function groupBy(obj, val) { |
|
170 | + | /** |
|
171 | + | * @param {string|number} attr |
|
172 | + | * @returns {(string|number)[]} |
|
173 | + | * @private |
|
174 | + | */ |
|
175 | + | function _prepareAttributeParts(attr) { |
|
176 | + | if (!attr) { |
|
177 | + | return []; |
|
178 | + | } |
|
179 | + | ||
180 | + | if (typeof attr === 'string') { |
|
181 | + | return attr.split('.'); |
|
182 | + | } |
|
183 | + | ||
184 | + | return [attr]; |
|
185 | + | } |
|
186 | + | ||
187 | + | /** |
|
188 | + | * @param {string} attribute Attribute value. Dots allowed. |
|
189 | + | * @returns {function(Object): *} |
|
190 | + | */ |
|
191 | + | function getAttrGetter(attribute) { |
|
192 | + | const parts = _prepareAttributeParts(attribute); |
|
193 | + | ||
194 | + | return function attrGetter(item) { |
|
195 | + | let _item = item; |
|
196 | + | ||
197 | + | for (let i = 0; i < parts.length; i++) { |
|
198 | + | const part = parts[i]; |
|
199 | + | ||
200 | + | // If item is not an object, and we still got parts to handle, it means |
|
201 | + | // that something goes wrong. Just roll out to undefined in that case. |
|
202 | + | if (hasOwnProp(_item, part)) { |
|
203 | + | _item = _item[part]; |
|
204 | + | } else { |
|
205 | + | return undefined; |
|
206 | + | } |
|
207 | + | } |
|
208 | + | ||
209 | + | return _item; |
|
210 | + | }; |
|
211 | + | } |
|
212 | + | ||
213 | + | function groupBy(obj, val, throwOnUndefined) { |
|
171 | 214 | const result = {}; |
|
172 | - | const iterator = isFunction(val) ? val : (o) => o[val]; |
|
215 | + | const iterator = isFunction(val) ? val : getAttrGetter(val); |
|
173 | 216 | for (let i = 0; i < obj.length; i++) { |
|
174 | 217 | const value = obj[i]; |
|
175 | 218 | const key = iterator(value, i); |
|
219 | + | if (key === undefined && throwOnUndefined === true) { |
|
220 | + | throw new TypeError(`groupby: attribute "${val}" resolved to undefined`); |
|
221 | + | } |
|
176 | 222 | (result[key] || (result[key] = [])).push(value); |
|
177 | 223 | } |
|
178 | 224 | return result; |
Files | Coverage |
---|---|
nunjucks | 89.65% |
Project Totals (22 files) | 89.65% |
1369.3
1369.2
c6k1relg99jjxe02
8nyymj5txnyr4yv1
79rxsjqo89jkc17d
4lo479f9lkbximkd
n6aegv6cueak1a5a
1368.1
1368.3
5m4gargsf4utwtk0
1368.2
i8alht0dpow51srt
y7eqnd08a8ol9fef
birx0bm2lnkaf46x
90n715v8smm02pae
1369.1
2y1f97f6hhay5xdf
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file.
The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files.
The size and color of each slice is representing the number of statements and the coverage, respectively.