summaryrefslogtreecommitdiffstats
path: root/devtools/shared/webconsole/test/test_jsterm_autocomplete.html
blob: 0e32e1a639eeae722604944fed686b56675d54f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
<!DOCTYPE HTML>
<html lang="en">
<head>
  <meta charset="utf8">
  <title>Test for JavaScript terminal functionality</title>
  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript;version=1.8" src="common.js"></script>
  <!-- Any copyright is dedicated to the Public Domain.
     - http://creativecommons.org/publicdomain/zero/1.0/ -->
</head>
<body>
<p>Test for JavaScript terminal autocomplete functionality</p>

<script class="testbody" type="text/javascript;version=1.8">
SimpleTest.waitForExplicitFinish();

let gState;
let {MAX_AUTOCOMPLETE_ATTEMPTS,MAX_AUTOCOMPLETIONS} = require("devtools/shared/webconsole/js-property-provider");

function evaluateJS(input, options = {}) {
  return new Promise((resolve, reject) => {
    gState.client.evaluateJSAsync(input, resolve, options);
  });
}

function autocompletePromise(str, cursor, frameActor) {
  return new Promise(resolve => {
    gState.client.autocomplete(str, cursor, resolve, frameActor);
  });
}

// This test runs all of its assertions twice - once with
// the tab as a target and once with a worker
let runningInTab = true;
function startTest({worker}) {
  if (worker) {
    attachConsoleToWorker(["PageError"], onAttach);
  } else {
    attachConsoleToTab(["PageError"], onAttach);
  }
};

let onAttach = Task.async(function*(aState, response) {
  gState = aState;

  let longStrLength = DebuggerServer.LONG_STRING_LENGTH;

  // Set up the global variables needed to test autocompletion
  // in the target.
  let script = `
    // This is for workers so autocomplete acts the same
    if (!this.window) {
      window = this;
    }

    window.foobarObject = Object.create(null);
    window.foobarObject.foo = 1;
    window.foobarObject.foobar = 2;
    window.foobarObject.foobaz = 3;
    window.foobarObject.omg = 4;
    window.foobarObject.omgfoo = 5;
    window.foobarObject.strfoo = "foobarz";
    window.foobarObject.omgstr = "foobarz" +
      (new Array(${longStrLength})).join("abb");
    window.largeObject1 = Object.create(null);
    for (let i = 0; i < ${MAX_AUTOCOMPLETE_ATTEMPTS + 1}; i++) {
      window.largeObject1['a' + i] = i;
    }

    window.largeObject2 = Object.create(null);
    for (let i = 0; i < ${MAX_AUTOCOMPLETIONS * 2}; i++) {
      window.largeObject2['a' + i] = i;
    }
  `;

  yield evaluateJS(script);

  let tests = [doAutocomplete1, doAutocomplete2, doAutocomplete3,
               doAutocomplete4, doAutocompleteLarge1,
               doAutocompleteLarge2].map(t => {
                 return Task.async(t);
               });

  runTests(tests, testEnd);
});

function* doAutocomplete1() {
  info("test autocomplete for 'window.foo'");
  let response = yield autocompletePromise("window.foo", 10);
  let matches = response.matches;

  is(response.matchProp, "foo", "matchProp");
  is(matches.length, 1, "matches.length");
  is(matches[0], "foobarObject", "matches[0]");

  nextTest();
}

function* doAutocomplete2() {
  info("test autocomplete for 'window.foobarObject.'");
  let response = yield autocompletePromise("window.foobarObject.", 20);
  let matches = response.matches;

  ok(!response.matchProp, "matchProp");
  is(matches.length, 7, "matches.length");
  checkObject(matches,
    ["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);

  nextTest();
}

function* doAutocomplete3() {
  // Check that completion suggestions are offered inside the string.
  info("test autocomplete for 'dump(window.foobarObject.)'");
  let response = yield autocompletePromise("dump(window.foobarObject.)", 25);
  let matches = response.matches;

  ok(!response.matchProp, "matchProp");
  is(matches.length, 7, "matches.length");
  checkObject(matches,
    ["foo", "foobar", "foobaz", "omg", "omgfoo", "omgstr", "strfoo"]);

  nextTest();
}

function* doAutocomplete4() {
  // Check that completion requests can have no suggestions.
  info("test autocomplete for 'dump(window.foobarObject.)'");
  let response = yield autocompletePromise("dump(window.foobarObject.)", 26);
  ok(!response.matchProp, "matchProp");
  is(response.matches.length, 0, "matches.length");

  nextTest();
}

function* doAutocompleteLarge1() {
  // Check that completion requests with too large objects will
  // have no suggestions.
  info("test autocomplete for 'window.largeObject1.'");
  let response = yield autocompletePromise("window.largeObject1.", 20);
  ok(!response.matchProp, "matchProp");
  info (response.matches.join("|"));
  is(response.matches.length, 0, "Bailed out with too many properties");

  nextTest();
}

function* doAutocompleteLarge2() {
  // Check that completion requests with pretty large objects will
  // have MAX_AUTOCOMPLETIONS suggestions
  info("test autocomplete for 'window.largeObject2.'");
  let response = yield autocompletePromise("window.largeObject2.", 20);
  ok(!response.matchProp, "matchProp");
  is(response.matches.length, MAX_AUTOCOMPLETIONS, "matches.length is MAX_AUTOCOMPLETIONS");

  nextTest();
}

function testEnd()
{
  // If this is the first run, reload the page and do it again
  // in a worker.  Otherwise, end the test.
  closeDebugger(gState, function() {
    gState = null;
    if (runningInTab) {
      runningInTab = false;
      startTest({
        worker: true
      });
    } else {
      SimpleTest.finish();
    }
  });
}

addEventListener("load", () => {
  startTest({
    worker: false
  });
});
</script>
</body>
</html>