lazylead 0.4.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.docs/accuracy.md +2 -2
  3. data/.docs/duedate_expired.md +3 -3
  4. data/.docs/propagate_down.md +3 -3
  5. data/.gitattributes +1 -0
  6. data/.github/dependabot.yml +6 -0
  7. data/Rakefile +6 -3
  8. data/bin/lazylead +7 -5
  9. data/lazylead.gemspec +4 -3
  10. data/lib/lazylead/cli/app.rb +5 -2
  11. data/lib/lazylead/exchange.rb +15 -9
  12. data/lib/lazylead/log.rb +2 -1
  13. data/lib/lazylead/model.rb +36 -2
  14. data/lib/lazylead/opts.rb +13 -1
  15. data/lib/lazylead/postman.rb +9 -4
  16. data/lib/lazylead/schedule.rb +16 -15
  17. data/lib/lazylead/smtp.rb +3 -1
  18. data/lib/lazylead/system/jira.rb +44 -0
  19. data/lib/lazylead/task/accuracy/accuracy.rb +13 -8
  20. data/lib/lazylead/task/accuracy/affected_build.rb +2 -6
  21. data/lib/lazylead/task/accuracy/attachment.rb +44 -0
  22. data/lib/lazylead/task/accuracy/environment.rb +39 -0
  23. data/lib/lazylead/task/accuracy/logs.rb +40 -0
  24. data/lib/lazylead/task/accuracy/records.rb +45 -0
  25. data/lib/lazylead/task/accuracy/requirement.rb +9 -0
  26. data/lib/lazylead/task/accuracy/servers.rb +50 -0
  27. data/lib/lazylead/task/accuracy/stacktrace.rb +63 -0
  28. data/lib/lazylead/task/accuracy/testcase.rb +85 -0
  29. data/lib/lazylead/task/accuracy/wiki.rb +41 -0
  30. data/lib/lazylead/task/echo.rb +18 -0
  31. data/lib/lazylead/task/fix_version.rb +9 -2
  32. data/lib/lazylead/task/touch.rb +28 -11
  33. data/lib/lazylead/version.rb +1 -1
  34. data/lib/messages/svn_log.erb +117 -0
  35. data/lib/messages/svn_touch.erb +1 -1
  36. data/license.txt +1 -1
  37. data/readme.md +5 -5
  38. data/test/lazylead/cli/app_test.rb +11 -11
  39. data/test/lazylead/opts_test.rb +4 -0
  40. data/test/lazylead/system/jira_test.rb +38 -0
  41. data/test/lazylead/task/accuracy/accuracy_test.rb +1 -1
  42. data/test/lazylead/task/accuracy/affected_build_test.rb +2 -2
  43. data/test/lazylead/task/accuracy/attachment_test.rb +50 -0
  44. data/test/lazylead/task/accuracy/environment_test.rb +42 -0
  45. data/test/lazylead/task/accuracy/logs_test.rb +78 -0
  46. data/test/lazylead/task/accuracy/records_test.rb +60 -0
  47. data/test/lazylead/task/accuracy/score_test.rb +46 -0
  48. data/test/lazylead/task/accuracy/servers_test.rb +66 -0
  49. data/test/lazylead/task/accuracy/stacktrace_test.rb +113 -0
  50. data/test/lazylead/task/accuracy/testcase_test.rb +215 -0
  51. data/test/lazylead/task/accuracy/wiki_test.rb +40 -0
  52. data/test/lazylead/task/touch_test.rb +48 -23
  53. data/test/test.rb +25 -0
  54. data/upgrades/sqlite/001-install-main-lazylead-tables.sql +1 -5
  55. data/upgrades/sqlite/999.testdata.sql +12 -17
  56. metadata +59 -18
  57. data/.travis.yml +0 -16
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2019-2020 Yurii Dubinka
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"),
9
+ # to deal in the Software without restriction, including without limitation
10
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ # and/or sell copies of the Software, and to permit persons to whom
12
+ # the Software is furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
23
+ # OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ require_relative "requirement"
26
+
27
+ module Lazylead
28
+ # Check the 'Description' field that ticket has mandatory details like
29
+ # - test case (TC)
30
+ # - actual result (AR)
31
+ # - expected result (ER)
32
+ class Testcase < Lazylead::Requirement
33
+ def initialize(score = 4)
34
+ super "Test case with AR/ER", score, "Description"
35
+ end
36
+
37
+ def passed(issue)
38
+ return false if issue.description.nil?
39
+ @tc = @ar = @er = -1
40
+ issue.description.split("\n").reject(&:blank?).each_with_index do |l, i|
41
+ line = escape(l.strip.downcase)
42
+ detect_tc(line, i)
43
+ detect_ar(line, i)
44
+ detect_er(line, i)
45
+ break if with_tc_ar_er?
46
+ end
47
+ with_tc_ar_er?
48
+ end
49
+
50
+ def escape(line)
51
+ if line.include?("{color")
52
+ line.gsub(
53
+ /({color:(#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})|[A-Za-z]+)})|{color}/, ""
54
+ )
55
+ else
56
+ line.gsub(/[^a-zA-Z(:|=)]/, "")
57
+ end
58
+ end
59
+
60
+ # @return true if description has test case, AR and ER
61
+ def with_tc_ar_er?
62
+ (@tc.zero? || @tc.positive?) && @ar.positive? && @er.positive?
63
+ end
64
+
65
+ # Detect index of line with test case
66
+ def detect_tc(line, index)
67
+ return unless @tc.negative?
68
+ @tc = index if %w[testcase: tc: teststeps: teststeps steps:].any? do |e|
69
+ e.eql? line
70
+ end
71
+ end
72
+
73
+ # Detect index of line with actual result
74
+ def detect_ar(line, index)
75
+ return unless @ar.negative? && index > @tc
76
+ @ar = index if %w[ar: actualresult: ar=].any? { |e| line.start_with? e }
77
+ end
78
+
79
+ # Detect index of line with expected result
80
+ def detect_er(line, index)
81
+ return unless @er.negative? && index > @tc
82
+ @er = index if %w[er: expectedresult: er=].any? { |e| line.start_with? e }
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2019-2020 Yurii Dubinka
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"),
9
+ # to deal in the Software without restriction, including without limitation
10
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ # and/or sell copies of the Software, and to permit persons to whom
12
+ # the Software is furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
23
+ # OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ require_relative "requirement"
26
+
27
+ module Lazylead
28
+ # Check that ticket has a remote link to external system with relationship
29
+ # type = "Wiki Page".
30
+ class Wiki < Lazylead::Requirement
31
+ def initialize(score = 2, relationship = "Wiki Page")
32
+ super "Reference to design specification", score, "Ticket Links (Wiki)"
33
+ @relationship = relationship
34
+ end
35
+
36
+ def passed(issue)
37
+ return false if issue.remote_links.nil? || issue.remote_links.empty?
38
+ issue.remote_links.any? { |l| @relationship.eql? l.attrs["relationship"] }
39
+ end
40
+ end
41
+ end
@@ -22,6 +22,8 @@
22
22
  # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
23
23
  # OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
+ require_relative "../log"
26
+
25
27
  module Lazylead
26
28
  module Task
27
29
  # Lazylead task which prints to STDOUT the current class name and team.
@@ -38,5 +40,21 @@ module Lazylead
38
40
  self.class.to_s
39
41
  end
40
42
  end
43
+
44
+ # Lazylead task which prints the current time to a file.
45
+ #
46
+ # Author:: Yurii Dubinka (yurii.dubinka@gmail.com)
47
+ # Copyright:: Copyright (c) 2019-2020 Yurii Dubinka
48
+ # License:: MIT
49
+ class EchoIO
50
+ def initialize(log = Log.new, path = "test/resources/echo.txt")
51
+ @log = log
52
+ @path = path
53
+ end
54
+
55
+ def run(_, _, _)
56
+ File.open(@path, "w") { |f| f.write Time.now }
57
+ end
58
+ end
41
59
  end
42
60
  end
@@ -38,13 +38,15 @@ module Lazylead
38
38
 
39
39
  def run(sys, postman, opts)
40
40
  allowed = opts.slice("allowed", ",")
41
+ silent = opts.key? "silent"
41
42
  issues = sys.issues(
42
43
  opts["jql"], opts.jira_defaults.merge(expand: "changelog")
43
44
  )
44
45
  return if issues.empty?
45
46
  postman.send opts.merge(
46
- versions: issues.map { |i| Version.new(i, allowed) }
47
+ versions: issues.map { |i| Version.new(i, allowed, silent) }
47
48
  .select(&:changed?)
49
+ .each(&:add_label)
48
50
  )
49
51
  end
50
52
  end
@@ -53,9 +55,10 @@ module Lazylead
53
55
  class Version
54
56
  attr_reader :issue
55
57
 
56
- def initialize(issue, allowed)
58
+ def initialize(issue, allowed, silent)
57
59
  @issue = issue
58
60
  @allowed = allowed
61
+ @silent = silent
59
62
  end
60
63
 
61
64
  # Gives true when last change of "Fix Version" field was done
@@ -78,6 +81,10 @@ module Lazylead
78
81
  end
79
82
  end
80
83
  end
84
+
85
+ def add_label
86
+ @issue.add_label("LL.IllegalChangeOfFixVersion") unless @silent
87
+ end
81
88
  end
82
89
  end
83
90
  end
@@ -58,26 +58,22 @@ module Lazylead
58
58
 
59
59
  # Return all svn commits for particular date range in repo
60
60
  def svn_log(opts)
61
- url = opts["svn_url"]
62
- usr = decrypt(opts["svn_user"])
63
- psw = decrypt(opts["svn_password"])
64
61
  now = if opts.key? "now"
65
62
  DateTime.parse(opts["now"])
66
63
  else
67
64
  DateTime.now
68
65
  end
69
66
  start = (now.to_time - opts["period"].to_i).to_datetime
70
- raw = `svn log --no-auth-cache --username #{usr} --password #{psw}
71
- --xml -v -r {#{start}}:{#{now}} #{url}`
67
+ cmd = [
68
+ "svn log --no-auth-cache",
69
+ "--username #{opts.decrypt('svn_user', 'svn_salt')}",
70
+ "--password #{opts.decrypt('svn_password', 'svn_salt')}",
71
+ "--xml -v -r {#{start}}:{#{now}} #{opts['svn_url']}"
72
+ ]
73
+ raw = `#{cmd.join(" ")}`
72
74
  Nokogiri.XML(raw, nil, "UTF-8")
73
75
  end
74
76
 
75
- # Decrypt text using cryptography salt
76
- def decrypt(text, sid = "svn_salt")
77
- return Salt.new(sid).decrypt(text) if ENV.key? sid
78
- text
79
- end
80
-
81
77
  # Convert single revision(XML text) to entry object.
82
78
  # Entry object is a simple ruby struct object.
83
79
  def to_entry(xml)
@@ -98,5 +94,26 @@ module Lazylead
98
94
  )
99
95
  end
100
96
  end
97
+
98
+ #
99
+ # Send notification about modification of svn files since particular
100
+ # revision.
101
+ #
102
+ class SvnLog
103
+ def initialize(log = Log.new)
104
+ @log = log
105
+ end
106
+
107
+ def run(_, postman, opts)
108
+ cmd = [
109
+ "svn log --diff --no-auth-cache",
110
+ "--username #{opts.decrypt('svn_user', 'svn_salt')}",
111
+ "--password #{opts.decrypt('svn_password', 'svn_salt')}",
112
+ "-r#{opts['since_rev']}:HEAD #{opts['svn_url']}"
113
+ ]
114
+ stdout = `#{cmd.join(" ")}`
115
+ postman.send(opts.merge(stdout: stdout)) unless stdout.blank?
116
+ end
117
+ end
101
118
  end
102
119
  end
@@ -23,5 +23,5 @@
23
23
  # OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
25
  module Lazylead
26
- VERSION = "0.4.1"
26
+ VERSION = "0.5.2"
27
27
  end
@@ -0,0 +1,117 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <style>
5
+ /* CSS styles taken from https://github.com/yegor256/tacit */
6
+ pre, code, kbd, samp, var, output {
7
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
8
+ font-size: 14.4px
9
+ }
10
+
11
+ pre code {
12
+ background: none;
13
+ border: 0;
14
+ line-height: 29.7px;
15
+ padding: 0
16
+ }
17
+
18
+ code, kbd {
19
+ background: #daf1e0;
20
+ border-radius: 3.6px;
21
+ color: #2a6f3b;
22
+ display: inline-block;
23
+ line-height: 18px;
24
+ padding: 3.6px 6.3px 2.7px
25
+ }
26
+
27
+ a {
28
+ color: #275a90;
29
+ text-decoration: none
30
+ }
31
+
32
+ a:hover {
33
+ text-decoration: underline
34
+ }
35
+
36
+ * {
37
+ border: 0;
38
+ border-collapse: separate;
39
+ border-spacing: 0;
40
+ box-sizing: border-box;
41
+ margin: 0;
42
+ max-width: 100%;
43
+ padding: 0;
44
+ vertical-align: baseline;
45
+ font-family: system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
46
+ font-size: 13px;
47
+ font-stretch: normal;
48
+ font-style: normal;
49
+ font-weight: 400;
50
+ line-height: 29.7px
51
+ }
52
+
53
+ html, body {
54
+ width: 100%
55
+ }
56
+
57
+ html {
58
+ height: 100%
59
+ }
60
+
61
+ body {
62
+ background: #fff;
63
+ color: #1a1919;
64
+ padding: 36px
65
+ }
66
+
67
+ .commit {
68
+ min-width: 100%;
69
+ border-radius: 3.5px;
70
+ overflow: hidden;
71
+ display: inline-block;
72
+ line-height: 15px;
73
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
74
+ border: 1px solid #BCC6CC;
75
+ }
76
+
77
+ .commit * {
78
+ padding-left: 4px;
79
+ font-size: 8px;
80
+ line-height: 15px;
81
+ }
82
+ </style>
83
+ <title>SVN log</title>
84
+ </head>
85
+ <body>
86
+ <p>Hi,</p>
87
+ <p>The following file(s) changed since <code><%= since_rev %></code> rev in <a href="<%= svn_url %>"><%= svn_url %></a>:</p>
88
+ <% stdout.split("------------------------------------------------------------------------").reject(&:blank?).reverse.each do |commit| %>
89
+ <div class="commit">
90
+ <% commit.split("\n").reject(&:blank?).each_with_index do |line, index| %>
91
+ <% if index.zero? %>
92
+ <% details = line.split("|").map(&:strip).reject(&:blank?) %>
93
+ <p style="background: gainsboro;">
94
+ <a href="<%= commit_url %><%= details[0][1 .. -1] %>"><%= details[0] %></a>
95
+ by <a href="<%= user %><%= details[1] %>"><%= details[1] %></a>
96
+ at <span style="color: #275a90;"><%= details[2] %></span>
97
+ </p>
98
+ <% else %>
99
+ <% if line.start_with?("+++") || line.start_with?("---") %>
100
+ <p style="background: gainsboro;"><%= line.gsub(/[<>]/, '<' => '&lt;', '>' => '&gt;') %></p>
101
+ <% elsif line.start_with?("+") %>
102
+ <p style="<%= "background: darkseagreen;" %>"><%= line.gsub(/[<>]/, '<' => '&lt;', '>' => '&gt;') %></p>
103
+ <% elsif line.start_with?("-") %>
104
+ <p style="<%= "background: lightsalmon;" %>"><%= line.gsub(/[<>]/, '<' => '&lt;', '>' => '&gt;') %></p>
105
+ <% else %>
106
+ <p style="background: gainsboro;"><%= line.gsub(/[<>]/,'<' => '&lt;', '>' => '&gt;') %></p>
107
+ <% end %>
108
+ <% end %>
109
+ <% end %>
110
+ </div>
111
+ <br/><br/><br/>
112
+ <% end %>
113
+ <p>Posted by
114
+ <a href="https://github.com/dgroup/lazylead">lazylead v<%= version %></a>.
115
+ </p>
116
+ </body>
117
+ </html>
@@ -106,7 +106,7 @@
106
106
  padding: 3.6px 6.3px 2.7px
107
107
  }
108
108
  </style>
109
- <title>RCA</title>
109
+ <title>SVN touch</title>
110
110
  </head>
111
111
  <body>
112
112
  <p>Hi,</p>
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2019-2020 Yurii Dubinka
3
+ Copyright (c) 2019-2021 Yurii Dubinka
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"),
data/readme.md CHANGED
@@ -113,7 +113,7 @@ For simplicity, we are using [docker-compose](https://docs.docker.com/compose/):
113
113
  ll > docker-compose -f .github/tasks.yml up
114
114
  Creating lazylead ... done
115
115
  Attaching to lazylead
116
- lazylead | [2020-08-09T06:17:32] DEBUG [main] Version: 0.4.0
116
+ lazylead | [2020-08-09T06:17:32] DEBUG [main] Version: 0.5.0
117
117
  lazylead | [2020-08-09T06:17:32] DEBUG [main] Memory footprint at start is 52MB
118
118
  lazylead | [2020-08-09T06:17:32] DEBUG [main] Database: '/lazylead/db/ll.db', sql migration dir: '/lazylead/upgrades/sqlite'
119
119
  lazylead | [2020-08-09T06:17:32] DEBUG [main] Migration applied to /lazylead/db/ll.db from /lazylead/upgrades/sqlite
@@ -135,16 +135,16 @@ For simplicity, we are using [docker-compose](https://docs.docker.com/compose/):
135
135
  values (1, 'Dream team with lazylead', '{}');
136
136
  insert into systems(id, properties)
137
137
  values (1,'{"type":"Lazylead::Jira", "username":"${jira_user}", "password":"${jira_password}", "site":"${jira_url}", "context_path":""}');
138
- insert into tasks (name, cron, enabled, id, system, team_id, action, properties)
138
+ insert into tasks (name, schedule, enabled, id, system, team_id, action, properties)
139
139
  values ('Expired due dates',
140
- '0 8 * * 1-5',
140
+ 'cron:0 8 * * 1-5',
141
141
  'true',
142
142
  1, 1, 1,
143
143
  'Lazylead::Task::AssigneeAlert',
144
144
  '{"sql":"filter=555", "cc":"<youremail.com>", "subject":"[LL] Expired due dates", "template":"lib/messages/due_date_expired.erb", "postman":"Lazylead::Exchange"}');
145
145
 
146
146
  ```
147
- Yes, for task scheduling we are using [cron](https://crontab.guru).
147
+ Yes, for task scheduling we are using [cron](https://crontab.guru) here, but you may use other scheduling types from [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler).
148
148
 
149
149
  4. Once you changed `./ll.db`, please restart the container using `docker-compose -f .github/tasks.yml restart`
150
150
  ```bash
@@ -154,7 +154,7 @@ For simplicity, we are using [docker-compose](https://docs.docker.com/compose/):
154
154
  check the logs and stop container if needed
155
155
  ```bash
156
156
  ll > docker logs lazylead
157
- lazylead | [2020-08-09T06:17:32] DEBUG [main] Version: 0.4.0
157
+ lazylead | [2020-08-09T06:17:32] DEBUG [main] Version: 0.5.0
158
158
  lazylead | [2020-08-09T06:17:32] DEBUG [main] Memory footprint at start is 52MB
159
159
  lazylead | [2020-08-09T06:17:32] DEBUG [main] Database: '/lazylead/db/ll.db', sql migration dir: '/lazylead/upgrades/sqlite'
160
160
  lazylead | [2020-08-09T06:17:32] DEBUG [main] Migration applied to /lazylead/db/ll.db from /lazylead/upgrades/sqlite
@@ -39,14 +39,14 @@ module Lazylead
39
39
  assert_tables "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
40
40
  systems: %w[id properties],
41
41
  teams: %w[id name properties],
42
- tasks: %w[id name cron system action team_id enabled properties]
42
+ tasks: %w[id name schedule system action team_id enabled properties]
43
43
  assert_fk "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
44
44
  %w[tasks team_id teams id],
45
45
  %w[tasks system systems id]
46
46
  end
47
47
 
48
48
  test "activesupport is activated for access to domain entities" do
49
- CLI::App.new(Log.new, Schedule.new(cling: false)).run(
49
+ CLI::App.new(Log.new, NoSchedule.new).run(
50
50
  home: ".",
51
51
  sqlite: "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
52
52
  vcs4sql: "upgrades/sqlite",
@@ -57,16 +57,16 @@ module Lazylead
57
57
  "Required team record wasn't found in the database"
58
58
  end
59
59
 
60
- # @todo #10/DEV Think about using "timecop" >v0.9.1 gem in order to make
61
- # E2E application skeleton https://stackoverflow.com/questions/59955571.
62
- # The depedency for gemspec should be after *thin* in .gemspec
63
- # ..
64
- # s.add_runtime_dependency "thin", "1.7.2"
65
- # s.add_runtime_dependency "timecop", "0.9.1"
66
- # ..
67
- # More https://github.com/travisjeffery/timecop
68
60
  test "scheduled task was triggered successfully" do
69
- skip "Not implemented yet"
61
+ CLI::App.new(Log.new, Schedule.new(cling: false)).run(
62
+ home: ".",
63
+ sqlite: "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
64
+ vcs4sql: "upgrades/sqlite",
65
+ testdata: true
66
+ )
67
+ sleep 0.4
68
+ assert (Time.now - 5.seconds) < Time.parse(File.open("test/resources/echo.txt").first),
69
+ "Scheduled task wasn't executed few seconds ago"
70
70
  end
71
71
  end
72
72
  end