local_time 0.2.0 → 1.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c2499d2a165c030164525b49b02920c90c4b4953
4
- data.tar.gz: 41e33a6cbb60e66d98aba1a9089b82e324207314
3
+ metadata.gz: 0d42dfef630d09374cd897d5a842566191ff07cd
4
+ data.tar.gz: 671f048d37ba09ade8df1e01dd8c4bb36f5ccfab
5
5
  SHA512:
6
- metadata.gz: a03eda21f6d818690cf468931e43f832afdf5fc27a5adaac2d6af551b48b5f2fff3b0990e98d5ef2d49edd3ff361a4776c2e10a691a8598f69940844108c984f
7
- data.tar.gz: d9843bb2c0f6a8f892a99218a1e95c25ea88f55ddef92be471ceac46ce25d352974947219c08de3e0cfe96b28fb4081cde6b7ebe09432673628db4e6e963a53f
6
+ metadata.gz: 6209af737d470ff029db6233ca5f30e6840e8e74c40db30aca1a8ad9a592dbd705ea2159ff16eb37118946dee8d6f6db1fbfd69d6f129d30b9aab1c3f3a93b18
7
+ data.tar.gz: 26786c11ec81af062927263f55e5f4103532dbdc871d535e0e272a5c95b8a94f6e8979d165154330c3bc2cc0b93ac202f4202546f04258012e75b82d4c1d8ce1
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2013 Javan Makhmali
1
+ Copyright 2014 Javan Makhmali, Basecamp
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,11 +1,16 @@
1
- Local Time is a Rails engine with helpers and JavaScript for displaying times and dates to users in their local time. The helpers render a `<time>` element in UTC and the JavaScript swoops in to convert and format. Because the `<time>` element is only rendered in one timezone, it is ideal for caching.
1
+ Local Time is a Rails engine with helpers and JavaScript for displaying times and dates to users in their local time. The helpers render a `<time>` element and the JavaScript swoops in to convert and format. The helper output is ideal for caching since it's always in UTC time.
2
2
 
3
3
  ---
4
4
 
5
5
  ####Example
6
6
 
7
+ ```ruby
8
+ > comment.created_at
9
+ "Wed, 27 Nov 2013 18:43:22 EST -0500"
10
+ ```
11
+
7
12
  ```erb
8
- <%= local_time(comment.created_at) # comment.created_at => Wed, 27 Nov 2013 18:43:22 EST -0500 %>
13
+ <%= local_time(comment.created_at) %>
9
14
  ```
10
15
 
11
16
  Renders:
@@ -22,6 +27,7 @@ When the DOM loads, the content is immediately replaced with a local, formatted
22
27
  <time data-format="%B %e, %Y %l:%M%P"
23
28
  data-local="time"
24
29
  datetime="2013-11-27T23:43:22Z"
30
+ title="November 27, 2013 6:43pm EDT"
25
31
  data-localized="true">November 27, 2013 6:43pm</time>
26
32
  ```
27
33
 
@@ -30,14 +36,36 @@ When the DOM loads, the content is immediately replaced with a local, formatted
30
36
  #### Time and date helpers
31
37
 
32
38
  ```erb
33
- Pass a time and an optional strftime format (default format shown here)
34
- <%= local_time(time, format: '%B %e, %Y %l:%M%P') %>
39
+ <%= local_time(time) %>
40
+ ```
41
+
42
+ Format with a strftime string (default format shown here)
43
+
44
+ ```erb
45
+ <%= local_time(time, '%B %e, %Y %l:%M%P') %>
46
+ ```
47
+
48
+ Alias for `local_time` with a month-formatted default
49
+
50
+ ```erb
51
+ <%= local_date(time, '%B %e, %Y') %>
52
+ ```
53
+
54
+ To set attributes on the time tag, pass a hash as the second argument with a `:format` key and your attributes.
35
55
 
36
- Alias for local_time with a month-formatted default
37
- <%= local_date(time, format: '%B %e, %Y') %>
56
+ ```erb
57
+ <%= local_time(time, format: '%B %e, %Y %l:%M%P', class: 'my-time') %>
38
58
  ```
39
59
 
40
- Note: The included strftime JavaScript implementation is not 100% complete. It supports the following directives: `%a %A %b %B %c %d %e %H %I %l %m %M %p %P %S %w %y %Y`
60
+ To use a strftime format already defined in your app, pass a symbol as the format.
61
+
62
+ ```erb
63
+ <%= local_time(date, :long) %>
64
+ ```
65
+
66
+ `I18n.t("time.formats.#{format}")`, `I18n.t("date.formats.#{format}")`, `Time::DATE_FORMATS[format]`, and `Date::DATE_FORMATS[format]` will be scanned (in that order) for your format.
67
+
68
+ Note: The included strftime JavaScript implementation is not 100% complete. It supports the following directives: `%a %A %b %B %c %d %e %H %I %l %m %M %p %P %S %w %y %Y %Z`
41
69
 
42
70
  #### Time ago helper
43
71
 
@@ -45,7 +73,9 @@ Note: The included strftime JavaScript implementation is not 100% complete. It s
45
73
  <%= local_time_ago(time) %>
46
74
  ```
