diff --git a/AUTHORS b/AUTHORS index 5a212e2828c..8c2a9055b9b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -253,3 +253,8 @@ Dave Irvine Ju-yeong Park Phil Sung Damon Oehlman +Ryunosuke SATO +Michael Bernstein +Guillermo Rauch +Dan Williams +Brandon Benvie diff --git a/ChangeLog b/ChangeLog index 4571c4d3ae0..566ec16a086 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,7 +13,32 @@ * Bug fixes -2012.01.06, Version 0.6.7 (stable) +2012.01.19, Version 0.6.8 (stable) + +* Update V8 to 3.6.6.19 + +* Numeric key hash collision fix for V8 (Erik Corry, Fedor Indutny) + +* Add missing TTY key translations for F1-F5 on Windows (Brandon Benvie) + +* path.extname bugfix with . and .. paths (Bert Belder) + +* cluster: don't always kill the master on uncaughtException (Ben Noordhuis) + +* Update npm to 1.1.0-2 (isaacs) + +* typed arrays: set class name (Ben Noordhuis) + +* zlib binding cleanup (isaacs, Bert Belder) + +* dgram: use slab memory allocator (Michael Bernstein) + +* fix segfault #2473 + +* #2521 60% improvement in fs.stat on Windows (Igor Zinkovsky) + + +2012.01.06, Version 0.6.7 (stable), d5a189acef14a851287ee555f7a39431fe276e1c * V8 hash collision fix (Breaks MIPS) (Bert Belder, Erik Corry) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 6f99f8be48e..4527b24063b 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -6,7 +6,8 @@ knowledge of several libraries: - V8 JavaScript, a C++ library. Used for interfacing with JavaScript: creating objects, calling functions, etc. Documented mostly in the - `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree). + `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree), + which is also available [online](http://izs.me/v8-docs/main.html). - [libuv](https://github.com/joyent/libuv), C event loop library. Anytime one needs to wait for a file descriptor to become readable, wait for a timer, or @@ -22,12 +23,15 @@ Node statically compiles all its dependencies into the executable. When compiling your module, you don't need to worry about linking to any of these libraries. + +### Hello world + To get started let's make a small Addon which is the C++ equivalent of the following Javascript code: exports.hello = function() { return 'world'; }; -To get started we create a file `hello.cc`: +First we create a file `hello.cc`: #include #include @@ -40,7 +44,8 @@ To get started we create a file `hello.cc`: } void init(Handle target) { - NODE_SET_METHOD(target, "hello", Method); + target->Set(String::NewSymbol("hello"), + FunctionTemplate::New(Method)->GetFunction()); } NODE_MODULE(hello, init) @@ -87,5 +92,537 @@ the recently built module: console.log(addon.hello()); // 'world' -For the moment, that is all the documentation on addons. Please see - for a real example. +Please see patterns below for further information or + for an example in production. + + +## Addon patterns + +Below are some addon patterns to help you get started. Consult the online +[v8 reference](http://izs.me/v8-docs/main.html) for help with the various v8 +calls, and v8's [Embedder's Guide](http://code.google.com/apis/v8/embed.html) +for an explanation of several concepts used such as handles, scopes, +function templates, etc. + +To compile these examples, create the `wscript` file below and run +`node-waf configure build`: + + srcdir = '.' + blddir = 'build' + VERSION = '0.0.1' + + def set_options(opt): + opt.tool_options('compiler_cxx') + + def configure(conf): + conf.check_tool('compiler_cxx') + conf.check_tool('node_addon') + + def build(bld): + obj = bld.new_task_gen('cxx', 'shlib', 'node_addon') + obj.target = 'addon' + obj.source = ['addon.cc'] + +In cases where there is more than one `.cc` file, simply add the file name to the +`obj.source` array, e.g.: + + obj.source = ['addon.cc', 'myexample.cc'] + + +#### Function arguments + +The following pattern illustrates how to read arguments from JavaScript +function calls and return a result. This is the main and only needed source +`addon.cc`: + + #define BUILDING_NODE_EXTENSION + #include + + using namespace v8; + + Handle Add(const Arguments& args) { + HandleScope scope; + + if (args.Length() < 2) { + ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); + return scope.Close(Undefined()); + } + + if (!args[0]->IsNumber() || !args[1]->IsNumber()) { + ThrowException(Exception::TypeError(String::New("Wrong arguments"))); + return scope.Close(Undefined()); + } + + Local num = Number::New(args[0]->NumberValue() + + args[1]->NumberValue()); + return scope.Close(num); + } + + void Init(Handle target) { + target->Set(String::NewSymbol("add"), + FunctionTemplate::New(Add)->GetFunction()); + } + + NODE_MODULE(addon, Init) + +You can test it with the following JavaScript snippet: + + var addon = require('./build/Release/addon'); + + console.log( 'This should be eight:', addon.add(3,5) ); + + +#### Callbacks + +You can pass JavaScript functions to a C++ function and execute them from +there. Here's `addon.cc`: + + #define BUILDING_NODE_EXTENSION + #include + + using namespace v8; + + Handle RunCallback(const Arguments& args) { + HandleScope scope; + + Local cb = Local::Cast(args[0]); + const unsigned argc = 1; + Local argv[argc] = { Local::New(String::New("hello world")) }; + cb->Call(Context::GetCurrent()->Global(), argc, argv); + + return scope.Close(Undefined()); + } + + void Init(Handle target) { + target->Set(String::NewSymbol("runCallback"), + FunctionTemplate::New(RunCallback)->GetFunction()); + } + + NODE_MODULE(addon, Init) + +To test it run the following JavaScript snippet: + + var addon = require('./build/Release/addon'); + + addon.runCallback(function(msg){ + console.log(msg); // 'hello world' + }); + + +#### Object factory + +You can create and return new objects from within a C++ function with this +`addon.cc` pattern, which returns an object with property `msg` that echoes +the string passed to `createObject()`: + + #define BUILDING_NODE_EXTENSION + #include + + using namespace v8; + + Handle CreateObject(const Arguments& args) { + HandleScope scope; + + Local obj = Object::New(); + obj->Set(String::NewSymbol("msg"), args[0]->ToString()); + + return scope.Close(obj); + } + + void Init(Handle target) { + target->Set(String::NewSymbol("createObject"), + FunctionTemplate::New(CreateObject)->GetFunction()); + } + + NODE_MODULE(addon, Init) + +To test it in JavaScript: + + var addon = require('./build/Release/addon'); + + var obj1 = addon.createObject('hello'); + var obj2 = addon.createObject('world'); + console.log(obj1.msg+' '+obj2.msg); // 'hello world' + + +#### Function factory + +This pattern illustrates how to create and return a JavaScript function that +wraps a C++ function: + + #define BUILDING_NODE_EXTENSION + #include + + using namespace v8; + + Handle MyFunction(const Arguments& args) { + HandleScope scope; + return scope.Close(String::New("hello world")); + } + + Handle CreateFunction(const Arguments& args) { + HandleScope scope; + + Local tpl = FunctionTemplate::New(MyFunction); + Local fn = tpl->GetFunction(); + fn->SetName(String::NewSymbol("theFunction")); // omit this to make it anonymous + + return scope.Close(fn); + } + + void Init(Handle target) { + target->Set(String::NewSymbol("createFunction"), + FunctionTemplate::New(CreateFunction)->GetFunction()); + } + + NODE_MODULE(addon, Init) + + +To test: + + var addon = require('./build/Release/addon'); + + var fn = addon.createFunction(); + console.log(fn()); // 'hello world' + + +#### Wrapping C++ objects + +Here we will create a wrapper for a C++ object/class `MyObject` that can be +instantiated in JavaScript through the `new` operator. First prepare the main +module `addon.cc`: + + #define BUILDING_NODE_EXTENSION + #include + #include "myobject.h" + + using namespace v8; + + void InitAll(Handle target) { + MyObject::Init(target); + } + + NODE_MODULE(addon, InitAll) + +Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`: + + #ifndef MYOBJECT_H + #define MYOBJECT_H + + #include + + class MyObject : public node::ObjectWrap { + public: + static void Init(v8::Handle target); + + private: + MyObject(); + ~MyObject(); + + static v8::Handle New(const v8::Arguments& args); + static v8::Handle PlusOne(const v8::Arguments& args); + double counter_; + }; + + #endif + +And in `myobject.cc` implement the various methods that you want to expose. +Here we expose the method `plusOne` by adding it to the constructor's +prototype: + + #define BUILDING_NODE_EXTENSION + #include + #include "myobject.h" + + using namespace v8; + + MyObject::MyObject() {}; + MyObject::~MyObject() {}; + + void MyObject::Init(Handle target) { + // Prepare constructor template + Local tpl = FunctionTemplate::New(New); + tpl->SetClassName(String::NewSymbol("MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + // Prototype + tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"), + FunctionTemplate::New(PlusOne)->GetFunction()); + + Persistent constructor = Persistent::New(tpl->GetFunction()); + target->Set(String::NewSymbol("MyObject"), constructor); + } + + Handle MyObject::New(const Arguments& args) { + HandleScope scope; + + MyObject* obj = new MyObject(); + obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + obj->Wrap(args.This()); + + return args.This(); + } + + Handle MyObject::PlusOne(const Arguments& args) { + HandleScope scope; + + MyObject* obj = ObjectWrap::Unwrap(args.This()); + obj->counter_ += 1; + + return scope.Close(Number::New(obj->counter_)); + } + +Test it with: + + var addon = require('./build/Release/addon'); + + var obj = new addon.MyObject(10); + console.log( obj.plusOne() ); // 11 + console.log( obj.plusOne() ); // 12 + console.log( obj.plusOne() ); // 13 + + +#### Factory of wrapped objects + +This is useful when you want to be able to create native objects without +explicitly instantiating them with the `new` operator in JavaScript, e.g. + + var obj = addon.createObject(); + // instead of: + // var obj = new addon.Object(); + +Let's register our `createObject` method in `addon.cc`: + + #define BUILDING_NODE_EXTENSION + #include + #include "myobject.h" + + using namespace v8; + + Handle CreateObject(const Arguments& args) { + HandleScope scope; + return scope.Close(MyObject::NewInstance(args)); + } + + void InitAll(Handle target) { + MyObject::Init(); + + target->Set(String::NewSymbol("createObject"), + FunctionTemplate::New(CreateObject)->GetFunction()); + } + + NODE_MODULE(addon, InitAll) + +In `myobject.h` we now introduce the static method `NewInstance` that takes +care of instantiating the object (i.e. it does the job of `new` in JavaScript): + + #define BUILDING_NODE_EXTENSION + #ifndef MYOBJECT_H + #define MYOBJECT_H + + #include + + class MyObject : public node::ObjectWrap { + public: + static void Init(); + static v8::Handle NewInstance(const v8::Arguments& args); + + private: + MyObject(); + ~MyObject(); + + static v8::Persistent constructor; + static v8::Handle New(const v8::Arguments& args); + static v8::Handle PlusOne(const v8::Arguments& args); + double counter_; + }; + + #endif + +The implementation is similar to the above in `myobject.cc`: + + #define BUILDING_NODE_EXTENSION + #include + #include "myobject.h" + + using namespace v8; + + MyObject::MyObject() {}; + MyObject::~MyObject() {}; + + Persistent MyObject::constructor; + + void MyObject::Init() { + // Prepare constructor template + Local tpl = FunctionTemplate::New(New); + tpl->SetClassName(String::NewSymbol("MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + // Prototype + tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"), + FunctionTemplate::New(PlusOne)->GetFunction()); + + constructor = Persistent::New(tpl->GetFunction()); + } + + Handle MyObject::New(const Arguments& args) { + HandleScope scope; + + MyObject* obj = new MyObject(); + obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + obj->Wrap(args.This()); + + return args.This(); + } + + Handle MyObject::NewInstance(const Arguments& args) { + HandleScope scope; + + const unsigned argc = 1; + Handle argv[argc] = { args[0] }; + Local instance = constructor->NewInstance(argc, argv); + + return scope.Close(instance); + } + + Handle MyObject::PlusOne(const Arguments& args) { + HandleScope scope; + + MyObject* obj = ObjectWrap::Unwrap(args.This()); + obj->counter_ += 1; + + return scope.Close(Number::New(obj->counter_)); + } + +Test it with: + + var addon = require('./build/Release/addon'); + + var obj = addon.createObject(10); + console.log( obj.plusOne() ); // 11 + console.log( obj.plusOne() ); // 12 + console.log( obj.plusOne() ); // 13 + + var obj2 = addon.createObject(20); + console.log( obj2.plusOne() ); // 21 + console.log( obj2.plusOne() ); // 22 + console.log( obj2.plusOne() ); // 23 + + +#### Passing wrapped objects around + +In addition to wrapping and returning C++ objects, you can pass them around +by unwrapping them with Node's `node::ObjectWrap::Unwrap` helper function. +In the following `addon.cc` we introduce a function `add()` that can take on two +`MyObject` objects: + + #define BUILDING_NODE_EXTENSION + #include + #include "myobject.h" + + using namespace v8; + + Handle CreateObject(const Arguments& args) { + HandleScope scope; + return scope.Close(MyObject::NewInstance(args)); + } + + Handle Add(const Arguments& args) { + HandleScope scope; + + MyObject* obj1 = node::ObjectWrap::Unwrap( + args[0]->ToObject()); + MyObject* obj2 = node::ObjectWrap::Unwrap( + args[1]->ToObject()); + + double sum = obj1->Val() + obj2->Val(); + return scope.Close(Number::New(sum)); + } + + void InitAll(Handle target) { + MyObject::Init(); + + target->Set(String::NewSymbol("createObject"), + FunctionTemplate::New(CreateObject)->GetFunction()); + + target->Set(String::NewSymbol("add"), + FunctionTemplate::New(Add)->GetFunction()); + } + + NODE_MODULE(addon, InitAll) + +To make things interesting we introduce a public method in `myobject.h` so we +can probe private values after unwrapping the object: + + #define BUILDING_NODE_EXTENSION + #ifndef MYOBJECT_H + #define MYOBJECT_H + + #include + + class MyObject : public node::ObjectWrap { + public: + static void Init(); + static v8::Handle NewInstance(const v8::Arguments& args); + double Val() const { return val_; } + + private: + MyObject(); + ~MyObject(); + + static v8::Persistent constructor; + static v8::Handle New(const v8::Arguments& args); + double val_; + }; + + #endif + +The implementation of `myobject.cc` is similar as before: + + #define BUILDING_NODE_EXTENSION + #include + #include "myobject.h" + + using namespace v8; + + MyObject::MyObject() {}; + MyObject::~MyObject() {}; + + Persistent MyObject::constructor; + + void MyObject::Init() { + // Prepare constructor template + Local tpl = FunctionTemplate::New(New); + tpl->SetClassName(String::NewSymbol("MyObject")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + constructor = Persistent::New(tpl->GetFunction()); + } + + Handle MyObject::New(const Arguments& args) { + HandleScope scope; + + MyObject* obj = new MyObject(); + obj->val_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + obj->Wrap(args.This()); + + return args.This(); + } + + Handle MyObject::NewInstance(const Arguments& args) { + HandleScope scope; + + const unsigned argc = 1; + Handle argv[argc] = { args[0] }; + Local instance = constructor->NewInstance(argc, argv); + + return scope.Close(instance); + } + +Test it with: + + var addon = require('./build/Release/addon'); + + var obj1 = addon.createObject(10); + var obj2 = addon.createObject(20); + var result = addon.add(obj1, obj2); + + console.log(result); // 30 diff --git a/doc/api/appendix_1.markdown b/doc/api/appendix_1.markdown index d25d7f9f3c3..59430c20e25 100644 --- a/doc/api/appendix_1.markdown +++ b/doc/api/appendix_1.markdown @@ -38,7 +38,7 @@ elsewhere. - [ncurses](https://github.com/mscdex/node-ncurses) - Testing/TDD/BDD: [vows](http://vowsjs.org/), - [expresso](https://github.com/visionmedia/expresso), + [mocha](https://github.com/visionmedia/mocha), [mjsunit.runner](https://github.com/tmpvar/mjsunit.runner) Patches to this list are welcome. diff --git a/doc/community/index.html b/doc/community/index.html index dec8b58b900..3219f7bf847 100644 --- a/doc/community/index.html +++ b/doc/community/index.html @@ -28,7 +28,11 @@
-

