timeplan_calculation_spec.rb 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe TimeplanCalculation do
  4. subject(:instance) { described_class.new(timeplan, timezone) }
  5. let(:timezone) { nil }
  6. describe '#contains?' do
  7. context 'without a valid timeplan' do
  8. let(:timeplan) { {} }
  9. it { is_expected.not_to be_contains(Time.zone.now) }
  10. end
  11. context 'with monday 09:20' do
  12. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true }, 'minutes' => { '20' => true } } }
  13. it { is_expected.to be_contains(Time.zone.parse('2020-12-28 09:20')) }
  14. it { is_expected.to be_contains(Time.zone.parse('2020-12-21 09:20')) }
  15. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-21 10:20')) }
  16. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-21 9:10')) }
  17. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-22 9:20')) }
  18. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-20 9:20')) }
  19. end
  20. context 'with monday and tuesday 09:20' do
  21. let(:timeplan) { { 'days' => { 'Mon' => true, 'Tue' => true }, 'hours' => { '9' => true }, 'minutes' => { '20' => true } } }
  22. it { is_expected.to be_contains(Time.zone.parse('2020-12-28 09:20')) }
  23. it { is_expected.to be_contains(Time.zone.parse('2020-12-21 09:20')) }
  24. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-21 10:20')) }
  25. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-21 9:10')) }
  26. it { is_expected.to be_contains(Time.zone.parse('2020-12-22 9:20')) }
  27. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-20 9:20')) }
  28. end
  29. context 'with monday 09:20 and 10:20' do
  30. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true, '10' => true }, 'minutes' => { '20' => true } } }
  31. it { is_expected.to be_contains(Time.zone.parse('2020-12-28 09:20')) }
  32. it { is_expected.to be_contains(Time.zone.parse('2020-12-21 09:20')) }
  33. it { is_expected.to be_contains(Time.zone.parse('2020-12-21 10:20')) }
  34. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-21 9:10')) }
  35. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-22 9:20')) }
  36. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-20 9:20')) }
  37. end
  38. context 'with monday 09:20 and 9:10' do
  39. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true }, 'minutes' => { '20' => true, '10' => true } } }
  40. it { is_expected.to be_contains(Time.zone.parse('2020-12-28 09:20')) }
  41. it { is_expected.to be_contains(Time.zone.parse('2020-12-21 09:20')) }
  42. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-21 10:20')) }
  43. it { is_expected.to be_contains(Time.zone.parse('2020-12-21 9:10')) }
  44. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-22 9:20')) }
  45. it { is_expected.not_to be_contains(Time.zone.parse('2020-12-20 9:20')) }
  46. end
  47. context 'with monday 09:00 and time zone' do
  48. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '1' => true }, 'minutes' => { '0' => true } } }
  49. let(:timezone) { 'Europe/Vilnius' }
  50. it { is_expected.to be_contains(Time.use_zone('Europe/Vilnius') { Time.zone.parse('2020-12-21 01:00') }) }
  51. it { is_expected.to be_contains(Time.zone.parse('2020-12-20 23:00')) }
  52. end
  53. end
  54. describe '#next_at' do
  55. context 'without a valid timeplan' do
  56. let(:timeplan) { {} }
  57. it { expect(instance.next_at(Time.zone.now)).to be_nil }
  58. end
  59. context 'with monday 09:20' do
  60. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true }, 'minutes' => { '20' => true } } }
  61. it { expect(instance.next_at(Time.zone.parse('2020-12-28 09:31'))).to eq(Time.zone.parse('2021-01-04 09:20')) }
  62. it { expect(instance.next_at(Time.zone.parse('2020-12-28 09:30'))).to eq(Time.zone.parse('2021-01-04 09:20')) }
  63. it { expect(instance.next_at(Time.zone.parse('2020-12-28 09:20'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  64. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:21'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  65. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  66. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:20'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  67. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:21'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  68. it { expect(instance.next_at(Time.zone.parse('2020-12-21 9:10'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  69. it { expect(instance.next_at(Time.zone.parse('2020-12-22 9:20'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  70. it { expect(instance.next_at(Time.zone.parse('2020-12-20 9:20'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  71. end
  72. context 'with monday and tuesday 09:20' do
  73. let(:timeplan) { { 'days' => { 'Mon' => true, 'Tue' => true }, 'hours' => { '9' => true }, 'minutes' => { '20' => true } } }
  74. it { expect(instance.next_at(Time.zone.parse('2020-12-28 09:30'))).to eq(Time.zone.parse('2020-12-29 09:20')) }
  75. it { expect(instance.next_at(Time.zone.parse('2020-12-29 09:30'))).to eq(Time.zone.parse('2021-01-04 09:20')) }
  76. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:25'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  77. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-22 09:20')) }
  78. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:20'))).to eq(Time.zone.parse('2020-12-22 09:20')) }
  79. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:21'))).to eq(Time.zone.parse('2020-12-22 09:20')) }
  80. it { expect(instance.next_at(Time.zone.parse('2020-12-21 9:10'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  81. it { expect(instance.next_at(Time.zone.parse('2020-12-22 9:30'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  82. it { expect(instance.next_at(Time.zone.parse('2020-12-20 9:20'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  83. end
  84. context 'with monday 09:20 and 10:20' do
  85. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true, '10' => true }, 'minutes' => { '20' => true } } }
  86. it { expect(instance.next_at(Time.zone.parse('2020-12-28 09:30'))).to eq(Time.zone.parse('2020-12-28 10:20')) }
  87. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:30'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  88. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  89. it { expect(instance.next_at(Time.zone.parse('2020-12-21 08:07'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  90. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:30'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  91. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:31'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  92. it { expect(instance.next_at(Time.zone.parse('2020-12-21 9:10'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  93. it { expect(instance.next_at(Time.zone.parse('2020-12-21 9:47'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  94. it { expect(instance.next_at(Time.zone.parse('2020-12-22 9:20'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  95. it { expect(instance.next_at(Time.zone.parse('2020-12-20 9:30'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  96. end
  97. context 'with monday 09:30 and 9:10' do
  98. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true }, 'minutes' => { '30' => true, '10' => true } } }
  99. it { expect(instance.next_at(Time.zone.parse('2020-12-28 09:40'))).to eq(Time.zone.parse('2021-01-04 09:10')) }
  100. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:40'))).to eq(Time.zone.parse('2020-12-28 09:10')) }
  101. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:30'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  102. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:25'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  103. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  104. it { expect(instance.next_at(Time.zone.parse('2020-12-21 09:45'))).to eq(Time.zone.parse('2020-12-28 09:10')) }
  105. it { expect(instance.next_at(Time.zone.parse('2020-12-21 08:07'))).to eq(Time.zone.parse('2020-12-21 09:10')) }
  106. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:20'))).to eq(Time.zone.parse('2020-12-28 09:10')) }
  107. it { expect(instance.next_at(Time.zone.parse('2020-12-21 10:21'))).to eq(Time.zone.parse('2020-12-28 09:10')) }
  108. it { expect(instance.next_at(Time.zone.parse('2020-12-21 9:10'))).to eq(Time.zone.parse('2020-12-21 09:10')) }
  109. it { expect(instance.next_at(Time.zone.parse('2020-12-21 9:20'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  110. it { expect(instance.next_at(Time.zone.parse('2020-12-22 9:20'))).to eq(Time.zone.parse('2020-12-28 09:10')) }
  111. it { expect(instance.next_at(Time.zone.parse('2020-12-20 9:20'))).to eq(Time.zone.parse('2020-12-21 09:10')) }
  112. end
  113. context 'with monday 09:00 and time zone' do
  114. let(:timezone) { 'Europe/Vilnius' }
  115. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '1' => true }, 'minutes' => { '0' => true } } }
  116. it 'calculates time respecting time zone' do
  117. from = Time.use_zone('Europe/Vilnius') { Time.zone.parse('2020-12-21 01:15') }
  118. to = Time.use_zone('Europe/Vilnius') { Time.zone.parse('2020-12-28 01:00') }
  119. expect(instance.next_at(from)).to eq(to)
  120. end
  121. it 'calculates time converting to time zone' do
  122. from = Time.zone.parse('2020-12-20 23:10')
  123. to = Time.use_zone('Europe/Vilnius') { Time.zone.parse('2020-12-28 01:00') }
  124. expect(instance.next_at(from)).to eq(to)
  125. end
  126. end
  127. end
  128. describe '#previous_at' do
  129. context 'without a valid timeplan' do
  130. let(:timeplan) { {} }
  131. it { expect(instance.previous_at(Time.zone.now)).to be_nil }
  132. end
  133. context 'with monday 09:20' do
  134. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true }, 'minutes' => { '20' => true } } }
  135. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 09:31'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  136. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 09:30'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  137. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 09:20'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  138. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:21'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  139. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  140. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 10:20'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  141. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 10:21'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  142. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 9:10'))).to eq(Time.zone.parse('2020-12-14 09:20')) }
  143. it { expect(instance.previous_at(Time.zone.parse('2020-12-22 9:20'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  144. it { expect(instance.previous_at(Time.zone.parse('2020-12-20 9:20'))).to eq(Time.zone.parse('2020-12-14 09:20')) }
  145. end
  146. context 'with monday 23:00' do
  147. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '23' => true }, 'minutes' => { '0' => true } } }
  148. it { expect(instance.previous_at(Time.zone.parse('2020-12-29 00:00'))).to eq(Time.zone.parse('2020-12-28 23:00')) }
  149. end
  150. context 'with monday and tuesday 09:20' do
  151. let(:timeplan) { { 'days' => { 'Mon' => true, 'Tue' => true }, 'hours' => { '9' => true }, 'minutes' => { '20' => true } } }
  152. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 09:30'))).to eq(Time.zone.parse('2020-12-28 09:20')) }
  153. it { expect(instance.previous_at(Time.zone.parse('2020-12-29 09:30'))).to eq(Time.zone.parse('2020-12-29 09:20')) }
  154. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:25'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  155. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  156. it { expect(instance.previous_at(Time.zone.parse('2020-12-22 8:20'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  157. it { expect(instance.previous_at(Time.zone.parse('2020-12-22 8:21'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  158. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 9:30'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  159. it { expect(instance.previous_at(Time.zone.parse('2020-12-22 9:10'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  160. it { expect(instance.previous_at(Time.zone.parse('2020-12-23 9:10'))).to eq(Time.zone.parse('2020-12-22 09:20')) }
  161. end
  162. context 'with monday 09:20 and 10:20' do
  163. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true, '10' => true }, 'minutes' => { '20' => true } } }
  164. it { expect(instance.previous_at(Time.zone.parse('2020-12-29 09:10'))).to eq(Time.zone.parse('2020-12-28 10:20')) }
  165. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:30'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  166. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  167. it { expect(instance.previous_at(Time.zone.parse('2020-12-22 08:07'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  168. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 10:30'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  169. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 10:31'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  170. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 9:10'))).to eq(Time.zone.parse('2020-12-14 10:20')) }
  171. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 9:47'))).to eq(Time.zone.parse('2020-12-21 09:20')) }
  172. it { expect(instance.previous_at(Time.zone.parse('2020-12-22 9:20'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  173. it { expect(instance.previous_at(Time.zone.parse('2020-12-23 9:30'))).to eq(Time.zone.parse('2020-12-21 10:20')) }
  174. end
  175. context 'with monday 09:30 and 9:10' do
  176. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '9' => true }, 'minutes' => { '30' => true, '10' => true } } }
  177. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 09:40'))).to eq(Time.zone.parse('2020-12-28 09:30')) }
  178. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 07:40'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  179. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:30'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  180. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:25'))).to eq(Time.zone.parse('2020-12-21 09:10')) }
  181. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 09:35'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  182. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 05:45'))).to eq(Time.zone.parse('2020-12-14 09:30')) }
  183. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 14:07'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  184. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 10:20'))).to eq(Time.zone.parse('2020-12-28 09:30')) }
  185. it { expect(instance.previous_at(Time.zone.parse('2020-12-28 10:21'))).to eq(Time.zone.parse('2020-12-28 09:30')) }
  186. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 9:10'))).to eq(Time.zone.parse('2020-12-21 09:10')) }
  187. it { expect(instance.previous_at(Time.zone.parse('2020-12-21 9:20'))).to eq(Time.zone.parse('2020-12-21 09:10')) }
  188. it { expect(instance.previous_at(Time.zone.parse('2020-12-22 9:20'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  189. it { expect(instance.previous_at(Time.zone.parse('2020-12-25 9:20'))).to eq(Time.zone.parse('2020-12-21 09:30')) }
  190. end
  191. context 'with monday 01:00 and time zone' do
  192. let(:timezone) { 'Europe/Vilnius' }
  193. let(:timeplan) { { 'days' => { 'Mon' => true }, 'hours' => { '1' => true }, 'minutes' => { '0' => true } } }
  194. it 'calculates time respecting time zone' do
  195. from = Time.use_zone('Europe/Vilnius') { Time.zone.parse('2020-12-21 00:15') }
  196. to = Time.use_zone('Europe/Vilnius') { Time.zone.parse('2020-12-14 01:00') }
  197. expect(instance.previous_at(from)).to eq(to)
  198. end
  199. it 'calculates time converting to time zone' do
  200. from = Time.zone.parse('2020-12-20 23:10')
  201. to = Time.use_zone('Europe/Vilnius') { Time.zone.parse('2020-12-21 01:00') }
  202. expect(instance.previous_at(from)).to eq(to)
  203. end
  204. end
  205. end
  206. describe 'legacy tests moved from Job model' do
  207. let(:job) { create(:job, :never_on) }
  208. let(:timeplan) { job.timeplan }
  209. let(:time) { Time.current }
  210. context 'when the current day, hour, and minute all match true values in #timeplan' do
  211. it 'for Symbol/Integer keys returns true' do
  212. timeplan[:days].transform_keys!(&:to_sym)[time.strftime('%a').to_sym] = true
  213. timeplan[:hours].transform_keys!(&:to_i)[time.hour] = true
  214. timeplan[:minutes].transform_keys!(&:to_i)[time.min.floor(-1)] = true
  215. expect(instance.contains?(time)).to be(true)
  216. end
  217. it 'for String keys returns true' do
  218. timeplan[:days].transform_keys!(&:to_s)[time.strftime('%a')] = true
  219. timeplan[:hours].transform_keys!(&:to_s)[time.hour.to_s] = true
  220. timeplan[:minutes].transform_keys!(&:to_s)[time.min.floor(-1).to_s] = true
  221. expect(instance.contains?(time)).to be(true)
  222. end
  223. end
  224. context 'when the current day does not match a true value in #timeplan' do
  225. it 'for Symbol/Integer keys returns false' do
  226. timeplan[:days].transform_keys!(&:to_sym).transform_values! { true }[time.strftime('%a').to_sym] = false
  227. timeplan[:hours].transform_keys!(&:to_i)[time.hour] = true
  228. timeplan[:minutes].transform_keys!(&:to_i)[time.min.floor(-1)] = true
  229. expect(instance.contains?(time)).to be(false)
  230. end
  231. it 'for String keys returns false' do
  232. timeplan[:days].transform_keys!(&:to_s).transform_values! { true }[time.strftime('%a')] = false
  233. timeplan[:hours].transform_keys!(&:to_s)[time.hour.to_s] = true
  234. timeplan[:minutes].transform_keys!(&:to_s)[time.min.floor(-1).to_s] = true
  235. expect(instance.contains?(time)).to be(false)
  236. end
  237. end
  238. context 'when the current hour does not match a true value in #timeplan' do
  239. it 'for Symbol/Integer keys returns false' do
  240. timeplan[:days].transform_keys!(&:to_sym)[time.strftime('%a').to_sym] = true
  241. timeplan[:hours].transform_keys!(&:to_i).transform_values! { true }[time.hour] = false
  242. timeplan[:minutes].transform_keys!(&:to_i)[time.min.floor(-1)] = true
  243. expect(instance.contains?(time)).to be(false)
  244. end
  245. it 'for String keys returns false' do
  246. timeplan[:days].transform_keys!(&:to_s)[time.strftime('%a')] = true
  247. timeplan[:hours].transform_keys!(&:to_s).transform_values! { true }[time.hour.to_s] = false
  248. timeplan[:minutes].transform_keys!(&:to_s)[time.min.floor(-1).to_s] = true
  249. expect(instance.contains?(time)).to be(false)
  250. end
  251. end
  252. context 'when the current minute does not match a true value in #timeplan' do
  253. it 'for Symbol/Integer keys returns false' do
  254. timeplan[:days].transform_keys!(&:to_sym)[time.strftime('%a').to_sym] = true
  255. timeplan[:hours].transform_keys!(&:to_i)[time.hour] = true
  256. timeplan[:minutes].transform_keys!(&:to_i).transform_values! { true }[time.min.floor(-1)] = false
  257. expect(instance.contains?(time)).to be(false)
  258. end
  259. it 'for String keys returns false' do
  260. timeplan[:days].transform_keys!(&:to_s)[time.strftime('%a')] = true
  261. timeplan[:hours].transform_keys!(&:to_s)[time.hour.to_s] = true
  262. timeplan[:minutes].transform_keys!(&:to_s).transform_values! { true }[time.min.floor(-1).to_s] = false
  263. expect(instance.contains?(time)).to be(false)
  264. end
  265. end
  266. end
  267. end