sproutcore 1.0.1042 → 1.0.1043

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -427,7 +427,98 @@ SC.RootResponder = SC.Object.extend({
427
427
 
428
428
  @returns {void}
429
429
  */
430
- setup: function() {}
430
+ setup: function() {
431
+ this.listenFor('touchstart touchmove touchend touchcancel'.w(), document);
432
+ },
433
+
434
+ touchstart: function(evt) {
435
+ try {
436
+ var view = this.targetViewForEvent(evt) ;
437
+ view = this._touchView = this.sendEvent('touchStart', evt, view) ;
438
+ if (view && view.respondsTo('touchDragged')) this._touchCanDrag = YES ;
439
+ } catch (e) {
440
+ console.log('Exception during touchStart: %@'.fmt(e)) ;
441
+ this._touchView = null ;
442
+ this._touchCanDrag = NO ;
443
+ return NO ;
444
+ }
445
+ return view ? evt.hasCustomEventHandling : YES;
446
+ },
447
+
448
+ touchmove: function(evt) {
449
+ SC.RunLoop.begin();
450
+ try {
451
+ var lh = this._lastHovered || [] ;
452
+ var nh = [] ;
453
+ var view = this.targetViewForEvent(evt) ;
454
+
455
+ // work up the view chain. Notify of touchEntered and
456
+ // touchMoved if implemented.
457
+ while(view && (view !== this)) {
458
+ if (lh.indexOf(view) !== -1) {
459
+ view.tryToPerform('touchMoved', evt);
460
+ nh.push(view) ;
461
+ } else {
462
+ view.tryToPerform('touchEntered', evt);
463
+ nh.push(view) ;
464
+ }
465
+
466
+ view = view.get('nextResponder');
467
+ }
468
+
469
+ // now find those views last hovered over that were no longer found
470
+ // in this chain and notify of mouseExited.
471
+ for(var loc=0; loc < lh.length; loc++) {
472
+ view = lh[loc] ;
473
+ var exited = view.respondsTo('touchExited') ;
474
+ if (exited && !(nh.indexOf(view) !== -1)) {
475
+ view.tryToPerform('touchExited',evt);
476
+ }
477
+ }
478
+
479
+ this._lastHovered = nh;
480
+
481
+ // also, if a touchView exists, call the touchDragged action, if
482
+ // it exists.
483
+ if (this._touchView) this._touchView.tryToPerform('touchDragged', evt);
484
+ } catch (e) {
485
+ console.log('Exception during touchMove: %@'.fmt(e)) ;
486
+ }
487
+ SC.RunLoop.end();
488
+ return YES ;
489
+ },
490
+
491
+ touchend: function(evt) {
492
+ try {
493
+ evt.cancel = NO ;
494
+ var handler = null, view = this._touchView ;
495
+
496
+ // attempt the call only if there's a target.
497
+ // don't want a touch end going to anyone unless they handled the
498
+ // touch start...
499
+ if (view) handler = this.sendEvent('touchEnd', evt, view) ;
500
+
501
+ // try whoever's under the mouse if we haven't handle the mouse up yet
502
+ if (!handler) view = this.targetViewForEvent(evt) ;
503
+
504
+ // cleanup
505
+ this._touchCanDrag = NO; this._touchView = null ;
506
+ } catch (e) {
507
+ console.log('Exception during touchEnd: %@'.fmt(e)) ;
508
+ this._touchCanDrag = NO; this._touchView = null ;
509
+ return NO ;
510
+ }
511
+ return (handler) ? evt.hasCustomEventHandling : YES ;
512
+ },
513
+
514
+ /** @private
515
+ Handle touch cancel event. Works just like touch end except evt.cancel
516
+ is set to YES.
517
+ */
518
+ touchcancel: function(evt) {
519
+ evt.cancel = YES ;
520
+ return this.touchend(evt);
521
+ }
431
522
 
432
523
  });
433
524
 
