runt19 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/History.txt +153 -0
  4. data/LICENSE +22 -0
  5. data/LICENSE.txt +44 -0
  6. data/Manifest.txt +112 -0
  7. data/README.md +29 -0
  8. data/README.txt +106 -0
  9. data/Rakefile +2 -0
  10. data/TODO +13 -0
  11. data/examples/payment_report.rb +59 -0
  12. data/examples/payment_reporttest.rb +49 -0
  13. data/examples/reminder.rb +63 -0
  14. data/examples/schedule_tutorial.rb +59 -0
  15. data/examples/schedule_tutorialtest.rb +52 -0
  16. data/lib/runt.rb +249 -0
  17. data/lib/runt/daterange.rb +74 -0
  18. data/lib/runt/dprecision.rb +150 -0
  19. data/lib/runt/expressionbuilder.rb +65 -0
  20. data/lib/runt/pdate.rb +165 -0
  21. data/lib/runt/schedule.rb +88 -0
  22. data/lib/runt/sugar.rb +171 -0
  23. data/lib/runt/temporalexpression.rb +795 -0
  24. data/lib/runt/version.rb +3 -0
  25. data/lib/runt19.rb +1 -0
  26. data/runt19.gemspec +17 -0
  27. data/setup.rb +1331 -0
  28. data/site/blue-robot3.css +132 -0
  29. data/site/dcl-small.gif +0 -0
  30. data/site/index.html +72 -0
  31. data/site/logohover.png +0 -0
  32. data/site/runt-logo.gif +0 -0
  33. data/site/runt-logo.psd +0 -0
  34. data/test/aftertetest.rb +31 -0
  35. data/test/baseexpressiontest.rb +110 -0
  36. data/test/beforetetest.rb +31 -0
  37. data/test/collectiontest.rb +63 -0
  38. data/test/combinedexpressionstest.rb +158 -0
  39. data/test/daterangetest.rb +89 -0
  40. data/test/dayintervaltetest.rb +37 -0
  41. data/test/difftest.rb +37 -0
  42. data/test/dimonthtest.rb +59 -0
  43. data/test/diweektest.rb +32 -0
  44. data/test/dprecisiontest.rb +58 -0
  45. data/test/everytetest.rb +36 -0
  46. data/test/expressionbuildertest.rb +64 -0
  47. data/test/icalendartest.rb +1104 -0
  48. data/test/intersecttest.rb +34 -0
  49. data/test/pdatetest.rb +147 -0
  50. data/test/redaytest.rb +40 -0
  51. data/test/remonthtest.rb +37 -0
  52. data/test/reweektest.rb +51 -0
  53. data/test/reyeartest.rb +99 -0
  54. data/test/rspectest.rb +25 -0
  55. data/test/runttest.rb +98 -0
  56. data/test/scheduletest.rb +148 -0
  57. data/test/spectest.rb +36 -0
  58. data/test/sugartest.rb +104 -0
  59. data/test/temporalexpressiontest.rb +76 -0
  60. data/test/uniontest.rb +36 -0
  61. data/test/wimonthtest.rb +54 -0
  62. data/test/yeartetest.rb +22 -0
  63. metadata +137 -0
