text: // Test search
  
  var assert = require('assert');
  var fs = require('fs');
  
  var icalendar = require('../lib');
  
  // NB: Ported to jasmine from expresso, hence the strange layout
  // TODO: Make this look more like a jasmine spec
  describe("iCalendar", function() {
      it('calendar object', function() {
          // assert that we create a valid empty iCal object
          var ics = new icalendar.iCalendar();
          assert.deepEqual([
              'BEGIN:VCALENDAR',
              'VERSION:2.0',
              'PRODID:'+icalendar.PRODID,
              'END:VCALENDAR'], ics.format());
      });
  
      it('calendar stream', function(done) {
          var Writable = require('readable-stream').Writable;
          // fake Writable stream to collect the data into a string
          function toStr(next) {
            var stream = new Writable();
            var str = "";
            stream.write = function(chunk) {
                str += (chunk);
            };
            stream.end = function() {
                next(str);
            };
            return stream;
          }
          var ical = new icalendar.iCalendar();
          var vevent = new icalendar.VEvent('testuid@example.com');
          vevent.addProperty('DTSTART', new Date(Date.UTC(2011,10,12,14,0,0)));
          vevent.addProperty('DTEND', new Date(Date.UTC(2011,10,12,15,3,0)));
          ical.addComponent(vevent);
          ical.pipe(toStr(function (str) {
              assert.equal(str, ical.toString());
              done();
          }));
      });
  
      it('format vevent', function() {
          var vevent = new icalendar.VEvent('testuid@daybilling.com');
          vevent.addProperty('DTSTART', new Date(Date.UTC(2011,10,12,14,00,00)));
          vevent.addProperty('DTEND', new Date(Date.UTC(2011,10,12,15,03,00)));
  
          var dtstamp = icalendar.format_value('DATE-TIME',vevent.getPropertyValue('DTSTAMP'));
          assert.deepEqual([
              'BEGIN:VEVENT',
              'DTSTAMP:'+dtstamp,
              'UID:testuid@daybilling.com',
              'DTSTART:20111112T140000Z',
              'DTEND:20111112T150300Z',
              'END:VEVENT'], vevent.format());
      });
  
      it('VEvent.toString', function() {
          // VEvent objects need to get a calendar wrapper...
          var vevent = new icalendar.VEvent('testuid@daybilling.com');
          vevent.addProperty('DTSTART', new Date(Date.UTC(2011,10,12,14,00,00)));
          vevent.addProperty('DTEND', new Date(Date.UTC(2011,10,12,15,03,00)));
  
          var dtstamp = icalendar.format_value('DATE-TIME',vevent.getPropertyValue('DTSTAMP'));
          assert.equal(
              'BEGIN:VCALENDAR\r\n'+
              'VERSION:2.0\r\n'+
              'PRODID:'+icalendar.PRODID+'\r\n'+
              'BEGIN:VEVENT\r\n'+
              'DTSTAMP:'+dtstamp+'\r\n'+
              'UID:testuid@daybilling.com\r\n'+
              'DTSTART:20111112T140000Z\r\n'+
              'DTEND:20111112T150300Z\r\n'+
              'END:VEVENT\r\n'+
              'END:VCALENDAR\r\n', vevent.toString());
      });
  
      it('wraps long lines correctly', function() {
          var vevent = new icalendar.VEvent('testuid@daybilling.com');
          vevent.setDate(new Date(Date.UTC(2011,11,2,16,59,00)), 3600);
          vevent.setDescription(
              "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod "+
              "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, "+
              "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");
  
          var dtstamp = icalendar.format_value('DATE-TIME',vevent.getPropertyValue('DTSTAMP'));
          assert.deepEqual([
              'BEGIN:VEVENT',
              'DTSTAMP:'+dtstamp,
              'UID:testuid@daybilling.com',
              'DTSTART:20111202T165900Z',
              'DURATION:PT1H',
              'DESCRIPTION:Lorem ipsum dolor sit amet\\, consectetur adipisicing elit\\, sed',
              '  do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad',
              '  minim veniam\\, quis nostrud exercitation ullamco laboris nisi ut aliquip ',
              ' ex ea commodo consequat.',
              'END:VEVENT'], vevent.format());
      });
  
      it('timezone object', function() {
          var tz = new icalendar.VTimezone(null, 'Totally/Bogus');
          var dst = tz.addComponent('DAYLIGHT');
          dst.addProperty('DTSTART', new Date(1970,2,8,2,0,0));
          dst.addProperty('RRULE', {FREQ: 'YEARLY', BYMONTH: 3, BYDAY: '2SU'});
          dst.addProperty('TZOFFSETFROM', -500);
          dst.addProperty('TZOFFSETTO', -400);
          dst.addProperty('TZNAME', 'EDT');
          var std = tz.addComponent('STANDARD');
          std.addProperty('DTSTART', new Date(1970,10,1,2,0,0));
          std.addProperty('RRULE', {FREQ: 'YEARLY', BYMONTH: 11, BYDAY: '1SU'});
          std.addProperty('TZOFFSETFROM', -400);
          std.addProperty('TZOFFSETTO', -500);
          std.addProperty('TZNAME', 'EST');
  
          // These are easy...
          expect(tz.getOffsetForDate(new Date(2011,6,2))).toEqual(-400);
          expect(tz.getOffsetForDate(new Date(2011,1,2))).toEqual(-500);
  
          // Do we handle transitions correctly?
          // NB: These come in as an array because Date objects can't
          //     represent a time that doesn't actually exist
          expect(tz.getOffsetForDate([2011,3,13,1,59,59])).toEqual(-500);
          expect(tz.getOffsetForDate([2011,3,13,2,0,0])).toEqual(-400);
  
          expect(tz.getOffsetForDate([2011,11,6,1,59,59])).toEqual(-400);
          expect(tz.getOffsetForDate([2011,11,6,2,0,0])).toEqual(-500);
      });
  
      it('creates calendar clones', function() {
          var cal = icalendar.parse_calendar(
              'BEGIN:VCALENDAR\r\n'+
              'VERSION:2.0\r\n'+
              'PRODID:-//Bobs Software Emporium//NONSGML Bobs Calendar//EN\r\n'+
              'BEGIN:VEVENT\r\n'+
              'DTSTAMP:20111202T165900\r\n'+
              'UID:testuid@someotherplace.com\r\n'+
              'DESCRIPTION:This bit of text is long and should be sp\r\n'+
              ' lit across multiple lines of output\r\n'+
              'END:VEVENT\r\n'+
              'END:VCALENDAR\r\n');
  
          var cal2 = cal.clone();
  
          expect(cal).toNotBe(cal2);
          expect(cal.components['VEVENT'][0])
              .toNotBe(cal2.components['VEVENT'][0]);
          expect(cal2.toString())
              .toEqual(cal.toString())
  
      });
  
      it('formats objects with multiple occurrences of a property', function() {
          var vevent = new icalendar.VEvent('testuid@tri-tech.com');
          vevent.addProperty('EXDATE', new Date(Date.UTC(2012,2,3, 11,30,00)));
          vevent.addProperty('EXDATE', new Date(2011,1,2), { VALUE: 'DATE' });
  
          var dtstamp = icalendar.format_value('DATE-TIME',vevent.getPropertyValue('DTSTAMP'));
          assert.deepEqual([
              'BEGIN:VEVENT',
              'DTSTAMP:'+dtstamp,
              'UID:testuid@tri-tech.com',
              'EXDATE:20120303T113000Z',
              'EXDATE;VALUE=DATE:20110202',
              'END:VEVENT'
              ],
              vevent.format());
      });
  });
  