blob: 69b9b54d1e9e40f38c127bbbe542e763dc539827 [file] [log] [blame]
Ryan Dahl55048cd2011-03-10 08:54:521// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
Ryan Dahla0159b42010-12-04 23:20:3422var common = require('../common');
23var assert = require('assert');
Ryan Dahla6942b32010-06-08 00:39:2424
Ryan Dahl02cc39f2010-12-04 21:40:3925common.globalCheck = false;
26
Oleg Efimov0ce9cba2010-12-04 22:45:5227var net = require('net'),
28 repl = require('repl'),
29 message = 'Read, Eval, Print Loop',
Oleg Efimov0ce9cba2010-12-04 22:45:5230 prompt_unix = 'node via Unix socket> ',
31 prompt_tcp = 'node via TCP socket> ',
32 prompt_multiline = '... ',
isaacs28e851c2012-06-05 19:02:3733 prompt_npm = 'npm should be run outside of the ' +
34 'node repl, in your normal shell.\n' +
35 '(Press Control-D to exit.)\n',
36 expect_npm = prompt_npm + prompt_unix,
Fedor Indutny1a52d6a2014-07-31 08:12:1837 server_tcp, server_unix, client_tcp, client_unix, timer;
Ryan Dahla6942b32010-06-08 00:39:2438
Ryan Dahl03a119e2011-08-09 23:06:3239
Ryan Dahl49627022010-09-19 18:20:2540// absolute path to test/fixtures/a.js
Oleg Efimov0ce9cba2010-12-04 22:45:5241var moduleFilename = require('path').join(common.fixturesDir, 'a');
Ryan Dahl49627022010-09-19 18:20:2542
isaacs4631c502013-08-28 01:53:3943console.error('repl test');
Matt Ranneyb7441042010-04-11 23:13:3244
45// function for REPL to run
Oleg Efimov0ce9cba2010-12-04 22:45:5246invoke_me = function(arg) {
47 return 'invoked ' + arg;
Matt Ranneyb7441042010-04-11 23:13:3248};
49
50function send_expect(list) {
51 if (list.length > 0) {
52 var cur = list.shift();
53
isaacs4631c502013-08-28 01:53:3954 console.error('sending ' + JSON.stringify(cur.send));
Ryan Dahla6942b32010-06-08 00:39:2455
Matt Ranneyb7441042010-04-11 23:13:3256 cur.client.expect = cur.expect;
57 cur.client.list = list;
58 if (cur.send.length > 0) {
Nathan Rajlichaab7cb72012-04-06 19:20:0159 cur.client.write(cur.send + '\n');
Matt Ranneyb7441042010-04-11 23:13:3260 }
61 }
62}
63
Marco Rogers118b88e2010-11-20 23:44:5864function clean_up() {
65 client_tcp.end();
66 client_unix.end();
67 clearTimeout(timer);
68}
69
70function error_test() {
Ryan Dahl08d81162010-12-01 21:43:0571 // The other stuff is done so reuse unix socket
Oleg Efimov0ce9cba2010-12-04 22:45:5272 var read_buffer = '';
Ryan Dahl08d81162010-12-01 21:43:0573 client_unix.removeAllListeners('data');
Marco Rogers118b88e2010-11-20 23:44:5874
Ben Noordhuis018e1102011-10-14 23:08:3675 client_unix.on('data', function(data) {
Ryan Dahl08d81162010-12-01 21:43:0576 read_buffer += data.toString('ascii', 0, data.length);
isaacs4631c502013-08-28 01:53:3977 console.error('Unix data: ' + JSON.stringify(read_buffer) + ', expecting ' +
Oleg Efimov0ce9cba2010-12-04 22:45:5278 (client_unix.expect.exec ?
79 client_unix.expect :
80 JSON.stringify(client_unix.expect)));
Marco Rogers118b88e2010-11-20 23:44:5881
Ryan Dahl08d81162010-12-01 21:43:0582 if (read_buffer.indexOf(prompt_unix) !== -1) {
isaacs28e851c2012-06-05 19:02:3783 // if it's an exact match, then don't do the regexp
84 if (read_buffer !== client_unix.expect) {
Yazhong Liu613654e2014-07-01 13:35:3585 var expect = client_unix.expect;
86 if (expect === prompt_multiline)
87 expect = /[\.]{3} /;
88 assert.ok(read_buffer.match(expect));
isaacs4631c502013-08-28 01:53:3989 console.error('match');
isaacs28e851c2012-06-05 19:02:3790 }
Oleg Efimov0ce9cba2010-12-04 22:45:5291 read_buffer = '';
Ryan Dahl08d81162010-12-01 21:43:0592 if (client_unix.list && client_unix.list.length > 0) {
93 send_expect(client_unix.list);
94 } else {
isaacs4631c502013-08-28 01:53:3995 console.error('End of Error test, running TCP test.');
Ryan Dahl08d81162010-12-01 21:43:0596 tcp_test();
97 }
98
seebees3421f432011-11-12 01:44:3999 } else if (read_buffer.indexOf(prompt_multiline) !== -1) {
Ryan Dahl08d81162010-12-01 21:43:05100 // Check that you meant to send a multiline test
101 assert.strictEqual(prompt_multiline, client_unix.expect);
Oleg Efimov0ce9cba2010-12-04 22:45:52102 read_buffer = '';
Ryan Dahl08d81162010-12-01 21:43:05103 if (client_unix.list && client_unix.list.length > 0) {
104 send_expect(client_unix.list);
105 } else {
isaacs4631c502013-08-28 01:53:39106 console.error('End of Error test, running TCP test.\n');
Ryan Dahl08d81162010-12-01 21:43:05107 tcp_test();
108 }
109
110 } else {
isaacs4631c502013-08-28 01:53:39111 console.error('didn\'t see prompt yet, buffering.');
Ryan Dahl08d81162010-12-01 21:43:05112 }
113 });
114
115 send_expect([
116 // Uncaught error throws and prints out
Oleg Efimov0ce9cba2010-12-04 22:45:52117 { client: client_unix, send: 'throw new Error(\'test error\');',
118 expect: /^Error: test error/ },
Ryan Dahl08d81162010-12-01 21:43:05119 // Common syntax error is treated as multiline command
Oleg Efimov0ce9cba2010-12-04 22:45:52120 { client: client_unix, send: 'function test_func() {',
121 expect: prompt_multiline },
Ryan Dahl08d81162010-12-01 21:43:05122 // You can recover with the .break command
Oleg Efimov0ce9cba2010-12-04 22:45:52123 { client: client_unix, send: '.break',
124 expect: prompt_unix },
isaacs4631c502013-08-28 01:53:39125 // But passing the same string to eval() should throw
126 { client: client_unix, send: 'eval("function test_func() {")',
127 expect: /^SyntaxError: Unexpected end of input/ },
Ben Noordhuisb6e98972012-11-10 17:21:13128 // Floating point numbers are not interpreted as REPL commands.
129 { client: client_unix, send: '.1234',
130 expect: '0.1234' },
Nirk Niggler0459a232013-01-03 14:27:55131 // Floating point expressions are not interpreted as REPL commands
Ben Noordhuis8a65df92013-07-10 07:48:55132 { client: client_unix, send: '.1+.1',
Nirk Niggler0459a232013-01-03 14:27:55133 expect: '0.2' },
Ryan Dahl08d81162010-12-01 21:43:05134 // Can parse valid JSON
Oleg Efimov0ce9cba2010-12-04 22:45:52135 { client: client_unix, send: 'JSON.parse(\'{"valid": "json"}\');',
136 expect: '{ valid: \'json\' }'},
137 // invalid input to JSON.parse error is special case of syntax error,
138 // should throw
139 { client: client_unix, send: 'JSON.parse(\'{invalid: \\\'json\\\'}\');',
koichik8faf9412011-07-04 19:10:14140 expect: /^SyntaxError: Unexpected token i/ },
Nathan Rajlich3b7312d2012-10-01 18:36:06141 // end of input to JSON.parse error is special case of syntax error,
142 // should throw
Brian White774b28f2013-05-26 16:26:39143 { client: client_unix, send: 'JSON.parse(\'066\');',
144 expect: /^SyntaxError: Unexpected number/ },
145 // should throw
Nathan Rajlich3b7312d2012-10-01 18:36:06146 { client: client_unix, send: 'JSON.parse(\'{\');',
147 expect: /^SyntaxError: Unexpected end of input/ },
Nathan Rajlich4a267072012-09-22 01:46:16148 // invalid RegExps are a special case of syntax error,
149 // should throw
150 { client: client_unix, send: '/(/;',
151 expect: /^SyntaxError: Invalid regular expression\:/ },
Nathan Rajlichf1722a22012-10-01 05:43:35152 // invalid RegExp modifiers are a special case of syntax error,
153 // should throw (GH-4012)
154 { client: client_unix, send: 'new RegExp("foo", "wrong modifier");',
155 expect: /^SyntaxError: Invalid flags supplied to RegExp constructor/ },
Nathan Rajlich085f9d62013-03-30 20:10:30156 // strict mode syntax errors should be caught (GH-5178)
157 { client: client_unix, send: '(function() { "use strict"; return 0755; })()',
158 expect: /^SyntaxError: Octal literals are not allowed in strict mode/ },
159 { client: client_unix, send: '(function() { "use strict"; return { p: 1, p: 2 }; })()',
160 expect: /^SyntaxError: Duplicate data property in object literal not allowed in strict mode/ },
161 { client: client_unix, send: '(function(a, a, b) { "use strict"; return a + b + c; })()',
162 expect: /^SyntaxError: Strict mode function may not have duplicate parameter names/ },
163 { client: client_unix, send: '(function() { "use strict"; with (this) {} })()',
164 expect: /^SyntaxError: Strict mode code may not include a with statement/ },
165 { client: client_unix, send: '(function() { "use strict"; var x; delete x; })()',
166 expect: /^SyntaxError: Delete of an unqualified identifier in strict mode/ },
167 { client: client_unix, send: '(function() { "use strict"; eval = 17; })()',
Fedor Indutnyce04c722014-03-13 16:38:14168 expect: /^SyntaxError: Unexpected eval or arguments in strict mode/ },
Nathan Rajlich085f9d62013-03-30 20:10:30169 { client: client_unix, send: '(function() { "use strict"; if (true){ function f() { } } })()',
170 expect: /^SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function/ },
Ryan Dahlfeb77ea2011-01-03 02:08:08171 // Named functions can be used:
172 { client: client_unix, send: 'function blah() { return 1; }',
173 expect: prompt_unix },
174 { client: client_unix, send: 'blah()',
Colton Baker87286cc2011-10-04 22:08:18175 expect: '1\n' + prompt_unix },
Fedor Indutnyae5e2332012-02-17 18:18:11176 // Functions should not evaluate twice (#2773)
177 { client: client_unix, send: 'var I = [1,2,3,function() {}]; I.pop()',
178 expect: '[Function]' },
Ryan Dahlfeb77ea2011-01-03 02:08:08179 // Multiline object
180 { client: client_unix, send: '{ a: ',
181 expect: prompt_multiline },
182 { client: client_unix, send: '1 }',
Colton Baker87286cc2011-10-04 22:08:18183 expect: '{ a: 1 }' },
Ryan Dahlfeb77ea2011-01-03 02:08:08184 // Multiline anonymous function with comment
185 { client: client_unix, send: '(function () {',
186 expect: prompt_multiline },
187 { client: client_unix, send: '// blah',
188 expect: prompt_multiline },
189 { client: client_unix, send: 'return 1;',
190 expect: prompt_multiline },
191 { client: client_unix, send: '})()',
isaacs28e851c2012-06-05 19:02:37192 expect: '1' },
193 // npm prompt error message
194 { client: client_unix, send: 'npm install foobar',
Maciej Małecki6a11f3e2012-07-03 02:13:24195 expect: expect_npm },
196 { client: client_unix, send: '(function () {\n\nreturn 1;\n})()',
Nathan Rajlich9126dd22012-07-04 18:51:24197 expect: '1' },
198 { client: client_unix, send: '{\n\na: 1\n}',
Felix Böhm9bce5e82013-01-12 20:07:06199 expect: '{ a: 1 }' },
200 { client: client_unix, send: 'url.format("http://google.com")',
201 expect: 'http://google.com/' },
202 { client: client_unix, send: 'var path = 42; path',
203 expect: '42' }
Ryan Dahl08d81162010-12-01 21:43:05204 ]);
Marco Rogers118b88e2010-11-20 23:44:58205}
206
Matt Ranneyb7441042010-04-11 23:13:32207function tcp_test() {
Oleg Efimov0ce9cba2010-12-04 22:45:52208 server_tcp = net.createServer(function(socket) {
Matt Ranneyb7441042010-04-11 23:13:32209 assert.strictEqual(server_tcp, socket.server);
Ryan Dahla6942b32010-06-08 00:39:24210
Ben Noordhuis018e1102011-10-14 23:08:36211 socket.on('end', function() {
Matt Ranneyb7441042010-04-11 23:13:32212 socket.end();
213 });
214
215 repl.start(prompt_tcp, socket);
216 });
217
Oleg Efimov0ce9cba2010-12-04 22:45:52218 server_tcp.listen(common.PORT, function() {
219 var read_buffer = '';
Ryan Dahla6942b32010-06-08 00:39:24220
Ryan Dahl9fd5e3c2010-07-15 18:47:25221 client_tcp = net.createConnection(common.PORT);
Matt Ranneyb7441042010-04-11 23:13:32222
Ben Noordhuis018e1102011-10-14 23:08:36223 client_tcp.on('connect', function() {
Matt Ranneyb7441042010-04-11 23:13:32224 assert.equal(true, client_tcp.readable);
225 assert.equal(true, client_tcp.writable);
226
227 send_expect([
Oleg Efimov0665f022010-12-05 19:15:30228 { client: client_tcp, send: '',
229 expect: prompt_tcp },
Nathan Rajlichaab7cb72012-04-06 19:20:01230 { client: client_tcp, send: 'invoke_me(333)',
Oleg Efimov0665f022010-12-05 19:15:30231 expect: ('\'' + 'invoked 333' + '\'\n' + prompt_tcp) },
Nathan Rajlichaab7cb72012-04-06 19:20:01232 { client: client_tcp, send: 'a += 1',
Oleg Efimov0665f022010-12-05 19:15:30233 expect: ('12346' + '\n' + prompt_tcp) },
234 { client: client_tcp,
Nathan Rajlichaab7cb72012-04-06 19:20:01235 send: 'require(' + JSON.stringify(moduleFilename) + ').number',
Oleg Efimov0665f022010-12-05 19:15:30236 expect: ('42' + '\n' + prompt_tcp) }
237 ]);
Matt Ranneyb7441042010-04-11 23:13:32238 });
239
Ben Noordhuis018e1102011-10-14 23:08:36240 client_tcp.on('data', function(data) {
Ryan Dahl4fe5e862010-09-06 19:12:36241 read_buffer += data.toString('ascii', 0, data.length);
isaacs4631c502013-08-28 01:53:39242 console.error('TCP data: ' + JSON.stringify(read_buffer) +
Oleg Efimov0ce9cba2010-12-04 22:45:52243 ', expecting ' + JSON.stringify(client_tcp.expect));
Matt Ranneyafe3c1c2010-04-12 21:29:49244 if (read_buffer.indexOf(prompt_tcp) !== -1) {
245 assert.strictEqual(client_tcp.expect, read_buffer);
isaacs4631c502013-08-28 01:53:39246 console.error('match');
Oleg Efimov0ce9cba2010-12-04 22:45:52247 read_buffer = '';
Matt Ranneyafe3c1c2010-04-12 21:29:49248 if (client_tcp.list && client_tcp.list.length > 0) {
249 send_expect(client_tcp.list);
Ryan Dahl08d81162010-12-01 21:43:05250 } else {
isaacs4631c502013-08-28 01:53:39251 console.error('End of TCP test.\n');
Marco Rogers118b88e2010-11-20 23:44:58252 clean_up();
Matt Ranneyafe3c1c2010-04-12 21:29:49253 }
Ryan Dahl08d81162010-12-01 21:43:05254 } else {
isaacs4631c502013-08-28 01:53:39255 console.error('didn\'t see prompt yet, buffering');
Matt Ranneyb7441042010-04-11 23:13:32256 }
257 });
Ryan Dahla6942b32010-06-08 00:39:24258
Ben Noordhuis018e1102011-10-14 23:08:36259 client_tcp.on('error', function(e) {
Matt Ranneyb7441042010-04-11 23:13:32260 throw e;
261 });
Ryan Dahla6942b32010-06-08 00:39:24262
Ben Noordhuis018e1102011-10-14 23:08:36263 client_tcp.on('close', function() {
Matt Ranneyb7441042010-04-11 23:13:32264 server_tcp.close();
265 });
266 });
267
Matt Ranneyb7441042010-04-11 23:13:32268}
269
270function unix_test() {
Oleg Efimov0ce9cba2010-12-04 22:45:52271 server_unix = net.createServer(function(socket) {
Matt Ranneyb7441042010-04-11 23:13:32272 assert.strictEqual(server_unix, socket.server);
Matt Ranneyb7441042010-04-11 23:13:32273
Ben Noordhuis018e1102011-10-14 23:08:36274 socket.on('end', function() {
Matt Ranneyb7441042010-04-11 23:13:32275 socket.end();
276 });
277
Fedor Indutny1a52d6a2014-07-31 08:12:18278 repl.start({
Nathan Rajlichb1e78ce2012-10-12 23:34:36279 prompt: prompt_unix,
280 input: socket,
281 output: socket,
282 useGlobal: true
Fedor Indutny1a52d6a2014-07-31 08:12:18283 }).context.message = message;
Matt Ranneyb7441042010-04-11 23:13:32284 });
285
Ben Noordhuis018e1102011-10-14 23:08:36286 server_unix.on('listening', function() {
Oleg Efimov0ce9cba2010-12-04 22:45:52287 var read_buffer = '';
Ryan Dahla6942b32010-06-08 00:39:24288
Ryan Dahl03a119e2011-08-09 23:06:32289 client_unix = net.createConnection(common.PIPE);
Matt Ranneyb7441042010-04-11 23:13:32290
Ben Noordhuis018e1102011-10-14 23:08:36291 client_unix.on('connect', function() {
Matt Ranneyb7441042010-04-11 23:13:32292 assert.equal(true, client_unix.readable);
293 assert.equal(true, client_unix.writable);
294
295 send_expect([
Oleg Efimov0665f022010-12-05 19:15:30296 { client: client_unix, send: '',
297 expect: prompt_unix },
Nathan Rajlichaab7cb72012-04-06 19:20:01298 { client: client_unix, send: 'message',
Oleg Efimov0665f022010-12-05 19:15:30299 expect: ('\'' + message + '\'\n' + prompt_unix) },
Nathan Rajlichaab7cb72012-04-06 19:20:01300 { client: client_unix, send: 'invoke_me(987)',
Oleg Efimov0665f022010-12-05 19:15:30301 expect: ('\'' + 'invoked 987' + '\'\n' + prompt_unix) },
Nathan Rajlichaab7cb72012-04-06 19:20:01302 { client: client_unix, send: 'a = 12345',
Ryan Dahl8b352bd2011-01-02 05:14:06303 expect: ('12345' + '\n' + prompt_unix) },
Nathan Rajlichaab7cb72012-04-06 19:20:01304 { client: client_unix, send: '{a:1}',
Colton Baker87286cc2011-10-04 22:08:18305 expect: ('{ a: 1 }' + '\n' + prompt_unix) }
Oleg Efimov0665f022010-12-05 19:15:30306 ]);
Matt Ranneyb7441042010-04-11 23:13:32307 });
308
Ben Noordhuis018e1102011-10-14 23:08:36309 client_unix.on('data', function(data) {
Ryan Dahl4fe5e862010-09-06 19:12:36310 read_buffer += data.toString('ascii', 0, data.length);
isaacs4631c502013-08-28 01:53:39311 console.error('Unix data: ' + JSON.stringify(read_buffer) +
Oleg Efimov0ce9cba2010-12-04 22:45:52312 ', expecting ' + JSON.stringify(client_unix.expect));
Matt Ranneyafe3c1c2010-04-12 21:29:49313 if (read_buffer.indexOf(prompt_unix) !== -1) {
314 assert.strictEqual(client_unix.expect, read_buffer);
isaacs4631c502013-08-28 01:53:39315 console.error('match');
Oleg Efimov0ce9cba2010-12-04 22:45:52316 read_buffer = '';
Matt Ranneyafe3c1c2010-04-12 21:29:49317 if (client_unix.list && client_unix.list.length > 0) {
318 send_expect(client_unix.list);
Ryan Dahla6942b32010-06-08 00:39:24319 } else {
isaacs4631c502013-08-28 01:53:39320 console.error('End of Unix test, running Error test.\n');
Marco Rogers118b88e2010-11-20 23:44:58321 process.nextTick(error_test);
Matt Ranneyafe3c1c2010-04-12 21:29:49322 }
Ryan Dahl08d81162010-12-01 21:43:05323 } else {
isaacs4631c502013-08-28 01:53:39324 console.error('didn\'t see prompt yet, buffering.');
Matt Ranneyb7441042010-04-11 23:13:32325 }
326 });
Ryan Dahla6942b32010-06-08 00:39:24327
Ben Noordhuis018e1102011-10-14 23:08:36328 client_unix.on('error', function(e) {
Matt Ranneyb7441042010-04-11 23:13:32329 throw e;
330 });
331
Ben Noordhuis018e1102011-10-14 23:08:36332 client_unix.on('close', function() {
Matt Ranneyb7441042010-04-11 23:13:32333 server_unix.close();
334 });
335 });
336
Ryan Dahl03a119e2011-08-09 23:06:32337 server_unix.listen(common.PIPE);
Matt Ranneyb7441042010-04-11 23:13:32338}
339
340unix_test();
Marco Rogers118b88e2010-11-20 23:44:58341
Oleg Efimov0ce9cba2010-12-04 22:45:52342timer = setTimeout(function() {
343 assert.fail('Timeout');
Ryan Dahl129217a2011-01-26 01:35:06344}, 5000);