@@ -0,0 +1,68 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2006-2009 Apple Inc. and contributors.
4
+ // License: Licensed under MIT license (see license.js)
5
+ // ==========================================================================
6
+
7
+ /*global module test equals context ok same */
8
+
9
+ htmlbody('<style> .sc-static-layout { border: 1px red dotted; } </style>');
10
+
11
+
12
+ var pane = SC.ControlTestPane.design()
13
+ .add("basic", SC.View.extend(SC.Control, SC.Button,
14
+ {
15
+ localize: YES,
16
+ displayProperties: ['title'],
17
+ render: function(context, firstTime) {
18
+ this.renderTitle(context, firstTime);
19
+ },
20
+ title: "Hello World"
21
+ })
22
+ );
23
+
24
+ pane.show();
25
+
26
+ module('SC.Button ui', {
27
+ setup: function() {
28
+ var view = pane.view('basic');
29
+ }
30
+ });
31
+
32
+ test("should set the innerHTML to the title", function() {
33
+ var view = pane.view('basic');
34
+
35
+ ok(view.$('label'), 'button has no label');
36
+ var label = view.$('label');
37
+
38
+ ok(label[0], 'label has no html node');
39
+ var htmlNode = label[0];
40
+
41
+ equals(htmlNode.innerHTML, 'Hello World', 'innerHTML should be set to title');
42
+ });
43
+
44
+ test("should modify the innerHTML if the title changes", function() {
45
+ var view = pane.view('basic');
46
+
47
+ SC.RunLoop.begin();
48
+ view.set('title', 'Goodbye World');
49
+ SC.RunLoop.end();
50
+
51
+ var label = view.$('label');
52
+ var htmlNode = label[0];
53
+
54
+ equals(htmlNode.innerHTML, 'Goodbye World', 'innerHTML should be modified when title changes');
55
+ });
56
+
57
+ test("should still modify the innerHTML if the title changes and then changes back to previous value", function() {
58
+ var view = pane.view('basic');
59
+
60
+ SC.RunLoop.begin();
61
+ view.set('title', 'Hello World');
62
+ SC.RunLoop.end();
63
+
64
+ var label = view.$('label');
65
+ var htmlNode = label[0];
66
+
67
+ equals(htmlNode.innerHTML, 'Hello World', 'innerHTML should be modified when title changes and then changes back to original value');
68
+ });
@@ -6,24 +6,26 @@
6
6
 
7
7
  module('Time');
8
8
 
9
- var ms, options, dt, timezones;
9
+ var dt, options, ms, timezone, startTime, timezones;
10
10
 
11
11
  module("SC.DateTime", {
12
12
  setup: function() {
13
- ms = 484387222925; // 1985-05-08T01:00:22-07:00
14
- options = {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: SC.DateTime.timezone};
13
+ ms = 487054822032; // June 8, 1985, 05:00:22:32 UTC
14
+ options = { year: 1985, month: 6, day: 8, hour: 4, minute: 0, second: 22, millisecond: 32, timezone: 60 }; // an arbitrary time zone
15
15
  dt = SC.DateTime.create(options);
16
16
  timezones = [480, 420, 0, -60, -120, -330]; // PST, PDT, UTC, CET, CEST, Mumbai
17
17
  },
18
18
  teardown: function() {
19
- delete ms;
20
- delete options;
21
19
  delete dt;
20
+ delete options;
21
+ delete ms;
22
+ delete timezone;
23
+ delete startTime;
22
24
  }
23
25
  });
24
26
 
