sproutcore 1.0.1042 → 1.0.1043

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  });