Skip to content

Commit ef0dd07

Browse files
author
Robert Jackson
authored
Support referenced functions from within the gather function (#20)
Support referenced functions from within the gather function
2 parents 7911f36 + 5776ba7 commit ef0dd07

5 files changed

Lines changed: 137 additions & 99 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,4 @@ typings/
6161
.next
6262

6363
test/fixtures/classic-app/dist/
64+
lib/gather/cli.js

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,13 @@ After `0.5.0`, a few breaking changes occured.
7070
```javascript
7171
gatherTelemetryForUrl(url, gatherFunction, puppeteerArgs);
7272
```
73+
74+
## Caveats
75+
If the gather function references functions defined outside of the the gather function body, all of those functions must be exported as well. It is strongly suggested that the gather function be self contained, and if functions must be used (code maintainability/readability), that they be defined within the function. If this is not possible, the `gatherTelemetryForUrl` has been enhanced to accept all functions that must go along with the gather function:
7376

77+
```javascript
78+
gatherTelemetryForUrl(appLocation, gatherFunction, suppportFn1, suppportFn2, ..., puppeteerArgs);
79+
```
7480

7581
## Contributing
7682

lib/gather/analyze-ember-object.js

Lines changed: 95 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,101 @@ module.exports = function analyzeEmberObject(possibleEmberObject) {
1111
/* globals Ember */
1212
let meta = Ember.meta(proto);
1313

14+
/**
15+
* Parses the ember meta with passed key
16+
*
17+
* @param {Ember.meta} map
18+
* @param {String} key
19+
* @returns {Object} meta - The listener meta data
20+
* @returns {String} meta.type - Type of listener can be observer|event
21+
* @returns {String[]} meta.events - name of events/properties the listener is registered on
22+
*/
23+
let getListenerData = (map, key) => {
24+
while (map) {
25+
let type = 'event';
26+
const events = parseListeners(map._listeners).reduce((acc, [event, , method]) => {
27+
if (method === key) {
28+
const [observedProp, observerEvent] = event.split(':');
29+
if (observerEvent) {
30+
type = 'observer';
31+
}
32+
acc.push(observedProp);
33+
}
34+
return acc;
35+
}, []);
36+
if (events.length) {
37+
return {
38+
type,
39+
events,
40+
};
41+
}
42+
map = map.parent;
43+
}
44+
return {};
45+
};
46+
47+
/**
48+
* Checks if passed key is overriding any value from the parent objects
49+
*
50+
* @param {Object} map
51+
* @param {String} key
52+
* @returns boolean
53+
*/
54+
let isOverridden = (map, key) => {
55+
while (map) {
56+
const value = map.peekValues ? map.peekValues(key) : undefined;
57+
if (value !== undefined || (map.source && key in map.source)) {
58+
return true;
59+
}
60+
map = map.parent;
61+
}
62+
return false;
63+
};
64+
65+
/**
66+
* Parse the listeners to a group of array of 4 elements
67+
*
68+
* @param {Array} listeners
69+
* @param {int} size
70+
* @returns Array
71+
*/
72+
let parseListeners = (listeners = [], size = 4) => {
73+
var result = [];
74+
if (listeners.length) {
75+
if (typeof listeners[0] === 'object') {
76+
result = listeners.map(({ event, target, method, kind }) => [event, target, method, kind]);
77+
} else {
78+
const input = listeners.slice(0);
79+
while (input.length) {
80+
result.push(input.splice(0, size));
81+
}
82+
}
83+
}
84+
return result;
85+
};
86+
87+
/**
88+
* Checks if passed key is overriding any value from the parent objects' actions
89+
*
90+
* @param {Object} map
91+
* @param {String} key
92+
* @returns boolean
93+
*/
94+
let isActionOverridden = (map, key) => {
95+
while (map) {
96+
const { source } = map;
97+
if (source) {
98+
const { actions } = source;
99+
const value = actions ? actions[key] : undefined;
100+
if (value !== undefined) {
101+
return true;
102+
}
103+
}
104+
map = map.parent;
105+
}
106+
return false;
107+
};
108+
14109
// eslint-disable-next-line no-undef
15110
if (!meta || !meta.source) {
16111
return {};
@@ -112,98 +207,3 @@ module.exports = function analyzeEmberObject(possibleEmberObject) {
112207
unobservedProperties,
113208
};
114209
};
115-
116-
/**
117-
* Parses the ember meta with passed key
118-
*
119-
* @param {Ember.meta} map
120-
* @param {String} key
121-
* @returns {Object} meta - The listener meta data
122-
* @returns {String} meta.type - Type of listener can be observer|event
123-
* @returns {String[]} meta.events - name of events/properties the listener is registered on
124-
*/
125-
function getListenerData(map, key) {
126-
while (map) {
127-
let type = 'event';
128-
const events = parseListeners(map._listeners).reduce((acc, [event, , method]) => {
129-
if (method === key) {
130-
const [observedProp, observerEvent] = event.split(':');
131-
if (observerEvent) {
132-
type = 'observer';
133-
}
134-
acc.push(observedProp);
135-
}
136-
return acc;
137-
}, []);
138-
if (events.length) {
139-
return {
140-
type,
141-
events,
142-
};
143-
}
144-
map = map.parent;
145-
}
146-
return {};
147-
}
148-
149-
/**
150-
* Parse the listeners to a group of array of 4 elements
151-
*
152-
* @param {Array} listeners
153-
* @param {int} size
154-
* @returns Array
155-
*/
156-
function parseListeners(listeners = [], size = 4) {
157-
var result = [];
158-
if (listeners.length) {
159-
if (typeof listeners[0] === 'object') {
160-
result = listeners.map(({ event, target, method, kind }) => [event, target, method, kind]);
161-
} else {
162-
const input = listeners.slice(0);
163-
while (input.length) {
164-
result.push(input.splice(0, size));
165-
}
166-
}
167-
}
168-
return result;
169-
}
170-
171-
/**
172-
* Checks if passed key is overriding any value from the parent objects
173-
*
174-
* @param {Object} map
175-
* @param {String} key
176-
* @returns boolean
177-
*/
178-
function isOverridden(map, key) {
179-
while (map) {
180-
const value = map.peekValues ? map.peekValues(key) : undefined;
181-
if (value !== undefined || (map.source && key in map.source)) {
182-
return true;
183-
}
184-
map = map.parent;
185-
}
186-
return false;
187-
}
188-
189-
/**
190-
* Checks if passed key is overriding any value from the parent objects' actions
191-
*
192-
* @param {Object} map
193-
* @param {String} key
194-
* @returns boolean
195-
*/
196-
function isActionOverridden(map, key) {
197-
while (map) {
198-
const { source } = map;
199-
if (source) {
200-
const { actions } = source;
201-
const value = actions ? actions[key] : undefined;
202-
if (value !== undefined) {
203-
return true;
204-
}
205-
}
206-
map = map.parent;
207-
}
208-
return false;
209-
}

lib/gather/gather-telemetry.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ const { setTelemetry } = require('../utils/telemetry');
33

44
const DEFAULT_PUPPETEER_ARGS = { ignoreHTTPSErrors: true };
55

6-
module.exports = async function gatherTelemetry(url, gatherFn, puppeteerArgs = {}) {
6+
module.exports = async function gatherTelemetry(url, gatherFn, ...args) {
7+
let puppeteerArgs = [...args].pop();
8+
let supportFns = args;
9+
10+
if (typeof puppeteerArgs === 'object') {
11+
supportFns.pop();
12+
} else {
13+
puppeteerArgs = {};
14+
}
715
Object.assign(puppeteerArgs, DEFAULT_PUPPETEER_ARGS);
816

917
const browser = await puppeteer.launch(puppeteerArgs);
@@ -17,7 +25,11 @@ module.exports = async function gatherTelemetry(url, gatherFn, puppeteerArgs = {
1725

1826
const telemetry = await bridgeEvaluate(
1927
page,
20-
async gFn => {
28+
async (gFn, ...supportFns) => {
29+
supportFns.forEach(fn => {
30+
this[fn.name] = fn;
31+
});
32+
2133
const SKIPPED_MODULES = ['fetch/ajax'];
2234
/* globals window,*/
2335
let telemetry = {};
@@ -38,7 +50,8 @@ module.exports = async function gatherTelemetry(url, gatherFn, puppeteerArgs = {
3850
}
3951
return telemetry;
4052
},
41-
gatherFn
53+
gatherFn,
54+
...supportFns
4255
);
4356

4457
setTelemetry(telemetry);

lib/gather/gather-telemetry.test.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ function helper(possibleEmberObject) {
1414
}
1515
}
1616

17+
function outer(possibleEmberObject) {
18+
let obj = possibleEmberObject.default;
19+
if (obj && obj.name) {
20+
return obj.name === 'jQuery';
21+
}
22+
return false;
23+
}
24+
25+
function inner(possibleEmberObject) {
26+
return outer(possibleEmberObject);
27+
}
28+
1729
describe('Provide a personalized `Gathering Function`', () => {
1830
let app;
1931
let localAppPath = './test/fixtures/classic-app';
@@ -37,7 +49,13 @@ describe('Provide a personalized `Gathering Function`', () => {
3749
test('can determine components with a robust function', async () => {
3850
await gatherTelemetry('http://localhost:4200', analyzeEmberObject);
3951
let telemetry = getTelemetry();
40-
expect(Object.keys(telemetry).filter(Boolean).length).toEqual(1);
52+
expect(Object.values(telemetry).filter(Boolean).length).toEqual(29);
53+
});
54+
55+
test('can handle external functions', async () => {
56+
await gatherTelemetry('http://localhost:4200', inner, outer);
57+
let telemetry = getTelemetry();
58+
expect(Object.values(telemetry).filter(Boolean).length).toEqual(1);
4159
});
4260

4361
afterAll(async () => {

0 commit comments

Comments
 (0)