freq 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ module Autotest::CustomTestMatch
2
+ Autotest.add_hook :initialize do |at|
3
+ at.add_mapping(/test/) do |f, _|
4
+ at.files_matching(/_test\.rb$/)
5
+ end
6
+ at.add_mapping(/lib\/.*/) do |f, _|
7
+ at.files_matching(/_test\.rb$/)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ pkg
@@ -0,0 +1,3 @@
1
+ = Freq
2
+
3
+ A library for parsing and using natural language frequency descriptions.
@@ -0,0 +1,3 @@
1
+ h1. Freq
2
+
3
+ A library for parsing and using natural language frequency descriptions.
@@ -0,0 +1,39 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run tests.'
6
+ task :default => [:test]
7
+
8
+ desc 'Run tests.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Freq'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README.rdoc')
21
+ rdoc.rdoc_files.include('lib/*.rb')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+
26
+ begin
27
+ require 'jeweler'
28
+ Jeweler::Tasks.new do |gemspec|
29
+ gemspec.name = "freq"
30
+ gemspec.summary = "Freq provides parsing of strings describing periodically occurring events."
31
+ gemspec.email = "anthonyeden@gmail.com"
32
+ gemspec.homepage = "http://github.com/aeden/freq"
33
+ gemspec.description = "Freq provides parsing of strings describing periodically occurring events."
34
+ gemspec.authors = ["Anthony Eden"]
35
+ gemspec.files.exclude 'docs/**/*'
36
+ end
37
+ rescue LoadError
38
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
39
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,97 @@
1
+ # Class that defines a frequency for a recurring thing.
2
+ #
3
+ # Note: this class does not properly handle months and years.
4
+ class Freq
5
+
6
+ SECOND = 1 unless defined? SECOND
7
+ MINUTE = SECOND * 60 unless defined? MINUTE
8
+ HOUR = MINUTE * 60 unless defined? HOUR
9
+ DAY = HOUR * 24 unless defined? DAY
10
+ WEEK = DAY * 7 unless defined? WEEK
11
+
12
+ MONTH = DAY * 30 unless defined? MONTH
13
+ YEAR = DAY * 365 unless defined? YEAR
14
+
15
+ attr_accessor :period
16
+ attr_accessor :times
17
+
18
+ def initialize(period, times)
19
+ @period = period
20
+ @times = times
21
+ end
22
+
23
+ def to_seconds
24
+ return 0 if times == 0 || period == 0
25
+ period / times
26
+ end
27
+
28
+ # Apply the frequency to the given timestamp to get the next occurrence.
29
+ def next(t)
30
+ Time.at(t + to_seconds)
31
+ end
32
+
33
+ def self.parse(str)
34
+ times = 1
35
+ period = 0
36
+ multiplier = 1
37
+
38
+ words = str.downcase.split
39
+ words.each_with_index do |word, i|
40
+ case word
41
+ when 'every'
42
+ if words[i+1] == 'other'
43
+ multiplier = 2
44
+ end
45
+ if words[i+1] =~ /\d+/
46
+ multiplier = words[i+1].to_i
47
+ end
48
+ when 'twice' then times = 2
49
+ when /times?/
50
+ times = word_to_number(words[i-1])
51
+ when /seconds?/ then period = SECOND
52
+ when /minutes?/ then period = MINUTE
53
+ when /hours?/ then period = HOUR
54
+ when /days?/ then period = DAY
55
+ when /weeks?/ then period = WEEK
56
+ when /months?/ then period = MONTH
57
+ when /years?/ then period = YEAR
58
+ end
59
+ end
60
+
61
+ new(period * multiplier, times)
62
+ end
63
+
64
+ def self.word_to_number(word)
65
+ if n = word.to_i
66
+ if n == 0
67
+ return 0 if word == '0' || word == 'zero'
68
+ else
69
+ return n
70
+ end
71
+ end
72
+
73
+ irregular = {
74
+ 'zero' => 0,
75
+ 'one' => 1,
76
+ 'two' => 2,
77
+ 'three' => 3,
78
+ 'four' => 4,
79
+ 'five' => 5,
80
+ 'six' => 6,
81
+ 'seven' => 7,
82
+ 'eight' => 8,
83
+ 'nine' => 9,
84
+ 'ten' => 10,
85
+ 'eleven' => 11,
86
+ 'twelve' => 12,
87
+ 'thirteen' => 13,
88
+ 'fourteen' => 14,
89
+ 'fifteen' => 15,
90
+ 'sixteen' => 16,
91
+ 'seventeen' => 17,
92
+ 'eighteen' => 18,
93
+ 'nineteen' => 19
94
+ }
95
+ return irregular[word] if irregular[word]
96
+ end
97
+ end
@@ -0,0 +1,5 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+ require File.dirname(__FILE__) + '/../lib/freq'
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ class FreqTest < Test::Unit::TestCase
4
+ context "a frequency" do
5
+ context "when parsed as a string" do
6
+ should "construct the correct frequency" do
7
+ expectations.each do |s, expect|
8
+ assert_equal expect, Freq.parse(s).to_seconds
9
+ end
10
+ end
11
+ end
12
+ context "next" do
13
+ should "return the correct Time value" do
14
+ expectations.each do |s, expect|
15
+ t = Time.now
16
+ assert_equal t + expect, Freq.parse(s).next(t)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ def expectations
23
+ {
24
+ 'every second' => Freq::SECOND,
25
+ 'once a second' => Freq::SECOND,
26
+ 'every minute' => Freq::MINUTE,
27
+ 'once a minute' => Freq::MINUTE,
28
+ 'every hour' => Freq::HOUR,
29
+ 'once an hour' => Freq::HOUR,
30
+ 'every day' => Freq::DAY,
31
+ 'once a day' => Freq::DAY,
32
+ 'every week' => Freq::WEEK,
33
+ 'once a week' => Freq::WEEK,
34
+ 'every month' => Freq::MONTH,
35
+ 'once a month' => Freq::MONTH,
36
+ 'every year' => Freq::YEAR,
37
+ 'once a year' => Freq::YEAR,
38
+
39
+ 'every other second' => Freq::SECOND * 2,
40
+ 'every other minute' => Freq::MINUTE * 2,
41
+ 'every other hour' => Freq::HOUR * 2,
42
+ 'every other day' => Freq::DAY * 2,
43
+ 'every other week' => Freq::WEEK * 2,
44
+
45
+ 'every 2 seconds' => Freq::SECOND * 2,
46
+ 'every 10 seconds' => Freq::SECOND * 10,
47
+ 'every 2 minutes' => Freq::MINUTE * 2,
48
+ 'every 10 minutes' => Freq::MINUTE * 10,
49
+ 'every 2 hours' => Freq::HOUR * 2,
50
+ 'every 10 hours' => Freq::HOUR * 10,
51
+ 'every 2 days' => Freq::DAY * 2,
52
+ 'every 10 days' => Freq::DAY * 10,
53
+ 'every 2 weeks' => Freq::WEEK * 2,
54
+ 'every 10 weeks' => Freq::WEEK * 10,
55
+
56
+ 'once every 2 seconds' => Freq::SECOND * 2,
57
+ 'twice every 2 seconds' => Freq::SECOND * 1,
58
+
59
+ '1 time every 2 seconds' => Freq::SECOND * 2,
60
+ '1 time every second' => Freq::SECOND * 1,
61
+ '10 times every minute' => Freq::SECOND * 6,
62
+ '5 times every other day' => Freq::DAY / 5 * 2,
63
+
64
+ 'twice a minute' => Freq::MINUTE / 2,
65
+ '4 times a minute' => Freq::MINUTE / 4,
66
+ 'four times a minute' => Freq::MINUTE / 4,
67
+ 'ten times per minute' => Freq::MINUTE / 10,
68
+ 'twice an hour' => Freq::HOUR / 2,
69
+ '4 times an hour' => Freq::HOUR / 4,
70
+ 'four times an hour' => Freq::HOUR / 4,
71
+ 'ten times per hour' => Freq::HOUR / 10,
72
+ 'twice a day' => Freq::DAY / 2,
73
+ '4 times a day' => Freq::DAY / 4,
74
+ 'four times a day' => Freq::DAY / 4,
75
+ 'ten times per day' => Freq::DAY / 10,
76
+ 'twice a week' => Freq::WEEK / 2,
77
+ '4 times a week' => Freq::WEEK / 4,
78
+ 'four times a week' => Freq::WEEK / 4,
79
+ 'ten times per week' => Freq::WEEK / 10,
80
+ }
81
+ end
82
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: freq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anthony Eden
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-20 00:00:00 -10:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Freq provides parsing of strings describing periodically occurring events.
17
+ email: anthonyeden@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - README.textile
25
+ files:
26
+ - .autotest
27
+ - .gitignore
28
+ - README.rdoc
29
+ - README.textile
30
+ - Rakefile
31
+ - VERSION
32
+ - lib/freq.rb
33
+ - test/test_helper.rb
34
+ - test/unit/freq_test.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/aeden/freq
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options:
41
+ - --charset=UTF-8
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Freq provides parsing of strings describing periodically occurring events.
63
+ test_files:
64
+ - test/test_helper.rb
65
+ - test/unit/freq_test.rb