1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
require 'time'
require 'date'
class Time #:nodoc:
class << self
def mock_time
mocked_time_stack_item = Timecop.top_stack_item
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.time(self)
end
alias_method :now_without_mock_time, :now
def now_with_mock_time
mock_time || now_without_mock_time
end
alias_method :now, :now_with_mock_time
alias_method :new_without_mock_time, :new
def new_with_mock_time(*args)
args.size <= 0 ? now : new_without_mock_time(*args)
end
ruby2_keywords :new_with_mock_time if Module.private_method_defined?(:ruby2_keywords)
alias_method :new, :new_with_mock_time
end
end
class Date #:nodoc:
class << self
def mock_date
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.date(self)
end
alias_method :today_without_mock_date, :today
def today_with_mock_date
mock_date || today_without_mock_date
end
alias_method :today, :today_with_mock_date
alias_method :strptime_without_mock_date, :strptime
def strptime_with_mock_date(str = '-4712-01-01', fmt = '%F', start = Date::ITALY)
#If date is not valid the following line raises
Date.strptime_without_mock_date(str, fmt, start)
d = Date._strptime(str, fmt)
now = Time.now.to_date
year = d[:year] || d[:cwyear] || now.year
mon = d[:mon] || now.mon
if d.keys == [:year]
Date.new(year, 1, 1, start)
elsif d[:mday]
Date.new(year, mon, d[:mday], start)
elsif d[:yday]
Date.new(year, 1, 1, start).next_day(d[:yday] - 1)
elsif d[:cwyear] || d[:cweek] || d[:wnum0] || d[:wnum1] || d[:wday] || d[:cwday]
week = d[:cweek] || d[:wnum1] || d[:wnum0] || now.strftime('%W').to_i
if d[:wnum0] #Week of year where week starts on sunday
if d[:cwday] #monday based day of week
Date.strptime_without_mock_date("#{year} #{week} #{d[:cwday]}", '%Y %U %u', start)
else
Date.strptime_without_mock_date("#{year} #{week} #{d[:wday] || 0}", '%Y %U %w', start)
end
else #Week of year where week starts on monday
if d[:wday] #sunday based day of week
Date.strptime_without_mock_date("#{year} #{week} #{d[:wday]}", '%Y %W %w', start)
else
Date.strptime_without_mock_date("#{year} #{week} #{d[:cwday] || 1}", '%Y %W %u', start)
end
end
elsif d[:seconds]
Time.at(d[:seconds]).to_date
else
Date.new(year, mon, 1, start)
end
end
alias_method :strptime, :strptime_with_mock_date
def parse_with_mock_date(*args)
parsed_date = parse_without_mock_date(*args)
return parsed_date unless mocked_time_stack_item
date_hash = Date._parse(*args)
case
when date_hash[:year] && date_hash[:mon]
parsed_date
when date_hash[:mon] && date_hash[:mday]
Date.new(mocked_time_stack_item.year, date_hash[:mon], date_hash[:mday])
when date_hash[:mday]
Date.new(mocked_time_stack_item.year, mocked_time_stack_item.month, date_hash[:mday])
when date_hash[:wday]
closest_wday(date_hash[:wday])
else
parsed_date + mocked_time_stack_item.travel_offset_days
end
end
alias_method :parse_without_mock_date, :parse
alias_method :parse, :parse_with_mock_date
def mocked_time_stack_item
Timecop.top_stack_item
end
def closest_wday(wday)
today = Date.today
result = today - today.wday
result += 1 until wday == result.wday
result
end
end
end
class DateTime #:nodoc:
class << self
def mock_time
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.datetime(self)
end
def now_with_mock_time
mock_time || now_without_mock_time
end
alias_method :now_without_mock_time, :now
alias_method :now, :now_with_mock_time
def parse_with_mock_date(*args)
parsed_date = parse_without_mock_date(*args)
return parsed_date unless mocked_time_stack_item
date_hash = DateTime._parse(*args)
case
when date_hash[:year] && date_hash[:mon]
parsed_date
when date_hash[:mon] && date_hash[:mday]
DateTime.new(mocked_time_stack_item.year, date_hash[:mon], date_hash[:mday])
when date_hash[:mday]
DateTime.new(mocked_time_stack_item.year, mocked_time_stack_item.month, date_hash[:mday])
when date_hash[:wday] && date_hash[:hour] && date_hash[:min]
closest_date = Date.closest_wday(date_hash[:wday]).to_datetime
DateTime.new(
closest_date.year, closest_date.month, closest_date.day,
date_hash[:hour], date_hash[:min]
)
when date_hash[:wday]
Date.closest_wday(date_hash[:wday]).to_datetime
when date_hash[:hour] && date_hash[:min] && date_hash[:sec]
DateTime.new(mocked_time_stack_item.year, mocked_time_stack_item.month, mocked_time_stack_item.day, date_hash[:hour], date_hash[:min], date_hash[:sec])
else
parsed_date + mocked_time_stack_item.travel_offset_days
end
end
alias_method :parse_without_mock_date, :parse
alias_method :parse, :parse_with_mock_date
def mocked_time_stack_item
Timecop.top_stack_item
end
end
end
if RUBY_VERSION >= '2.1.0'
module Process #:nodoc:
class << self
alias_method :clock_gettime_without_mock, :clock_gettime
def clock_gettime_mock_time(clock_id, unit = :float_second)
mock_time = case clock_id
when Process::CLOCK_MONOTONIC
mock_time_monotonic
when Process::CLOCK_REALTIME
mock_time_realtime
end
return clock_gettime_without_mock(clock_id, unit) unless Timecop.mock_process_clock? && mock_time
divisor = case unit
when :float_second
1_000_000_000.0
when :second
1_000_000_000
when :float_millisecond
1_000_000.0
when :millisecond
1_000_000
when :float_microsecond
1000.0
when :microsecond
1000
when :nanosecond
1
end
(mock_time / divisor)
end
alias_method :clock_gettime, :clock_gettime_mock_time
private
def mock_time_monotonic
mocked_time_stack_item = Timecop.top_stack_item
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.monotonic
end
def mock_time_realtime
mocked_time_stack_item = Timecop.top_stack_item
return nil if mocked_time_stack_item.nil?
t = mocked_time_stack_item.time
t.to_i * 1_000_000_000 + t.nsec
end
end
end
end
|