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 +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +82 -8
- data/app/assets/javascripts/local_time.js.coffee +52 -15
- data/app/helpers/local_time_helper.rb +47 -8
- data/test/helpers/local_time_helper_test.rb +72 -2
- data/test/javascripts/{index.js.coffee → local_time/index.js.coffee} +11 -5
- data/test/javascripts/{unit → local_time}/local_time_test.js.coffee +1 -1
- data/test/javascripts/{unit → local_time}/page_events_test.js.coffee +0 -5
- data/test/javascripts/local_time/public_api_test.js.coffee +11 -0
- data/test/javascripts/local_time/relative_date_test.js.coffee +65 -0
- data/test/javascripts/{unit → local_time}/strftime_test.js.coffee +10 -2
- data/test/javascripts/{unit → local_time}/time_ago_test.js.coffee +5 -6
- data/test/javascripts/{config.ru → runner/config.ru} +2 -3
- data/test/javascripts/{index.html → runner/index.html} +2 -2
- data/test/javascripts/vendor/moment.js +6 -0
- data/test/javascripts/vendor/qunit.css +244 -0
- data/test/javascripts/vendor/qunit.js +2212 -0
- data/test/javascripts/vendor/run-qunit.coffee +50 -0
- data/test/javascripts/vendor/sinon-timers.js +385 -0
- metadata +32 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d42dfef630d09374cd897d5a842566191ff07cd
|
|
4
|
+
data.tar.gz: 671f048d37ba09ade8df1e01dd8c4bb36f5ccfab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6209af737d470ff029db6233ca5f30e6840e8e74c40db30aca1a8ad9a592dbd705ea2159ff16eb37118946dee8d6f6db1fbfd69d6f129d30b9aab1c3f3a93b18
|
|
7
|
+
data.tar.gz: 26786c11ec81af062927263f55e5f4103532dbdc871d535e0e272a5c95b8a94f6e8979d165154330c3bc2cc0b93ac202f4202546f04258012e75b82d4c1d8ce1
|
data/MIT-LICENSE
CHANGED
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
|
|
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)
|
|
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
|
-
|
|
34
|
-
|
|
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
|
-
|
|
37
|
-
<%=
|
|
56
|
+
```erb
|
|
57
|
+
<%= local_time(time, format: '%B %e, %Y %l:%M%P', class: 'my-time') %>
|
|
38
58
|
```
|
|
39
59
|
|
|
40
|
-
|
|
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
|
|
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 /%([%
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
193
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
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
|
|
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:
|
|
27
|
+
options[:data].merge! local: type
|
|
28
|
+
|
|
29
|
+
time_tag time, time.strftime(DEFAULT_FORMAT), options
|
|
30
|
+
end
|
|
22
31
|
|
|
23
|
-
|
|
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 <
|
|
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
|
-
|
|
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",
|
|
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
|
|
@@ -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,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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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("
|
|
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>
|