• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3require('../common');
4const assert = require('assert');
5const util = require('util');
6
7function findInGraph(graph, type, n) {
8  let found = 0;
9  for (let i = 0; i < graph.length; i++) {
10    const node = graph[i];
11    if (node.type === type) found++;
12    if (found === n) return node;
13  }
14}
15
16function pruneTickObjects(activities) {
17  // Remove one TickObject on each pass until none is left anymore
18  // not super efficient, but simplest especially to handle
19  // multiple TickObjects in a row
20  const tickObject = {
21    found: true,
22    index: null,
23    data: null
24  };
25
26  if (!Array.isArray(activities))
27    return activities;
28
29  while (tickObject.found) {
30    for (let i = 0; i < activities.length; i++) {
31      if (activities[i].type === 'TickObject') {
32        tickObject.index = i;
33        break;
34      } else if (i + 1 >= activities.length) {
35        tickObject.found = false;
36      }
37    }
38
39    if (tickObject.found) {
40      // Point all triggerAsyncIds that point to the tickObject
41      // to its triggerAsyncId and finally remove it from the activities
42      tickObject.data = activities[tickObject.index];
43      const triggerId = {
44        new: tickObject.data.triggerAsyncId,
45        old: tickObject.data.uid
46      };
47
48      activities.forEach(function repointTriggerId(x) {
49        if (x.triggerAsyncId === triggerId.old)
50          x.triggerAsyncId = triggerId.new;
51      });
52
53      activities.splice(tickObject.index, 1);
54    }
55  }
56  return activities;
57}
58
59module.exports = function verifyGraph(hooks, graph) {
60  pruneTickObjects(hooks);
61
62  // Map actual ids to standin ids defined in the graph
63  const idtouid = {};
64  const uidtoid = {};
65  const typeSeen = {};
66  const errors = [];
67
68  const activities = pruneTickObjects(hooks.activities);
69  activities.forEach(processActivity);
70
71  function processActivity(x) {
72    if (!typeSeen[x.type]) typeSeen[x.type] = 0;
73    typeSeen[x.type]++;
74
75    const node = findInGraph(graph, x.type, typeSeen[x.type]);
76    if (node == null) return;
77
78    idtouid[node.id] = x.uid;
79    uidtoid[x.uid] = node.id;
80    if (node.triggerAsyncId == null) return;
81
82    const tid = idtouid[node.triggerAsyncId];
83    if (x.triggerAsyncId === tid) return;
84
85    errors.push({
86      id: node.id,
87      expectedTid: node.triggerAsyncId,
88      actualTid: uidtoid[x.triggerAsyncId]
89    });
90  }
91
92  if (errors.length) {
93    errors.forEach((x) =>
94      console.error(
95        `'${x.id}' expected to be triggered by '${x.expectedTid}', ` +
96        `but was triggered by '${x.actualTid}' instead.`
97      )
98    );
99  }
100  assert.strictEqual(errors.length, 0);
101
102  // Verify that all expected types are present (but more/others are allowed)
103  const expTypes = Object.create(null);
104  for (let i = 0; i < graph.length; i++) {
105    if (expTypes[graph[i].type] == null) expTypes[graph[i].type] = 0;
106    expTypes[graph[i].type]++;
107  }
108
109  for (const type in expTypes) {
110    assert.ok(typeSeen[type] >= expTypes[type],
111              `Type '${type}': expecting: ${expTypes[type]} ` +
112              `found: ${typeSeen[type]}`);
113  }
114};
115
116//
117// Helper to generate the input to the verifyGraph tests
118//
119function inspect(obj, depth) {
120  console.error(util.inspect(obj, false, depth || 5, true));
121}
122
123module.exports.printGraph = function printGraph(hooks) {
124  const ids = {};
125  const uidtoid = {};
126  const activities = pruneTickObjects(hooks.activities);
127  const graph = [];
128  activities.forEach(procesNode);
129
130  function procesNode(x) {
131    const key = x.type.replace(/WRAP/, '').toLowerCase();
132    if (!ids[key]) ids[key] = 1;
133    const id = `${key}:${ids[key]++}`;
134    uidtoid[x.uid] = id;
135    const triggerAsyncId = uidtoid[x.triggerAsyncId] || null;
136    graph.push({ type: x.type, id, triggerAsyncId });
137  }
138  inspect(graph);
139};
140