25
27
  function timeShouldBeEqualToHash(t, h) {
26
- if (h === undefined) h = testHash;
28
+ if (h === undefined) h = options;
27
29
  if (h.timezone === undefined) h.timezone = SC.DateTime.timezone;
28
30
 
29
31
  equals(t.get('year'), h.year , 'year');
@@ -44,63 +46,160 @@ function formatTimezone(offset) {
44
46
  return modifier + SC.DateTime._pad(hours) + ':' + SC.DateTime._pad(minutes);
45
47
  }
46
48
 
49
+ test('_toMilliseconds()', function() {
50
+ var originalTimezone = options.timezone;
51
+ var originalHour = options.hour;
52
+
53
+ dt = SC.DateTime;
54
+ timezone = 300;
55
+ startTime = 1264958583000; // Sun, 31 Jan 2010 17:23:03 GMT (a randomly chosen time with which to re-init the internal date object for more robustness)
56
+
57
+ // Check the default behavior
58
+ equals(dt._toMilliseconds(null, ms, timezone), ms, "Should equal start milliseconds when no options hash provided");
59
+ equals(dt._toMilliseconds({}, ms, timezone), ms, "Should equal start milliseconds when empty options hash provided");
60
+
61
+ // Test a completely defined date/time hash with no specified start milliseconds.
62
+ equals(dt._toMilliseconds(options, null, options.timezone), ms, "Milliseconds should express the parsed options hash");
63
+
64
+ // Now specify the same time in timezone (+60), one hour west of the prime meridian.
65
+ // Pass in 'startTime' to force a reset of the internal date object so we can be sure we're not
66
+ // succeeding because of old values.
67
+ options.hour = originalHour - 1;
68
+ equals(dt._toMilliseconds(options, startTime, options.timezone + 60), ms, "Should get same milliseconds when expressing time in westerly time zone");
69
+
70
+ // Now specify the same time in timezone (-60), one hour east of the prime meridian
71
+ options.hour = originalHour + 1;
72
+ equals(dt._toMilliseconds(options, startTime, options.timezone - 60), ms, "Should get same milliseconds when expressing time in easterly time zone");
73
+
74
+ // Now start at the original 1985 time, but modify only the hour as specified in time zone 60.
75
+ options = { hour: originalHour - 1 };
76
+ equals(dt._toMilliseconds(options, ms, originalTimezone + 60, NO), ms, "Should get same result modifying only the hour as expressed in westerly time zone");
77
+
78
+ // Now do the same thing the other way
79
+ options = { hour: originalHour + 1 };
80
+ equals(dt._toMilliseconds(options, ms, originalTimezone - 60, NO), ms, "Should get same result modifying only the hour as expressed in westerly time zone");
81
+ });
82
+
47
83
  test('create with a hash', function() {
48
84
  timeShouldBeEqualToHash(dt, options);
49
85
  });
50
86
 
51
- test('create with milliseconds', function() {
52
- var t = SC.DateTime.create(ms);
53
- options.timezone = 0;
87
+ test('create with local time milliseconds', function() {
88
+ var d = new Date(); // create a local date
89
+ var hash = { // create a hash that represents it, expressed in local time
90
+ year: d.getFullYear(),
91
+ month: d.getMonth() + 1,
92
+ day: d.getDate(),
93
+ hour: d.getHours(),
94
+ minute: d.getMinutes(),
95
+ second: d.getSeconds(),
96
+ millisecond: d.getMilliseconds(),
97
+ timezone: d.getTimezoneOffset()
98
+ };
54
99
 
55
- equals(t.get('milliseconds'), ms);
56
- timeShouldBeEqualToHash(t, options);
57
- equals(SC.DateTime.create(0).get('milliseconds'), 0);
100
+ dt = SC.DateTime.create(d.getTime()); // init a DateTime using that date's milliseconds
101
+ timeShouldBeEqualToHash(dt, hash);
102
+
103
+ // Now try creating with 0 milliseconds
104
+ equals(SC.DateTime.create(0).get('milliseconds'), 0, "Can create with 0 milliseconds");
105
+ });
106
+
107
+ test('create with default time zone', function() {
108
+ var d = new Date();
109
+
110
+ // Check that the default creation time zone is local
111
+ timezone = d.getTimezoneOffset(); // get the current location's time zone.
112
+ dt = SC.DateTime.create();
113
+ equals(dt.get('timezone'), timezone, "Default time zone should be local");
114
+ });
115
+
116
+ test('create with a hash containing milliseconds and a specified time zone', function() {
117
+ // Check that creating a predefined date from milliseconds returns the correct values
118
+ dt = SC.DateTime.create({ milliseconds: ms, timezone: options.timezone });
119
+ timeShouldBeEqualToHash(dt, options);
120
+ });
121
+
122
+ test('create with hashes expressed in various time zones', function() {
123
+ timezones.forEach(function(timezone) {
124
+ options.timezone = timezone;
125
+ dt = SC.DateTime.create(options);
126
+ timeShouldBeEqualToHash(dt, options);
127
+ });
128
+ });
129
+
130
+ test('create with default time zone', function() {
131
+ var d = new Date();
132
+
133
+ // Check that the default creation time zone is local
134
+ timezone = d.getTimezoneOffset(); // get the current location's time zone.
135
+ dt = SC.DateTime.create();
136
+ equals(dt.get('timezone'), timezone, "Default time zone should be local");
137
+ });
138
+
139
+ test('create with a hash containing milliseconds and a specified time zone', function() {
140
+ // Check that creating a predefined date from milliseconds returns the correct values
141
+ dt = SC.DateTime.create({ milliseconds: ms, timezone: options.timezone });
142
+ timeShouldBeEqualToHash(dt, options);
58
143
  });
59
144
 
60
- test('adjust', function() {
145
+ test('Adjust with hashes expressed in various time zones', function() {
61
146
  timezones.forEach(function(timezone) {
147
+ var newHour;
148
+
62
149
  options.timezone = timezone;
63
150
  dt = SC.DateTime.create(options);
151
+
152
+ // According to Date specs, must specify all three of year, month, and date if we specify one of them,
153
+ // for the calculation to be correct. Calling adjust to change only one can have
154
+ // unpredictable results, depending on what the other two values already were.
155
+ timeShouldBeEqualToHash(dt.adjust({ year: 2005, month: 9, day: 30 }), {year: 2005, month: 9, day: 30, hour: options.hour, minute: options.minute, second: options.second, millisecond: options.millisecond, timezone: timezone});
156
+
157
+ // Setting only the hour should cascade minute, second, and millisecond to 0, etc
158
+ timeShouldBeEqualToHash(dt.adjust({ hour: 3 }), { year: options.year, month: options.month, day: options.day, hour: 3, minute: 0, second: 0, millisecond: 0, timezone: timezone});
159
+ timeShouldBeEqualToHash(dt.adjust({ minute: 1 }), { year: options.year, month: options.month, day: options.day, hour: options.hour, minute: 1, second: 0, millisecond: 0, timezone: timezone});
160
+ timeShouldBeEqualToHash(dt.adjust({ second: 12 }), { year: options.year, month: options.month, day: options.day, hour: options.hour, minute: options.minute, second: 12, millisecond: 0, timezone: timezone});
161
+ timeShouldBeEqualToHash(dt.adjust({ millisecond: 18 }), { year: options.year, month: options.month, day: options.day, hour: options.hour, minute: options.minute, second: options.second, millisecond: 18, timezone: timezone});
64
162
 
65
- timeShouldBeEqualToHash(dt.adjust({year: 2005}), {year: 2005, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: timezone});
66
- timeShouldBeEqualToHash(dt.adjust({month: 9}), {year: 1985, month: 9, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: timezone});
67
- timeShouldBeEqualToHash(dt.adjust({day: 31}), {year: 1985, month: 5, day: 31, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: timezone});
68
- timeShouldBeEqualToHash(dt.adjust({hour: 3}), {year: 1985, month: 5, day: 8, hour: 3, minute: 0, second: 0, millisecond: 0, timezone: timezone});
69
- timeShouldBeEqualToHash(dt.adjust({minute: 1}), {year: 1985, month: 5, day: 8, hour: 1, minute: 1, second: 0, millisecond: 0, timezone: timezone});
70
- timeShouldBeEqualToHash(dt.adjust({second: 12}), {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 12, millisecond: 0, timezone: timezone});
71
- timeShouldBeEqualToHash(dt.adjust({millisecond: 18}), {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 18, timezone: timezone});
72
- timeShouldBeEqualToHash(dt.adjust({timezone: 0}), {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: 0});
163
+ // Test taking each to time zone 0. Manually calculate what the hour should be
164
+ // then test that a call to get() returns that value.
165
+ newHour = Math.floor((options.hour + 48 + (timezone / 60)) % 24); // small hack -- add 48 hours to ensure positive results when adding negative time zone offsets (doesn't affect the calculation since we mod by 24)
166
+ equals(dt.adjust({ timezone: 0 }).get('hour'), newHour);
73
167
  });
74
168
  });
75
169
 
76
170
  test('advance', function() {
171
+ var o = options;
172
+
77
173
  timeShouldBeEqualToHash(
78
- dt.advance({year: 1, month: 1, day: 1, hour: 1, minute: 1, second: 1, millisecond: 1}),
79
- {year: 1986, month: 6, day: 9, hour: 2, minute: 1, second: 23, millisecond: 926});
80
- timeShouldBeEqualToHash(dt.advance({year: 1}), {year: 1986, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925});
81
- timeShouldBeEqualToHash(dt.advance({month: 1}), {year: 1985, month: 6, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925});
82
- timeShouldBeEqualToHash(dt.advance({day: 1}), {year: 1985, month: 5, day: 9, hour: 1, minute: 0, second: 22, millisecond: 925});
83
- timeShouldBeEqualToHash(dt.advance({hour: 1}), {year: 1985, month: 5, day: 8, hour: 2, minute: 0, second: 22, millisecond: 925});
84
- timeShouldBeEqualToHash(dt.advance({minute: 1}), {year: 1985, month: 5, day: 8, hour: 1, minute: 1, second: 22, millisecond: 925});
85
- timeShouldBeEqualToHash(dt.advance({second: 1}), {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 23, millisecond: 925});
86
- timeShouldBeEqualToHash(dt.advance({millisecond: 1}), {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 926});
174
+ dt.advance({ year: 1, month: 1, day: 1, hour: 1, minute: 1, second: 1, millisecond: 1 }),
175
+ { year: o.year + 1, month: o.month + 1, day: o.day + 1, hour: o.hour + 1, minute: o.minute + 1, second: o.second + 1, millisecond: o.millisecond + 1, timezone: o.timezone });
176
+
177
+ timeShouldBeEqualToHash(dt.advance({year: 1}), { year: o.year + 1, month: o.month, day: o.day, hour: o.hour, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: o.timezone });
178
+ timeShouldBeEqualToHash(dt.advance({month: 1}), { year: o.year, month: o.month + 1, day: o.day, hour: o.hour, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: o.timezone });
179
+ timeShouldBeEqualToHash(dt.advance({day: 1}), { year: o.year, month: o.month, day: o.day + 1, hour: o.hour, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: o.timezone });
180
+ timeShouldBeEqualToHash(dt.advance({hour: 1}), { year: o.year, month: o.month, day: o.day, hour: o.hour + 1, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: o.timezone });
181
+ timeShouldBeEqualToHash(dt.advance({minute: 1}), { year: o.year, month: o.month, day: o.day, hour: o.hour, minute: o.minute + 1, second: o.second, millisecond: o.millisecond, timezone: o.timezone });
182
+ timeShouldBeEqualToHash(dt.advance({second: 1}), { year: o.year, month: o.month, day: o.day, hour: o.hour, minute: o.minute, second: o.second + 1, millisecond: o.millisecond, timezone: o.timezone });
183
+ timeShouldBeEqualToHash(dt.advance({millisecond: 1}), { year: o.year, month: o.month, day: o.day, hour: o.hour, minute: o.minute, second: o.second, millisecond: o.millisecond + 1, timezone: o.timezone });
87
184
 
88
185
  // Convert time from CEST to UTC, then UTC to UTC+05:30 (Mumbai)
89
- var h = {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: -120};
186
+ var h = { year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: -120 };
90
187
  var t = SC.DateTime.create(h);
91
188
  timeShouldBeEqualToHash(t, h);
92
- timeShouldBeEqualToHash(t.advance({timezone: 120}), {year: 1985, month: 5, day: 7, hour: 23, minute: 0, second: 22, millisecond: 925, timezone: 0});
93
- timeShouldBeEqualToHash(t.advance({timezone: 120}).advance({timezone: -330}), {year: 1985, month: 5, day: 8, hour: 4, minute: 30, second: 22, millisecond: 925, timezone: -330});
189
+ timeShouldBeEqualToHash(t.advance({ timezone: 120 }), { year: 1985, month: 5, day: 7, hour: 23, minute: 0, second: 22, millisecond: 925, timezone: 0 });
190
+ timeShouldBeEqualToHash(t.advance({ timezone: 120 }).advance({ timezone: -330 }), { year: 1985, month: 5, day: 8, hour: 4, minute: 30, second: 22, millisecond: 925, timezone: -330 });
94
191
  equals(SC.DateTime.compare(
95
- t.advance({timezone: 120}).advance({timezone: -330}),
96
- t.advance({timezone: -210})),
192
+ t.advance({ timezone: 120 }).advance({ timezone: -330 }),
193
+ t.advance({ timezone: -210 })),
97
194
  0);
98
195
  });
99
196
 
100
197
  test('compare', function() {
101
- equals(SC.DateTime.isComparable, YES);
102
- equals(SC.compare(dt, dt), 0);
103
- equals(dt.isEqual(dt), YES);
198
+ var exception = null;
199
+
200
+ equals(SC.DateTime.isComparable, YES, "SC.DateTime is comparable");
201
+ equals(SC.compare(dt, dt), 0, "A DateTime instance is equal to itself via compare()");
202
+ equals(dt.isEqual(dt), YES, "A DateTime instance is equal to itself via isEqual()");
104
203
  equals(dt.advance({hour: 1}).isEqual(dt), NO);
105
204
  equals(SC.compare(dt, dt.advance({hour: 1})), -1);
106
205
  equals(SC.compare(dt.advance({hour: 1}), dt), 1);
@@ -111,9 +210,8 @@ test('compare', function() {
111
210
  equals(SC.compare(
112
211
  SC.DateTime.create({year: 1985, month: 5, day: 7, hour: 23, minute: 0, second: 22, millisecond: 925, timezone: 0}),
113
212
  SC.DateTime.create({year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: -120})),
114
- 0);
213
+ 0, "The expressions of the same date in two different time zones are considered equal");
115
214
 
116
- var exception = null;
117
215
  try {
118
216
  equals(SC.DateTime.compareDate(
119
217
  SC.DateTime.create({year: 1985, month: 5, day: 7, hour: 23, minute: 0, second: 22, millisecond: 925, timezone: 0}),
@@ -122,70 +220,71 @@ test('compare', function() {
122
220
  } catch(e) {
123
221
  exception = e;
124
222
  } finally {
125
- ok(!SC.none(exception), "Comparing two dates with a different timezone should throw an exception.");
223
+ ok(!SC.none(exception), "Comparing two dates with a different timezone via compareDate() should throw an exception.");
126
224
  }
127
-
128
- equals(SC.compare(dt, dt.advance({timezone: 120, minutes: 120})), 0);
129
225
  });
130
226
 
131
227
  test('Format', function() {
132
228
  equals(
133
229
  dt.toFormattedString('%a %A %b %B %d %H %I %j %m %M %p %S %w %y %Y %%a'),
134
- 'Wed Wednesday May May 08 01 01 128 05 00 AM 22 3 85 1985 %a');
135
-
136
- equals(dt.toFormattedString('%Z'), formatTimezone(SC.DateTime.timezone));
137
- equals(dt.adjust({timezone: 0}).toFormattedString('%Y-%m-%d %H:%M:%S %Z'), '1985-05-08 01:00:22 +00:00');
138
- equals(dt.adjust({timezone: -120}).toFormattedString('%Y-%m-%d %H:%M:%S %Z'), '1985-05-08 01:00:22 +02:00');
139
- equals(dt.adjust({timezone: 420}).toFormattedString('%Y-%m-%d %H:%M:%S %Z'), '1985-05-08 01:00:22 -07:00');
230
+ 'Sat Saturday Jun June 08 04 04 159 06 00 AM 22 6 85 1985 %a');
140
231
 
232
+ equals(dt.toFormattedString('%Z'), formatTimezone(dt.get('timezone')));
233
+ equals(dt.adjust({ timezone: 0 }).toFormattedString('%Y-%m-%d %H:%M:%S %Z'), '1985-06-08 05:00:22 +00:00');
234
+ equals(dt.adjust({ timezone: -120 }).toFormattedString('%Y-%m-%d %H:%M:%S %Z'), '1985-06-08 07:00:22 +02:00');
235
+ equals(dt.adjust({ timezone: 420 }).toFormattedString('%Y-%m-%d %H:%M:%S %Z'), '1985-06-07 22:00:22 -07:00'); // the previous day
141
236
  });
142
237
 
143
238
  test('fancy getters', function() {
144
239
  equals(dt.get('isLeapYear'), NO);
145
- equals(SC.DateTime.create({year: 1900}).get('isLeapYear'), NO);
146
- equals(SC.DateTime.create({year: 2000}).get('isLeapYear'), YES);
147
- equals(SC.DateTime.create({year: 2004}).get('isLeapYear'), YES);
148
-
149
- equals(dt.get('daysInMonth'), 31);
150
- equals(SC.DateTime.create({year: 2000, month: 2}).get('daysInMonth'), 29);
151
- equals(SC.DateTime.create({year: 2001, month: 2}).get('daysInMonth'), 28);
152
-
153
- equals(dt.get('dayOfYear'), 128);
154
- equals(SC.DateTime.create({year: 2000, month: 12, day: 31}).get('dayOfYear'), 366);
155
- equals(SC.DateTime.create({year: 2001, month: 12, day: 31}).get('dayOfYear'), 365);
240
+
241
+ // (note must set all three components of a date
242
+ // in order to get predictable results, per JS Date object spec)
243
+ equals(SC.DateTime.create({ year: 1900, month: 1, day: 1 }).get('isLeapYear'), NO);
244
+ equals(SC.DateTime.create({ year: 2000, month: 1, day: 1 }).get('isLeapYear'), YES);
245
+ equals(SC.DateTime.create({ year: 2004, month: 1, day: 1 }).get('isLeapYear'), YES);
156
246
 
157
- equals(dt.get('week'), 18);
158
- equals(SC.DateTime.create({year: 2006, month: 1, day: 1}).get('week0'), 1);
159
- equals(SC.DateTime.create({year: 2006, month: 1, day: 1}).get('week1'), 0);
160
- equals(SC.DateTime.create({year: 2006, month: 1, day: 8}).get('week0'), 2);
161
- equals(SC.DateTime.create({year: 2006, month: 1, day: 8}).get('week1'), 1);
162
- equals(SC.DateTime.create({year: 2006, month: 12, day: 31}).get('week0'), 53);
163
- equals(SC.DateTime.create({year: 2006, month: 12, day: 31}).get('week1'), 52);
247
+ equals(dt.get('daysInMonth'), 30); // june
248
+ equals(SC.DateTime.create({ year: 2000, month: 2, day: 1 }).get('daysInMonth'), 29);
249
+ equals(SC.DateTime.create({ year: 2001, month: 2, day: 1 }).get('daysInMonth'), 28);
164
250
 
165
- equals(dt.get('lastMonday'), dt.advance({day: -2}).adjust({hour: 0}));
166
- equals(dt.get('nextFriday'), dt.advance({day: 2}).adjust({hour: 0}));
167
- equals(dt.get('lastWednesday'), dt.advance({day: -7}).adjust({hour: 0}));
168
- });
251
+ equals(dt.get('dayOfYear'), 159);
252
+ equals(SC.DateTime.create({ year: 2000, month: 12, day: 31 }).get('dayOfYear'), 366);
253
+ equals(SC.DateTime.create({ year: 2001, month: 12, day: 31 }).get('dayOfYear'), 365);
169
254
 
255
+ equals(dt.get('week'), 22);
256
+ equals(SC.DateTime.create({ year: 2006, month: 1, day: 1 }).get('week0'), 1);
257
+ equals(SC.DateTime.create({ year: 2006, month: 1, day: 1 }).get('week1'), 0);
258
+ equals(SC.DateTime.create({ year: 2006, month: 1, day: 8 }).get('week0'), 2);
259
+ equals(SC.DateTime.create({ year: 2006, month: 1, day: 8 }).get('week1'), 1);
260
+ equals(SC.DateTime.create({ year: 2006, month: 12, day: 31 }).get('week0'), 53);
261
+ equals(SC.DateTime.create({ year: 2006, month: 12, day: 31 }).get('week1'), 52);
262
+
263
+ var e = dt.get('lastMonday');
264
+ equals(dt.get('lastMonday'), dt.advance({ day: -5 }));
265
+ equals(dt.get('nextFriday'), dt.advance({ day: 6 }));
266
+ equals(dt.get('lastWednesday'), dt.advance({ day: -3 }));
267
+ });
268
+
170
269
  test('parse', function() {
171
270
  timeShouldBeEqualToHash(
172
271
  SC.DateTime.parse('08/05/1985 01:00:22 %a', '%d/%m/%Y %H:%M:%S %%a'),
173
- {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 0});
272
+ { year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 0 });
174
273
  timeShouldBeEqualToHash(
175
274
  SC.DateTime.parse('08/05/1985 01:00:22 PM', '%d/%m/%Y %H:%M:%S %p'),
176
- {year: 1985, month: 5, day: 8, hour: 13, minute: 0, second: 22, millisecond: 0});
275
+ { year: 1985, month: 5, day: 8, hour: 13, minute: 0, second: 22, millisecond: 0 });
177
276
  timeShouldBeEqualToHash(
178
277
  SC.DateTime.parse('Wed 08 May 1985 01:00:22 AM', '%a %d %b %Y %H:%M:%S %p'),
179
- {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 0});
278
+ { year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 0 });
180
279
  ok(
181
280
  SC.DateTime.parse('Tue 08 May 1985 01:00:22 AM', '%a %d %b %Y %H:%M:%S %p')
182
281
  === null, '1985-05-08 is not a tuesday');
183
282
  timeShouldBeEqualToHash(
184
283
  SC.DateTime.parse('70-01-01 00:00:00', '%y-%m-%d %H:%M:%S'),
185
- {year: 2070, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0});
284
+ { year: 2070, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0 });
186
285
  timeShouldBeEqualToHash(
187
286
  SC.DateTime.parse('71-01-01 00:00:00', '%y-%m-%d %H:%M:%S'),
188
- {year: 1971, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0});
287
+ { year: 1971, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0 });
189
288
  });
