PageRenderTime 135ms CodeModel.GetById 8ms app.highlight 122ms RepoModel.GetById 1ms app.codeStats 0ms

/spec/aef/weekling/week_day_spec.rb

https://gitlab.com/weekling/weekling
Ruby | 623 lines | 488 code | 117 blank | 18 comment | 13 complexity | aa21e0d90cf6a2d0eb52002faf3387f2 MD5 | raw file
  1# encoding: UTF-8
  2=begin
  3Copyright Alexander E. Fischer <aef@raxys.net>, 2012
  4
  5This file is part of Weekling.
  6
  7Permission to use, copy, modify, and/or distribute this software for any
  8purpose with or without fee is hereby granted, provided that the above
  9copyright notice and this permission notice appear in all copies.
 10
 11THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 12REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 13FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 14INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 15LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 16OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 17PERFORMANCE OF THIS SOFTWARE.
 18=end
 19
 20require 'spec_helper'
 21require 'aef/weekling/week_day'
 22require 'ostruct'
 23
 24describe Aef::Weekling::WeekDay do
 25  [:today, :now].each do |method|
 26    context ".#{method}" do
 27      it "should generate a representation of the current day as week day" do
 28        today = Date.today
 29
 30        week_day = described_class.method(method).call
 31
 32        week_day.week.year.should  eql Aef::Weekling::Year.new(today.year)
 33        week_day.week.index.should eql today.cweek
 34        week_day.index.should      eql ((today.wday - 1) % 7) + 1
 35      end
 36    end
 37  end
 38  
 39  context ".parse" do
 40    it "should recognize an ancient week day" do
 41      week_day = described_class.parse('-1503-W50-6')
 42
 43      week_day.week.should  eql Aef::Weekling::Week.new(-1503, 50)
 44      week_day.index.should eql 6
 45    end
 46
 47    it "should recognize a normal week day" do
 48      week_day = described_class.parse('2011-W30-1')
 49
 50      week_day.week.should  eql Aef::Weekling::Week.new(2011, 30)
 51      week_day.index.should eql 1
 52    end
 53
 54    it "should recognize a post apocalyptic week day" do
 55      week_day = described_class.parse('50023-W03-7')
 56
 57      week_day.week.should  eql Aef::Weekling::Week.new(50023, 3)
 58      week_day.index.should eql 7
 59    end
 60
 61    it "should report being unable to parse the given String" do
 62      lambda{
 63        described_class.parse('no week day!')
 64      }.should raise_error(ArgumentError, 'No week day found for parsing')
 65    end
 66  end
 67
 68  context ".new" do
 69    it "should complain about a param of invalid type" do
 70      lambda {
 71        described_class.new(123)
 72      }.should raise_error(ArgumentError, 'A single argument must either respond to #week and #index or to #to_date')
 73    end
 74
 75    it "should complain about less than one argument" do
 76      lambda {
 77        described_class.new
 78      }.should raise_error(ArgumentError, 'wrong number of arguments (0 for 1..3)')
 79    end
 80
 81    it "should complain about more than three arguments" do
 82      lambda {
 83        described_class.new(123, 456, 789, 123)
 84      }.should raise_error(ArgumentError, 'wrong number of arguments (4 for 1..3)')
 85    end
 86
 87    it "should allow to create a weekday by a given year, week index and day index" do
 88      week_day = described_class.new(2011, 1, 6)
 89      week_day.week.should  eql Aef::Weekling::Week.new(2011, 1)
 90      week_day.index.should eql 6
 91    end
 92
 93    it "should allow to create a weekday by a given year, week index and day symbol" do
 94      week_day = described_class.new(2011, 1, :saturday)
 95      week_day.week.should  eql Aef::Weekling::Week.new(2011, 1)
 96      week_day.index.should eql 6
 97    end
 98
 99    it "should allow to create a weekday by a given WeekDay object" do
