texp 0.0.7 → 0.1.1

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.
@@ -4,15 +4,18 @@ require 'texp/version'
4
4
  require 'texp/errors'
5
5
  require 'texp/base'
6
6
  require 'texp/parse'
7
+ require 'texp/logic'
8
+ require 'texp/operators'
7
9
  require 'texp/day_of_week'
8
10
  require 'texp/day_of_month'
9
11
  require 'texp/week'
10
12
  require 'texp/month'
11
13
  require 'texp/year'
12
14
  require 'texp/day_interval'
15
+ require 'texp/week_interval'
16
+ require 'texp/day_of_week_interval'
17
+ require 'texp/month_interval'
13
18
  require 'texp/every_day'
14
19
  require 'texp/window'
15
- require 'texp/logic'
16
20
  require 'texp/dsl'
17
- require 'texp/operators'
18
21
  require 'texp/ext'
@@ -1,4 +1,10 @@
1
1
  module TExp
2
+
3
+ class TExpError < StandardError
4
+ end
5
+
6
+ class TExpIncludeError < TExpError
7
+ end
2
8
 
3
9
  ####################################################################
4
10
  # Abstract Base class for all Texp Temporal Expressions.
@@ -13,6 +19,10 @@ module TExp
13
19
  codes.join("")
14
20
  end
15
21
 
22
+ def include?(*args)
23
+ raise TExpIncludeError, "Use includes? rather than include?"
24
+ end
25
+
16
26
  # Create a new temporal expression with a new anchor date.
17
27
  def reanchor(date)
18
28
  self
@@ -2,8 +2,16 @@ module TExp
2
2
  class DayInterval < Base
3
3
  register_parse_callback('i')
4
4
 
5
- attr_reader :base_date
5
+ attr_reader :base_date, :interval
6
6
 
7
+ def day_multiplier
8
+ 1
9
+ end
10
+
11
+ def interval_unit
12
+ "day"
13
+ end
14
+
7
15
  def initialize(base_date, interval)
8
16
  @base_date = base_date.kind_of?(Date) ? base_date : nil
9
17
  @interval = interval
@@ -14,7 +22,7 @@ module TExp
14
22
  if @base_date.nil? || date < @base_date
15
23
  false
16
24
  else
17
- ((date.mjd - base_mjd) % @interval) == 0
25
+ ((date.mjd - base_mjd) % (@interval * day_multiplier)) == 0
18
26
  end
19
27
  end
20
28
 
@@ -26,9 +34,11 @@ module TExp
26
34
  # Human readable version of the temporal expression.
27
35
  def inspect
28
36
  if @interval == 1
29
- "every day starting on #{humanize_date(@base_date)}"
37
+ "every #{interval_unit}"
38
+ elsif @interval == 2
39
+ "every other #{interval_unit}"
30
40
  else
31
- "every #{ordinal(@interval)} day starting on #{humanize_date(@base_date)}"
41
+ "every #{@interval} #{pluralize(interval_unit)}"
32
42
  end
33
43
  end
34
44
 
@@ -44,6 +54,10 @@ module TExp
44
54
 
45
55
  private
46
56
 
57
+ def pluralize(word)
58
+ "#{word}s"
59
+ end
60
+
47
61
  def base_mjd
48
62
  @base_date.mjd
49
63
  end
@@ -52,7 +66,7 @@ module TExp
52
66
  def parse_callback(stack)
53
67
  interval = stack.pop
54
68
  date = stack.pop
55
- stack.push TExp::DayInterval.new(date, interval)
69
+ stack.push self.new(date, interval)
56
70
  end
57
71
  end
58
72
  end
@@ -1,5 +1,7 @@
1
1
  module TExp
2
2
  class DayOfWeek < Base
3
+ attr_reader :days
4
+
3
5
  register_parse_callback('w')
4
6
 
5
7
  def initialize(days)
@@ -13,8 +15,8 @@ module TExp
13
15
 
14
16
  # Human readable version of the temporal expression.
15
17
  def inspect
16
- "the day of the week is " +
17
- humanize_list(@days) { |d| Date::DAYNAMES[d] }
18
+ "on " +
19
+ humanize_list(@days, "and") { |d| Date::DAYNAMES[d] }
18
20
  end