@@ -0,0 +1,132 @@
1
+
2
+ body {
3
+ color:#333;
4
+ background-color:#CCCCCC;
5
+ margin:20px;
6
+ padding:0px;
7
+ font:11px verdana, arial, helvetica, sans-serif;
8
+ }
9
+ h1 {
10
+ margin:0px 0px 15px 0px;
11
+ padding:0px;
12
+ font-size:14px;
13
+ font-weight:900;
14
+ color:#ccc;
15
+ }
16
+ h2 {
17
+ font:bold 12px/14px verdana, arial, helvetica, sans-serif;
18
+ margin:0px 0px 5px 0px;
19
+ padding:0px;
20
+ }
21
+ p {
22
+ font:11px/20px verdana, arial, helvetica, sans-serif;
23
+ margin:0px 0px 16px 0px;
24
+ padding:0px;
25
+ }
26
+ .Content>p {margin:0px;}
27
+ .Content>p+p {text-indent:30px;}
28
+
29
+ a {
30
+ color:#09c;
31
+ font-size:11px;
32
+ font-family:verdana, arial, helvetica, sans-serif;
33
+ font-weight:600;
34
+ text-decoration:none;
35
+ }
36
+ a:link {color:#09c;}
37
+ a:visited {color:#07a;}
38
+ a:hover {background-color:#eee;}
39
+
40
+
41
+ /* All the content boxes belong to the content class. */
42
+ .content {
43
+ position:relative; /* Position is declared "relative" to gain control of stacking order (z-index). */
44
+ width:auto;
45
+ min-width:120px;
46
+ margin:0px 210px 20px 170px;
47
+ border:1px solid black;
48
+ background-color:white;
49
+ padding:10px;
50
+ z-index:3; /* This allows the content to overlap the right menu in narrow windows in good browsers. */
51
+ }
52
+
53
+ /* 2004-03-12 MSL */
54
+ .ruby-link {
55
+ color: rgb(255, 0, 0);
56
+ }
57
+
58
+ .keyword {
59
+ font-weight:bold;
60
+ }
61
+
62
+
63
+ #navAlpha {
64
+ position:absolute;
65
+ width:150px;
66
+ top:20px;
67
+ left:20px;
68
+ border:1px dashed black;
69
+ background-color:#eee;
70
+ padding:10px;
71
+ z-index:2;
72
+
73
+ /* Here is the ugly brilliant hack that protects IE5/Win from its own stupidity.
74
+ Thanks to Tantek Celik for the hack and to Eric Costello for publicizing it.
75
+ IE5/Win incorrectly parses the "\"}"" value, prematurely closing the style
76
+ declaration. The incorrect IE5/Win value is above, while the correct value is
77
+ below. See http://glish.com/css/hacks.asp for details. */
78
+ voice-family: "\"}\"";
79
+ voice-family:inherit;
80
+ width:128px;
81
+ }
82
+ /* I've heard this called the "be nice to Opera 5" rule. Basically, it feeds correct
83
+ length values to user agents that exhibit the parsing error exploited above yet get
84
+ the CSS box model right and understand the CSS2 parent-child selector. ALWAYS include
85
+ a "be nice to Opera 5" rule every time you use the Tantek Celik hack (above). */
86
+ body>#navAlpha {width:128px;}
87
+
88
+ #navBeta {
89
+ position:absolute;
90
+ width:190px;
91
+ top:20px;
92
+ right:20px;
93
+ border:1px dashed black;
94
+ background-color:#eee;
95
+ padding:10px;
96
+ z-index:1;
97
+ /* Again, the ugly brilliant hack. */
98
+ voice-family: "\"}\"";
99
+ voice-family:inherit;
100
+ width:168px;
101
+ }
102
+ /* Again, "be nice to Opera 5". */
103
+ body>#navBeta {width:168px;}
104
+
105
+ /* 2004-03-12 MSL */
106
+
107
+ #contentFooter {
108
+ text-align: center;
109
+ font-size:10px;
110
+ }
111
+
112
+ #contentFooter a {
113
+ font-size:10px;
114
+ }
115
+
116
+
117
+ #logo {
118
+ border: 0px solid ;
119
+ width: 97px;
120
+ height: 33px;
121
+ vertical-align: -50%;
122
+ }
123
+
124
+
125
+ #dcl-logo {
126
+ border: 0px solid ;
127
+ width: 140px;
128
+ height: 29px;
129
+ vertical-align: -110%;
130
+ margin: 2px;
131
+ }
132
+
Binary file
@@ -0,0 +1,72 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2
+ "http://www.w3.org/TR/html4/strict.dtd">
3
+
4
+ <html>
5
+ <head>
6
+ <title>Runt - Ruby Temporal Expressions</title>
7
+ <style type="text/css" media="screen">@import "blue-robot3.css";</style>
8
+
9
+ </head>
10
+
11
+ <body>
12
+
13
+ <div class="content">
14
+ <h1><a href="http://runt.rubyforge.org"><img id="logo" src="runt-logo.gif" title="Choose your own damn acronym" alt="runt logo"></a>Ruby Temporal Expressions</h1>
15
+ <p><span class="keyword">Runt</span> is an implementation of select temporal patterns by <a href="http://www.martinfowler.com">Martin Fowler</a> in the super-fantastic <a href="http://ruby-lang.org"><span class="ruby-link">Ruby</span></a> language.
16
+ <span class="keyword">Runt</span> provides:
17
+ <ul>
18
+ <li>ability to define recurring events using simple, set-like expressions</li>
19
+ <li>an interfaced-based API for creating schedules for arbitrary events/objects</li>
20
+ <li>precisioned date types using <a href="http://martinfowler.com/ap2/timePoint.html">Time Point</a>s</li>
21
+ <li>date <a href="http://martinfowler.com/ap2/range.html">Range</a>s</li>
22
+ <li>everlasting peace and/or eternal life</li>
23
+ </ul>
24
+ </p>
25
+ <p>Visit our <a href="http://rubyforge.org/projects/runt/">project page</a> provided by the generous folks at <a href="http://rubyforge.org">Rubyforge</a>.</p>
26
+ </div>
27
+
28
+ <div class="content">
29
+
30
+ <h2>Getting Started</h2>
31
+ <p>
32
+ Check out the <a href="./doc/files/doc/tutorial_te_rdoc.html" title="TE Tutorial">temporal expressions tutorial</a>. Then try
33
+ <a href="./doc/files/doc/tutorial_schedule_rdoc.html" title="Schedule Tutorial">schedule tutorial</a> and finally,
34
+ <a href="./doc/files/doc/tutorial_sugar_rdoc.html" title="Sugar Tutorial">sugar tutorial</a> for some useful shortcuts.
35
+ </p>
36
+ </div>
37
+
38
+ <div id="contentFooter" class="content">
39
+ <a href="http://www.digitalclash.com">&lt;&lt;<img id="dcl-logo" src="dcl-small.gif" title="Digital Clash LLC" alt="Digital Clash logo">&copy;2008, Digital Clash LLC&gt;&gt;</a>
40
+ <br/><i>&quot;The weather is here, wish you were beautiful...&quot;</i>
41
+ </div>
42
+
43
+ <div id="navAlpha">
44
+ <h2>Links</h2>
45
+ <p>
46
+ <a href="http://rubyforge.org/projects/runt/" title="Download Runt">Download</a><br>
47
+ ----<br/>
48
+ <a href="./doc/index.html" title="RDoc for Runt">RDocs</a><br>
49
+ <a href="./doc/files/doc/tutorial_te_rdoc.html" title="TE Tutorial">Expression Tutorial</a><br>
50
+ <a href="./doc/files/doc/tutorial_schedule_rdoc.html" title="Schedule Tutorial">Schedule Tutorial</a><br>
51
+ <a href="./doc/files/doc/tutorial_sugar_rdoc.html" title="Sugar Tutorial">Sugar Tutorial</a><br>
52
+ ----<br/>
53
+ <a href="./doc/files/README.html">README</a><br/>
54
+ <a href="./doc/files/CHANGES.html">CHANGES</a><br/>
55
+ </p>
56
+ </div>
57
+
58
+ <div id="navBeta">
59
+ <h2>Suggested Reading</h2>
60
+ <p>Most of the usage and design patterns contained in this library are based on a series of articles by Martin Fowler. Some suggested reading:</p>
61
+ <p>
62
+ <a href="http://martinfowler.com/ap2/timeNarrative.html">Time Narrative</a><br/>
63
+ <a href="http://martinfowler.com/apsupp/recurring.pdf">Recurring Events</a><br/>
64
+ <a href="http://martinfowler.com/ap2/timePoint.html">Time Point</a><br/>
65
+ <a href="http://martinfowler.com/ap2/range.html">Range</a><br/>
66
+ </p>
67
+ </div>
68
+
69
+ <!-- BlueRobot was here. -->
70
+
71
+ </body>
72
+ </html>
Binary file
Binary file
Binary file
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baseexpressiontest'
4
+
5
+ # Unit tests for AfterTE class
6
+ # Author:: Matthew Lipper
7
+
8
+ class AfterTETest < BaseExpressionTest
9
+
10
+ include TExpr
11
+
12
+ def test_include_inclusive
13
+ expr = AfterTE.new(@pdate_20071030, true)
14
+ assert !expr.include?(@date_20050101), "Should not include an earlier date"
15
+ assert expr.include?(@pdate_20071114), "Should include a later date"
16
+ assert expr.include?(@pdate_20071030), "Should include the same date"
17
+ end
18
+
19
+ def test_include_non_inclusive
20
+ expr = AfterTE.new(@pdate_20071030)
21
+ assert !expr.include?(@date_20050101), "Should not include an earlier date"
22
+ assert expr.include?(@pdate_20071114), "Should include a later date"
23
+ assert !expr.include?(@pdate_20071030), "Should not include the same date"
24
+ end
25
+
26
+ def test_to_s
27
+ expr = AfterTE.new(@pdate_20071114)
28
+ assert_equal "after #{Runt.format_date(@pdate_20071114)}", expr.to_s
29
+ end
30
+
31
+ end
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'runt'
5
+ require 'date'
6
+ require 'time'
7
+
8
+ $DEBUG=false
9
+
10
+ # Base test case for refactored temporal expression unit tests
11
+ # Author:: Matthew Lipper
12
+
13
+ class BaseExpressionTest < Test::Unit::TestCase
14
+
15
+ include Runt
16
+ include DPrecision
17
+
18
+ def setup
19
+ @stub1 = StubExpression.new(false, "stub 1", false)
20
+ @stub2 = StubExpression.new(false, "stub 2", false)
21
+ @pdate_198606 = PDate.month(1986,6) # June, 1986
22
+ @pdate_20040531 = PDate.day(2004,5,31) # Monday, May 31st, 2004
23
+ @pdate_20040704 = PDate.day(2004,7,4) # Sunday, July 4th, 2004
24
+ @pdate_20060914 = PDate.day(2006,9,14) # Thursday, September 14th, 2006
25
+ @pdate_20060921 = PDate.day(2006,9,21) # Thursday, September 21st, 2006
26
+ @pdate_20071008 = PDate.day(2007,10,8) # Monday, October 8th, 2007
27
+ @pdate_20071024 = PDate.day(2007,10,24) # Wednesday, October 24th, 2007
28
+ @pdate_20071028 = PDate.day(2007,10,28) # Sunday, October 28th, 2007
29
+ @pdate_20071030 = PDate.day(2007,10,30) # Tuesday, October 30th, 2007
30
+ @pdate_20071114 = PDate.day(2007,11,14) # Wednesday, November 14th, 2007
31
+ @pdate_1922041816 = PDate.hour(1922,4,18,16) # 4pm, Tuesday, April 18th, 1922
32
+ @pdate_1975060512 = PDate.hour(1975,6,5,12) # 12pm, Thursday, June 5th, 1975
33
+ @pdate_2004090600 = PDate.hour(2004,9,6,0) # 12am, Monday, September 6th, 2004
34
+ @pdate_2012050803 = PDate.hour(2012,5,8,3) # 3am, Tuesday, May 8th, 2012
35
+ @pdate_2012050815 = PDate.hour(2012,5,8,15) # 3pm, Tuesday, May 8th, 2012
36
+ @pdate_200401282100 = PDate.min(2004,1,28,21,0) # 9:00pm, Wednesday, January 28th, 2004
37
+ @pdate_200401280000 = PDate.min(2004,1,28,0,0) # 12:00am, Wednesday, January 28th, 2004
38
+ @pdate_200401280001 = PDate.min(2004,1,28,0,1) # 12:01am, Wednesday, January 28th, 2004
39
+ @pdate_200405010806 = PDate.min(2004,5,1,8,6) # 8:06am, Saturday, May 1st, 2004
40
+ @pdate_200405030906 = PDate.min(2004,5,3,9,6) # 9:06am, Monday, May 3rd, 2004
41
+ @pdate_200405040806 = PDate.min(2004,5,4,8,6) # 8:06am, Tuesday, May 4th, 2004
42
+ @pdate_200605291012 = PDate.min(2006,5,29,10,12)
43
+ @pdate_200605301400 = PDate.min(2006,5,30,14,00)
44
+ @pdate_200609211001 = PDate.min(2006,9,21,10,1)
45
+ @pdate_200609211002 = PDate.min(2006,9,21,10,2)
46
+ @pdate_20071116100030 = PDate.sec(2007,11,16,10,0,30)
47
+ @date_19611101 = Date.civil(1961,11,1)
48
+ @date_20040109 = Date.civil(2004,1,9) # Friday, January 9th 2004
49
+ @date_20040116 = Date.civil(2004,1,16) # Friday, January 16th 2004
50
+ @date_20040125 = Date.civil(2004,1,25) # Sunday, January 25th 2004
51
+ @date_20040501 = Date.civil(2004,5,1)
52
+ @date_20040806 = Date.civil(2004,8,6)
53
+ @date_20050101 = Date.civil(2005,1,1)
54
+ @date_20050102 = Date.civil(2005,1,2)
55
+ @date_20050109 = Date.civil(2005,1,9)
56
+ @date_20050116 = Date.civil(2005,1,16)
57
+ @date_20050123 = Date.civil(2005,1,23)
58
+ @date_20050130 = Date.civil(2005,1,30)
59
+ @date_20050131 = Date.civil(2005,1,31)
60
+ @date_20050228 = Date.civil(2005,2,28)
61
+ @date_20051231 = Date.civil(2005,12,31)
62
+ @date_20060504 = Date.civil(2006,5,4)
63
+ @datetime_200403081200 = DateTime.new(2004,3,8,12,0) # 12:00pm, Monday, March 8th, 2004
64
+ @datetime_200403100800 = DateTime.new(2004,3,10,8,00)
65
+ @datetime_200403100915 = DateTime.new(2004,3,10,9,15)
66
+ @datetime_200403101915 = DateTime.new(2004,3,10,19,15) # 7:15pm, Wednesday, March 10th, 2004
67
+ @datetime_200403110000 = DateTime.new(2004,3,11,0,0) # 12:00am, Thursday, March 11th, 2004
68
+ @datetime_200403110115 = DateTime.new(2004,3,11,1,15)
69
+ @datetime_200403111215 = DateTime.new(2004,3,11,12,15)
70
+ @datetime_200403140900 = DateTime.new(2004,3,14,9,00) # 9:00am, Sunday, March 14th, 2004
71
+ @datetime_200709161007 = DateTime.new(2007,9,16,10,7)
72
+ @time_20070925115959 = Time.mktime(2007,9,25,11,59,59) # 11:59:59am, Tuesday, September 25th, 2007
73
+ @time_20070926000000 = Time.mktime(2007,9,26,0,0,0) # 12:00:00am, Wednesday, September 26th, 2007
74
+ @time_20070927065959 = Time.mktime(2007,9,27,6,59,59) # 6:59:59am, Thursday, September 27th, 2007
75
+ @time_20070927115900 = Time.mktime(2007,9,27,11,59,0) # 11:59:00am, Thursday, September 27th, 2007
76
+ @time_20070928000000 = Time.mktime(2007,9,28,0,0,0) # 12:00:00am, Friday, September 28th, 2007
77
+ @time_20070929110000 = Time.mktime(2007,9,29,11,0,0) # 11:00:00am, Saturday, September 29th, 2007
78
+ @time_20070929000000 = Time.mktime(2007,9,29,0,0,0) # 12:00:00am, Saturday, September 29th, 2007
79
+ @time_20070929235959 = Time.mktime(2007,9,29,23,59,59) # 11:59:59pm, Saturday, September 29th, 2007
80
+ @time_20070930235959 = Time.mktime(2007,9,30,23,59,59) # 11:59:59am, Sunday, September 30th, 2007
81
+ end
82
+
83
+ def test_nothing
84
+ # Sigh...I should figure out how to tell TestUnit that this is an "abstract" class
85
+ end
86
+
87
+ end
88
+
89
+ class StubExpression
90
+ include Runt
91
+ include TExpr
92
+ attr_accessor :match, :string, :overlap, :args
93
+ def initialize(match=false, string="StubExpression",overlap=false)
94
+ @match=match
95
+ @string=string
96
+ @overlap=overlap
97
+ @args=[]
98
+ end
99
+ def include?(arg)
100
+ @args << arg
101
+ @match
102
+ end
103
+ def overlap?(arg)
104
+ @args << arg
105
+ @overlap
106
+ end
107
+ def to_s
108
+ @string
109
+ end
110
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baseexpressiontest'
4
+
5
+ # Unit tests for BeforeTE class
6
+ # Author:: Matthew Lipper
7
+
8
+ class BeforeTETest < BaseExpressionTest
9
+
10
+ include TExpr
11
+
12
+ def test_include_inclusive
13
+ expr = BeforeTE.new(@pdate_20071030, true)
14
+ assert expr.include?(@date_20050101), "Should include an earlier date"
15
+ assert !expr.include?(@pdate_20071114), "Should not include a later date"
16
+ assert expr.include?(@pdate_20071030), "Should include the same date"
17
+ end
18
+
19
+ def test_include_non_inclusive
20
+ expr = BeforeTE.new(@pdate_20071030)
21
+ assert expr.include?(@date_20050101), "Should include an earlier date"
22
+ assert !expr.include?(@pdate_20071114), "Should not include a later date"
23
+ assert !expr.include?(@pdate_20071030), "Should not include the same date"
24
+ end
25
+
26
+ def test_to_s
27
+ expr = BeforeTE.new(@pdate_20071114)
28
+ assert_equal "before #{Runt.format_date(@pdate_20071114)}", expr.to_s
29
+ end
30
+
31
+ end
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'baseexpressiontest'
4
+
5
+ # Unit tests for Collection class
6
+ # Author:: Matthew Lipper
7
+
8
+ class CollectionTest < BaseExpressionTest
9
+
10
+ def setup
11
+ super
12
+ @expr = Collection.new
13
+ end
14
+
15
+ def test_initialize
16
+ assert !@expr.expressions.nil?, "Newly created Collection should have a non-nil @expressions attribute"
17
+ assert @expr.expressions.empty?, "Newly created Collection should have an empty @expressions attribute"
18
+ end
19
+
20
+ def test_include
21
+ #base class that should always return false
22
+ assert !@expr.include?(StubExpression.new(true)), "Collection#include? should always return false"
23
+ end
24
+
25
+
26
+ def test_to_s
27
+ assert_equal 'empty', @expr.to_s
28
+ assert_equal 'empty', @expr.to_s{['b','oo']}
29
+ dim = StubExpression.new(false,"Mock1")
30
+ @expr.expressions << dim
31
+ assert_equal 'ff' + dim.to_s, @expr.to_s{['ff','nn']}
32
+ red = StubExpression.new(false, "Mock2")
33
+ @expr.expressions << red
34
+ assert_equal 'ff' + dim.to_s + 'nn' + red.to_s, @expr.to_s{['ff','nn']}
35
+ wim = StubExpression.new(false, "Mock3")
36
+ @expr.expressions << wim
37
+ assert_equal 'ff' + dim.to_s + 'nn' + red.to_s + 'nn' + wim.to_s, @expr.to_s{['ff','nn']}
38
+ end
39
+
40
+ def test_add
41
+ e1 = StubExpression.new
42
+ e2 = StubExpression.new
43
+ assert @expr.expressions.empty?, "Empty Collection should not include any expressions"
44
+ result = @expr.add(e1)
45
+ assert_same @expr, result, "Collection#add method should return self instance"
46
+ assert @expr.expressions.include?(e1), "Collection should include added expression"
47
+ @expr.add(e2)
48
+ assert @expr.expressions.include?(e2), "Collection should include added expression"
49
+ assert_same e2, @expr.expressions.pop, "Collection should keep added expressions in stack order"
50
+ assert_same e1, @expr.expressions.pop, "Collection should keep added expressions in stack order"
51
+ end
52
+
53
+ def test_overlap
54
+ stub = StubExpression.new(false, "stubby", true) # start with "always overlap?" stub
55
+ assert !@expr.overlap?(stub), "Empty Collection should never overlap"
56
+ @expr.add StubExpression.new
57
+ assert @expr.overlap?(stub), "Collection should overlap with given stub argument"
58
+ assert_same stub.args[0], @expr.expressions.first, "First expression should be given to stub in the first call to overlap?"
59
+ stub.overlap = false
60
+ assert !@expr.overlap?(stub), "Collection should not overlap with given stub argument"
61
+ end
62
+
63
+ end