Welcome to Work Calendar. To experiment with that code, run bin/console
for an interactive prompt.
All the main logic in the gem is being maintained in work_calendar.rb
file. I chose to implement the functionality using a module to provide the flexibility to consume this library as mixin by other components. all the methods are implemented as class level as methods. mainly becuause we do not need class instantiation to perform these operations.
Tests are written using rspec
- whether to implement using module or a class: I went ahead with implmenting this as a module provides providing methods that you can use across multiple classes. thinking about them as library (one of the main points in requirement)
- class methods or instance methods:
I went ahead with class level methods mainly becuause we do not need class instantiation to perform these operations. These operations can be performed independent of the behaviour of the class that is consuming it. To verify it works as intended I have added a
TestCal
class which can be used to test the library (module) is behaving as intended when consumed by other classes. To do so jut execute the bellow line
# this just calls the test method in TestCal class which calls configure method in module
TestCal.new.test
- parameter validation: Adding nil checks or checking for date to be valid type. In order to take advantage of ruby's duck typing I didnt add these kind of validation, instead I went ahead with rescuing a
NoMethodError
. In this way the module by itself has no idea of the type of the date variable passed in. Having less knowledge of outside object makes the module more flexible. Now methods are capable of accepting any object which responds towday
,prev_day
,next_day
I encountered few special cases (edge cases) some of them are:
-
when the block passed to configure does not contain a list
- configure method handles this case by setting the missing list to empty array (if both are not passed, both are set to empty array).
active?
method handles this by checking only the non empty list to see if the given date is active or not.
-
negative number being passed to days_after/before method
- this is being handled by returning the given the date back when a number is negative.
-
given date is newer than the end date for the between method
- this is handled by returning empty array in this case
Some of the operations you can perform
https://github.com/sujaysudheenda/WorkCalendar.git
cd WorkCalendar
bin/console
WorkCalendar.configure do |c|
c.weekdays = %i[mon tue wed thu fri]
c.holidays = [Date.new(2015, 1, 1), Date.new(2015, 7, 3), Date.new(2015, 12, 25)]
end
WorkCalendar.active?(Date.new(2014, 1, 5))
WorkCalendar.days_before(5, Date.new(2015, 1, 5))
WorkCalendar.days_after(5, Date.new(2015, 1, 5))
WorkCalendar.between(Date.new(2015, 1, 1), Date.new(2015, 1, 8))
The gem is available as open source under the terms of the MIT License.