texp 0.0.7 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-