| #ifndef X_INJECTED_SCRIPT_HOST_ | ||
| #define X_INJECTED_SCRIPT_HOST_ | ||
| #include <nan.h> | ||
| namespace nodex { | ||
| class InjectedScriptHost { | ||
| public: | ||
| static void Initialize(v8::Handle<v8::Object> target); | ||
| static NAN_METHOD(Eval); | ||
| static NAN_METHOD(EvaluateWithExceptionDetails); | ||
| static NAN_METHOD(SetNonEnumProperty); | ||
| static NAN_METHOD(Subtype); | ||
| static NAN_METHOD(InternalConstructorName); | ||
| static NAN_METHOD(FunctionDetailsWithoutScopes); | ||
| static NAN_METHOD(CallFunction); | ||
| /* | ||
| static v8::Local<v8::Value> New(const v8::CpuProfile* node); | ||
| static Nan::Persistent<v8::Array> profiles; | ||
| */ | ||
| private: | ||
| static v8::Handle<v8::Object> createExceptionDetails(v8::Handle<v8::Message> message); | ||
| static v8::Local<v8::String> functionDisplayName(v8::Handle<v8::Function> function); | ||
| /* | ||
| static NAN_METHOD(Delete); | ||
| static void Initialize(); | ||
| static Nan::Persistent<v8::ObjectTemplate> profile_template_; | ||
| static uint32_t uid_counter; | ||
| */ | ||
| }; | ||
| } //namespace nodex | ||
| #endif // X_INJECTED_SCRIPT_HOST_ |
+28
| #ifndef X_DEBUG_TOOLS_ | ||
| #define X_DEBUG_TOOLS_ | ||
| #define CHK(VALUE) \ | ||
| VALUE.ToLocalChecked() | ||
| #define RETURN(VALUE) { \ | ||
| info.GetReturnValue().Set(VALUE); \ | ||
| return; \ | ||
| } | ||
| #define SET(TARGET, NAME, VALUE) \ | ||
| Nan::Set(TARGET, CHK(Nan::New(NAME)), VALUE) | ||
| #define RUNSCRIPT(EXPRESSION, RESULT) while (true) { \ | ||
| Nan::MaybeLocal<Nan::BoundScript> script = Nan::CompileScript(EXPRESSION);\ | ||
| if (tryCatch.HasCaught()) break; \ | ||
| RESULT = Nan::RunScript(CHK(script)); \ | ||
| break; \ | ||
| } | ||
| #define MAYBE_RETHROW() \ | ||
| if (tryCatch.HasCaught()) { \ | ||
| tryCatch.ReThrow(); \ | ||
| return; \ | ||
| } | ||
| #endif // X_DEBUG_TOOLS_ |
| var expect = require('chai').expect; | ||
| var binary = require('node-pre-gyp'); | ||
| var path = require('path'); | ||
| var binding_path = binary.find(path.resolve(path.join(__dirname,'../package.json'))); | ||
| var NODE_NEXT = require('../tools/NODE_NEXT.js'); | ||
| if (!NODE_NEXT) return; | ||
| describe('binding', function() { | ||
| var binding = require(binding_path); | ||
| it('source was builded and can be accessed from script', function() { | ||
| expect(binding.InjectedScriptHost).to.be.instanceof(Object); | ||
| }); | ||
| describe('InjectedScriptHost', function() { | ||
| var host = binding.InjectedScriptHost; | ||
| describe('function `subtype`', function() { | ||
| checksTypeValid(new Array(), 'array'); | ||
| checksTypeValid(new Date(), 'date'); | ||
| checksTypeValid(new RegExp(), 'regexp'); | ||
| checksTypeValid(new Error(), 'error'); | ||
| checksTypeValid(new String(), undefined); | ||
| function checksTypeValid(value, type) { | ||
| it('checks ' + type + ' subtype', function() { | ||
| expect(host.subtype(value)).to.equal(type); | ||
| }); | ||
| } | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.subtype).to.throw(); | ||
| }); | ||
| }); | ||
| describe('function `setNonEnumProperty`', function() { | ||
| it('should set non enumerable property to object', function() { | ||
| var object = { | ||
| 'visibleProp': '1' | ||
| }; | ||
| host.setNonEnumProperty(object, 'hiddenProp', 'value'); | ||
| var keys = Object.keys(object); | ||
| expect(keys).to.deep.equal(['visibleProp']); | ||
| expect(object.hiddenProp).to.equal('value'); | ||
| }); | ||
| throwsOnArgs([]); | ||
| throwsOnArgs([{}, 'a']); | ||
| throwsOnArgs([{}, null, 'b']); | ||
| throwsOnArgs([null, {}, 'b']); | ||
| function throwsOnArgs(argvList) { | ||
| it('should throw on wrong arguments ' + JSON.stringify(argvList), function() { | ||
| expect(host.setNonEnumProperty.bind.apply( | ||
| host.setNonEnumProperty, [host].concat(argvList))).to.throw(); | ||
| }); | ||
| } | ||
| it('should not throw on valid arguments', function() { | ||
| expect(host.setNonEnumProperty.bind(host, {}, 'a', null)).to.not.throw(); | ||
| expect(host.setNonEnumProperty.bind(host, {}, 'a', 'b')).to.not.throw(); | ||
| }); | ||
| }); | ||
| describe('function `internalConstructorName`', function() { | ||
| checksNameValid(new Number(), 'Number'); | ||
| checksNameValid(new Object(), 'Object'); | ||
| function checksNameValid(value, name) { | ||
| it('checks new ' + name + '() constructor name', function() { | ||
| expect(host.internalConstructorName(value)).to.equal(name); | ||
| }); | ||
| } | ||
| throwsOnArgs([]); | ||
| throwsOnArgs([1]); | ||
| throwsOnArgs([null]); | ||
| function throwsOnArgs(argvList) { | ||
| it('should throw on wrong arguments ' + JSON.stringify(argvList), function() { | ||
| expect(host.internalConstructorName.bind.apply( | ||
| host.internalConstructorName, [host].concat(argvList))).to.throw(); | ||
| }); | ||
| } | ||
| }); | ||
| describe('function `functionDetailsWithoutScopes`', function() { | ||
| it('should return valid details', function() { | ||
| function example() {} | ||
| var details = host.functionDetailsWithoutScopes(example); | ||
| expect(details).to.include.keys(['location', 'functionName']); | ||
| expect(details.location).to.include.keys(['lineNumber', 'columnNumber', 'scriptId']); | ||
| }); | ||
| throwsOnArgs([]); | ||
| throwsOnArgs([null]); | ||
| function throwsOnArgs(argvList) { | ||
| it('should throw on wrong arguments ' + JSON.stringify(argvList), function() { | ||
| expect(host.functionDetailsWithoutScopes.bind.apply( | ||
| host.functionDetailsWithoutScopes, [host].concat(argvList))).to.throw(); | ||
| }); | ||
| } | ||
| }); | ||
| describe('function `eval`', function() { | ||
| it('should evaluate expression', function() { | ||
| expect(host.eval("[1]")).to.deep.equal([1]); | ||
| }); | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.eval).to.throw(); | ||
| }); | ||
| it('should throw on wrong expression', function() { | ||
| expect(host.eval.bind(null, "[1")).to.throw(SyntaxError); | ||
| }); | ||
| }); | ||
| describe('function `evaluateWithExceptionDetails`', function() { | ||
| it('should evaluate expression', function() { | ||
| expect(host.evaluateWithExceptionDetails("[1]")).to.deep.equal({ | ||
| result: [1], | ||
| exceptionDetails: undefined | ||
| }); | ||
| }); | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.evaluateWithExceptionDetails).to.throw(); | ||
| }); | ||
| }); | ||
| describe('function `callFunction`', function() { | ||
| it('should call function without args', function(done) { | ||
| host.callFunction(done, this); | ||
| }); | ||
| it('should call function with args', function(done) { | ||
| host.callFunction(function(arg) { | ||
| expect(arg).to.equal(1); | ||
| done(); | ||
| }, this, [1]); | ||
| }); | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.callFunction.bind(null, null, null, [1])).to.throw(); | ||
| expect(host.callFunction.bind(null, null, null, 1)).to.throw(); | ||
| }); | ||
| it('should rethrow ReferenceError', function() { | ||
| expect(host.callFunction.bind(null, function() { | ||
| 'use strict'; | ||
| if (error_here) return; | ||
| }, this)).to.throw(ReferenceError); | ||
| }); | ||
| }); | ||
| }); | ||
| }); |
| return module.exports = process.versions.modules > 45; |
+3
-2
| { | ||
| "name": "v8-debug", | ||
| "version": "0.5.4", | ||
| "version": "0.6.0", | ||
| "description": "v8 debugger extending API", | ||
@@ -40,6 +40,7 @@ "homepage": "http://github.com/node-inspector/v8-debug", | ||
| "scripts": { | ||
| "preinstall": " ", | ||
| "preinstall": "node -e 'process.exit(0)'", | ||
| "install": "node-pre-gyp install --fallback-to-build", | ||
| "rebuild": "node-pre-gyp rebuild", | ||
| "test": "mocha --debug" | ||
| } | ||
| } |
+10
-295
@@ -0,65 +1,29 @@ | ||
| #include <v8-debug.h> | ||
| #include <nan.h> | ||
| #include <v8-debug.h> | ||
| #include "tools.h" | ||
| #if (NODE_NEXT) | ||
| #include "InjectedScriptHost.h" | ||
| #endif | ||
| using v8::Isolate; | ||
| using v8::Handle; | ||
| using v8::Local; | ||
| using v8::Value; | ||
| using v8::Number; | ||
| using v8::Integer; | ||
| using v8::String; | ||
| using v8::Script; | ||
| using v8::Object; | ||
| using v8::Array; | ||
| using v8::Message; | ||
| using v8::Context; | ||
| using v8::Function; | ||
| using v8::FunctionTemplate; | ||
| using Nan::To; | ||
| using Nan::New; | ||
| using Nan::Get; | ||
| using Nan::Set; | ||
| using Nan::ForceSet; | ||
| using Nan::SetMethod; | ||
| using Nan::HandleScope; | ||
| using Nan::EscapableHandleScope; | ||
| using Nan::Undefined; | ||
| using Nan::TryCatch; | ||
| using Nan::ThrowError; | ||
| using Nan::ThrowTypeError; | ||
| using Nan::CompileScript; | ||
| using Nan::RunScript; | ||
| using Nan::MaybeLocal; | ||
| using Nan::EmptyString; | ||
| using Nan::BoundScript; | ||
| using Nan::Utf8String; | ||
| namespace nodex { | ||
| #define CHK(VALUE) \ | ||
| VALUE.ToLocalChecked() | ||
| #define RETURN(VALUE) { \ | ||
| info.GetReturnValue().Set(VALUE); \ | ||
| return; \ | ||
| } | ||
| #define SET(TARGET, NAME, VALUE) \ | ||
| Set(TARGET, CHK(New(NAME)), VALUE) | ||
| #define RUNSCRIPT(EXPRESSION, RESULT) while (true) { \ | ||
| MaybeLocal<BoundScript> script = CompileScript(EXPRESSION); \ | ||
| if (tryCatch.HasCaught()) break; \ | ||
| RESULT = Nan::RunScript(CHK(script)); \ | ||
| break; \ | ||
| } | ||
| #define MAYBE_RETHROW() \ | ||
| if (tryCatch.HasCaught()) { \ | ||
| tryCatch.ReThrow(); \ | ||
| return; \ | ||
| } | ||
| class Debug { | ||
@@ -73,3 +37,3 @@ public: | ||
| Handle<Function> fn = Handle<Function>::Cast(info[0]); | ||
| Local<Function> fn = Local<Function>::Cast(info[0]); | ||
| v8::Debug::Call(fn); | ||
@@ -82,3 +46,3 @@ | ||
| String::Value command(info[0]); | ||
| #if (NODE_MODULE_VERSION > 0x000B) | ||
| #if (NODE_MODULE_VERSION > 11) | ||
| Isolate* debug_isolate = v8::Debug::GetDebugContext()->GetIsolate(); | ||
@@ -99,3 +63,2 @@ v8::HandleScope debug_scope(debug_isolate); | ||
| Local<Context> debug_context = v8::Debug::GetDebugContext(); | ||
@@ -126,242 +89,2 @@ #if (NODE_MODULE_VERSION > 45) | ||
| static Handle<Object> createExceptionDetails(Handle<Message> message) { | ||
| EscapableHandleScope scope; | ||
| Local<Object> exceptionDetails = New<Object>(); | ||
| SET(exceptionDetails, "text", message->Get()); | ||
| #if (NODE_MODULE_VERSION > 0x000E) | ||
| SET(exceptionDetails, "url", message->GetScriptOrigin().ResourceName()); | ||
| SET(exceptionDetails, "scriptId", New<Integer>((int32_t)message->GetScriptOrigin().ScriptID()->Value())); | ||
| #else | ||
| SET(exceptionDetails, "url", message->GetScriptResourceName()); | ||
| #endif | ||
| SET(exceptionDetails, "line", New<Integer>(message->GetLineNumber())); | ||
| SET(exceptionDetails, "column", New<Number>(message->GetStartColumn())); | ||
| if (!message->GetStackTrace().IsEmpty()) | ||
| SET(exceptionDetails, "stackTrace", message->GetStackTrace()->AsArray()); | ||
| else | ||
| SET(exceptionDetails, "stackTrace", Undefined()); | ||
| return scope.Escape(exceptionDetails); | ||
| }; | ||
| static NAN_METHOD(EvaluateWithExceptionDetails) { | ||
| if (info.Length() < 1) | ||
| return ThrowError("One argument expected."); | ||
| Local<Object> wrappedResult = New<Object>(); | ||
| Local<String> expression = CHK(To<String>(info[0])); | ||
| if (expression.IsEmpty()) | ||
| return ThrowTypeError("The argument must be a string."); | ||
| TryCatch tryCatch; | ||
| MaybeLocal<Value> result; | ||
| RUNSCRIPT(expression, result); | ||
| if (tryCatch.HasCaught()) { | ||
| SET(wrappedResult, "result", tryCatch.Exception()); | ||
| SET(wrappedResult, "exceptionDetails", createExceptionDetails(tryCatch.Message())); | ||
| } else { | ||
| SET(wrappedResult, "result", CHK(result)); | ||
| SET(wrappedResult, "exceptionDetails", Undefined()); | ||
| } | ||
| RETURN(wrappedResult); | ||
| }; | ||
| static NAN_METHOD(SetNonEnumProperty) { | ||
| if (info.Length() < 3) | ||
| return ThrowError("Three arguments expected."); | ||
| if (!info[0]->IsObject()) | ||
| return ThrowTypeError("Argument 0 must be an object."); | ||
| if (!info[1]->IsString()) | ||
| return ThrowTypeError("Argument 1 must be a string."); | ||
| Local<Object> object = CHK(To<Object>(info[0])); | ||
| ForceSet(object, info[1], info[2], v8::DontEnum); | ||
| RETURN(Undefined()); | ||
| }; | ||
| static NAN_METHOD(Subtype) { | ||
| if (info.Length() < 1) | ||
| return ThrowError("One argument expected."); | ||
| Handle<Value> value = info[0]; | ||
| if (value->IsArray()) | ||
| RETURN(CHK(New("array"))); | ||
| #if (NODE_MODULE_VERSION > 0x000B) | ||
| if (value->IsTypedArray()) | ||
| RETURN(CHK(New("array"))); | ||
| #endif | ||
| if (value->IsDate()) | ||
| RETURN(CHK(New("date"))); | ||
| if (value->IsRegExp()) | ||
| RETURN(CHK(New("regexp"))); | ||
| if (value->IsNativeError()) | ||
| RETURN(CHK(New("error"))); | ||
| #if (NODE_MODULE_VERSION > 0x000E) | ||
| if (value->IsArgumentsObject()) | ||
| RETURN(CHK(New("array"))); | ||
| if (value->IsMap() || value->IsWeakMap()) | ||
| RETURN(CHK(New("map"))); | ||
| if (value->IsSet() || value->IsWeakSet()) | ||
| RETURN(CHK(New("set"))); | ||
| if (value->IsMapIterator() || value->IsSetIterator()) | ||
| RETURN(CHK(New("iterator"))); | ||
| #endif | ||
| RETURN(Undefined()); | ||
| }; | ||
| static Local<String> functionDisplayName(Handle<Function> function) { | ||
| EscapableHandleScope scope; | ||
| Local<String> value; | ||
| #if (NODE_MODULE_VERSION > 0x000B) | ||
| value = CHK(To<String>(function->GetDisplayName())); | ||
| if (value->Length()) | ||
| return scope.Escape(value); | ||
| value = CHK(To<String>(function->GetName())); | ||
| if (value->Length()) | ||
| return scope.Escape(value); | ||
| value = CHK(To<String>(function->GetInferredName())); | ||
| if (value->Length()) | ||
| return scope.Escape(value); | ||
| #else | ||
| value = function->GetName()->ToString(); | ||
| if (value->Length()) | ||
| return scope.Escape(value); | ||
| value = function->GetInferredName()->ToString(); | ||
| if (value->Length()) | ||
| return scope.Escape(value); | ||
| #endif | ||
| return scope.Escape(EmptyString()); | ||
| }; | ||
| static NAN_METHOD(InternalConstructorName) { | ||
| if (info.Length() < 1) | ||
| return ThrowError("One argument expected."); | ||
| if (!info[0]->IsObject()) | ||
| return ThrowTypeError("The argument must be an object."); | ||
| Local<Object> object = CHK(To<Object>(info[0])); | ||
| Local<String> result = object->GetConstructorName(); | ||
| const char* result_type; | ||
| if (result.IsEmpty() || result->IsNull() || result->IsUndefined()) | ||
| result_type = ""; | ||
| else | ||
| result_type = *Utf8String(info[0]); | ||
| if (!result.IsEmpty() && strcmp(result_type, "Object") == 0) { | ||
| Local<String> constructorSymbol = CHK(New("constructor")); | ||
| if (object->HasRealNamedProperty(constructorSymbol) && !object->HasRealNamedCallbackProperty(constructorSymbol)) { | ||
| TryCatch tryCatch; | ||
| Local<Value> constructor = object->GetRealNamedProperty(constructorSymbol); | ||
| if (!constructor.IsEmpty() && constructor->IsFunction()) { | ||
| Local<String> constructorName = functionDisplayName(Handle<Function>::Cast(constructor)); | ||
| if (!constructorName.IsEmpty() && !tryCatch.HasCaught()) | ||
| result = constructorName; | ||
| } | ||
| } | ||
| if (strcmp(result_type, "Object") == 0 && object->IsFunction()) | ||
| result = CHK(New("Function")); | ||
| } | ||
| RETURN(result); | ||
| } | ||
| static NAN_METHOD(FunctionDetailsWithoutScopes) { | ||
| if (info.Length() < 1) | ||
| return ThrowError("One argument expected."); | ||
| if (!info[0]->IsFunction()) | ||
| return ThrowTypeError("The argument must be a function."); | ||
| Handle<Function> function = Handle<Function>::Cast(info[0]); | ||
| int32_t lineNumber = function->GetScriptLineNumber(); | ||
| int32_t columnNumber = function->GetScriptColumnNumber(); | ||
| Local<Object> location = New<Object>(); | ||
| SET(location, "lineNumber", New(lineNumber)); | ||
| SET(location, "columnNumber", New(columnNumber)); | ||
| #if (NODE_MODULE_VERSION > 0x000B) | ||
| SET(location, "scriptId", CHK(To<String>(New(function->ScriptId())))); | ||
| #else | ||
| SET(location, "scriptId", CHK(To<String>(New(function->GetScriptId()->ToInt32()->Value())))); | ||
| #endif | ||
| Local<Object> result = New<Object>(); | ||
| SET(result, "location", location); | ||
| Handle<String> name = functionDisplayName(function); | ||
| SET(result, "functionName", name.IsEmpty() ? EmptyString() : name); | ||
| RETURN(result); | ||
| } | ||
| static NAN_METHOD(CallFunction) { | ||
| if (info.Length() < 2 || info.Length() > 3) | ||
| return ThrowError("Two or three arguments expected."); | ||
| if (!info[0]->IsFunction()) | ||
| return ThrowTypeError("Argument 0 must be a function."); | ||
| Handle<Function> function = Handle<Function>::Cast(info[0]); | ||
| #if (NODE_MODULE_VERSION > 0x000B) | ||
| Handle<Value> receiver = info[1]; | ||
| #else | ||
| Handle<Object> receiver = CHK(To<Object>(info[1])); | ||
| #endif | ||
| TryCatch tryCatch; | ||
| MaybeLocal<Value> result; | ||
| if (info.Length() < 3 || info[2]->IsUndefined()) { | ||
| result = function->Call(receiver, 0, NULL); | ||
| MAYBE_RETHROW(); | ||
| RETURN(CHK(result)); | ||
| } | ||
| if (!info[2]->IsArray()) | ||
| return ThrowTypeError("Argument 2 must be an array."); | ||
| Handle<Array> arguments = Handle<Array>::Cast(info[2]); | ||
| int argc = arguments->Length(); | ||
| Handle<Value> *argv = new Handle<Value>[argc]; | ||
| for (int i = 0; i < argc; ++i) | ||
| argv[i] = CHK(Get(arguments, i)); | ||
| result = function->Call(receiver, argc, argv); | ||
| delete [] argv; | ||
| MAYBE_RETHROW(); | ||
| RETURN(CHK(result)); | ||
| }; | ||
| static NAN_METHOD(Eval) { | ||
| if (info.Length() < 1) | ||
| return ThrowError("One argument expected."); | ||
| Local<String> expression = info[0]->ToString(); | ||
| if (expression.IsEmpty()) | ||
| return ThrowTypeError("The argument must be a string."); | ||
| TryCatch tryCatch; | ||
| MaybeLocal<Value> result; | ||
| RUNSCRIPT(expression, result); | ||
| MAYBE_RETHROW(); | ||
| RETURN(CHK(result)); | ||
| }; | ||
| private: | ||
@@ -373,13 +96,6 @@ Debug() {} | ||
| NAN_MODULE_INIT(Initialize) { | ||
| HandleScope scope; | ||
| #if (NODE_NEXT) | ||
| InjectedScriptHost::Initialize(target); | ||
| #endif | ||
| Local<Object> InjectedScriptHost = New<Object>(); | ||
| SetMethod(InjectedScriptHost, "eval", Debug::Eval); | ||
| SetMethod(InjectedScriptHost, "evaluateWithExceptionDetails", Debug::EvaluateWithExceptionDetails); | ||
| SetMethod(InjectedScriptHost, "setNonEnumProperty", Debug::SetNonEnumProperty); | ||
| SetMethod(InjectedScriptHost, "subtype", Debug::Subtype); | ||
| SetMethod(InjectedScriptHost, "internalConstructorName", Debug::InternalConstructorName); | ||
| SetMethod(InjectedScriptHost, "functionDetailsWithoutScopes", Debug::FunctionDetailsWithoutScopes); | ||
| SetMethod(InjectedScriptHost, "callFunction", Debug::CallFunction); | ||
| SetMethod(target, "call", Debug::Call); | ||
@@ -389,3 +105,2 @@ SetMethod(target, "sendCommand", Debug::SendCommand); | ||
| SetMethod(target, "allowNatives", Debug::AllowNatives); | ||
| SET(target, "InjectedScriptHost", InjectedScriptHost); | ||
| } | ||
@@ -392,0 +107,0 @@ |
+0
-145
@@ -29,147 +29,2 @@ var expect = require('chai').expect; | ||
| }); | ||
| describe('InjectedScriptHost', function() { | ||
| var host = binding.InjectedScriptHost; | ||
| describe('function `subtype`', function() { | ||
| checksTypeValid(new Array(), 'array'); | ||
| checksTypeValid(new Date(), 'date'); | ||
| checksTypeValid(new RegExp(), 'regexp'); | ||
| checksTypeValid(new Error(), 'error'); | ||
| checksTypeValid(new String(), undefined); | ||
| function checksTypeValid(value, type) { | ||
| it('checks ' + type + ' subtype', function() { | ||
| expect(host.subtype(value)).to.equal(type); | ||
| }); | ||
| } | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.subtype).to.throw(); | ||
| }); | ||
| }); | ||
| describe('function `setNonEnumProperty`', function() { | ||
| it('should set non enumerable property to object', function() { | ||
| var object = { | ||
| 'visibleProp': '1' | ||
| }; | ||
| host.setNonEnumProperty(object, 'hiddenProp', 'value'); | ||
| var keys = Object.keys(object); | ||
| expect(keys).to.deep.equal(['visibleProp']); | ||
| expect(object.hiddenProp).to.equal('value'); | ||
| }); | ||
| throwsOnArgs([]); | ||
| throwsOnArgs([{}, 'a']); | ||
| throwsOnArgs([{}, null, 'b']); | ||
| throwsOnArgs([null, {}, 'b']); | ||
| function throwsOnArgs(argvList) { | ||
| it('should throw on wrong arguments ' + JSON.stringify(argvList), function() { | ||
| expect(host.setNonEnumProperty.bind.apply( | ||
| host.setNonEnumProperty, [host].concat(argvList))).to.throw(); | ||
| }); | ||
| } | ||
| it('should not throw on valid arguments', function() { | ||
| expect(host.setNonEnumProperty.bind(host, {}, 'a', null)).to.not.throw(); | ||
| expect(host.setNonEnumProperty.bind(host, {}, 'a', 'b')).to.not.throw(); | ||
| }); | ||
| }); | ||
| describe('function `internalConstructorName`', function() { | ||
| checksNameValid(new Number(), 'Number'); | ||
| checksNameValid(new Object(), 'Object'); | ||
| function checksNameValid(value, name) { | ||
| it('checks new ' + name + '() constructor name', function() { | ||
| expect(host.internalConstructorName(value)).to.equal(name); | ||
| }); | ||
| } | ||
| throwsOnArgs([]); | ||
| throwsOnArgs([1]); | ||
| throwsOnArgs([null]); | ||
| function throwsOnArgs(argvList) { | ||
| it('should throw on wrong arguments ' + JSON.stringify(argvList), function() { | ||
| expect(host.internalConstructorName.bind.apply( | ||
| host.internalConstructorName, [host].concat(argvList))).to.throw(); | ||
| }); | ||
| } | ||
| }); | ||
| describe('function `functionDetailsWithoutScopes`', function() { | ||
| it('should return valid details', function() { | ||
| function example() {} | ||
| var details = host.functionDetailsWithoutScopes(example); | ||
| expect(details).to.include.keys(['location', 'functionName']); | ||
| expect(details.location).to.include.keys(['lineNumber', 'columnNumber', 'scriptId']); | ||
| }); | ||
| throwsOnArgs([]); | ||
| throwsOnArgs([null]); | ||
| function throwsOnArgs(argvList) { | ||
| it('should throw on wrong arguments ' + JSON.stringify(argvList), function() { | ||
| expect(host.functionDetailsWithoutScopes.bind.apply( | ||
| host.functionDetailsWithoutScopes, [host].concat(argvList))).to.throw(); | ||
| }); | ||
| } | ||
| }); | ||
| describe('function `eval`', function() { | ||
| it('should evaluate expression', function() { | ||
| expect(host.eval("[1]")).to.deep.equal([1]); | ||
| }); | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.eval).to.throw(); | ||
| }); | ||
| it('should throw on wrong expression', function() { | ||
| expect(host.eval.bind(null, "[1")).to.throw(SyntaxError); | ||
| }); | ||
| }); | ||
| describe('function `evaluateWithExceptionDetails`', function() { | ||
| it('should evaluate expression', function() { | ||
| expect(host.evaluateWithExceptionDetails("[1]")).to.deep.equal({ | ||
| result: [1], | ||
| exceptionDetails: undefined | ||
| }); | ||
| }); | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.evaluateWithExceptionDetails).to.throw(); | ||
| }); | ||
| }); | ||
| describe('function `callFunction`', function() { | ||
| it('should call function without args', function(done) { | ||
| host.callFunction(done, this); | ||
| }); | ||
| it('should call function with args', function(done) { | ||
| host.callFunction(function(arg) { | ||
| expect(arg).to.equal(1); | ||
| done(); | ||
| }, this, [1]); | ||
| }); | ||
| it('should throw on wrong arguments', function() { | ||
| expect(host.callFunction.bind(null, null, null, [1])).to.throw(); | ||
| expect(host.callFunction.bind(null, null, null, 1)).to.throw(); | ||
| }); | ||
| it('should rethrow ReferenceError', function() { | ||
| expect(host.callFunction.bind(null, function() { | ||
| 'use strict'; | ||
| if (error_here) return; | ||
| }, this)).to.throw(ReferenceError); | ||
| }); | ||
| }); | ||
| }); | ||
| }); |
+18
-10
| var expect = require('chai').expect, | ||
| v8debug = require('../'); | ||
| var NODE_NEXT = require('../tools/NODE_NEXT'); | ||
| var _debugger = require('child_process').spawn('node', ['./test/helpers/debugger.js']); | ||
@@ -35,13 +37,19 @@ | ||
| it('enableWebkitProtocol should enable Webkit protocol', function() { | ||
| v8debug.enableWebkitProtocol(); | ||
| expect(v8debug.enableWebkitProtocol.bind(v8debug)).to.not.throw(); | ||
| }); | ||
| if (NODE_NEXT) { | ||
| it('enableWebkitProtocol should enable Webkit protocol', function() { | ||
| v8debug.enableWebkitProtocol(); | ||
| expect(v8debug.enableWebkitProtocol.bind(v8debug)).to.not.throw(); | ||
| }); | ||
| it('if enabled registerAgentCommand should register command', function(done) { | ||
| expect(v8debug.registerAgentCommand.bind(v8debug, 'command', [], function() { | ||
| done(); | ||
| })).to.not.throw(); | ||
| v8debug.sendCommand('command'); | ||
| }); | ||
| it('if enabled registerAgentCommand should register command', function(done) { | ||
| expect(v8debug.registerAgentCommand.bind(v8debug, 'command', [], function() { | ||
| done(); | ||
| })).to.not.throw(); | ||
| v8debug.sendCommand('command'); | ||
| }); | ||
| } else { | ||
| it('enableWebkitProtocol should throw error', function() { | ||
| expect(v8debug.enableWebkitProtocol).to.throw(); | ||
| }); | ||
| } | ||
| }); | ||
@@ -48,0 +56,0 @@ |
+6
-0
@@ -10,2 +10,4 @@ var binary = require('node-pre-gyp'); | ||
| var NODE_NEXT = require('./tools/NODE_NEXT'); | ||
| // Don't cache debugger module | ||
@@ -218,2 +220,6 @@ delete require.cache[module.id]; | ||
| V8Debug.prototype.enableWebkitProtocol = function() { | ||
| if (!NODE_NEXT) { | ||
| throw new Error('WebKit protocol is not supported on target node version (' + process.version + ')'); | ||
| } | ||
| if (this._webkitProtocolEnabled) return; | ||
@@ -220,0 +226,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Install scripts
Supply chain riskInstall scripts are run when the package is installed or built. Malicious packages often use scripts that run automatically to execute payloads or fetch additional code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed or built. Malicious packages often use scripts that run automatically to execute payloads or fetch additional code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
127437
6.62%21
23.53%2733
4.63%10
-23.08%9
50%