├── .gitignore ├── makefile ├── lib ├── vendor │ └── js-opts │ │ ├── .hgignore │ │ ├── .hg_archival.txt │ │ ├── README │ │ ├── example3.js │ │ ├── example1.js │ │ ├── example4.js │ │ ├── LICENSE │ │ ├── example2.js │ │ └── opts.js ├── ndb │ ├── commands │ │ ├── step_in.js │ │ ├── step_out.js │ │ ├── quit.js │ │ ├── continue.js │ │ ├── version.js │ │ ├── step.js │ │ ├── help.js │ │ ├── verbose.js │ │ ├── next.js │ │ ├── backtrace.js │ │ ├── raw_write.js │ │ ├── history.js │ │ ├── break.js │ │ ├── repl.js │ │ ├── evaluate.js │ │ ├── setbreakpoint.js │ │ └── list.js │ ├── message_parser.js │ ├── commands.js │ ├── helpers.js │ ├── main.js │ ├── option_parser.js │ ├── command_center.js │ └── event_listener.js └── ndb.js ├── .ditz-config ├── bin └── ndb ├── spec ├── unit │ ├── node_spec.js │ ├── state.js │ ├── commands │ │ ├── help.js │ │ ├── continue.js │ │ ├── quit.js │ │ ├── version.js │ │ ├── history.js │ │ ├── step_in.js │ │ ├── step_out.js │ │ ├── verbose.js │ │ ├── raw_write.js │ │ ├── list.js │ │ ├── repl.js │ │ ├── backtrace.js │ │ ├── next.js │ │ ├── evaluate.js │ │ └── setbreakpoint.js │ ├── ndb.js │ ├── spec.helper.js │ ├── message_parser.js │ ├── event_listeners │ │ ├── source.js │ │ └── break.js │ ├── event_listener.js │ ├── spec.js │ ├── option_parser │ │ └── option_parser_spec.js │ └── command_center.js ├── fixtures │ ├── backtrace_one_output.txt │ └── backtrace_one.js └── node.js ├── .gitmodules ├── package.json ├── Rakefile ├── bugs ├── issue-cf5776071382766d9b1a8138764f61803bd89187.yaml ├── issue-076604a4da8e74f9cf0d21905affd4784e37e76b.yaml ├── issue-a3186b7a4ba509122aa448d1878a31dedc01b734.yaml ├── issue-4d556abcd314ded02d84d205f2f00c80c20cd947.yaml ├── issue-b9e9f0bc319918f4f6fc9e6a7dcb3f24da0c4885.yaml ├── issue-7d59e14b137e633d22d3270768de22dbb1b81063.yaml ├── issue-20b8233f1c98b73504a3390a93d648be9e6cab91.yaml ├── issue-ab0738bb06ef3b545497991dcaa257a57aa5bce6.yaml ├── issue-5c67d835c9b48fae705b016479f111f849d52432.yaml ├── issue-81f88ce897f0af5fb45a26f67e510acb59350066.yaml ├── issue-52176871fbdf6851c5f447154de8001d28897164.yaml ├── issue-42c787954471dffb9a81a938e66a38750a820042.yaml ├── issue-1d6c2ce3dabebc58914f1e59c0c035d77cf9893e.yaml ├── issue-1828642d0eeea0fec3b2858b9042e7f481c68db4.yaml ├── issue-a137797b955bbb73a14bb820581396d077a15c36.yaml ├── issue-25cc1df8c4a3d316704d42cfb45cf4f5db5854d2.yaml ├── issue-ccd5785e2f5ab794eb9327ddc3a75f62875b13a7.yaml ├── issue-e2795256659b306f7e10a8027a07d4fc68561332.yaml ├── issue-9f024e237aa0de2c3ec9844e34f57d28603c3e60.yaml ├── issue-6e2e86e3118f9eff7e4fe9e6f774c0a01539796e.yaml ├── issue-15d0b5c14d26eed3ae77579da27a97a9e737e178.yaml ├── issue-6eb9906701c3a3ec3ebfedddffb1df0783670d7a.yaml └── project.yaml ├── Readme.md └── CHANGELOG /.gitignore: -------------------------------------------------------------------------------- 1 | *.tmproj 2 | .DS_Store -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | test: 2 | node spec/node.js -------------------------------------------------------------------------------- /lib/vendor/js-opts/.hgignore: -------------------------------------------------------------------------------- 1 | # use glob syntax. 2 | syntax: glob 3 | 4 | *.swp 5 | *~ 6 | -------------------------------------------------------------------------------- /.ditz-config: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/config 2 | name: Scott Taylor 3 | email: scott@railsnewbie.com 4 | issue_dir: bugs 5 | -------------------------------------------------------------------------------- /lib/vendor/js-opts/.hg_archival.txt: -------------------------------------------------------------------------------- 1 | repo: e84e7c9b5d4b210ae78de578a707e13094061383 2 | node: 2e251e82a2aa4f458012dc07caec8634a6e31fe3 3 | -------------------------------------------------------------------------------- /bin/ndb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | ; 3 | 4 | require.paths.unshift(__dirname + "/../lib"); 5 | 6 | var ndb = require("ndb"); 7 | ndb.OptionParser.parse(); 8 | -------------------------------------------------------------------------------- /spec/unit/node_spec.js: -------------------------------------------------------------------------------- 1 | describe("node & jspec integration", function() { 2 | it("should pass with true === true", function() { 3 | true.should.equal(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /lib/ndb/commands/step_in.js: -------------------------------------------------------------------------------- 1 | var step = require("ndb/commands/step"); 2 | 3 | exports.commandNames = ["s", "step", "stepin"]; 4 | exports.stepAction = "in"; 5 | 6 | for (var key in step) { 7 | exports[key] = step[key]; 8 | } -------------------------------------------------------------------------------- /lib/ndb/commands/step_out.js: -------------------------------------------------------------------------------- 1 | var step = require("ndb/commands/step"); 2 | 3 | exports.commandNames = ["so", "stepout"]; 4 | exports.stepAction = "out"; 5 | 6 | for (var key in step) { 7 | exports[key] = step[key]; 8 | } -------------------------------------------------------------------------------- /lib/vendor/js-opts/README: -------------------------------------------------------------------------------- 1 | 2 | Version: 3 | 1.0 4 | 5 | Installation: 6 | Just copy opts.js to your node.js project and import it with the require 7 | function. See included files for an example. 8 | 9 | Bugs: 10 | Please report bugs tohttp://bitbucket.org/mazzarelli/js-opts/issues/ 11 | 12 | -------------------------------------------------------------------------------- /lib/ndb/commands/quit.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["quit", "exit"]; 6 | 7 | exports.parseCommand = function(text) { 8 | return this.ndb.Helpers.commonParse.call(this, text); 9 | }; 10 | 11 | exports.run = function() { 12 | this.ndb.Helpers.puts("bye!"); 13 | process.exit(); 14 | }; 15 | -------------------------------------------------------------------------------- /lib/ndb/commands/continue.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["c", "continue"]; 6 | 7 | exports.parseCommand = function(text) { 8 | return this.ndb.Helpers.commonParse.call(this, text); 9 | }; 10 | 11 | exports.run = function(json) { 12 | this.ndb.Commands.RawWrite.run({ 13 | type: "request", 14 | command: "continue" 15 | }); 16 | }; 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "spec/espionage"] 2 | path = spec/espionage 3 | url = git://github.com/smtlaissezfaire/espionage.git 4 | [submodule "spec/underscore"] 5 | path = spec/underscore 6 | url = git://github.com/documentcloud/underscore.git 7 | [submodule "spec/jspec"] 8 | path = spec/jspec 9 | url = git://github.com/visionmedia/jspec.git 10 | [submodule "spec/jspec_dot_reporter"] 11 | path = spec/jspec_dot_reporter 12 | url = git://github.com/smtlaissezfaire/jspec_dot_reporter.git 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ndb", 3 | "author": "Scott Taylor (http://blog.railsnewbie.com/)", 4 | "version": "0.2.3", 5 | "bin": "./bin/ndb", 6 | "main": "./lib/ndb.js", 7 | "directories": { 8 | "bin": "./bin", 9 | "lib": "./lib", 10 | "doc": "./doc" 11 | }, 12 | "repository": { 13 | "url": "git://github.com/smtlaissezfaire/ndb.git", 14 | "type": "git" 15 | }, 16 | "scripts": { 17 | "test": "make test" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/vendor/js-opts/example3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple example that is broken by design (conflicting options) 3 | * 4 | * Examples: 5 | * $ node example3.js 6 | * > Conflicting flags: -v 7 | */ 8 | 9 | var opts = require('./opts'); 10 | 11 | var options = [ 12 | { short : 'v' 13 | , description : 'Show version and exit' 14 | }, 15 | { short : 'v' 16 | , description : 'Be verbose' 17 | }, 18 | ]; 19 | 20 | opts.parse(options); 21 | puts('Example 3'); 22 | process.exit(0); 23 | 24 | 25 | -------------------------------------------------------------------------------- /lib/ndb/commands/version.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["version"]; 6 | 7 | exports.parseCommand = function(text) { 8 | return this.ndb.Helpers.commonParse.call(this, text); 9 | }; 10 | 11 | exports.run = function() { 12 | var ndb = this.ndb, 13 | puts = ndb.Helpers.puts, 14 | version = ndb.version; 15 | 16 | puts("ndb: version " + version); 17 | puts("node (local): version " + process.version); 18 | ndb.Helpers.prompt(); 19 | }; 20 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | 2 | desc "JS lint the project. Must have jsl installed in path" 3 | task :jsl do 4 | def jsl_file(filename) 5 | puts `jsl -process #{filename}` 6 | end 7 | 8 | files = [ 9 | Dir.glob("lib/**/*.js"), 10 | Dir.glob("spec/unit/**/*.js"), 11 | "spec/node.js" 12 | ].flatten 13 | 14 | files.each do |file| 15 | unless file =~ /vendor/ 16 | jsl_file(file) 17 | end 18 | end 19 | end 20 | 21 | desc "Run specs by opening in browser. Only works on OS X" 22 | task :spec do 23 | sh "node spec/node.js" 24 | end 25 | 26 | task :default => [:jsl, :spec] 27 | -------------------------------------------------------------------------------- /lib/ndb/commands/step.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.parseCommand = function(text) { 6 | var ndb = this.ndb; 7 | return ndb.Helpers.commonParse.call(this, text); 8 | }; 9 | 10 | exports.run = function(stepcount) { 11 | var ndb = this.ndb, 12 | rw = ndb.Commands.RawWrite; 13 | 14 | if (stepcount === undefined) { 15 | stepcount = 1; 16 | } 17 | 18 | rw.run({ 19 | type: "request", 20 | command: "continue", 21 | arguments: { 22 | stepaction: this.stepAction, 23 | stepcount: stepcount 24 | } 25 | }); 26 | }; -------------------------------------------------------------------------------- /bugs/issue-cf5776071382766d9b1a8138764f61803bd89187.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: remove rakefile 3 | desc: remove rakefile in favor of makefile. Currently, there is both a rakefile & makefile. 4 | type: :task 5 | component: ndb 6 | release: 7 | reporter: Scott Taylor 8 | status: :unstarted 9 | disposition: 10 | creation_time: 2010-05-30 05:38:29.111993 Z 11 | references: [] 12 | 13 | id: cf5776071382766d9b1a8138764f61803bd89187 14 | log_events: 15 | - - 2010-05-30 05:38:30.063909 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | -------------------------------------------------------------------------------- /spec/unit/state.js: -------------------------------------------------------------------------------- 1 | describe('NodeDebugger', function() { 2 | describe('State', function() { 3 | it("should have the filename as null", function() { 4 | ndb.State.filename.should.equal(null); 5 | }); 6 | 7 | it("should have the line number as null", function() { 8 | ndb.State.lineNumber.should.equal(null); 9 | }); 10 | 11 | it("should reset properly", function() { 12 | ndb.State.filename = "foo.js"; 13 | ndb.State.lineNumber = 10; 14 | 15 | ndb.reset(); 16 | 17 | ndb.State.filename.should.equal(null); 18 | ndb.State.lineNumber.should.equal(null); 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /lib/ndb/commands/help.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["h", "help"]; 6 | 7 | var text = function(commands) { 8 | var commandNames = [], 9 | property, 10 | obj; 11 | 12 | for (property in commands) { 13 | obj = commands[property]; 14 | 15 | if (obj.commandNames) { 16 | commandNames.push(obj.commandNames.join(", ")); 17 | } 18 | } 19 | 20 | return commandNames.sort().join("\n"); 21 | }; 22 | 23 | exports.run = function() { 24 | var ndb = this.ndb, 25 | puts = ndb.Helpers.puts; 26 | 27 | puts(text(ndb.Commands)); 28 | ndb.Helpers.prompt(); 29 | }; 30 | -------------------------------------------------------------------------------- /bugs/issue-076604a4da8e74f9cf0d21905affd4784e37e76b.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: Add installation documentation 3 | desc: Add installation documentation. Check email to Mario Aquino for beginnings of documentation. 4 | type: :task 5 | component: ndb 6 | release: 7 | reporter: Scott Taylor 8 | status: :unstarted 9 | disposition: 10 | creation_time: 2010-06-02 11:51:25.662099 Z 11 | references: [] 12 | 13 | id: 076604a4da8e74f9cf0d21905affd4784e37e76b 14 | log_events: 15 | - - 2010-06-02 11:51:27.173988 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | -------------------------------------------------------------------------------- /bugs/issue-a3186b7a4ba509122aa448d1878a31dedc01b734.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: stderr 3 | desc: |- 4 | We should be hooking into stderr with the --local flag (if the file doesn't 5 | exist, etc., we should throw an exception and quit ndb) 6 | type: :feature 7 | component: ndb 8 | release: 9 | reporter: Scott Taylor 10 | status: :unstarted 11 | disposition: 12 | creation_time: 2010-05-16 22:37:05.465993 Z 13 | references: [] 14 | 15 | id: a3186b7a4ba509122aa448d1878a31dedc01b734 16 | log_events: 17 | - - 2010-05-16 22:37:06.474135 Z 18 | - Scott Taylor 19 | - created 20 | - "" 21 | -------------------------------------------------------------------------------- /lib/ndb/commands/verbose.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["verbose"]; 6 | 7 | exports.parseCommand = function(text) { 8 | return this.ndb.Helpers.commonParse.call(this, text); 9 | }; 10 | 11 | function toggle(obj, value) { 12 | obj[value] = !obj[value]; 13 | } 14 | 15 | function boolToName(value) { 16 | return (value ? "on" : "off"); 17 | } 18 | 19 | exports.run = function() { 20 | var ndb = this.ndb, 21 | puts = ndb.Helpers.puts, 22 | prompt = ndb.Helpers.prompt; 23 | 24 | toggle(ndb, "verbose"); 25 | puts("verbose mode now " + boolToName(ndb.verbose)); 26 | prompt(); 27 | }; 28 | -------------------------------------------------------------------------------- /bugs/issue-4d556abcd314ded02d84d205f2f00c80c20cd947.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: Document --local 3 | desc: Add --local documentation in readme. 4 | type: :task 5 | component: ndb 6 | release: 0.1.4 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-05-17 06:16:58.557937 Z 11 | references: [] 12 | 13 | id: 4d556abcd314ded02d84d205f2f00c80c20cd947 14 | log_events: 15 | - - 2010-05-17 06:16:59.462143 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-05-20 05:38:44.479053 Z 20 | - Scott Taylor 21 | - closed with disposition fixed 22 | - "" 23 | -------------------------------------------------------------------------------- /bugs/issue-b9e9f0bc319918f4f6fc9e6a7dcb3f24da0c4885.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: Chrome integration 3 | desc: It would be super nice to have chrome integration. 4 | type: :feature 5 | component: ndb 6 | release: 7 | reporter: Scott Taylor 8 | status: :unstarted 9 | disposition: 10 | creation_time: 2010-04-14 06:28:18.709278 Z 11 | references: [] 12 | 13 | id: b9e9f0bc319918f4f6fc9e6a7dcb3f24da0c4885 14 | log_events: 15 | - - 2010-04-14 06:29:25.177678 Z 16 | - Scott Taylor 17 | - created 18 | - There's absolutely no reason (in the abstract) why it couldn't be done, although investigation will need to occur to see if Chrome will run a hook into v8 with an external port. 19 | -------------------------------------------------------------------------------- /bugs/issue-7d59e14b137e633d22d3270768de22dbb1b81063.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: Use readline's history instead of custom history 3 | desc: |- 4 | Once readline support is baked in (ditz issue {issue 81f88ce897f0af5fb45a26f67e510acb59350066}), we should remove our history support and rely on the native readline 5 | history support 6 | type: :feature 7 | component: ndb 8 | release: 9 | reporter: Scott Taylor 10 | status: :unstarted 11 | disposition: 12 | creation_time: 2010-06-11 15:08:48.952023 Z 13 | references: [] 14 | 15 | id: 7d59e14b137e633d22d3270768de22dbb1b81063 16 | log_events: 17 | - - 2010-06-11 15:08:49.887882 Z 18 | - Scott Taylor 19 | - created 20 | - "" 21 | -------------------------------------------------------------------------------- /lib/ndb/message_parser.js: -------------------------------------------------------------------------------- 1 | exports.parse = function(text) { 2 | var lines = text.split("\r\n"), 3 | done_with_headers = false, 4 | header, 5 | value, 6 | i; 7 | 8 | var obj = { 9 | headers: {}, 10 | body: "", 11 | raw_headers: "" 12 | }; 13 | 14 | lines.forEach(function(line) { 15 | if (done_with_headers === true) { 16 | obj.body += line; 17 | } else if (line === "") { 18 | done_with_headers = true; 19 | } else { 20 | i = line.indexOf(":"); 21 | header = line.slice(0, i); 22 | value = line.slice(i+1, line.length).trimLeft(); 23 | 24 | obj.raw_headers += line + "\r\n"; 25 | obj.headers[header] = value; 26 | } 27 | }); 28 | 29 | return obj; 30 | }; 31 | -------------------------------------------------------------------------------- /bugs/issue-20b8233f1c98b73504a3390a93d648be9e6cab91.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: add history tracking 3 | desc: track history per session with "history" 4 | type: :feature 5 | component: ndb 6 | release: 0.1.5 7 | reporter: . 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-05-21 05:06:09.910133 Z 11 | references: [] 12 | 13 | id: 20b8233f1c98b73504a3390a93d648be9e6cab91 14 | log_events: 15 | - - 2010-05-21 05:06:11.862143 Z 16 | - Scott Taylor 17 | - created 18 | - gs 19 | - - 2010-05-21 05:51:54.522400 Z 20 | - Scott Taylor 21 | - closed with disposition fixed 22 | - "" 23 | - - 2010-05-21 05:54:37.577515 Z 24 | - Scott Taylor 25 | - assigned to release 0.1.5 from unassigned 26 | - "" 27 | -------------------------------------------------------------------------------- /bugs/issue-ab0738bb06ef3b545497991dcaa257a57aa5bce6.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: repl 3 | desc: It would be really nice to have a repl 4 | type: :feature 5 | component: ndb 6 | release: 0.1.5 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-04-14 06:20:51.215478 Z 11 | references: [] 12 | 13 | id: ab0738bb06ef3b545497991dcaa257a57aa5bce6 14 | log_events: 15 | - - 2010-04-14 06:20:52.743426 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-05-30 05:17:23.031295 Z 20 | - Scott Taylor 21 | - closed with disposition fixed 22 | - "" 23 | - - 2010-05-30 06:07:34.582341 Z 24 | - Scott Taylor 25 | - assigned to release 0.1.5 from unassigned 26 | - "" 27 | -------------------------------------------------------------------------------- /lib/ndb/commands/next.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["n", "next"]; 6 | 7 | exports.parseCommand = function(text) { 8 | var match = /^(n|next)(.*)$/.exec(text), 9 | args; 10 | 11 | if (match) { 12 | args = match[2].trim(); 13 | 14 | if (args === "") { 15 | return [this]; 16 | } else { 17 | return [this, match[2].trim()]; 18 | } 19 | } 20 | }; 21 | 22 | exports.run = function(stepcount) { 23 | var ndb = this.ndb, 24 | rw = ndb.Commands.RawWrite, 25 | obj; 26 | 27 | if (!stepcount) { 28 | stepcount = 1; 29 | } 30 | 31 | obj = { 32 | type: "request", 33 | command: "continue", 34 | arguments: { 35 | stepaction: "next", 36 | stepcount: stepcount 37 | } 38 | }; 39 | 40 | rw.run(obj); 41 | }; 42 | -------------------------------------------------------------------------------- /bugs/issue-5c67d835c9b48fae705b016479f111f849d52432.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: add npm package 3 | desc: Add an npm package for increased distribution 4 | type: :task 5 | component: ndb 6 | release: 0.2.2 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-05-20 06:41:53.969460 Z 11 | references: [] 12 | 13 | id: 5c67d835c9b48fae705b016479f111f849d52432 14 | log_events: 15 | - - 2010-05-20 06:41:54.856924 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-11-23 23:16:41.941110 Z 20 | - Scott Taylor 21 | - closed with disposition fixed 22 | - "" 23 | - - 2010-11-23 23:25:12.788618 Z 24 | - Scott Taylor 25 | - assigned to release 0.2.2 from unassigned 26 | - "" 27 | -------------------------------------------------------------------------------- /bugs/issue-81f88ce897f0af5fb45a26f67e510acb59350066.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: add readline support 3 | desc: |- 4 | From ry: 5 | 6 | Hi Scott, 7 | 8 | I just wanted to alert you that there is a primitive readline library 9 | in Node now. 10 | 11 | http://github.com/ry/node/blob/6056d2ea2c5e158f9a0daaad4bd242c405e49ab3/lib/readline.js 12 | 13 | I hope you'll be able to use it in ndb. Let me know what issues you hit 14 | type: :feature 15 | component: ndb 16 | release: 17 | reporter: Scott Taylor 18 | status: :unstarted 19 | disposition: 20 | creation_time: 2010-06-08 06:11:24.936417 Z 21 | references: [] 22 | 23 | id: 81f88ce897f0af5fb45a26f67e510acb59350066 24 | log_events: 25 | - - 2010-06-08 06:11:25.944271 Z 26 | - Scott Taylor 27 | - created 28 | - "" 29 | -------------------------------------------------------------------------------- /lib/ndb/commands/backtrace.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["bt", "backtrace"]; 6 | 7 | exports.parseCommand = function(text) { 8 | return this.ndb.Helpers.commonParse.call(this, text); 9 | }; 10 | 11 | exports.run = function() { 12 | var ndb = this.ndb, 13 | rw = ndb.Commands.RawWrite; 14 | 15 | rw.run({ 16 | type: "request", 17 | command: "backtrace" 18 | }); 19 | }; 20 | 21 | exports.output = function(json) { 22 | var ndb = this.ndb, 23 | puts = ndb.Helpers.puts, 24 | buffer = "\n"; 25 | 26 | json.body.frames.forEach(function(frame) { 27 | buffer += " " + frame.text + "\n"; 28 | }); 29 | 30 | puts(buffer); 31 | }; 32 | 33 | exports.parseResponse = function(response) { 34 | if (response.command === "backtrace") { 35 | return this; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /bugs/issue-52176871fbdf6851c5f447154de8001d28897164.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: set host 3 | desc: host should default to localhost, but be settable with --host 4 | type: :feature 5 | component: ndb 6 | release: 0.1.4 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-05-16 19:08:09.548552 Z 11 | references: [] 12 | 13 | id: 52176871fbdf6851c5f447154de8001d28897164 14 | log_events: 15 | - - 2010-05-16 19:08:10.524514 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-05-16 19:16:37.592342 Z 20 | - Scott Taylor 21 | - closed with disposition fixed 22 | - "" 23 | - - 2010-05-16 22:50:19.957607 Z 24 | - Scott Taylor 25 | - assigned to release 0.1.4 from unassigned 26 | - "" 27 | -------------------------------------------------------------------------------- /lib/ndb/commands/raw_write.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["rw"]; 6 | 7 | exports.parseCommand = function(text) { 8 | var match = new RegExp("^rw (.+)").exec(text); 9 | 10 | if (match === null) { 11 | return false; 12 | } else { 13 | return [this, match[1]]; 14 | } 15 | }; 16 | 17 | exports.run = function(json) { 18 | if (typeof(json) != "string") { 19 | json = JSON.stringify(json); 20 | } 21 | 22 | var connection = this.ndb.Commands.connection, 23 | log = this.ndb.Helpers.log, 24 | verbose = this.ndb.verbose; 25 | 26 | var data = json + "\n", 27 | header = "Content-Length: " + data.length + "\r\n\r\n", 28 | message = header + data; 29 | 30 | if (verbose) { 31 | log(message, "verbose: >>> "); 32 | } 33 | 34 | connection.write(message); 35 | }; 36 | -------------------------------------------------------------------------------- /bugs/issue-42c787954471dffb9a81a938e66a38750a820042.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: get ndb working with latest released version of node.js 3 | desc: according to their tags, that appears to be 0.1.90 (at the current time) 4 | type: :task 5 | component: ndb 6 | release: 0.1.2 7 | reporter: scott@railsnewbie.com 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-04-14 06:47:32.570551 Z 11 | references: [] 12 | 13 | id: 42c787954471dffb9a81a938e66a38750a820042 14 | log_events: 15 | - - 2010-04-14 06:47:37.370271 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-04-14 06:48:20.944097 Z 20 | - Scott Taylor 21 | - edited reporter 22 | - "" 23 | - - 2010-04-16 06:59:04.690655 Z 24 | - Scott Taylor 25 | - closed with disposition fixed 26 | - various api changes (mostly to stdin, & net) 27 | -------------------------------------------------------------------------------- /bugs/issue-1d6c2ce3dabebc58914f1e59c0c035d77cf9893e.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: more version info 3 | desc: |- 4 | add more version info: 5 | - remote v8 version (taken from the first connection) 6 | - node remote version 7 | type: :feature 8 | component: ndb 9 | release: 10 | reporter: Scott Taylor 11 | status: :unstarted 12 | disposition: 13 | creation_time: 2010-04-14 06:21:47.629233 Z 14 | references: [] 15 | 16 | id: 1d6c2ce3dabebc58914f1e59c0c035d77cf9893e 17 | log_events: 18 | - - 2010-04-14 06:21:49.948082 Z 19 | - Scott Taylor 20 | - created 21 | - "" 22 | - - 2010-04-14 06:41:56.558347 Z 23 | - Scott Taylor 24 | - assigned to release 0.1.2 from unassigned 25 | - "" 26 | - - 2010-04-27 07:52:13.270085 Z 27 | - Scott Taylor 28 | - unassigned from release 0.1.2 29 | - "" 30 | -------------------------------------------------------------------------------- /bugs/issue-1828642d0eeea0fec3b2858b9042e7f481c68db4.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: command line options 3 | desc: |- 4 | Need various command line options: 5 | - verbose 6 | - server 7 | - port 8 | - version 9 | - help 10 | type: :feature 11 | component: ndb 12 | release: 0.1.3 13 | reporter: Scott Taylor 14 | status: :closed 15 | disposition: :fixed 16 | creation_time: 2010-04-14 06:24:38.635604 Z 17 | references: [] 18 | 19 | id: 1828642d0eeea0fec3b2858b9042e7f481c68db4 20 | log_events: 21 | - - 2010-04-14 06:24:41.586609 Z 22 | - Scott Taylor 23 | - created 24 | - "" 25 | - - 2010-05-14 06:48:24.864084 Z 26 | - Scott Taylor 27 | - closed with disposition fixed 28 | - "" 29 | - - 2010-05-14 06:55:30.927914 Z 30 | - Scott Taylor 31 | - assigned to release 0.1.3 from unassigned 32 | - "" 33 | -------------------------------------------------------------------------------- /bugs/issue-a137797b955bbb73a14bb820581396d077a15c36.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: wait for remote host to be up 3 | desc: When booting, we should have the main loop wait for the remote end to come up - not fail immediately if it isn't. 4 | type: :feature 5 | component: ndb 6 | release: 0.1.4 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-05-16 21:13:19.798821 Z 11 | references: [] 12 | 13 | id: a137797b955bbb73a14bb820581396d077a15c36 14 | log_events: 15 | - - 2010-05-16 21:13:20.766635 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-05-16 22:23:35.914310 Z 20 | - Scott Taylor 21 | - closed with disposition fixed 22 | - "" 23 | - - 2010-05-16 22:50:04.337830 Z 24 | - Scott Taylor 25 | - assigned to release 0.1.4 from unassigned 26 | - "" 27 | -------------------------------------------------------------------------------- /lib/ndb/commands.js: -------------------------------------------------------------------------------- 1 | exports.List = require("./commands/list"); 2 | exports.RawWrite = require("./commands/raw_write"); 3 | exports.Help = require("./commands/help"); 4 | exports.SetBreakpoint = require("./commands/setbreakpoint"); 5 | exports.Break = require("./commands/break"); 6 | exports.Continue = require("./commands/continue"); 7 | exports.Next = require("./commands/next"); 8 | exports.Evaluate = require("./commands/evaluate"); 9 | exports.Quit = require("./commands/quit"); 10 | exports.Version = require("./commands/version"); 11 | exports.Verbose = require("./commands/verbose"); 12 | exports.Backtrace = require("./commands/backtrace"); 13 | exports.StepIn = require("./commands/step_in"); 14 | exports.StepOut = require("./commands/step_out"); 15 | exports.History = require("./commands/history"); 16 | exports.REPL = require("./commands/repl"); -------------------------------------------------------------------------------- /lib/vendor/js-opts/example1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple example with one optional parameter, including the help option. 3 | * 4 | * Examples: 5 | * $ node example1.js 6 | * 7 | * Example 1 8 | * $ node example1.js -v 9 | * > v1.0 10 | * 11 | * $ node example1.js --version 12 | * > v1.0 13 | * 14 | * $ node example1.js -version 15 | * > Unknown option: -version 16 | * 17 | * $ node example1.js --help 18 | * > Show version and exit 19 | * -v, --version 20 | * Show this help message 21 | * --help 22 | */ 23 | 24 | var opts = require('./opts') 25 | , puts = require('util').puts; 26 | 27 | var options = [ 28 | { short : 'v' 29 | , long : 'version' 30 | , description : 'Show version and exit' 31 | , callback : function () { puts('v1.0'); process.exit(1); } 32 | } 33 | ]; 34 | 35 | opts.parse(options, true); 36 | puts('Example 1'); 37 | process.exit(0); 38 | 39 | 40 | -------------------------------------------------------------------------------- /lib/ndb/commands/history.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.commandNames = ["history"]; 4 | 5 | exports.parseCommand = function(text) { 6 | return ndb.Helpers.commonParse.call(this, text); 7 | }; 8 | 9 | var repeatString = function(str, times) { 10 | var newStr = "", 11 | i; 12 | 13 | for(i = 0; i < times; i++) { 14 | newStr += str; 15 | } 16 | 17 | return newStr; 18 | }; 19 | 20 | var rjust = function(string, width) { 21 | string = string.toString(); 22 | 23 | if (string.length < width) { 24 | return repeatString(" ", width - string.length) + string; 25 | } else { 26 | return string; 27 | } 28 | }; 29 | 30 | exports.run = function() { 31 | var ndb = require("ndb"), 32 | puts = ndb.Helpers.puts, 33 | prompt = ndb.Helpers.prompt, 34 | index = 1; 35 | 36 | ndb.State.history.forEach(function(command) { 37 | puts(rjust(index, 5) + " " + command); 38 | index++; 39 | }); 40 | 41 | prompt(); 42 | }; -------------------------------------------------------------------------------- /bugs/issue-25cc1df8c4a3d316704d42cfb45cf4f5db5854d2.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: update version number 3 | desc: Update version number for 0.1.2 release (0.1.1 is lies) 4 | type: :task 5 | component: ndb 6 | release: 0.1.3 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-04-14 06:43:31.736670 Z 11 | references: [] 12 | 13 | id: 25cc1df8c4a3d316704d42cfb45cf4f5db5854d2 14 | log_events: 15 | - - 2010-04-14 06:43:33.384428 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-04-27 07:52:29.307324 Z 20 | - Scott Taylor 21 | - unassigned from release 0.1.2 22 | - "" 23 | - - 2010-05-14 06:50:55.178072 Z 24 | - Scott Taylor 25 | - closed with disposition fixed 26 | - "" 27 | - - 2010-05-14 06:55:21.809308 Z 28 | - Scott Taylor 29 | - assigned to release 0.1.3 from unassigned 30 | - "" 31 | -------------------------------------------------------------------------------- /bugs/issue-ccd5785e2f5ab794eb9327ddc3a75f62875b13a7.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: tmate 3 | desc: Add 'tmate' command to open textmate on current file & lineno 4 | type: :feature 5 | component: ndb 6 | release: 7 | reporter: Scott Taylor 8 | status: :unstarted 9 | disposition: 10 | creation_time: 2010-04-14 06:22:36.187228 Z 11 | references: [] 12 | 13 | id: ccd5785e2f5ab794eb9327ddc3a75f62875b13a7 14 | log_events: 15 | - - 2010-04-14 06:23:20.622961 Z 16 | - Scott Taylor 17 | - created 18 | - |- 19 | Will need to track the current file & lineno of the debugger. Should this be taken from the last request instead 20 | of querying when the command is given? 21 | - - 2010-04-14 06:42:08.245262 Z 22 | - Scott Taylor 23 | - assigned to release 0.1.2 from unassigned 24 | - "" 25 | - - 2010-04-27 07:52:17.596157 Z 26 | - Scott Taylor 27 | - unassigned from release 0.1.2 28 | - "" 29 | -------------------------------------------------------------------------------- /bugs/issue-e2795256659b306f7e10a8027a07d4fc68561332.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: list command consistency 3 | desc: |- 4 | the list command should consistenly follow other gdb like debuggers: 5 | 6 | "l" should print the current line. Invoking it a second time should show the next X lines 7 | "l=" should always print the current line 8 | "l+" should show the next set of lines (as if invoking l for a second time) 9 | "l+X" should show the next X lines of input 10 | "l-X" should do the same, but in reverse 11 | "l 1-100" should show lines 1-100 12 | "l 10" should print as if on line 10 13 | type: :feature 14 | component: ndb 15 | release: 16 | reporter: Scott Taylor 17 | status: :unstarted 18 | disposition: 19 | creation_time: 2010-04-14 06:19:49.907138 Z 20 | references: [] 21 | 22 | id: e2795256659b306f7e10a8027a07d4fc68561332 23 | log_events: 24 | - - 2010-04-14 06:19:52.852292 Z 25 | - Scott Taylor 26 | - created 27 | - "" 28 | -------------------------------------------------------------------------------- /spec/fixtures/backtrace_one_output.txt: -------------------------------------------------------------------------------- 1 | 2 | #00 #.[anonymous](exports=#, require=function require(path) { 3 | return loadModule(path, self); 4 | }, module=#, __filename=/Users/scotttaylor/src/git/ndb/spec/node.js, __dirname=/Users/scotttaylor/src/git/ndb/spec) /Users/scotttaylor/src/git/ndb/spec/node.js line 4 column 1 (position 149) 5 | #01 #._compile(content=require.paths.unshift("./lib/"); 6 | 7 | require("./jspec_dot_reporter/jspec_dot_report... (length: 1374), filename=/Users/scotttaylor/src/git/ndb/spec/node.js) module line 384 column 23 (position 9266) 8 | #02 #._loadScriptSync(filename=/Users/scotttaylor/src/git/ndb/spec/node.js) module line 393 column 16 (position 9517) 9 | #03 #.loadSync(filename=/Users/scotttaylor/src/git/ndb/spec/node.js) module line 296 column 10 (position 7159) 10 | #04 #.runMain() module line 459 column 22 (position 11106) 11 | #05 [anonymous](process=#) node.js line 168 column 8 (position 4677) 12 | -------------------------------------------------------------------------------- /bugs/issue-9f024e237aa0de2c3ec9844e34f57d28603c3e60.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: stepout 3 | desc: chrome has a stepout feature. Does it truely step out of the function call, returning to the outer scope? 4 | type: :task 5 | component: ndb 6 | release: 0.2.0 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-04-14 06:27:37.144930 Z 11 | references: [] 12 | 13 | id: 9f024e237aa0de2c3ec9844e34f57d28603c3e60 14 | log_events: 15 | - - 2010-04-14 06:27:38.631745 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-05-30 07:15:12.310424 Z 20 | - Scott Taylor 21 | - assigned to release 0.1.6 from unassigned 22 | - "" 23 | - - 2010-05-30 07:15:26.376720 Z 24 | - Scott Taylor 25 | - closed with disposition fixed 26 | - "" 27 | - - 2010-08-20 20:43:20.666674 Z 28 | - Scott Taylor 29 | - assigned to release 0.2.0 from 0.1.6 30 | - "" 31 | -------------------------------------------------------------------------------- /spec/unit/commands/help.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("help", function() { 4 | before_each(function() { 5 | connection = { 6 | write: function() {} 7 | }; 8 | 9 | commands = ndb.Commands; 10 | commands.connection = connection; 11 | 12 | help = commands.Help; 13 | }); 14 | 15 | it("should output all of the command names", function() { 16 | var text = ""; 17 | 18 | spy.stub(ndb.Helpers, "puts", function(t) { 19 | text += t; 20 | }); 21 | 22 | help.run(); 23 | text.should.match(/b\, break/); 24 | text.should.match(/l\, list/); 25 | }); 26 | 27 | it("should sort the commands", function() { 28 | var text = ""; 29 | 30 | spy.stub(ndb.Helpers, "puts", function(t) { 31 | text += t; 32 | }); 33 | 34 | help.run(); 35 | text.replace(/\n/g, "").should.match(/break.+list/); 36 | }); 37 | }); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /bugs/issue-6e2e86e3118f9eff7e4fe9e6f774c0a01539796e.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: Get tests working on v0.1.97. 3 | desc: |- 4 | Reporting no tests on v0.1.97: 5 | 6 | node spec/node.js 7 | 8 | Passes: 0 9 | Failures: 0 10 | Duration: 0 ms 11 | type: :bugfix 12 | component: ndb 13 | release: 0.2.0 14 | reporter: Scott Taylor 15 | status: :closed 16 | disposition: :fixed 17 | creation_time: 2010-06-08 06:10:31.531466 Z 18 | references: [] 19 | 20 | id: 6e2e86e3118f9eff7e4fe9e6f774c0a01539796e 21 | log_events: 22 | - - 2010-06-08 06:10:33.667398 Z 23 | - Scott Taylor 24 | - created 25 | - "" 26 | - - 2010-06-08 07:25:33.122283 Z 27 | - Scott Taylor 28 | - closed with disposition fixed 29 | - "" 30 | - - 2010-06-08 07:25:38.513619 Z 31 | - Scott Taylor 32 | - assigned to release 0.1.6 from unassigned 33 | - "" 34 | - - 2010-08-20 20:43:34.810509 Z 35 | - Scott Taylor 36 | - assigned to release 0.2.0 from 0.1.6 37 | - "" 38 | -------------------------------------------------------------------------------- /spec/unit/ndb.js: -------------------------------------------------------------------------------- 1 | describe("Node Debugger", function() { 2 | describe("version", function() { 3 | it("should be at 0.2.3", function() { 4 | ndb.version.should.equal("0.2.3"); 5 | }); 6 | }); 7 | 8 | it("should have verbose off by default", function() { 9 | ndb.reset(); 10 | ndb.verbose.should.equal(false); 11 | }); 12 | 13 | it("should have the host set to 127.0.0.1 by default", function() { 14 | ndb.host.should.equal("127.0.0.1"); 15 | }); 16 | 17 | it("should have the default port as 5858", function() { 18 | ndb.port.should.equal(5858); 19 | }); 20 | 21 | it("should keep the same values after multiple requires", function() { 22 | ndb = require("ndb"); 23 | ndb.replOn = true; 24 | 25 | ndb = require("ndb"); 26 | ndb.replOn.should.equal(true); 27 | }); 28 | 29 | it("should be able to call the setup method multiple times", function() { 30 | ndb.setup(); 31 | ndb.setup(); 32 | }); 33 | 34 | it("should have replOn = false by default", function() { 35 | ndb.reset(); 36 | ndb.State.replOn.should.equal(false); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /spec/unit/spec.helper.js: -------------------------------------------------------------------------------- 1 | SpecHelpers = { 2 | makeHeader: function(content) { 3 | return "Content-Length: " + content.length + "\r\n\r\n"; 4 | }, 5 | 6 | makeResponse: function(content) { 7 | return SpecHelpers.makeHeader(content) + content; 8 | } 9 | }; 10 | 11 | JSpec.include({ 12 | beforeSpec: function() { 13 | ndb = require("ndb"); 14 | ndb.reset(); 15 | ndb.Commands.List.context = 2; 16 | 17 | connection = { 18 | setEncoding: function() {}, 19 | addListener: function() {} 20 | }; 21 | 22 | tcp = { 23 | createConnection: function() { 24 | return connection; 25 | } 26 | }; 27 | 28 | ndb.Helpers.tcp = tcp; 29 | 30 | stdinStream = { 31 | addListener: function() {} 32 | }; 33 | 34 | mock_process = { 35 | openStdin: function() { 36 | return { 37 | setEncoding: function() {}, 38 | addListener: function() {} 39 | }; 40 | } 41 | }; 42 | 43 | ndb.Helpers.process = mock_process; 44 | ndb.Helpers.puts = function() {}; 45 | ndb.Helpers.print = function() {}; 46 | } 47 | }); 48 | 49 | 50 | -------------------------------------------------------------------------------- /lib/ndb.js: -------------------------------------------------------------------------------- 1 | var ndb = exports; 2 | 3 | ndb.version = "0.2.3"; 4 | 5 | ndb.setup = function() { 6 | if (!ndb.loaded) { 7 | this.reset(); 8 | } 9 | }; 10 | 11 | ndb.reset = function() { 12 | this.loaded = true; 13 | this.host = "127.0.0.1"; 14 | this.port = 5858; 15 | this.verbose = false; 16 | 17 | this.State.reset(); 18 | this.EventListener.reset(); 19 | this.CommandCenter.reset(); 20 | this.Commands.List.reset(); 21 | }; 22 | 23 | ndb.State = { 24 | reset: function() { 25 | this.filename = null; 26 | this.lineNumber = null; 27 | this.replOn = false; 28 | this.history = []; 29 | } 30 | }; 31 | 32 | ndb.Helpers = require("./ndb/helpers"); 33 | ndb.Commands = require("./ndb/commands"); 34 | ndb.CommandCenter = require("./ndb/command_center"); 35 | ndb.EventListener = require("./ndb/event_listener"); 36 | ndb.MessageParser = require("./ndb/message_parser"); 37 | ndb.OptionParser = require("./ndb/option_parser"); 38 | 39 | var main = require("./ndb/main"); 40 | 41 | ndb.setup(); 42 | 43 | for (key in main) { 44 | if (main.hasOwnProperty(key)) { 45 | ndb[key] = main[key]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /spec/unit/commands/continue.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("continue", function() { 4 | before_each(function() { 5 | connection = { 6 | write: function() {} 7 | }; 8 | 9 | commands = ndb.Commands; 10 | commands.connection = connection; 11 | 12 | c = commands.Continue; 13 | }); 14 | 15 | // {"seq":117,"type":"request","command":"continue"} 16 | // {"seq":118,"type":"request","command":"continue","arguments":{"stepaction":"out"}} 17 | // {"seq":119,"type":"request","command":"continue","arguments":{"stepaction":"next","stepcount":5}} 18 | it("should raw_write the continue command", function() { 19 | var obj = undefined; 20 | 21 | ndb.Commands.RawWrite = { 22 | run: function(o) { 23 | obj = o; 24 | } 25 | }; 26 | 27 | var expected_object = { 28 | type: "request", 29 | command: "continue" 30 | }; 31 | 32 | c.run(); 33 | 34 | JSON.stringify(obj).should.equal(JSON.stringify(expected_object)); 35 | }); 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /bugs/issue-15d0b5c14d26eed3ae77579da27a97a9e737e178.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: backtrace 3 | desc: bt/backtrace doesn't output anything at all. It should be smart and show file & line no's 4 | type: :feature 5 | component: ndb 6 | release: 0.1.4 7 | reporter: Scott Taylor 8 | status: :closed 9 | disposition: :fixed 10 | creation_time: 2010-04-14 06:08:41.522552 Z 11 | references: [] 12 | 13 | id: 15d0b5c14d26eed3ae77579da27a97a9e737e178 14 | log_events: 15 | - - 2010-04-14 06:08:46.314303 Z 16 | - Scott Taylor 17 | - created 18 | - "" 19 | - - 2010-04-14 06:41:10.424713 Z 20 | - Scott Taylor 21 | - assigned to release 0.1.2 from unassigned 22 | - "" 23 | - - 2010-04-27 07:52:08.820597 Z 24 | - Scott Taylor 25 | - unassigned from release 0.1.2 26 | - "" 27 | - - 2010-05-16 08:20:46.534851 Z 28 | - Scott Taylor 29 | - closed with disposition fixed 30 | - See e189c119b61c13f64214ec4d8c49917bb5194e2b 31 | - - 2010-05-16 22:50:36.890060 Z 32 | - Scott Taylor 33 | - assigned to release 0.1.4 from unassigned 34 | - "" 35 | -------------------------------------------------------------------------------- /lib/ndb/helpers.js: -------------------------------------------------------------------------------- 1 | var sys = require("util"), 2 | tcp = require("net"), 3 | child_process = require("child_process"); 4 | ndb = require("ndb"); 5 | 6 | exports.puts = sys.puts; 7 | exports.print = sys.print; 8 | exports.tcp = tcp; 9 | exports.process = process; 10 | exports.exit = process.exit; 11 | exports.setTimeout = setTimeout; 12 | exports.childProcess = child_process; 13 | 14 | exports.log = function(str, repetition) { 15 | var lines = str.split("\n"), 16 | puts = ndb.Helpers.puts, 17 | line, 18 | i; 19 | 20 | for (i = 0; i < lines.length; i++) { 21 | line = lines[i]; 22 | puts(repetition + line); 23 | } 24 | }; 25 | 26 | exports.prompt = function() { 27 | var print = ndb.Helpers.print; 28 | print("ndb> "); 29 | }; 30 | 31 | exports.replPrompt = function() { 32 | var print = ndb.Helpers.print; 33 | print("repl> "); 34 | }; 35 | 36 | exports.include = function(array, element) { 37 | return array.indexOf(element) !== -1; 38 | }; 39 | 40 | exports.commonParse = function(text) { 41 | var include = ndb.Helpers.include; 42 | 43 | if (include(this.commandNames, text)) { 44 | return [this]; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /lib/ndb/commands/break.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | function constructSource(obj, puts) { 6 | var str = ""; 7 | 8 | var body = obj.body; 9 | 10 | str += "Breakpoint at "; 11 | 12 | if (body.scriptData) { 13 | str += body.scriptData + ":"; 14 | } 15 | 16 | str += (body.sourceLine + 1) + ":" + body.sourceColumn; 17 | str += " (in function " + body.functionName; 18 | 19 | if (body.breakpoints) { 20 | str += " - breakpoints: [" + body.breakpoints + "]"; 21 | } 22 | 23 | str += ")"; 24 | 25 | if (body.sourceLineText) { 26 | str += "\n"; 27 | str += body.sourceLineText; 28 | } 29 | 30 | return str; 31 | } 32 | 33 | exports.output = function(json) { 34 | var ndb = this.ndb, 35 | puts = ndb.Helpers.puts, 36 | script; 37 | 38 | if (json.body) { 39 | ndb.State.lineNumber = json.body.sourceLine + 1; 40 | 41 | if (json.body.script) { 42 | script = json.body.script; 43 | 44 | if (script.name) { 45 | ndb.State.filename = script.name; 46 | } 47 | } 48 | } 49 | 50 | puts(constructSource(json)); 51 | }; 52 | 53 | exports.parseResponse = function(obj) { 54 | if (obj.event === "break") { 55 | return this; 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /bugs/issue-6eb9906701c3a3ec3ebfedddffb1df0783670d7a.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/issue 2 | title: --local option to run script directly 3 | desc: |- 4 | syntax: 5 | 'ndb foo.js' (or 'ndb --local foo.js') 6 | Run this as a little 'shell script', invoking the script with node --debug-brk foo.js, and then invoking the debugger 7 | type: :feature 8 | component: ndb 9 | release: 0.1.4 10 | reporter: Scott Taylor 11 | status: :closed 12 | disposition: :fixed 13 | creation_time: 2010-04-14 06:26:13.156897 Z 14 | references: [] 15 | 16 | id: 6eb9906701c3a3ec3ebfedddffb1df0783670d7a 17 | log_events: 18 | - - 2010-04-14 06:26:16.748364 Z 19 | - Scott Taylor 20 | - created 21 | - "" 22 | - - 2010-04-14 06:42:43.971351 Z 23 | - Scott Taylor 24 | - assigned to release 0.1.2 from unassigned 25 | - "" 26 | - - 2010-04-27 07:52:24.163718 Z 27 | - Scott Taylor 28 | - unassigned from release 0.1.2 29 | - "" 30 | - - 2010-05-16 22:43:55.923167 Z 31 | - Scott Taylor 32 | - closed with disposition fixed 33 | - "" 34 | - - 2010-05-16 22:49:50.270165 Z 35 | - Scott Taylor 36 | - assigned to release 0.1.4 from unassigned 37 | - "" 38 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # ndb - the node debugger 3 | 4 | A command line node.js/v8 debugger. It is still in beta, but perfectly usable. 5 | 6 | # NOT MAINTAINED 7 | 8 | This project is no longer being maintained. Use the built in debugger in versions of node >= 0.4.x. 9 | 10 | If there are features that you are relying on in ndb that aren't present in the built in debugger, I'd be happy to port them to the mainline debugger; just file a ticket in this project. 11 | 12 | ## License 13 | 14 | ndb - the node.js command line debugger 15 | Copyright (C) 2010 Scott Taylor 16 | 17 | This program is free software: you can redistribute it and/or modify 18 | it under the terms of the GNU General Public License as published by 19 | the Free Software Foundation, either version 3 of the License, or 20 | (at your option) any later version. 21 | 22 | This program is distributed in the hope that it will be useful, 23 | but WITHOUT ANY WARRANTY; without even the implied warranty of 24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 | GNU General Public License for more details. 26 | 27 | You should have received a copy of the GNU General Public License 28 | along with this program. If not, see . 29 | -------------------------------------------------------------------------------- /spec/unit/commands/quit.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("quitting", function() { 4 | before_each(function() { 5 | original_exit = process.quit; 6 | exit_called = false; 7 | process.exit = function() { 8 | exit_called = true; 9 | }; 10 | 11 | original_puts = ndb.Helpers.puts; 12 | puts_called_with = undefined; 13 | ndb.Helpers.puts = function(text) { 14 | puts_called_with = text; 15 | }; 16 | 17 | quitter = ndb.Commands.Quit; 18 | }); 19 | 20 | after_each(function() { 21 | process.exit = original_exit; 22 | ndb.Helpers.puts = original_puts; 23 | }); 24 | 25 | it("should quit", function() { 26 | quitter.run(); 27 | exit_called.should.be(true); 28 | }); 29 | 30 | it("should output a message", function() { 31 | quitter.run(); 32 | puts_called_with.should.equal("bye!"); 33 | }); 34 | 35 | it("should parse 'quit' as quit", function() { 36 | quitter.parseCommand("quit")[0].should.equal(quitter); 37 | }); 38 | 39 | it("should parse 'exit' as quit", function() { 40 | quitter.parseCommand("exit")[0].should.equal(quitter); 41 | }); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /lib/ndb/commands/repl.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.commandNames = ["repl"]; 4 | 5 | exports.parseCommand = function(text) { 6 | if (/(repl)/.exec(text)) { 7 | return [this]; 8 | } 9 | }; 10 | 11 | exports.execute = function(str) { 12 | var eval = ndb.Commands.Evaluate; 13 | 14 | if (str.trim() === ".break") { 15 | return false; 16 | } else { 17 | eval.run(str, true); 18 | } 19 | 20 | return true; 21 | }; 22 | 23 | var printHelp = function() { 24 | var puts = ndb.Helpers.puts, 25 | str = ""; 26 | 27 | str += "Welcome to the ndb repl.\n"; 28 | str += "Type .break to exit."; 29 | 30 | puts(str); 31 | }; 32 | 33 | exports.run = function(callback) { 34 | var replPrompt = ndb.Helpers.replPrompt, 35 | process = ndb.Helpers.process, 36 | listener, 37 | removeListener, 38 | stdin; 39 | 40 | listener = function(str) { 41 | if (!exports.execute(str)) { 42 | removeListener(); 43 | } 44 | }; 45 | 46 | removeListener = function() { 47 | stdin.removeListener("data", listener); 48 | ndb.State.replOn = false; 49 | ndb.Helpers.prompt(); 50 | }; 51 | 52 | ndb.State.replOn = true; 53 | 54 | printHelp(); 55 | replPrompt(); 56 | 57 | stdin = process.openStdin(); 58 | stdin.setEncoding("ascii"); 59 | stdin.addListener("data", listener); 60 | }; -------------------------------------------------------------------------------- /lib/ndb/main.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.start = function() { 4 | var tcp = ndb.Helpers.tcp, 5 | eventListener = ndb.eventListener || Object.create(ndb.EventListener); 6 | 7 | connection = tcp.createConnection(ndb.port, ndb.host); 8 | connection.setEncoding("ascii"); 9 | 10 | connection.addListener("error", ndb.restart); 11 | 12 | connection.addListener("data", function() { 13 | eventListener.receive.apply(eventListener, arguments); 14 | }); 15 | 16 | connection.addListener("end", ndb.Helpers.exit); 17 | 18 | connection.addListener("connect", function() { 19 | ndb.startDebugger(connection); 20 | }); 21 | 22 | eventListener.verbose = this.verbose; 23 | 24 | return connection; 25 | }; 26 | 27 | exports.restart = function() { 28 | var puts = ndb.Helpers.puts, 29 | setTimeout = ndb.Helpers.setTimeout; 30 | 31 | puts("Could not connect to host " + ndb.host + " on port " + ndb.port + ". Will try again in 2 seconds."); 32 | setTimeout(ndb.start, 2000); 33 | }; 34 | 35 | exports.startDebugger = function(connection) { 36 | var puts = ndb.Helpers.puts, 37 | prompt = ndb.Helpers.prompt, 38 | commandCenter = this.commandCenter || Object.create(ndb.CommandCenter); 39 | 40 | commandCenter.connection = connection; 41 | 42 | // start the main repl loop 43 | puts("welcome to the node debugger!"); 44 | prompt(); 45 | commandCenter.loop(); 46 | }; 47 | -------------------------------------------------------------------------------- /lib/ndb/commands/evaluate.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["e", "eval", "p", "print"]; 6 | 7 | exports.parseCommand = function(text) { 8 | var regex = new RegExp("^(" + this.commandNames.join("|") + ") (.+)$"), 9 | match = regex.exec(text); 10 | 11 | if (match) { 12 | return [this, match[2]]; 13 | } 14 | }; 15 | 16 | var construct_expression = function(expr) { 17 | var str = ""; 18 | str += "if (typeof(require) === 'undefined') { \n"; 19 | str += " " + expr + " \n"; 20 | str += "} else { \n"; 21 | str += " require('util').inspect(" + expr + "); \n"; 22 | str += "} \n"; 23 | return str; 24 | }; 25 | 26 | exports.__testing = { 27 | construct_expression: construct_expression 28 | }; 29 | 30 | exports.run = function(expr, raw) { 31 | var ndb = this.ndb, 32 | raw_write = ndb.Commands.RawWrite; 33 | 34 | if (raw === false || raw === undefined) { 35 | expr = construct_expression(expr); 36 | } 37 | 38 | raw_write.run({ 39 | type: "request", 40 | command: "evaluate", 41 | arguments: { 42 | expression: expr 43 | } 44 | }); 45 | }; 46 | 47 | exports.output = function(json) { 48 | var puts = this.ndb.Helpers.puts; 49 | 50 | if (json.success) { 51 | puts("=> " + json.body.text); 52 | } else { 53 | puts(json.message); 54 | } 55 | }; 56 | 57 | exports.parseResponse = function(obj) { 58 | if (obj.command === "evaluate") { 59 | return this; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /spec/unit/commands/version.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("version", function() { 4 | before_each(function() { 5 | version = ndb.Commands.Version; 6 | 7 | puts_called_with = []; 8 | spy.stub(ndb.Helpers, "puts", function(text) { 9 | puts_called_with.push(text); 10 | }); 11 | 12 | prompt_called = false; 13 | spy.stub(ndb.Helpers, "prompt", function() { 14 | prompt_called = true; 15 | }); 16 | }); 17 | 18 | it("should output the ndb + node version", function() { 19 | version.run(); 20 | puts_called_with[0].should.equal("ndb: version 0.2.3"); 21 | puts_called_with[1].should.equal("node (local): version " + process.version); 22 | }); 23 | 24 | it("should output the prompt", function() { 25 | version.run(); 26 | prompt_called.should.be(true); 27 | }); 28 | 29 | it("should parse 'version' as the version", function() { 30 | version.parseCommand("version")[0].should.equal(version); 31 | }); 32 | 33 | it("should not parse 'foo'", function() { 34 | version.parseCommand("foo").should.equal(undefined); 35 | }); 36 | }); 37 | 38 | describe("package.json version", function() { 39 | it("should have the correct version", function() { 40 | var file_contents = require("fs").readFileSync("./package.json", 'ascii'); 41 | var data = JSON.parse(file_contents); 42 | 43 | data["version"].should.equal("0.2.3"); 44 | }); 45 | }); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /spec/node.js: -------------------------------------------------------------------------------- 1 | require.paths.unshift("./lib/"); 2 | 3 | require("./jspec_dot_reporter/jspec_dot_reporter"); 4 | require("./espionage/lib/espionage"); 5 | require("./underscore/underscore"); 6 | require('./jspec/lib/jspec'); 7 | require('./unit/spec.helper'); 8 | 9 | 10 | spy = Espionage; 11 | 12 | JSpec.include({ 13 | beforeSpec: function() { 14 | spy.tearDown(); 15 | }, 16 | 17 | afterSpec: function() { 18 | spy.tearDown(); 19 | } 20 | }); 21 | 22 | JSpec. 23 | exec("spec/unit/node_spec.js"). 24 | exec('spec/unit/spec.js'). 25 | exec('spec/unit/ndb.js'). 26 | exec('spec/unit/command_center.js'). 27 | exec('spec/unit/event_listener.js'). 28 | exec('spec/unit/event_listeners/break.js'). 29 | exec('spec/unit/event_listeners/source.js'). 30 | exec('spec/unit/commands/raw_write.js'). 31 | exec('spec/unit/commands/help.js'). 32 | exec('spec/unit/commands/list.js'). 33 | exec('spec/unit/commands/continue.js'). 34 | exec('spec/unit/commands/step_in.js'). 35 | exec('spec/unit/commands/step_out.js'). 36 | exec('spec/unit/commands/setbreakpoint.js'). 37 | exec('spec/unit/commands/quit.js'). 38 | exec('spec/unit/commands/version.js'). 39 | exec('spec/unit/commands/evaluate.js'). 40 | exec('spec/unit/commands/next.js'). 41 | exec('spec/unit/commands/verbose.js'). 42 | exec('spec/unit/commands/backtrace.js'). 43 | exec('spec/unit/commands/history.js'). 44 | exec('spec/unit/commands/repl.js'). 45 | exec('spec/unit/message_parser.js'). 46 | exec('spec/unit/state.js'). 47 | exec('spec/unit/option_parser/option_parser_spec.js'). 48 | run({ reporter: JSpecDotReporter, fixturePath: 'spec/fixtures' }). 49 | report(); 50 | -------------------------------------------------------------------------------- /lib/ndb/option_parser.js: -------------------------------------------------------------------------------- 1 | var js_opts = require("./../vendor/js-opts/opts"), 2 | ndb = require("./../ndb"); 3 | 4 | exports.opts = js_opts; 5 | 6 | exports.parse = function() { 7 | this.opts.parse(this.options, true, true); 8 | ndb.start(); 9 | }; 10 | 11 | exports.options = [ 12 | { 13 | "short": "v", 14 | "long": "version", 15 | description: "Print version and exit", 16 | callback: function() { 17 | ndb.Helpers.puts("ndb version 0.2.3"); 18 | ndb.Helpers.exit(); 19 | } 20 | }, 21 | { 22 | "short": "p", 23 | "long": "port", 24 | description: "Set the port (default: 5858)", 25 | value: true, 26 | callback: function(value) { 27 | ndb.port = parseInt(value, "10"); 28 | } 29 | }, 30 | { 31 | "short": "h", 32 | "long": "host", 33 | description: "Set the host (default: 127.0.0.1)", 34 | value: true, 35 | callback: function(value) { 36 | ndb.host = value; 37 | } 38 | }, 39 | { 40 | "long": "verbose", 41 | description: "Turn on verbose/debugging mode (default: off)", 42 | callback: function() { 43 | ndb.verbose = true; 44 | } 45 | }, 46 | { 47 | "short": "l", 48 | "long": "local", 49 | description: "Shortcut for running $(node --debug-brk &; ndb) locally.", 50 | value: true, 51 | callback: function(scriptName) { 52 | var puts = ndb.Helpers.puts, 53 | spawn = ndb.Helpers.childProcess.spawn, 54 | cmd, 55 | args; 56 | 57 | cmd = "node"; 58 | args = ["--debug-brk", scriptName]; 59 | 60 | puts("Spawning process: " + "`" + cmd + " " + args.join(" ") + "`"); 61 | spawn(cmd, args); 62 | } 63 | } 64 | ]; 65 | -------------------------------------------------------------------------------- /lib/vendor/js-opts/example4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Advanced example using namespaces for a library and named arguments 3 | * 4 | * Run: 5 | * node example4.js --help 6 | * and play with the options to see the behavior. 7 | */ 8 | 9 | var opts = require('./opts') 10 | , puts = require('util').puts 11 | , host = 'localhost'; // default host value 12 | 13 | // Example of using some library in the same app 14 | var libOpts = [ 15 | { short : 'l' 16 | , long : 'list' 17 | , description : 'Show the library list' 18 | , callback : function () { puts('mylib list!'); }, 19 | }, 20 | ]; 21 | opts.add(libOpts, 'mylib'); 22 | 23 | // NOTE: ------------ 24 | // You would never actually add options for a library from within your 25 | // app, this would be done from within the library itself. It is shown 26 | // here for readability 27 | 28 | var options = [ 29 | { short : 'l' // deliberately conflicting with 'mylib' option 30 | , long : 'list' 31 | , description : 'List all files' 32 | }, 33 | { short : 'd' 34 | , long : 'debug' 35 | , description : 'Set a debug level' 36 | , value : true 37 | }, 38 | ]; 39 | 40 | var arguments = [ { name : 'script' , required : true } 41 | , { name : 'timeout' } 42 | ]; 43 | 44 | opts.parse(options, arguments, true); 45 | 46 | var debug = opts.get('d') || 'info' // default debug value 47 | , list = opts.get('list'); 48 | 49 | var script = opts.arg('script') 50 | , timeout = opts.arg('timeout') || 30; 51 | 52 | 53 | if (list) puts('List arg was set'); 54 | puts('Debug level is: ' + debug); 55 | puts('Script is: ' + script); 56 | puts('Timeout is: ' + timeout); 57 | 58 | process.exit(0); 59 | 60 | -------------------------------------------------------------------------------- /lib/ndb/command_center.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | var parse_command = function(command, text, fun) { 4 | var match = new RegExp("^" + command + " " + "(.+)").exec(text); 5 | 6 | if (match === null) { 7 | return false; 8 | } else { 9 | return match[1]; 10 | } 11 | }; 12 | 13 | exports.commands = ndb.Commands; 14 | 15 | exports.reset = function() { 16 | this.lastCommand = null; 17 | }; 18 | 19 | exports.parse = function(text) { 20 | var puts = ndb.Helpers.puts, 21 | commands = this.commands, 22 | result = false, 23 | command, 24 | i; 25 | 26 | text = text.trim(); 27 | 28 | if (text === "" && this.lastCommand) { 29 | return this.lastCommand; 30 | } 31 | 32 | for (i in this.commands) { 33 | command = commands[i]; 34 | 35 | if (command.parseCommand) { 36 | result = command.parseCommand(text); 37 | if (result) { 38 | ndb.State.history.push(text); 39 | this.lastCommand = result; 40 | return result; 41 | } 42 | } 43 | } 44 | 45 | this.lastCommand = null; 46 | 47 | return [commands.Help]; 48 | }; 49 | 50 | exports.stdinListener = function(text) { 51 | ndb = require("ndb"); 52 | 53 | if (!ndb.State.replOn) { 54 | var pair = this.parse(text); 55 | 56 | if (pair instanceof Array) { 57 | pair[0].run(pair[1]); 58 | } 59 | } 60 | }; 61 | 62 | exports.loop = function() { 63 | var process = ndb.Helpers.process, 64 | stdin; 65 | 66 | this.commands.connection = this.connection; 67 | stdin = process.openStdin(); 68 | stdin.setEncoding("ascii"); 69 | 70 | var self = this; 71 | 72 | stdin.addListener("data", function() { 73 | self.stdinListener.apply(self, arguments); 74 | }); 75 | }; 76 | -------------------------------------------------------------------------------- /spec/unit/commands/history.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("history", function() { 4 | before_each(function() { 5 | history = ndb.Commands.History; 6 | 7 | puts_called_with = []; 8 | spy.stub(ndb.Helpers, "puts", function(text) { 9 | puts_called_with.push(text); 10 | }); 11 | 12 | prompt_called = false; 13 | spy.stub(ndb.Helpers, "prompt", function() { 14 | prompt_called = true; 15 | }); 16 | }); 17 | 18 | it("should output the command history - one for one line", function() { 19 | ndb.State.history = ["list"]; 20 | history.run(); 21 | puts_called_with[0].should.equal(" 1 list"); 22 | }); 23 | 24 | it("should output several commands, numbering them appropriately", function() { 25 | ndb.State.history = ["list", "foo"]; 26 | history.run(); 27 | puts_called_with[0].should.equal(" 1 list"); 28 | puts_called_with[1].should.equal(" 2 foo"); 29 | }); 30 | 31 | it("should pad the numbers appropriately", function() { 32 | ndb.State.history = [ 33 | "one", 34 | "two", 35 | "three", 36 | "four", 37 | "five", 38 | "six", 39 | "seven", 40 | "eight", 41 | "nine", 42 | "ten" 43 | ]; 44 | 45 | history.run(); 46 | puts_called_with[8].should.equal(" 9 nine"); 47 | puts_called_with[9].should.equal(" 10 ten"); 48 | }); 49 | 50 | it("should output the prompt", function() { 51 | history.run(); 52 | prompt_called.should.be(true); 53 | }); 54 | }); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /lib/vendor/js-opts/LICENSE: -------------------------------------------------------------------------------- 1 | Author : Joey Mazzarelli 2 | Email : mazzarelli@gmail.com 3 | Homepage : http://joey.mazzarelli.com/js-opts/ 4 | Source : http://bitbucket.org/mazzarell/js-opts/ 5 | License : Simplified BSD License 6 | 7 | Copyright 2010 Joey Mazzarelli. All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI 'AS IS' AND ANY EXPRESS OR IMPLIED 20 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 22 | EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | The views and conclusions contained in the software and documentation are those 31 | of the authors and should not be interpreted as representing official policies, 32 | either expressed or implied, of Joey Mazzarelli. 33 | -------------------------------------------------------------------------------- /lib/ndb/commands/setbreakpoint.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["b", "break"]; 6 | 7 | exports.parseCommand = function(text) { 8 | var obj = {}, 9 | array; 10 | 11 | if (text == "b" || text == "break") { 12 | return [this, obj]; 13 | } 14 | 15 | var match = new RegExp("^b(reak)? (.+)").exec(text); 16 | 17 | if (match === null) { 18 | return false; 19 | } else { 20 | array = match[2].split(":"); 21 | 22 | if (array.length === 1) { 23 | obj.lineNumber = array[0]; 24 | } else { 25 | obj.filename = array[0]; 26 | obj.lineNumber = array[1]; 27 | } 28 | 29 | obj.lineNumber = parseInt(obj.lineNumber, "10"); 30 | 31 | return([this, obj]); 32 | } 33 | }; 34 | 35 | exports.run = function() { 36 | var obj = arguments[0] || {}, 37 | ndb = this.ndb, 38 | file = obj.filename || ndb.State.filename, 39 | line = obj.lineNumber || ndb.State.lineNumber || 1; 40 | 41 | ndb.Commands.RawWrite.run({ 42 | type: "request", 43 | command: "setbreakpoint", 44 | arguments: { 45 | type: "script", 46 | target: file, 47 | // v8 starts counting at 0 48 | // so line 10 for us is really line 9 for them 49 | line: line - 1 50 | } 51 | }); 52 | }; 53 | 54 | exports.parseResponse = function(obj) { 55 | if (obj.command === "setbreakpoint") { 56 | return this; 57 | } 58 | }; 59 | 60 | exports.output = function(msg) { 61 | var ndb = this.ndb, 62 | puts = ndb.Helpers.puts, 63 | str; 64 | 65 | str = "Breakpoint " + msg.body.breakpoint + " set"; 66 | 67 | if (msg.body.script_name) { 68 | str += " at "; 69 | str += msg.body.script_name; 70 | 71 | if (msg.body.line) { 72 | str += ":"; 73 | // v8 starts counting at 0 74 | // so line 0 for them is really line 1 for us 75 | str += msg.body.line + 1; 76 | } 77 | } 78 | 79 | puts(str); 80 | }; 81 | -------------------------------------------------------------------------------- /lib/vendor/js-opts/example2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * More complex example. 3 | * 4 | * Run: 5 | * node example2.js --help 6 | * and play with the options to see the behavior. 7 | * 8 | * This example shows different ways of using the library. It is deliberately 9 | * inconsistent. Choose the style that suits you best. 10 | */ 11 | 12 | var opts = require('./opts') 13 | , puts = require('util').puts 14 | , host = 'localhost'; // default host value 15 | 16 | var options = [ 17 | { short : 'v' 18 | , long : 'version' 19 | , description : 'Show version and exit' 20 | , callback : function () { puts('v1.0'); process.exit(1); } 21 | }, 22 | { short : 'l' 23 | , long : 'list' 24 | , description : 'List all files' 25 | }, 26 | { short : 'f' 27 | , long : 'file' 28 | , description : 'Load a file' 29 | , value : true 30 | , required : true 31 | }, 32 | { short : 'd' 33 | , long : 'debug' 34 | , description : 'Set a debug level' 35 | , value : true 36 | }, 37 | { short : 'h' 38 | , long : 'host' 39 | , description : 'The hostname to connect to' 40 | , value : true 41 | , callback : function (value) { host = value; } // override host value 42 | }, 43 | { short : 'p' 44 | , long : 'port' 45 | , description : 'The port to connect to' 46 | , value : true 47 | }, 48 | ]; 49 | 50 | opts.parse(options, true); 51 | 52 | var port = opts.get('port') || 8000 // default port value 53 | , debug = opts.get('d') || 'info' // default debug value 54 | , file = opts.get('f') 55 | , list = opts.get('list'); 56 | 57 | var arg1 = opts.args()[0] 58 | , arg2 = opts.args()[1]; 59 | 60 | 61 | if (list) puts('List arg was set'); 62 | if (file) puts('File arg was set: ' + file); 63 | puts('Debug level is: ' + debug); 64 | puts('Host is: ' + host); 65 | puts('Port is: ' + port); 66 | 67 | if (arg1) puts('Extra arg 1: ' + arg1); 68 | if (arg2) puts('Extra arg 2: ' + arg2); 69 | 70 | process.exit(0); 71 | 72 | -------------------------------------------------------------------------------- /lib/ndb/commands/list.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"); 2 | 3 | exports.ndb = ndb; 4 | 5 | exports.commandNames = ["l", "list"]; 6 | 7 | exports.parseCommand = function(text) { 8 | return this.ndb.Helpers.commonParse.call(this, text); 9 | }; 10 | 11 | exports.calculateContext = function(num) { 12 | var prev = num - this.context; 13 | 14 | if (prev < 1) { 15 | prev = 1; 16 | } 17 | 18 | return { 19 | posterior: prev, 20 | anterior: prev + (this.context * 2) 21 | }; 22 | }; 23 | 24 | exports.run = function() { 25 | var ndb = this.ndb, 26 | writer = ndb.Commands.RawWrite, 27 | lineNumber = ndb.State.lineNumber; 28 | 29 | if (!lineNumber) { 30 | lineNumber = 1; 31 | } 32 | 33 | var context = this.calculateContext(lineNumber); 34 | 35 | writer.run({ 36 | type: "request", 37 | command: "source", 38 | arguments: { 39 | fromLine: context.posterior - 1, 40 | toLine: context.anterior 41 | } 42 | }); 43 | }; 44 | 45 | function fromUpto(start, end, fun) { 46 | var index = 0, 47 | current = start; 48 | 49 | for (; current <= end; current++, index++) { 50 | fun(current, index); 51 | } 52 | } 53 | 54 | function constructString(obj, current_line) { 55 | var source = obj.body.source.split("\n"), 56 | fromLine = obj.body.fromLine + 1, 57 | toLine = obj.body.toLine, 58 | str = ""; 59 | 60 | fromUpto(fromLine, toLine, function(sourceNum, counter) { 61 | if (sourceNum === current_line) { 62 | str += "=> "; 63 | } else { 64 | str += " "; 65 | } 66 | 67 | str += sourceNum + " " + source[counter]; 68 | 69 | if (sourceNum !== toLine) { 70 | str += "\n"; 71 | } 72 | }); 73 | 74 | return str; 75 | } 76 | 77 | exports.output = function(obj) { 78 | var ndb = this.ndb, 79 | puts = ndb.Helpers.puts; 80 | 81 | puts(constructString(obj, ndb.State.lineNumber)); 82 | }; 83 | 84 | exports.parseResponse = function(obj) { 85 | if (obj.command === "source") { 86 | return this; 87 | } 88 | }; 89 | 90 | exports.reset = function() { 91 | this.context = 4; 92 | }; 93 | 94 | exports.reset(); -------------------------------------------------------------------------------- /spec/unit/commands/step_in.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("step in", function() { 4 | describe("running", function() { 5 | before_each(function() { 6 | connection = { 7 | write: function() {} 8 | }; 9 | 10 | commands = ndb.Commands; 11 | commands.connection = connection; 12 | 13 | c = commands.StepIn; 14 | }); 15 | 16 | // {"seq":117,"type":"request","command":"continue"} 17 | // {"seq":118,"type":"request","command":"continue","arguments":{"stepaction":"out"}} 18 | // {"seq":119,"type":"request","command":"continue","arguments":{"stepaction":"next","stepcount":5}} 19 | 20 | // { "seq" : , 21 | // "type" : "request", 22 | // "command" : "continue", 23 | // "arguments" : { "stepaction" : <"in", "next" or "out">, 24 | // "stepcount" : 25 | // } 26 | // } 27 | it("should raw_write the continue command", function() { 28 | var obj = undefined; 29 | 30 | spy.stub(ndb.Commands.RawWrite, "run", function(o) { 31 | obj = o; 32 | }); 33 | 34 | var expected_object = { 35 | type: "request", 36 | command: "continue", 37 | arguments: { 38 | stepaction: "in", 39 | stepcount: 1 40 | } 41 | }; 42 | 43 | c.run(); 44 | 45 | JSON.stringify(obj).should.equal(JSON.stringify(expected_object)); 46 | }); 47 | 48 | it("should use the stepcount given when one is given", function() { 49 | var obj = undefined; 50 | 51 | spy.stub(ndb.Commands.RawWrite, "run", function(o) { 52 | obj = o; 53 | }); 54 | 55 | var expected_object = { 56 | type: "request", 57 | command: "continue", 58 | arguments: { 59 | stepaction: "in", 60 | stepcount: 5 61 | } 62 | }; 63 | 64 | c.run(5); 65 | 66 | JSON.stringify(obj).should.equal(JSON.stringify(expected_object)); 67 | }); 68 | }); 69 | }); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /lib/ndb/event_listener.js: -------------------------------------------------------------------------------- 1 | var ndb = require("ndb"), 2 | sys = require("util"); 3 | 4 | exports.reset = function() { 5 | this.buffer = ""; 6 | }; 7 | 8 | exports.regexp = new RegExp("Content-Length: \\d+\r\n\r\n"); 9 | 10 | exports.receive = function(str, __json_callback) { 11 | var puts = ndb.Helpers.puts, 12 | log = ndb.Helpers.log, 13 | prompt = ndb.Helpers.prompt, 14 | replPrompt = ndb.Helpers.replPrompt, 15 | verbose = ndb.verbose, 16 | regexp = this.regexp, 17 | message, 18 | message_body, 19 | content_length, 20 | json, 21 | result, 22 | object, 23 | i; 24 | 25 | if (verbose) { 26 | log(str, "verbose: <<< "); 27 | } 28 | 29 | this.buffer += str; 30 | 31 | do { 32 | message = ndb.MessageParser.parse(this.buffer); 33 | content_length = message.headers["Content-Length"]; 34 | 35 | if (content_length && message.body.length >= parseInt(content_length, "10")) { 36 | message_body = message.body.substr(0, content_length); 37 | 38 | if (content_length > 0) { 39 | try { 40 | json = JSON.parse(message_body); 41 | 42 | if (__json_callback) { 43 | __json_callback(json); 44 | } 45 | 46 | for (i in ndb.Commands) { 47 | object = ndb.Commands[i]; 48 | 49 | if (object.parseResponse) { 50 | result = object.parseResponse(json); 51 | 52 | if (result) { 53 | result.output(json); 54 | 55 | if (ndb.State.replOn) { 56 | replPrompt(); 57 | } else { 58 | prompt(); 59 | } 60 | } 61 | } 62 | } 63 | } catch (e) { 64 | sys.puts(""); 65 | sys.puts(""); 66 | sys.puts("ERROR: " + sys.inspect(e)); 67 | sys.puts("BUFFER: " + this.buffer); 68 | sys.puts("content length: " + content_length); 69 | sys.puts("message body: " + message_body); 70 | sys.puts(""); 71 | sys.puts(""); 72 | sys.puts(""); 73 | } 74 | } 75 | 76 | this.buffer = this.buffer.replace(message.raw_headers + "\r\n" + message_body, ""); 77 | } else { 78 | break; 79 | } 80 | } while (true) 81 | }; 82 | -------------------------------------------------------------------------------- /spec/unit/commands/step_out.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("step out", function() { 4 | describe("running", function() { 5 | before_each(function() { 6 | connection = { 7 | write: function() {} 8 | }; 9 | 10 | commands = ndb.Commands; 11 | commands.connection = connection; 12 | 13 | c = commands.StepOut; 14 | }); 15 | 16 | // {"seq":117,"type":"request","command":"continue"} 17 | // {"seq":118,"type":"request","command":"continue","arguments":{"stepaction":"out"}} 18 | // {"seq":119,"type":"request","command":"continue","arguments":{"stepaction":"next","stepcount":5}} 19 | 20 | // { "seq" : , 21 | // "type" : "request", 22 | // "command" : "continue", 23 | // "arguments" : { "stepaction" : <"in", "next" or "out">, 24 | // "stepcount" : 25 | // } 26 | // } 27 | it("should raw_write the continue command", function() { 28 | var obj = undefined; 29 | 30 | spy.stub(ndb.Commands.RawWrite, "run", function(o) { 31 | obj = o; 32 | }); 33 | 34 | var expected_object = { 35 | type: "request", 36 | command: "continue", 37 | arguments: { 38 | stepaction: "out", 39 | stepcount: 1 40 | } 41 | }; 42 | 43 | c.run(); 44 | 45 | JSON.stringify(obj).should.equal(JSON.stringify(expected_object)); 46 | }); 47 | 48 | it("should use the stepcount given when one is given", function() { 49 | var obj = undefined; 50 | 51 | spy.stub(ndb.Commands.RawWrite, "run", function(o) { 52 | obj = o; 53 | }); 54 | 55 | var expected_object = { 56 | type: "request", 57 | command: "continue", 58 | arguments: { 59 | stepaction: "out", 60 | stepcount: 5 61 | } 62 | }; 63 | 64 | c.run(5); 65 | 66 | JSON.stringify(obj).should.equal(JSON.stringify(expected_object)); 67 | true.should.equal(true); 68 | }); 69 | }); 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /spec/unit/commands/verbose.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("verbose", function() { 4 | before_each(function() { 5 | verbose = ndb.Commands.Verbose; 6 | node_debugger = verbose.ndb; 7 | }); 8 | 9 | describe("parsing", function() { 10 | it("should parse 'verbose'", function() { 11 | verbose.parseCommand("verbose")[0].should.equal(verbose); 12 | }); 13 | 14 | it("should not parse a random string", function() { 15 | verbose.parseCommand("asdfasdfa").should.be(undefined); 16 | }); 17 | }); 18 | 19 | describe("running", function() { 20 | before_each(function() { 21 | spy.stub(node_debugger.Helpers, "puts"); 22 | }); 23 | 24 | it("should turn off the verbose flag if on", function() { 25 | node_debugger.verbose = true; 26 | verbose.run(); 27 | node_debugger.verbose.should.be(false); 28 | }); 29 | 30 | it("should turn on the verbose flag if off", function() { 31 | node_debugger.verbose = false; 32 | verbose.run(); 33 | node_debugger.verbose.should.be(true); 34 | }); 35 | 36 | it("should output it's new status (as off when toggled off)", function() { 37 | spy.spyOn(node_debugger.Helpers, function() { 38 | node_debugger.verbose = true; 39 | verbose.run(); 40 | 41 | spy.intercepted(node_debugger.Helpers, "puts", function(text) { 42 | text.should.equal("verbose mode now off"); 43 | }); 44 | }); 45 | }); 46 | 47 | it("should output it's new status (as on when toggled on)", function() { 48 | spy.spyOn(node_debugger.Helpers, function() { 49 | node_debugger.verbose = false; 50 | verbose.run(); 51 | 52 | spy.intercepted(node_debugger.Helpers, "puts", function(text) { 53 | text.should.equal("verbose mode now on"); 54 | }); 55 | }); 56 | }); 57 | 58 | it("should display the prompt when done", function() { 59 | spy.spyOn(node_debugger.Helpers, function() { 60 | verbose.run(); 61 | spy.intercepted(node_debugger.Helpers, "prompt").should.be(true); 62 | }); 63 | }); 64 | }); 65 | }); 66 | }); 67 | }); -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | == 0.2.3 / 2010-11-24 2 | * minor release to fix version info 3 | 4 | == 0.2.2 / 2010-11-23 5 | * npm support (Isaac Z. Schlueter - i@izs.me) 6 | 7 | == 0.2.3 / 2010-11-02 8 | * node 0.3.0 support 9 | 10 | == 0.2.0 / 2010-08-20 11 | * bugfix: Compatibility with node v0.1.97 / v0.2.0. 12 | * add stepout functionality 13 | 14 | == 0.1.5 / 2010-05-30 15 | * add history tracking 16 | ndb> history 17 | 1 list 18 | 2 n 19 | 3 history 20 | 21 | * repl 22 | 23 | ndb> repl 24 | Welcome to the ndb repl. 25 | Type .break to exit. 26 | repl> this 27 | => # 28 | repl> 1+1 29 | => 2 30 | repl> .break 31 | 32 | == 0.1.4 / 2010-05-20 33 | * Implement backtrace command. 34 | * set host with --host 35 | * use --local option to run script directly - 36 | a shortcut for starting the script with two commands: 37 | 38 | Instead of: 39 | 40 | $ node --debug-brk my_js.js & 41 | $ ndb 42 | 43 | The convenience --local is provided: 44 | 45 | ndb --local my_js.js 46 | 47 | * wait for remote host to be up. It'll spin in a loop and look for a connection every two 48 | seconds instead of bombing out immediately if it doesn't find one. 49 | 50 | == 0.1.3 / 2010-05-14 51 | * fix off-by-one error when setting breakpoints (36f62560d62d653fde5bb789f38b172b2c6bdc0f) 52 | * command line options 53 | 54 | == 0.1.2 / 2010-04-27 55 | - get ndb working with latest released version of node.js (0.1.91) 56 | - exit when the remote process is finished (instead of stalling and eventually raising an error) 57 | - add 'exit' as an alias for 'quit' 58 | 59 | 60 | 0.1.1.1 / 2010-04-08 61 | ------- 62 | 63 | - Improved display of prompt (no additional prompts displayed) 64 | - Fixed Bug #1 - "list command occasionally doesn't display code" 65 | (http://github.com/smtlaissezfaire/ndb/issues/closed#issue/1) 66 | - Add step (stepin) 67 | - Improve eval support when require isn't defined 68 | - Display errors when eval throws an error 69 | - Add confirmation for setting a breakpoint: 70 | ndb> break 6 71 | Breakpoint 1 set at /Users/scotttaylor/src/git/ndb/spec/node.js:6 72 | ndb> break 7 73 | ndb> Breakpoint 2 set at /Users/scotttaylor/src/git/ndb/spec/node.js:7 74 | 75 | 76 | 0.1.0 / 2010-03-20 77 | ------------------ 78 | 79 | - Initial release 80 | - Following commands are at least partially supported: 81 | 82 | * list source (on current line) 83 | * break points 84 | * next 85 | * continue 86 | * eval / print 87 | 88 | - A few meta commands: 89 | 90 | * version 91 | * verbose (for showing the interaction with the debugging server) 92 | * rw - raw write json over the wire 93 | * quit 94 | -------------------------------------------------------------------------------- /spec/unit/commands/raw_write.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("RawWrite", function() { 4 | before_each(function() { 5 | connection = { 6 | write: function() {} 7 | }; 8 | 9 | commands = ndb.Commands; 10 | commands.connection = connection; 11 | 12 | raw_write = commands.RawWrite; 13 | }); 14 | 15 | it("should write the json to the connection", function() { 16 | text = ""; 17 | connection.write = function(t) { text += t; }; 18 | 19 | commands.RawWrite.run("{some: json}"); 20 | 21 | text.should.match(/\{some\: json\}/); 22 | }); 23 | 24 | it("should output the correct json", function() { 25 | text = ""; 26 | connection.write = function(t) { text += t; }; 27 | 28 | commands.RawWrite.run("{foo: bar}"); 29 | 30 | text.should.match(/\{foo\: bar\}/); 31 | }); 32 | 33 | it("should output a final \\n at the end of the json", function() { 34 | text = ""; 35 | connection.write = function(t) { text += t; }; 36 | 37 | commands.RawWrite.run("{foo: bar}"); 38 | 39 | text.should.match(/\{foo\: bar\}\n/); 40 | }); 41 | 42 | it("should output the content length header before the text, as well as two \\r\\n's", function() { 43 | text = ""; 44 | connection.write = function(t) { text += t; }; 45 | 46 | commands.RawWrite.run("{foo: bar}"); 47 | 48 | text.should.match(/Content-Length: 11\r\n\r\n\{foo\: bar\}\n/); 49 | }); 50 | 51 | it("should output the correct content length", function() { 52 | text = ""; 53 | connection.write = function(t) { text += t; }; 54 | 55 | commands.RawWrite.run("{a: b}"); 56 | 57 | text.should.match(/Content-Length: 7\r/); 58 | }); 59 | 60 | it("should JSON.stringify an object", function() { 61 | text = ""; 62 | connection.write = function(t) { text += t; }; 63 | 64 | commands.RawWrite.run({foo: 'bar'}); 65 | 66 | var str = JSON.stringify({foo: 'bar'}); 67 | 68 | text.should.match(str); 69 | }); 70 | 71 | it("should write to the log before writing out", function() { 72 | var called = false; 73 | 74 | raw_write.ndb.verbose = true; 75 | 76 | raw_write.ndb.Helpers.log = function() { 77 | called = true; 78 | }; 79 | 80 | raw_write.run("foo"); 81 | called.should.be(true); 82 | }); 83 | 84 | it("should not write to the log when its turned off", function() { 85 | var called = false; 86 | 87 | raw_write.ndb.verbose = false; 88 | 89 | raw_write.ndb.Helpers.log = function() { 90 | called = true; 91 | }; 92 | 93 | raw_write.run("foo"); 94 | called.should.be(false); 95 | }); 96 | }); 97 | }); 98 | }); -------------------------------------------------------------------------------- /bugs/project.yaml: -------------------------------------------------------------------------------- 1 | --- !ditz.rubyforge.org,2008-03-06/project 2 | name: ndb 3 | version: "0.5" 4 | components: 5 | - !ditz.rubyforge.org,2008-03-06/component 6 | name: ndb 7 | releases: 8 | - !ditz.rubyforge.org,2008-03-06/release 9 | name: 0.1.2 10 | status: :released 11 | release_time: 2010-04-27 07:53:09.817074 Z 12 | log_events: 13 | - - 2010-04-14 06:40:27.435513 Z 14 | - Scott Taylor 15 | - created 16 | - "" 17 | - - 2010-04-27 07:53:09.817084 Z 18 | - Scott Taylor 19 | - released 20 | - Compatiblity with node v0.1.91 21 | - !ditz.rubyforge.org,2008-03-06/release 22 | name: 0.1.3 23 | status: :released 24 | release_time: 2010-05-14 06:58:06.417526 Z 25 | log_events: 26 | - - 2010-05-14 06:53:24.116180 Z 27 | - Scott Taylor 28 | - created 29 | - "" 30 | - - 2010-05-14 06:58:06.417539 Z 31 | - Scott Taylor 32 | - released 33 | - "" 34 | - !ditz.rubyforge.org,2008-03-06/release 35 | name: 0.1.4 36 | status: :released 37 | release_time: 2010-05-20 05:40:28.490184 Z 38 | log_events: 39 | - - 2010-05-16 22:49:19.982336 Z 40 | - Scott Taylor 41 | - created 42 | - "" 43 | - - 2010-05-20 05:40:28.490194 Z 44 | - Scott Taylor 45 | - released 46 | - "" 47 | - !ditz.rubyforge.org,2008-03-06/release 48 | name: 0.1.5 49 | status: :released 50 | release_time: 2010-05-30 06:09:35.735608 Z 51 | log_events: 52 | - - 2010-05-21 05:52:57.654953 Z 53 | - Scott Taylor 54 | - created 55 | - "" 56 | - - 2010-05-30 06:09:35.735622 Z 57 | - Scott Taylor 58 | - released 59 | - "" 60 | - !ditz.rubyforge.org,2008-03-06/release 61 | name: 0.2.0 62 | status: :released 63 | release_time: 2010-08-20 20:49:15.490929 Z 64 | log_events: 65 | - - 2010-08-20 20:41:15.642505 Z 66 | - Scott Taylor 67 | - created 68 | - "" 69 | - - 2010-08-20 20:49:15.490944 Z 70 | - Scott Taylor 71 | - released 72 | - "" 73 | - !ditz.rubyforge.org,2008-03-06/release 74 | name: 0.2.1 75 | status: :released 76 | release_time: 2010-11-02 07:11:07.604460 Z 77 | log_events: 78 | - - 2010-11-02 07:10:42.277425 Z 79 | - Scott Taylor 80 | - created 81 | - Add node 0.3.0 support 82 | - - 2010-11-02 07:11:07.604473 Z 83 | - Scott Taylor 84 | - released 85 | - "" 86 | - !ditz.rubyforge.org,2008-03-06/release 87 | name: 0.2.2 88 | status: :released 89 | release_time: 2010-11-23 23:23:54.969294 Z 90 | log_events: 91 | - - 2010-11-23 23:23:40.185182 Z 92 | - Scott Taylor 93 | - created 94 | - "" 95 | - - 2010-11-23 23:23:54.969307 Z 96 | - Scott Taylor 97 | - released 98 | - "" 99 | -------------------------------------------------------------------------------- /spec/unit/commands/list.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("List", function() { 4 | before_each(function() { 5 | connection = { 6 | write: function() {} 7 | }; 8 | 9 | commands = ndb.Commands; 10 | commands.connection = connection; 11 | 12 | list = commands.List; 13 | 14 | writer = ndb.Commands.RawWrite; 15 | }); 16 | 17 | it("should raw write the json", function() { 18 | var obj = undefined; 19 | 20 | ndb.Commands.RawWrite = { 21 | run: function(o) { 22 | obj = o; 23 | } 24 | }; 25 | 26 | var expected_object = { 27 | type: "request", 28 | command: "source", 29 | arguments: { 30 | "fromLine": 0, 31 | "toLine": 5 32 | } 33 | }; 34 | 35 | list.run(); 36 | 37 | JSON.stringify(obj).should.equal(JSON.stringify(expected_object)); 38 | }); 39 | 40 | it("should use the line number from the break event", function() { 41 | ndb.State.lineNumber = 10; 42 | 43 | spy.spyOn(writer, function() { 44 | list.run(); 45 | 46 | spy.intercepted(writer, "run", function(obj) { 47 | obj["arguments"].fromLine.should.equal(7); 48 | obj["arguments"].toLine.should.equal(12); 49 | }); 50 | }); 51 | }); 52 | 53 | describe("context", function() { 54 | it("should have the default of 2", function() { 55 | list.reset(); 56 | list.context.should.equal(4); 57 | }); 58 | }); 59 | 60 | describe("calculating the context", function() { 61 | it("should return -2, +2", function() { 62 | var context = list.calculateContext(10); 63 | context.posterior.should.equal(8); 64 | context.anterior.should.equal(12); 65 | }); 66 | 67 | it("should use the correct numbers", function() { 68 | var context = list.calculateContext(20); 69 | context.posterior.should.equal(18); 70 | context.anterior.should.equal(22); 71 | }); 72 | 73 | it("should calculate based on the value of the context variable", function() { 74 | list.context = 3; 75 | 76 | var context = list.calculateContext(10); 77 | context.posterior.should.equal(7); 78 | context.anterior.should.equal(13); 79 | }); 80 | 81 | it("should never go below 1", function() { 82 | var context = list.calculateContext(1); 83 | context.posterior.should.equal(1); 84 | }); 85 | 86 | it("should change the second value to account for the first going below 1", function() { 87 | list.context.should.equal(2); 88 | 89 | var context = list.calculateContext(1); 90 | context.posterior.should.equal(1); 91 | context.anterior.should.equal(5); 92 | }); 93 | }); 94 | }); 95 | }); 96 | }); 97 | -------------------------------------------------------------------------------- /spec/unit/commands/repl.js: -------------------------------------------------------------------------------- 1 | describe("ndb", function() { 2 | describe("Commands", function() { 3 | describe("repl", function() { 4 | before_each(function() { 5 | repl = ndb.Commands.REPL; 6 | 7 | raw_write = ndb.Commands.RawWrite; 8 | spy.stub(raw_write, "run"); 9 | }); 10 | 11 | it("should have the command name 'repl'", function() { 12 | repl.commandNames[0].should.equal('repl'); 13 | }); 14 | 15 | it("should output a prompt + help text", function() { 16 | spy.spyOn(ndb.Helpers, function() { 17 | repl.run(); 18 | 19 | spy.intercepted(ndb.Helpers, "puts", function(text) { 20 | text.should.equal("Welcome to the ndb repl.\nType .break to exit."); 21 | }); 22 | 23 | spy.intercepted(ndb.Helpers, "print", function(text) { 24 | text.should.equal("repl> "); 25 | }); 26 | }); 27 | }); 28 | 29 | it("should have the normal repl off before executing", function() { 30 | ndb.State.replOn.should.equal(false); 31 | }); 32 | 33 | it("should turn on the main repl when executing", function() { 34 | repl.run(function(){ 35 | ndb.State.replOn.should.equal(true); 36 | }); 37 | }); 38 | }); 39 | 40 | describe("running the repl", function() { 41 | before_each(function() { 42 | repl = ndb.Commands.REPL; 43 | 44 | raw_write = ndb.Commands.RawWrite; 45 | spy.stub(raw_write, "run"); 46 | }); 47 | 48 | it("should evaluate a command", function() { 49 | spy.spyOn(raw_write, function() { 50 | repl.execute("1+1"); 51 | 52 | spy.intercepted(raw_write, "run", function(args) { 53 | args.type.should.equal("request"); 54 | args.command.should.equal("evaluate"); 55 | args.arguments.expression.should.equal("1+1"); 56 | }); 57 | }); 58 | }); 59 | 60 | it("should evaluate the correct command", function() { 61 | spy.spyOn(raw_write, function() { 62 | repl.execute("foo"); 63 | 64 | spy.intercepted(raw_write, "run", function(args) { 65 | args.arguments.expression.should.equal("foo"); 66 | }); 67 | }); 68 | }); 69 | 70 | it("should loop until a break is given - (it should not raw write the command)", function() { 71 | raw_write.run = function() { 72 | false.should.equal(true); 73 | }; 74 | 75 | repl.execute(".break"); 76 | true.should.equal(true); 77 | }); 78 | 79 | it("should return false when the str == .break", function() { 80 | repl.execute(".break").should.equal(false); 81 | }); 82 | 83 | it("should return false when the str === '.break\n'", function() { 84 | repl.execute(".break\n").should.equal(false); 85 | }); 86 | 87 | it("should return true when the str != '.break'", function() { 88 | repl.execute("foo").should.equal(true); 89 | }); 90 | }); 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /spec/unit/commands/backtrace.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("backtrace", function() { 4 | before_each(function() { 5 | backtrace = ndb.Commands.Backtrace; 6 | }); 7 | 8 | describe("parsing", function() { 9 | it("should not parse with random text", function() { 10 | backtrace.parseCommand("fooasdfasd").should.equal(undefined); 11 | }); 12 | 13 | it("should parse bt", function() { 14 | backtrace.parseCommand("bt")[0].should.equal(backtrace); 15 | }); 16 | 17 | it("should parse backtrace", function() { 18 | backtrace.parseCommand("backtrace")[0].should.equal(backtrace); 19 | }); 20 | }); 21 | 22 | describe("running", function() { 23 | before_each(function() { 24 | raw_write = ndb.Commands.RawWrite; 25 | spy.stub(raw_write, "run"); 26 | }); 27 | 28 | // {"seq":117,"type":"request","command":"backtrace"} 29 | // {"seq":118,"type":"request","command":"backtrace","arguments":{"toFrame":2}} 30 | // {"seq":119,"type":"request","command":"backtrace","arguments":{"fromFrame":0,"toFrame":9}} 31 | it("should send the backtrace command", function() { 32 | spy.spyOn(raw_write, function() { 33 | backtrace.run(); 34 | spy.intercepted(raw_write, "run", function(obj) { 35 | obj.type.should.equal("request"); 36 | obj.command.should.equal("backtrace"); 37 | }); 38 | }); 39 | }); 40 | }); 41 | 42 | describe("outputting the backtrace", function() { 43 | before_each(function() { 44 | fs = require("fs"); 45 | file = fs.readFileSync(__dirname + "/../../fixtures/backtrace_one.js", "ascii"); 46 | json = JSON.parse(file); 47 | }); 48 | 49 | it("should have the calling module", function() { 50 | backtrace.ndb.should.equal(ndb); 51 | }); 52 | 53 | it("should output the stacktrace", function() { 54 | output = fs.readFileSync(__dirname + "/../../fixtures/backtrace_one_output.txt", "ascii"); 55 | 56 | spy.spyOn(node_debugger.Helpers, function() { 57 | backtrace.output(json); 58 | 59 | spy.intercepted(node_debugger.Helpers, "puts", function(str) { 60 | output.length.should.equal(str.length); 61 | output.should.equal(str); 62 | }); 63 | }); 64 | }); 65 | }); 66 | 67 | describe("recognizing the response", function() { 68 | it("should return itself if the command is a backtrace command", function() { 69 | var obj = {command: 'backtrace'}; 70 | backtrace.parseResponse(obj).should.equal(backtrace); 71 | }); 72 | 73 | it("should return undefined if it does not match a backtrace command", function() { 74 | backtrace.parseResponse({command: 'foobar'}).should.not.equal(backtrace); 75 | }); 76 | }); 77 | }); 78 | }); 79 | }); -------------------------------------------------------------------------------- /spec/unit/commands/next.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("next", function() { 4 | before_each(function() { 5 | next = ndb.Commands.Next; 6 | }); 7 | 8 | describe("parsing", function() { 9 | it("should parse 'n' as next", function() { 10 | next.parseCommand("n")[0].should.equal(next); 11 | }); 12 | 13 | it("should be a parse failure with random text", function() { 14 | next.parseCommand("adsfadsf").should.be(undefined); 15 | }); 16 | 17 | it("should parse 'next' as next", function() { 18 | next.parseCommand("next")[0].should.equal(next); 19 | }); 20 | 21 | it("should not have a second argument if not given one", function() { 22 | // var result = next.parseCommand("next"); 23 | // result.length.should.equal(1); 24 | }); 25 | 26 | it("should parse n 10 as [next, 10]", function() { 27 | var result = next.parseCommand("n 10"); 28 | result[0].should.equal(next); 29 | result[1].should.equal("10"); 30 | }); 31 | 32 | it("should use the correct arguments when parsing", function() { 33 | var result = next.parseCommand("n 2"); 34 | result[0].should.equal(next); 35 | result[1].should.equal("2"); 36 | }); 37 | }); 38 | 39 | // {"seq":117,"type":"request","command":"continue"} 40 | // {"seq":118,"type":"request","command":"continue","arguments":{"stepaction":"out"}} 41 | // {"seq":119,"type":"request","command":"continue","arguments":{"stepaction":"next","stepcount":5}} 42 | describe("running", function() { 43 | before_each(function() { 44 | raw_write = ndb.Commands.RawWrite; 45 | spy.stub(raw_write, "run"); 46 | }); 47 | 48 | it("should raw write", function() { 49 | spy.spyOn(raw_write, function() { 50 | next.run(); 51 | spy.intercepted(raw_write, "run").should.be(true); 52 | }); 53 | }); 54 | 55 | it("should raw write with the stepaction next when given no args", function() { 56 | spy.spyOn(raw_write, function() { 57 | next.run(); 58 | 59 | spy.intercepted(raw_write, "run", function(obj) { 60 | obj.type.should.equal("request"); 61 | obj.command.should.equal("continue"); 62 | obj.arguments.stepaction.should.equal("next"); 63 | obj.arguments.stepcount.should.equal(1); 64 | }); 65 | }); 66 | }); 67 | 68 | it("should use the stepcount", function() { 69 | spy.spyOn(raw_write, function() { 70 | next.run(1); 71 | 72 | spy.intercepted(raw_write, "run", function(obj) { 73 | obj.arguments.stepaction.should.equal("next"); 74 | obj.arguments.stepcount.should.equal(1); 75 | }); 76 | }); 77 | }); 78 | 79 | it("should use the correct stepcount", function() { 80 | spy.spyOn(raw_write, function() { 81 | next.run(2); 82 | 83 | spy.intercepted(raw_write, "run", function(obj) { 84 | obj.arguments.stepaction.should.equal("next"); 85 | obj.arguments.stepcount.should.equal(2); 86 | }); 87 | }); 88 | }); 89 | }); 90 | }); 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /spec/unit/message_parser.js: -------------------------------------------------------------------------------- 1 | describe("Node Debugger", function() { 2 | describe("message parser", function() { 3 | before_each(function() { 4 | parser = ndb.MessageParser; 5 | }); 6 | 7 | it("should disregard an invalid header", function() { 8 | var str = "A-Header\r\n\r\n"; 9 | var obj = parser.parse(str); 10 | 11 | obj.headers["A-Header"].should.be(undefined); 12 | }); 13 | 14 | describe("parsing an appropriate message", function() { 15 | it("should have a message header, raw_header, and body", function() { 16 | var message = "A-Header: 1\r\n\r\n", 17 | parsed_message; 18 | 19 | parsed_message = parser.parse(message); 20 | parsed_message.raw_headers.should.equal("A-Header: 1\r\n"); 21 | parsed_message.headers.should.not.equal(null); 22 | parsed_message.body.should.not.equal(null); 23 | }); 24 | 25 | it("should parse the body as after the empty line", function() { 26 | var message = "A-Header: 1\r\n\r\n", 27 | parsed_message; 28 | 29 | parsed_message = parser.parse(message); 30 | parsed_message.body.should.equal(""); 31 | }); 32 | 33 | it("should parse the correct body text", function() { 34 | var message = "A-Header: 1\r\n\r\nfoo", 35 | parsed_message; 36 | 37 | parsed_message = parser.parse(message); 38 | parsed_message.body.should.equal("foo"); 39 | }); 40 | 41 | it("should parse a header into it's components", function() { 42 | var message = "A-Header: 1\r\n\r\n", 43 | parsed_message; 44 | 45 | parsed_message = parser.parse(message); 46 | parsed_message.headers["A-Header"].should.equal("1"); 47 | }); 48 | 49 | it("should parse a different header", function() { 50 | var message = "Foo: 1\r\n\r\n\n", 51 | parsed_message; 52 | 53 | parsed_message = parser.parse(message); 54 | parsed_message.headers["Foo"].should.equal("1"); 55 | }); 56 | 57 | it("should parse a header value appropriately", function() { 58 | var message = "Foo: 2\r\n\r\n\n", 59 | parsed_message; 60 | 61 | parsed_message = parser.parse(message); 62 | parsed_message.headers["Foo"].should.equal("2"); 63 | }); 64 | 65 | it("should parse a header value appropriately where the value has a colon in it", function() { 66 | var message = "Foo: 2: 1", 67 | parsed_message; 68 | 69 | parsed_message = parser.parse(message); 70 | parsed_message.headers["Foo"].should.equal("2: 1"); 71 | }); 72 | 73 | it("should not trim text to the right of the variable", function() { 74 | var message = "Foo: 2: 1 ", 75 | parsed_message; 76 | 77 | parsed_message = parser.parse(message); 78 | parsed_message.headers["Foo"].should.equal("2: 1 "); 79 | }); 80 | 81 | it("should allow no whitespace between the variable + value in the header", function() { 82 | var message = "Foo:2\r\n\r\n\n", 83 | parsed_message; 84 | 85 | parsed_message = parser.parse(message); 86 | parsed_message.headers["Foo"].should.equal("2"); 87 | }); 88 | 89 | it("should allow multiple headers", function() { 90 | var message = "Foo:1\r\nBar:2\r\n\r\n\n", 91 | parsed_message; 92 | 93 | parsed_message = parser.parse(message); 94 | parsed_message.headers["Foo"].should.equal("1"); 95 | parsed_message.headers["Bar"].should.equal("2"); 96 | }); 97 | }); 98 | }); 99 | }); 100 | -------------------------------------------------------------------------------- /spec/unit/event_listeners/source.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("EventListener", function() { 3 | before_each(function() { 4 | event_listner = ndb.EventListener; 5 | ndb.verbose = false; 6 | header = "Content-Length: 1\r\n\r\n"; 7 | }); 8 | 9 | describe("for a source event", function() { 10 | before_each(function() { 11 | event_listner.verbose = false; 12 | 13 | out = ""; 14 | 15 | ndb.Helpers.puts = function(t) { 16 | out += t; 17 | }; 18 | 19 | source = ""; 20 | source += "function() {\n"; 21 | source += " a += 1;\n"; 22 | source += " b += 2;\n"; 23 | source += "}\n"; 24 | 25 | obj = { 26 | "seq": 2, 27 | "type": "response", 28 | "command": "source", 29 | "success": true, 30 | "body": { 31 | "source": source, 32 | "fromLine": 0, 33 | "toLine": 4, 34 | "fromPosition": 0, 35 | "toPosition": 88, 36 | "totalLines": 4 37 | }, 38 | "refs": [], 39 | "running": false 40 | }; 41 | }); 42 | 43 | // { "seq" : , 44 | // "type" : "response", 45 | // "request_seq" : , 46 | // "command" : "source", 47 | // "body" : { "source" : 48 | // "fromLine" : 49 | // "toLine" : 50 | // "fromPosition" : 51 | // "toPosition" : 52 | // "totalLines" : 53 | // } 54 | // "running" : 55 | // "success" : true 56 | // } 57 | 58 | it("should output the source code", function() { 59 | var lines = obj.body.source.split("\n"); 60 | 61 | var expected_output = ""; 62 | expected_output += " 1 " + lines[0] + "\n"; 63 | expected_output += " 2 " + lines[1] + "\n"; 64 | expected_output += " 3 " + lines[2] + "\n"; 65 | expected_output += " 4 " + lines[3]; 66 | 67 | event_listner.receive(SpecHelpers.makeResponse(JSON.stringify(obj))); 68 | 69 | out.should.equal(expected_output); 70 | }); 71 | 72 | it("should output when the content-length header is included", function() { 73 | event_listner.receive(SpecHelpers.makeResponse(JSON.stringify(obj))); 74 | 75 | (/function\(\) \{/).test(out).should.be(true); 76 | }); 77 | 78 | it("should ignore all headers", function() { 79 | var content = JSON.stringify(obj); 80 | var headers = "Content-Length: " + content.length + "\r\nFoo: bar\r\n\r\n"; 81 | 82 | event_listner.receive(headers + content); 83 | 84 | (/function\(\) \{/).test(out).should.be(true); 85 | }); 86 | 87 | it("should display an arrow next to the current breakpoint line", function() { 88 | var lines = obj.body.source.split("\n"); 89 | 90 | ndb.State.lineNumber = 3; 91 | 92 | var expected_output = ""; 93 | expected_output += " 1 " + lines[0] + "\n"; 94 | expected_output += " 2 " + lines[1] + "\n"; 95 | expected_output += "=> 3 " + lines[2] + "\n"; 96 | expected_output += " 4 " + lines[3]; 97 | 98 | event_listner.receive(SpecHelpers.makeResponse(JSON.stringify(obj))); 99 | 100 | out.should.equal(expected_output); 101 | }); 102 | 103 | it("should not display empty undefined lines", function() { 104 | obj.body.fromLine = 9; 105 | obj.body.toLine = 13; 106 | 107 | var lines = obj.body.source.split("\n"); 108 | 109 | var expected_output = ""; 110 | expected_output += " 10 " + lines[0] + "\n"; 111 | expected_output += " 11 " + lines[1] + "\n"; 112 | expected_output += " 12 " + lines[2] + "\n"; 113 | expected_output += " 13 " + lines[3]; 114 | 115 | event_listner.receive(SpecHelpers.makeResponse(JSON.stringify(obj))); 116 | 117 | out.should.equal(expected_output); 118 | }); 119 | }); 120 | }); 121 | }); 122 | -------------------------------------------------------------------------------- /spec/unit/event_listener.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("EventListener", function() { 3 | before_each(function() { 4 | event_listner = ndb.EventListener; 5 | }); 6 | 7 | it("should output the data received in verbose mode", function() { 8 | var text = ""; 9 | 10 | ndb.Helpers.puts = function(t) { 11 | text += t; 12 | }; 13 | 14 | ndb.verbose = true; 15 | event_listner.receive("{}"); 16 | text.should.equal("verbose: <<< {}"); 17 | }); 18 | 19 | it("should not output the data received when not in verbose mode", function() { 20 | var text = ""; 21 | 22 | ndb.Helpers.puts = function(t) { 23 | text += t; 24 | }; 25 | 26 | ndb.verbose = false; 27 | event_listner.receive("{}"); 28 | text.should.equal(""); 29 | }); 30 | 31 | it("should not raise an error if it cannot parse the json given", function() { 32 | var text = ""; 33 | 34 | ndb.Helpers.puts = function(t) { 35 | text += t; 36 | }; 37 | 38 | ndb.verbose = true; 39 | event_listner.receive("foo"); 40 | text.should.equal("verbose: <<< foo"); 41 | }); 42 | 43 | it("should not output the repl text after an unsuccessful parse", function() { 44 | var text = ""; 45 | ndb.Helpers.print = function(t) { 46 | text += t; 47 | }; 48 | 49 | ndb.verbose = true; 50 | event_listner.receive(SpecHelpers.makeResponse("{}")); 51 | text.search(/ndb\> /).should.equal(-1); 52 | }); 53 | 54 | it("should output the repl text after the parse is successful and is a command that is recognized", function() { 55 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"f","sourceLine":0,"sourceColumn":14}}'; 56 | 57 | var text = ""; 58 | ndb.Helpers.print = function(t) { 59 | text += t; 60 | }; 61 | 62 | ndb.verbose = true; 63 | event_listner.receive(SpecHelpers.makeResponse(json)); 64 | text.search(/ndb\> /).should.not.equal(-1); 65 | }); 66 | 67 | it("should output the eval repl text after the parse is successful and is a command that is recognized", function() { 68 | ndb.State.replOn = true; 69 | 70 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"f","sourceLine":0,"sourceColumn":14}}'; 71 | 72 | var text = ""; 73 | ndb.Helpers.print = function(t) { 74 | text += t; 75 | }; 76 | 77 | ndb.verbose = true; 78 | event_listner.receive(SpecHelpers.makeResponse(json)); 79 | text.search(/repl\> /).should.not.equal(-1); 80 | }); 81 | 82 | describe("handling the content-length", function() { 83 | it("should reset the buffer to the empty string when Content-Length: 0", function() { 84 | var message = ""; 85 | 86 | event_listner.receive(SpecHelpers.makeResponse(message)); 87 | event_listner.buffer.should.equal(""); 88 | }); 89 | 90 | describe("when passed in the correct content-length, but more content", function() { 91 | before_each(function() { 92 | obj1 = {"one": "two"}; 93 | obj2 = {"three": "four"}; 94 | 95 | message1 = SpecHelpers.makeResponse(JSON.stringify(obj1)); 96 | message2 = SpecHelpers.makeResponse(JSON.stringify(obj2)); 97 | 98 | text = message1; 99 | text += message2.slice(0, 10); // an arbitrary part of the second message 100 | }); 101 | 102 | it("should parse only the json for the content-length given", function() { 103 | var received_obj = ""; 104 | 105 | event_listner.receive(text, function(obj) { 106 | received_obj = obj; 107 | }); 108 | 109 | _.isEqual(received_obj, obj1).should.be_true; 110 | }); 111 | 112 | it("should keep around the buffer for the next request", function() { 113 | event_listner.receive(text); 114 | event_listner.buffer.should.equal(message2.slice(0, 10)); 115 | }); 116 | }); 117 | 118 | describe("when passed multiple, completed messages", function() { 119 | before_each(function() { 120 | obj1 = {"one": "two"}; 121 | obj2 = {"three": "four"}; 122 | 123 | message1 = SpecHelpers.makeResponse(JSON.stringify(obj1)); 124 | message2 = SpecHelpers.makeResponse(JSON.stringify(obj2)); 125 | 126 | text = message1; 127 | text += message2; 128 | }); 129 | 130 | it("should parse & run all of them", function() { 131 | var received_objects = []; 132 | 133 | event_listner.receive(text, function(obj) { 134 | received_objects.push(obj); 135 | }); 136 | 137 | _.isEqual(received_objects, [obj1, obj2]).should.be_true; 138 | }); 139 | }); 140 | }); 141 | }); 142 | }); 143 | -------------------------------------------------------------------------------- /spec/unit/spec.js: -------------------------------------------------------------------------------- 1 | describe('NodeDebugger', function() { 2 | describe('Client', function() { 3 | before_each(function() { 4 | command_center = { 5 | loop: function() {} 6 | }; 7 | 8 | ndb.commandCenter = command_center; 9 | }); 10 | 11 | describe("starting the debugger itself", function() { 12 | before_each(function() { 13 | connection = {}; 14 | }); 15 | 16 | it("should output welcome text", function() { 17 | var text = ""; 18 | 19 | ndb.Helpers.puts = function(t) { 20 | text += t; 21 | }; 22 | 23 | ndb.startDebugger(connection); 24 | 25 | text.search(/welcome to the node debugger!/).should.not.equal(-1); 26 | }); 27 | 28 | it("should output the prompt", function() { 29 | var text = ""; 30 | 31 | ndb.Helpers.print = function(t) { 32 | text += t; 33 | }; 34 | 35 | ndb.startDebugger(connection); 36 | 37 | text.search(/ndb> /).should.not.equal(-1); 38 | }); 39 | 40 | it("should set the command center's connection", function() { 41 | ndb.startDebugger(connection); 42 | 43 | command_center.connection.should.equal(connection); 44 | }); 45 | 46 | it("should call the commandCenter's loop method", function() { 47 | var loop_called = false; 48 | 49 | command_center.loop = function() { 50 | loop_called = true; 51 | }; 52 | 53 | ndb.startDebugger(connection); 54 | 55 | loop_called.should.be(true); 56 | }); 57 | }); 58 | 59 | describe("starting", function() { 60 | it("should establish the connection on port 5858 and 127.0.0.1", function() { 61 | var port_received = null, 62 | host_received = null; 63 | 64 | tcp.createConnection = function(port, host) { 65 | port_received = port; 66 | host_received = host; 67 | return connection; 68 | }; 69 | 70 | ndb.start(); 71 | port_received.should.equal(5858); 72 | host_received.should.equal("127.0.0.1"); 73 | }); 74 | 75 | it("should establish the connection on the correct port", function() { 76 | var port_received = null; 77 | 78 | ndb.port = 6000; 79 | 80 | tcp.createConnection = function(port) { 81 | port_received = port; 82 | return connection; 83 | }; 84 | 85 | ndb.start(); 86 | port_received.should.equal(6000); 87 | }); 88 | 89 | it("should speak in ascii", function() { 90 | var encoding_received = null; 91 | 92 | connection.setEncoding = function(encoding) { 93 | encoding_received = encoding; 94 | }; 95 | 96 | ndb.start(); 97 | encoding_received.should.equal("ascii"); 98 | }); 99 | 100 | it("should install the connection's event listener", function() { 101 | var called = false; 102 | 103 | connection.addListener = function() { 104 | called = true; 105 | }; 106 | 107 | ndb.start(); 108 | called.should.be(true); 109 | }); 110 | 111 | it("should listen for an end message", function() { 112 | var args = []; 113 | 114 | connection.addListener = function(msg, fun) { 115 | if (msg === "end") { 116 | args.push(msg); 117 | args.push(fun); 118 | } 119 | }; 120 | 121 | ndb.start(); 122 | 123 | args[0].should.equal("end"); 124 | args[1].should.equal(ndb.Helpers.exit); 125 | }); 126 | 127 | it("should listen for a connection error message", function() { 128 | var args = []; 129 | 130 | connection.addListener = function(msg, fun) { 131 | if (msg === "error") { 132 | args.push(msg); 133 | args.push(fun); 134 | } 135 | }; 136 | 137 | ndb.start(); 138 | 139 | args[0].should.equal("error"); 140 | args[1].should.equal(ndb.restart); 141 | }); 142 | 143 | describe("when there is an error", function() { 144 | before_each(function() { 145 | spy.stub(ndb.Helpers, "setTimeout"); 146 | }); 147 | 148 | it("should output that it is about to restart", function() { 149 | spy.spyOn(ndb.Helpers, function() { 150 | ndb.restart(); 151 | 152 | spy.intercepted(ndb.Helpers, "puts", function(text) { 153 | text.should.equal("Could not connect to host 127.0.0.1 on port 5858. Will try again in 2 seconds."); 154 | }); 155 | }); 156 | }); 157 | 158 | it("should use the correct host + port in the error message", function() { 159 | ndb.host = "localhost"; 160 | ndb.port = "2020"; 161 | 162 | spy.spyOn(ndb.Helpers, function() { 163 | ndb.restart(); 164 | 165 | spy.intercepted(ndb.Helpers, "puts", function(text) { 166 | text.should.equal("Could not connect to host localhost on port 2020. Will try again in 2 seconds."); 167 | }); 168 | }); 169 | }); 170 | 171 | it("should call start again in 2 seconds", function() { 172 | spy.spyOn(ndb.Helpers, function() { 173 | ndb.restart(); 174 | spy.intercepted(ndb.Helpers, "setTimeout", ndb.start, 2000); 175 | }); 176 | }); 177 | }); 178 | }); 179 | }); 180 | }); 181 | -------------------------------------------------------------------------------- /spec/unit/commands/evaluate.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("evaluate", function() { 4 | before_each(function() { 5 | evaluator = ndb.Commands.Evaluate; 6 | 7 | raw_write = ndb.Commands.RawWrite; 8 | spy.stub(raw_write, "run"); 9 | }); 10 | 11 | describe("running", function() { 12 | // {"seq":117,"type":"request","command":"evaluate","arguments":{"expression":"1+2"}} 13 | // {"seq":118,"type":"request","command":"evaluate","arguments":{"expression":"a()","frame":3,"disable_break":false}} 14 | // {"seq":119,"type":"request","command":"evaluate","arguments":{"expression":"[o.a,o.b,o.c]","global":true,"disable_break":true}} 15 | it("should raw write", function() { 16 | spy.spyOn(raw_write, function() { 17 | evaluator.run("1+2"); 18 | spy.intercepted(raw_write, "run").should.be(true); 19 | }); 20 | }); 21 | 22 | it("should raw write with the expression", function() { 23 | spy.spyOn(raw_write, function() { 24 | evaluator.run("1+2", true); 25 | spy.intercepted(raw_write, "run", function(obj) { 26 | obj.type.should.equal("request"); 27 | obj.command.should.equal("evaluate"); 28 | obj.arguments.expression.should.equal("1+2"); 29 | }); 30 | }); 31 | }); 32 | 33 | it("should use the correct expression", function() { 34 | spy.spyOn(raw_write, function() { 35 | evaluator.run("a()", true); 36 | 37 | spy.intercepted(raw_write, "run", function(obj) { 38 | obj.arguments.expression.should.equal("a()"); 39 | }); 40 | }); 41 | }); 42 | 43 | it("should inspect when given a false arg", function() { 44 | spy.spyOn(raw_write, function() { 45 | evaluator.run("a()", false); 46 | 47 | spy.intercepted(raw_write, "run", function(obj) { 48 | obj.arguments.expression.should.equal(evaluator.__testing.construct_expression("a()")); 49 | }); 50 | }); 51 | }); 52 | 53 | it("should inspect when given no second arg", function() { 54 | spy.spyOn(raw_write, function() { 55 | evaluator.run("a()"); 56 | 57 | spy.intercepted(raw_write, "run", function(obj) { 58 | obj.arguments.expression.should.equal(evaluator.__testing.construct_expression("a()")); 59 | }); 60 | }); 61 | }); 62 | }); 63 | 64 | // verbose: >>> Content-Length: 73 65 | // verbose: >>> 66 | // verbose: >>> {"type":"request","command":"evaluate","arguments":{"expression":"1+1"}} 67 | // verbose: >>> 68 | // verbose: <<< Content-Length: 147 69 | // verbose: <<< 70 | // verbose: <<< {"seq":4,"type":"response","command":"evaluate","success":true,"body":{"handle":13,"type":"number","value":2,"text":"2"},"refs":[],"running":false} 71 | describe("output", function() { 72 | before_each(function() { 73 | event_listner = ndb.EventListener; 74 | }); 75 | 76 | it("should ouptut the text with an arrow", function() { 77 | var json = '{"seq":4,"type":"response","command":"evaluate","success":true,"body":{"handle":13,"type":"number","value":2,"text":"2"},"refs":[],"running":false}'; 78 | 79 | spy.spyOn(ndb.Helpers, function() { 80 | event_listner.receive(SpecHelpers.makeResponse(json)); 81 | 82 | spy.intercepted(ndb.Helpers, "puts", function(text) { 83 | text.should.equal("=> 2"); 84 | }); 85 | }); 86 | }); 87 | 88 | it("should output the correct text", function() { 89 | var json = '{"seq":4,"type":"response","command":"evaluate","success":true,"body":{"handle":13,"type":"number","value":3,"text":"3"},"refs":[],"running":false}'; 90 | 91 | spy.spyOn(ndb.Helpers, function() { 92 | event_listner.receive(SpecHelpers.makeResponse(json)); 93 | 94 | spy.intercepted(ndb.Helpers, "puts", function(text) { 95 | text.should.equal("=> 3"); 96 | }); 97 | }); 98 | }); 99 | 100 | // verbose: >>> Content-Length: 132 101 | // verbose: >>> 102 | // verbose: >>> {"type":"request","command":"evaluate","arguments":{"expression":"try { require('util').inspect(require); } catch (_) { require }"}} 103 | // verbose: >>> 104 | // verbose: <<< Content-Length: 132 105 | // verbose: <<< 106 | // verbose: <<< {"seq":53,"type":"response","command":"evaluate","success":false,"message":"ReferenceError: require is not defined","running":false} 107 | it("should display an error", function() { 108 | var json = '{"seq":53,"type":"response","command":"evaluate","success":false,"message":"ReferenceError: require is not defined","running":false}'; 109 | 110 | spy.spyOn(ndb.Helpers, function() { 111 | event_listner.receive(SpecHelpers.makeResponse(json)); 112 | 113 | spy.intercepted(ndb.Helpers, "puts", function(text) { 114 | text.should.equal("ReferenceError: require is not defined"); 115 | }); 116 | }); 117 | }); 118 | }); 119 | 120 | describe("parse", function() { 121 | it("should parse 'e' with a statement", function() { 122 | var e = evaluator.parseCommand("e foo"); 123 | e[0].should.equal(evaluator); 124 | e[1].should.equal("foo"); 125 | }); 126 | 127 | it("should parse 'eval' with a statement", function() { 128 | _.isEqual(evaluator.parseCommand("eval foo"), [evaluator, "foo"]).should.be(true); 129 | }); 130 | 131 | it("should render the correct text", function() { 132 | var e = evaluator.parseCommand("e {}"); 133 | e[0].should.equal(evaluator); 134 | e[1].should.equal("{}"); 135 | }); 136 | 137 | it("should parse 'print' with some text", function() { 138 | var e = evaluator.parseCommand("print {}"); 139 | e[0].should.equal(evaluator); 140 | }); 141 | 142 | it("should parse 'p' with some text", function() { 143 | var e = evaluator.parseCommand("p 1"); 144 | e[0].should.equal(evaluator); 145 | }); 146 | }); 147 | }); 148 | }); 149 | }); 150 | -------------------------------------------------------------------------------- /spec/unit/commands/setbreakpoint.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("Commands", function() { 3 | describe("Breakpoint", function() { 4 | before_each(function() { 5 | breakpoint = commands.SetBreakpoint; 6 | 7 | expected_object = { 8 | type: "request", 9 | command: "setbreakpoint", 10 | arguments: { 11 | type: "script", 12 | target: "filename.js", 13 | line: 16 14 | } 15 | }; 16 | 17 | obj = {}; 18 | 19 | spy.stub(ndb.Commands.RawWrite, "run", function(arg) { 20 | obj = arg; 21 | }); 22 | }); 23 | 24 | it("should raw write the json with the filename + fileno", function() { 25 | breakpoint.run({filename: "filename.js", lineNumber: 17}); 26 | _.isEqual(obj, expected_object).should.be(true); 27 | }); 28 | 29 | it('should use the correct filename + lineno', function() { 30 | breakpoint.run({filename: "foo.js", lineNumber: 20}); 31 | obj.arguments.target.should.equal("foo.js"); 32 | obj.arguments.line.should.equal(19); 33 | }); 34 | 35 | it("should use the current filename if none is provided", function() { 36 | ndb.State.filename = "/my/filename.js"; 37 | 38 | breakpoint.run({lineNumber: 20}); 39 | 40 | obj.arguments.target.should.equal("/my/filename.js"); 41 | obj.arguments.line.should.equal(19); 42 | }); 43 | 44 | it("should use the current line number + filename if none provided", function() { 45 | ndb.State.filename = "/foo/bar.js"; 46 | ndb.State.lineNumber = 10; 47 | 48 | breakpoint.run(); 49 | obj.arguments.target.should.equal("/foo/bar.js"); 50 | obj.arguments.line.should.equal(9); 51 | }); 52 | 53 | it("should use line 1 if line number is not set", function() { 54 | breakpoint.run(); 55 | obj.arguments.line.should.equal(0); 56 | }); 57 | 58 | it("should not set the filename if not set (either globally or passed)", function() { 59 | breakpoint.run(); 60 | obj.arguments.target.should.equal(null); 61 | }); 62 | 63 | // The result of the setbreakpoint request is a response with the number of the newly created break point. This break point number is used in the changebreakpoint and clearbreakpoint requests. 64 | // 65 | // { "seq" : , 66 | // "type" : "response", 67 | // "request_seq" : , 68 | // "command" : "setbreakpoint", 69 | // "body" : { "type" : <"function" or "script"> 70 | // "breakpoint" : 71 | // } 72 | // "running" : 73 | // "success" : true 74 | // } 75 | // Here are a couple of examples. 76 | 77 | describe("receiving a breakpoint confirmation", function() { 78 | before_each(function() { 79 | msg = { 80 | type: "response", 81 | request_seq: 1, 82 | command: "setbreakpoint", 83 | body: { 84 | type: "script", 85 | breakpoint: 1 86 | }, 87 | running: false, 88 | success: true 89 | }; 90 | 91 | event_listener = ndb.EventListener; 92 | ndb.verbose = false; 93 | }); 94 | 95 | it("should output the setbreakpoint confirmation", function() { 96 | spy.spyOn(ndb.Helpers, function() { 97 | event_listener.receive(SpecHelpers.makeResponse(JSON.stringify(msg))); 98 | 99 | spy.intercepted(ndb.Helpers, "puts", function(str) { 100 | str.should.equal("Breakpoint 1 set"); 101 | }); 102 | }); 103 | }); 104 | 105 | it("should output the correct breakpoint number", function() { 106 | msg.body.breakpoint = 2; 107 | 108 | spy.spyOn(ndb.Helpers, function() { 109 | event_listener.receive(SpecHelpers.makeResponse(JSON.stringify(msg))); 110 | 111 | spy.intercepted(ndb.Helpers, "puts", function(str) { 112 | str.should.equal("Breakpoint 2 set"); 113 | }); 114 | }); 115 | }); 116 | 117 | // ndb> break 10 118 | // verbose: >>> Content-Length: 140 119 | // verbose: >>> 120 | // verbose: >>> {"type":"request","command":"setbreakpoint","arguments":{"type":"script","target":"/Users/scotttaylor/src/git/ndb/spec/node.js","line":10}} 121 | // verbose: >>> 122 | // verbose: <<< Content-Length: 222 123 | // verbose: <<< 124 | // verbose: <<< {"seq":3,"type":"response","command":"setbreakpoint","success":true,"body":{"type":"scriptName","breakpoint":1,"script_name":"/Users/scotttaylor/src/git/ndb/spec/node.js","line":10,"column":null},"refs":[],"running":false} 125 | it("should output the script_name and line number when given", function() { 126 | msg.body.script_name = "/Users/scotttaylor/src/git/ndb/spec/node.js"; 127 | msg.body.line = 10; 128 | 129 | spy.spyOn(ndb.Helpers, function() { 130 | event_listener.receive(SpecHelpers.makeResponse(JSON.stringify(msg))); 131 | 132 | spy.intercepted(ndb.Helpers, "puts", function(str) { 133 | str.should.equal("Breakpoint 1 set at /Users/scotttaylor/src/git/ndb/spec/node.js:11"); 134 | }); 135 | }); 136 | }); 137 | 138 | it("should use the correct file + line no.", function() { 139 | msg.body.script_name = "/foo.js"; 140 | msg.body.line = 20; 141 | 142 | spy.spyOn(ndb.Helpers, function() { 143 | event_listener.receive(SpecHelpers.makeResponse(JSON.stringify(msg))); 144 | 145 | spy.intercepted(ndb.Helpers, "puts", function(str) { 146 | str.should.equal("Breakpoint 1 set at /foo.js:21"); 147 | }); 148 | }); 149 | }); 150 | 151 | it("should output the filename without a line number if no lineno is given", function() { 152 | msg.body.script_name = "/foo.js"; 153 | 154 | spy.spyOn(ndb.Helpers, function() { 155 | event_listener.receive(SpecHelpers.makeResponse(JSON.stringify(msg))); 156 | 157 | spy.intercepted(ndb.Helpers, "puts", function(str) { 158 | str.should.equal("Breakpoint 1 set at /foo.js"); 159 | }); 160 | }); 161 | }); 162 | }); 163 | }); 164 | }); 165 | }); 166 | -------------------------------------------------------------------------------- /spec/unit/option_parser/option_parser_spec.js: -------------------------------------------------------------------------------- 1 | describe("Option Parsing", function() { 2 | describe("opts", function() { 3 | it("should have opts as the option parser", function() { 4 | var optionParser = ndb.OptionParser.opts; 5 | optionParser["parse"].should.not.be_null; 6 | }); 7 | }); 8 | 9 | describe("parsing and running", function() { 10 | it("should parse the options", function() { 11 | var option_parser = ndb.OptionParser; 12 | var internalOptParseLibrary = option_parser.opts; 13 | 14 | spy.stub(internalOptParseLibrary, "parse"); 15 | 16 | spy.spyOn(internalOptParseLibrary, function() { 17 | option_parser.parse(); 18 | 19 | spy.intercepted(internalOptParseLibrary, "parse", function(options, arguments, auto_generated_help) { 20 | options.should.equal(option_parser.options); 21 | arguments.should.equal(true); 22 | auto_generated_help.should.equal(true); 23 | }); 24 | }); 25 | }); 26 | 27 | it("should call ndb.start()", function() { 28 | spy.spyOn(ndb, function() { 29 | ndb.OptionParser.parse(); 30 | spy.intercepted(ndb, "start"); 31 | }); 32 | }); 33 | }); 34 | 35 | describe("version", function() { 36 | before_each(function() { 37 | spy.stub(ndb.Helpers, "exit"); 38 | 39 | findShortOption = function(option_name) { 40 | var result = null; 41 | 42 | ndb.OptionParser.options.forEach(function(option) { 43 | if (option["short"] === option_name) { 44 | result = option; 45 | } 46 | }); 47 | 48 | return result; 49 | }; 50 | 51 | findLongOption = function(option_name) { 52 | var result = null; 53 | 54 | ndb.OptionParser.options.forEach(function(option) { 55 | if (option["long"] === option_name) { 56 | result = option; 57 | } 58 | }); 59 | 60 | return result; 61 | }; 62 | }); 63 | 64 | describe("version", function() { 65 | it("should parse -v as version", function() { 66 | findShortOption("v").should.not.be_null; 67 | }); 68 | 69 | it("should parse --version", function() { 70 | findLongOption("version").should.not.be_null; 71 | }); 72 | 73 | it("should have a description", function() { 74 | findLongOption("version").description.should.equal("Print version and exit"); 75 | }); 76 | 77 | it("should print out the current version", function() { 78 | spy.spyOn(ndb.Helpers, function() { 79 | findLongOption("version").callback(); 80 | 81 | spy.intercepted(ndb.Helpers, "puts", function(text) { 82 | text.should.equal("ndb version 0.2.3"); 83 | }); 84 | }); 85 | }); 86 | 87 | it("should exit after running", function() { 88 | spy.spyOn(ndb.Helpers, function() { 89 | findLongOption("version").callback(); 90 | 91 | spy.intercepted(ndb.Helpers, "exit"); 92 | }); 93 | }); 94 | }); 95 | 96 | describe("port", function() { 97 | it("should parse -p as port", function() { 98 | findShortOption("p").should.not.be_null; 99 | }); 100 | 101 | it("should parse --port", function() { 102 | findLongOption("port").should.not.be_null; 103 | }); 104 | 105 | it("should have a description", function() { 106 | findLongOption("port").description.should.equal("Set the port (default: 5858)"); 107 | }); 108 | 109 | it("should take a value", function() { 110 | findLongOption("port").value.should.be(true); 111 | }); 112 | 113 | it("should set the value when given", function() { 114 | findLongOption("port").callback(1000); 115 | ndb.port.should.equal(1000); 116 | }); 117 | 118 | it("should convert the arg to an int", function() { 119 | findLongOption("port").callback("1000"); 120 | ndb.port.should.equal(1000); 121 | }); 122 | }); 123 | 124 | describe("host", function() { 125 | it("should parse -h as host", function() { 126 | findShortOption("h").should.not.be_null; 127 | }); 128 | 129 | it("should parse --host", function() { 130 | findLongOption("host").should.not.be_null; 131 | }); 132 | 133 | it("should have a description", function() { 134 | findLongOption("host").description.should.equal("Set the host (default: 127.0.0.1)"); 135 | }); 136 | 137 | it("should take a value", function() { 138 | findLongOption("host").value.should.be(true); 139 | }); 140 | 141 | it("should set the value when given", function() { 142 | findLongOption("host").callback("example.com"); 143 | ndb.host.should.equal("example.com"); 144 | }); 145 | }); 146 | 147 | describe("local", function() { 148 | before_each(function() { 149 | childProcess = ndb.Helpers.childProcess; 150 | spy.stub(childProcess, "spawn"); 151 | spy.stub(ndb.Helpers, "puts"); 152 | }); 153 | 154 | it("should have ndb.Helpers.childProcess as child_process provided by node", function() { 155 | ndb.Helpers.childProcess.should.equal(require("child_process")); 156 | }); 157 | 158 | it("should parse -l as local", function() { 159 | findShortOption("l").should.not.be_null; 160 | }); 161 | 162 | it("should parse --local", function() { 163 | findLongOption("local").should.not.be_null; 164 | }); 165 | 166 | it("should have a description", function() { 167 | findLongOption("local").description.should.equal("Shortcut for running $(node --debug-brk &; ndb) locally."); 168 | }); 169 | 170 | it("should require a value", function() { 171 | findLongOption("local").value.should.be(true); 172 | }); 173 | 174 | it("should shell out to start the script", function() { 175 | spy.spyOn(childProcess, function() { 176 | findLongOption("local").callback("tmp.js"); 177 | 178 | spy.intercepted(childProcess, "spawn", function(name, args) { 179 | name.should.equal("node"); 180 | args[0].should.equal("--debug-brk"); 181 | args[1].should.equal("tmp.js"); 182 | }); 183 | }); 184 | }); 185 | 186 | it("should use the correct script name when shelling out", function() { 187 | spy.spyOn(childProcess, function() { 188 | findLongOption("local").callback("foobar.js"); 189 | 190 | spy.intercepted(childProcess, "spawn", function(name, args) { 191 | name.should.equal("node"); 192 | args[0].should.equal("--debug-brk"); 193 | args[1].should.equal("foobar.js"); 194 | }); 195 | }); 196 | }); 197 | 198 | it("should display the shell command to STDOUT", function() { 199 | spy.spyOn(ndb.Helpers, function() { 200 | findLongOption("local").callback("tmp.js"); 201 | 202 | spy.intercepted(ndb.Helpers, "puts", function(text) { 203 | text.should.equal("Spawning process: `node --debug-brk tmp.js`"); 204 | }); 205 | }); 206 | }); 207 | }); 208 | 209 | describe("verbose", function() { 210 | it("should parse --verbose", function() { 211 | findLongOption("verbose").should.not.be_null; 212 | }); 213 | 214 | it("should have a description", function() { 215 | findLongOption("verbose").description.should.equal("Turn on verbose/debugging mode (default: off)"); 216 | }); 217 | 218 | it("should turn on verbosity", function() { 219 | findLongOption("verbose").callback(); 220 | ndb.verbose.should.be(true); 221 | }); 222 | }); 223 | }); 224 | }); 225 | -------------------------------------------------------------------------------- /spec/unit/event_listeners/break.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("EventListener", function() { 3 | before_each(function() { 4 | event_listner = ndb.EventListener; 5 | ndb.verbose = false; 6 | }); 7 | 8 | describe("for a break event", function() { 9 | before_each(function() { 10 | out = ""; 11 | 12 | ndb.Helpers.puts = function(t) { 13 | out += t; 14 | }; 15 | }); 16 | 17 | // {"seq":117,"type":"event","event":"break","body":{"functionName":"f","sourceLine":1,"sourceColumn":14}} 18 | 19 | it("should output a break event", function() { 20 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"f","sourceLine":0,"sourceColumn":14}}'; 21 | 22 | event_listner.receive(SpecHelpers.makeResponse(json)); 23 | 24 | out.should.equal("Breakpoint at 1:14 (in function f)"); 25 | }); 26 | 27 | it("should buffer the data", function() { 28 | var json = '{"seq":117,"type":"event","event":"break","bo'; 29 | var json2 = 'dy":{"functionName":"f","sourceLine":0,"sourceColumn":14}}'; 30 | 31 | event_listner.receive(SpecHelpers.makeHeader(json + json2) + json); 32 | event_listner.receive(json2); 33 | 34 | out.should.equal("Breakpoint at 1:14 (in function f)"); 35 | }); 36 | 37 | it("should reset the buffer after a successful call", function() { 38 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"f","sourceLine":0,"sourceColumn":14}}'; 39 | 40 | event_listner.receive(SpecHelpers.makeResponse(json)); 41 | 42 | event_listner.buffer.should.equal(""); 43 | }); 44 | 45 | it("should use the correct source column number", function() { 46 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"f","sourceLine":0,"sourceColumn":6}}'; 47 | 48 | event_listner.receive(SpecHelpers.makeResponse(json)); 49 | 50 | out.should.equal("Breakpoint at 1:6 (in function f)"); 51 | }); 52 | 53 | it("should use the correct source line number (first line === 0)", function() { 54 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"f","sourceLine":1,"sourceColumn":14}}'; 55 | 56 | event_listner.receive(SpecHelpers.makeResponse(json)); 57 | 58 | out.should.equal("Breakpoint at 2:14 (in function f)"); 59 | }); 60 | 61 | it("should use the correct function name", function() { 62 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"foo","sourceLine":0,"sourceColumn":14}}'; 63 | 64 | event_listner.receive(SpecHelpers.makeResponse(json)); 65 | 66 | out.should.equal("Breakpoint at 1:14 (in function foo)"); 67 | }); 68 | 69 | // {"seq":117,"type":"event","event":"break","body":{"functionName":"g","scriptData":"test.js","sourceLine":12,"sourceColumn":22,"breakpoints":[1]}} 70 | 71 | it("should output the filename + breakpoints when given", function() { 72 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"g","scriptData":"test.js","sourceLine":12,"sourceColumn":22,"breakpoints":[1]}}'; 73 | 74 | event_listner.receive(SpecHelpers.makeResponse(json)); 75 | 76 | out.should.equal("Breakpoint at test.js:13:22 (in function g - breakpoints: [1])"); 77 | }); 78 | 79 | // {"seq":117,"type":"event","event":"break","body":{"functionName":"h","sourceLine":100,"sourceColumn":12,"breakpoints":[3,5,7]}} 80 | it("should output multiple breakpoints", function() { 81 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"h","sourceLine":100,"sourceColumn":12,"breakpoints":[3,5,7]}}'; 82 | 83 | event_listner.receive(SpecHelpers.makeResponse(json)); 84 | 85 | out.should.equal("Breakpoint at 101:12 (in function h - breakpoints: [3,5,7])"); 86 | }); 87 | 88 | it("should output the sourceline if one is given", function() { 89 | var json = '{"seq":117,"type":"event","event":"break","body":{"functionName":"h","sourceLine":100,"sourceColumn":12,"sourceLineText":"foo() {};"}}'; 90 | 91 | event_listner.receive(SpecHelpers.makeResponse(json)); 92 | 93 | var regex = new RegExp(/foo\(\)\ \{\}\;/); 94 | out.search(regex).should.not.equal(-1); 95 | }); 96 | 97 | it("should pretty format the code", function() { 98 | var json = { 99 | "seq":117, 100 | "type":"event", 101 | "event":"break", 102 | "body": { 103 | "functionName":"f", 104 | "sourceLine":0, 105 | "sourceColumn":14, 106 | "sourceLineText":"foo() {};" 107 | } 108 | }; 109 | 110 | event_listner.receive(SpecHelpers.makeResponse(JSON.stringify(json))); 111 | 112 | out.should.equal("Breakpoint at 1:14 (in function f)\nfoo() {};"); 113 | }); 114 | 115 | // { "seq" : , 116 | // "type" : "event", 117 | // 118 | // "event" : "break", 119 | // "body" : { "invocationText" : , 120 | // "sourceLine" : , 121 | // "sourceColumn" : , 122 | // "sourceLineText" : , 123 | // "script" : { name : 124 | // lineOffset : 125 | // columnOffset : 126 | // lineCount : 127 | // "breakpoints" : 128 | // } 129 | // } 130 | // 131 | // { 132 | // "seq":6, 133 | // "type":"event", 134 | // "event":"break", 135 | // "body":{ 136 | // "invocationText":"#.[anonymous](exports=#, require=function require(path) {\n return loadModule(path, self);\n }, module=#, __filename=/Users/scotttaylor/src/git/ndb/lib/ndb.js, __dirname=/ 137 | // "sourceLine":5, 138 | // "sourceColumn":12, 139 | // "sourceLineText":"ndb.version = \"0.0.1\";", 140 | // "script":{ 141 | // "id":18, 142 | // "name":"/Users/scotttaylor/src/git/ndb/lib/ndb.js", 143 | // "lineOffset":0, 144 | // "columnOffset":0, 145 | // "lineCount":255 146 | // }, 147 | // "breakpoints":[1] 148 | // } 149 | // } 150 | it("should store the filename + line number", function() { 151 | var json = JSON.stringify({ 152 | seq: 1, 153 | type: "event", 154 | event: "break", 155 | body: { 156 | sourceLine: 30, 157 | script: { 158 | name: "foo.js" 159 | } 160 | } 161 | }); 162 | 163 | event_listner.receive(SpecHelpers.makeResponse(json)); 164 | ndb.State.filename.should.equal("foo.js"); 165 | ndb.State.lineNumber.should.equal(31); 166 | }); 167 | 168 | it("should set the line number when it is 0 to 1 (we get back lineOffset, but we want to know it's true line number)", function() { 169 | var json = JSON.stringify({ 170 | seq: 1, 171 | type: "event", 172 | event: "break", 173 | body: { 174 | sourceLine: 0, 175 | script: { 176 | name: "foo.js" 177 | } 178 | } 179 | }); 180 | 181 | event_listner.receive(SpecHelpers.makeResponse(json)); 182 | ndb.State.lineNumber.should.equal(1); 183 | }); 184 | }); 185 | }); 186 | }); 187 | -------------------------------------------------------------------------------- /spec/unit/command_center.js: -------------------------------------------------------------------------------- 1 | describe("NodeDebugger", function() { 2 | describe("CommandCenter", function() { 3 | before_each(function() { 4 | command_center = ndb.CommandCenter; 5 | command_center.commands = ndb.Commands; 6 | }); 7 | 8 | describe("parsing", function() { 9 | before_each(function() { 10 | out = ""; 11 | 12 | ndb.Helpers.puts = function(t) { 13 | out += t; 14 | }; 15 | }); 16 | 17 | it("should return the RawWrite command when matching rw ", function() { 18 | command_center.parse("rw {}").toString().should.equal([ndb.Commands.RawWrite, "{}"].toString()); 19 | }); 20 | 21 | it("should return the RawWrite command when matching any rw ", function() { 22 | command_center.parse("rw {foo: bar}").toString().should.equal([ndb.Commands.RawWrite, "{foo: bar}"].toString()); 23 | }); 24 | 25 | it("should return the help command for 'help'", function() { 26 | command_center.parse("help").toString().should.equal([ndb.Commands.Help].toString()); 27 | }); 28 | 29 | it("should return the help command for 'h'", function() { 30 | command_center.parse("h").toString().should.equal([ndb.Commands.Help].toString()); 31 | }); 32 | 33 | it("should trim a command", function() { 34 | command_center.parse(" rw {foo: bar} ").toString().should.equal([ndb.Commands.RawWrite, "{foo: bar}"].toString()); 35 | }); 36 | 37 | it("should parse l as a list command", function() { 38 | command_center.parse("l")[0].should.equal(ndb.Commands.List); 39 | }); 40 | 41 | it("should parse 'list' as a list command", function() { 42 | command_center.parse("list")[0].should.equal(ndb.Commands.List); 43 | }); 44 | 45 | it("should output the help command if it doesn't parse another command", function() { 46 | command_center.parse("asdfasdfasdfas").toString().should.equal([ndb.Commands.Help].toString()); 47 | }); 48 | 49 | it("should parse 'continue' as a continue command", function() { 50 | command_center.parse("continue")[0].should.equal(ndb.Commands.Continue); 51 | }); 52 | 53 | it("should parse 'c' as a c command", function() { 54 | command_center.parse("c")[0].should.equal(ndb.Commands.Continue); 55 | }); 56 | 57 | it("should parse 'b' as a break command", function() { 58 | command_center.parse("b")[0].should.equal(ndb.Commands.SetBreakpoint); 59 | }); 60 | 61 | it("should parse 'history' as the history command", function() { 62 | command_center.parse("history")[0].should.equal(ndb.Commands.History); 63 | }); 64 | 65 | it("should parse 'break' as a break command", function() { 66 | var result = command_center.parse("break"); 67 | 68 | result[0].should.equal(ndb.Commands.SetBreakpoint); 69 | result[1].filename.should.equal(undefined); 70 | result[1].lineNumber.should.equal(undefined); 71 | }); 72 | 73 | it("should return a list of filename:linenumber when specified in that format", function() { 74 | var result = command_center.parse("break /foo/bar.js:10"); 75 | 76 | result[0].should.equal(ndb.Commands.SetBreakpoint); 77 | result[1].filename.should.equal("/foo/bar.js"); 78 | result[1].lineNumber.should.equal(10); 79 | }); 80 | 81 | it("should return the null + linenumber when only a number is specified", function() { 82 | var result = command_center.parse("break 10"); 83 | 84 | result[0].should.equal(ndb.Commands.SetBreakpoint); 85 | result[1].filename.should.equal(undefined); 86 | result[1].lineNumber.should.equal(10); 87 | }); 88 | 89 | it("should use the b command with arguments", function() { 90 | var result = command_center.parse("b 10"); 91 | 92 | result[0].should.equal(ndb.Commands.SetBreakpoint); 93 | result[1].filename.should.equal(undefined); 94 | result[1].lineNumber.should.equal(10); 95 | }); 96 | 97 | it("should parse version as the version", function() { 98 | var parse = command_center.parse("version"); 99 | parse[0].should.equal(ndb.Commands.Version); 100 | }); 101 | 102 | it("should parse stepin as a step in command", function() { 103 | var parse = command_center.parse("stepin"); 104 | parse[0].should.equal(ndb.Commands.StepIn); 105 | }); 106 | 107 | it("should parse step as a step in command", function() { 108 | var parse = command_center.parse("step"); 109 | parse[0].should.equal(ndb.Commands.StepIn); 110 | }); 111 | 112 | it("should parse s in as a step in command", function() { 113 | var parse = command_center.parse("s"); 114 | parse[0].should.equal(ndb.Commands.StepIn); 115 | }); 116 | 117 | it("should parse 'so' as a step out command", function() { 118 | var parse = command_center.parse("so"); 119 | parse[0].should.equal(ndb.Commands.StepOut); 120 | }); 121 | 122 | it("should parse 'stepout' as a step out command", function() { 123 | var parse = command_center.parse("stepout"); 124 | parse[0].should.equal(ndb.Commands.StepOut); 125 | }); 126 | 127 | it("should parse 'repl'", function() { 128 | var parse = command_center.parse("repl"); 129 | parse[0].should.equal(ndb.Commands.REPL); 130 | }); 131 | }); 132 | 133 | describe("stdinListener", function() { 134 | it("should not run if ndb.State.replOn = true", function() { 135 | ndb.State.replOn = true; 136 | 137 | spy.stub(command_center, "parse", function() { 138 | false.should.equal(true); 139 | }); 140 | 141 | command_center.stdinListener("foo"); 142 | true.should.equal(true); 143 | }); 144 | }); 145 | 146 | describe("loop", function() { 147 | before_each(function() { 148 | opened_stdin = false; 149 | encoding_set_to = undefined; 150 | 151 | mock_process.openStdin = function() { 152 | opened_stdin = true; 153 | 154 | return { 155 | setEncoding: function(val) { 156 | encoding_set_to = val; 157 | }, 158 | addListener: function() {} 159 | }; 160 | }; 161 | }); 162 | 163 | it("should set the connection of the commands object", function() { 164 | command_center.connection = {}; 165 | 166 | command_center.loop(); 167 | command_center.commands.connection.should.equal(command_center.connection); 168 | }); 169 | 170 | it('should open stdin', function() { 171 | command_center.loop(); 172 | opened_stdin.should.be(true); 173 | }); 174 | 175 | it("should set the encoding of stdin to ascii", function() { 176 | command_center.loop(); 177 | encoding_set_to.should.equal("ascii"); 178 | }); 179 | 180 | describe("storing a command", function() { 181 | describe("storing all the commands", function() { 182 | it("should have no commands initially", function() { 183 | ndb.State.history.length.should.equal(0); 184 | }); 185 | 186 | it('should store a command in the history', function() { 187 | command_center.parse("c"); 188 | ndb.State.history.length.should.equal(1); 189 | ndb.State.history[0].should.equal("c"); 190 | }); 191 | 192 | it("should store several commands in the history", function() { 193 | command_center.parse("list"); 194 | command_center.parse("continue"); 195 | 196 | ndb.State.history.length.should.equal(2); 197 | ndb.State.history[0].should.equal("list"); 198 | ndb.State.history[1].should.equal("continue"); 199 | }); 200 | }); 201 | 202 | it('should have the last command as null if no commands have been run', function() { 203 | command_center.lastCommand.should.equal(null); 204 | }); 205 | 206 | it("should store the last command when parsed succesfully", function() { 207 | var continue_cmd = command_center.parse("c"); 208 | command_center.lastCommand.should.equal(continue_cmd); 209 | }); 210 | 211 | it("should reset the command when none found (after a successful parse)", function() { 212 | command_center.parse("c"); 213 | command_center.parse("adfasdfasdfad"); 214 | command_center.lastCommand.should.equal(null); 215 | }); 216 | 217 | it("should run the last command if an empty string is given", function() { 218 | var continue_cmd = command_center.parse("c"); 219 | command_center.parse("").should.equal(continue_cmd); 220 | }); 221 | 222 | it("should not return the last command if there is no last command", function() { 223 | command_center.parse("")[0].should.equal(command_center.parse("asdfadf")[0]); 224 | }); 225 | }); 226 | }); 227 | }); 228 | }); 229 | -------------------------------------------------------------------------------- /lib/vendor/js-opts/opts.js: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Author : Joey Mazzarelli 3 | Email : mazzarelli@gmail.com 4 | Homepage : http://joey.mazzarelli.com/js-opts 5 | Source : http://bitbucket.org/mazzarell/js-opts/ 6 | License : Simplified BSD License 7 | Version : 1.0 8 | 9 | Copyright 2010 Joey Mazzarelli. All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | 14 | 1. Redistributions of source code must retain the above copyright notice, 15 | this list of conditions and the following disclaimer. 16 | 17 | 2. Redistributions in binary form must reproduce the above copyright notice, 18 | this list of conditions and the following disclaimer in the documentation 19 | and/or other materials provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI 'AS IS' AND ANY EXPRESS OR IMPLIED 22 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 24 | EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 29 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | The views and conclusions contained in the software and documentation are those 33 | of the authors and should not be interpreted as representing official policies, 34 | either expressed or implied, of Joey Mazzarelli. 35 | ***************************************************************************/ 36 | 37 | var puts = require('util').puts 38 | , values = {} 39 | , args = {} 40 | , argv = [] 41 | , errors = [] 42 | , descriptors = {opts:[], args:[]}; 43 | 44 | /** 45 | * Add a set of option descriptors, not yet ready to be parsed. 46 | * See exports.parse for description of options object 47 | * 48 | * Additionally, it takes a namespace as an argument, useful for 49 | * building options for a library in addition to the main app. 50 | */ 51 | exports.add = function (options, namespace) { 52 | for (var i=0; i or by including the option; 78 | * { 79 | * long : 'help', 80 | * description : 'Show this help message', 81 | * callback : require('./opts').help, 82 | * } 83 | * 84 | * ===== Arguments Docs ===== 85 | * Arguments are different than options, and simpler. They typically come 86 | * after the options, but the library really doesn't care. Each argument 87 | * can have the form of: 88 | * { 89 | * name : 'script', 90 | * required : true, // default false 91 | * callback : function (value) { ... }, 92 | * } 93 | */ 94 | exports.parse = function (options, params, help) { 95 | 96 | if (params === true) { 97 | help == true; 98 | } else if (!params) { 99 | params = []; 100 | } else { 101 | for (var i=0; i.[anonymous](exports=#, require=function require(path) {\n return loadModule(path, self);\n }, module=#, __filename=/Users/scotttaylor/src/git/ndb/spec/node.js, __dirname=/Users/scotttaylor/src/git/ndb/spec) /Users/scotttaylor/src/git/ndb/spec/node.js line 4 column 1 (position 149)"},{"type":"frame","index":1,"receiver":{"ref":7},"func":{"ref":13},"script":{"ref":15},"constructCall":false,"debuggerFrame":false,"arguments":[{"name":"content","value":{"ref":16}},{"name":"filename","value":{"ref":9}}],"locals":[{"name":"require","value":{"ref":6}},{"name":"dirName","value":{"ref":10}},{"name":"requireAsync","value":{"ref":17}},{"name":"compiledWrapper","value":{"ref":0}},{"name":"wrapper","value":{"ref":18}},{"name":"ext","value":{"ref":19}},{"name":"self","value":{"ref":7}}],"position":9265,"line":383,"column":22,"sourceLineText":" compiledWrapper.apply(self.exports, [self.exports, require, self, filename, dirName]);","scopes":[{"type":1,"index":0},{"type":3,"index":1},{"type":0,"index":2}],"text":"#01 #._compile(content=require.paths.unshift(\"./lib/\");\n\nrequire(\"./jspec_dot_reporter/jspec_dot_report... (length: 1374), filename=/Users/scotttaylor/src/git/ndb/spec/node.js) module line 384 column 23 (position 9266)"},{"type":"frame","index":2,"receiver":{"ref":7},"func":{"ref":21},"script":{"ref":15},"constructCall":false,"debuggerFrame":false,"arguments":[{"name":"filename","value":{"ref":9}}],"locals":[{"name":"e","value":{"ref":3}},{"name":"content","value":{"ref":16}}],"position":9516,"line":392,"column":15,"sourceLineText":" var e = this._compile(content, filename);","scopes":[{"type":1,"index":0},{"type":3,"index":1},{"type":0,"index":2}],"text":"#02 #._loadScriptSync(filename=/Users/scotttaylor/src/git/ndb/spec/node.js) module line 393 column 16 (position 9517)"},{"type":"frame","index":3,"receiver":{"ref":7},"func":{"ref":22},"script":{"ref":15},"constructCall":false,"debuggerFrame":false,"arguments":[{"name":"filename","value":{"ref":9}}],"locals":[],"position":7158,"line":295,"column":9,"sourceLineText":" this._loadScriptSync(filename);","scopes":[{"type":1,"index":0},{"type":3,"index":1},{"type":0,"index":2}],"text":"#03 #.loadSync(filename=/Users/scotttaylor/src/git/ndb/spec/node.js) module line 296 column 10 (position 7159)"},{"type":"frame","index":4,"receiver":{"ref":23},"func":{"ref":24},"script":{"ref":15},"constructCall":false,"debuggerFrame":false,"arguments":[],"locals":[{"name":"cwd","value":{"ref":25}}],"position":11105,"line":458,"column":21,"sourceLineText":" process.mainModule.loadSync(process.argv[1]);","scopes":[{"type":1,"index":0},{"type":3,"index":1},{"type":0,"index":2}],"text":"#04 #.runMain() module line 459 column 22 (position 11106)"},{"type":"frame","index":5,"receiver":{"ref":26},"func":{"ref":27},"script":{"ref":29},"constructCall":false,"debuggerFrame":false,"arguments":[{"name":"process","value":{"ref":30}}],"locals":[{"name":"removed","value":{"ref":31}},{"name":"process","value":{"ref":30}},{"name":"stdout","value":{"ref":3}},{"name":"stdin","value":{"ref":3}},{"name":"nextTickQueue","value":{"ref":32}},{"name":"addTimerListener","value":{"ref":33}},{"name":"evalcxMsg","value":{"ref":3}},{"name":"isSignal","value":{"ref":34}},{"name":"module","value":{"ref":23}}],"position":4676,"line":167,"column":7,"sourceLineText":"module.runMain();","scopes":[{"type":1,"index":0},{"type":0,"index":1}],"text":"#05 [anonymous](process=#) node.js line 168 column 8 (position 4677)"}]},"refs":[{"handle":1,"type":"object","className":"Object","constructorFunction":{"ref":2},"protoObject":{"ref":4},"prototypeObject":{"ref":3},"properties":[],"text":"#"},{"handle":0,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":39},"name":"","inferredName":"","resolved":true,"source":"function (exports, require, module, __filename, __dirname) { require.paths.unshift(\"./lib/\");\n\nrequire(\"./jspec_dot_reporter/jspec_dot_reporter\");\nrequire(\"./espionage/lib/espionage\");\nrequire(\"./underscore/underscore\");\nrequire('./jspec/lib/jspec');\nrequire('./unit/spec.helper');\n\n\nspy = Espionage;\n\nJSpec.include({\n beforeSpec: function() {\n spy.tearDown();\n },\n\n afterSpec: function() {\n spy.tearDown();\n }\n});\n\nJSpec.\n exec(\"spec/unit/node_spec.js\").\n exec('spec/unit/spec.js').\n exec('spec/unit/ndb.js').\n exec('spec/unit/command_center.js').\n exec('spec/unit/event_listener.js').\n exec('spec/unit/event_listeners/break.js').\n exec('spec/unit/event_listeners/source.js').\n exec('spec/unit/commands/raw_write.js').\n exec('spec/unit/commands/help.js').\n exec('spec/unit/commands/list.js').\n exec('spec/unit/commands/continue.js').\n exec('spec/unit/commands/step_in.js').\n exec('spec/unit/commands/setbreakpoint.js').\n exec('spec/unit/commands/quit.js').\n exec('spec/unit/commands/version.js').\n exec('spec/unit/commands/evaluate.js').\n exec('spec/unit/commands/next.js').\n exec('spec/unit/commands/verbose.js').\n exec('spec/unit/commands/backtrace.js').\n exec('spec/unit/commands/scripts.js').\n exec('spec/unit/message_parser.js').\n exec('spec/unit/state.js').\n exec('spec/unit/option_parser/option_parser_spec.js').\n run({ reporter: JSpecDotReporter, fixturePath: 'spec/fixtures' }).\n report();\n\n}","script":{"ref":12},"scriptId":21,"position":10,"line":0,"column":10,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":216},{"name":"length","attributes":7,"propertyType":3,"ref":41},{"name":"name","attributes":7,"propertyType":3,"ref":42},{"name":"prototype","attributes":6,"propertyType":3,"ref":39},{"name":"caller","attributes":7,"propertyType":3,"ref":13}],"text":"function (exports, require, module, __filename, __dirname) { require.paths.unshift(\"./lib/\");\n\nrequire(\"./jspec_dot_reporter/jspec_dot_reporter\");\nrequire(\"./espionage/lib/espionage\");\nrequire(\"./underscore/underscore\");\nrequire('./jspec/lib/jspec');\nrequire('./unit/spec.helper');\n\n\nspy = Espionage;\n\nJSpec.include({\n beforeSpec: function() {\n spy.tearDown();\n },\n\n afterSpec: function() {\n spy.tearDown();\n }\n});\n\nJSpec.\n exec(\"spec/unit/node_spec.js\").\n exec('spec/unit/spec.js').\n exec('spec/unit/ndb.js').\n exec('spec/unit/command_center.js').\n exec('spec/unit/event_listener.js').\n exec('spec/unit/event_listeners/break.js').\n exec('spec/unit/event_listeners/source.js').\n exec('spec/unit/commands/raw_write.js').\n exec('spec/unit/commands/help.js').\n exec('spec/unit/commands/list.js').\n exec('spec/unit/commands/continue.js').\n exec('spec/unit/commands/step_in.js').\n exec('spec/unit/commands/setbreakpoint.js').\n exec('spec/unit/commands/quit.js').\n exec('spec/unit/commands/version.js').\n exec('spec/unit/commands/evaluate.js').\n exec('spec/unit/commands/next.js').\n exec('spec/unit/commands/verbose.js').\n exec('spec/unit/commands/backtrace.js').\n exec('spec/unit/commands/scripts.js').\n exec('spec/unit/message_parser.js').\n exec('spec/unit/state.js').\n exec('spec/unit/option_parser/option_parser_spec.js').\n run({ reporter: JSpecDotReporter, fixturePath: 'spec/fixtures' }).\n report();\n\n}"},{"handle":12,"type":"script","name":"/Users/scotttaylor/src/git/ndb/spec/node.js","id":21,"lineOffset":0,"columnOffset":0,"lineCount":49,"sourceStart":"(function (exports, require, module, __filename, __dirname) { require.paths.unsh","sourceLength":1440,"scriptType":2,"compilationType":0,"context":{"ref":11},"text":"/Users/scotttaylor/src/git/ndb/spec/node.js (lines: 49)"},{"handle":6,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":43},"name":"require","inferredName":"","resolved":true,"source":"function require(path) {\n return loadModule(path, self);\n }","script":{"ref":15},"scriptId":15,"position":8650,"line":362,"column":19,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":5},{"name":"length","attributes":7,"propertyType":3,"ref":44},{"name":"name","attributes":7,"propertyType":3,"ref":45},{"name":"main","propertyType":1,"ref":7},{"name":"paths","propertyType":1,"ref":46},{"name":"prototype","attributes":6,"propertyType":3,"ref":43},{"name":"caller","attributes":7,"propertyType":3,"ref":5},{"name":"registerExtension","propertyType":1,"ref":47},{"name":"async","propertyType":1,"ref":17}],"text":"function require(path) {\n return loadModule(path, self);\n }"},{"handle":7,"type":"object","className":"Object","constructorFunction":{"ref":8},"protoObject":{"ref":20},"prototypeObject":{"ref":3},"properties":[{"name":"filename","propertyType":1,"ref":9},{"name":"children","propertyType":1,"ref":48},{"name":"id","propertyType":1,"ref":49},{"name":"exited","propertyType":1,"ref":50},{"name":"loaded","propertyType":1,"ref":50},{"name":"moduleCache","propertyType":1,"ref":51},{"name":"parent","propertyType":1,"ref":3},{"name":"exports","propertyType":1,"ref":1}],"text":"#"},{"handle":9,"type":"string","value":"/Users/scotttaylor/src/git/ndb/spec/node.js","length":43,"text":"/Users/scotttaylor/src/git/ndb/spec/node.js"},{"handle":10,"type":"string","value":"/Users/scotttaylor/src/git/ndb/spec","length":35,"text":"/Users/scotttaylor/src/git/ndb/spec"},{"handle":13,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":52},"name":"","inferredName":"Module._compile","resolved":true,"source":"function (content, filename) {\n var self = this;\n // remove shebang\n content = content.replace(/^\\#\\!.*/, '');\n\n // Compile content if needed\n var ext = path.extname(filename);\n if (extensionCache[ext]) {\n content = extensionCache[ext](content);\n }\n\n function requireAsync (url, cb) {\n loadModule(url, self, cb);\n }\n\n function require (path) {\n return loadModule(path, self);\n }\n\n require.paths = modulePaths;\n require.async = requireAsync;\n require.main = process.mainModule;\n require.registerExtension = registerExtension;\n\n\n if ('string' === typeof content) {\n // create wrapper function\n var wrapper = \"(function (exports, require, module, __filename, __dirname) { \"\n + content\n + \"\\n});\";\n\n var compiledWrapper = process.compile(wrapper, filename);\n var dirName = path.dirname(filename);\n if (filename === process.argv[1]) {\n process.checkBreak();\n }\n compiledWrapper.apply(self.exports, [self.exports, require, self, filename, dirName]);\n } else {\n self.exports = content;\n }\n}","script":{"ref":15},"scriptId":15,"position":8308,"line":347,"column":37,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":217},{"name":"length","attributes":7,"propertyType":3,"ref":54},{"name":"name","attributes":7,"propertyType":3,"ref":42},{"name":"prototype","attributes":6,"propertyType":3,"ref":52},{"name":"caller","attributes":7,"propertyType":3,"ref":21}],"text":"function (content, filename) {\n var self = this;\n // remove shebang\n content = content.replace(/^\\#\\!.*/, '');\n\n // Compile content if needed\n var ext = path.extname(filename);\n if (extensionCache[ext]) {\n content = extensionCache[ext](content);\n }\n\n function requireAsync (url, cb) {\n loadModule(url, self, cb);\n }\n\n function require (path) {\n return loadModule(path, self);\n }\n\n require.paths = modulePaths;\n require.async = requireAsync;\n require.main = process.mainModule;\n require.registerExtension = registerExtension;\n\n\n if ('string' === typeof content) {\n // create wrapper function\n var wrapper = \"(function (exports, require, module, __filename, __dirname) { \"\n + content\n + \"\\n});\";\n\n var compiledWrapper = process.compile(wrapper, filename);\n var dirName = path.dirname(filename);\n if (filename === process.argv[1]) {\n process.checkBreak();\n }\n compiledWrapper.apply(self.exports, [self.exports, require, self, filename, dirName]);\n } else {\n self.exports = content;\n }\n}"},{"handle":15,"type":"script","name":"module","id":15,"lineOffset":0,"columnOffset":0,"lineCount":462,"sourceStart":"(function (exports) {/**********************************************************","sourceLength":11137,"scriptType":2,"compilationType":0,"context":{"ref":14},"text":"module (lines: 462)"},{"handle":16,"type":"string","value":"require.paths.unshift(\"./lib/\");\n\nrequire(\"./jspec_dot_reporter/jspec_dot_report... (length: 1374)","fromIndex":0,"toIndex":80,"length":1374,"text":"require.paths.unshift(\"./lib/\");\n\nrequire(\"./jspec_dot_reporter/jspec_dot_report... (length: 1374)"},{"handle":17,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":55},"name":"requireAsync","inferredName":"","resolved":true,"source":"function requireAsync(url, cb) {\n loadModule(url, self, cb);\n }","script":{"ref":15},"scriptId":15,"position":8583,"line":358,"column":24,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":5},{"name":"length","attributes":7,"propertyType":3,"ref":54},{"name":"name","attributes":7,"propertyType":3,"ref":56},{"name":"prototype","attributes":6,"propertyType":3,"ref":55},{"name":"caller","attributes":7,"propertyType":3,"ref":5}],"text":"function requireAsync(url, cb) {\n loadModule(url, self, cb);\n }"},{"handle":18,"type":"string","value":"(function (exports, require, module, __filename, __dirname) { require.paths.unsh... (length: 1440)","fromIndex":0,"toIndex":80,"length":1440,"text":"(function (exports, require, module, __filename, __dirname) { require.paths.unsh... (length: 1440)"},{"handle":19,"type":"string","value":".js","length":3,"text":".js"},{"handle":21,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":57},"name":"","inferredName":"Module._loadScriptSync","resolved":true,"source":"function (filename) {\n var content = requireNative('fs').readFileSync(filename);\n var e = this._compile(content, filename);\n if (e) {\n throw e;\n } else {\n this.loaded = true;\n }\n}","script":{"ref":15},"scriptId":15,"position":9428,"line":390,"column":44,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":218},{"name":"length","attributes":7,"propertyType":3,"ref":44},{"name":"name","attributes":7,"propertyType":3,"ref":42},{"name":"prototype","attributes":6,"propertyType":3,"ref":57},{"name":"caller","attributes":7,"propertyType":3,"ref":22}],"text":"function (filename) {\n var content = requireNative('fs').readFileSync(filename);\n var e = this._compile(content, filename);\n if (e) {\n throw e;\n } else {\n this.loaded = true;\n }\n}"},{"handle":3,"type":"undefined","text":"undefined"},{"handle":22,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":59},"name":"","inferredName":"Module.loadSync","resolved":true,"source":"function (filename) {\n ;\n\n process.assert(!this.loaded);\n this.filename = filename;\n\n if (filename.match(/\\.node$/)) {\n this._loadObjectSync(filename);\n } else {\n this._loadScriptSync(filename);\n }\n}","script":{"ref":15},"scriptId":15,"position":6988,"line":286,"column":37,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":219},{"name":"length","attributes":7,"propertyType":3,"ref":44},{"name":"name","attributes":7,"propertyType":3,"ref":42},{"name":"prototype","attributes":6,"propertyType":3,"ref":59},{"name":"caller","attributes":7,"propertyType":3,"ref":24}],"text":"function (filename) {\n ;\n\n process.assert(!this.loaded);\n this.filename = filename;\n\n if (filename.match(/\\.node$/)) {\n this._loadObjectSync(filename);\n } else {\n this._loadScriptSync(filename);\n }\n}"},{"handle":23,"type":"object","className":"Object","constructorFunction":{"ref":2},"protoObject":{"ref":4},"prototypeObject":{"ref":3},"properties":[{"name":"runMain","propertyType":1,"ref":24},{"name":"requireNative","propertyType":1,"ref":61}],"text":"#"},{"handle":24,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":62},"name":"","inferredName":"exports.runMain","resolved":true,"source":"function () {\n var cwd = process.cwd();\n\n // Make process.argv[0] and process.argv[1] into full paths.\n if (process.argv[0].indexOf('/') > 0) {\n process.argv[0] = path.join(cwd, process.argv[0]);\n }\n\n if (process.argv[1].charAt(0) != \"/\" && !(/^http:\\/\\//).exec(process.argv[1])) {\n process.argv[1] = path.join(cwd, process.argv[1]);\n }\n\n // Load the main module--the command line argument.\n process.mainModule = new Module(\".\");\n process.mainModule.loadSync(process.argv[1]);\n}","script":{"ref":15},"scriptId":15,"position":10649,"line":444,"column":27,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":220},{"name":"length","attributes":7,"propertyType":3,"ref":64},{"name":"name","attributes":7,"propertyType":3,"ref":42},{"name":"prototype","attributes":6,"propertyType":3,"ref":62},{"name":"caller","attributes":7,"propertyType":3,"ref":27}],"text":"function () {\n var cwd = process.cwd();\n\n // Make process.argv[0] and process.argv[1] into full paths.\n if (process.argv[0].indexOf('/') > 0) {\n process.argv[0] = path.join(cwd, process.argv[0]);\n }\n\n if (process.argv[1].charAt(0) != \"/\" && !(/^http:\\/\\//).exec(process.argv[1])) {\n process.argv[1] = path.join(cwd, process.argv[1]);\n }\n\n // Load the main module--the command line argument.\n process.mainModule = new Module(\".\");\n process.mainModule.loadSync(process.argv[1]);\n}"},{"handle":25,"type":"string","value":"/Users/scotttaylor/src/git/ndb","length":30,"text":"/Users/scotttaylor/src/git/ndb"},{"handle":26,"type":"object","className":"global","constructorFunction":{"ref":2},"protoObject":{"ref":35},"prototypeObject":{"ref":3},"properties":[],"text":"#"},{"handle":27,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":65},"name":"","inferredName":"","resolved":true,"source":"function (process) {\n\nprocess.global.process = process;\nprocess.global.global = process.global;\nglobal.GLOBAL = global;\n\n/** deprecation errors ************************************************/\n\nfunction removed (reason) {\n return function () {\n throw new Error(reason)\n }\n}\n\nGLOBAL.__module = removed(\"'__module' has been renamed to 'module'\");\nGLOBAL.include = removed(\"include(module) has been removed. Use require(module)\");\nGLOBAL.puts = removed(\"puts() has moved. Use require('util') to bring it back.\");\nGLOBAL.print = removed(\"print() has moved. Use require('util') to bring it back.\");\nGLOBAL.p = removed(\"p() has moved. Use require('util') to bring it back.\");\nprocess.debug = removed(\"process. has moved. Use require('util') to bring it back.\");\nprocess.error = removed(\"process.error() has moved. Use require('util') to bring it back.\");\nprocess.watchFile = removed(\"process.watchFile() has moved to fs.watchFile()\");\nprocess.unwatchFile = removed(\"process.unwatchFile() has moved to fs.unwatchFile()\");\nprocess.mixin = removed('process.mixin() has been removed.');\nprocess.createChildProcess = removed(\"childProcess API has changed. See doc/api.txt.\");\nprocess.inherits = removed(\"process.inherits() has moved to sys.inherits.\");\n\nprocess.assert = function (x, msg) {\n if (!x) throw new Error(msg || \"assertion error\");\n};\n\nvar evalcxMsg;\nprocess.evalcx = function () {\n if (!evalcxMsg) {\n process.binding('stdio').writeError(evalcxMsg =\n \"process.evalcx is deprecated. Use Script.runInNewContext instead.\\n\");\n }\n return process.binding('evals').Script\n .runInNewContext.apply(null, arguments);\n};\n\n// nextTick()\n\nvar nextTickQueue = [];\n\nprocess._tickCallback = function () {\n for (var l = nextTickQueue.length; l; l--) {\n nextTickQueue.shift()();\n }\n};\n\nprocess.nextTick = function (callback) {\n nextTickQueue.push(callback);\n process._needTickCallback();\n};\n\n// Module System\nvar module = {}\nprocess.compile(\"(function (exports) {\"\n + process.binding(\"natives\").module\n + \"\\n})\", \"module\")(module);\n\n// TODO: make sure that event module gets loaded here once it's\n// factored out of module.js\n// module.require(\"events\");\n\n// Signal Handlers\n\nfunction isSignal (event) {\n return event.slice(0, 3) === 'SIG' && process.hasOwnProperty(event);\n};\n\nprocess.addListener(\"newListener\", function (event) {\n if (isSignal(event) && process.listeners(event).length === 0) {\n var b = process.binding('signal_watcher');\n var w = new b.SignalWatcher(process[event]);\n w.addListener(\"signal\", function () {\n process.emit(event);\n });\n }\n});\n\n// Timers\nfunction addTimerListener (callback) {\n var timer = this;\n // Special case the no param case to avoid the extra object creation.\n if (arguments.length > 2) {\n var args = Array.prototype.slice.call(arguments, 2);\n timer.callback = function () { callback.apply(timer, args); };\n } else {\n timer.callback = callback;\n }\n}\n\nglobal.setTimeout = function (callback, after) {\n var timer = new process.Timer();\n addTimerListener.apply(timer, arguments);\n timer.start(after, 0);\n return timer;\n};\n\nglobal.setInterval = function (callback, repeat) {\n var timer = new process.Timer();\n addTimerListener.apply(timer, arguments);\n timer.start(repeat, repeat);\n return timer;\n};\n\nglobal.clearTimeout = function (timer) {\n if (timer instanceof process.Timer) {\n timer.stop();\n }\n};\n\nglobal.clearInterval = global.clearTimeout;\n\nvar stdout;\nprocess.__defineGetter__('stdout', function () {\n if (stdout) return stdout;\n\n var binding = process.binding('stdio'),\n net = module.requireNative('net'),\n fs = module.requireNative('fs'),\n fd = binding.stdoutFD;\n\n if (binding.isStdoutBlocking()) {\n stdout = new fs.WriteStream(null, {fd: fd});\n } else {\n stdout = new net.Stream(fd);\n // FIXME Should probably have an option in net.Stream to create a stream from\n // an existing fd which is writable only. But for now we'll just add\n // this hack and set the `readable` member to false.\n // Test: ./node test/fixtures/echo.js < /etc/passwd\n stdout.readable = false;\n }\n\n return stdout;\n});\n\nvar stdin;\nprocess.openStdin = function () {\n if (stdin) return stdin;\n\nvar binding = process.binding('stdio'),\n net = module.requireNative('net'),\n fs = module.requireNative('fs'),\n fd = binding.openStdin();\n\n if (binding.isStdinBlocking()) {\n stdin = new net.Stream(fd);\n stdin.readable = true;\n } else {\n stdin = new fs.ReadStream(null, {fd: fd});\n }\n\n stdin.resume();\n\n return stdin;\n};\n\n\nprocess.exit = function (code) {\n process.emit(\"exit\");\n process.reallyExit(code);\n};\n\n\nmodule.runMain();\n\n\n// All our arguments are loaded. We've evaluated all of the scripts. We\n// might even have created TCP servers. Now we enter the main eventloop. If\n// there are no watchers on the loop (except for the ones that were\n// ev_unref'd) then this function exits. As long as there are active\n// watchers, it blocks.\nprocess.loop();\n\nprocess.emit(\"exit\");\n\n}","script":{"ref":29},"scriptId":14,"position":10,"line":0,"column":10,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":221},{"name":"length","attributes":7,"propertyType":3,"ref":44},{"name":"name","attributes":7,"propertyType":3,"ref":42},{"name":"prototype","attributes":6,"propertyType":3,"ref":65},{"name":"caller","attributes":7,"propertyType":3,"ref":5}],"text":"function (process) {\n\nprocess.global.process = process;\nprocess.global.global = process.global;\nglobal.GLOBAL = global;\n\n/** deprecation errors ************************************************/\n\nfunction removed (reason) {\n return function () {\n throw new Error(reason)\n }\n}\n\nGLOBAL.__module = removed(\"'__module' has been renamed to 'module'\");\nGLOBAL.include = removed(\"include(module) has been removed. Use require(module)\");\nGLOBAL.puts = removed(\"puts() has moved. Use require('util') to bring it back.\");\nGLOBAL.print = removed(\"print() has moved. Use require('util') to bring it back.\");\nGLOBAL.p = removed(\"p() has moved. Use require('util') to bring it back.\");\nprocess.debug = removed(\"process. has moved. Use require('util') to bring it back.\");\nprocess.error = removed(\"process.error() has moved. Use require('util') to bring it back.\");\nprocess.watchFile = removed(\"process.watchFile() has moved to fs.watchFile()\");\nprocess.unwatchFile = removed(\"process.unwatchFile() has moved to fs.unwatchFile()\");\nprocess.mixin = removed('process.mixin() has been removed.');\nprocess.createChildProcess = removed(\"childProcess API has changed. See doc/api.txt.\");\nprocess.inherits = removed(\"process.inherits() has moved to sys.inherits.\");\n\nprocess.assert = function (x, msg) {\n if (!x) throw new Error(msg || \"assertion error\");\n};\n\nvar evalcxMsg;\nprocess.evalcx = function () {\n if (!evalcxMsg) {\n process.binding('stdio').writeError(evalcxMsg =\n \"process.evalcx is deprecated. Use Script.runInNewContext instead.\\n\");\n }\n return process.binding('evals').Script\n .runInNewContext.apply(null, arguments);\n};\n\n// nextTick()\n\nvar nextTickQueue = [];\n\nprocess._tickCallback = function () {\n for (var l = nextTickQueue.length; l; l--) {\n nextTickQueue.shift()();\n }\n};\n\nprocess.nextTick = function (callback) {\n nextTickQueue.push(callback);\n process._needTickCallback();\n};\n\n// Module System\nvar module = {}\nprocess.compile(\"(function (exports) {\"\n + process.binding(\"natives\").module\n + \"\\n})\", \"module\")(module);\n\n// TODO: make sure that event module gets loaded here once it's\n// factored out of module.js\n// module.require(\"events\");\n\n// Signal Handlers\n\nfunction isSignal (event) {\n return event.slice(0, 3) === 'SIG' && process.hasOwnProperty(event);\n};\n\nprocess.addListener(\"newListener\", function (event) {\n if (isSignal(event) && process.listeners(event).length === 0) {\n var b = process.binding('signal_watcher');\n var w = new b.SignalWatcher(process[event]);\n w.addListener(\"signal\", function () {\n process.emit(event);\n });\n }\n});\n\n// Timers\nfunction addTimerListener (callback) {\n var timer = this;\n // Special case the no param case to avoid the extra object creation.\n if (arguments.length > 2) {\n var args = Array.prototype.slice.call(arguments, 2);\n timer.callback = function () { callback.apply(timer, args); };\n } else {\n timer.callback = callback;\n }\n}\n\nglobal.setTimeout = function (callback, after) {\n var timer = new process.Timer();\n addTimerListener.apply(timer, arguments);\n timer.start(after, 0);\n return timer;\n};\n\nglobal.setInterval = function (callback, repeat) {\n var timer = new process.Timer();\n addTimerListener.apply(timer, arguments);\n timer.start(repeat, repeat);\n return timer;\n};\n\nglobal.clearTimeout = function (timer) {\n if (timer instanceof process.Timer) {\n timer.stop();\n }\n};\n\nglobal.clearInterval = global.clearTimeout;\n\nvar stdout;\nprocess.__defineGetter__('stdout', function () {\n if (stdout) return stdout;\n\n var binding = process.binding('stdio'),\n net = module.requireNative('net'),\n fs = module.requireNative('fs'),\n fd = binding.stdoutFD;\n\n if (binding.isStdoutBlocking()) {\n stdout = new fs.WriteStream(null, {fd: fd});\n } else {\n stdout = new net.Stream(fd);\n // FIXME Should probably have an option in net.Stream to create a stream from\n // an existing fd which is writable only. But for now we'll just add\n // this hack and set the `readable` member to false.\n // Test: ./node test/fixtures/echo.js < /etc/passwd\n stdout.readable = false;\n }\n\n return stdout;\n});\n\nvar stdin;\nprocess.openStdin = function () {\n if (stdin) return stdin;\n\nvar binding = process.binding('stdio'),\n net = module.requireNative('net'),\n fs = module.requireNative('fs'),\n fd = binding.openStdin();\n\n if (binding.isStdinBlocking()) {\n stdin = new net.Stream(fd);\n stdin.readable = true;\n } else {\n stdin = new fs.ReadStream(null, {fd: fd});\n }\n\n stdin.resume();\n\n return stdin;\n};\n\n\nprocess.exit = function (code) {\n process.emit(\"exit\");\n process.reallyExit(code);\n};\n\n\nmodule.runMain();\n\n\n// All our arguments are loaded. We've evaluated all of the scripts. We\n// might even have created TCP servers. Now we enter the main eventloop. If\n// there are no watchers on the loop (except for the ones that were\n// ev_unref'd) then this function exits. As long as there are active\n// watchers, it blocks.\nprocess.loop();\n\nprocess.emit(\"exit\");\n\n}"},{"handle":29,"type":"script","name":"node.js","id":14,"lineOffset":0,"columnOffset":0,"lineCount":180,"sourceStart":"(function (process) {\n\nprocess.global.process = process;\nprocess.global.global =","sourceLength":5042,"scriptType":2,"compilationType":0,"context":{"ref":28},"text":"node.js (lines: 180)"},{"handle":30,"type":"object","className":"EventEmitter","constructorFunction":{"ref":36},"protoObject":{"ref":67},"prototypeObject":{"ref":3},"properties":[{"name":"ENOMSG","ref":68},{"name":"setuid","ref":69},{"name":"SIGQUIT","ref":70},{"name":"S_IXOTH","ref":44},{"name":"compile","ref":71},{"name":"EISCONN","ref":72},{"name":"EOVERFLOW","ref":73},{"name":"platform","ref":74},{"name":"EIO","ref":41},{"name":"EAFNOSUPPORT","ref":75},{"name":"O_WRONLY","ref":44},{"name":"SIGFPE","ref":76},{"name":"SIGXCPU","ref":77},{"name":"ENODATA","ref":78},{"name":"argv","ref":79},{"name":"EPROTO","ref":80},{"name":"ENAMETOOLONG","ref":81},{"name":"S_IRWXO","ref":82},{"name":"ENOEXEC","ref":76},{"name":"O_EXCL","ref":83},{"name":"dlopen","ref":84},{"name":"_byteLength","ref":85},{"name":"SIGSEGV","ref":86},{"name":"EPROTONOSUPPORT","ref":87},{"name":"cwd","ref":88},{"name":"ENOLCK","ref":89},{"name":"O_SYNC","ref":90},{"name":"ECANCELED","ref":91},{"name":"ECONNABORTED","ref":92},{"name":"SIGINT","ref":54},{"name":"S_IRUSR","ref":93},{"name":"EBADMSG","ref":94},{"name":"error","ref":95},{"name":"O_RDWR","ref":54},{"name":"O_NOFOLLOW","ref":93},{"name":"SIGXFSZ","ref":96},{"name":"EIDRM","ref":97},{"name":"ENOSYS","ref":98},{"name":"S_IFBLK","ref":99},{"name":"SIGIOT","ref":100},{"name":"getuid","ref":101},{"name":"ENV","ref":102},{"name":"S_IWOTH","ref":54},{"name":"SIGUSR2","ref":103},{"name":"nextTick","ref":104},{"name":"SIGURG","ref":105},{"name":"ETIMEDOUT","ref":106},{"name":"ETXTBSY","ref":107},{"name":"S_IFIFO","ref":108},{"name":"EMLINK","ref":103},{"name":"SIGTTIN","ref":109},{"name":"S_IWGRP","ref":105},{"name":"S_IFCHR","ref":110},{"name":"loop","ref":111},{"name":"SIGKILL","ref":112},{"name":"S_IRWXG","ref":72},{"name":"S_IXGRP","ref":76},{"name":"EWOULDBLOCK","ref":113},{"name":"SIGHUP","ref":44},{"name":"reallyExit","ref":114},{"name":"ENOTSOCK","ref":115},{"name":"assert","ref":116},{"name":"SIGPROF","ref":117},{"name":"debug","ref":118},{"name":"EOPNOTSUPP","ref":119},{"name":"EEXIST","ref":120},{"name":"SIGALRM","ref":121},{"name":"ESRCH","ref":70},{"name":"EFAULT","ref":121},{"name":"EPROTOTYPE","ref":122},{"name":"SIGSYS","ref":123},{"name":"checkBreak","ref":124},{"name":"stdout","propertyType":3,"ref":3},{"name":"EDEADLK","ref":86},{"name":"ENOTTY","ref":96},{"name":"_tickCallback","ref":125},{"name":"S_IRGRP","ref":126},{"name":"Timer","ref":127},{"name":"ELOOP","ref":128},{"name":"SIGTRAP","ref":41},{"name":"S_IXUSR","ref":129},{"name":"O_APPEND","ref":76},{"name":"EDOM","ref":130},{"name":"O_TRUNC","ref":131},{"name":"O_DIRECTORY","ref":132},{"name":"Promise","ref":133},{"name":"ENOTCONN","ref":134},{"name":"ESTALE","ref":135},{"name":"memoryUsage","ref":136},{"name":"openStdin","ref":137},{"name":"EBUSY","ref":105},{"name":"EPERM","ref":44},{"name":"installPrefix","ref":138},{"name":"SIGTSTP","ref":139},{"name":"ENOTEMPTY","ref":140},{"name":"unloop","ref":141},{"name":"SIGABRT","ref":100},{"name":"mixin","ref":142},{"name":"unwatchFile","ref":143},{"name":"EFBIG","ref":117},{"name":"ECONNRESET","ref":144},{"name":"version","ref":145},{"name":"setgid","ref":146},{"name":"EINPROGRESS","ref":147},{"name":"EADDRNOTAVAIL","ref":148},{"name":"EINTR","ref":149},{"name":"evalcx","ref":150},{"name":"kill","ref":151},{"name":"pid","ref":152},{"name":"ENETUNREACH","ref":153},{"name":"SIGCHLD","ref":154},{"name":"ESPIPE","ref":155},{"name":"EALREADY","ref":156},{"name":"O_CREAT","ref":157},{"name":"EV_MAXPRI","ref":54},{"name":"global","ref":26},{"name":"mainModule","ref":7},{"name":"EROFS","ref":158},{"name":"SIGILL","ref":149},{"name":"EMULTIHOP","ref":159},{"name":"ETIME","ref":160},{"name":"ENOENT","ref":54},{"name":"S_IWUSR","ref":90},{"name":"env","ref":102},{"name":"EMSGSIZE","ref":161},{"name":"SIGTTOU","ref":162},{"name":"ENOSR","ref":163},{"name":"EMFILE","ref":77},{"name":"SIGWINCH","ref":164},{"name":"SIGUSR1","ref":158},{"name":"ENXIO","ref":100},{"name":"S_IFREG","ref":165},{"name":"SIGTERM","ref":166},{"name":"EventEmitter","ref":36},{"name":"ECHILD","ref":167},{"name":"EHOSTUNREACH","ref":168},{"name":"inherits","ref":169},{"name":"ENOTSUP","ref":170},{"name":"EADDRINUSE","ref":171},{"name":"S_IROTH","ref":149},{"name":"EBADF","ref":112},{"name":"S_IRWXU","ref":172},{"name":"EXDEV","ref":139},{"name":"ECONNREFUSED","ref":173},{"name":"ENOSTR","ref":174},{"name":"SIGVTALRM","ref":107},{"name":"S_IFSOCK","ref":175},{"name":"SIGPIPE","ref":176},{"name":"chdir","ref":177},{"name":"EDESTADDRREQ","ref":178},{"name":"ERANGE","ref":179},{"name":"exit","ref":180},{"name":"EILSEQ","ref":181},{"name":"ENOMEM","ref":123},{"name":"EPIPE","ref":126},{"name":"ARGV","ref":79},{"name":"EISDIR","ref":109},{"name":"SIGBUS","ref":167},{"name":"_needTickCallback","ref":182},{"name":"SIGCONT","ref":183},{"name":"SIGSTOP","ref":120},{"name":"EAGAIN","ref":113},{"name":"ENOPROTOOPT","ref":184},{"name":"ENETDOWN","ref":185},{"name":"ENETRESET","ref":186},{"name":"O_NOCTTY","ref":187},{"name":"createChildProcess","ref":188},{"name":"binding","ref":189},{"name":"ENFILE","ref":190},{"name":"ENOLINK","ref":191},{"name":"ENOTDIR","ref":154},{"name":"EINVAL","ref":162},{"name":"O_RDONLY","ref":64},{"name":"IOWatcher","ref":192},{"name":"EV_MINPRI","ref":193},{"name":"getgid","ref":194},{"name":"ENOSPC","ref":164},{"name":"ENOBUFS","ref":195},{"name":"SIGIO","ref":190},{"name":"EDQUOT","ref":196},{"name":"EACCES","ref":176},{"name":"S_IFDIR","ref":197},{"name":"E2BIG","ref":82},{"name":"_events","ref":198},{"name":"ENODEV","ref":183},{"name":"watchFile","ref":199},{"name":"S_IFLNK","ref":200},{"name":"umask","ref":201}],"text":"#"},{"handle":31,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":202},"name":"removed","inferredName":"","resolved":true,"source":"function removed(reason) {\n return function () {\n throw new Error(reason)\n }\n}","script":{"ref":29},"scriptId":14,"position":213,"line":8,"column":17,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":5},{"name":"length","attributes":7,"propertyType":3,"ref":44},{"name":"name","attributes":7,"propertyType":3,"ref":203},{"name":"prototype","attributes":6,"propertyType":3,"ref":202},{"name":"caller","attributes":7,"propertyType":3,"ref":5}],"text":"function removed(reason) {\n return function () {\n throw new Error(reason)\n }\n}"},{"handle":32,"type":"object","className":"Array","constructorFunction":{"ref":204},"protoObject":{"ref":205},"prototypeObject":{"ref":3},"properties":[{"name":"length","attributes":6,"propertyType":3,"ref":64}],"text":"#"},{"handle":33,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":206},"name":"addTimerListener","inferredName":"","resolved":true,"source":"function addTimerListener(callback) {\n var timer = this;\n // Special case the no param case to avoid the extra object creation.\n if (arguments.length > 2) {\n var args = Array.prototype.slice.call(arguments, 2);\n timer.callback = function () { callback.apply(timer, args); };\n } else {\n timer.callback = callback;\n }\n}","script":{"ref":29},"scriptId":14,"position":2652,"line":83,"column":26,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":5},{"name":"length","attributes":7,"propertyType":3,"ref":44},{"name":"name","attributes":7,"propertyType":3,"ref":207},{"name":"prototype","attributes":6,"propertyType":3,"ref":206},{"name":"caller","attributes":7,"propertyType":3,"ref":5}],"text":"function addTimerListener(callback) {\n var timer = this;\n // Special case the no param case to avoid the extra object creation.\n if (arguments.length > 2) {\n var args = Array.prototype.slice.call(arguments, 2);\n timer.callback = function () { callback.apply(timer, args); };\n } else {\n timer.callback = callback;\n }\n}"},{"handle":34,"type":"function","className":"Function","constructorFunction":{"ref":37},"protoObject":{"ref":38},"prototypeObject":{"ref":208},"name":"isSignal","inferredName":"","resolved":true,"source":"function isSignal(event) {\n return event.slice(0, 3) === 'SIG' && process.hasOwnProperty(event);\n}","script":{"ref":29},"scriptId":14,"position":2229,"line":68,"column":18,"properties":[{"name":"arguments","attributes":7,"propertyType":3,"ref":5},{"name":"length","attributes":7,"propertyType":3,"ref":44},{"name":"name","attributes":7,"propertyType":3,"ref":209},{"name":"prototype","attributes":6,"propertyType":3,"ref":208},{"name":"caller","attributes":7,"propertyType":3,"ref":5}],"text":"function isSignal(event) {\n return event.slice(0, 3) === 'SIG' && process.hasOwnProperty(event);\n}"}],"running":false} 2 | --------------------------------------------------------------------------------