190
289
 
191
290
  test('parse with time zones',function() {
@@ -203,9 +302,10 @@ test('parse with time zones',function() {
203
302
  test('binding', function() {
204
303
  var fromObject = SC.Object.create({value: dt});
205
304
  var toObject = SC.Object.create({value: ''});
206
- var binding = SC.Binding.dateTime('%Y-%m-%d %H:%M:%S').from('value', fromObject).to('value', toObject).connect();
305
+ var format = '%Y-%m-%d %H:%M:%S';
306
+ var binding = SC.Binding.dateTime(format).from('value', fromObject).to('value', toObject).connect();
207
307
  SC.Binding.flushPendingChanges();
208
- equals(toObject.get('value'), '1985-05-08 01:00:22');
308
+ equals(toObject.get('value'), dt.toFormattedString(format));
209
309
  });
210
310
 
211
311
  test('cache', function() {
@@ -225,28 +325,29 @@ test('cache', function() {
225
325
  ok(
226
326
  SC.keys(SC.DateTime._dt_cache).length <= 2*SC.DateTime._DT_CACHE_MAX_LENGTH,
227
327
  "Creating a lot of datetimes should not make a cache larger than the maximum allowed size");
228
-
328
+
229
329
  });
230
330
 
231
331
  test('timezones', function() {
332
+ var o = options;
333
+
232
334
  options.timezone = 0;
233
335
  timeShouldBeEqualToHash(SC.DateTime.create(options), options);
234
- timeShouldBeEqualToHash(SC.DateTime.create(ms), options);
235
336
 
236
337
  options.timezone = -120;
237
338
  timeShouldBeEqualToHash(SC.DateTime.create(options), options);
238
-
339
+
239
340
  options.timezone = 330;
240
341
  timeShouldBeEqualToHash(SC.DateTime.create(options), options);
241
342
 
242
- options.timezone = 0;
343
+ options.timezone = 0; // note that test dates will now be created at timezone 0
243
344
  dt = SC.DateTime.create(options);
244
-
245
- timeShouldBeEqualToHash(dt, {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: 0});
246
- timeShouldBeEqualToHash(dt.toTimezone(480), {year: 1985, month: 5, day: 7, hour: 17, minute: 0, second: 22, millisecond: 925, timezone: 480});
247
- timeShouldBeEqualToHash(dt.toTimezone(420), {year: 1985, month: 5, day: 7, hour: 18, minute: 0, second: 22, millisecond: 925, timezone: 420});
248
- timeShouldBeEqualToHash(dt.toTimezone(), {year: 1985, month: 5, day: 8, hour: 1, minute: 0, second: 22, millisecond: 925, timezone: 0});
249
- timeShouldBeEqualToHash(dt.toTimezone( -60), {year: 1985, month: 5, day: 8, hour: 2, minute: 0, second: 22, millisecond: 925, timezone: -60});
250
- timeShouldBeEqualToHash(dt.toTimezone(-120), {year: 1985, month: 5, day: 8, hour: 3, minute: 0, second: 22, millisecond: 925, timezone: -120});
251
- timeShouldBeEqualToHash(dt.toTimezone(-330), {year: 1985, month: 5, day: 8, hour: 6, minute: 30, second: 22, millisecond: 925, timezone: -330});
345
+
346
+ timeShouldBeEqualToHash(dt, {year: o.year, month: o.month, day: o.day, hour: o.hour, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: o.timezone });
347
+ timeShouldBeEqualToHash(dt.toTimezone(480), {year: o.year, month: o.month, day: o.day - 1, hour: 20, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: 480 });
348
+ timeShouldBeEqualToHash(dt.toTimezone(420), {year: o.year, month: o.month, day: o.day - 1, hour: 21, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: 420 });
349
+ timeShouldBeEqualToHash(dt.toTimezone(), {year: o.year, month: o.month, day: o.day, hour: o.hour, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: 0 });
350
+ timeShouldBeEqualToHash(dt.toTimezone(-60), {year: o.year, month: o.month, day: o.day, hour: 5, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: -60 });
351
+ timeShouldBeEqualToHash(dt.toTimezone(-120), {year: o.year, month: o.month, day: o.day, hour: 6, minute: o.minute, second: o.second, millisecond: o.millisecond, timezone: -120 });
352
+ timeShouldBeEqualToHash(dt.toTimezone(-330), {year: o.year, month: o.month, day: o.day, hour: 9, minute: 30, second: o.second, millisecond: o.millisecond, timezone: -330 });
252
353
  });