47
75
 
48
- Displays the relative amount of time passed. With age, the descriptions transition from specific quantities to general dates. The `<time>` elements are updated every 60 seconds. Examples (in quotes):
76
+ Displays the relative amount of time passed. With age, the descriptions transition from {quantity of seconds, minutes, or hours} to {date + time} to {date}. The `<time>` elements are updated every 60 seconds.
77
+
78
+ Examples (in quotes):
49
79
 
50
80
  * Recent: "a second ago", "32 seconds ago", "an hour ago", "14 hours ago"
51
81
  * Yesterday: "yesterday at 5:22pm"
@@ -53,6 +83,22 @@ Displays the relative amount of time passed. With age, the descriptions transiti
53
83
  * This year: "on Nov 17"
54
84
  * Last year: "on Jan 31, 2012"
55
85
 
86
+ #### Relative time helper
87
+
88
+ Preset time and date formats that vary with age. The available types are `date`, `time-ago`, `time-or-date`, and `weekday`. Like the `local_time` helper, `:type` can be passed a string or in an options hash.
89
+
90
+ ```erb
91
+ <%= local_relative_time(time, 'weekday') %>
92
+ <%= local_relative_time(time, type: 'time-or-date') %>
93
+ ```
94
+
95
+ **Available `:type` options**
96
+
97
+ * `date` Inlcudes the year unless it's current. "Apr 11" or "Apr 11, 2013"
98
+ * `time-ago` See above. `local_time_ago` calls `local_relative_time` with this `:type` option.
99
+ * `time-or-date` Displays the time if it's todday. Displays time otherwise. "3:26pm" or "Apr 11"
100
+ * `weekday` Displays "Today", "Yesterday", or the weekday (e.g. Wednesday) if the time is within a week of today.
101
+
56
102
  #### Installation
57
103
 
58
104
  1. Add `gem 'local_time'` to your Gemfile.
@@ -63,8 +109,36 @@ Displays the relative amount of time passed. With age, the descriptions transiti
63
109
 
64
110
  The included JavaScript does not depend on any frameworks or libraries, and listens for a `DOMContentLoaded` event to run initially. It also listens on `document` for `page:update` if you're using Turbolinks and `ajaxSuccess` if you're using jQuery. This should catch most cases where new `<time>` elements have been added to the DOM and process them automatically. If you're adding new elements in another context, trigger `time:elapse` to process them.
65
111
 
112
+ #### JavaScript API
113
+
114
+ `relativeDate`, `relativeTimeAgo`, `relativeTimeOrDate`, `relativeWeekday`, `run`, and `strftime` methods are available on the global `LocalTime` object.
115
+
116
+ ```js
117
+ > LocalTime.relativeTimeAgo(new Date(new Date - 60 * 1000 * 5))
118
+ "5 minutes ago"
119
+
120
+ // Process <time> tags. Equivalent to dispatching a "time:elapse" Event.
121
+ > LocalTime.run()
122
+
123
+ > LocalTime.strftime(new Date, "%B %e, %Y %l:%M%P")
124
+ "February 9, 2014 12:55pm"
125
+ ```
126
+
66
127
  #### Version History
67
128
 