Node's most valuable feature is the friendly and colorful community of developers. There are many places where this group congregates on the internet. This page attempts to highlight the best forums.

+

Node's most valuable feature is the friendly and colorful + community of developers. There are many places where + this group congregates on the internet. This page attempts + to highlight the best forums.

Periodicals

diff --git a/doc/index.html b/doc/index.html index 61f10893d7b..3769002f911 100644 --- a/doc/index.html +++ b/doc/index.html @@ -77,15 +77,15 @@ X
diff --git a/lib/child_process.js b/lib/child_process.js index 5ba6065cb04..9cdf7d6eecb 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -146,7 +146,7 @@ function setupChannel(target, channel) { var writeReq = channel.write(buffer, 0, buffer.length, sendHandle); if (!writeReq) { - throw new Error(errno + 'cannot write to IPC channel.'); + throw errnoException(errno, 'write', 'cannot write to IPC channel.'); } writeReq.oncomplete = nop; @@ -496,11 +496,15 @@ ChildProcess.prototype.spawn = function(options) { }; -function errnoException(errorno, syscall) { +function errnoException(errorno, syscall, errmsg) { // TODO make this more compatible with ErrnoException from src/node.cc // Once all of Node is using this function the ErrnoException from // src/node.cc should be removed. - var e = new Error(syscall + ' ' + errorno); + var message = syscall + ' ' + errorno; + if (errmsg) { + message += ' - ' + errmsg; + } + var e = new Error(message); e.errno = e.code = errorno; e.syscall = syscall; return e; diff --git a/lib/dgram.js b/lib/dgram.js index 26e0a2a3e81..d5c2e0da69c 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -223,7 +223,11 @@ Socket.prototype.address = function() { Socket.prototype.setBroadcast = function(arg) { - throw new Error('not yet implemented'); + if (this._handle.setBroadcast((arg) ? 1 : 0) == -1) { + throw errnoException(errno, 'setBroadcast'); + } + + return true; }; @@ -233,7 +237,11 @@ Socket.prototype.setTTL = function(arg) { Socket.prototype.setMulticastTTL = function(arg) { - throw new Error('not yet implemented'); + if (this._handle.setMulticastTTL(arg) == -1) { + throw errnoException(errno, 'setMulticastTTL'); + } + + return true; }; @@ -243,16 +251,26 @@ Socket.prototype.setMulticastLoopback = function(arg) { Socket.prototype.addMembership = function(multicastAddress, - multicastInterface) { - // are we ever going to support this in libuv? - throw new Error('not yet implemented'); + interfaceAddress) { + this._healthCheck(); + + if (!multicastAddress) { + throw new Error('multicast address must be specified'); + } + + return this._handle.addMembership(multicastAddress, interfaceAddress); }; Socket.prototype.dropMembership = function(multicastAddress, - multicastInterface) { - // are we ever going to support this in libuv? - throw new Error('not yet implemented'); + interfaceAddress) { + this._healthCheck(); + + if (!multicastAddress) { + throw new Error('multicast address must be specified'); + } + + return this._handle.dropMembership(multicastAddress, interfaceAddress); }; diff --git a/lib/http.js b/lib/http.js index 14e41ba24c9..7ad7765a668 100644 --- a/lib/http.js +++ b/lib/http.js @@ -1181,13 +1181,23 @@ ClientRequest.prototype.onSocket = function(socket) { // Setup "drain" propogation. httpSocketSetup(socket); + var freeParser = function() { + if (parser) { + parsers.free(parser); + parser = null; + } + }; + var errorListener = function(err) { debug('HTTP SOCKET ERROR: ' + err.message + '\n' + err.stack); req.emit('error', err); // For Safety. Some additional errors might fire later on // and we need to make sure we don't double-fire the error event. req._hadError = true; - parser.finish(); + if (parser) { + parser.finish(); + freeParser(); + } socket.destroy(); } socket.on('error', errorListener); @@ -1196,6 +1206,7 @@ ClientRequest.prototype.onSocket = function(socket) { var ret = parser.execute(d, start, end - start); if (ret instanceof Error) { debug('parse error'); + freeParser(); socket.destroy(ret); } else if (parser.incoming && parser.incoming.upgrade) { // Upgrade or CONNECT @@ -1226,6 +1237,9 @@ ClientRequest.prototype.onSocket = function(socket) { // Got Upgrade header or CONNECT method, but have no handler. socket.destroy(); } + freeParser(); + } else if (parser.incoming && parser.incoming.complete) { + freeParser(); } }; @@ -1236,8 +1250,10 @@ ClientRequest.prototype.onSocket = function(socket) { req.emit('error', createHangUpError()); req._hadError = true; } - parser.finish(); - parsers.free(parser); // I don't know if this is necessary --Mikeal + if (parser) { + parser.finish(); + freeParser(); + } socket.destroy(); }; diff --git a/lib/path.js b/lib/path.js index 6a744dfeca7..bdae368c256 100644 --- a/lib/path.js +++ b/lib/path.js @@ -62,7 +62,7 @@ if (isWindows) { /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/; // Regex to split the tail part of the above into [*, dir, basename, ext] - var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:[\s\S]+?)?(\.[^.]*)?)$/; + var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/; // Function to split a filename into [root, dir, basename, ext] // windows version @@ -256,7 +256,7 @@ if (isWindows) { // Split a filename into [root, dir, basename, ext], unix version // 'root' is just a slash, or nothing. - var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/; + var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/; var splitPath = function(filename) { var result = splitPathRe.exec(filename); return [result[1] || '', result[2] || '', result[3] || '', result[4] || '']; diff --git a/lib/tls.js b/lib/tls.js index c8f2ed27d0d..faf81c06649 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -271,7 +271,11 @@ CryptoStream.prototype._done = function() { this.pair.encrypted._doneFlag && !this.pair._doneFlag) { // If both streams are done: - this.pair.destroy(); + if (!this.pair._secureEstablished) { + this.pair.error(); + } else { + this.pair.destroy(); + } } }; @@ -724,7 +728,6 @@ SecurePair.prototype.destroy = function() { } var self = this; - var error = this.ssl.error; this._doneFlag = true; this.ssl.error = null; @@ -739,20 +742,18 @@ SecurePair.prototype.destroy = function() { self.encrypted.emit('close'); self.cleartext.emit('close'); }); - - if (!this._secureEstablished) { - if (!error) { - error = new Error('socket hang up'); - error.code = 'ECONNRESET'; - } - this.emit('error', error); - } }; SecurePair.prototype.error = function() { if (!this._secureEstablished) { + var error = this.ssl.error; + if (!error) { + error = new Error('socket hang up'); + error.code = 'ECONNRESET'; + } this.destroy(); + this.emit('error', error); } else { var err = this.ssl.error; this.ssl.error = null; diff --git a/lib/tty.js b/lib/tty.js index 32ba512d525..dccda5a4812 100644 --- a/lib/tty.js +++ b/lib/tty.js @@ -225,6 +225,13 @@ ReadStream.prototype._emitKey = function(s) { case '[13~': key.name = 'f3'; break; case '[14~': key.name = 'f4'; break; + /* from Cygwin and used in libuv */ + case '[[A': key.name = 'f1'; break; + case '[[B': key.name = 'f2'; break; + case '[[C': key.name = 'f3'; break; + case '[[D': key.name = 'f4'; break; + case '[[E': key.name = 'f5'; break; + /* common */ case '[15~': key.name = 'f5'; break; case '[17~': key.name = 'f6'; break; diff --git a/lib/util.js b/lib/util.js index 8cc4739f275..d3b13066f88 100644 --- a/lib/util.js +++ b/lib/util.js @@ -296,29 +296,28 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str; - if (value.__lookupGetter__) { - if (value.__lookupGetter__(key)) { - if (value.__lookupSetter__(key)) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); } else { - if (value.__lookupSetter__(key)) { - str = ctx.stylize('[Setter]', 'special'); - } + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); } } if (visibleKeys.indexOf(key) < 0) { name = '[' + key + ']'; } if (!str) { - if (ctx.seen.indexOf(value[key]) < 0) { + if (ctx.seen.indexOf(desc.value) < 0) { if (recurseTimes === null) { - str = formatValue(ctx, value[key], null); + str = formatValue(ctx, desc.value, null); } else { - str = formatValue(ctx, value[key], recurseTimes - 1); + str = formatValue(ctx, desc.value, recurseTimes - 1); } if (str.indexOf('\n') > -1) { if (array) { diff --git a/lib/zlib.js b/lib/zlib.js index 339f1e71356..349c5c64d97 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -122,18 +122,18 @@ function zlibBuffer(engine, buffer, callback) { var buffers = []; var nread = 0; - engine.on('error', function(err) { - engine.removeListener('end'); - engine.removeListener('error'); + function onError(err) { + engine.removeListener('end', onEnd); + engine.removeListener('error', onError); callback(err); - }); + } - engine.on('data', function(chunk) { + function onData(chunk) { buffers.push(chunk); nread += chunk.length; - }); + } - engine.on('end', function() { + function onEnd() { var buffer; switch(buffers.length) { case 0: @@ -153,7 +153,11 @@ function zlibBuffer(engine, buffer, callback) { break; } callback(null, buffer); - }); + } + + engine.on('error', onError); + engine.on('data', onData); + engine.on('end', onEnd); engine.write(buffer); engine.end(); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 7e547ee5759..59cb7fbb292 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -592,6 +592,7 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) { if (rv >= 0) return rv; int retry = BIO_should_retry(bio); + (void) retry; // unused if !defined(SSL_PRINT_DEBUG) if (BIO_should_write(bio)) { DEBUG_PRINT("[%p] BIO: %s want write. should retry %d\n", ssl_, func, retry); diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 6d79410779a..c3099d65ee8 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -92,6 +92,10 @@ public: static Handle RecvStart(const Arguments& args); static Handle RecvStop(const Arguments& args); static Handle GetSockName(const Arguments& args); + static Handle AddMembership(const Arguments& args); + static Handle DropMembership(const Arguments& args); + static Handle SetMulticastTTL(const Arguments& args); + static Handle SetBroadcast(const Arguments& args); private: static inline char* NewSlab(v8::Handle global, v8::Handle wrap_obj); @@ -101,6 +105,8 @@ private: static Handle DoBind(const Arguments& args, int family); static Handle DoSend(const Arguments& args, int family); + static Handle SetMembership(const Arguments& args, + uv_membership membership); static uv_buf_t OnAlloc(uv_handle_t* handle, size_t suggested_size); static void OnSend(uv_udp_send_t* req, int status); @@ -148,6 +154,10 @@ void UDPWrap::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(t, "recvStart", RecvStart); NODE_SET_PROTOTYPE_METHOD(t, "recvStop", RecvStop); NODE_SET_PROTOTYPE_METHOD(t, "getsockname", GetSockName); + NODE_SET_PROTOTYPE_METHOD(t, "addMembership", AddMembership); + NODE_SET_PROTOTYPE_METHOD(t, "dropMembership", DropMembership); + NODE_SET_PROTOTYPE_METHOD(t, "setMulticastTTL", SetMulticastTTL); + NODE_SET_PROTOTYPE_METHOD(t, "setBroadcast", SetBroadcast); target->Set(String::NewSymbol("UDP"), Persistent::New(t)->GetFunction()); @@ -204,6 +214,69 @@ Handle UDPWrap::Bind6(const Arguments& args) { return DoBind(args, AF_INET6); } +Handle UDPWrap::SetBroadcast(const Arguments& args) { + HandleScope scope; + UNWRAP + + assert(args.Length() == 1); + + int on = args[0]->Uint32Value(); + int r = uv_udp_set_broadcast(&wrap->handle_, on); + + if (r) + SetErrno(uv_last_error(uv_default_loop())); + + return scope.Close(Integer::New(r)); +} + +Handle UDPWrap::SetMembership(const Arguments& args, + uv_membership membership) { + HandleScope scope; + UNWRAP + + assert(args.Length() == 2); + + String::Utf8Value address(args[0]->ToString()); + String::Utf8Value interface(args[1]->ToString()); + + const char* interface_cstr = *interface; + if (args[1]->IsUndefined() || args[1]->IsNull()) { + interface_cstr = NULL; + } + + int r = uv_udp_set_membership(&wrap->handle_, *address, interface_cstr, + membership); + + if (r) + SetErrno(uv_last_error(uv_default_loop())); + + return scope.Close(Integer::New(r)); +} + + +Handle UDPWrap::AddMembership(const Arguments& args) { + return SetMembership(args, UV_JOIN_GROUP); +} + + +Handle UDPWrap::DropMembership(const Arguments& args) { + return SetMembership(args, UV_LEAVE_GROUP); +} + +Handle UDPWrap::SetMulticastTTL(const Arguments& args) { + HandleScope scope; + UNWRAP + + assert(args.Length() == 1); + + int ttl = args[0]->Uint32Value(); + int r = uv_udp_set_multicast_ttl(&wrap->handle_, ttl); + + if (r) + SetErrno(uv_last_error(uv_default_loop())); + + return scope.Close(Integer::New(r)); +} Handle UDPWrap::DoSend(const Arguments& args, int family) { HandleScope scope; diff --git a/src/v8_typed_array.cc b/src/v8_typed_array.cc index c25f5451e5f..9941845fc55 100644 --- a/src/v8_typed_array.cc +++ b/src/v8_typed_array.cc @@ -141,6 +141,7 @@ class TypedArray { v8::HandleScope scope; ft_cache = v8::Persistent::New( v8::FunctionTemplate::New(&TypedArray::V8New)); + ft_cache->SetClassName(v8::String::New(TypeName())); v8::Local instance = ft_cache->InstanceTemplate(); instance->SetInternalFieldCount(0); @@ -434,6 +435,20 @@ class TypedArray { return TypedArray::GetTemplate()-> GetFunction()->NewInstance(3, argv); } + + static const char* TypeName() { + switch (TEAType) { + case v8::kExternalByteArray: return "Int8Array"; + case v8::kExternalUnsignedByteArray: return "Uint8Array"; + case v8::kExternalShortArray: return "Int16Array"; + case v8::kExternalUnsignedShortArray: return "Uint16Array"; + case v8::kExternalIntArray: return "Int32Array"; + case v8::kExternalUnsignedIntArray: return "Uint32Array"; + case v8::kExternalFloatArray: return "Float32Array"; + case v8::kExternalDoubleArray: return "Float64Array"; + } + abort(); + } }; class Int8Array : public TypedArray<1, v8::kExternalByteArray> { }; diff --git a/test/common.js b/test/common.js index d9fa7b70e82..202d1fa9bce 100644 --- a/test/common.js +++ b/test/common.js @@ -55,7 +55,7 @@ exports.indirectInstanceOf = function(obj, cls) { exports.ddCommand = function(filename, kilobytes) { if (process.platform == 'win32') { return '"' + process.argv[0] + '" "' + path.resolve(exports.fixturesDir, - 'create-file.js') + '" "' + filename + '" ' + (kilobytes * 1024); + 'create-file.js') + '" "' + filename + '" ' + (kilobytes * 1024); } else { return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes; } diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index 095b47ad664..9da388cb54f 100644 --- a/test/internet/test-dns.js +++ b/test/internet/test-dns.js @@ -383,11 +383,11 @@ TEST(function test_lookup_localhost_ipv4(done) { var getaddrinfoCallbackCalled = false; -console.log("looking up nodejs.org..."); +console.log('looking up nodejs.org...'); var req = process.binding('cares_wrap').getaddrinfo('nodejs.org'); req.oncomplete = function(domains) { - console.log("nodejs.org = ", domains); + console.log('nodejs.org = ', domains); assert.ok(Array.isArray(domains)); assert.ok(domains.length >= 1); assert.ok(typeof domains[0] == 'string'); diff --git a/test/message/throw_custom_error.js b/test/message/throw_custom_error.js index 5c994c009db..bef7f5dab01 100644 --- a/test/message/throw_custom_error.js +++ b/test/message/throw_custom_error.js @@ -28,6 +28,6 @@ var assert = require('assert'); common.error('before'); // custom error throwing -throw { name: 'MyCustomError', message: 'This is a custom message' } +throw { name: 'MyCustomError', message: 'This is a custom message' }; common.error('after'); diff --git a/test/message/throw_non_error.js b/test/message/throw_non_error.js index 702a40d9b6d..afea96f49ce 100644 --- a/test/message/throw_non_error.js +++ b/test/message/throw_non_error.js @@ -28,6 +28,6 @@ var assert = require('assert'); common.error('before'); // custom error throwing -throw { foo: 'bar' } +throw { foo: 'bar' }; common.error('after'); diff --git a/test/pummel/test-net-timeout2.js b/test/pummel/test-net-timeout2.js index 2e2568b490c..16f69cc022a 100644 --- a/test/pummel/test-net-timeout2.js +++ b/test/pummel/test-net-timeout2.js @@ -32,12 +32,12 @@ var counter = 0; var server = net.createServer(function(socket) { socket.setTimeout((seconds / 2) * 1000, function() { gotTimeout = true; - console.log('timeout!!'); - socket.destroy(); + console.log('timeout!!'); + socket.destroy(); process.exit(1); - }); + }); - var interval = setInterval(function() { + var interval = setInterval(function() { counter++; if (counter == seconds) { @@ -46,9 +46,9 @@ var server = net.createServer(function(socket) { socket.destroy(); } - if (socket.writable) { - socket.write(Date.now()+'\n'); - } + if (socket.writable) { + socket.write(Date.now() + '\n'); + } }, 1000); }); diff --git a/test/simple/test-assert.js b/test/simple/test-assert.js index 1c68c44b294..84c333b5744 100644 --- a/test/simple/test-assert.js +++ b/test/simple/test-assert.js @@ -214,7 +214,7 @@ threw = false; try { assert.throws( function() { - throw {} + throw {}; }, Array ); diff --git a/test/simple/test-child-process-double-pipe.js b/test/simple/test-child-process-double-pipe.js index cb1edfae54e..b0fc11d33ff 100644 --- a/test/simple/test-child-process-double-pipe.js +++ b/test/simple/test-child-process-double-pipe.js @@ -28,11 +28,16 @@ var assert = require('assert'), // We're trying to reproduce: // $ echo "hello\nnode\nand\nworld" | grep o | sed s/o/a/ -var echo = is_windows ? spawn('cmd.exe', ['/c', 'echo', 'hello&&', 'echo', - 'node&&', 'echo', 'and&&', 'echo', 'world']) : - spawn('echo', ['hello\nnode\nand\nworld\n']), - grep = spawn('grep', ['o']), - sed = spawn('sed', ['s/o/O/']); +var grep = spawn('grep', ['o']), + sed = spawn('sed', ['s/o/O/']), + echo; + +if (is_windows) { + echo = spawn('cmd.exe', ['/c', 'echo', 'hello&&', 'echo', + 'node&&', 'echo', 'and&&', 'echo', 'world']); +} else { + echo = spawn('echo', ['hello\nnode\nand\nworld\n']); +} /* * grep and sed hang if the spawn function leaks file descriptors to child diff --git a/test/simple/test-child-process-fork2.js b/test/simple/test-child-process-fork2.js index 70c39deb3ac..66dff69ac52 100644 --- a/test/simple/test-child-process-fork2.js +++ b/test/simple/test-child-process-fork2.js @@ -51,12 +51,12 @@ server.listen(common.PORT, function() { function makeConnections() { for (var i = 0; i < N; i++) { var socket = net.connect(common.PORT, function() { - console.log("CLIENT connected"); + console.log('CLIENT connected'); }); - socket.on("close", function() { + socket.on('close', function() { socketCloses++; - console.log("CLIENT closed " + socketCloses); + console.log('CLIENT closed ' + socketCloses); if (socketCloses == N) { n.kill(); server.close(); diff --git a/test/simple/test-cluster-uncaught-exception.js b/test/simple/test-cluster-uncaught-exception.js new file mode 100644 index 00000000000..48a82512704 --- /dev/null +++ b/test/simple/test-cluster-uncaught-exception.js @@ -0,0 +1,59 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Installing a custom uncaughtException handler should override the default +// one that the cluster module installs. +// https://github.com/joyent/node/issues/2556 + +var common = require('../common'); +var assert = require('assert'); +var cluster = require('cluster'); +var fork = require('child_process').fork; + +var MAGIC_EXIT_CODE = 42; + +var isTestRunner = process.argv[2] != 'child'; + +if (isTestRunner) { + var exitCode = -1; + + process.on('exit', function() { + assert.equal(exitCode, MAGIC_EXIT_CODE); + }); + + var master = fork(__filename, ['child']); + master.on('exit', function(code) { + exitCode = code; + }); +} +else if (cluster.isMaster) { + process.on('uncaughtException', function() { + process.nextTick(function() { + process.exit(MAGIC_EXIT_CODE); + }); + }); + + cluster.fork(); + throw new Error('kill master'); +} +else { // worker + process.exit(); +} diff --git a/test/simple/test-crypto-ecb.js b/test/simple/test-crypto-ecb.js index 23a5e682f12..1ffaa4f24be 100644 --- a/test/simple/test-crypto-ecb.js +++ b/test/simple/test-crypto-ecb.js @@ -35,17 +35,16 @@ try { // Testing whether EVP_CipherInit_ex is functioning correctly. // Reference: bug#1997 -(function() -{ +(function() { var encrypt = crypto.createCipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', ''); var hex = encrypt.update('Hello World!', 'ascii', 'hex'); hex += encrypt.final('hex'); assert.equal(hex.toUpperCase(), '6D385F424AAB0CFBF0BB86E07FFB7D71'); }()); -(function() -{ - var decrypt = crypto.createDecipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', ''); +(function() { + var decrypt = crypto.createDecipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', + ''); var msg = decrypt.update('6D385F424AAB0CFBF0BB86E07FFB7D71', 'hex', 'ascii'); msg += decrypt.final('ascii'); assert.equal(msg, 'Hello World!'); diff --git a/test/simple/test-dgram-broadcast-multi-process.js b/test/simple/test-dgram-broadcast-multi-process.js new file mode 100644 index 00000000000..d0a98aa1cf3 --- /dev/null +++ b/test/simple/test-dgram-broadcast-multi-process.js @@ -0,0 +1,160 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'), + assert = require('assert'), + cluster = require('cluster'), + dgram = require('dgram'), + util = require('util'), + assert = require('assert'), + Buffer = require('buffer').Buffer, + LOCAL_BROADCAST_HOST = '255.255.255.255', + messages = [ + new Buffer('First message to send'), + new Buffer('Second message to send'), + new Buffer('Third message to send'), + new Buffer('Fourth message to send') + ]; + +if (cluster.isMaster) { + var workers = {}, + listeners = 3, + listening = 0, + i = 0, + done = 0; + + //launch child processes + for (var x = 0; x < listeners; x++) { + (function () { + var worker = cluster.fork(); + workers[worker.pid] = worker; + + worker.messagesReceived = []; + + worker.on('message', function (msg) { + if (msg.listening) { + listening += 1; + + if (listening === listeners) { + //all child process are listening, so start sending + sendSocket.sendNext(); + } + } + else if (msg.message) { + worker.messagesReceived.push(msg.message); + + if (worker.messagesReceived.length === messages.length) { + done += 1; + console.error('%d received %d messages total.', worker.pid, + worker.messagesReceived.length); + } + + if (done === listeners) { + console.error('All workers have received the required number of ' + + 'messages. Will now compare.'); + + Object.keys(workers).forEach(function (pid) { + var worker = workers[pid]; + + var count = 0; + + worker.messagesReceived.forEach(function(buf) { + for (var i = 0; i < messages.length; ++i) { + if (buf.toString() === messages[i].toString()) { + count++; + break; + } + } + }); + + console.error('%d received %d matching messges.', worker.pid + , count); + + assert.equal(count, messages.length + ,'A worker received an invalid multicast message'); + }); + } + } + }); + })(x); + } + + var sendSocket = dgram.createSocket('udp4'); + + sendSocket.bind(common.PORT); + sendSocket.setBroadcast(true); + + sendSocket.on('close', function() { + console.error('sendSocket closed'); + }); + + sendSocket.sendNext = function() { + var buf = messages[i++]; + + if (!buf) { + try { sendSocket.close(); } catch (e) {} + return; + } + + sendSocket.send(buf, 0, buf.length, + common.PORT, LOCAL_BROADCAST_HOST, function(err) { + + if (err) throw err; + + console.error('sent %s to %s:%s', util.inspect(buf.toString()) + , LOCAL_BROADCAST_HOST, common.PORT); + + process.nextTick(sendSocket.sendNext); + }); + }; +} + +if (!cluster.isMaster) { + var receivedMessages = []; + var listenSocket = dgram.createSocket('udp4'); + + listenSocket.on('message', function(buf, rinfo) { + console.error('%s received %s from %j', process.pid + , util.inspect(buf.toString()), rinfo); + + receivedMessages.push(buf); + + process.send({ message : buf.toString() }); + + if (receivedMessages.length == messages.length) { + listenSocket.dropMembership(LOCAL_BROADCAST_HOST); + process.nextTick(function() { // TODO should be changed to below. + // listenSocket.dropMembership(LOCAL_BROADCAST_HOST, function() { + listenSocket.close(); + }); + } + }); + + listenSocket.on('close', function() { + process.exit(); + }); + + listenSocket.on('listening', function() { + process.send({ listening : true }); + }); + + listenSocket.bind(common.PORT); +} diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js new file mode 100644 index 00000000000..784bb6c0943 --- /dev/null +++ b/test/simple/test-dgram-multicast-multi-process.js @@ -0,0 +1,160 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'), + assert = require('assert'), + cluster = require('cluster'), + dgram = require('dgram'), + util = require('util'), + assert = require('assert'), + Buffer = require('buffer').Buffer, + LOCAL_BROADCAST_HOST = '224.0.0.1', + messages = [ + new Buffer('First message to send'), + new Buffer('Second message to send'), + new Buffer('Third message to send'), + new Buffer('Fourth message to send') + ]; + +if (cluster.isMaster) { + var workers = {}, + listeners = 3, + listening = 0, + i = 0, + done = 0; + + //launch child processes + for (var x = 0; x < listeners; x++) { + (function () { + var worker = cluster.fork(); + workers[worker.pid] = worker; + + worker.messagesReceived = []; + + worker.on('message', function (msg) { + if (msg.listening) { + listening += 1; + + if (listening === listeners) { + //all child process are listening, so start sending + sendSocket.sendNext(); + } + } + else if (msg.message) { + worker.messagesReceived.push(msg.message); + + if (worker.messagesReceived.length === messages.length) { + done += 1; + console.error('%d received %d messages total.', worker.pid, + worker.messagesReceived.length); + } + + if (done === listeners) { + console.error('All workers have received the required number of' + + 'messages. Will now compare.'); + + Object.keys(workers).forEach(function (pid) { + var worker = workers[pid]; + + var count = 0; + + worker.messagesReceived.forEach(function(buf) { + for (var i = 0; i < messages.length; ++i) { + if (buf.toString() === messages[i].toString()) { + count++; + break; + } + } + }); + + console.error('%d received %d matching messges.', worker.pid + , count); + + assert.equal(count, messages.length + ,'A worker received an invalid multicast message'); + }); + } + } + }); + })(x); + } + + var sendSocket = dgram.createSocket('udp4'); + + //sendSocket.setBroadcast(true); + //sendSocket.setMulticastTTL(1); + //sendSocket.setMulticastLoopback(true); + + sendSocket.on('close', function() { + console.error('sendSocket closed'); + }); + + sendSocket.sendNext = function() { + var buf = messages[i++]; + + if (!buf) { + try { sendSocket.close(); } catch (e) {} + return; + } + + sendSocket.send(buf, 0, buf.length, + common.PORT, LOCAL_BROADCAST_HOST, function(err) { + if (err) throw err; + console.error('sent %s to %s', util.inspect(buf.toString()), + LOCAL_BROADCAST_HOST + common.PORT); + process.nextTick(sendSocket.sendNext); + }); + }; +} + +if (!cluster.isMaster) { + var receivedMessages = []; + var listenSocket = dgram.createSocket('udp4'); + + listenSocket.addMembership(LOCAL_BROADCAST_HOST); + + listenSocket.on('message', function(buf, rinfo) { + console.error('%s received %s from %j', process.pid + ,util.inspect(buf.toString()), rinfo); + + receivedMessages.push(buf); + + process.send({ message : buf.toString() }); + + if (receivedMessages.length == messages.length) { + listenSocket.dropMembership(LOCAL_BROADCAST_HOST); + process.nextTick(function() { // TODO should be changed to below. + // listenSocket.dropMembership(LOCAL_BROADCAST_HOST, function() { + listenSocket.close(); + }); + } + }); + + listenSocket.on('close', function() { + process.exit(); + }); + + listenSocket.on('listening', function() { + process.send({ listening : true }); + }); + + listenSocket.bind(common.PORT); +} diff --git a/test/simple/test-dgram-multicast-setTTL.js b/test/simple/test-dgram-multicast-setTTL.js new file mode 100644 index 00000000000..a2207a78d00 --- /dev/null +++ b/test/simple/test-dgram-multicast-setTTL.js @@ -0,0 +1,41 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'), + assert = require('assert'), + dgram = require('dgram'), + thrown = false, + socket = dgram.createSocket('udp4'); + +socket.bind(common.PORT); +socket.setMulticastTTL(16); + +//Try to set an invalid TTL (valid ttl is > 0 and < 256) +try { + socket.setMulticastTTL(1000); +} catch (e) { + thrown = true; +} + +assert(thrown, 'Setting an invalid mutlicast TTL should throw some error'); + +//close the socket +socket.close(); \ No newline at end of file diff --git a/test/simple/test-dgram-send-error.js b/test/simple/test-dgram-send-error.js index 803a371fccc..346f36dbe29 100644 --- a/test/simple/test-dgram-send-error.js +++ b/test/simple/test-dgram-send-error.js @@ -73,9 +73,9 @@ function doSend() { } process.on('exit', function() { - console.log(packetsSent + ' UDP packets sent, ' + + console.log(packetsSent + ' UDP packets sent, ' + packetsReceived + ' received'); - + assert.strictEqual(packetsSent, ITERATIONS * 2); assert.strictEqual(packetsReceived, ITERATIONS); }); diff --git a/test/simple/test-eval.js b/test/simple/test-eval.js index a2e56e02c98..9c656a8770b 100644 --- a/test/simple/test-eval.js +++ b/test/simple/test-eval.js @@ -30,8 +30,8 @@ var exec = require('child_process').exec; var success_count = 0; var error_count = 0; -var cmd = [process.execPath, '-e', '"console.error(process.argv)"', 'foo', 'bar'] - .join(' '); +var cmd = [process.execPath, '-e', '"console.error(process.argv)"', + 'foo', 'bar'].join(' '); var expected = util.format([process.execPath, 'foo', 'bar']) + '\n'; var child = exec(cmd, function(err, stdout, stderr) { if (err) { diff --git a/test/simple/test-executable-path.js b/test/simple/test-executable-path.js index c33a8007488..8d82b745010 100644 --- a/test/simple/test-executable-path.js +++ b/test/simple/test-executable-path.js @@ -26,14 +26,14 @@ var match = false; var isDebug = process.features.debug; -var debugPaths = [ path.normalize(path.join(__dirname, '..', '..', - 'out', 'Debug', 'node')), - path.normalize(path.join(__dirname, '..', '..', - 'Debug', 'node'))]; -var defaultPaths = [ path.normalize(path.join(__dirname, '..', '..', - 'out', 'Release', 'node')), - path.normalize(path.join(__dirname, '..', '..', - 'Release', 'node'))]; +var debugPaths = [path.normalize(path.join(__dirname, '..', '..', + 'out', 'Debug', 'node')), + path.normalize(path.join(__dirname, '..', '..', + 'Debug', 'node'))]; +var defaultPaths = [path.normalize(path.join(__dirname, '..', '..', + 'out', 'Release', 'node')), + path.normalize(path.join(__dirname, '..', '..', + 'Release', 'node'))]; console.error('debugPaths: ' + debugPaths); console.error('defaultPaths: ' + defaultPaths); diff --git a/test/simple/test-fs-long-path.js b/test/simple/test-fs-long-path.js index 2ae80d0edbc..eac58f68e5b 100644 --- a/test/simple/test-fs-long-path.js +++ b/test/simple/test-fs-long-path.js @@ -31,8 +31,10 @@ var fileNameLen = Math.max(260 - common.tmpDir.length - 1, 1); var fileName = path.join(common.tmpDir, new Array(fileNameLen + 1).join('x')); var fullPath = path.resolve(fileName); -console.log({ filenameLength: fileName.length, - fullPathLength: fullPath.length }); +console.log({ + filenameLength: fileName.length, + fullPathLength: fullPath.length +}); fs.writeFile(fullPath, 'ok', function(err) { if (err) throw err; diff --git a/test/simple/test-fs-mkdir.js b/test/simple/test-fs-mkdir.js index 9d00b1e75a0..d99cd371b37 100644 --- a/test/simple/test-fs-mkdir.js +++ b/test/simple/test-fs-mkdir.js @@ -80,4 +80,4 @@ function unlink(pathname) { // Keep the event loop alive so the async mkdir() requests // have a chance to run (since they don't ref the event loop). -process.nextTick(function(){}); +process.nextTick(function() {}); diff --git a/test/simple/test-fs-symlink.js b/test/simple/test-fs-symlink.js index 83bf13e4943..6b23b1e1c10 100644 --- a/test/simple/test-fs-symlink.js +++ b/test/simple/test-fs-symlink.js @@ -38,8 +38,7 @@ var runtest = function(skip_symlinks) { // Delete previously created link try { fs.unlinkSync(linkPath); - } catch(e) - {} + } catch (e) {} fs.symlink(linkData, linkPath, function(err) { if (err) throw err; @@ -60,8 +59,7 @@ var runtest = function(skip_symlinks) { // Delete previously created link try { fs.unlinkSync(dstPath); - } catch(e) - {} + } catch (e) {} fs.link(srcPath, dstPath, function(err) { if (err) throw err; @@ -71,12 +69,12 @@ var runtest = function(skip_symlinks) { assert.equal(srcContent, dstContent); completed++; }); -} +}; if (is_windows) { // On Windows, creating symlinks requires admin privileges. // We'll only try to run symlink test if we have enough privileges. - exec("whoami /priv", function(err, o) { + exec('whoami /priv', function(err, o) { if (err || o.indexOf('SeCreateSymbolicLinkPrivilege') == -1) { expected_tests = 1; runtest(true); diff --git a/test/simple/test-fs-utimes.js b/test/simple/test-fs-utimes.js index df75fcb6413..eae80238bc1 100644 --- a/test/simple/test-fs-utimes.js +++ b/test/simple/test-fs-utimes.js @@ -68,7 +68,7 @@ function expect_ok(syscall, resource, err, atime, mtime) { // the tests assume that __filename belongs to the user running the tests // this should be a fairly safe assumption; testing against a temp file // would be even better though (node doesn't have such functionality yet) -function runTests(atime, mtime, callback) { +function runTest(atime, mtime, callback) { var fd, err; // @@ -144,10 +144,10 @@ function runTests(atime, mtime, callback) { var stats = fs.statSync(__filename); -runTests(new Date('1982-09-10 13:37'), new Date('1982-09-10 13:37'), function() { - runTests(new Date(), new Date(), function() { - runTests(123456.789, 123456.789, function() { - runTests(stats.mtime, stats.mtime, function() { +runTest(new Date('1982-09-10 13:37'), new Date('1982-09-10 13:37'), function() { + runTest(new Date(), new Date(), function() { + runTest(123456.789, 123456.789, function() { + runTest(stats.mtime, stats.mtime, function() { // done }); }); diff --git a/test/simple/test-http-1.0.js b/test/simple/test-http-1.0.js index 2ed1d13fb1c..fadaaf0f1e6 100644 --- a/test/simple/test-http-1.0.js +++ b/test/simple/test-http-1.0.js @@ -112,7 +112,8 @@ function test(handler, request_generator, response_validator) { function request_generator() { return ('GET / HTTP/1.0\r\n' + - 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' + + 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 ' + + 'OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' + 'Host: 127.0.0.1:1337\r\n' + 'Accept: */*\r\n' + '\r\n'); @@ -147,7 +148,8 @@ function test(handler, request_generator, response_validator) { function request_generator() { return ('GET / HTTP/1.1\r\n' + - 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' + + 'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 ' + + 'OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' + 'Connection: close\r\n' + 'Host: 127.0.0.1:1337\r\n' + 'Accept: */*\r\n' + diff --git a/test/simple/test-http-abort-before-end.js b/test/simple/test-http-abort-before-end.js index e701ed90500..11e424fbe1a 100644 --- a/test/simple/test-http-abort-before-end.js +++ b/test/simple/test-http-abort-before-end.js @@ -28,7 +28,7 @@ var server = http.createServer(function(req, res) { }); server.listen(common.PORT, function() { - var req = http.request({method:'GET', host:'127.0.0.1', port:common.PORT}); + var req = http.request({method: 'GET', host: '127.0.0.1', port: common.PORT}); req.on('error', function(ex) { // https://github.com/joyent/node/issues/1399#issuecomment-2597359 diff --git a/test/simple/test-http-parser-free.js b/test/simple/test-http-parser-free.js new file mode 100644 index 00000000000..bbf4a502749 --- /dev/null +++ b/test/simple/test-http-parser-free.js @@ -0,0 +1,54 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var http = require('http'); +var N = 100; +var responses = 0; + +var server = http.createServer(function(req, res) { + res.end('Hello'); +}); + +server.listen(common.PORT, function() { + http.globalAgent.maxSockets = 1; + var parser; + for (var i = 0; i < N; ++i) { + (function makeRequest(i) { + var req = http.get({port: common.PORT}, function(res) { + if (!parser) { + parser = req.parser; + } else { + assert.strictEqual(req.parser, parser); + } + + if (++responses === N) { + server.close(); + } + }); + })(i); + } +}); + +process.on('exit', function() { + assert.equal(responses, N); +}); diff --git a/test/simple/test-http-res-write-end-dont-take-array.js b/test/simple/test-http-res-write-end-dont-take-array.js index 2a7c025a067..f4b3f8ccee4 100644 --- a/test/simple/test-http-res-write-end-dont-take-array.js +++ b/test/simple/test-http-res-write-end-dont-take-array.js @@ -25,7 +25,7 @@ var http = require('http'); var test = 1; -var server = http.createServer(function (req, res) { +var server = http.createServer(function(req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); if (test === 1) { // write should accept string @@ -53,11 +53,11 @@ var server = http.createServer(function (req, res) { server.listen(common.PORT, function() { // just make a request, other tests handle responses - http.get({port:common.PORT}, function() { + http.get({port: common.PORT}, function() { // lazy serial test, becuase we can only call end once per request test += 1; // do it again to test .end(Buffer); - http.get({port:common.PORT}, function() { + http.get({port: common.PORT}, function() { server.close(); }); }); diff --git a/test/simple/test-http-response-no-headers.js b/test/simple/test-http-response-no-headers.js index 95bd01aed56..cc5250d826f 100644 --- a/test/simple/test-http-response-no-headers.js +++ b/test/simple/test-http-response-no-headers.js @@ -27,8 +27,8 @@ var net = require('net'); var expected = { '0.9': 'I AM THE WALRUS', '1.0': 'I AM THE WALRUS', - '1.1': '', -} + '1.1': '' +}; var gotExpected = false; @@ -38,11 +38,12 @@ function test(httpVersion, callback) { }); var server = net.createServer(function(conn) { - var reply = 'HTTP/' + httpVersion + ' 200 OK\r\n\r\n' + expected[httpVersion]; + var reply = 'HTTP/' + httpVersion + ' 200 OK\r\n\r\n' + + expected[httpVersion]; conn.write(reply, function() { conn.destroy(); - }) + }); }); server.listen(common.PORT, '127.0.0.1', function() { diff --git a/test/simple/test-http-should-keep-alive.js b/test/simple/test-http-should-keep-alive.js new file mode 100644 index 00000000000..9e3dcf677e1 --- /dev/null +++ b/test/simple/test-http-should-keep-alive.js @@ -0,0 +1,71 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var http = require('http'); +var net = require('net'); + +var SERVER_RESPONSES = [ + 'HTTP/1.0 200 ok\r\nContent-Length: 0\r\n\r\n', + 'HTTP/1.0 200 ok\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n', + 'HTTP/1.0 200 ok\r\nContent-Length: 0\r\nConnection: close\r\n\r\n', + 'HTTP/1.1 200 ok\r\nContent-Length: 0\r\n\r\n', + 'HTTP/1.1 200 ok\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n', + 'HTTP/1.1 200 ok\r\nContent-Length: 0\r\nConnection: close\r\n\r\n', +]; +var SHOULD_KEEP_ALIVE = [ + false, // HTTP/1.0, default + true, // HTTP/1.0, Connection: keep-alive + false, // HTTP/1.0, Connection: close + true, // HTTP/1.1, default + true, // HTTP/1.1, Connection: keep-alive + false, // HTTP/1.1, Connection: close +]; +var requests = 0; +var responses = 0; + +var server = net.createServer(function(socket) { + socket.write(SERVER_RESPONSES[requests]); + ++requests; +}).listen(common.PORT, function() { + function makeRequest() { + var req = http.get({port: common.PORT}, function(res) { + assert.equal(req.shouldKeepAlive, SHOULD_KEEP_ALIVE[responses], + SERVER_RESPONSES[responses] + ' should ' + + (SHOULD_KEEP_ALIVE[responses] ? '' : 'not ') + + 'Keep-Alive'); + ++responses; + if (responses < SHOULD_KEEP_ALIVE.length) { + makeRequest(); + } else { + server.close(); + } + }); + } + + makeRequest(); +}); + +process.on('exit', function() { + assert.equal(requests, SERVER_RESPONSES.length); + assert.equal(responses, SHOULD_KEEP_ALIVE.length); +}); diff --git a/test/simple/test-init.js b/test/simple/test-init.js index 0aaa0d3d5a9..da059846d15 100644 --- a/test/simple/test-init.js +++ b/test/simple/test-init.js @@ -36,11 +36,13 @@ child.exec(process.execPath + ' test-init', {env: {'TEST_INIT': 1}}, function(err, stdout, stderr) { - assert.equal(stdout, 'Loaded successfully!', '`node test-init` failed!'); + assert.equal(stdout, 'Loaded successfully!', + '`node test-init` failed!'); }); child.exec(process.execPath + ' test-init.js', {env: {'TEST_INIT': 1}}, function(err, stdout, stderr) { - assert.equal(stdout, 'Loaded successfully!', '`node test-init.js` failed!'); + assert.equal(stdout, 'Loaded successfully!', + '`node test-init.js` failed!'); }); // test-init-index is in fixtures dir as requested by ry, so go there @@ -48,16 +50,19 @@ child.exec(process.execPath + ' test-init-index', {env: {'TEST_INIT': 1}}, function(err, stdout, stderr) { - assert.equal(stdout, 'Loaded successfully!', '`node test-init-index failed!'); + assert.equal(stdout, 'Loaded successfully!', + '`node test-init-index failed!'); }); // ensures that `node fs` does not mistakenly load the native 'fs' module - // instead of the desired file and that the fs module loads as expected in node + // instead of the desired file and that the fs module loads as + // expected in node process.chdir(common.fixturesDir + '/test-init-native/'); child.exec(process.execPath + ' fs', {env: {'TEST_INIT': 1}}, function(err, stdout, stderr) { - assert.equal(stdout, 'fs loaded successfully', '`node fs` failed!'); + assert.equal(stdout, 'fs loaded successfully', + '`node fs` failed!'); }); } })(); diff --git a/test/simple/test-module-load-list.js b/test/simple/test-module-load-list.js index 0ecf7a8798d..a2a1b332306 100644 --- a/test/simple/test-module-load-list.js +++ b/test/simple/test-module-load-list.js @@ -24,19 +24,20 @@ // beginning of this file. function assertEqual(x, y) { - if (x !== y) throw new Error("Expected '" + x + "' got '" + y + "'"); + if (x !== y) throw new Error('Expected \'' + x + '\' got \'' + y + '\''); } function checkExpected() { var toCompare = Math.max(expected.length, process.moduleLoadList.length); for (var i = 0; i < toCompare; i++) { if (expected[i] !== process.moduleLoadList[i]) { - console.error("process.moduleLoadList[" + i + "] = " + process.moduleLoadList[i]); - console.error("expected[" + i + "] = " + expected[i]); + console.error('process.moduleLoadList[' + i + '] = ' + + process.moduleLoadList[i]); + console.error('expected[' + i + '] = ' + expected[i]); - console.error("process.moduleLoadList", process.moduleLoadList); - console.error("expected = ", expected); - throw new Error("mismatch"); + console.error('process.moduleLoadList', process.moduleLoadList); + console.error('expected = ', expected); + throw new Error('mismatch'); } } } diff --git a/test/simple/test-net-connect-buffer.js b/test/simple/test-net-connect-buffer.js index 75486af9741..d0878ebb4c1 100644 --- a/test/simple/test-net-connect-buffer.js +++ b/test/simple/test-net-connect-buffer.js @@ -85,7 +85,7 @@ tcp.listen(common.PORT, function() { // Write a string that contains a multi-byte character sequence to test that // `bytesWritten` is incremented with the # of bytes, not # of characters. var a = "L'État, c'est "; - var b = "moi"; + var b = 'moi'; // We're still connecting at this point so the datagram is first pushed onto // the connect queue. Make sure that it's not added to `bytesWritten` again diff --git a/test/simple/test-net-pipe-connect-errors.js b/test/simple/test-net-pipe-connect-errors.js index f5896bf8896..b659f439832 100644 --- a/test/simple/test-net-pipe-connect-errors.js +++ b/test/simple/test-net-pipe-connect-errors.js @@ -31,42 +31,40 @@ var accessErrorFired = false; // Test if ENOTSOCK is fired when trying to connect to a file which is not // a socket. -var notSocketClient = net.createConnection( - path.join(common.fixturesDir, 'empty.txt'), - function () { - assert.ok(false); - } -); +var emptyTxt = path.join(common.fixturesDir, 'empty.txt'); +var notSocketClient = net.createConnection(emptyTxt, function() { + assert.ok(false); +}); -notSocketClient.on('error', function (err) { +notSocketClient.on('error', function(err) { assert(err.code === 'ENOTSOCK' || err.code === 'ECONNREFUSED'); notSocketErrorFired = true; }); // Trying to connect to not-existing socket should result in ENOENT error -var noEntSocketClient = net.createConnection('no-ent-file', function () { +var noEntSocketClient = net.createConnection('no-ent-file', function() { assert.ok(false); }); -noEntSocketClient.on('error', function (err) { +noEntSocketClient.on('error', function(err) { assert.equal(err.code, 'ENOENT'); noEntErrorFired = true; }); // Trying to connect to a socket one has no access to should result in EACCES -var accessServer = net.createServer(function () { +var accessServer = net.createServer(function() { assert.ok(false); }); -accessServer.listen(common.PIPE, function () { +accessServer.listen(common.PIPE, function() { fs.chmodSync(common.PIPE, 0); - var accessClient = net.createConnection(common.PIPE, function () { + var accessClient = net.createConnection(common.PIPE, function() { assert.ok(false); }); - accessClient.on('error', function (err) { + accessClient.on('error', function(err) { assert.equal(err.code, 'EACCES'); accessErrorFired = true; accessServer.close(); @@ -75,7 +73,7 @@ accessServer.listen(common.PIPE, function () { // Assert that all error events were fired -process.on('exit', function () { +process.on('exit', function() { assert.ok(notSocketErrorFired); assert.ok(noEntErrorFired); assert.ok(accessErrorFired); diff --git a/test/simple/test-net-server-max-connections.js b/test/simple/test-net-server-max-connections.js index f45c1e53d3f..43bc2fee17e 100644 --- a/test/simple/test-net-server-max-connections.js +++ b/test/simple/test-net-server-max-connections.js @@ -42,9 +42,7 @@ var server = net.createServer(function(connection) { }); server.listen(common.PORT, function() { - for (var i = 0; i < N; i++) { - makeConnection(i); - } + makeConnection(0); }); server.maxConnections = N / 2; @@ -53,50 +51,54 @@ console.error('server.maxConnections = %d', server.maxConnections); function makeConnection(index) { - setTimeout(function() { - var c = net.createConnection(common.PORT); - var gotData = false; + var c = net.createConnection(common.PORT); + var gotData = false; - c.on('end', function() { c.end(); }); + c.on('connect', function() { + if (index + 1 < N) { + makeConnection(index + 1); + } + }); - c.on('data', function(b) { - gotData = true; - assert.ok(0 < b.length); - }); + c.on('end', function() { c.end(); }); - c.on('error', function(e) { - console.error('error %d: %s', index, e); - }); + c.on('data', function(b) { + gotData = true; + assert.ok(0 < b.length); + }); - c.on('close', function() { - console.error('closed %d', index); - closes++; + c.on('error', function(e) { + console.error('error %d: %s', index, e); + }); - if (closes < N / 2) { - assert.ok(server.maxConnections <= index, - index + - ' was one of the first closed connections ' + - 'but shouldnt have been'); + c.on('close', function() { + console.error('closed %d', index); + closes++; + + if (closes < N / 2) { + assert.ok(server.maxConnections <= index, + index + + ' was one of the first closed connections ' + + 'but shouldnt have been'); + } + + if (closes === N / 2) { + var cb; + console.error('calling wait callback.'); + while (cb = waits.shift()) { + cb(); } + server.close(); + } - if (closes === N / 2) { - var cb; - console.error('calling wait callback.'); - while (cb = waits.shift()) { - cb(); - } - server.close(); - } - - if (index < server.maxConnections) { - assert.equal(true, gotData, - index + ' didn\'t get data, but should have'); - } else { - assert.equal(false, gotData, - index + ' got data, but shouldn\'t have'); - } - }); - }, index); + if (index < server.maxConnections) { + assert.equal(true, gotData, + index + ' didn\'t get data, but should have'); + } else { + assert.equal(false, gotData, + index + ' got data, but shouldn\'t have'); + } + }); } diff --git a/test/simple/test-path-makelong.js b/test/simple/test-path-makelong.js index 885eb12a9a0..0ec298fe3d8 100644 --- a/test/simple/test-path-makelong.js +++ b/test/simple/test-path-makelong.js @@ -26,13 +26,13 @@ if (process.platform === 'win32') { var file = path.join(common.fixturesDir, 'a.js'); var resolvedFile = path.resolve(file); - var networkFile = '\\\\someserver\\someshare\\somefile'; assert.equal('\\\\?\\' + resolvedFile, path._makeLong(file)); assert.equal('\\\\?\\' + resolvedFile, path._makeLong('\\\\?\\' + file)); assert.equal('\\\\?\\UNC\\someserver\\someshare\\somefile', - path._makeLong('\\\\someserver\\someshare\\somefile')); + path._makeLong('\\\\someserver\\someshare\\somefile')); assert.equal('\\\\?\\UNC\\someserver\\someshare\\somefile', - path._makeLong('\\\\?\\UNC\\someserver\\someshare\\somefile')); - assert.equal('\\\\.\\pipe\\somepipe', path._makeLong('\\\\.\\pipe\\somepipe')); + path._makeLong('\\\\?\\UNC\\someserver\\someshare\\somefile')); + assert.equal('\\\\.\\pipe\\somepipe', + path._makeLong('\\\\.\\pipe\\somepipe')); } diff --git a/test/simple/test-path.js b/test/simple/test-path.js index c60230ab814..caf86aa4658 100644 --- a/test/simple/test-path.js +++ b/test/simple/test-path.js @@ -35,12 +35,14 @@ assert.equal(path.basename(f, '.js'), 'test-path'); // c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html if (!isWindows) { var controlCharFilename = 'Icon' + String.fromCharCode(13); - assert.equal(path.basename('/a/b/' + controlCharFilename), controlCharFilename); + assert.equal(path.basename('/a/b/' + controlCharFilename), + controlCharFilename); } assert.equal(path.extname(f), '.js'); -assert.equal(path.dirname(f).substr(-11), isWindows ? 'test\\simple' : 'test/simple'); +assert.equal(path.dirname(f).substr(-11), + isWindows ? 'test\\simple' : 'test/simple'); assert.equal(path.dirname('/a/b/'), '/a'); assert.equal(path.dirname('/a/b'), '/a'); assert.equal(path.dirname('/a'), '/'); @@ -97,6 +99,34 @@ assert.equal(path.extname('/.file.ext'), '.ext'); assert.equal(path.extname('.path/file.ext'), '.ext'); assert.equal(path.extname('file.ext.ext'), '.ext'); assert.equal(path.extname('file.'), '.'); +assert.equal(path.extname('.'), ''); +assert.equal(path.extname('./'), ''); +assert.equal(path.extname('.file.ext'), '.ext'); +assert.equal(path.extname('.file'), ''); +assert.equal(path.extname('.file.'), '.'); +assert.equal(path.extname('.file..'), '.'); +assert.equal(path.extname('..'), ''); +assert.equal(path.extname('../'), ''); +assert.equal(path.extname('..file.ext'), '.ext'); +assert.equal(path.extname('..file'), '.file'); +assert.equal(path.extname('..file.'), '.'); +assert.equal(path.extname('..file..'), '.'); +assert.equal(path.extname('...'), '.'); +assert.equal(path.extname('...ext'), '.ext'); +assert.equal(path.extname('....'), '.'); +assert.equal(path.extname('file.ext/'), ''); + +if (isWindows) { + // On windows, backspace is a path separator. + assert.equal(path.extname('.\\'), ''); + assert.equal(path.extname('..\\'), ''); + assert.equal(path.extname('file.ext\\'), ''); +} else { + // On unix, backspace is a valid name component like any other character. + assert.equal(path.extname('.\\'), ''); + assert.equal(path.extname('..\\'), '.\\'); + assert.equal(path.extname('file.ext\\'), '.ext\\'); +} // path.join tests var failures = []; @@ -234,7 +264,9 @@ var failures = []; relativeTests.forEach(function(test) { var actual = path.relative(test[0], test[1]); var expected = test[2]; - var message = 'path.relative(' + test.slice(0, 2).map(JSON.stringify).join(',') + ')' + + var message = 'path.relative(' + + test.slice(0, 2).map(JSON.stringify).join(',') + + ')' + '\n expect=' + JSON.stringify(expected) + '\n actual=' + JSON.stringify(actual); if (actual !== expected) failures.push('\n' + message); diff --git a/test/simple/test-punycode.js b/test/simple/test-punycode.js index 9a144c58a10..1fd67105d6a 100644 --- a/test/simple/test-punycode.js +++ b/test/simple/test-punycode.js @@ -62,101 +62,102 @@ assert.equal(punycode.decode('wgv71a119e'), '日本語'); var tests = { // (A) Arabic (Egyptian) 'egbpdaj6bu4bxfgehfvwxn': - '\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644\u0645\u0648' + - '\u0634\u0639\u0631\u0628\u064A\u061F', + '\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644\u0645\u0648' + + '\u0634\u0639\u0631\u0628\u064A\u061F', // (B) Chinese (simplified) 'ihqwcrb4cv8a8dqg056pqjye': - '\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587', + '\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587', // (C) Chinese (traditional) 'ihqwctvzc91f659drss3x8bo0yb': - '\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587', + '\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587', // (D) Czech: Proprostnemluvesky 'Proprostnemluvesky-uyb24dma41a': - '\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074\u011B\u006E' + - '\u0065\u006D\u006C\u0075\u0076\u00ED\u010D\u0065\u0073\u006B\u0079', + '\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074\u011B\u006E' + + '\u0065\u006D\u006C\u0075\u0076\u00ED\u010D\u0065\u0073\u006B\u0079', // (E) Hebrew '4dbcagdahymbxekheh6e0a7fei0b': - '\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8\u05DC\u05D0' + - '\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2\u05D1\u05E8\u05D9\u05EA', + '\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8\u05DC\u05D0' + + '\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2\u05D1\u05E8\u05D9\u05EA', // (F) Hindi (Devanagari) 'i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd': - '\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D\u0926\u0940' + - '\u0915\u094D\u092F\u094B\u0902\u0928\u0939\u0940\u0902\u092C\u094B' + - '\u0932\u0938\u0915\u0924\u0947\u0939\u0948\u0902', + '\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D\u0926\u0940' + + '\u0915\u094D\u092F\u094B\u0902\u0928\u0939\u0940\u0902\u092C\u094B' + + '\u0932\u0938\u0915\u0924\u0947\u0939\u0948\u0902', // (G) Japanese (kanji and hiragana) 'n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa': - '\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092\u8A71\u3057' + - '\u3066\u304F\u308C\u306A\u3044\u306E\u304B', + '\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092\u8A71\u3057' + + '\u3066\u304F\u308C\u306A\u3044\u306E\u304B', // (H) Korean (Hangul syllables) '989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c': - '\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774\uD55C\uAD6D' + - '\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74\uC5BC\uB9C8\uB098\uC88B' + - '\uC744\uAE4C', + '\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774\uD55C\uAD6D' + + '\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74\uC5BC\uB9C8\uB098\uC88B' + + '\uC744\uAE4C', // (I) Russian (Cyrillic) /* XXX disabled, fails - possibly a bug in the RFC 'b1abfaaepdrnnbgefbaDotcwatmq2g4l': - '\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E\u043D\u0438' + - '\u043D\u0435\u0433\u043E\u0432\u043E\u0440\u044F\u0442\u043F\u043E' + - '\u0440\u0443\u0441\u0441\u043A\u0438', + '\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E\u043D\u0438' + + '\u043D\u0435\u0433\u043E\u0432\u043E\u0440\u044F\u0442\u043F\u043E' + + '\u0440\u0443\u0441\u0441\u043A\u0438', */ // (J) Spanish: PorqunopuedensimplementehablarenEspaol 'PorqunopuedensimplementehablarenEspaol-fmd56a': - '\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070\u0075\u0065' + - '\u0064\u0065\u006E\u0073\u0069\u006D\u0070\u006C\u0065\u006D\u0065' + - '\u006E\u0074\u0065\u0068\u0061\u0062\u006C\u0061\u0072\u0065\u006E' + - '\u0045\u0073\u0070\u0061\u00F1\u006F\u006C', + '\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070\u0075\u0065' + + '\u0064\u0065\u006E\u0073\u0069\u006D\u0070\u006C\u0065\u006D\u0065' + + '\u006E\u0074\u0065\u0068\u0061\u0062\u006C\u0061\u0072\u0065\u006E' + + '\u0045\u0073\u0070\u0061\u00F1\u006F\u006C', - // (K) Vietnamese: TisaohkhngthchnitingVit + // (K) Vietnamese: Tisaohkhngth + // chnitingVit 'TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g': - '\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B\u0068\u00F4' + - '\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068\u1EC9\u006E\u00F3\u0069' + - '\u0074\u0069\u1EBF\u006E\u0067\u0056\u0069\u1EC7\u0074', + '\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B\u0068\u00F4' + + '\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068\u1EC9\u006E\u00F3\u0069' + + '\u0074\u0069\u1EBF\u006E\u0067\u0056\u0069\u1EC7\u0074', // (L) 3B '3B-ww4c5e180e575a65lsy2b': - '\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F', + '\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F', // (M) -with-SUPER-MONKEYS '-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n': - '\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074\u0068\u002D' + - '\u0053\u0055\u0050\u0045\u0052\u002D\u004D\u004F\u004E\u004B\u0045' + - '\u0059\u0053', + '\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074\u0068\u002D' + + '\u0053\u0055\u0050\u0045\u0052\u002D\u004D\u004F\u004E\u004B\u0045' + + '\u0059\u0053', // (N) Hello-Another-Way- 'Hello-Another-Way--fc4qua05auwb3674vfr0b': - '\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F\u0074\u0068' + - '\u0065\u0072\u002D\u0057\u0061\u0079\u002D\u305D\u308C\u305E\u308C' + - '\u306E\u5834\u6240', + '\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F\u0074\u0068' + + '\u0065\u0072\u002D\u0057\u0061\u0079\u002D\u305D\u308C\u305E\u308C' + + '\u306E\u5834\u6240', // (O) 2 '2-u9tlzr9756bt3uc0v': - '\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032', + '\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032', // (P) MajiKoi5 'MajiKoi5-783gue6qz075azm5e': - '\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059\u308B\u0035' + - '\u79D2\u524D', + '\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059\u308B\u0035' + + '\u79D2\u524D', // (Q) de 'de-jg4avhby1noc0d': - '\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0', + '\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0', // (R) 'd9juau41awczczp': - '\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067', + '\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067', // (S) -> $1.00 <- '-> $1.00 <--': - '\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020\u003C\u002D' + '\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020\u003C\u002D' }; var errors = 0; diff --git a/test/simple/test-readdir.js b/test/simple/test-readdir.js index 0f95ea28520..24997241f9b 100644 --- a/test/simple/test-readdir.js +++ b/test/simple/test-readdir.js @@ -66,7 +66,7 @@ process.on('exit', function() { var has_caught = false; try { - fs.readdirSync(__filename) + fs.readdirSync(__filename); } catch (e) { has_caught = true; diff --git a/test/simple/test-regress-GH-1899.js b/test/simple/test-regress-GH-1899.js index 350e6947a3a..7fc8007a24c 100644 --- a/test/simple/test-regress-GH-1899.js +++ b/test/simple/test-regress-GH-1899.js @@ -20,18 +20,20 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. var path = require('path'); -var assert = require('assert') +var assert = require('assert'); var spawn = require('child_process').spawn; var common = require('../common'); -var child = spawn(process.argv[0], [path.join(common.fixturesDir, 'GH-1899-output.js')]); +var child = spawn(process.argv[0], [ + path.join(common.fixturesDir, 'GH-1899-output.js') +]); var output = ''; -child.stdout.on('data', function (data) { +child.stdout.on('data', function(data) { output += data; }); -child.on('exit', function (code, signal) { +child.on('exit', function(code, signal) { assert.equal(code, 0); assert.equal(output, 'hello, world!\n'); }); diff --git a/test/simple/test-regress-GH-877.js b/test/simple/test-regress-GH-877.js index 0714e6df5de..d9877f431f2 100644 --- a/test/simple/test-regress-GH-877.js +++ b/test/simple/test-regress-GH-877.js @@ -35,6 +35,8 @@ var server = http.createServer(function(req, res) { res.end('Hello World\n'); }); +var addrString = '127.0.0.1:' + common.PORT; + server.listen(common.PORT, '127.0.0.1', function() { for (var i = 0; i < N; i++) { var options = { @@ -50,12 +52,15 @@ server.listen(common.PORT, '127.0.0.1', function() { assert.equal(req.agent, agent); - console.log('Socket: ' + agent.sockets['127.0.0.1:' + common.PORT].length + - '/' + agent.maxSockets + - ' queued: ' + (agent.requests['127.0.0.1:' + common.PORT] ? agent.requests['127.0.0.1:' + common.PORT].length : 0)); + console.log('Socket: ' + agent.sockets[addrString].length + '/' + + agent.maxSockets + ' queued: ' + (agent.requests[addrString] ? + agent.requests['127.0.0.1:' + common.PORT].length : 0)); - if (maxQueued < (agent.requests['127.0.0.1:' + common.PORT] ? agent.requests['127.0.0.1:' + common.PORT].length : 0)) { - maxQueued = (agent.requests['127.0.0.1:' + common.PORT] ? agent.requests['127.0.0.1:' + common.PORT].length : 0); + var agentRequests = agent.requests[addrString] ? + agent.requests[addrString].length : 0; + + if (maxQueued < agentRequests) { + maxQueued = agentRequests; } } }); diff --git a/test/simple/test-repl-.save.load.js b/test/simple/test-repl-.save.load.js index 97a0a53de93..ef318311711 100644 --- a/test/simple/test-repl-.save.load.js +++ b/test/simple/test-repl-.save.load.js @@ -29,9 +29,9 @@ var repl = require('repl'); // A stream to push an array into a REPL function ArrayStream() { - this.run = function (data) { + this.run = function(data) { var self = this; - data.forEach(function (line) { + data.forEach(function(line) { self.emit('data', line); }); } @@ -39,10 +39,10 @@ function ArrayStream() { util.inherits(ArrayStream, require('stream').Stream); ArrayStream.prototype.readable = true; ArrayStream.prototype.writable = true; -ArrayStream.prototype.resume = function () {}; -ArrayStream.prototype.write = function () {}; +ArrayStream.prototype.resume = function() {}; +ArrayStream.prototype.write = function() {}; -var works = [ [ 'inner.one' ], 'inner.o' ]; +var works = [['inner.one'], 'inner.o']; var putIn = new ArrayStream(); var testMe = repl.start('', putIn); @@ -61,13 +61,11 @@ putIn.run(testFile); putIn.run(['.save ' + saveFileName]); // the file should have what I wrote -assert.equal( - fs.readFileSync(saveFileName, 'utf8'), - testFile.join('\n') + '\n'); +assert.equal(fs.readFileSync(saveFileName, 'utf8'), testFile.join('\n') + '\n'); // make sure that the REPL data is "correct" // so when I load it back I know I'm good -testMe.complete('inner.o', function (error, data) { +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, works); }); @@ -78,7 +76,7 @@ putIn.run(['.clear']); putIn.run(['.load ' + saveFileName]); // make sure that the REPL data is "correct" -testMe.complete('inner.o', function (error, data) { +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, works); }); @@ -90,12 +88,11 @@ var loadFile = join(common.tmpDir, 'file.does.not.exist'); // shold not break putIn.write = function(data) { // make sure I get a failed to load message and not some crazy error - assert.equal(data, - 'Failed to load:' + loadFile + '\n'); + assert.equal(data, 'Failed to load:' + loadFile + '\n'); // eat me to avoid work putIn.write = function() {}; }; -putIn.run(['.load ' +loadFile]); +putIn.run(['.load ' + loadFile]); //TODO how do I do a failed .save test? diff --git a/test/simple/test-repl-tab-complete.js b/test/simple/test-repl-tab-complete.js index 4fdd923c9fe..ba511046b51 100644 --- a/test/simple/test-repl-tab-complete.js +++ b/test/simple/test-repl-tab-complete.js @@ -26,9 +26,9 @@ var repl = require('repl'); // A stream to push an array into a REPL function ArrayStream() { - this.run = function (data) { + this.run = function(data) { var self = this; - data.forEach(function (line) { + data.forEach(function(line) { self.emit('data', line); }); } @@ -36,11 +36,11 @@ function ArrayStream() { util.inherits(ArrayStream, require('stream').Stream); ArrayStream.prototype.readable = true; ArrayStream.prototype.writable = true; -ArrayStream.prototype.resume = function () {}; -ArrayStream.prototype.write = function () {}; +ArrayStream.prototype.resume = function() {}; +ArrayStream.prototype.write = function() {}; -var works = [ [ 'inner.one' ], 'inner.o' ]; -var doesNotBreak = [ [], 'inner.o' ]; +var works = [['inner.one'], 'inner.o']; +var doesNotBreak = [[], 'inner.o']; var putIn = new ArrayStream(); var testMe = repl.start('', putIn); @@ -49,14 +49,15 @@ var testMe = repl.start('', putIn); putIn.run(['.clear']); putIn.run([ 'var inner = {', - 'one:1']); -testMe.complete('inner.o', function (error, data) { + 'one:1' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, doesNotBreak); }); // Tab Complete will return globaly scoped variables putIn.run(['};']); -testMe.complete('inner.o', function (error, data) { +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, works); }); @@ -66,8 +67,9 @@ putIn.run(['.clear']); putIn.run([ 'var inner = ( true ' , '?', - '{one: 1} : ']); -testMe.complete('inner.o', function (error, data) { + '{one: 1} : ' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, doesNotBreak); }); @@ -76,15 +78,16 @@ putIn.run(['.clear']); // Tab Complete will return a simple local variable putIn.run([ 'var top = function () {', - 'var inner = {one:1};']); -testMe.complete('inner.o', function (error, data) { + 'var inner = {one:1};' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, works); }); // When you close the function scope tab complete will not return the // locally scoped variable putIn.run(['};']); -testMe.complete('inner.o', function (error, data) { +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, doesNotBreak); }); @@ -93,10 +96,11 @@ putIn.run(['.clear']); // Tab Complete will return a complex local variable putIn.run([ 'var top = function () {', - 'var inner = {', - ' one:1', - '};']); -testMe.complete('inner.o', function (error, data) { + 'var inner = {', + ' one:1', + '};' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, works); }); @@ -106,10 +110,11 @@ putIn.run(['.clear']); // has paramaters putIn.run([ 'var top = function (one, two) {', - 'var inner = {', - ' one:1', - '};']); -testMe.complete('inner.o', function (error, data) { + 'var inner = {', + ' one:1', + '};' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, works); }); @@ -119,11 +124,12 @@ putIn.run(['.clear']); // scope is nested inside an immediately executed function putIn.run([ 'var top = function () {', - '(function test () {', - 'var inner = {', - ' one:1', - '};']); -testMe.complete('inner.o', function (error, data) { + '(function test () {', + 'var inner = {', + ' one:1', + '};' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, works); }); @@ -133,12 +139,13 @@ putIn.run(['.clear']); // def has the params and { on a seperate line putIn.run([ 'var top = function () {', - 'r = function test (', - ' one, two) {', - 'var inner = {', - ' one:1', - '};']); -testMe.complete('inner.o', function (error, data) { + 'r = function test (', + ' one, two) {', + 'var inner = {', + ' one:1', + '};' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, doesNotBreak); }); @@ -147,12 +154,13 @@ putIn.run(['.clear']); // currently does not work, but should not break, not the { putIn.run([ 'var top = function () {', - 'r = function test ()', - '{', - 'var inner = {', - ' one:1', - '};']); -testMe.complete('inner.o', function (error, data) { + 'r = function test ()', + '{', + 'var inner = {', + ' one:1', + '};' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, doesNotBreak); }); @@ -161,13 +169,14 @@ putIn.run(['.clear']); // currently does not work, but should not break putIn.run([ 'var top = function () {', - 'r = function test (', - ')', - '{', - 'var inner = {', - ' one:1', - '};']); -testMe.complete('inner.o', function (error, data) { + 'r = function test (', + ')', + '{', + 'var inner = {', + ' one:1', + '};' +]); +testMe.complete('inner.o', function(error, data) { assert.deepEqual(data, doesNotBreak); }); diff --git a/test/simple/test-script-context.js b/test/simple/test-script-context.js index 581974418d4..a8d6c7a694a 100644 --- a/test/simple/test-script-context.js +++ b/test/simple/test-script-context.js @@ -54,9 +54,11 @@ try { } catch (e) { gh1140Exception = e; - assert.ok(/expected-filename/.test(e.stack), 'expected appearance of filename in Error stack'); + assert.ok(/expected-filename/.test(e.stack), + 'expected appearance of filename in Error stack'); } -assert.ok(gh1140Exception, 'expected exception from runInContext signature test'); +assert.ok(gh1140Exception, + 'expected exception from runInContext signature test'); // GH-558, non-context argument segfaults / raises assertion function isTypeError(o) { diff --git a/test/simple/test-setproctitle.js b/test/simple/test-setproctitle.js index 0bf6fd35c3e..207c2e3f510 100644 --- a/test/simple/test-setproctitle.js +++ b/test/simple/test-setproctitle.js @@ -23,14 +23,14 @@ // FIXME add sunos support if ('linux freebsd'.indexOf(process.platform) === -1) { - console.error("Skipping test, platform not supported."); + console.error('Skipping test, platform not supported.'); process.exit(); } var assert = require('assert'); var exec = require('child_process').exec; -var title = "testTestTESTtest123123123123123123HiHaiJo"; +var title = 'testTestTESTtest123123123123123123HiHaiJo'; assert.notEqual(process.title, title); process.title = title; diff --git a/test/simple/test-stdin-child-proc.js b/test/simple/test-stdin-child-proc.js index 6c499995d2a..ee23eee36e7 100644 --- a/test/simple/test-stdin-child-proc.js +++ b/test/simple/test-stdin-child-proc.js @@ -24,4 +24,4 @@ var child_process = require('child_process'); var path = require('path'); child_process.spawn(process.execPath, - [ path.resolve(__dirname, 'test-stdin-pause-resume.js') ]); + [path.resolve(__dirname, 'test-stdin-pause-resume.js')]); diff --git a/test/simple/test-stdin-pause-resume.js b/test/simple/test-stdin-pause-resume.js index cfa44bae2c0..fed5d665329 100644 --- a/test/simple/test-stdin-pause-resume.js +++ b/test/simple/test-stdin-pause-resume.js @@ -19,19 +19,19 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -console.error("before opening stdin"); +console.error('before opening stdin'); process.stdin.resume(); -console.error("stdin opened"); +console.error('stdin opened'); setTimeout(function() { - console.error("pausing stdin"); + console.error('pausing stdin'); process.stdin.pause(); setTimeout(function() { - console.error("opening again"); + console.error('opening again'); process.stdin.resume(); setTimeout(function() { - console.error("pausing again"); + console.error('pausing again'); process.stdin.pause(); - console.error("should exit now"); + console.error('should exit now'); }, 1); }, 1); }, 1); diff --git a/test/simple/test-tls-client-abort2.js b/test/simple/test-tls-client-abort2.js new file mode 100644 index 00000000000..f8119627687 --- /dev/null +++ b/test/simple/test-tls-client-abort2.js @@ -0,0 +1,45 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +if (!process.versions.openssl) { + console.error('Skipping because node compiled without OpenSSL.'); + process.exit(0); +} + +var common = require('../common'); +var assert = require('assert'); +var tls = require('tls'); + +var errors = 0; + +var conn = tls.connect(common.PORT, function() { + assert(false); // callback should never be executed +}); +conn.on('error', function() { + ++errors; + assert.doesNotThrow(function() { + conn.destroy(); + }); +}); + +process.on('exit', function() { + assert.equal(errors, 1); +}); diff --git a/test/simple/test-tls-passphrase.js b/test/simple/test-tls-passphrase.js index f428e6fd52b..e3c0f2a849c 100644 --- a/test/simple/test-tls-passphrase.js +++ b/test/simple/test-tls-passphrase.js @@ -37,7 +37,7 @@ var server = tls.Server({ key: key, passphrase: 'passphrase', cert: cert, - ca: [ cert ], + ca: [cert], requestCert: true, rejectUnauthorized: true }, function(s) { diff --git a/test/simple/test-tls-session-cache.js b/test/simple/test-tls-session-cache.js index 53f736b84d9..64e41993589 100644 --- a/test/simple/test-tls-session-cache.js +++ b/test/simple/test-tls-session-cache.js @@ -20,12 +20,12 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. if (!process.versions.openssl) { - console.error("Skipping because node compiled without OpenSSL."); + console.error('Skipping because node compiled without OpenSSL.'); process.exit(0); } require('child_process').exec('openssl version', function(err) { if (err !== null) { - console.error("Skipping because openssl command is not available."); + console.error('Skipping because openssl command is not available.'); process.exit(0); } doTest(); @@ -46,7 +46,7 @@ function doTest() { var options = { key: key, cert: cert, - ca: [ cert ], + ca: [cert], requestCert: true }; var requestCount = 0; diff --git a/test/simple/test-tls-set-ciphers.js b/test/simple/test-tls-set-ciphers.js index ba5c868d12c..576094dcb73 100644 --- a/test/simple/test-tls-set-ciphers.js +++ b/test/simple/test-tls-set-ciphers.js @@ -51,7 +51,8 @@ var server = tls.createServer(options, function(conn) { }); server.listen(common.PORT, '127.0.0.1', function() { - var cmd = 'openssl s_client -cipher NULL-MD5 -connect 127.0.0.1:' + common.PORT; + var cmd = 'openssl s_client -cipher NULL-MD5 -connect 127.0.0.1:' + + common.PORT; exec(cmd, function(err, stdout, stderr) { if (err) throw err; diff --git a/test/simple/test-tty-stdout-end.js b/test/simple/test-tty-stdout-end.js index f09bf8ac76f..7c7f7feb2ba 100644 --- a/test/simple/test-tty-stdout-end.js +++ b/test/simple/test-tty-stdout-end.js @@ -27,7 +27,7 @@ var exceptionCaught = false; try { process.stdout.end(); -} catch(e) { +} catch (e) { exceptionCaught = true; assert.ok(common.isError(e)); assert.equal('process.stdout cannot be closed', e.message); diff --git a/test/simple/test-typed-arrays-typenames.js b/test/simple/test-typed-arrays-typenames.js new file mode 100644 index 00000000000..a78c7598acb --- /dev/null +++ b/test/simple/test-typed-arrays-typenames.js @@ -0,0 +1,48 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); + +// TODO: merge with test-typed-arrays.js some time in the future. +// That file only exists in master right now. +[ + 'ArrayBuffer', + 'Int8Array', + 'Uint8Array', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array' +].forEach(function(name) { + var expected = '[object ' + name + ']'; + var clazz = global[name]; + var obj = new clazz(1); + + assert.equal(obj.toString(), expected); + assert.equal(Object.prototype.toString.call(obj), expected); + + obj = new DataView(obj); + assert.equal(obj.toString(), '[object DataView]'); + assert.equal(Object.prototype.toString.call(obj), '[object DataView]'); +}); diff --git a/test/simple/test-util-inspect.js b/test/simple/test-util-inspect.js index c7a64f63906..f21123e82f1 100644 --- a/test/simple/test-util-inspect.js +++ b/test/simple/test-util-inspect.js @@ -42,6 +42,27 @@ assert.equal(util.inspect(a), "[ 'foo', , 'baz' ]"); assert.equal(util.inspect(a, true), "[ 'foo', , 'baz', [length]: 3 ]"); assert.equal(util.inspect(new Array(5)), '[ , , , , ]'); +// test for property descriptors +var getter = Object.create(null, { + a: { + get: function() { return 'aaa'; } + } +}); +var setter = Object.create(null, { + b: { + set: function() {} + }, +}); +var getterAndSetter = Object.create(null, { + c: { + get: function() { return 'ccc'; }, + set: function() {} + } +}); +assert.equal(util.inspect(getter, true), "{ [a]: [Getter] }"); +assert.equal(util.inspect(setter, true), "{ [b]: [Setter] }"); +assert.equal(util.inspect(getterAndSetter, true), "{ [c]: [Getter/Setter] }"); + // exceptions should print the error message, not "{}" assert.equal(util.inspect(new Error()), '[Error]'); assert.equal(util.inspect(new Error('FAIL')), '[Error: FAIL]'); @@ -61,16 +82,16 @@ assert.ok(ex.indexOf('[type]') != -1); // GH-1941 // should not throw: -assert.equal(util.inspect(Object.create(Date.prototype)), '{}') +assert.equal(util.inspect(Object.create(Date.prototype)), '{}'); // GH-1944 -assert.doesNotThrow(function () { +assert.doesNotThrow(function() { var d = new Date(); d.toUTCString = null; util.inspect(d); }); -assert.doesNotThrow(function () { +assert.doesNotThrow(function() { var r = /regexp/; r.toString = null; util.inspect(r); diff --git a/test/simple/test-util.js b/test/simple/test-util.js index bb1e7c012b1..87ee77509a9 100644 --- a/test/simple/test-util.js +++ b/test/simple/test-util.js @@ -26,46 +26,46 @@ var util = require('util'); var context = require('vm').runInNewContext; // isArray -assert.equal(true, util.isArray([])) -assert.equal(true, util.isArray(Array())) -assert.equal(true, util.isArray(new Array())) -assert.equal(true, util.isArray(new Array(5))) -assert.equal(true, util.isArray(new Array('with', 'some', 'entries'))) -assert.equal(true, util.isArray(context('Array')())) -assert.equal(false, util.isArray({})) -assert.equal(false, util.isArray({ push: function () {} })) -assert.equal(false, util.isArray(/regexp/)) -assert.equal(false, util.isArray(new Error)) -assert.equal(false, util.isArray(Object.create(Array.prototype))) +assert.equal(true, util.isArray([])); +assert.equal(true, util.isArray(Array())); +assert.equal(true, util.isArray(new Array())); +assert.equal(true, util.isArray(new Array(5))); +assert.equal(true, util.isArray(new Array('with', 'some', 'entries'))); +assert.equal(true, util.isArray(context('Array')())); +assert.equal(false, util.isArray({})); +assert.equal(false, util.isArray({ push: function() {} })); +assert.equal(false, util.isArray(/regexp/)); +assert.equal(false, util.isArray(new Error)); +assert.equal(false, util.isArray(Object.create(Array.prototype))); // isRegExp -assert.equal(true, util.isRegExp(/regexp/)) -assert.equal(true, util.isRegExp(RegExp())) -assert.equal(true, util.isRegExp(new RegExp())) -assert.equal(true, util.isRegExp(context('RegExp')())) -assert.equal(false, util.isRegExp({})) -assert.equal(false, util.isRegExp([])) -assert.equal(false, util.isRegExp(new Date())) -assert.equal(false, util.isRegExp(Object.create(RegExp.prototype))) +assert.equal(true, util.isRegExp(/regexp/)); +assert.equal(true, util.isRegExp(RegExp())); +assert.equal(true, util.isRegExp(new RegExp())); +assert.equal(true, util.isRegExp(context('RegExp')())); +assert.equal(false, util.isRegExp({})); +assert.equal(false, util.isRegExp([])); +assert.equal(false, util.isRegExp(new Date())); +assert.equal(false, util.isRegExp(Object.create(RegExp.prototype))); // isDate -assert.equal(true, util.isDate(new Date())) -assert.equal(true, util.isDate(new Date(0))) -assert.equal(true, util.isDate(new (context('Date')))) -assert.equal(false, util.isDate(Date())) -assert.equal(false, util.isDate({})) -assert.equal(false, util.isDate([])) -assert.equal(false, util.isDate(new Error)) -assert.equal(false, util.isDate(Object.create(Date.prototype))) +assert.equal(true, util.isDate(new Date())); +assert.equal(true, util.isDate(new Date(0))); +assert.equal(true, util.isDate(new (context('Date')))); +assert.equal(false, util.isDate(Date())); +assert.equal(false, util.isDate({})); +assert.equal(false, util.isDate([])); +assert.equal(false, util.isDate(new Error)); +assert.equal(false, util.isDate(Object.create(Date.prototype))); // isError -assert.equal(true, util.isError(new Error)) -assert.equal(true, util.isError(new TypeError)) -assert.equal(true, util.isError(new SyntaxError)) -assert.equal(true, util.isError(new (context('Error')))) -assert.equal(true, util.isError(new (context('TypeError')))) -assert.equal(true, util.isError(new (context('SyntaxError')))) -assert.equal(false, util.isError({})) -assert.equal(false, util.isError({ name: 'Error', message: '' })) -assert.equal(false, util.isError([])) -assert.equal(false, util.isError(Object.create(Error.prototype))) +assert.equal(true, util.isError(new Error)); +assert.equal(true, util.isError(new TypeError)); +assert.equal(true, util.isError(new SyntaxError)); +assert.equal(true, util.isError(new (context('Error')))); +assert.equal(true, util.isError(new (context('TypeError')))); +assert.equal(true, util.isError(new (context('SyntaxError')))); +assert.equal(false, util.isError({})); +assert.equal(false, util.isError({ name: 'Error', message: '' })); +assert.equal(false, util.isError([])); +assert.equal(false, util.isError(Object.create(Error.prototype))); diff --git a/test/simple/test-zlib-from-gzip.js b/test/simple/test-zlib-from-gzip.js index 9607bd39117..39935420999 100644 --- a/test/simple/test-zlib-from-gzip.js +++ b/test/simple/test-zlib-from-gzip.js @@ -43,6 +43,6 @@ out.on('close', function() { var actual = fs.readFileSync(outputFile); assert.equal(actual.length, expect.length, 'length should match'); for (var i = 0, l = actual.length; i < l; i++) { - assert.equal(actual[i], expect[i], 'byte['+i+']'); + assert.equal(actual[i], expect[i], 'byte[' + i + ']'); } }); diff --git a/test/simple/test-zlib-from-string.js b/test/simple/test-zlib-from-string.js index fe4fb498407..83bdeea83a9 100644 --- a/test/simple/test-zlib-from-string.js +++ b/test/simple/test-zlib-from-string.js @@ -25,12 +25,31 @@ var common = require('../common.js'); var assert = require('assert'); var zlib = require('zlib'); -var inputString = 'ΩΩLorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi faucibus, purus at gravida dictum, libero arcu convallis lacus, in commodo libero metus eu nisi. Nullam commodo, neque nec porta placerat, nisi est fermentum augue, vitae gravida tellus sapien sit amet tellus. Aenean non diam orci. Proin quis elit turpis. Suspendisse non diam ipsum. Suspendisse nec ullamcorper odio. Vestibulum arcu mi, sodales non suscipit id, ultrices ut massa. Sed ac sem sit amet arcu malesuada fermentum. Nunc sed. '; -var expectedBase64Deflate = 'eJxdUUtOQzEMvMoc4OndgT0gJCT2buJWlpI4jePeqZfpmXAKLRKbLOzx/HK73q6vOrhCunlF1qIDJhNUeW5I2ozT5OkDlKWLJWkncJG5403HQXAkT3Jw29B9uIEmToMukglZ0vS6ociBh4JG8sV4oVLEUCitK2kxq1WzPnChHDzsaGKy491LofoAbWh8do43oeuYhB5EPCjcLjzYJo48KrfQBvnJecNFJvHT1+RSQsGoC7dn2t/xjhduTA1NWyQIZR0pbHwMDatnD+crPqKSqGPHp1vnlsWM/07ubf7bheF7kqSj84Bm0R1fYTfaK8vqqqfKBtNMhe3OZh6N95CTvMX5HJJi4xOVzCgUOIMSLH7wmeOHaFE4RdpnGavKtrB5xzfO/Ll9'; -var expectedBase64Gzip = 'H4sIAAAAAAAAA11RS05DMQy8yhzg6d2BPSAkJPZu4laWkjiN496pl+mZcAotEpss7PH8crverq86uEK6eUXWogMmE1R5bkjajNPk6QOUpYslaSdwkbnjTcdBcCRPcnDb0H24gSZOgy6SCVnS9LqhyIGHgkbyxXihUsRQKK0raTGrVbM+cKEcPOxoYrLj3Uuh+gBtaHx2jjeh65iEHkQ8KNwuPNgmjjwqt9AG+cl5w0Um8dPX5FJCwagLt2fa3/GOF25MDU1bJAhlHSlsfAwNq2cP5ys+opKoY8enW+eWxYz/Tu5t/tuF4XuSpKPzgGbRHV9hN9ory+qqp8oG00yF7c5mHo33kJO8xfkckmLjE5XMKBQ4gxIsfvCZ44doUThF2mcZq8q2sHnHNzRtagj5AQAA'; +var inputString = 'ΩΩLorem ipsum dolor sit amet, consectetur adipiscing el' + + 'it. Morbi faucibus, purus at gravida dictum, libero arcu convallis la' + + 'cus, in commodo libero metus eu nisi. Nullam commodo, neque nec porta' + + ' placerat, nisi est fermentum augue, vitae gravida tellus sapien sit ' + + 'amet tellus. Aenean non diam orci. Proin quis elit turpis. Suspendiss' + + 'e non diam ipsum. Suspendisse nec ullamcorper odio. Vestibulum arcu m' + + 'i, sodales non suscipit id, ultrices ut massa. Sed ac sem sit amet ar' + + 'cu malesuada fermentum. Nunc sed. '; +var expectedBase64Deflate = 'eJxdUUtOQzEMvMoc4OndgT0gJCT2buJWlpI4jePeqZfpm' + + 'XAKLRKbLOzx/HK73q6vOrhCunlF1qIDJhNUeW5I2ozT5OkDlKWLJWkncJG5403HQXAkT3' + + 'Jw29B9uIEmToMukglZ0vS6ociBh4JG8sV4oVLEUCitK2kxq1WzPnChHDzsaGKy491Lofo' + + 'AbWh8do43oeuYhB5EPCjcLjzYJo48KrfQBvnJecNFJvHT1+RSQsGoC7dn2t/xjhduTA1N' + + 'WyQIZR0pbHwMDatnD+crPqKSqGPHp1vnlsWM/07ubf7bheF7kqSj84Bm0R1fYTfaK8vqq' + + 'qfKBtNMhe3OZh6N95CTvMX5HJJi4xOVzCgUOIMSLH7wmeOHaFE4RdpnGavKtrB5xzfO/Ll9'; +var expectedBase64Gzip = 'H4sIAAAAAAAAA11RS05DMQy8yhzg6d2BPSAkJPZu4laWkjiN' + + '496pl+mZcAotEpss7PH8crverq86uEK6eUXWogMmE1R5bkjajNPk6QOUpYslaSdwkbnjT' + + 'cdBcCRPcnDb0H24gSZOgy6SCVnS9LqhyIGHgkbyxXihUsRQKK0raTGrVbM+cKEcPOxoYr' + + 'Lj3Uuh+gBtaHx2jjeh65iEHkQ8KNwuPNgmjjwqt9AG+cl5w0Um8dPX5FJCwagLt2fa3/G' + + 'OF25MDU1bJAhlHSlsfAwNq2cP5ys+opKoY8enW+eWxYz/Tu5t/tuF4XuSpKPzgGbRHV9h' + + 'N9ory+qqp8oG00yF7c5mHo33kJO8xfkckmLjE5XMKBQ4gxIsfvCZ44doUThF2mcZq8q2s' + + 'HnHNzRtagj5AQAA'; zlib.deflate(inputString, function(err, buffer) { - assert.equal(buffer.toString('base64'), expectedBase64Deflate, 'deflate encoded string should match'); + assert.equal(buffer.toString('base64'), expectedBase64Deflate, + 'deflate encoded string should match'); }); zlib.gzip(inputString, function(err, buffer) { @@ -40,7 +59,7 @@ zlib.gzip(inputString, function(err, buffer) { // However, decrypting it should definitely yield the same // result that we're expecting, and this should match what we get // from inflating the known valid deflate data. - zlib.gunzip(buffer, function (err, gunzipped) { + zlib.gunzip(buffer, function(err, gunzipped) { assert.equal(gunzipped.toString(), inputString, 'Should get original string after gzip/gunzip'); }); @@ -48,10 +67,12 @@ zlib.gzip(inputString, function(err, buffer) { var buffer = new Buffer(expectedBase64Deflate, 'base64'); zlib.unzip(buffer, function(err, buffer) { - assert.equal(buffer.toString(), inputString, 'decoded inflated string should match'); + assert.equal(buffer.toString(), inputString, + 'decoded inflated string should match'); }); buffer = new Buffer(expectedBase64Gzip, 'base64'); zlib.unzip(buffer, function(err, buffer) { - assert.equal(buffer.toString(), inputString, 'decoded gunzipped string should match'); + assert.equal(buffer.toString(), inputString, + 'decoded gunzipped string should match'); }); diff --git a/test/simple/test-zlib-invalid-input.js b/test/simple/test-zlib-invalid-input.js new file mode 100644 index 00000000000..4c581e1c33d --- /dev/null +++ b/test/simple/test-zlib-invalid-input.js @@ -0,0 +1,38 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// test uncompressing invalid input + +var common = require('../common.js'), + assert = require('assert'), + zlib = require('zlib'); + +var nonStringInputs = [1, true, {a: 1}, ['a']]; + +nonStringInputs.forEach(function(input) { + // zlib.gunzip should not throw an error when called with bad input. + assert.doesNotThrow(function () { + zlib.gunzip(input, function (err, buffer) { + // zlib.gunzip should pass the error to the callback. + assert.ok(err); + }); + }); +}); diff --git a/test/simple/test-zlib-random-byte-pipes.js b/test/simple/test-zlib-random-byte-pipes.js index ec5d7015e75..88838c68ca9 100644 --- a/test/simple/test-zlib-random-byte-pipes.js +++ b/test/simple/test-zlib-random-byte-pipes.js @@ -29,7 +29,7 @@ var zlib = require('zlib'); // emit random bytes, and keep a shasum -function RandomReadStream (opt) { +function RandomReadStream(opt) { Stream.call(this); this.readable = true; @@ -67,7 +67,7 @@ RandomReadStream.prototype.resume = function() { // console.error("rrs resume"); this._paused = false; this.emit('resume'); - this._process() + this._process(); }; RandomReadStream.prototype._process = function() { @@ -91,9 +91,9 @@ RandomReadStream.prototype._process = function() { if (jitter) { block += Math.ceil(Math.random() * jitter - (jitter / 2)); } - block = Math.min(block, this._remaining) + block = Math.min(block, this._remaining); var buf = new Buffer(block); - for (var i = 0; i < block; i ++) { + for (var i = 0; i < block; i++) { buf[i] = Math.random() * 256; } @@ -110,7 +110,7 @@ RandomReadStream.prototype._process = function() { // a filter that just verifies a shasum -function HashStream () { +function HashStream() { Stream.call(this); this.readable = this.writable = true; @@ -152,7 +152,7 @@ var gunz = zlib.createGunzip(); inp.pipe(gzip).pipe(gunz).pipe(out); var didSomething = false; -out.on('data', function (c) { +out.on('data', function(c) { didSomething = true; console.error('hash=%s', c); assert.equal(c, inp._hash, 'hashes should match'); @@ -160,4 +160,4 @@ out.on('data', function (c) { process.on('exit', function() { assert(didSomething, 'should have done something'); -}) +});