{"action":"created","comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/35181733","id":35181733,"diff_hunk":"@@ -0,0 +1,459 @@\n+/// <reference path=\"..\\..\\..\\src\\harness\\harness.ts\" />\r\n+\r\n+module ts.server {\r\n+\tlet lastWrittenToHost: string,\r\n+\tmockHost: ServerHost = {\r\n+\t\targs: [],\r\n+\t\tnewLine: '\\n',\r\n+\t\tuseCaseSensitiveFileNames: true,\r\n+\t\twrite: (s) => lastWrittenToHost = s,\r\n+\t\treadFile: () => void 0,\r\n+\t\twriteFile: () => void 0,\r\n+\t\tresolvePath: () => void 0,\r\n+\t\tfileExists: () => false,\r\n+\t\tdirectoryExists: () => false,\r\n+\t\tcreateDirectory: () => void 0,\r\n+\t\tgetExecutingFilePath: () => void 0,\r\n+\t\tgetCurrentDirectory: () => void 0,\r\n+\t\treadDirectory: () => void 0,\r\n+\t\texit: () => void 0\r\n+\t},\r\n+\tmockLogger: Logger = {\r\n+        close(): void {},\r\n+        isVerbose(): boolean { return false; },\r\n+        loggingEnabled(): boolean { return false; },\r\n+        perftrc(s: string): void {},\r\n+        info(s: string): void {},\r\n+        startGroup(): void {},\r\n+        endGroup(): void {},\r\n+        msg(s: string, type?: string): void {},\r\n+\t};\r\n+\t\r\n+\tdescribe('the Session class', () => {\r\n+\t\tlet session: Session,\r\n+\t\t\tlastSent: protocol.Message;\r\n+\r\n+\t\tbeforeEach(() => {\r\n+\t\t\tsession = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger);\r\n+\t\t\tsession.send = (msg: protocol.Message) => {\r\n+\t\t\t\tlastSent = msg;\r\n+\t\t\t};\r\n+\t\t});\r\n+\r\n+\t\tdescribe('executeCommand', () => {\r\n+\t\t\tit('should throw when commands are executed with invalid arguments', () => {\r\n+\t\t\t\tlet req : protocol.FileRequest = {\r\n+\t\t\t\t\tcommand: CommandNames.Open,\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\ttype: 'command',\r\n+\t\t\t\t\targuments: {\r\n+\t\t\t\t\t\tfile: undefined\r\n+\t\t\t\t\t}\r\n+\t\t\t\t};\r\n+\r\n+\t\t\t\texpect(() => session.executeCommand(req)).to.throw();\r\n+\t\t\t});\r\n+\t\t\tit('should output an error response when a command does not exist', () => {\r\n+\t\t\t\tlet req : protocol.Request = {\r\n+\t\t\t\t\tcommand: 'foobar',\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\ttype: 'command'\r\n+\t\t\t\t};\r\n+\r\n+\t\t\t\tsession.executeCommand(req);\r\n+\r\n+\t\t\t\texpect(lastSent).to.deep.equal(<protocol.Response>{\r\n+\t\t\t\t\tcommand: CommandNames.Unknown,\r\n+\t\t\t\t\ttype: 'response',\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\tmessage: 'Unrecognized JSON command: foobar',\r\n+\t\t\t\t\trequest_seq: 0,\r\n+\t\t\t\t\tsuccess: false\r\n+\t\t\t\t});\r\n+\t\t\t});\r\n+\t\t\tit('should return a tuple containing the response and if a response is required on success', () => {\r\n+\t\t\t\tlet req : protocol.ConfigureRequest = {\r\n+\t\t\t\t\tcommand: CommandNames.Configure,\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\ttype: 'command',\r\n+\t\t\t\t\targuments: {\r\n+\t\t\t\t\t\thostInfo: 'unit test',\r\n+\t\t\t\t\t\tformatOptions: {\r\n+\t\t\t\t\t\t\tnewLineCharacter: '`n'\r\n+\t\t\t\t\t\t}\r\n+\t\t\t\t\t}\r\n+\t\t\t\t};\r\n+\r\n+\t\t\t\texpect(session.executeCommand(req)).to.deep.equal({\r\n+\t\t\t\t\tresponseRequired: false\r\n+\t\t\t\t});\r\n+\t\t\t\texpect(lastSent).to.deep.equal({\r\n+\t\t\t\t\tcommand: CommandNames.Configure,\r\n+\t\t\t\t\ttype: 'response',\r\n+\t\t\t\t\tsuccess: true,\r\n+\t\t\t\t\trequest_seq: 0,\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\tbody: undefined\r\n+\t\t\t\t});\r\n+\t\t\t});\r\n+\t\t});\r\n+\r\n+\t\tdescribe('onMessage', () => {\r\n+\t\t\tit('should not throw when commands are executed with invalid arguments', () => {\r\n+\t\t\t\tlet i = 0;\r\n+\t\t\t\tfor (name in CommandNames) {\r\n+\t\t\t\t\tif (!Object.prototype.hasOwnProperty.call(CommandNames, name)) {\r\n+\t\t\t\t\t\tcontinue;\r\n+\t\t\t\t\t}\r\n+\t\t\t\t\tlet req : protocol.Request = {\r\n+\t\t\t\t\t\tcommand: name,\r\n+\t\t\t\t\t\tseq: i++,\r\n+\t\t\t\t\t\ttype: 'command'\r\n+\t\t\t\t\t};\r\n+\t\t\t\t\tsession.onMessage(JSON.stringify(req));\r\n+\t\t\t\t\treq.seq += 2;\r\n+\t\t\t\t\treq.arguments = {};\r\n+\t\t\t\t\tsession.onMessage(JSON.stringify(req));\r\n+\t\t\t\t\treq.seq += 2;\r\n+\t\t\t\t\treq.arguments = null;\r\n+\t\t\t\t\tsession.onMessage(JSON.stringify(req));\r\n+\t\t\t\t}\r\n+\t\t\t});\r\n+\t\t\tit('should output the response for a correctly handled message', () => {\r\n+\t\t\t\tlet req : protocol.ConfigureRequest = {\r\n+\t\t\t\t\tcommand: CommandNames.Configure,\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\ttype: 'command',\r\n+\t\t\t\t\targuments: {\r\n+\t\t\t\t\t\thostInfo: 'unit test',\r\n+\t\t\t\t\t\tformatOptions: {\r\n+\t\t\t\t\t\t\tnewLineCharacter: '`n'\r\n+\t\t\t\t\t\t}\r\n+\t\t\t\t\t}\r\n+\t\t\t\t};\r\n+\r\n+\t\t\t\tsession.onMessage(JSON.stringify(req));\r\n+\r\n+\t\t\t\texpect(lastSent).to.deep.equal(<protocol.ConfigureResponse>{\r\n+\t\t\t\t\tcommand: CommandNames.Configure,\r\n+\t\t\t\t\ttype: 'response',\r\n+\t\t\t\t\tsuccess: true,\r\n+\t\t\t\t\trequest_seq: 0,\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\tbody: undefined\r\n+\t\t\t\t});\r\n+\t\t\t});\r\n+\t\t});\r\n+\r\n+\t\tdescribe('exit', () => {\r\n+\t\t\tit('is a noop which can be handled by subclasses', () => {\r\n+\t\t\t\tsession.exit(); // Does nothing, should keep running tests\r\n+\t\t\t\texpect(session).to.exist;\r\n+\t\t\t});\r\n+\t\t});\r\n+\r\n+\t\tdescribe('send', () => {\r\n+\t\t\tit('is an overrideable handle which sends protocol messages over the wire', () => {\r\n+\t\t\t\tlet msg = {seq: 0, type: 'none'},\r\n+\t\t\t\tstrmsg = JSON.stringify(msg),\r\n+\t\t\t\tlen = 1 + Buffer.byteLength(strmsg, 'utf8'),\r\n+\t\t\t\tresultMsg = `Content-Length: ${len}\\r\\n\\r\\n${strmsg}\\n`;\r\n+\r\n+\t\t\t\tsession.send = Session.prototype.send;\r\n+\t\t\t\tassert(session.send);\r\n+\t\t\t\texpect(session.send(msg)).to.not.exist;\r\n+\t\t\t\texpect(lastWrittenToHost).to.equal(resultMsg);\r\n+\t\t\t});\r\n+\t\t});\r\n+\r\n+\t\tdescribe('addProtocolHandler', () => {\r\n+\t\t\tit('can add protocol handlers', () => {\r\n+\t\t\t\tlet respBody = {\r\n+\t\t\t\t\titem: false\r\n+\t\t\t\t},\r\n+\t\t\t\tcommand = 'newhandle',\r\n+\t\t\t\tresult = {\r\n+\t\t\t\t\tresponse: respBody,\r\n+\t\t\t\t\tresponseRequired: true\r\n+\t\t\t\t};\r\n+\r\n+\t\t\t\tsession.addProtocolHandler(command, (req) => result);\r\n+\r\n+\t\t\t\texpect(session.executeCommand({\r\n+\t\t\t\t\tcommand,\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\ttype: 'command'\r\n+\t\t\t\t})).to.deep.equal(result);\r\n+\t\t\t});\r\n+\t\t\tit('throws when a duplicate handler is passed', () => {\r\n+\t\t\t\tlet respBody = {\r\n+\t\t\t\t\titem: false\r\n+\t\t\t\t},\r\n+\t\t\t\tresp = {\r\n+\t\t\t\t\tresponse: respBody,\r\n+\t\t\t\t\tresponseRequired: true\r\n+\t\t\t\t},\r\n+\t\t\t\tcommand = 'newhandle';\r\n+\r\n+\t\t\t\tsession.addProtocolHandler(command, (req) => resp);\r\n+\r\n+\t\t\t\texpect(() => session.addProtocolHandler(command, (req) => resp))\r\n+\t\t\t\t.to.throw(`Protocol handler already exists for command \"${command}\"`);\r\n+\t\t\t});\r\n+\t\t});\r\n+\t\t\r\n+\t\tdescribe('event', () => {\r\n+\t\t\tit('can format event responses and send them', () => {\r\n+\t\t\t\tlet evt = 'notify-test',\r\n+\t\t\t\tinfo = {\r\n+\t\t\t\t\ttest: true\r\n+\t\t\t\t};\r\n+\r\n+\t\t\t\tsession.event(info, evt);\r\n+\r\n+\t\t\t\texpect(lastSent).to.deep.equal({\r\n+\t\t\t\t\ttype: 'event',\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\tevent: evt,\r\n+\t\t\t\t\tbody: info\r\n+\t\t\t\t});\r\n+\t\t\t});\r\n+\t\t});\r\n+\r\n+\t\tdescribe('output', () => {\r\n+\t\t\tit('can format command responses and send them', () => {\r\n+\t\t\t\tlet body = {\r\n+\t\t\t\t\tblock: {\r\n+\t\t\t\t\t\tkey: 'value'\r\n+\t\t\t\t\t}\r\n+\t\t\t\t},\r\n+\t\t\t\tcommand = 'test';\r\n+\r\n+\t\t\t\tsession.output(body, command);\r\n+\r\n+\t\t\t\texpect(lastSent).to.deep.equal({\r\n+\t\t\t\t\tseq: 0,\r\n+\t\t\t\t\trequest_seq: 0,\r\n+\t\t\t\t\ttype: 'response',\r\n+\t\t\t\t\tcommand,\r\n+\t\t\t\t\tbody: body,\r\n+\t\t\t\t\tsuccess: true\r\n+\t\t\t\t});\r\n+\t\t\t});\r\n+\t\t});\r\n+\t});\r\n+\r\n+\tdescribe('how Session is extendable via subclassing', () => {\r\n+\t\tlet TestSession = class extends Session {\r\n+\t\t\tlastSent: protocol.Message;\r\n+\t\t\tcustomHandler: string = 'testhandler';\r\n+\t\t\tconstructor(){\r\n+\t\t\t\tsuper(mockHost, Buffer.byteLength, process.hrtime, mockLogger);\r\n+\t\t\t\tthis.addProtocolHandler(this.customHandler, () => {\r\n+\t\t\t\t\treturn {response: undefined, responseRequired: true};\r\n+\t\t\t\t});\r\n+\t\t\t}\r\n+\t\t\tsend(msg: protocol.Message) {\r\n+\t\t\t\tthis.lastSent = msg;\r\n+\t\t\t}\r\n+\t\t};\r\n+\r\n+\t\tit('can override methods such as send', () => {\r\n+\t\t\tlet session = new TestSession(),\r\n+\t\t\tbody = {\r\n+\t\t\t\tblock: {\r\n+\t\t\t\t\tkey: 'value'\r\n+\t\t\t\t}\r\n+\t\t\t},\r\n+\t\t\tcommand = 'test';\r\n+\r\n+\t\t\tsession.output(body, command);\r\n+\r\n+\t\t\texpect(session.lastSent).to.deep.equal({\r\n+\t\t\t\tseq: 0,\r\n+\t\t\t\trequest_seq: 0,\r\n+\t\t\t\ttype: 'response',\r\n+\t\t\t\tcommand,\r\n+\t\t\t\tbody: body,\r\n+\t\t\t\tsuccess: true\r\n+\t\t\t});\r\n+\t\t});\r\n+\t\tit('can add and respond to new protocol handlers', () => {\r\n+\t\t\tlet session = new TestSession();\r\n+\r\n+\t\t\texpect(session.executeCommand({\r\n+\t\t\t\tseq: 0,\r\n+\t\t\t\ttype: 'command',\r\n+\t\t\t\tcommand: session.customHandler\r\n+\t\t\t})).to.deep.equal({\r\n+\t\t\t\tresponse: undefined,\r\n+\t\t\t\tresponseRequired: true\r\n+\t\t\t});\r\n+\t\t});\r\n+\t\tit('has access to the project service', () => {\r\n+\t\t\tlet ServiceSession = class extends TestSession {\r\n+\t\t\t\tconstructor() {\r\n+\t\t\t\t\tsuper();\r\n+\t\t\t\t\tassert(this.projectService);\r\n+\t\t\t\t\texpect(this.projectService).to.be.instanceOf(ProjectService);\r\n+\t\t\t\t}\r\n+\t\t\t};\r\n+\t\t\tnew ServiceSession();\r\n+\t\t});\r\n+\t});\r\n+\r\n+\tdescribe('an example of using the Session API to create an in-process server', () => {\r\n+\t\tlet inProcHost: ServerHost = {\r\n+\t\t\targs: [],\r\n+\t\t\tnewLine: '\\n',\r\n+\t\t\tuseCaseSensitiveFileNames: true,\r\n+\t\t\twrite: (s) => lastWrittenToHost = s,\r\n+\t\t\treadFile: () => void 0,\r\n+\t\t\twriteFile: () => void 0,\r\n+\t\t\tresolvePath: () => void 0,\r\n+\t\t\tfileExists: () => false,\r\n+\t\t\tdirectoryExists: () => false,\r\n+\t\t\tcreateDirectory: () => void 0,\r\n+\t\t\tgetExecutingFilePath: () => void 0,\r\n+\t\t\tgetCurrentDirectory: () => void 0,\r\n+\t\t\treadDirectory: () => void 0,\r\n+\t\t\texit: () => void 0\r\n+\t\t},\r\n+\t\tInProcSession = class extends Session {\r\n+\t\t\tprivate queue: protocol.Request[] = [];\r\n+\t\t\tconstructor(private client: {handle: (msg: protocol.Message) => void}) {\r\n+\t\t\t\tsuper(inProcHost, Buffer.byteLength, process.hrtime, mockLogger);\r\n+\t\t\t\tthis.addProtocolHandler('echo', (req: protocol.Request) => ({\r\n+\t\t\t\t\tresponse: req.arguments,\r\n+\t\t\t\t\tresponseRequired: true\r\n+\t\t\t\t}));\r\n+\t\t\t}\r\n+\t\t\t\r\n+\t\t\tsend(msg: protocol.Message) {\r\n+\t\t\t\tthis.client.handle(msg);\r\n+\t\t\t}\r\n+\r\n+\t\t\tenqueue(msg: protocol.Request) {\r\n+\t\t\t\tthis.queue = [msg].concat(this.queue);\r\n+\t\t\t}\r\n+\t\t\t\r\n+\t\t\thandleRequest(msg: protocol.Request) {\r\n+\t\t\t\tlet response: protocol.Response;\r\n+\t\t\t\ttry {\r\n+\t\t\t\t\tresponse = this.executeCommand(msg).response;\r\n+\t\t\t\t} catch (e) {\r\n+\t\t\t\t\tthis.output(undefined, msg.command, msg.seq, e.toString());\r\n+\t\t\t\t\treturn;\r\n+\t\t\t\t}\r\n+\t\t\t\tif (response) {\r\n+\t\t\t\t\tthis.output(response, msg.command, msg.seq);\r\n+\t\t\t\t}\r\n+\t\t\t}\r\n+\r\n+\t\t\tconsumeQueue() {\r\n+\t\t\t\twhile (this.queue.length > 0) {\r\n+\t\t\t\t\tlet elem = this.queue[this.queue.length - 1];\r\n+\t\t\t\t\tthis.queue = this.queue.slice(0, this.queue.length - 1);\r\n+\t\t\t\t\tthis.handleRequest(elem);\r\n+\t\t\t\t}\r\n+\t\t\t}\r\n+\t\t},\r\n+\t\tInProcClient = class {\r\n+\t\t\tprivate server: Session & {enqueue: (msg: protocol.Request) => void};\r\n+\t\t\tprivate seq: number = 0;\r\n+\t\t\tprivate callbacks: ts.Map<(resp: protocol.Response) => void> = {};\r\n+\t\t\tprivate eventHandlers: ts.Map<(args: any) => void> = {};\r\n+\r\n+\t\t\thandle(msg: protocol.Message): void {\r\n+\t\t\t\tif (msg.type === 'response') {\r\n+\t\t\t\t\tlet response = <protocol.Response>msg;\r\n+\t\t\t\t\tif (this.callbacks[response.request_seq]) {\r\n+\t\t\t\t\t\tthis.callbacks[response.request_seq](response);\r\n+\t\t\t\t\t\tdelete this.callbacks[response.request_seq];\r\n+\t\t\t\t\t}\r\n+\t\t\t\t} else if (msg.type === 'event') {\r\n+\t\t\t\t\tlet event = <protocol.Event>msg;\r\n+\t\t\t\t\tthis.emit(event.event, event.body);\r\n+\t\t\t\t}\r\n+\t\t\t}\r\n+\r\n+\t\t\temit(name: string, args: any): void {\r\n+\t\t\t\tif (!this.eventHandlers[name]) {\r\n+\t\t\t\t\treturn;\r\n+\t\t\t\t}\r\n+\t\t\t\tthis.eventHandlers[name](args);\r\n+\t\t\t}\r\n+\r\n+\t\t\ton(name: string, handler: (args: any) => void): void {\r\n+\t\t\t\tthis.eventHandlers[name] = handler;\r\n+\t\t\t}\r\n+\r\n+\t\t\tconnect(session: Session & {enqueue: (msg: protocol.Request) => void}): void {\r\n+\t\t\t\tthis.server = session;\r\n+\t\t\t}\r\n+\t\t\t\r\n+\t\t\texecute(command: string, args: any, callback: (resp: protocol.Response) => void): void {\r\n+\t\t\t\tif (!this.server) {\r\n+\t\t\t\t\treturn;\r\n+\t\t\t\t}\r\n+\t\t\t\tthis.seq++;\r\n+\t\t\t\tthis.server.enqueue({\r\n+\t\t\t\t\tseq: this.seq,\r\n+\t\t\t\t\ttype: 'command',\r\n+\t\t\t\t\tcommand,\r\n+\t\t\t\t\targuments: args\r\n+\t\t\t\t});\r\n+\t\t\t\tthis.callbacks[this.seq] = callback;\r\n+\t\t\t}\r\n+\t\t};\r\n+\t\t\r\n+\t\tit('can be constructed and respond to commands', (done) => {\r\n+\t\t\tlet cli = new InProcClient(),\r\n+\t\t\tsession = new InProcSession(cli),\r\n+\t\t\ttoEcho = {\r\n+\t\t\t\tdata: true\r\n+\t\t\t},\r\n+\t\t\ttoEvent = {\r\n+\t\t\t\tdata: false\t\r\n+\t\t\t},\r\n+\t\t\tresponses = 0;\r\n+\r\n+\t\t\t// Connect the client\r\n+\t\t\tcli.connect(session);\r\n+\t\t\t\r\n+\t\t\t// Add an event handler\r\n+\t\t\tcli.on('testevent', (eventinfo) => {\r\n+\t\t\t\texpect(eventinfo).to.equal(toEvent);\r\n+\t\t\t\tresponses++;\r\n+\t\t\t\texpect(responses).to.equal(1);\r\n+\t\t\t});\r\n+\t\t\t\r\n+\t\t\t// Trigger said event from the server\r\n+\t\t\tsession.event(toEvent, 'testevent');\r\n+\t\t\t\r\n+\t\t\t// Queue an echo command\r\n+\t\t\tcli.execute('echo', toEcho, (resp) => {\r\n+\t\t\t\tassert(resp.success, resp.message);\r\n+\t\t\t\tresponses++;\r\n+\t\t\t\texpect(responses).to.equal(2);\r\n+\t\t\t\texpect(resp.body).to.deep.equal(toEcho);\r\n+\t\t\t});\r\n+\t\t\t\r\n+\t\t\t// Queue a configure command\r\n+\t\t\tcli.execute('configure', {\r\n+\t\t\t\thostInfo: 'unit test',\r\n+\t\t\t\tformatOptions: {\r\n+\t\t\t\t\tnewLineCharacter: '`n'\r\n+\t\t\t\t}\r","path":"tests/cases/unittests/session.ts","position":447,"original_position":447,"commit_id":"8884f3b4f60881f00c510ab71ecf2776900151aa","original_commit_id":"8884f3b4f60881f00c510ab71ecf2776900151aa","user":{"login":"DanielRosenwasser","id":972891,"avatar_url":"https://avatars.githubusercontent.com/u/972891?v=3","gravatar_id":"","url":"https://api.github.com/users/DanielRosenwasser","html_url":"https://github.com/DanielRosenwasser","followers_url":"https://api.github.com/users/DanielRosenwasser/followers","following_url":"https://api.github.com/users/DanielRosenwasser/following{/other_user}","gists_url":"https://api.github.com/users/DanielRosenwasser/gists{/gist_id}","starred_url":"https://api.github.com/users/DanielRosenwasser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DanielRosenwasser/subscriptions","organizations_url":"https://api.github.com/users/DanielRosenwasser/orgs","repos_url":"https://api.github.com/users/DanielRosenwasser/repos","events_url":"https://api.github.com/users/DanielRosenwasser/events{/privacy}","received_events_url":"https://api.github.com/users/DanielRosenwasser/received_events","type":"User","site_admin":false},"body":"Is this intended to be ``'`n'``","created_at":"2015-07-22T05:05:15Z","updated_at":"2015-07-22T05:05:15Z","html_url":"https://github.com/Microsoft/TypeScript/pull/3967#discussion_r35181733","pull_request_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967","_links":{"self":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments/35181733"},"html":{"href":"https://github.com/Microsoft/TypeScript/pull/3967#discussion_r35181733"},"pull_request":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967"}}},"pull_request":{"url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967","id":40515034,"html_url":"https://github.com/Microsoft/TypeScript/pull/3967","diff_url":"https://github.com/Microsoft/TypeScript/pull/3967.diff","patch_url":"https://github.com/Microsoft/TypeScript/pull/3967.patch","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3967","number":3967,"state":"open","locked":false,"title":"Tests for the Session API","user":{"login":"weswigham","id":2932786,"avatar_url":"https://avatars.githubusercontent.com/u/2932786?v=3","gravatar_id":"","url":"https://api.github.com/users/weswigham","html_url":"https://github.com/weswigham","followers_url":"https://api.github.com/users/weswigham/followers","following_url":"https://api.github.com/users/weswigham/following{/other_user}","gists_url":"https://api.github.com/users/weswigham/gists{/gist_id}","starred_url":"https://api.github.com/users/weswigham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weswigham/subscriptions","organizations_url":"https://api.github.com/users/weswigham/orgs","repos_url":"https://api.github.com/users/weswigham/repos","events_url":"https://api.github.com/users/weswigham/events{/privacy}","received_events_url":"https://api.github.com/users/weswigham/received_events","type":"User","site_admin":false},"body":"Additionally, I added visibility modifiers to all the members, so we declare public as little as is required.\r\n\r\nWhen merged, this should close issue #3813.","created_at":"2015-07-21T23:08:52Z","updated_at":"2015-07-22T05:05:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f22a9c23de121e2720ef658663fd9ceb8065134f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967/commits","review_comments_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967/comments","review_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/3967/comments","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/8884f3b4f60881f00c510ab71ecf2776900151aa","head":{"label":"weswigham:issues/3813","ref":"issues/3813","sha":"8884f3b4f60881f00c510ab71ecf2776900151aa","user":{"login":"weswigham","id":2932786,"avatar_url":"https://avatars.githubusercontent.com/u/2932786?v=3","gravatar_id":"","url":"https://api.github.com/users/weswigham","html_url":"https://github.com/weswigham","followers_url":"https://api.github.com/users/weswigham/followers","following_url":"https://api.github.com/users/weswigham/following{/other_user}","gists_url":"https://api.github.com/users/weswigham/gists{/gist_id}","starred_url":"https://api.github.com/users/weswigham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weswigham/subscriptions","organizations_url":"https://api.github.com/users/weswigham/orgs","repos_url":"https://api.github.com/users/weswigham/repos","events_url":"https://api.github.com/users/weswigham/events{/privacy}","received_events_url":"https://api.github.com/users/weswigham/received_events","type":"User","site_admin":false},"repo":{"id":37160442,"name":"TypeScript","full_name":"weswigham/TypeScript","owner":{"login":"weswigham","id":2932786,"avatar_url":"https://avatars.githubusercontent.com/u/2932786?v=3","gravatar_id":"","url":"https://api.github.com/users/weswigham","html_url":"https://github.com/weswigham","followers_url":"https://api.github.com/users/weswigham/followers","following_url":"https://api.github.com/users/weswigham/following{/other_user}","gists_url":"https://api.github.com/users/weswigham/gists{/gist_id}","starred_url":"https://api.github.com/users/weswigham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/weswigham/subscriptions","organizations_url":"https://api.github.com/users/weswigham/orgs","repos_url":"https://api.github.com/users/weswigham/repos","events_url":"https://api.github.com/users/weswigham/events{/privacy}","received_events_url":"https://api.github.com/users/weswigham/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/weswigham/TypeScript","description":"TypeScript is a superset of JavaScript that compiles to clean JavaScript output.","fork":true,"url":"https://api.github.com/repos/weswigham/TypeScript","forks_url":"https://api.github.com/repos/weswigham/TypeScript/forks","keys_url":"https://api.github.com/repos/weswigham/TypeScript/keys{/key_id}","collaborators_url":"https://api.github.com/repos/weswigham/TypeScript/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/weswigham/TypeScript/teams","hooks_url":"https://api.github.com/repos/weswigham/TypeScript/hooks","issue_events_url":"https://api.github.com/repos/weswigham/TypeScript/issues/events{/number}","events_url":"https://api.github.com/repos/weswigham/TypeScript/events","assignees_url":"https://api.github.com/repos/weswigham/TypeScript/assignees{/user}","branches_url":"https://api.github.com/repos/weswigham/TypeScript/branches{/branch}","tags_url":"https://api.github.com/repos/weswigham/TypeScript/tags","blobs_url":"https://api.github.com/repos/weswigham/TypeScript/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/weswigham/TypeScript/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/weswigham/TypeScript/git/refs{/sha}","trees_url":"https://api.github.com/repos/weswigham/TypeScript/git/trees{/sha}","statuses_url":"https://api.github.com/repos/weswigham/TypeScript/statuses/{sha}","languages_url":"https://api.github.com/repos/weswigham/TypeScript/languages","stargazers_url":"https://api.github.com/repos/weswigham/TypeScript/stargazers","contributors_url":"https://api.github.com/repos/weswigham/TypeScript/contributors","subscribers_url":"https://api.github.com/repos/weswigham/TypeScript/subscribers","subscription_url":"https://api.github.com/repos/weswigham/TypeScript/subscription","commits_url":"https://api.github.com/repos/weswigham/TypeScript/commits{/sha}","git_commits_url":"https://api.github.com/repos/weswigham/TypeScript/git/commits{/sha}","comments_url":"https://api.github.com/repos/weswigham/TypeScript/comments{/number}","issue_comment_url":"https://api.github.com/repos/weswigham/TypeScript/issues/comments{/number}","contents_url":"https://api.github.com/repos/weswigham/TypeScript/contents/{+path}","compare_url":"https://api.github.com/repos/weswigham/TypeScript/compare/{base}...{head}","merges_url":"https://api.github.com/repos/weswigham/TypeScript/merges","archive_url":"https://api.github.com/repos/weswigham/TypeScript/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/weswigham/TypeScript/downloads","issues_url":"https://api.github.com/repos/weswigham/TypeScript/issues{/number}","pulls_url":"https://api.github.com/repos/weswigham/TypeScript/pulls{/number}","milestones_url":"https://api.github.com/repos/weswigham/TypeScript/milestones{/number}","notifications_url":"https://api.github.com/repos/weswigham/TypeScript/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/weswigham/TypeScript/labels{/name}","releases_url":"https://api.github.com/repos/weswigham/TypeScript/releases{/id}","created_at":"2015-06-09T21:48:48Z","updated_at":"2015-06-09T21:49:23Z","pushed_at":"2015-07-21T23:26:12Z","git_url":"git://github.com/weswigham/TypeScript.git","ssh_url":"git@github.com:weswigham/TypeScript.git","clone_url":"https://github.com/weswigham/TypeScript.git","svn_url":"https://github.com/weswigham/TypeScript","homepage":"http://www.typescriptlang.org","size":183960,"stargazers_count":0,"watchers_count":0,"language":"TypeScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Microsoft:master","ref":"master","sha":"6f00275b04378cf9004ea524d30d9a385c7322d8","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":20929025,"name":"TypeScript","full_name":"Microsoft/TypeScript","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/TypeScript","description":"TypeScript is a superset of JavaScript that compiles to clean JavaScript output.","fork":false,"url":"https://api.github.com/repos/Microsoft/TypeScript","forks_url":"https://api.github.com/repos/Microsoft/TypeScript/forks","keys_url":"https://api.github.com/repos/Microsoft/TypeScript/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/TypeScript/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/TypeScript/teams","hooks_url":"https://api.github.com/repos/Microsoft/TypeScript/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/TypeScript/events","assignees_url":"https://api.github.com/repos/Microsoft/TypeScript/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/TypeScript/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/TypeScript/tags","blobs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/TypeScript/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/TypeScript/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/TypeScript/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/TypeScript/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/TypeScript/languages","stargazers_url":"https://api.github.com/repos/Microsoft/TypeScript/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/TypeScript/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/TypeScript/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/TypeScript/subscription","commits_url":"https://api.github.com/repos/Microsoft/TypeScript/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/TypeScript/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/TypeScript/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/TypeScript/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/TypeScript/merges","archive_url":"https://api.github.com/repos/Microsoft/TypeScript/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/TypeScript/downloads","issues_url":"https://api.github.com/repos/Microsoft/TypeScript/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/TypeScript/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/TypeScript/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/TypeScript/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/TypeScript/releases{/id}","created_at":"2014-06-17T15:28:39Z","updated_at":"2015-07-22T01:47:04Z","pushed_at":"2015-07-22T01:28:01Z","git_url":"git://github.com/Microsoft/TypeScript.git","ssh_url":"git@github.com:Microsoft/TypeScript.git","clone_url":"https://github.com/Microsoft/TypeScript.git","svn_url":"https://github.com/Microsoft/TypeScript","homepage":"http://www.typescriptlang.org","size":945378,"stargazers_count":6005,"watchers_count":6005,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":657,"mirror_url":null,"open_issues_count":695,"forks":657,"open_issues":695,"watchers":6005,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967"},"html":{"href":"https://github.com/Microsoft/TypeScript/pull/3967"},"issue":{"href":"https://api.github.com/repos/Microsoft/TypeScript/issues/3967"},"comments":{"href":"https://api.github.com/repos/Microsoft/TypeScript/issues/3967/comments"},"review_comments":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967/comments"},"review_comment":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Microsoft/TypeScript/pulls/3967/commits"},"statuses":{"href":"https://api.github.com/repos/Microsoft/TypeScript/statuses/8884f3b4f60881f00c510ab71ecf2776900151aa"}}}}