19
21
 
20
22
  # Encode the temporal expression into +codes+.
@@ -0,0 +1,38 @@
1
+ # To change this template, choose Tools | Templates
2
+ # and open the template in the editor.
3
+ module TExp
4
+ class DayOfWeekInterval < And
5
+ register_parse_callback('q')
6
+ def initialize(*args)
7
+ if args.size == 3
8
+ day, week_interval, start_date = args[0..2]
9
+ @day_texp = DayOfWeek.new(day)
10
+ @week_interval_texp = WeekInterval.new(
11
+ find_day_of_week_on_or_after(start_date, day),
12
+ week_interval
13
+ )
14
+ super(@day_texp, @week_interval_texp)
15
+ else
16
+ @day_texp, @week_interval_texp = args[0], args[1]
17
+ super(@day_texp, @week_interval_texp)
18
+ end
19
+ end
20
+
21
+ def find_day_of_week_on_or_after(date, day_of_week)
22
+ raise ArgumentError, "#{day_of_week} is not a valid day of week" unless
23
+ (0..6).to_a.include? day_of_week
24
+ while date.wday != day_of_week
25
+ date = date + 1
26
+ end
27
+ date
28
+ end
29
+
30
+ def reanchor(date)
31
+ super(find_day_of_week_on_or_after(date, @day_texp.days[0]))
32
+ end
33
+
34
+ def inspect
35
+ "#{@week_interval_texp.inspect} #{@day_texp.inspect}"
36
+ end
37
+ end
38
+ end
@@ -164,7 +164,7 @@ module TExp
164
164
  # Evaluate a temporal expression in the TExp environment.
165
165
  # Redirect missing method calls to the containing environment.
166
166
  def evaluate_expression_in_environment(&block) # :nodoc:
167
- env = EvalEnvironment.new(block)
167
+ env = EvalEnvironment.new(block.binding)
168
168
  env.instance_eval(&block)
169
169
  end
170
170
 
@@ -0,0 +1,29 @@
1
+ module TExp
2
+ class MonthInterval < DayInterval
3
+ register_parse_callback('c')
4
+
5
+ def day_multiplier
6
+ 28
7
+ end
8
+
9
+ def interval_unit
10
+ "month"
11
+ end
12
+
13
+ def inspect
14
+ case interval
15
+ when 1
16
+ "once per month"
17
+ when 0.5
18
+ base = "twice per month"
19
+ when 0.25
20
+ base = "4 times per month"
21
+ else
22
+ base = super
23
+ end
24
+ base + " (#{interval * day_multiplier} days)"
25
+ end
26
+
27
+
28
+ end
29
+ end
@@ -26,7 +26,7 @@ module TExp
26
26
  def register_parse_callback(token, callback)
27
27
  PARSE_CALLBACKS[token] = callback
28
28
  end
29
-
29
+
30
30
  # Return the temporal expression encoded by string.
31
31
  def parse(string)
32
32
  @stack = []
@@ -37,6 +37,10 @@ module TExp
37
37
  @stack.pop
38
38
  end
39
39
 
40
+ def parse_callbacks
41
+ PARSE_CALLBACKS
42
+ end
43
+
40
44
  private
41
45
 
42
46
  # Compile the token into the current definition.
@@ -51,7 +55,7 @@ module TExp
51
55
  when /^[-+]?\d+$/
52
56
  @stack.push tok.to_i
53
57
  else
54
- fail ParseError, "Unrecoginized TExp Token '#{tok}'"
58
+ fail ParseError, "Unrecognized TExp Token '#{tok}'"
55
59
  end
56
60
  end
57
61
  end
@@ -67,18 +71,18 @@ module TExp
67
71
  @callback.call(stack)
68
72
  end
69
73
  end
70
-
74
+
71
75
  # List parsing handlers
72
-
76
+
73
77
  # Mark the end of the list.
74
78
  MARK = :mark # :nodoc:
75
-
79
+
76
80
  # Push a mark on the stack to start a list.
