kronic 0.4.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source :rubygems
2
2
 
3
3
  gemspec
4
+
5
+ platforms(:ruby) do
6
+ gem 'therubyracer', '>= 0.8.0.pre2'
7
+ end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kronic (0.4)
4
+ kronic (0.4.1)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -18,6 +18,7 @@ GEM
18
18
  rspec-mocks (2.0.0.beta.22)
19
19
  rspec-core (= 2.0.0.beta.22)
20
20
  rspec-expectations (= 2.0.0.beta.22)
21
+ therubyracer (0.8.0.pre2)
21
22
  timecop (0.3.5)
22
23
  tzinfo (0.3.23)
23
24
 
@@ -29,5 +30,6 @@ DEPENDENCIES
29
30
  activesupport
30
31
  kronic!
31
32
  rspec (>= 2.0.0.beta.16)
33
+ therubyracer (>= 0.8.0.pre2)
32
34
  timecop
33
35
  tzinfo
data/HISTORY CHANGED
@@ -1,23 +1,27 @@
1
- 0.4.1
1
+ 1.0.0 - 27 October 2010
2
+ * Added javascript implementation
3
+ * Committed to backwards compatibility for current API until v2
4
+
5
+ 0.4.1 - 22 October 2010
2
6
  * Fixed parsing of "January 1999" (returns nil, rather than raising an exception)
3
- * Support optional commas in delimeters: "Sep 14, 2010"
7
+ * Support optional commas in delimiters: "Sep 14, 2010"
4
8
 
5
- 0.4.0
9
+ 0.4.0 - 30 September 2010
6
10
  * Support ISO 8601 dates ("2010-09-30")
7
11
  * Kronic.format supports Time and DateTime as a parameter
8
12
  * Ironclad guarantee it works on 1.8.7, 1.9.2, Rubinius, and JRuby
9
13
 
10
- 0.3.0
14
+ 0.3.0 - 27 September 2010
11
15
  * Support month before day ("June 14")
12
16
  * Support day ordinals ("14th June")
13
17
  * Use Time.zone if available
14
18
  * Fix Kronic.format for ruby 1.8
15
19
 
16
- 0.2.1
20
+ 0.2.1 - 20 September 2010
17
21
  * Removed dependency on active_support, no external dependencies!
18
22
  * Dates in the future with a year specified are parsed correctly
19
23
 
20
- 0.2.0
24
+ 0.2.0 - 20 September 2010
21
25
  * Support "tomorrow"
22
26
  * Support "this monday"
23
27
 
@@ -1,17 +1,11 @@
1
1
  = Kronic
2
2
 
3
- A dirt simple library for parsing human readable dates (Today, Yesterday, Last Monday).
4
-
5
- == Why not Chronic or Tickle
6
-
7
- Chronic and Tickle both parse a *heap* of formats. That's not useful to me when they fail on cases I want (14 Sep), and also not useful because I don't need times or spans. I just want to replace my calendar picker.
8
-
9
- In addition, Kronic can take a date and give you a human readable form, neither of which Chronic nor Tickle does.
10
-
11
- Oh yeah, Kronic is about 150 lines of code with no dependencies.
3
+ A dirt simple library for parsing human readable dates (Today, Yesterday, Last Monday). Both a ruby and a javascript implementation are included.
12
4
 
13
5
  == Usage
14
6
 
7
+ === Ruby
8
+
15
9
  gem install kronic
16
10
 
17
11
  require 'kronic'
@@ -20,12 +14,49 @@ Oh yeah, Kronic is about 150 lines of code with no dependencies.
20
14
 
21
15
  Supported formats: Today, yesterday, tomorrow, last thursday, this thursday, 14 Sep, 14 June 2010. Any dates without a year are assumed to be in the past (that's what my app needs, so that's what it does).
22
16
 
