win32-taskscheduler 1.0.2 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -7
- data/Rakefile +5 -0
- data/VERSION +1 -1
- data/appveyor.yml +40 -0
- data/lib/win32/taskscheduler.rb +29 -21
- data/lib/win32/taskscheduler/version.rb +1 -1
- data/spec/functional/win32/taskschedular_spec.rb +829 -0
- data/spec/{win32 → functional/win32}/windows/time_calc_helper_spec.rb +0 -0
- data/spec/spec_helper.rb +224 -1
- data/spec/unit/win32/taskschedular_spec.rb +132 -0
- data/spec/unit/win32/windows/constants_spec.rb +20 -0
- data/spec/unit/win32/windows/time_calc_helper_spec.rb +217 -0
- data/win32-taskscheduler.gemspec +0 -1
- metadata +8 -6
- data/MANIFEST +0 -10
- data/certs/djberg96_pub.pem +0 -21
File without changes
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,224 @@
|
|
1
|
-
|
1
|
+
libx = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(libx) unless $LOAD_PATH.include?(libx)
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
# In order to test some dummy task and folder, we are creating
|
7
|
+
# 'Test' folder and consider it as 'root'.
|
8
|
+
# After the test case, all the above created elements
|
9
|
+
# i.e, 'Test', Tasks and nested folders will be deleted.
|
10
|
+
# It will ensure No Harm be caused to any existing tasks at root
|
11
|
+
|
12
|
+
# Creating folder 'Test'; This will be treated as root
|
13
|
+
def create_test_folder
|
14
|
+
@service ||= service
|
15
|
+
@root_path = '\\'
|
16
|
+
@test_path = '\\Test'
|
17
|
+
@root_folder = @service.GetFolder(@root_path)
|
18
|
+
@test_folder = @root_folder.CreateFolder(@test_path)
|
19
|
+
@ts.instance_variable_set(:@root, @test_folder) if @ts
|
20
|
+
end
|
21
|
+
|
22
|
+
# Deleting the test folder its nested folder(if any)
|
23
|
+
# And the tasks within(if any)
|
24
|
+
def clear_them
|
25
|
+
if @test_folder
|
26
|
+
delete_all(@test_folder)
|
27
|
+
else
|
28
|
+
@test_folder = nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Logic to delete tasks and folder using Win32OLE methods
|
33
|
+
def delete_all(folder)
|
34
|
+
delete_tasks_in(folder)
|
35
|
+
folder.GetFolders(0).each do |nested_folder|
|
36
|
+
delete_all(nested_folder)
|
37
|
+
end
|
38
|
+
@root_folder.DeleteFolder(folder.Path, 0)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Deleting the task in specified folder using Win32OLE methods
|
42
|
+
def delete_tasks_in(folder)
|
43
|
+
folder.GetTasks(0).each do |task|
|
44
|
+
folder.DeleteTask(task.Name, 0)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns Win32 Service object
|
49
|
+
def service
|
50
|
+
service = WIN32OLE.new('Schedule.Service')
|
51
|
+
service.Connect
|
52
|
+
service
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns no of task in the specified folder
|
56
|
+
def no_of_tasks(folder = @test_folder)
|
57
|
+
if folder.is_a?(String)
|
58
|
+
folder = @test_path + folder
|
59
|
+
folder = @service.GetFolder(folder)
|
60
|
+
end
|
61
|
+
folder.GetTasks(0).Count
|
62
|
+
end
|
63
|
+
|
64
|
+
# Steps to create (Register) a task
|
65
|
+
# This is an example activity to test
|
66
|
+
# the related functionalities over a task in RSpecs
|
67
|
+
def create_task
|
68
|
+
return nil unless @service
|
69
|
+
@task_definition = @service.NewTask(0)
|
70
|
+
task_registration
|
71
|
+
task_prinicipals
|
72
|
+
task_settings
|
73
|
+
task_triggers
|
74
|
+
task_action
|
75
|
+
register_task
|
76
|
+
end
|
77
|
+
|
78
|
+
def task_registration
|
79
|
+
reg_info = @task_definition.RegistrationInfo
|
80
|
+
reg_info.Description = 'Sample task for testing purpose'
|
81
|
+
reg_info.Author = 'Rspec'
|
82
|
+
end
|
83
|
+
|
84
|
+
def task_prinicipals
|
85
|
+
principal = @task_definition.Principal
|
86
|
+
principal.LogonType = 3 # Interactive Logon
|
87
|
+
end
|
88
|
+
|
89
|
+
def task_settings
|
90
|
+
settings = @task_definition.Settings
|
91
|
+
settings.Enabled = true
|
92
|
+
settings.StartWhenAvailable = true
|
93
|
+
settings.Hidden = false
|
94
|
+
end
|
95
|
+
|
96
|
+
def task_triggers
|
97
|
+
triggers = @task_definition.Triggers
|
98
|
+
trigger = triggers.Create(1) # Time
|
99
|
+
start_time, end_time = start_end_time
|
100
|
+
trigger.StartBoundary = start_time
|
101
|
+
trigger.EndBoundary = end_time
|
102
|
+
trigger.ExecutionTimeLimit = 'PT5M' # Five minutes
|
103
|
+
trigger.Id = 'TimeTriggerId'
|
104
|
+
trigger.Enabled = true
|
105
|
+
end
|
106
|
+
|
107
|
+
def task_action
|
108
|
+
action = @task_definition.Actions.Create(0)
|
109
|
+
action.Path = @app
|
110
|
+
end
|
111
|
+
|
112
|
+
# Registering(Creating) a task in test folder
|
113
|
+
def register_task
|
114
|
+
@current_task = @test_folder.RegisterTaskDefinition(
|
115
|
+
@task, # Name of the task
|
116
|
+
@task_definition, # Definition
|
117
|
+
6, # Flag: TASK_CREATE_OR_UPDATE
|
118
|
+
nil, # UserId
|
119
|
+
nil, # Password
|
120
|
+
3
|
121
|
+
)
|
122
|
+
@ts.instance_variable_set(:@task, @current_task) if @ts
|
123
|
+
end
|
124
|
+
|
125
|
+
def start_end_time
|
126
|
+
t = Date.new(2010)
|
127
|
+
start_time = t.strftime('%FT%T')
|
128
|
+
end_time = (t + 5).strftime('%FT%T') # 5 Days
|
129
|
+
[start_time, end_time]
|
130
|
+
end
|
131
|
+
|
132
|
+
def tasksch_err
|
133
|
+
Win32::TaskScheduler::Error
|
134
|
+
end
|
135
|
+
|
136
|
+
# Methods to build all types of triggers and their values
|
137
|
+
|
138
|
+
def all_triggers
|
139
|
+
all_triggers = {}
|
140
|
+
|
141
|
+
%w[ONCE DAILY WEEKLY MONTHLYDATE MONTHLYDOW
|
142
|
+
ON_IDLE AT_SYSTEMSTART AT_LOGON].each do |trig_type|
|
143
|
+
trigger = {}
|
144
|
+
trigger[:trigger_type] = Win32::TaskScheduler.class_eval(trig_type)
|
145
|
+
start_end_params(trigger)
|
146
|
+
other_trigger_params(trig_type, trigger)
|
147
|
+
all_triggers[trig_type] = trigger
|
148
|
+
end
|
149
|
+
|
150
|
+
all_triggers
|
151
|
+
end
|
152
|
+
|
153
|
+
def start_end_params(trigger)
|
154
|
+
%i[start_year end_year].each do |t|
|
155
|
+
trigger[t] = '2030'
|
156
|
+
end
|
157
|
+
|
158
|
+
%i[start_month start_day start_hour start_minute].each do |t|
|
159
|
+
trigger[t] = '02'
|
160
|
+
end
|
161
|
+
|
162
|
+
%i[end_day end_month].each do |t|
|
163
|
+
trigger[t] = '03'
|
164
|
+
end
|
165
|
+
|
166
|
+
%i[minutes_duration minutes_interval].each do |t|
|
167
|
+
trigger[t] = 2
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def other_trigger_params(trig_type, trigger)
|
172
|
+
type = {}
|
173
|
+
case trig_type
|
174
|
+
when 'ONCE'
|
175
|
+
trigger[:type] = type
|
176
|
+
type[:once] = nil
|
177
|
+
trigger[:random_minutes_interval] = 2
|
178
|
+
when 'DAILY'
|
179
|
+
trigger[:type] = type
|
180
|
+
type[:days_interval] = 2
|
181
|
+
trigger[:random_minutes_interval] = 2
|
182
|
+
when 'WEEKLY'
|
183
|
+
trigger[:type] = type
|
184
|
+
type[:weeks_interval] = 2
|
185
|
+
type[:days_of_week] = sunday
|
186
|
+
trigger[:random_minutes_interval] = 2
|
187
|
+
when 'MONTHLYDATE'
|
188
|
+
trigger[:type] = type
|
189
|
+
type[:months] = january
|
190
|
+
type[:days] = first_day
|
191
|
+
trigger[:run_on_last_day_of_month] = false
|
192
|
+
trigger[:random_minutes_interval] = 2
|
193
|
+
when 'MONTHLYDOW'
|
194
|
+
trigger[:type] = type
|
195
|
+
type[:months] = january
|
196
|
+
type[:days_of_week] = sunday
|
197
|
+
type[:weeks_of_month] = first_week
|
198
|
+
trigger[:run_on_last_week_of_month] = false
|
199
|
+
trigger[:random_minutes_interval] = 2
|
200
|
+
when 'ON_IDLE'
|
201
|
+
trigger[:execution_time_limit] = 2
|
202
|
+
when 'AT_SYSTEMSTART'
|
203
|
+
trigger[:delay_duration] = 2
|
204
|
+
when 'AT_LOGON'
|
205
|
+
trigger[:user_id] = 'SYSTEM'
|
206
|
+
trigger[:delay_duration] = 2
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def sunday
|
211
|
+
Win32::TaskScheduler::SUNDAY
|
212
|
+
end
|
213
|
+
|
214
|
+
def january
|
215
|
+
Win32::TaskScheduler::JANUARY
|
216
|
+
end
|
217
|
+
|
218
|
+
def first_day
|
219
|
+
Win32::TaskScheduler::FIRST
|
220
|
+
end
|
221
|
+
|
222
|
+
def first_week
|
223
|
+
Win32::TaskScheduler::FIRST_WEEK
|
224
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'win32ole'
|
3
|
+
require 'win32/taskscheduler'
|
4
|
+
|
5
|
+
RSpec.describe Win32::TaskScheduler, :windows_only do
|
6
|
+
before { create_test_folder }
|
7
|
+
after { clear_them }
|
8
|
+
before { load_task_variables }
|
9
|
+
|
10
|
+
describe '#Constructor' do
|
11
|
+
let(:ts) { Win32::TaskScheduler }
|
12
|
+
context 'no of arguments' do
|
13
|
+
it 'zero' do
|
14
|
+
expect(ts.new).to be_a(ts)
|
15
|
+
expect(no_of_tasks).to eq(0)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'one: task' do
|
19
|
+
expect(ts.new(@task)).to be_a(ts)
|
20
|
+
expect(no_of_tasks).to eq(0)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'two: task, trigger; trigger_type is blank' do
|
24
|
+
@trigger[:trigger_type] = nil
|
25
|
+
expect { ts.new(@task, @trigger) }.to raise_error(ArgumentError)
|
26
|
+
expect(no_of_tasks).to eq(0)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'two: task, trigger; trigger_type is not blank; Creates a task' do
|
30
|
+
expect(ts.new(@task, @trigger)).to be_a(ts)
|
31
|
+
expect(no_of_tasks).to eq(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'three: task, trigger, folder; Creates a task' do
|
35
|
+
expect(ts.new(@task, @trigger, @folder)).to be_a(ts)
|
36
|
+
expect(no_of_tasks).to eq(1)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'four: task, trigger, folder, force; Creates a task' do
|
40
|
+
expect(ts.new(@task, @trigger, @folder, @force)).to be_a(ts)
|
41
|
+
expect(no_of_tasks).to eq(1)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raises an error for more than four arguments' do
|
45
|
+
expect { ts.new(@task, @trigger, @folder, @force, 1) }.to raise_error(ArgumentError)
|
46
|
+
expect { ts.new(@task, @trigger, @folder, @force, 'abc') }.to raise_error(ArgumentError)
|
47
|
+
expect(no_of_tasks).to eq(0)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#Tasks' do
|
53
|
+
before { create_task }
|
54
|
+
it 'Returns an Array' do
|
55
|
+
expect(@ts.tasks).to be_a(Array)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'Returns an Empty Array if no task is present' do
|
59
|
+
delete_tasks_in(@test_folder)
|
60
|
+
expect(@ts.tasks).to be_empty
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#exists?' do
|
65
|
+
let(:folder) { '\\Foo' }
|
66
|
+
let(:force) { true }
|
67
|
+
before { create_task }
|
68
|
+
|
69
|
+
context 'At Root' do
|
70
|
+
it 'Requires only task name' do
|
71
|
+
expect(@ts.exists?(@task)).to be_truthy
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'Does not require root to be appended' do
|
75
|
+
task = @folder + '\\' + @task
|
76
|
+
expect(@ts.exists?(task)).to be_falsey
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'At Nested folder' do
|
81
|
+
it 'Returns false for non existing folder' do
|
82
|
+
task = folder + '\\' + @task
|
83
|
+
expect(@ts.exists?(task)).to be_falsey
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'Returns true for existing folder' do
|
87
|
+
@ts = Win32::TaskScheduler.new(@task, @trigger, folder, force)
|
88
|
+
task = folder + '\\' + @task
|
89
|
+
expect(@ts.exists?(task)).to be_truthy
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#get_task' do
|
95
|
+
before { create_task }
|
96
|
+
it 'Requires a string: Task Name' do
|
97
|
+
expect { @ts.get_task(0) }.to raise_error(TypeError)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#activate' do
|
102
|
+
before { create_task }
|
103
|
+
it 'Requires a string: Task Name' do
|
104
|
+
expect { @ts.activate(0) }.to raise_error(TypeError)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#delete' do
|
109
|
+
before { create_task }
|
110
|
+
it 'Requires a string: Task Name' do
|
111
|
+
expect { @ts.delete(0) }.to raise_error(TypeError)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def load_task_variables
|
118
|
+
time = Time.now
|
119
|
+
# Ensuring root path will be test path
|
120
|
+
allow_any_instance_of(Win32::TaskScheduler).to receive(:root_path).and_return(@test_path)
|
121
|
+
@app = 'notepad.exe'
|
122
|
+
@task = 'test_task'
|
123
|
+
@folder = @test_path
|
124
|
+
@force = false
|
125
|
+
@trigger = { start_year: time.year, start_month: time.month,
|
126
|
+
start_day: time.day, start_hour: time.hour,
|
127
|
+
start_minute: time.min,
|
128
|
+
# Will update this in test cases when required
|
129
|
+
trigger_type: Win32::TaskScheduler::ONCE }
|
130
|
+
@ts = Win32::TaskScheduler.new
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'win32/taskscheduler'
|
3
|
+
require 'win32/windows/constants'
|
4
|
+
|
5
|
+
RSpec.describe Win32::TaskScheduler, :windows_only do
|
6
|
+
describe 'Ensuring trigger constants' do
|
7
|
+
subject(:ts) { Win32::TaskScheduler }
|
8
|
+
describe 'to handle scheduled tasks' do
|
9
|
+
[:ONCE, :DAILY, :WEEKLY, :MONTHLYDATE, :MONTHLYDOW].each do |const|
|
10
|
+
it { should be_const_defined(const) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'to handle other types' do
|
15
|
+
[:AT_LOGON, :AT_SYSTEMSTART, :ON_IDLE].each do |const|
|
16
|
+
it { should be_const_defined(const) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'win32/windows/time_calc_helper'
|
3
|
+
|
4
|
+
RSpec.describe Windows::TimeCalcHelper do
|
5
|
+
let(:object) { klass.new }
|
6
|
+
let(:klass) do
|
7
|
+
Class.new do
|
8
|
+
include Windows::TimeCalcHelper
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#is_leap_year?' do
|
13
|
+
it 'require an year in integer format' do
|
14
|
+
expect { object.is_leap_year? }.to raise_error(ArgumentError)
|
15
|
+
expect { object.is_leap_year?('year') }.to raise_error(NoMethodError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns true for leap years' do
|
19
|
+
year = 2000
|
20
|
+
expect(object.is_leap_year?(year)).to be_truthy
|
21
|
+
year = 2004
|
22
|
+
expect(object.is_leap_year?(year)).to be_truthy
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns false for non-leap years' do
|
26
|
+
year = 1900
|
27
|
+
expect(object.is_leap_year?(year)).to be_falsy
|
28
|
+
year = 2001
|
29
|
+
expect(object.is_leap_year?(year)).to be_falsy
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#days_in_month' do
|
34
|
+
it 'require month and year in integer format' do
|
35
|
+
expect { object.days_in_month }.to raise_error(ArgumentError)
|
36
|
+
expect { object.days_in_month('month', 'year') }.to raise_error(TypeError)
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'leap year' do
|
40
|
+
year = 2000
|
41
|
+
it 'January will have 31 days' do
|
42
|
+
month = 1
|
43
|
+
expect(object.days_in_month(month, year)).to eql(31)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'February will have 29 days' do
|
47
|
+
month = 2
|
48
|
+
expect(object.days_in_month(month, year)).to eql(29)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'November will have 30 days' do
|
52
|
+
month = 11
|
53
|
+
expect(object.days_in_month(month, year)).to eql(30)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'non-leap year' do
|
58
|
+
year = 2003
|
59
|
+
it 'January will have 31 days' do
|
60
|
+
month = 1
|
61
|
+
expect(object.days_in_month(month, year)).to eql(31)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'February will have 28 days' do
|
65
|
+
month = 2
|
66
|
+
expect(object.days_in_month(month, year)).to eql(28)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'November will have 30 days' do
|
70
|
+
month = 11
|
71
|
+
expect(object.days_in_month(month, year)).to eql(30)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#time_details' do
|
77
|
+
it 'require a time string in String format' do
|
78
|
+
expect { object.time_details }.to raise_error(ArgumentError)
|
79
|
+
expect { object.time_details(1234) }.to raise_error(TypeError)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns an empty hash if no string is passed' do
|
83
|
+
expect(object.time_details(nil)).to be_a(Hash)
|
84
|
+
expect(object.time_details(nil)).to be_empty
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'of MSDN time string' do
|
88
|
+
it 'returns hash with date' do
|
89
|
+
time_str = 'P10Y10M10D'
|
90
|
+
time_hsh = { year: '10', month: '10', day: '10' }
|
91
|
+
expect(object.time_details(time_str)).to eq(time_hsh)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'returns hash with time' do
|
95
|
+
time_str = 'PT10H10M10S'
|
96
|
+
time_hsh = { hour: '10', min: '10', sec: '10' }
|
97
|
+
expect(object.time_details(time_str)).to eq(time_hsh)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'returns hash with date-time' do
|
101
|
+
time_str = 'P10Y10M10DT10H10M10S'
|
102
|
+
time_hsh = { year: '10', month: '10', day: '10',
|
103
|
+
hour: '10', min: '10', sec: '10' }
|
104
|
+
expect(object.time_details(time_str)).to eq(time_hsh)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#time_in_seconds' do
|
110
|
+
it 'require a time string in String format' do
|
111
|
+
expect { object.time_in_seconds }.to raise_error(ArgumentError)
|
112
|
+
expect { object.time_in_seconds(1234) }.to raise_error(TypeError)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'returns zero if no string is passed' do
|
116
|
+
expect(object.time_in_seconds(nil)).to be_zero
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'in leap year' do
|
120
|
+
before do
|
121
|
+
time_now = Time.new(2004)
|
122
|
+
allow(Time).to receive(:now).and_return(time_now)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'returns seconds for date' do
|
126
|
+
time_str = 'P10Y10M10D'
|
127
|
+
expect(object.time_in_seconds(time_str)).to eq(342_748_800)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'returns seconds for time' do
|
131
|
+
time_str = 'PT10H10M10S'
|
132
|
+
expect(object.time_in_seconds(time_str)).to eq(36_610)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'returns seconds for date-time' do
|
136
|
+
time_str = 'P10Y10M10DT10H10M10S'
|
137
|
+
expect(object.time_in_seconds(time_str)).to eq(342_785_410)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
context 'in non-leap year' do
|
141
|
+
before do
|
142
|
+
time_now = Time.new(2003)
|
143
|
+
allow(Time).to receive(:now).and_return(time_now)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'returns seconds for date' do
|
147
|
+
time_str = 'P10Y10M10D'
|
148
|
+
expect(object.time_in_seconds(time_str)).to eq(342_748_800)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'returns seconds for time' do
|
152
|
+
time_str = 'PT10H10M10S'
|
153
|
+
expect(object.time_in_seconds(time_str)).to eq(36_610)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'returns seconds for date-time' do
|
157
|
+
time_str = 'P10Y10M10DT10H10M10S'
|
158
|
+
expect(object.time_in_seconds(time_str)).to eq(342_785_410)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#time_in_minutes' do
|
164
|
+
it 'require a time string in String format' do
|
165
|
+
expect { object.time_in_minutes }.to raise_error(ArgumentError)
|
166
|
+
expect { object.time_in_minutes(1234) }.to raise_error(TypeError)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'returns zero if no string is passed' do
|
170
|
+
expect(object.time_in_minutes(nil)).to be_zero
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'in leap year' do
|
174
|
+
before do
|
175
|
+
time_now = Time.new(2004)
|
176
|
+
allow(Time).to receive(:now).and_return(time_now)
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'returns minutes for date' do
|
180
|
+
time_str = 'P10Y10M10D'
|
181
|
+
expect(object.time_in_minutes(time_str)).to eq(5_712_480)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'returns minutes for time' do
|
185
|
+
time_str = 'PT10H10M10S'
|
186
|
+
expect(object.time_in_minutes(time_str)).to eq(610)
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'returns minutes for date-time' do
|
190
|
+
time_str = 'P10Y10M10DT10H10M10S'
|
191
|
+
expect(object.time_in_minutes(time_str)).to eq(5_713_090)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'in non-leap year' do
|
196
|
+
before do
|
197
|
+
time_now = Time.new(2003)
|
198
|
+
allow(Time).to receive(:now).and_return(time_now)
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'returns minutes for date' do
|
202
|
+
time_str = 'P10Y10M10D'
|
203
|
+
expect(object.time_in_minutes(time_str)).to eq(5_712_480)
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'returns minutes for time' do
|
207
|
+
time_str = 'PT10H10M10S'
|
208
|
+
expect(object.time_in_minutes(time_str)).to eq(610)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'returns minutes for date-time' do
|
212
|
+
time_str = 'P10Y10M10DT10H10M10S'
|
213
|
+
expect(object.time_in_minutes(time_str)).to eq(5_713_090)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|