129
+ **1.0.0** (April 12, 2014)
130
+
131
+ * Added `local_relative_time` helper with several built in types
132
+ * Allow `:format` (and `:type`) option as a bare string or value in hash
133
+ * Added `relativeDate`, `relativeTimeOrDate`, `relativeWeekday` and `run` to the API
134
+ * Dropped ineffective `popstate` event listener
135
+ * Now in use at [Basecamp](https://basecamp.com/)
136
+
137
+ **0.3.0** (February 9, 2014)
138
+
139
+ * Allow :format option lookup in I18n or DATE_FORMATS hashes [Paul Dobbins]
140
+ * Expose public API to JavaScript helpers
141
+
68
142
  **0.2.0** (December 10, 2013)
69
143
 
70
144
  * Prefer `textContent` over `innerText` for Firefox compatibility
@@ -30,7 +30,7 @@ strftime = (time, formatString) ->
30
30
  minute = time.getMinutes()
31
31
  second = time.getSeconds()
32
32
 
33
- formatString.replace /%([%aAbBcdeHIlmMpPSwyY])/g, ([match, modifier]) ->
33
+ formatString.replace /%([%aAbBcdeHIlmMpPSwyYZ])/g, ([match, modifier]) ->
34
34
  switch modifier
35
35
  when '%' then '%'
36
36
  when 'a' then weekdays[day].slice 0, 3
@@ -51,6 +51,7 @@ strftime = (time, formatString) ->
51
51
  when 'w' then day
52
52
  when 'y' then pad year % 100
53
53
  when 'Y' then year
54
+ when 'Z' then time.toString().match(/\((\w+)\)$/)?[1] ? ''
54
55
 
55
56
 
56
57
  class CalendarDate
@@ -67,6 +68,16 @@ class CalendarDate
67
68
  @year = @date.getUTCFullYear()
68
69
  @month = @date.getUTCMonth() + 1
69
70
  @day = @date.getUTCDate()
71
+ @value = @date.getTime()
72
+
73
+ equals: (calendarDate) ->
74
+ calendarDate?.value is @value
75
+
76
+ is: (calendarDate) ->
77
+ @equals calendarDate
78
+
79
+ isToday: ->
80
+ @is @constructor.today()
70
81
 
71
82
  occursOnSameYearAs: (date) ->
72
83
  @year is date?.year
@@ -82,10 +93,7 @@ class CalendarDate
82
93
  @constructor.today().daysSince @
83
94
 
84
95
 
85
- class RelativeTimeAgo
86
- @generate: (date) ->
87
- new this(date).toString()
88
-
96
+ class RelativeTime
89
97
  constructor: (@date) ->
90
98
  @calendarDate = CalendarDate.fromDate @date
91
99
 
@@ -103,6 +111,12 @@ class RelativeTimeAgo
103
111
  else
104
112
  "on #{@formatDate()}"
105
113
 
114
+ toTimeOrDateString: ->
115
+ if @calendarDate.isToday()
116
+ @formatTime()
117
+ else
118
+ @formatDate()
119
+
106
120
  timeElapsed: ->
107
121
  ms = new Date().getTime() - @date.getTime()
108
122
  sec = Math.round ms / 1000
@@ -146,6 +160,19 @@ class RelativeTimeAgo
146
160
  formatTime: ->
147
161
  strftime @date, '%l:%M%P'
148
162
 
163
+ relativeDate = (date) ->
164
+ new RelativeTime(date).formatDate()
165
+
166
+ relativeTimeAgo = (date) ->
167
+ new RelativeTime(date).toString()
168
+
169
+ relativeTimeOrDate = (date) ->
170
+ new RelativeTime(date).toTimeOrDateString()
171
+
172
+ relativeWeekday = (date) ->
173
+ if day = new RelativeTime(date).relativeWeekday()
174
+ day.charAt(0).toUpperCase() + day.substring(1)
175
+
149
176
 
150
177
  domLoaded = false
151
178
 
@@ -157,10 +184,6 @@ update = (callback) ->
157
184
  if Turbolinks?.supported
158
185
  document.addEventListener "page:update", callback
159
186
  else
160
- setTimeout ->
161
- window.addEventListener "popstate", callback
162
- , 1
163
-
164
187
  jQuery?(document).on "ajaxSuccess", (event, xhr) ->
165
188
  callback() if jQuery.trim xhr.responseText
166
189
 
@@ -181,16 +204,30 @@ document.addEventListener "DOMContentLoaded", ->
181
204
  time = new Date Date.parse datetime
182
205
  return if isNaN time
183
206
 
207
+ unless element.hasAttribute("title")
208
+ element.setAttribute "title", strftime(time, "%B %e, %Y at %l:%M%P %Z")
209
+
184
210
  element[textProperty] =
185
211
  switch local
212
+ when "date"
213
+ element.setAttribute "data-localized", true
214
+ relativeDate time
186
215
  when "time"
187
216
  element.setAttribute "data-localized", true
188
217
  strftime time, format
189
218
  when "time-ago"
190
- RelativeTimeAgo.generate time
219
+ relativeTimeAgo time
220
+ when "time-or-date"
221
+ relativeTimeOrDate time
222
+ when "weekday"
223
+ relativeWeekday(time) ? ""
224
+
225
+ run = ->
226
+ event = document.createEvent "Events"
227
+ event.initEvent "time:elapse", true, true
228
+ document.dispatchEvent event
229
+
230
+ setInterval run, 60 * 1000
191
231
 
192
- setInterval ->
193
- event = document.createEvent "Events"
194
- event.initEvent "time:elapse", true, true
195
- document.dispatchEvent event
196
- , 60 * 1000
232
+ # Public API
233
+ @LocalTime = {relativeDate, relativeTimeAgo, relativeTimeOrDate, relativeWeekday, run, strftime}
@@ -1,7 +1,11 @@
1
1
  module LocalTimeHelper
2
- def local_time(time, options = {})
3
- time = utc_time(time)
4
- format = options.delete(:format).presence || '%B %e, %Y %l:%M%P'
2
+ DEFAULT_FORMAT = '%B %e, %Y %l:%M%P'
3
+
4
+ def local_time(time, options = nil)
5
+ time = utc_time(time)
6
+
7
+ options, format = extract_options_and_value(options, :format)
8
+ format = find_time_format(format)
5
9
 
6
10
  options[:data] ||= {}
7
11
  options[:data].merge! local: :time, format: format
@@ -9,18 +13,26 @@ module LocalTimeHelper
9
13
  time_tag time, time.strftime(format), options
10
14
  end
11
15
 
12
- def local_date(time, options = {})
13
- options.reverse_merge! format: '%B %e, %Y'
16
+ def local_date(time, options = nil)
17
+ options, format = extract_options_and_value(options, :format)
18
+ options[:format] = format || '%B %e, %Y'
14
19
  local_time time, options
15
20
  end
16
21
 
17
- def local_time_ago(time, options = {})
22
+ def local_relative_time(time, options = nil)
18
23
  time = utc_time(time)
24
+ options, type = extract_options_and_value(options, :type)
19
25
 
20
26
  options[:data] ||= {}
21
- options[:data].merge! local: 'time-ago'
27
+ options[:data].merge! local: type
28
+
29
+ time_tag time, time.strftime(DEFAULT_FORMAT), options
30
+ end
22
31
 
23
- time_tag time, time.strftime('%B %e, %Y %l:%M%P'), options
32
+ def local_time_ago(time, options = nil)
33
+ options, type = extract_options_and_value(options, :type)
34
+ options[:type] = 'time-ago'
35
+ local_relative_time time, options
24
36
  end
25
37
 
26
38
  def utc_time(time_or_date)
@@ -30,4 +42,31 @@ module LocalTimeHelper
30
42
  time_or_date.to_time.utc
31
43
  end
32
44
  end
45
+
46
+ private
47
+ def find_time_format(format)
48
+ if format.is_a?(Symbol)
49
+ if (i18n_format = I18n.t("time.formats.#{format}", default: [:"date.formats.#{format}", ''])).present?
50
+ i18n_format
51
+ elsif (date_format = Time::DATE_FORMATS[format] || Date::DATE_FORMATS[format])
52
+ date_format.is_a?(Proc) ? DEFAULT_FORMAT : date_format
53
+ else
54
+ DEFAULT_FORMAT
55
+ end
56
+ else
57
+ format.presence || DEFAULT_FORMAT
58
+ end
59
+ end
60
+
61
+ def extract_options_and_value(options, value_key = nil)
62
+ case options
63
+ when Hash
64
+ value = options.delete(value_key)
65
+ [ options, value ]
66
+ when NilClass
67
+ [ {} ]
68
+ else
69
+ [ {}, options ]
70
+ end
71
+ end
33
72
  end
@@ -1,16 +1,30 @@
1
1
  require_relative '../../app/helpers/local_time_helper'
2
2
  require 'active_support/all'
3
3
  require 'action_view'
4
+
4
5
  require 'minitest/autorun'
6
+ begin
7
+ # 2.0.0
8
+ class TestCase < MiniTest::Test; end
9
+ rescue NameError
10
+ # 1.9.3
11
+ class TestCase < MiniTest::Unit::TestCase; end
12
+ end
5
13
 
14
+ I18n.enforce_available_locales = false
6
15
 
7
- class LocalTimeHelperTest < MiniTest::Unit::TestCase
16
+ class LocalTimeHelperTest < TestCase
8
17
  include ActionView::Helpers::DateHelper, ActionView::Helpers::TagHelper
9
18
  include LocalTimeHelper
10
19
 
11
20
  def setup
12
21
  @original_zone = Time.zone
13
22
  Time.zone = ActiveSupport::TimeZone["Central Time (US & Canada)"]
23
+ I18n.backend.store_translations(:en, {
24
+ time: { formats: { simple_time: "%b %e" } },
25
+ date: { formats: { simple_date: "%b %e" } } })
26
+ Time::DATE_FORMATS[:time_formats_simple_time] = '%b %e'
27
+ Date::DATE_FORMATS[:date_formats_simple_date] = '%b %e'
14
28
 
15
29
  @date = "2013-11-21"
16
30
  @time = Time.zone.parse(@date)
@@ -45,6 +59,32 @@ class LocalTimeHelperTest < MiniTest::Unit::TestCase
45
59
  assert_equal expected, local_time(@time, format: '%b %e')
46
60
  end
47
61
 
62
+ def test_local_time_with_format_as_string
63
+ expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}">Nov 21</time>)
64
+ assert_equal expected, local_time(@time, '%b %e')
65
+ end
66
+
67
+ def test_local_time_with_i18n_format
68
+ expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}">Nov 21</time>)
69
+ assert_equal expected, local_time(@time, format: :simple_time)
70
+ end
71
+
72
+ def test_local_time_with_date_formats_format
73
+ expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}">Nov 21</time>)
74
+ assert_equal expected, local_time(@time, format: :time_formats_simple_time)
75
+ end
76
+
77
+ def test_local_time_with_missing_i18n_and_date_formats_format
78
+ expected = %Q(<time data-format="%B %e, %Y %l:%M%P" data-local="time" datetime="#{@time_js}">November 21, 2013 6:00am</time>)
79
+ assert_equal expected, local_time(@time, format: :missing_format)
80
+ end
81
+
82
+ def test_local_time_with_date_formats_proc_format
83
+ Time::DATE_FORMATS[:proc] = proc { |time| "nope" }
84
+ expected = %Q(<time data-format="%B %e, %Y %l:%M%P" data-local="time" datetime="#{@time_js}">November 21, 2013 6:00am</time>)
85
+ assert_equal expected, local_time(@time, format: :proc)
86
+ end
87
+
48
88
  def test_local_time_with_options
49
89
  expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}" style="display:none">Nov 21</time>)
50
90
  assert_equal expected, local_time(@time, format: '%b %e', style: 'display:none')
@@ -58,7 +98,27 @@ class LocalTimeHelperTest < MiniTest::Unit::TestCase
58
98
 
59
99
  def test_local_date_with_format
60
100
  expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}">Nov 21</time>)
61
- assert_equal expected, local_date(@time, format: '%b %e')
101
+ assert_equal expected, local_date(@time.to_date, format: '%b %e')
102
+ end
103
+
104
+ def test_local_date_with_format_as_string
105
+ expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}">Nov 21</time>)
106
+ assert_equal expected, local_date(@time.to_date, '%b %e')
107
+ end
108
+
109
+ def test_local_date_with_i18n_format
110
+ expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}">Nov 21</time>)
111
+ assert_equal expected, local_date(@time.to_date, format: :simple_date)
112
+ end
113
+
114
+ def test_local_date_with_date_formats_format
115
+ expected = %Q(<time data-format="%b %e" data-local="time" datetime="#{@time_js}">Nov 21</time>)
116
+ assert_equal expected, local_date(@time.to_date, format: :date_formats_simple_date)
117
+ end
118
+
119
+ def test_local_date_with_missing_i18n_and_date_formats_format
120
+ expected = %Q(<time data-format="%B %e, %Y %l:%M%P" data-local="time" datetime="#{@time_js}">November 21, 2013 6:00am</time>)
121
+ assert_equal expected, local_date(@time.to_date, format: :missing_date_format)
62
122
  end