17
+ === Javascript
18
+
19
+ Install by grabbing the latest versions direct from github:
20
+
21
+ curl http://github.com/xaviershay/kronic/raw/master/lib/js/strftime.js > public/javascripts/strftime.js
22
+ curl http://github.com/xaviershay/kronic/raw/master/lib/js/kronic.js > public/javascripts/kronic.js
23
+
24
+ Use with the following script:
25
+
26
+ <script src="/javascripts/strftime.js" type="text/javascript"></script>
27
+ <script src="/javascripts/kronic.js" type="text/javascript"></script>
28
+ <script>
29
+ Kronic.parse("Today");
30
+ Kronic.format(new Date());
31
+ </script>
32
+
33
+ == Why not Chronic or Tickle
34
+
35
+ Chronic and Tickle both parse a *heap* of formats. That's not useful to me when they fail on cases I want (14 Sep), and also not useful because I don't need times or spans. I just want to replace my calendar picker.
36
+
37
+ In addition, Kronic can take a date and give you a human readable form, neither of which Chronic nor Tickle does.
38
+
39
+ Oh yeah, Kronic is about 150 lines of ruby code with no dependencies, and provides a javascript implementation.
40
+
23
41
  == Compatibility
24
42
 
25
43
  Kronic does not require ActiveSupport, but if it is present Kronic will use the current time zone. In short, everything should work as you would expect.
26
44
 
27
- Kronic is tested on 1.8.7, 1.9.2, Rubinius, and JRuby.
45
+ Kronic is tested on 1.8.7, 1.9.2, Rubinius 1.1, and JRuby 1.5.1.
46
+
47
+ == Developing
48
+
49
+ git clone git://github.com/xaviershay/kronic.git
50
+ bundle install # May take a while, needs to install therubyracer/V8 to test JS
51
+ rake
52
+ open spec/kronic_spec.rb
53
+
54
+ There are comments to help you along but it is pretty basic code, so everything should make sense pretty quickly. The javascript code is a direct translation of the ruby code, and as such it is undocumented - just refer back to the ruby code. strftime.js is an external library bundled here for convenience. Do not change it.
55
+
56
+ The exact same set of specs are run again the ruby and javascript libraries, so they should be 100% compatible.
57
+
58
+ Patches welcome! Fork and send a pull request. Please follow coding conventions already in use. If +jsl+ (JSLint) is in your path, rake will run it over the javascript implementation. There are currently no warnings, please keep it that way.
28
59
 
29
- == Future
60
+ == Status
30
61
 
31
- Current release is a release candidate for 1.0, when the API will be declared stable. i18n work has been started in a branch, and also in yolk's fork. I'm not using this personally. Maybe also a flag to toggle the interpretation of dates without years would be nice. Neither of those things will be in 1.0 I don't reckon.
62
+ Current release is stable, and being used in production sites. Some I18n work is in yolk's fork, but it is lagging behind the current release. I am not using this personally. Maybe also a flag to toggle the interpretation of dates without years would be nice, but not something I need.
data/Rakefile CHANGED
@@ -4,5 +4,8 @@ task :default => :spec
4
4
  # RSpec provided helper doesn't like me, for now just run it myself
5
5
  desc "Run specs"
6
6
  task :spec do
7
- exec("rspec spec/*_spec.rb")
7
+ commands = []
8
+ commands << "bundle exec rspec spec/*_spec.rb"
9
+ commands << "jsl -nologo -process lib/js/kronic.js" if `which jsl`.length > 0
10
+ exec commands.join(" && ")
8
11
  end
@@ -23,8 +23,9 @@ class Kronic
23
23
  end
24
24
 
25
25
  # Public: Converts a date to a human readable string. If Time.zone is
26
- # available and set (added by active_support and rails), Time.zone.today
27
- # will be used as a reference point, otherwise Date.today will be used.
26
+ # available and set (it is added by active_support and rails by default),
27
+ # Time.zone.today will be used as a reference point, otherwise Date.today
28
+ # will be used.
28
29
  #
29
30
  # date - The Date to be converted
30
31
  # opts - The Hash options used to customize formatting
@@ -48,7 +49,7 @@ class Kronic
48
49
 
49
50
  DELIMITER = /[,\s]+/
50
51
  NUMBER = /^[0-9]+$/
51
- NUMBER_WITH_ORDINAL = /^[0-9]+(st|nd|rd|th)?$/
52
+ NUMBER_WITH_ORDINAL = /^([0-9]+)(st|nd|rd|th)?$/
52
53
  ISO_8601_DATE = /^([0-9]{4})-?(1[0-2]|0?[1-9])-?(3[0-1]|[1-2][0-9]|0?[1-9])$/
53
54
 
