diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a34d626 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ + + +TESTS = test/*.js +REPORTER = spec + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter $(REPORTER) \ + --growl \ + $(TESTS) + +.PHONY: test \ No newline at end of file diff --git a/ical.js b/ical.js deleted file mode 100644 index f80e3ca..0000000 --- a/ical.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - Parser: require('./lib/parser').Parser -}; \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..db59000 --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/ical'); \ No newline at end of file diff --git a/lib/ical.js b/lib/ical.js new file mode 100644 index 0000000..0670557 --- /dev/null +++ b/lib/ical.js @@ -0,0 +1,3 @@ +module.exports = { + Parser: require('./parser').Parser +} \ No newline at end of file diff --git a/lib/parser.js b/lib/parser.js index 254296e..0920232 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -8,6 +8,7 @@ function Parser(opts) { this.writable = true; this.calendars = []; this._handles = []; + this._done = false; } util.inherits(Parser, Stream); exports.Parser = Parser; @@ -20,7 +21,7 @@ Parser.parseLine = function (line) { var obj = { }; var valueSplitter = line.indexOf(':'); if (valueSplitter === -1) { - throw new Error('this line has no ":"!'); + throw new Error('this line has no ":", "' + line + '"'); } var paramSplitter = line.indexOf(';'); if (paramSplitter === -1) { @@ -110,22 +111,31 @@ Parser.prototype._dispatch = function () { * Need to take into * account \r\n in quotes here */ - var content = this.buffer.substr(0, this.buffer.lastIndexOf('\r\n')); - this.buffer = this.buffer.substr(2); + var limit = this.buffer.lastIndexOf('\r\n') + 2; + if (limit == -1) { + return; + } + debugger; + var content = this.buffer.substr(0, limit); + this.buffer = this.buffer.slice(limit + 2, limit + 4); var contentLines = content.split('\r\n'); for (var i = 0; i < contentLines.length; i++) { var line = contentLines[i]; + if (line === '') { + this.emit('end') + break + } line = Parser.parseLine(line); var fn = this.handlers[line.name]; if (!fn) { - console.log('dont know how to handle ' + line.name + ' will use dummy handler'); + //console.log('dont know how to handle ' + line.name + ' will use dummy handler'); this.handlers._onlyCopy.call(this, line); } else { fn.call(this, line); } } -}; +} Parser.prototype.end = function () { this.emit('end'); diff --git a/package.json b/package.json index 3e399d6..924770d 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,12 @@ "keywords": [ "ical", "icalendar", "rfc2445" ], - "main": "./ical.js", + "main": "./", "private": true, "dependencies": {}, "devDependencies": { + "mocha": "0.12.1", + "should": "0.5.1" }, "license": { "type": "MIT", diff --git a/test/parse_full.js b/test/parse_full.js new file mode 100644 index 0000000..baa2b24 --- /dev/null +++ b/test/parse_full.js @@ -0,0 +1,23 @@ +var should = require('should'), + fs = require('fs'), + ical = require('../'); + +describe('Parser', function () { + var parser, full_ics_stream + var full_ics = fs.readFileSync(__dirname + '/resources/full.ics') + beforeEach(function (done) { + parser = new ical.Parser() + full_ics_stream = fs.createReadStream(__dirname + '/resources/full.ics') + done() + }) + describe('parses correctly tests', function () { + it('must parse full.ics', function (done) { + parser.on('end', done) + parser.write(full_ics) + }) + it('must parse full.ics streamed', function (done) { + parser.on('end', done); + full_ics_stream.pipe(parser) + }) + }) +}) \ No newline at end of file diff --git a/test/resources/full.ics b/test/resources/full.ics new file mode 100644 index 0000000..c27310b --- /dev/null +++ b/test/resources/full.ics @@ -0,0 +1,30 @@ +BEGIN:VCALENDAR +PRODID:-//Google Inc//Google Calendar 70.9054//EN +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:dan Mylonakis +X-WR-TIMEZONE:Europe/Athens +BEGIN:VEVENT +DTSTART:20111206T150000Z +DTEND:20111206T180000Z +DTSTAMP:20120217T005926Z +UID:3v454h0dqpe7m0kbqds4rca32g@google.com +ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=danmyl + onakis@gmail.com;X-NUM-GUESTS=0:mailto:danmylonakis@gmail.com +CREATED:20111206T013929Z +DESCRIPTION: +LAST-MODIFIED:20111206T013929Z +LOCATION: +SEQUENCE:1 +STATUS:TENTATIVE +SUMMARY:557 με δαμον +TRANSP:OPAQUE +CATEGORIES:http://schemas.google.com/g/2005#event +BEGIN:VALARM +ACTION:DISPLAY +DESCRIPTION:This is an event reminder +TRIGGER:-P0DT0H10M0S +END:VALARM +END:VEVENT +END:VCALENDAR