slot_machine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ .bundle
3
+ .rvmrc
4
+ Gemfile.lock
5
+ doc
6
+ pkg
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - jruby-18mode
6
+ - jruby-19mode
7
+ - rbx-18mode
8
+ - rbx-19mode
9
+ - 1.8.7
10
+ - ree
@@ -0,0 +1,5 @@
1
+ = SlotMachine CHANGELOG
2
+
3
+ == Version 0.1.0 (September 16, 2012)
4
+
5
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :gem_default do
6
+ gem "slot_machine", :path => "."
7
+ end
8
+
9
+ group :gem_development do
10
+ gem "pry"
11
+ end
12
+
13
+ group :gem_test do
14
+ gem "minitest"
15
+ gem "mocha"
16
+ gem "pry"
17
+ gem "rake"
18
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Paul Engel
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,146 @@
1
+ # SlotMachine [![Build Status](https://secure.travis-ci.org/archan937/slot_machine.png)](http://travis-ci.org/archan937/slot_machine)
2
+
3
+ Ruby gem for matching available slots (time slots are also supported)
4
+
5
+ ## Introduction
6
+
7
+ One of the classic programming problems is the determination of time slot availability. Very often this is used within scheduling / calendar programs. SlotMachine is a very small Ruby gem which can do the job for you. It does not only focuses on time slots, but also slots in general.
8
+
9
+ ## Installation
10
+
11
+ ### Add `SlotMachine` to your Gemfile
12
+
13
+ gem "slot_machine"
14
+
15
+ ### Install the gem dependencies
16
+
17
+ $ bundle
18
+
19
+ ## Usage
20
+
21
+ ### SlotMachine::Slot module
22
+
23
+ The core implementation of SlotMachine is written in `SlotMachine::Slot`. A module which has to be included within a Ruby class.
24
+ SlotMachine provides the classes `Slot` and `TimeSlot` of which `Slot` is defined as follows:
25
+
26
+ class Slot
27
+ include SlotMachine::Slot
28
+ end
29
+
30
+ Clean and simple. Cool, huh? `TimeSlot` also includes the `SlotMachine::Slot` module and overrides a few methods to provide time slot specific behaviour.
31
+
32
+ ### Slot
33
+
34
+ `SlotMachine` is pretty straightforward. A slot consists of a start and an end (integer) value. You can define a slot as follows:
35
+
36
+ [1] pry(main)> s = Slot.new 0..20
37
+ => #<Slot @start=0 @end=20>
38
+ [2] pry(main)> s.start
39
+ => 0
40
+ [3] pry(main)> s.end
41
+ => 20
42
+
43
+ After having defined a slot, you can match available slots within that slot. Let's say that you want to calculate available slots with a length of `10`:
44
+
45
+ [4] pry(main)> s.match 10
46
+ => [#<Slot @start=0 @end=10>, #<Slot @start=10 @end=20>]
47
+
48
+ The `match` method returns an array with the available slots. At default, the `Slot` searches for slots with an interval size of `10` and thus `0..10` and `10..20` are matched.
49
+
50
+ You can change the interval by passing it as a second argument. Using an interval size of `2`:
51
+
52
+ [5] pry(main)> s.match 10, 2
53
+ => [#<Slot @start=0 @end=10>,
54
+ #<Slot @start=2 @end=12>,
55
+ #<Slot @start=4 @end=14>,
56
+ #<Slot @start=6 @end=16>,
57
+ #<Slot @start=8 @end=18>,
58
+ #<Slot @start=10 @end=20>]
59
+
60
+ You can also match a slot with another slot instance. This returns the slot in which both slots overlap each other:
61
+
62
+ [5] pry(main)> s.match 15..30 #=> you can also use: s.match Slot.new(15..30)
63
+ => [#<Slot @start=15 @end=20>]
64
+ [6] s.match Slot.new(21..30) #=> no overlap
65
+ => []
66
+
67
+ ### TimeSlot
68
+
69
+ The `TimeSlot` class is (of course) similar to the `Slot` class, but accepts military times (e.g. 1300 for 1:00 pm). In other words, it only counts from `0` untill `59` within a `0` to `99` range. Also, the default interval size is `15`.
70
+
71
+ An example:
72
+
73
+ [1] pry(main)> ts = TimeSlot.new 1015..1045
74
+ => #<TimeSlot @start=1015 @end=1045>
75
+ [2] pry(main)> ts.match 10
76
+ => [#<TimeSlot @start=1015 @end=1025>, #<TimeSlot @start=1030 @end=1040>]
77
+ [3] pry(main)> ts.match 10, 5
78
+ => [#<TimeSlot @start=1015 @end=1025>,
79
+ #<TimeSlot @start=1020 @end=1030>,
80
+ #<TimeSlot @start=1025 @end=1035>,
81
+ #<TimeSlot @start=1030 @end=1040>,
82
+ #<TimeSlot @start=1035 @end=1045>]
83
+ [4] pry(main)> ts.match 1038..1100 #=> you can also use: ts.match TimeSlot.new(1038..1100)
84
+ => [#<TimeSlot @start=1038 @end=1045>]
85
+
86
+ ## Using the console
87
+
88
+ The SlotMachine repo is provided with `script/console` which you can use for development / testing purposes.
89
+
90
+ Run the following command in your console:
91
+
92
+ $ script/console
93
+ Loading development environment (SlotMachine 0.1.0)
94
+ [1] pry(main)> s = Slot.new 0..25
95
+ => #<Slot @start=0 @end=25>
96
+ [2] pry(main)> s.match 15
97
+ => [#<Slot @start=0 @end=15>, #<Slot @start=10 @end=25>]
98
+ [3] pry(main)> s.match 10, 4
99
+ => [#<Slot @start=0 @end=10>,
100
+ #<Slot @start=4 @end=14>,
101
+ #<Slot @start=8 @end=18>,
102
+ #<Slot @start=12 @end=22>]
103
+ [4] pry(main)> ts = TimeSlot.new 1015..1045
104
+ => #<TimeSlot @start=1015 @end=1045>
105
+ [5] pry(main)> ts.match 10
106
+ => [#<TimeSlot @start=1015 @end=1025>, #<TimeSlot @start=1030 @end=1040>]
107
+ [6] pry(main)> ts.match 10, 5
108
+ => [#<TimeSlot @start=1015 @end=1025>,
109
+ #<TimeSlot @start=1020 @end=1030>,
110
+ #<TimeSlot @start=1025 @end=1035>,
111
+ #<TimeSlot @start=1030 @end=1040>,
112
+ #<TimeSlot @start=1035 @end=1045>]
113
+
114
+ ## Testing
115
+
116
+ Run the following command for testing:
117
+
118
+ $ rake
119
+
120
+ You can also run a single test file:
121
+
122
+ $ ruby test/unit/test_time_slot.rb
123
+
124
+ ## Closing words
125
+
126
+ Well that's about it! Pretty straightforward, right? Have fun playing with the `SlotMachine`! ^^
127
+
128
+ ## TODO
129
+
130
+ * Accept Time objects within TimeSlot
131
+
132
+ ## Contact me
133
+
134
+ For support, remarks and requests, please mail me at [paul.engel@holder.nl](mailto:paul.engel@holder.nl).
135
+
136
+ ## License
137
+
138
+ Copyright (c) 2012 Paul Engel, released under the MIT license
139
+
140
+ [http://holder.nl](http://holder.nl) - [http://codehero.es](http://codehero.es) - [http://gettopup.com](http://gettopup.com) - [http://github.com/archan937](http://github.com/archan937) - [http://twitter.com/archan937](http://twitter.com/archan937) - [paul.engel@holder.nl](mailto:paul.engel@holder.nl)
141
+
142
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
143
+
144
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
145
+
146
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ task :default => :test
6
+
7
+ Rake::TestTask.new do |test|
8
+ test.pattern = "test/**/test_*.rb"
9
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,3 @@
1
+ class Slot
2
+ include SlotMachine::Slot
3
+ end
@@ -0,0 +1,4 @@
1
+ require "slot_machine/slot"
2
+ require "slot_machine/version"
3
+ require "slot"
4
+ require "time_slot"
@@ -0,0 +1,163 @@
1
+ module SlotMachine
2
+ module Slot
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ attr_reader :start, :end, :length
7
+
8
+ def self.interval(value)
9
+ @interval = value
10
+ end
11
+
12
+ def self.default_interval
13
+ @interval || 10
14
+ end
15
+ end
16
+ end
17
+
18
+ def initialize(range_or_length)
19
+ if range_or_length.is_a? Range
20
+ @type = :range
21
+ self.start = range_or_length.first
22
+ self.end = range_or_length.last
23
+ else
24
+ @type = :length
25
+ self.length = range_or_length
26
+ end
27
+ end
28
+
29
+ def range?
30
+ @type == :range
31
+ end
32
+
33
+ def length?
34
+ @type == :length
35
+ end
36
+
37
+ def start=(value)
38
+ @start = start!(value) if range?
39
+ end
40
+
41
+ def end=(value)
42
+ @end = end!(value) if range?
43
+ end
44
+
45
+ def length=(value)
46
+ @length = length!(value) if length?
47
+ end
48
+
49
+ def match(other, interval = nil)
50
+ interval ||= self.class.default_interval
51
+ raise ArgumentError, "Interval has to be greater than 0 (#{interval} given)" unless interval > 0
52
+ unless self.class == other.class
53
+ other = self.class.new other
54
+ end
55
+ match_compared to_compared, other.to_compared, interval
56
+ end
57
+
58
+ def ==(other)
59
+ self.class == other.class && self.start == other.start && self.end == other.end && self.length == other.length
60
+ end
61
+
62
+ def inspect
63
+ inspect_variables = begin
64
+ if range?
65
+ "@start=#{@start} @end=#{@end}"
66
+ else
67
+ "@length=#{@length}"
68
+ end
69
+ end
70
+ "#<#{self.class.name} #{inspect_variables}>"
71
+ end
72
+
73
+ protected
74
+
75
+ def valid?(value)
76
+ true
77
+ end
78
+
79
+ def to_compared
80
+ if range?
81
+ to_array
82
+ else
83
+ @length
84
+ end
85
+ end
86
+
87
+ def to_array
88
+ (@start..@end).to_a.tap do |array|
89
+ array.pop
90
+ end
91
+ end
92
+
93
+ def from_array(array)
94
+ self.class.new array.first..(add(array.last, 1))
95
+ end
96
+
97
+ def add(a, b)
98
+ a + b
99
+ end
100
+
101
+ private
102
+
103
+ def start!(value)
104
+ valid! abs!(lt!(value, @end))
105
+ end
106
+
107
+ def end!(value)
108
+ valid! abs!(gt!(value, @start))
109
+ end
110
+
111
+ def length!(value)
112
+ abs! value
113
+ end
114
+
115
+ def gt!(value, compared)
116
+ typecast! value, :>, compared
117
+ end
118
+
119
+ def lt!(value, compared)
120
+ typecast! value, :<, compared
121
+ end
122
+
123
+ def abs!(value)
124
+ typecast! value, :>=, 0
125
+ end
126
+
127
+ def typecast!(value, operator, compared)
128
+ Integer(value.to_s).tap do |value|
129
+ raise ArgumentError, "Passed value should be #{operator} #{compared} (#{value} given)" if compared && !value.send(operator, compared)
130
+ end
131
+ end
132
+
133
+ def valid!(value)
134
+ raise ArgumentError, "Passed value is invalid (#{value} given)" unless valid?(value)
135
+ value
136
+ end
137
+
138
+ def match_compared(a, b, interval)
139
+ if a.is_a?(Array) && b.is_a?(Fixnum)
140
+ raise ArgumentError, "Length has to be greater than 0 (#{b} given)" unless b > 0
141
+ i = 0
142
+ [].tap do |matches|
143
+ while (a.size / b) > 0
144
+ matches << from_array(a[0, b])
145
+ a.shift interval
146
+ i += interval
147
+ end
148
+ end
149
+ elsif a.is_a?(Fixnum) && b.is_a?(Array)
150
+ match_compared b, a, interval
151
+ elsif a.is_a?(Array) && b.is_a?(Array)
152
+ [].tap do |matches|
153
+ unless (array = a & b).empty?
154
+ matches << from_array(array)
155
+ end
156
+ end
157
+ else
158
+ raise ArgumentError, "Cannot match when passing two length slots"
159
+ end
160
+ end
161
+
162
+ end
163
+ end
@@ -0,0 +1,7 @@
1
+ module SlotMachine #:nodoc:
2
+ MAJOR = 0
3
+ MINOR = 1
4
+ TINY = 0
5
+
6
+ VERSION = [MAJOR, MINOR, TINY].join(".")
7
+ end
@@ -0,0 +1,26 @@
1
+ class TimeSlot
2
+ include SlotMachine::Slot
3
+
4
+ def self.default_interval
5
+ @interval || 15
6
+ end
7
+
8
+ protected
9
+
10
+ def valid?(value)
11
+ (value - (100 * (value / 100))) < 60
12
+ end
13
+
14
+ def to_array
15
+ super.delete_if{|i| !valid?(i)}
16
+ end
17
+
18
+ def add(a, b)
19
+ i = a
20
+ b.times do |t|
21
+ while !valid?(i += 1) do; end
22
+ end
23
+ i
24
+ end
25
+
26
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "bundler"
5
+
6
+ Bundler.require :gem_default, :gem_development
7
+
8
+ puts "Loading development environment (SlotMachine #{SlotMachine::VERSION})"
9
+
10
+ Pry.start
@@ -0,0 +1,16 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["Paul Engel"]
5
+ gem.email = ["paul.engel@holder.nl"]
6
+ gem.summary = %q{Ruby gem for matching available slots (time slots are also supported)}
7
+ gem.description = %q{One of the classic programming problems is the determination of time slot availability. Very often this is used within scheduling / calendar programs. SlotMachine is a very small Ruby gem which can do the job for you. It does not only focuses on time slots, but also slots in general.}
8
+ gem.homepage = "https://github.com/archan937/slot_machine"
9
+
10
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
11
+ gem.files = `git ls-files`.split("\n")
12
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
+ gem.name = "slot_machine"
14
+ gem.require_paths = ["lib"]
15
+ gem.version = "0.1.0"
16
+ end
@@ -0,0 +1,7 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+
4
+ require "minitest/unit"
5
+ require "minitest/autorun"
6
+
7
+ Bundler.require :gem_default, :gem_test
@@ -0,0 +1,237 @@
1
+ require File.expand_path("../../test_helper", __FILE__)
2
+
3
+ module Unit
4
+ class TestSlot < MiniTest::Unit::TestCase
5
+
6
+ describe Slot do
7
+ describe "class methods" do
8
+ it "should have the expected class methods" do
9
+ assert Slot.respond_to?(:interval)
10
+ assert Slot.respond_to?(:default_interval)
11
+
12
+ assert_equal 10, Slot.default_interval
13
+ Slot.class_eval do
14
+ interval 20
15
+ end
16
+ assert_equal 20, Slot.default_interval
17
+ end
18
+ end
19
+
20
+ describe "instance methods" do
21
+ it "should have the expected instance methods" do
22
+ slot = Slot.new 1
23
+ assert slot.respond_to?(:range?)
24
+ assert slot.respond_to?(:length?)
25
+ assert slot.respond_to?(:start)
26
+ assert slot.respond_to?(:start=)
27
+ assert slot.respond_to?(:end)
28
+ assert slot.respond_to?(:end=)
29
+ assert slot.respond_to?(:length)
30
+ assert slot.respond_to?(:length=)
31
+ assert slot.respond_to?(:to_compared)
32
+ assert slot.respond_to?(:match)
33
+ end
34
+ end
35
+
36
+ describe "initialization" do
37
+ it "should accept a range" do
38
+ slot = Slot.new 10..20
39
+ assert_equal 10, slot.start
40
+ assert_equal 20, slot.end
41
+ end
42
+
43
+ it "should accept a length" do
44
+ slot = Slot.new 10
45
+ assert_equal 10, slot.length
46
+ end
47
+
48
+ it "should raise an exception when invalid" do
49
+ assert_raises ArgumentError do
50
+ Slot.new
51
+ end
52
+ assert_raises ArgumentError do
53
+ Slot.new "bar"
54
+ end
55
+ assert_raises ArgumentError do
56
+ Slot.new 1.."bar"
57
+ end
58
+ assert_raises ArgumentError do
59
+ Slot.new "bar"..1
60
+ end
61
+ assert_raises ArgumentError do
62
+ Slot.new "slot".."bar"
63
+ end
64
+ end
65
+
66
+ it "should return whether it's a range or a length" do
67
+ slot = Slot.new 10..20
68
+ assert slot.range?
69
+ assert !slot.length?
70
+
71
+ slot = Slot.new 10
72
+ assert !slot.range?
73
+ assert slot.length?
74
+ end
75
+ end
76
+
77
+ describe "equality" do
78
+ it "should return whether it equals another objects" do
79
+ slot = Slot.new 1
80
+
81
+ assert !(slot == 1)
82
+ assert !(slot == Slot.new(1..2))
83
+ assert_equal slot, Slot.new(1)
84
+
85
+ slot = Slot.new 1..2
86
+
87
+ assert !(slot == (1..2))
88
+ assert !(slot == Slot.new(1))
89
+ assert_equal slot, Slot.new(1..2)
90
+ end
91
+ end
92
+
93
+ describe "range slots" do
94
+ it "should only set start or end (not length) and typecast the passed argument" do
95
+ slot = Slot.new 10..20
96
+
97
+ slot.start = 0
98
+ assert_equal 0, slot.start
99
+
100
+ assert_raises ArgumentError do
101
+ slot.start = "bar"
102
+ end
103
+
104
+ slot.end = 10
105
+ assert_equal 10, slot.end
106
+
107
+ assert_raises ArgumentError do
108
+ slot.end = "bar"
109
+ end
110
+
111
+ slot.length = 30
112
+ assert_nil slot.length
113
+
114
+ slot.length = "bar"
115
+ assert_nil slot.length
116
+ end
117
+
118
+ it "should validate the assigned value" do
119
+ assert_raises ArgumentError do
120
+ Slot.new -10..10
121
+ end
122
+
123
+ assert_raises ArgumentError do
124
+ Slot.new 10..1
125
+ end
126
+
127
+ slot = Slot.new 10..20
128
+
129
+ assert_raises ArgumentError do
130
+ slot.start = -10
131
+ end
132
+
133
+ assert_equal 10, slot.start
134
+
135
+ assert_raises ArgumentError do
136
+ slot.start = 30
137
+ end
138
+
139
+ assert_equal 10, slot.start
140
+
141
+ assert_raises ArgumentError do
142
+ slot.end = 5
143
+ end
144
+
145
+ assert_equal 20, slot.end
146
+
147
+ assert_raises ArgumentError do
148
+ slot.end = -10
149
+ end
150
+ end
151
+
152
+ it "should represent itself as an array when invoking to_compared" do
153
+ assert_equal [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], Slot.new(10..20).send(:to_compared)
154
+ assert_equal 50, Slot.new(855..905).send(:to_compared).size
155
+ end
156
+
157
+ it "should be able to match available slots" do
158
+ slot = Slot.new 0..15
159
+ assert_equal [], slot.match(20)
160
+ assert_equal [Slot.new(0..15)], slot.match(15)
161
+ assert_equal [Slot.new(0..10)], slot.match(10)
162
+ assert_equal [Slot.new(0..10), Slot.new(5..15)], slot.match(10, 5)
163
+ assert_equal [Slot.new(0..10), Slot.new(5..15)], slot.match(Slot.new(10), 5)
164
+ assert_equal [Slot.new(0..10), Slot.new(5..15)], Slot.new(10).match(0..15, 5)
165
+ assert_equal [Slot.new(0..10), Slot.new(5..15)], Slot.new(10).match(Slot.new(0..15), 5)
166
+ assert_equal [
167
+ Slot.new(0..5),
168
+ Slot.new(5..10),
169
+ Slot.new(10..15)
170
+ ], slot.match(5, 5)
171
+
172
+ slot = Slot.new 10..20
173
+ assert_equal [], slot.match(0..5)
174
+ assert_equal [], slot.match(25..30)
175
+ assert_equal [Slot.new(10..20)], slot.match(10..20)
176
+ assert_equal [Slot.new(10..20)], slot.match(0..30)
177
+ assert_equal [Slot.new(10..15)], slot.match(0..15)
178
+ assert_equal [Slot.new(15..20)], slot.match(15..30)
179
+
180
+ assert_raises ArgumentError do
181
+ slot.match 0
182
+ end
183
+ assert_raises ArgumentError do
184
+ slot.match -1
185
+ end
186
+ assert_raises ArgumentError do
187
+ slot.match 1, 0
188
+ end
189
+ assert_raises ArgumentError do
190
+ Slot.new(5).match(5)
191
+ end
192
+ end
193
+ end
194
+
195
+ describe "length slots" do
196
+ it "should only set length (not start or end) and typecast the passed argument" do
197
+ slot = Slot.new 10
198
+
199
+ slot.start = 0
200
+ assert_nil slot.start
201
+
202
+ slot.start = "bar"
203
+ assert_nil slot.start
204
+
205
+ slot.end = 10
206
+ assert_nil slot.end
207
+
208
+ slot.end = "bar"
209
+ assert_nil slot.end
210
+
211
+ slot.length = 30
212
+ assert_equal 30, slot.length
213
+
214
+ assert_raises ArgumentError do
215
+ slot.length = "bar"
216
+ end
217
+ end
218
+
219
+ it "should validate the assigned value" do
220
+ assert_raises ArgumentError do
221
+ Slot.new -10
222
+ end
223
+
224
+ slot = Slot.new 10
225
+
226
+ assert_raises ArgumentError do
227
+ slot.length = -10
228
+ end
229
+ end
230
+
231
+ it "should represent itself as an integer when invoking to_compared" do
232
+ assert_equal 10, Slot.new(10).send(:to_compared)
233
+ end
234
+ end
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path("../../test_helper", __FILE__)
2
+
3
+ module Unit
4
+ class TestTimeSlot < MiniTest::Unit::TestCase
5
+
6
+ describe TimeSlot do
7
+ it "should have the expected default interval" do
8
+ assert_equal 15, TimeSlot.default_interval
9
+ end
10
+
11
+ it "should validate the assigned value" do
12
+ assert TimeSlot.new(855..859)
13
+ assert_raises ArgumentError do
14
+ TimeSlot.new 855..860
15
+ end
16
+ end
17
+
18
+ it "should represent itself as an array when invoking to_compared" do
19
+ assert_equal 10 , TimeSlot.new(855..905).send(:to_compared).size
20
+ assert_equal 222, TimeSlot.new(955..1337).send(:to_compared).size
21
+ assert_equal [855, 856, 857, 858, 859, 900, 901, 902, 903, 904], TimeSlot.new(855..905).send(:to_compared)
22
+ end
23
+
24
+ it "should be able to match available slots" do
25
+ time_slot = TimeSlot.new 1015..1200
26
+
27
+ assert_equal [], time_slot.match(120)
28
+ assert_equal [TimeSlot.new(1015..1155)], time_slot.match(100)
29
+ assert_equal [TimeSlot.new(1015..1200)], time_slot.match(105)
30
+ assert_equal [TimeSlot.new(1015..1145), TimeSlot.new(1030..1200)], time_slot.match(90)
31
+
32
+ assert_equal [
33
+ TimeSlot.new(1015..1140),
34
+ TimeSlot.new(1025..1150),
35
+ TimeSlot.new(1035..1200)
36
+ ], time_slot.match(85, 10)
37
+
38
+ assert_equal [
39
+ TimeSlot.new(1015..1055),
40
+ TimeSlot.new(1033..1113),
41
+ TimeSlot.new(1051..1131),
42
+ TimeSlot.new(1109..1149)
43
+ ], time_slot.match(40, 18)
44
+
45
+ assert_equal [], time_slot.match(945..1005)
46
+ assert_equal [], time_slot.match(1205..1225)
47
+ assert_equal [TimeSlot.new(1015..1200)], time_slot.match(1015..1200)
48
+ assert_equal [TimeSlot.new(1015..1200)], time_slot.match(900..1300)
49
+ assert_equal [TimeSlot.new(1015..1030)], time_slot.match(900..1030)
50
+ assert_equal [TimeSlot.new(1155..1200)], time_slot.match(1155..1300)
51
+ end
52
+ end
53
+
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slot_machine
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Paul Engel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-09-15 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: One of the classic programming problems is the determination of time slot availability. Very often this is used within scheduling / calendar programs. SlotMachine is a very small Ruby gem which can do the job for you. It does not only focuses on time slots, but also slots in general.
22
+ email:
23
+ - paul.engel@holder.nl
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - .travis.yml
33
+ - CHANGELOG.rdoc
34
+ - Gemfile
35
+ - MIT-LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - VERSION
39
+ - lib/slot.rb
40
+ - lib/slot_machine.rb
41
+ - lib/slot_machine/slot.rb
42
+ - lib/slot_machine/version.rb
43
+ - lib/time_slot.rb
44
+ - script/console
45
+ - slot_machine.gemspec
46
+ - test/test_helper.rb
47
+ - test/unit/test_slot.rb
48
+ - test/unit/test_time_slot.rb
49
+ homepage: https://github.com/archan937/slot_machine
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options: []
54
+
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ hash: 3
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 1.8.24
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Ruby gem for matching available slots (time slots are also supported)
82
+ test_files:
83
+ - test/test_helper.rb
84
+ - test/unit/test_slot.rb
85
+ - test/unit/test_time_slot.rb