doing 2.1.17 → 2.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.yardoc/checksums +15 -14
  3. data/.yardoc/object_types +0 -0
  4. data/.yardoc/objects/root.dat +0 -0
  5. data/CHANGELOG.md +117 -53
  6. data/Gemfile.lock +11 -11
  7. data/README.md +1 -1
  8. data/Rakefile +12 -4
  9. data/bin/doing +161 -205
  10. data/docs/doc/Array.html +9 -37
  11. data/docs/doc/BooleanTermParser/Clause.html +3 -3
  12. data/docs/doc/BooleanTermParser/Operator.html +3 -3
  13. data/docs/doc/BooleanTermParser/Query.html +3 -3
  14. data/docs/doc/BooleanTermParser/QueryParser.html +3 -3
  15. data/docs/doc/BooleanTermParser/QueryTransformer.html +3 -3
  16. data/docs/doc/BooleanTermParser.html +3 -3
  17. data/docs/doc/Doing/Color.html +3 -3
  18. data/docs/doc/Doing/Completion.html +3 -3
  19. data/docs/doc/Doing/Configuration.html +4 -3
  20. data/docs/doc/Doing/Errors/DoingNoTraceError.html +3 -3
  21. data/docs/doc/Doing/Errors/DoingRuntimeError.html +3 -3
  22. data/docs/doc/Doing/Errors/DoingStandardError.html +3 -3
  23. data/docs/doc/Doing/Errors/EmptyInput.html +3 -3
  24. data/docs/doc/Doing/Errors/NoResults.html +3 -3
  25. data/docs/doc/Doing/Errors/PluginException.html +3 -3
  26. data/docs/doc/Doing/Errors/UserCancelled.html +3 -3
  27. data/docs/doc/Doing/Errors/WrongCommand.html +3 -3
  28. data/docs/doc/Doing/Errors.html +3 -3
  29. data/docs/doc/Doing/Hooks.html +3 -3
  30. data/docs/doc/Doing/Item.html +3 -3
  31. data/docs/doc/Doing/Items.html +3 -3
  32. data/docs/doc/Doing/LogAdapter.html +3 -3
  33. data/docs/doc/Doing/Note.html +3 -3
  34. data/docs/doc/Doing/Pager.html +3 -3
  35. data/docs/doc/Doing/Plugins.html +3 -3
  36. data/docs/doc/Doing/Prompt.html +7 -7
  37. data/docs/doc/Doing/Section.html +3 -3
  38. data/docs/doc/Doing/TemplateString.html +4 -4
  39. data/docs/doc/Doing/Util/Backup.html +3 -3
  40. data/docs/doc/Doing/Util.html +3 -3
  41. data/docs/doc/Doing/WWID.html +66 -8
  42. data/docs/doc/Doing.html +6 -6
  43. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +3 -3
  44. data/docs/doc/GLI/Commands.html +3 -3
  45. data/docs/doc/GLI.html +3 -3
  46. data/docs/doc/Hash.html +78 -6
  47. data/docs/doc/Numeric.html +3 -3
  48. data/docs/doc/PhraseParser/Operator.html +3 -3
  49. data/docs/doc/PhraseParser/PhraseClause.html +3 -3
  50. data/docs/doc/PhraseParser/Query.html +3 -3
  51. data/docs/doc/PhraseParser/QueryParser.html +3 -3
  52. data/docs/doc/PhraseParser/QueryTransformer.html +3 -3
  53. data/docs/doc/PhraseParser/TermClause.html +3 -3
  54. data/docs/doc/PhraseParser.html +3 -3
  55. data/docs/doc/Status.html +3 -3
  56. data/docs/doc/String.html +156 -17
  57. data/docs/doc/Symbol.html +3 -3
  58. data/docs/doc/Time.html +3 -3
  59. data/docs/doc/_index.html +23 -16
  60. data/docs/doc/class_list.html +1 -1
  61. data/docs/doc/file.README.html +4 -4
  62. data/docs/doc/frames.html +1 -1
  63. data/docs/doc/index.html +4 -4
  64. data/docs/doc/method_list.html +331 -283
  65. data/docs/doc/top-level-namespace.html +3 -3
  66. data/doing.gemspec +1 -1
  67. data/doing.rdoc +26 -12
  68. data/lib/completion/_doing.zsh +5 -5
  69. data/lib/completion/doing.bash +8 -8
  70. data/lib/completion/doing.fish +93 -15
  71. data/lib/doing/array.rb +5 -4
  72. data/lib/doing/array_chronify.rb +4 -3
  73. data/lib/doing/completion/fish_completion.rb +80 -11
  74. data/lib/doing/configuration.rb +2 -1
  75. data/lib/doing/hash.rb +22 -4
  76. data/lib/doing/item.rb +2 -2
  77. data/lib/doing/items.rb +3 -1
  78. data/lib/doing/log_adapter.rb +1 -1
  79. data/lib/doing/pager.rb +2 -2
  80. data/lib/doing/plugins/export/dayone_export.rb +1 -1
  81. data/lib/doing/plugins/export/markdown_export.rb +1 -1
  82. data/lib/doing/plugins/export/template_export.rb +8 -2
  83. data/lib/doing/prompt.rb +4 -2
  84. data/lib/doing/string.rb +25 -2
  85. data/lib/doing/string_chronify.rb +55 -17
  86. data/lib/doing/template_string.rb +7 -0
  87. data/lib/doing/types.rb +23 -0
  88. data/lib/doing/version.rb +1 -1
  89. data/lib/doing/wwid.rb +71 -50
  90. data/lib/doing.rb +1 -0
  91. data/lib/examples/commands/later.rb +32 -0
  92. data/lib/helpers/threaded_tests.rb +273 -0
  93. metadata +9 -6
@@ -0,0 +1,273 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tty-spinner'
4
+ require 'tty-progressbar'
5
+ require './lib/doing'
6
+ require 'open3'
7
+ require 'shellwords'
8
+
9
+ class ::String
10
+ include Doing::Color
11
+
12
+ def highlight_errors
13
+ cols = `tput cols`.strip.to_i
14
+
15
+ string = dup
16
+
17
+ errs = string.scan(/(?<==\n)(?:Failure|Error):.*?(?=\n=+)/m)
18
+
19
+ errs.map! do |error|
20
+ err = error.dup
21
+
22
+ err.gsub!(%r{^(/.*?/)([^/:]+):(\d+):in (.*?)$}) do
23
+ m = Regexp.last_match
24
+ "#{m[1].white}#{m[2].bold.white}:#{m[3].yellow}:in #{m[4].cyan}"
25
+ end
26
+ err.gsub!(/(Failure|Error): (.*?)\((.*?)\):\n (.*?)(?=\n)/m) do
27
+ m = Regexp.last_match
28
+ [
29
+ m[1].bold.boldbgred.white,
30
+ m[3].bold.boldbgcyan.white,
31
+ m[2].bold.boldbgyellow.black,
32
+ " #{m[4]} ".bold.boldbgwhite.black.reset
33
+ ].join(':'.boldblack.boldbgblack.reset)
34
+ end
35
+ err.gsub!(/(<.*?>) (was expected to) (.*?)\n( *<.*?>)./m) do
36
+ m = Regexp.last_match
37
+ "#{m[1].bold.green} #{m[2].white} #{m[3].boldwhite.boldbgred.reset}\n#{m[4].bold.white}"
38
+ end
39
+ err.gsub!(/(Finished in) ([\d.]+) (seconds)/) do
40
+ m = Regexp.last_match
41
+ "#{m[1].green} #{m[2].bold.white} #{m[3].green}"
42
+ end
43
+ err.gsub!(/(\d+) (failures)/) do
44
+ m = Regexp.last_match
45
+ "#{m[1].bold.red} #{m[2].red}"
46
+ end
47
+ err.gsub!(/100% passed/) do |m|
48
+ m.bold.green
49
+ end
50
+
51
+ err
52
+ end
53
+
54
+ errs.join("\n#{('=' * cols).blue}\n")
55
+ end
56
+ end
57
+
58
+ class ThreadedTests
59
+ include Doing::Color
60
+
61
+ def run(pattern: '*', max_threads: 8, max_tests: 0)
62
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
63
+
64
+ max_threads = 1000 if max_threads == 0
65
+
66
+ c = Doing::Color
67
+ c.coloring = true
68
+
69
+ pattern = "test/doing_*#{pattern}*_test.rb"
70
+
71
+ tests = Dir.glob(pattern)
72
+
73
+ if max_tests > 0
74
+ tests = tests.slice(0, max_tests - 1)
75
+ end
76
+
77
+ puts "#{tests.count} test files".boldcyan
78
+
79
+ banner = [
80
+ 'Running tests '.bold.white,
81
+ '['.black,
82
+ ':bar'.boldcyan,
83
+ '] '.black,
84
+ 'T'.green,
85
+ '/'.white,
86
+ 'A'.cyan,
87
+ ' ('.white,
88
+ max_threads.to_s.bold.magenta,
89
+ ' threads)'.white
90
+ ].join('')
91
+ progress = TTY::ProgressBar::Multi.new(banner,
92
+ width: 12,
93
+ hide_cursor: true)
94
+ @children = []
95
+ tests.each do |t|
96
+ test_name = File.basename(t, '.rb').sub(/doing_(.*?)_test/, '\1')
97
+ new_sp = progress.register("[#{':bar'.cyan}] #{test_name.bold.white}:status",
98
+ total: 2, width: 1, head: '.', hide_cursor: true, clear: true)
99
+ @children.push([test_name, new_sp, nil])
100
+ end
101
+
102
+ @elapsed = 0.0
103
+ @test_total = 0
104
+ @assrt_total = 0
105
+ @error_out = []
106
+ # progress.start
107
+ @threads = []
108
+
109
+ begin
110
+ while @children.count.positive?
111
+
112
+ slices = @children.slice!(0, max_threads)
113
+ slices.each { |c| c[1].start }
114
+ slices.each do |s|
115
+ @threads << Thread.new do
116
+ run_test(s)
117
+ end
118
+ end
119
+
120
+ @threads.each { |t| t.join }
121
+ end
122
+
123
+ finish_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
124
+
125
+ progress.finish
126
+
127
+ output = []
128
+ if @error_out.count.positive?
129
+ output << c.boldred("#{@error_out.count} Issues")
130
+ else
131
+ output << c.green('Success')
132
+ end
133
+ output << c.green("#{@test_total} tests")
134
+ output << c.cyan("#{@assrt_total} assertions")
135
+ output << c.yellow("#{(finish_time - start_time).round(3)}s")
136
+ puts output.join(', ')
137
+
138
+ puts @error_out.join("\n----\n".boldwhite) if @error_out.count.positive?
139
+ rescue
140
+ progress.stop
141
+ end
142
+ end
143
+
144
+ def run_test(s)
145
+ bar = s[1]
146
+ bar.advance(status: ": #{'running'.green}")
147
+
148
+ out, _err, status = Open3.capture3(ENV, 'rake', "test:#{s[0]}", stdin_data: nil)
149
+ unless status.success?
150
+ m = out.match(/(?<fail>\d+) failures, (?<err>\d+) errors/)
151
+ status = ": #{m['fail'].bold.red} #{'failures'.red}, #{m['err'].bold.red} #{'errors'.red}"
152
+ bar.update(head: '✖'.boldred)
153
+ bar.advance(head: '✖'.boldred, status: status)
154
+
155
+ # errs = out.scan(/(?:Failure|Error): [\w_]+\((?:.*?)\):(?:.*?)(?=\n=======)/m)
156
+ @error_out.push(out.highlight_errors)
157
+ bar.finish
158
+
159
+ next_test
160
+ Thread.exit
161
+ end
162
+
163
+ time = out.match(/^Finished in (?<time>\d+\.\d+) seconds\./)
164
+ count = out.match(/^(?<tests>\d+) tests, (?<assrt>\d+) assertions, (?<fails>\d+) failures, (?<errs>\d+) errors/)
165
+ status = [
166
+ ': ',
167
+ count['tests'].green,
168
+ '/',
169
+ count['assrt'].cyan,
170
+ # ' (',
171
+ # count['fails'].to_i == 0 ? '-'.dark.white.reset : count['fails'].bold.red,
172
+ # '/',
173
+ # count['errs'].to_i == 0 ? '-'.dark.white.reset : count['errs'].bold.red,
174
+ # ') ',
175
+ ' ',
176
+ time['time'].to_f.round(3).to_s.yellow,
177
+ 's'
178
+ ].join('')
179
+ bar.update(head: '✔'.boldgreen)
180
+ bar.advance(head: '✔'.boldgreen, status: status)
181
+ @test_total += count['tests'].to_i
182
+ @assrt_total += count['assrt'].to_i
183
+ @elapsed += time['time'].to_f
184
+
185
+ bar.finish
186
+
187
+ next_test
188
+ end
189
+
190
+ def next_test
191
+ if @children.count.positive?
192
+ t = Thread.new do
193
+ s = @children.shift
194
+ # s[1].start
195
+ # s[1].advance(status: ": #{'running'.green}")
196
+ run_test(s)
197
+ end
198
+
199
+ t.join
200
+ end
201
+ end
202
+ end
203
+
204
+
205
+ # require 'pastel'
206
+ ### Individual tests, multiple spinners
207
+ # pastel = Pastel.new
208
+ # format = "[#{pastel.yellow(':spinner')}] #{pastel.white("Running tests")} (#{pastel.green('tests')}/#{pastel.cyan('assertions')} #{pastel.yellow('time')})"
209
+ # spinners = TTY::Spinner::Multi.new(format, format: :dots, success_mark: pastel.green('✔'), error_mark: pastel.red('✖'))
210
+ # children = []
211
+ # tests = Dir.glob('test/doing_*_test.rb').each do |t|
212
+ # test_name = File.basename(t, '.rb').sub(/doing_(.*?)_test/, '\1')
213
+ # new_sp = spinners.register "[#{pastel.cyan(':spinner')}] #{test_name}:msg"
214
+ # new_sp.update(msg: '')
215
+ # children.push([test_name, new_sp])
216
+ # end
217
+
218
+ # @elapsed = 0.0
219
+ # @test_total = 0
220
+ # @assrt_total = 0
221
+ # spinners.auto_spin
222
+
223
+ # children.each do |spinner|
224
+ # spinner[1].run do |s|
225
+ # out, _err, status = Open3.capture3(ENV, 'rake', "test:#{spinner[0]}", stdin_data: nil)
226
+ # unless status.success?
227
+ # s.update(msg: "#{pastel.red('- FAILURE:')} #{pastel.bold.white(func)} in #{pastel.bold.yellow(tst)}")
228
+ # s.error
229
+ # s.stop
230
+ # puts `echo #{Shellwords.escape(out)} | colout '^(/.*?/)([^/:]+):(\d+):in (.*?)$' white,yellow,green,magenta | colout 'Failure: (.*?)\\((.*?)\\)' red,green | colout '(.*?) (was expected to be)' green,red | colout '(Finished in) ([\d.]+) (seconds)' green,white,green | colout '(\d+ failures)' red | colout '(100% passed)' green`
231
+ # Process.exit
232
+ # end
233
+
234
+ # time = out.match(/^Finished in (?<time>\d+\.\d+) seconds\./)
235
+ # count = out.match(/^(?<tests>\d+) tests, (?<assrt>\d+) assertions/)
236
+ # s.update(msg: ": #{pastel.green(count['tests'])}/#{pastel.cyan(count['assrt'])} #{pastel.yellow(time['time'].to_f.round(3))}s")
237
+ # @test_total += count['tests'].to_i
238
+ # @assrt_total += count['assrt'].to_i
239
+ # @elapsed += time['time'].to_f
240
+ # s.success
241
+ # end
242
+ # end
243
+
244
+ # output = []
245
+ # output << pastel.green('Success')
246
+ # output << pastel.green("#{@test_total} tests")
247
+ # output << pastel.cyan("#{@assrt_total} assertions")
248
+ # output << pastel.yellow("#{@elapsed.round(4)}s")
249
+ # puts output.join(', ')
250
+
251
+ ### Parallel test single spinner
252
+ # pastel = Pastel.new
253
+ # format = "[#{pastel.yellow(':spinner')}] #{pastel.white('Running parallel tests')} :msg"
254
+ # spinner = TTY::Spinner.new(format, format: :dots, success_mark: pastel.green('✔'), error_mark: pastel.red('✖'))
255
+
256
+ # spinner.run do |sp|
257
+ # sp.update(msg: '')
258
+ # out, err, status = Open3.capture3(ENV, 'rake', 'parallel:test', stdin_data: nil)
259
+
260
+ # unless status.success?
261
+ # failure = out.match(/^Failure: (.*?)\(([A-Z].*?)\)/)
262
+ # func = failure[1]
263
+ # tst = failure[2]
264
+ # sp.update(msg: "#{pastel.red('- FAILURE:')} #{pastel.bold.white(func)} in #{pastel.bold.yellow(tst)}")
265
+ # sp.error
266
+ # sp.stop
267
+ # puts `echo #{Shellwords.escape(out)} | colout '^(/.*?/)([^/:]+):(\d+):in (.*?)$' white,yellow,green,magenta | colout 'Failure: (.*?)\\((.*?)\\)' red,green | colout '(.*?) (was expected to be)' green,red | colout '(Finished in) ([\d.]+) (seconds)' green,white,green | colout '(\d+ failures)' red | colout '(100% passed)' green`
268
+ # Process.exit
269
+ # end
270
+
271
+ # sp.update(msg: pastel.green('- All tests passed'))
272
+ # sp.success
273
+ # end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doing
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.17
4
+ version: 2.1.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-18 00:00:00.000000000 Z
11
+ date: 2022-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: safe_yaml
@@ -212,20 +212,20 @@ dependencies:
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: '2.19'
215
+ version: '2.20'
216
216
  - - ">="
217
217
  - !ruby/object:Gem::Version
218
- version: 2.19.2
218
+ version: 2.20.1
219
219
  type: :runtime
220
220
  prerelease: false
221
221
  version_requirements: !ruby/object:Gem::Requirement
222
222
  requirements:
223
223
  - - "~>"
224
224
  - !ruby/object:Gem::Version
225
- version: '2.19'
225
+ version: '2.20'
226
226
  - - ">="
227
227
  - !ruby/object:Gem::Version
228
- version: 2.19.2
228
+ version: 2.20.1
229
229
  - !ruby/object:Gem::Dependency
230
230
  name: haml
231
231
  requirement: !ruby/object:Gem::Requirement
@@ -577,11 +577,13 @@ files:
577
577
  - lib/doing/symbol.rb
578
578
  - lib/doing/template_string.rb
579
579
  - lib/doing/time.rb
580
+ - lib/doing/types.rb
580
581
  - lib/doing/util.rb
581
582
  - lib/doing/util_backup.rb
582
583
  - lib/doing/version.rb
583
584
  - lib/doing/wwid.rb
584
585
  - lib/examples/commands/autotag.rb
586
+ - lib/examples/commands/later.rb
585
587
  - lib/examples/commands/wiki.rb
586
588
  - lib/examples/plugins/capture_thing_import.rb
587
589
  - lib/examples/plugins/hooks.rb
@@ -676,6 +678,7 @@ files:
676
678
  - lib/helpers/fzf/test/fzf.vader
677
679
  - lib/helpers/fzf/test/test_go.rb
678
680
  - lib/helpers/fzf/uninstall
681
+ - lib/helpers/threaded_tests.rb
679
682
  - lib/templates/doing-dayone-entry.erb
680
683
  - lib/templates/doing-dayone.erb
681
684
  - lib/templates/doing-markdown.erb