63
123
 
64
124
  def test_local_time_ago
@@ -70,4 +130,14 @@ class LocalTimeHelperTest < MiniTest::Unit::TestCase
70
130
  expected = %Q(<time class="date-time" data-local="time-ago" datetime="#{@time_js}">November 21, 2013 6:00am</time>)
71
131
  assert_equal expected, local_time_ago(@time, class: "date-time")
72
132
  end
133
+
134
+ def test_relative_time
135
+ expected = %Q(<time data-local="time-or-date" datetime="#{@time_js}">November 21, 2013 6:00am</time>)
136
+ assert_equal expected, local_relative_time(@time, type: "time-or-date")
137
+ end
138
+
139
+ def test_local_time_ago_with_type_as_string
140
+ expected = %Q(<time data-local="time-or-date" datetime="#{@time_js}">November 21, 2013 6:00am</time>)
141
+ assert_equal expected, local_relative_time(@time, "time-or-date")
142
+ end
73
143
  end
@@ -1,12 +1,18 @@
1
- #= require qunit
2
- #= require moment
1
+ #= require vendor/qunit
2
+ #= require vendor/moment
3
+ #= require vendor/sinon-timers
3
4
  #= require local_time
4
- #= require_directory ./unit
5
+
5
6
  #= require_self
7
+ #= require_directory .
8
+
9
+ @addTimeEl = ({format, type, datetime} = {}) ->
10
+ format ?= "%Y"
11
+ type ?= "time"
12
+ datetime ?= "2013-11-12T12:13:00Z"
6
13
 
7
- @addTimeEl = (format = "%Y", datetime = "2013-11-12T12:13:00Z") ->
8
14
  el = document.createElement "time"
9
- el.setAttribute "data-local", "time"
15
+ el.setAttribute "data-local", type
10
16
  el.setAttribute "data-format", format
11
17
  el.setAttribute "datetime", datetime
12
18
  document.body.appendChild el
@@ -8,7 +8,7 @@ test "date", ->
8
8
  assertLocalized "date", "date"
9
9
 
10
10
  test "unparseable time", ->
11
- el = addTimeEl "%Y", ":("
11
+ el = addTimeEl format: "%Y", datetime: ":("
12
12
  setText el, "2013"
13
13
  run()
14
14
  equal getText(el), "2013"
@@ -10,11 +10,6 @@ test "document time:elapse", ->
10
10
  triggerEvent "time:elapse"
11
11
  ok getText el
12
12
 
13
- test "window popstate", ->
14
- el = addTimeEl()
15
- triggerEvent "popstate", window
16
- ok getText el
17
-
18
13
  test "document page:update with Turbolinks on", ->
19
14
  el = addTimeEl()
20
15
  triggerEvent "page:update"
@@ -0,0 +1,11 @@
1
+ module "public API"
2
+
3
+ for name, method of @LocalTime when name isnt "strftime"
4
+ do (name, method) ->
5
+ test "##{name}", ->
6
+ ok method(new Date())
7
+
8
+ {strftime} = @LocalTime
9
+
10
+ test "#strftime", =>
11
+ ok strftime(new Date(), "%Y")
@@ -0,0 +1,65 @@
1
+ module "relative date"
2
+
3
+ test "this year", ->
4
+ now = moment()
5
+ el = addTimeEl type: "date", datetime: now.toISOString()
6
+ run()
7
+
8
+ equal getText(el), now.format("MMM D")
9
+
10
+ test "last year", ->
11
+ before = moment().subtract("years", 1).subtract("days", 1)
12
+ el = addTimeEl type: "date", datetime: before.toISOString()
13
+ run()
14
+
15
+ equal getText(el), before.format("MMM D, YYYY")
16
+
17
+
18
+ module "relative time or date"
19
+
20
+
21
+ test "today", ->
22
+ now = moment()
23
+ el = addTimeEl type: "time-or-date", datetime: now.toISOString()
24
+ run()
25
+
26
+ equal getText(el), now.format("h:mma")
27
+
28
+ test "before today", ->
29
+ before = moment().subtract("days", 1)
30
+ el = addTimeEl type: "time-or-date", datetime: before.toISOString()
31
+ run()
32
+
33
+ equal getText(el), before.format("MMM D")
34
+
35
+
36
+ module "relative weekday"
37
+
38
+
39
+ test "today", ->
40
+ now = moment()
41
+ el = addTimeEl type: "weekday", datetime: now.toISOString()
42
+ run()
43
+
44
+ equal getText(el), "Today"
45
+
46
+ test "yesterday", ->
47
+ yesterday = moment().subtract("days", 1)
48
+ el = addTimeEl type: "weekday", datetime: yesterday.toISOString()
49
+ run()
50
+
51
+ equal getText(el), "Yesterday"
52
+
53
+ test "this week", ->
54
+ recent = moment().subtract("days", 3)
55
+ el = addTimeEl type: "weekday", datetime: recent.toISOString()
56
+ run()
57
+
58
+ equal getText(el), recent.format("dddd")
59
+
60
+ test "before this week", ->
61
+ before = moment().subtract("days", 8)
62
+ el = addTimeEl type: "weekday", datetime: before.toISOString()
63
+ run()
64
+
65
+ equal getText(el), ""
@@ -24,12 +24,12 @@ for day in [0..30] by 6
24
24
  do (day) ->
25
25
  for hour in [0..24] by 6
26
26
  do (hour) ->
27
+
27
28
  for format, momentFormat of momentMap
28
29
  do (format, momentFormat) ->
29
-
30
30
  test "#{format} (+#{day} days, #{hour} hours)", ->
31
31
  now = moment().add("days", day).add("hours", hour)
32
- el = addTimeEl format, now.toISOString()
32
+ el = addTimeEl {format, datetime: now.toISOString()}
33
33
  run()
34
34
 
35
35
  equal getText(el),
@@ -38,3 +38,11 @@ for day in [0..30] by 6
38
38
  else
39
39
  now.format momentFormat
40
40
 
41
+ test "%Z Timezone (+#{day} days, #{hour} hours)", ->
42
+ now = moment().add("days", day).add("hours", hour)
43
+ el = addTimeEl format: "%Z", datetime: now.toISOString()
44
+ run()
45
+
46
+ text = getText el
47
+ ok /^\w{3,4}$/.test(text), "#{text} doesn't look like a timezone"
48
+
@@ -30,12 +30,11 @@ test "last week", ->
30
30
  assertTimeAgo "#{day} at #{time}", "days", 5
31
31
 
32
32
  test "this year", ->
33
- # This will fail on the first 7 days of the year.
34
- # Not sure how to test without somehow stubbing Date.
35
- if moment().dayOfYear() > 7
36
- date = moment().subtract("days", 7).format "MMM D"
37
- assertTimeAgo "on #{date}", "days", 7
38
-
33
+ clock = sinon.useFakeTimers(new Date(2013,11,11,11,11).getTime(), "Date")
34
+ date = moment().subtract("days", 7).format "MMM D"
35
+ assertTimeAgo "on #{date}", "days", 7
36
+ clock.restore()
37
+
39
38
  test "last year", ->
40
39
  date = moment().subtract("days", 366).format "MMM D, YYYY"
41
40
  assertTimeAgo "on #{date}", "days", 366
@@ -1,12 +1,11 @@
1
1
  require 'sprockets'
2
2
  require 'coffee-rails'
3
3
 
4
- Root = File.expand_path("../../..", __FILE__)
4
+ Root = File.expand_path("../../../..", __FILE__)
5
5
 
6
6
  Assets = Sprockets::Environment.new(Root) do |env|
7
7
  env.append_path "app/assets/javascripts"
8
8
  env.append_path "test/javascripts"
9
- env.append_path "vendor"
10
9
  end
11
10
 
12
11
  map "/css" do
@@ -17,4 +16,4 @@ map "/js" do
17
16
  run Assets
18
17
  end
19
18
 
20
- map("/") { run Rack::File.new("#{Root}/test/javascripts/index.html") }
19
+ map("/") { run Rack::File.new("#{Root}/test/javascripts/runner/index.html") }
@@ -2,8 +2,8 @@
2
2
  <html>
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <link rel="stylesheet" href="/css/qunit.css">
6
- <script type="text/javascript" src="/js/index.js"></script>
5
+ <link rel="stylesheet" href="/css/vendor/qunit.css">
6
+ <script type="text/javascript" src="/js/local_time/index.js"></script>
7
7
  </head>
8
8
  <body>
9
9
  <div id="qunit"></div>