100      old_week_day = described_class.new(2011, 1, 6)
101
102      week_day = described_class.new(old_week_day)
103      week_day.week.should  eql Aef::Weekling::Week.new(2011, 1)
104      week_day.index.should eql 6
105    end
106
107    it "should allow to create a weekday by a given Week object and day index" do
108      week_day = described_class.new(Aef::Weekling::Week.new(2011, 1), 3)
109      week_day.week.should  eql Aef::Weekling::Week.new(2011, 1)
110      week_day.index.should eql 3
111    end
112
113    it "should allow to create a weekday by a given Week object and day symbol" do
114      week_day = described_class.new(Aef::Weekling::Week.new(2011, 1), :wednesday)
115      week_day.week.should  eql Aef::Weekling::Week.new(2011, 1)
116      week_day.index.should eql 3
117    end
118
119    it "should allow to create a weekday by a given Date object" do
120      date = Date.new(2011, 4, 6)
121
122      week_day = described_class.new(date)
123      week_day.week.should  eql Aef::Weekling::Week.new(2011, 14)
124      week_day.index.should eql 3
125    end
126
127    it "should be able to initialize a weekday within the last week of a year by a given Date object which is already in the following year" do
128      date = Date.new(1802, 1, 1)
129
130      week_day = described_class.new(date)
131      week_day.week.should  eql Aef::Weekling::Week.new(1801, 53)
132      week_day.index.should eql 5
133    end
134
135    it "should be able to initialize a weekday within the first week of a year by a given Date object which is still in the previous year" do
136      date = Date.new(2008, 12, 30)
137
138      week_day = described_class.new(date)
139      week_day.week.should  eql Aef::Weekling::Week.new(2009, 1)
140      week_day.index.should eql 2
141    end
142
143    it "should allow to create a weekday by a given DateTime object" do
144      datetime = DateTime.parse('2011-04-06T16:45:30')
145
146      week_day = described_class.new(datetime)
147      week_day.week.should  eql Aef::Weekling::Week.new(2011, 14)
148      week_day.index.should eql 3
149    end
150
151    it "should allow to create a weekday by a given Time object" do
152      datetime = Time.parse('2011-04-06T16:45:30')
153
154      week_day = described_class.new(datetime)
155      week_day.week.should  eql Aef::Weekling::Week.new(2011, 14)
156      week_day.index.should eql 3
157    end
158
159    it "should complain about a day index below 1" do
160      lambda {
161        described_class.new(Aef::Weekling::Week.today, 0)
162      }.should raise_error(ArgumentError)
163    end
164
165    it "should complain about a day index above 7" do
166      lambda {
167        described_class.new(Aef::Weekling::Week.today, 8)
168      }.should raise_error(ArgumentError)
169    end
170
171    it "should complain about an invalid day symbol" do
172      lambda {
173        described_class.new(Aef::Weekling::Week.today, :poopsday)
174      }.should raise_error(ArgumentError)
175    end
176  end
177  
178  context "#== (type independent equality)" do
179    it "should be true if week and index match" do
180      week =  described_class.new(2012, 1, 3)
181      other = described_class.new(2012, 1, 3)
182
183      week.should == other
184    end
185
186    it "should be true if week and index match, independent of the other object's type" do
187      week = described_class.new(2012, 1, 3)
188
189      other = OpenStruct.new
190      other.week = Aef::Weekling::Week.new(2012, 1)
191      other.index = 3
192
193      week.should == other
194    end
195
196    it "should be false if week matches but not index" do
197      week  = described_class.new(2012, 1, 2)
198      other = described_class.new(2012, 1, 4)
199
200      week.should_not == other
201    end
202
203    it "should be false if week matches but not index, independent of the other object's type" do
204      week = described_class.new(2012, 1, 2)
205
206      other = OpenStruct.new
207      other.week = Aef::Weekling::Week.new(2012, 1)
208      other.index = 4
209
210      week.should_not == other
211    end
212
213    it "should be false if index matches but not week" do
214      week = described_class.new(2011, 15, 1)
215      other = described_class.new(2011, 17, 1)
216
217      week.should_not == other
218    end
219
220    it "should be false if index matches but not week, independent of the other object's type" do
221      week = described_class.new(2011, 15, 1)
222
223      other = OpenStruct.new
224      other.week = Aef::Weekling::Week.new(2011, 17)
225      other.index = 1
226
227      week.should_not == other
228    end
229
230    it "should be false if both index and week do not match" do
231      week = described_class.new(2012, 23, 1)
232      other = described_class.new(2005, 14, 5)
233
234      week.should_not == other
235    end
236
237    it "should be false if both index and year do not match, independent of the other object's type" do
238      week = described_class.new(2012, 23, 1)
239
240      other = OpenStruct.new
241      other.week = Aef::Weekling::Week.new(2005, 14)
242      other.index = 5
243
244      week.should_not == other
245    end
246  end
247
248  context "#eql? (type dependent equality)" do
249    it "should be true if week and index match" do
250      week =  described_class.new(2012, 1, 3)
251      other = described_class.new(2012, 1, 3)
252
253      week.should eql other
254    end
255
256    it "should be false if week matches but not index" do
257      week  = described_class.new(2012, 1, 2)
258      other = described_class.new(2012, 1, 4)
259
260      week.should_not eql other
261    end
262
263    it "should be false if index matches but not week" do
264      week = described_class.new(2011, 15, 1)
265      other = described_class.new(2011, 17, 1)
266
267      week.should_not eql other
268    end
269
270    it "should be false if both index and week do not match" do
271      week = described_class.new(2012, 23, 1)
272      other = described_class.new(2005, 14, 4)
273
274      week.should_not eql other
275    end
276  end
277
278  context "#hash" do
279    it "should return Integers" do
280      a_week_day = described_class.new(2012, 5, 4)
281      another_week_day = described_class.new(2012, 5, 5)
282
283      a_week_day.hash.should be_a(Integer)
284      another_week_day.hash.should be_a(Integer)
285    end
286
287    it "should discriminate a week-day from another one" do
288      a_week_day = described_class.new(2012, 5, 4)
289      another_week_day = described_class.new(2012, 5, 5)
290
291      a_week_day.hash.should_not == another_week_day.hash
292    end
293  end
294
295  context "#<=>" do
296    it "should correctly determine the order of week days based on week" do
297      lower_week_day = described_class.new(2011, 13, 3)
298      higher_week_day = described_class.new(2012, 50, 3)
299
300      lower_week_day.should < higher_week_day
301    end
302
303    it "should correctly determine the order of week days based on year, independent of type" do
304      lower_week_day = described_class.new(2011, 13, 3)
305
306      higher_week_day = OpenStruct.new
307      higher_week_day.week = Aef::Weekling::Week.new(2012, 50)
308      higher_week_day.index = 3
309
310      lower_week_day.should < higher_week_day
311    end
312
313    it "should correctly determine the order of week days based on index" do
314      lower_week_day = described_class.new(2011, 15, 2)
315      higher_week_day = described_class.new(2011, 15, 3)
316
317      lower_week_day.should < higher_week_day
318    end
319
320    it "should correctly determine the order of week days based on index, independent of type" do
321      lower_week_day = described_class.new(2011, 15, 2)
322
323      higher_week_day = OpenStruct.new
324      higher_week_day.week = Aef::Weekling::Week.new(2011, 15)
325      higher_week_day.index = 3
326
327      lower_week_day.should < higher_week_day
328    end
329
330    it "should prioritize the order weeks when determining the order of week days" do
331      lower_week_day = described_class.new(2012, 13, 4)
332      higher_week_day = described_class.new(2012, 14, 3)
333
334      lower_week_day.should < higher_week_day
335    end
336
337    it "should prioritize the order weeks when determining the order of week days, independent of type" do
338      lower_week_day = described_class.new(2012, 13, 4)
339
340      higher_week_day = OpenStruct.new
341      higher_week_day.week = Aef::Weekling::Week.new(2012, 14)
342      higher_week_day.index = 3
343
344      lower_week_day.should < higher_week_day
345    end
346  end
347
348  context "#to_s" do
349    it "should be able to display an ancient week day" do
350      week_day = described_class.new(-1503, 50, 3)
351
352      week_day.to_s.should eql '-1503-W50-3'
353    end
354
355    it "should be able to display a normal week" do
356      week_day = described_class.new(2011, 30, 7)
357
358      week_day.to_s.should eql '2011-W30-7'
359    end
360
361    it "should be able to display a post apocalyptic week" do
362      week_day = described_class.new(50023, 3, 1)
363
364      week_day.to_s.should eql '50023-W03-1'
365    end
366  end
367
368  context "#inspect" do
369    it "should be able to display an ancient week day" do
370      week_day = described_class.new(-1503, 50, 3)
371
372      week_day.inspect.should eql '#<Aef::Weekling::WeekDay: -1503-W50-3>'
373    end
374
375    it "should be able to display a normal week" do
376      week_day = described_class.new(2011, 30, 7)
377
378      week_day.inspect.should eql '#<Aef::Weekling::WeekDay: 2011-W30-7>'
379    end
380
381    it "should be able to display a post apocalyptic week" do
382      week_day = described_class.new(50023, 3, 1)
383
384      week_day.inspect.should eql '#<Aef::Weekling::WeekDay: 50023-W03-1>'
385    end
386  end
387
388  context "#to_date" do
389    it "should translate to the Date of the day" do
390      week_day = described_class.new(2011, 30, 3)
391
392      week_day.to_date.should eql Date.new(2011, 7, 27)
393    end
394
395    it "should translate to the Date of the day in edge cases early in the year" do
396      week_day = described_class.new(2010, 52, 6)
397
398      week_day.to_date.should eql Date.new(2011, 1, 1)
399    end
400
401    it "should translate to the Date of the day in edge cases late in the year" do
402      week_day = described_class.new(2011, 52, 7)
403
404      week_day.to_date.should eql Date.new(2012, 1, 1)
405    end
406  end
407
408  context "#to_week_date" do
409    it "should return itself" do
410      week_day = described_class.new(2011, 30, 6)
411      week_day.to_week_day.should equal(week_day)
412    end
413  end
414
415  [:next, :succ].each do |method|
416    context "##{method}" do
417      it "should return the next week day" do
418        described_class.new(2011, 19, 3).method(method).call.should eql described_class.new(2011, 19, 4)
419      end
420
421      it "should return the next week day at the end of a week" do
422        described_class.new(2011, 30, 7).method(method).call.should eql described_class.new(2011, 31, 1)
423      end
424
425      it "should return the next week day at the end of a year with 52 weeks" do
426        described_class.new(2000, 52, 7).method(method).call.should eql described_class.new(2001, 1, 1)
427      end
428
429      it "should return the next week day at the end of a year with 53 weeks" do
430        described_class.new(1998, 53, 7).method(method).call.should eql described_class.new(1999, 1, 1)
431      end
432    end
433  end
434
435  [:previous, :pred].each do |method|
436    context "##{method}" do
437      it "should return the previous week day" do
438        described_class.new(2011, 20, 3).method(method).call.should eql described_class.new(2011, 20, 2)
439      end
440
441      it "should return the previous week day at the beginning of a week" do
442        described_class.new(2011, 9, 1).method(method).call.should eql described_class.new(2011, 8, 7)
443      end
444
445      it "should return the previous week day at the beginning of a year following a year with 52 weeks" do
446        described_class.new(2001, 1, 1).method(method).call.should eql described_class.new(2000, 52, 7)
447      end
448
449      it "should return the previous week day at the beginning of a year following a year with 53 weeks" do
450        described_class.new(1999, 1, 1).method(method).call.should eql described_class.new(1998, 53, 7)
451      end
452    end
453  end
454
455  context "#+" do
456    it "should be able to add a positive amount of days" do
457      (described_class.new(1996, 51, 4) + 2).should eql described_class.new(1996, 51, 6)
458    end
459
460    it "should be able to add a positive amount of days so that the result isn't in the week anymore'" do
461      (described_class.new(1996, 51, 4) + 4).should eql described_class.new(1996, 52, 1)
462    end
463
464    it "should be able to add a positive amount of days so that the result isn't in the year anymore'" do
465      (described_class.new(1996, 51, 4) + 12).should eql described_class.new(1997, 1, 2)
466    end
467
468    it "should be able to add a positive amount of days so that the result isn't in the year with 53 weeks anymore'" do
469      (described_class.new(1998, 51, 4) + 20).should eql described_class.new(1999, 1, 3)
470    end
471
472    it "should be able to add a negative amount of days" do
473      (described_class.new(1996, 2, 4) + -2).should eql described_class.new(1996, 2, 2)
474    end
475
476    it "should be able to add a negative amount of days so that the result isn't in the week anymore'" do
477      (described_class.new(1996, 2, 4) + -5).should eql described_class.new(1996, 1, 6)
478    end
479
480    it "should be able to add a negative amount of days so that the result isn't in the year anymore'" do
481      (described_class.new(1996, 2, 4) + -15).should eql described_class.new(1995, 52, 3)
482    end
483
484    it "should be able to add a negative amount of days so that the result is in the previous year with 53 weeks'" do
485      (described_class.new(1999, 2, 1) + -10).should eql described_class.new(1998, 53, 5)
486    end
487
488    it "should be able to add zero days" do
489      (described_class.new(1996, 51, 4) + 0).should eql described_class.new(1996, 51, 4)
490    end
491  end
492
493  context "#-" do
494    it "should be able to subtract a positive amount of days" do
495      (described_class.new(1996, 2, 4) - 2).should eql described_class.new(1996, 2, 2)
496    end
497
498    it "should be able to subtract a positive amount of days so that the result isn't in the week anymore'" do
499      (described_class.new(1996, 2, 4) - 5).should eql described_class.new(1996, 1, 6)
500    end
501
502    it "should be able to subtract a positive amount of days so that the result isn't in the year anymore'" do
503      (described_class.new(1996, 2, 4) - 15).should eql described_class.new(1995, 52, 3)
504    end
505
506    it "should be able to subtract a positive amount of days so that the result is in the previous year with 53 weeks'" do
507      (described_class.new(1999, 2, 1) - 10).should eql described_class.new(1998, 53, 5)
508    end
509
510    it "should be able to subtract a negative amount of days" do
511      (described_class.new(1996, 51, 4) - -2).should eql described_class.new(1996, 51, 6)
512    end
513
514    it "should be able to subtract a negative amount of days so that the result isn't in the week anymore'" do
515      (described_class.new(1996, 51, 4) - -4).should eql described_class.new(1996, 52, 1)
516    end
517
518    it "should be able to subtract a negative amount of days so that the result isn't in the year anymore'" do
519      (described_class.new(1996, 51, 4) - -12).should eql described_class.new(1997, 1, 2)
520    end
521
522    it "should be able to subtract a negative amount of days so that the result isn't in the year with 53 weeks anymore'" do
523      (described_class.new(1998, 51, 4) - -20).should eql described_class.new(1999, 1, 3)
524    end
525
526    it "should be able to subtract zero days" do
527      (described_class.new(1996, 51, 4) - 0).should eql described_class.new(1996, 51, 4)
528    end
529  end
530
531  context "weekday methods" do
532    it "should report monday" do
533      week_day = described_class.new(2011, 17, 1)
534      week_day.monday?.should be_true
535      week_day.tuesday?.should be_false
536      week_day.wednesday?.should be_false
537      week_day.thursday?.should be_false
538      week_day.friday?.should be_false
539      week_day.saturday?.should be_false
540      week_day.sunday?.should be_false
541      week_day.weekend?.should be_false
542      week_day.to_sym.should eql :monday
543    end
544
545    it "should report tuesday" do
546      week_day = described_class.new(2011, 17, 2)
547      week_day.monday?.should be_false
548      week_day.tuesday?.should be_true
549      week_day.wednesday?.should be_false
550      week_day.thursday?.should be_false
551      week_day.friday?.should be_false
552      week_day.saturday?.should be_false
553      week_day.sunday?.should be_false
554      week_day.weekend?.should be_false
555      week_day.to_sym.should eql :tuesday
556    end
557
558    it "should report wednesday" do
559      week_day = described_class.new(2011, 17, 3)
560      week_day.monday?.should be_false
561      week_day.tuesday?.should be_false
562      week_day.wednesday?.should be_true
563      week_day.thursday?.should be_false
564      week_day.friday?.should be_false
565      week_day.saturday?.should be_false
566      week_day.sunday?.should be_false
567      week_day.weekend?.should be_false
568      week_day.to_sym.should eql :wednesday
569    end
570
571    it "should report thursday" do
572      week_day = described_class.new(2011, 17, 4)
573      week_day.monday?.should be_false
574      week_day.tuesday?.should be_false
575      week_day.wednesday?.should be_false
576      week_day.thursday?.should be_true
577      week_day.friday?.should be_false
578      week_day.saturday?.should be_false
579      week_day.sunday?.should be_false
580      week_day.weekend?.should be_false
581      week_day.to_sym.should eql :thursday
582    end
583
584    it "should report friday" do
585      week_day = described_class.new(2011, 17, 5)
586      week_day.monday?.should be_false
587      week_day.tuesday?.should be_false
588      week_day.wednesday?.should be_false
589      week_day.thursday?.should be_false
590      week_day.friday?.should be_true
591      week_day.saturday?.should be_false
592      week_day.sunday?.should be_false
593      week_day.weekend?.should be_false
594      week_day.to_sym.should eql :friday
595    end
596
597    it "should report saturday" do
598      week_day = described_class.new(2011, 17, 6)
599      week_day.monday?.should be_false
600      week_day.tuesday?.should be_false
601      week_day.wednesday?.should be_false
602      week_day.thursday?.should be_false
603      week_day.friday?.should be_false
604      week_day.saturday?.should be_true
605      week_day.sunday?.should be_false
606      week_day.weekend?.should be_true
607      week_day.to_sym.should eql :saturday
608    end
609
610    it "should report sunday" do
611      week_day = described_class.new(2011, 17, 7)
612      week_day.monday?.should be_false
613      week_day.tuesday?.should be_false
614      week_day.wednesday?.should be_false
615      week_day.thursday?.should be_false
616      week_day.friday?.should be_false
617      week_day.saturday?.should be_false
618      week_day.sunday?.should be_true
619      week_day.weekend?.should be_true
620      week_day.to_sym.should eql :sunday
621    end
622  end
623end