77
81
  register_parse_callback('[',
78
82
  ParseCallback.new do |stack|
79
83
  stack.push MARK
80
84
  end)
81
-
85
+
82
86
  # Pop the stack and build a list until you find a mark.
83
87
  register_parse_callback(']',
84
88
  ParseCallback.new do |stack|
@@ -1,3 +1,3 @@
1
1
  module TExp
2
- VERSION = '0.0.7'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -0,0 +1,13 @@
1
+ module TExp
2
+ class WeekInterval < DayInterval
3
+ register_parse_callback('b')
4
+
5
+ def day_multiplier
6
+ 7
7
+ end
8
+
9
+ def interval_unit
10
+ "week"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'texp_tests'
3
+ require 'date'
4
+ require 'texp'
@@ -1,7 +1,6 @@
1
- require 'test/unit'
2
- require 'texp'
1
+ require 'test_helper'
3
2
 
4
- class BaseEachTest < Test::Unit::TestCase
3
+ class BaseEachTest < Minitest::Test
5
4
  def test_each_on_base
6
5
  te = basic_texp
7
6
  assert_equal [te], te.collect { |t| t }
@@ -17,6 +16,12 @@ class BaseEachTest < Test::Unit::TestCase
17
16
  assert_equal [@basic, @multi], te.collect { |t| t }
18
17
  end
19
18
 
19
+ def test_complains_about_include
20
+ assert_raises TExp::TExpIncludeError do
21
+ basic_texp.include? Date.parse("Feb 1, 2009")
22
+ end
23
+ end
24
+
20
25
  private
21
26
 
22
27
  def basic_texp
@@ -33,7 +38,7 @@ class BaseEachTest < Test::Unit::TestCase
33
38
 
34
39
  end
35
40
 
36
- class BaseAnchorTest < Test::Unit::TestCase
41
+ class BaseAnchorTest < Minitest::Test
37
42
  def test_setting_anchor_date
38
43
  start_date = Date.parse("Feb 10, 2008")
39
44
  te = TExp::DayInterval.new(start_date, 3)
@@ -1,8 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ require 'test_helper'
2
2
 
3
- require 'test/texp_tests'
4
-
5
- class DayIntervalTest < Test::Unit::TestCase
3
+ class DayIntervalTest < Minitest::Test
6
4
 
7
5
  def test_day_interval
8
6
  te = TExp::DayInterval.new(Date.parse("Feb 10, 2008"), 3)
@@ -31,4 +29,3 @@ class DayIntervalTest < Test::Unit::TestCase
31
29
  assert_not_includes te, date-3, date-2, date-1
32
30
  end
33
31
  end
34
-
@@ -1,10 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ require 'test_helper'
2
2
 
3
- require 'date'
4
- require 'test/unit'
5
- require 'texp'
6
-
7
- class DayOfMonthTest < Test::Unit::TestCase
3
+ class DayOfMonthTest < Minitest::Test
8
4
 
9
5
  def test_day_of_month_with_single_arg
10
6
  te = TExp::DayOfMonth.new(14)
@@ -24,4 +20,3 @@ class DayOfMonthTest < Test::Unit::TestCase
24
20
  assert te.includes?(Date.parse("Feb 16, 2008"))
25
21
  end
26
22
  end
27
-
@@ -1,10 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ require 'test_helper'
2
2
 
3
- require 'date'
4
- require 'test/unit'
5
- require 'texp'
6
-
7
- class DayOfWeekTest < Test::Unit::TestCase
3
+ class DayOfWeekTest < Minitest::Test
8
4
 
9
5
  def test_day_of_week_include_with_one_day
10
6
  te = TExp::DayOfWeek.new([1])
@@ -28,4 +24,3 @@ class DayOfWeekTest < Test::Unit::TestCase
28
24
  assert ! te.includes?(Date.parse("Feb 16, 2008"))
29
25
  end
30
26
  end
31
-
@@ -1,7 +1,6 @@
1
- require 'test/texp_tests'
2
- require 'texp'
1
+ require 'test_helper'
3
2
 
4
- class BuilderTest < Test::Unit::TestCase
3
+ class BuilderTest < Minitest::Test
5
4
  def test_day_builder
6
5
  date = d("Mar 12, 2008")
7
6
  te = TExp.day(12)
@@ -152,19 +151,19 @@ class BuilderTest < Test::Unit::TestCase
152
151
  end
153
152
 
154
153
  def test_on_builder_with_invalid_arguments
155
- assert_raise(ArgumentError) do TExp.on(1) end
156
- assert_raise(ArgumentError) do TExp.on(1,2,3,4) end
157
- assert_raise(ArgumentError) do TExp.on(nil, nil) end
158
- assert_raise(ArgumentError) do TExp.on(0, 1) end
159
- assert_raise(ArgumentError) do TExp.on(1, 0) end
160
- assert_raise(ArgumentError) do TExp.on(32, 1) end
161
- assert_raise(ArgumentError) do TExp.on(1, 13) end
162
- assert_raise(ArgumentError) do TExp.on(0, 1, 2008) end
163
- assert_raise(ArgumentError) do TExp.on(1, 0, 2008) end
164
- assert_raise(ArgumentError) do TExp.on(32, 1, 2008) end
165
- assert_raise(ArgumentError) do TExp.on(1, 13, 2008) end
166
- assert_raise(ArgumentError) do TExp.on(1, 'nox') end
167
- assert_raise(ArgumentError) do TExp.on(1, 'nox', 2008) end
154
+ assert_raises(ArgumentError) do TExp.on(1) end
155
+ assert_raises(ArgumentError) do TExp.on(1,2,3,4) end
156
+ assert_raises(ArgumentError) do TExp.on(nil, nil) end
157
+ assert_raises(ArgumentError) do TExp.on(0, 1) end
158
+ assert_raises(ArgumentError) do TExp.on(1, 0) end
159
+ assert_raises(ArgumentError) do TExp.on(32, 1) end
160
+ assert_raises(ArgumentError) do TExp.on(1, 13) end
161
+ assert_raises(ArgumentError) do TExp.on(0, 1, 2008) end
162
+ assert_raises(ArgumentError) do TExp.on(1, 0, 2008) end
163
+ assert_raises(ArgumentError) do TExp.on(32, 1, 2008) end
164
+ assert_raises(ArgumentError) do TExp.on(1, 13, 2008) end
165
+ assert_raises(ArgumentError) do TExp.on(1, 'nox') end
166
+ assert_raises(ArgumentError) do TExp.on(1, 'nox', 2008) end
168
167
  end
169
168
 
170
169
  def test_dow_builder
@@ -259,7 +258,7 @@ class BuilderTest < Test::Unit::TestCase
259
258
  end
260
259
 
261
260
  def test_window_builder_with_bad_units
262
- assert_raise ArgumentError do
261
+ assert_raises ArgumentError do
263
262
  te = TExp.on(Date.today).window(1, nil)
264
263
  end
265
264
  end
@@ -1,15 +1,8 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'test/unit'
4
- require 'date'
5
-
6
- require 'texp'
7
-
8
- class EveryDayTest < Test::Unit::TestCase
1
+ require 'test_helper'
9
2
 
3
+ class EveryDayTest < Minitest::Test
10
4
  def test_every_day
11
5
  te = TExp::EveryDay.new
12
6
  assert te.includes?(Date.parse("Feb 15, 2008"))
13
7
  end
14
8
  end
15
-
@@ -1,8 +1,4 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'test/unit'
4
- require 'date'
5
- require 'texp'
1
+ require 'test_helper'
6
2
 
7
3
  module TExp
8
4
 
@@ -64,7 +60,7 @@ module TExp
64
60
  end # module Extensions
65
61
  end # module TExp
66
62
 
67
- class ExtensionsTest < Test::Unit::TestCase
63
+ class ExtensionsTest < Minitest::Test
68
64
  def test_never
69
65
  te = TExp::Extensions::MyExt::Never.new
70
66
  assert ! te.includes?(Date.today)
@@ -79,4 +75,3 @@ class ExtensionsTest < Test::Unit::TestCase
79
75
  assert_equal "<MyExt::never>", TExp.parse("<MyExt::never>").to_s
80
76
  end
81
77
  end
82
-