54
55
  MONTH_NAMES = Date::MONTHNAMES.zip(Date::ABBR_MONTHNAMES).flatten.compact.map {|x|
@@ -1,18 +1,37 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Kronic do
4
- def self.should_parse(string, date)
5
- it "should parse '#{string}'" do
6
- Kronic.parse(string).should == date
4
+ extend KronicMatchers
5
+
6
+ if js_supported?
7
+ # JRuby cannot currently run the specs against the JS implementation
8
+ before :all do
9
+ reset_timezone
10
+
11
+ @js = V8::Context.new
12
+ @js['alert'] = proc {|s| puts s.inspect } # For debugging, not used normally
13
+ %w(strftime kronic).each do |file|
14
+ @js.eval(File.open(File.dirname(__FILE__) + "/../lib/js/#{file}.js").read)
15
+ end
16
+ @js.eval("Kronic")['today'] = proc { date(:today).to_time }
7
17
  end
8
18
  end
9
19
 
10
- def self.should_format(string, date)
11
- it "should format '#{string}'" do
12
- Kronic.format(date).should == string
13
- end
20
+ before :each do
21
+ reset_timezone
22
+ Timecop.freeze(Time.utc(
23
+ date(:today).year,
24
+ date(:today).month,
25
+ date(:today).day
26
+ ))
14
27
  end
15
28
 
29
+ after :each do
30
+ Timecop.return
31
+ end
32
+
33
+ # A constant set of dates are used for testing, the current system time is frozen
34
+ # to date(:today) for the duration of each test.
16
35
  def self.date(key)
17
36
  {
18
37
  :today => Date.new(2010, 9, 18),
@@ -25,53 +44,44 @@ describe Kronic do
25
44
  end
26
45
  def date(key); self.class.date(key); end;
27
46
 
28
- before :each do
29
- Time.zone = nil
30
- ENV['TZ'] = "Australia/Melbourne"
31
- d = date(:today)
32
- Timecop.freeze(Time.utc(d.year, d.month, d.day))
33
- end
34
-
35
- after :each do
36
- Timecop.return
37
- end
47
+ # it_should_parse and it_should_format macros are defined in spec/spec_helper.rb
48
+ it_should_parse('Today', date(:today))
49
+ it_should_parse(:today, date(:today))
50
+ it_should_parse('today', date(:today))
51
+ it_should_parse(' Today', date(:today))
52
+ it_should_parse('Yesterday', date(:today) - 1)
53
+ it_should_parse('Tomorrow', date(:today) + 1)
54
+ it_should_parse('Last Monday', date(:last_monday))
55
+ it_should_parse('This Monday', date(:next_monday))
56
+ it_should_parse('4 Sep', date(:sep_4))
57
+ it_should_parse('4 Sep', date(:sep_4))
58
+ it_should_parse('4 September', date(:sep_4))
59
+ it_should_parse('20 Sep', date(:sep_20))
60
+ it_should_parse('28 Sep 2010', date(:sep_28))
61
+ it_should_parse('14 Sep 2008', Date.new(2008, 9, 14))
62
+ it_should_parse('14th Sep 2008', Date.new(2008, 9, 14))
63
+ it_should_parse('23rd Sep 2008', Date.new(2008, 9, 23))
64
+ it_should_parse('September 14 2008', Date.new(2008, 9, 14))
65
+ it_should_parse('Sep 14, 2008', Date.new(2008, 9, 14))
66
+ it_should_parse('14 Sep, 2008', Date.new(2008, 9, 14))
67
+ it_should_parse('Sep 4th', date(:sep_4))
68
+ it_should_parse('September 4', date(:sep_4))
69
+ it_should_parse('2008-09-04', Date.new(2008, 9, 4))
70
+ it_should_parse('2008-9-4', Date.new(2008, 9, 4))
71
+ it_should_parse('bogus', nil)
72
+ it_should_parse('14', nil)
73
+ it_should_parse('14 bogus in', nil)
74
+ it_should_parse('14 June oen', nil)
75
+ it_should_parse('January 1999', nil)
76
+ it_should_parse('Last M', nil)
38
77
 
39
- should_parse('Today', date(:today))
40
- should_parse(:today, date(:today))
41
- should_parse('today', date(:today))
42
- should_parse(' Today', date(:today))
43
- should_parse('Yesterday', date(:today) - 1)
44
- should_parse('Tomorrow', date(:today) + 1)
45
- should_parse('Last Monday', date(:last_monday))
46
- should_parse('This Monday', date(:next_monday))
47
- should_parse('4 Sep', date(:sep_4))
48
- should_parse('4 Sep', date(:sep_4))
49
- should_parse('4 September', date(:sep_4))
50
- should_parse('20 Sep', date(:sep_20))
51
- should_parse('28 Sep 2010', date(:sep_28))
52
- should_parse('14 Sep 2008', Date.new(2008, 9, 14))
53
- should_parse('14th Sep 2008', Date.new(2008, 9, 14))
54
- should_parse('23rd Sep 2008', Date.new(2008, 9, 23))
55
- should_parse('September 14 2008', Date.new(2008, 9, 14))
56
- should_parse('Sep 14, 2008', Date.new(2008, 9, 14))
57
- should_parse('14 Sep, 2008', Date.new(2008, 9, 14))
58
- should_parse('Sep 4th', date(:sep_4))
59
- should_parse('September 4', date(:sep_4))
60
- should_parse('2008-09-04', Date.new(2008, 9, 4))
61
- should_parse('2008-9-4', Date.new(2008, 9, 4))
62
- should_parse('bogus', nil)
63
- should_parse('14', nil)
64
- should_parse('14 bogus in', nil)
65
- should_parse('14 June oen', nil)
66
- should_parse('January 1999', nil)
67
-
68
- should_format('Today', date(:today))
69
- should_format('Yesterday', date(:today) - 1)
70
- should_format('Tomorrow', date(:today) + 1)
71
- should_format('Last Monday', date(:last_monday))
72
- should_format('This Monday', date(:next_monday))
73
- should_format('14 September 2008', Date.new(2008, 9, 14))
74
- should_format('14 September 2008', Time.utc(2008, 9, 14))
78
+ it_should_format('Today', date(:today))
79
+ it_should_format('Yesterday', date(:today) - 1)
80
+ it_should_format('Tomorrow', date(:today) + 1)
81
+ it_should_format('Last Monday', date(:last_monday))
82
+ it_should_format('This Monday', date(:next_monday))
83
+ it_should_format('14 September 2008', Date.new(2008, 9, 14))
84
+ it_should_format('14 September 2008', Time.utc(2008, 9, 14))
75
85
 
76
86
  describe 'timezone support' do
77
87
  before :all do
@@ -97,4 +107,9 @@ describe Kronic do
97
107
  Kronic.format(date(:today)).should == "Today"
98
108
  end
99
109
  end
110
+
111
+ def reset_timezone
112
+ Time.zone = nil
113
+ ENV['TZ'] = "Australia/Melbourne"
114
+ end
100
115
  end
@@ -2,6 +2,16 @@ require 'rspec'
2
2
  require 'timecop'
3
3
  require 'active_support/core_ext/integer/time'
4
4
  require 'active_support/core_ext/time/zones'
5
+ require 'active_support/core_ext/time/calculations'
6
+ require 'active_support/core_ext/date/conversions' # For nicer spec fail output
7
+
8
+ $js_loaded = begin
9
+ require 'v8'
10
+ true
11
+ rescue LoadError => e
12
+ # Can't run JS specs
13
+ false
14
+ end
5
15
 
6
16
  $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
7
17
  require 'kronic'
@@ -21,3 +31,40 @@ module MethodVisibility
21
31
  end
22
32
  end
23
33
  end
34
+
35
+ module KronicMatchers
36
+ def it_should_parse(string, date)
37
+ it "should parse '#{string}'" do
38
+ Kronic.parse(string).should == date
39
+ end
40
+
41
+ if js_supported?
42
+ it "should parse '#{string}' (JS)" do
43
+ x = @js.evaluate("Kronic").parse(string)
44
+
45
+ if x.is_a?(Time)
46
+ x = x.to_date
47
+ Date.new(x.year, x.month, x.day).should == date
48
+ else
49
+ x.should == date
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def it_should_format(string, date)
56
+ it "should format '#{string}'" do
57
+ Kronic.format(date).should == string
58
+ end
59
+
60
+ if js_supported?
61
+ it "should format '#{string}' (JS)" do
62
+ @js.evaluate("Kronic").format(date.to_time).should == string
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ def js_supported?
69
+ $js_loaded
70
+ end
metadata CHANGED
@@ -3,10 +3,10 @@ name: kronic
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 0
7
- - 4
8
6
  - 1
9
- version: 0.4.1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Xavier Shay
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-22 00:00:00 +10:30
17
+ date: 2010-10-27 00:00:00 +11:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency