pdd 0.24.0 → 0.24.2
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.
- checksums.yaml +4 -4
- data/Gemfile +17 -30
- data/Gemfile.lock +194 -0
- data/LICENSE.txt +1 -1
- data/LICENSES/MIT.txt +21 -0
- data/README.md +99 -100
- data/REUSE.toml +41 -0
- data/Rakefile +4 -31
- data/assets/puzzles.xsd +3 -22
- data/assets/puzzles.xsl +3 -22
- data/assets/puzzles_json.xsl +4 -23
- data/bin/pdd +6 -22
- data/cucumber.yml +3 -0
- data/features/applies_rules.feature +2 -0
- data/features/avoiding_duplicates.feature +2 -0
- data/features/catches_broken_puzzles.feature +2 -0
- data/features/cli.feature +2 -0
- data/features/gem_package.feature +2 -0
- data/features/html_output.feature +2 -0
- data/features/json_output.feature +2 -0
- data/features/parsing.feature +2 -0
- data/features/rake.feature +2 -2
- data/features/remove.feature +3 -0
- data/features/step_definitions/steps.rb +2 -19
- data/features/support/env.rb +2 -19
- data/features/unicode.feature +2 -0
- data/features/uses_config.feature +2 -1
- data/lib/pdd/puzzle.rb +2 -19
- data/lib/pdd/rake_task.rb +3 -1
- data/lib/pdd/rule/duplicates.rb +2 -19
- data/lib/pdd/rule/estimates.rb +2 -19
- data/lib/pdd/rule/roles.rb +2 -19
- data/lib/pdd/rule/text.rb +2 -19
- data/lib/pdd/source.rb +2 -19
- data/lib/pdd/sources.rb +2 -19
- data/lib/pdd/version.rb +4 -21
- data/lib/pdd.rb +3 -20
- data/pdd.gemspec +9 -25
- data/test_assets/aladdin.jpg +0 -0
- data/test_assets/elegant-objects.png +0 -0
- data/test_assets/puzzles/1-04e35eb3 +1 -1
- data/test_assets/puzzles/132-bc1dfafe +1 -1
- data/test_assets/puzzles/1425-59819ae3 +5 -5
- data/test_assets/puzzles/42-0d933cc0 +1 -1
- data/test_assets/puzzles/91-ecb9aa47 +1 -1
- data/test_assets/puzzles/93-641fe341 +1 -1
- data/utils/glob.rb +2 -19
- metadata +24 -33
- data/.0pdd.yml +0 -9
- data/.gitattributes +0 -12
- data/.github/workflows/codecov.yml +0 -23
- data/.github/workflows/pdd.yml +0 -15
- data/.github/workflows/rake.yml +0 -24
- data/.github/workflows/xcop.yml +0 -15
- data/.gitignore +0 -8
- data/.overcommit.yml +0 -96
- data/.pdd +0 -27
- data/.rubocop.yml +0 -32
- data/.rultor.yml +0 -22
- data/.simplecov +0 -35
- data/test/test__helper.rb +0 -43
- data/test/test_duplicates.rb +0 -48
- data/test/test_estimates.rb +0 -47
- data/test/test_many.rb +0 -42
- data/test/test_pdd.rb +0 -111
- data/test/test_rake_task.rb +0 -18
- data/test/test_roles.rb +0 -56
- data/test/test_source.rb +0 -396
- data/test/test_source_todo.rb +0 -295
- data/test/test_sources.rb +0 -137
- data/test/test_text.rb +0 -39
data/test/test_source.rb
DELETED
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2014-2024 Yegor Bugayenko
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the 'Software'), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
# copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
-
# SOFTWARE.
|
|
20
|
-
|
|
21
|
-
require 'minitest/autorun'
|
|
22
|
-
require 'tmpdir'
|
|
23
|
-
require_relative '../lib/pdd'
|
|
24
|
-
require_relative '../lib/pdd/sources'
|
|
25
|
-
require_relative 'test__helper'
|
|
26
|
-
|
|
27
|
-
# Source test.
|
|
28
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
29
|
-
# Copyright:: Copyright (c) 2014-2024 Yegor Bugayenko
|
|
30
|
-
# License:: MIT
|
|
31
|
-
class TestSource < Minitest::Test
|
|
32
|
-
def test_parsing
|
|
33
|
-
Dir.mktmpdir 'test' do |dir|
|
|
34
|
-
file = File.join(dir, 'a.txt')
|
|
35
|
-
File.write(
|
|
36
|
-
file,
|
|
37
|
-
"
|
|
38
|
-
* \x40todo #44 привет,
|
|
39
|
-
* how are you\t\tdoing?
|
|
40
|
-
* -something else
|
|
41
|
-
Something else
|
|
42
|
-
~~ \x40todo #ABC-3 this is another puzzle
|
|
43
|
-
~~ and it also has to work
|
|
44
|
-
"
|
|
45
|
-
)
|
|
46
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
47
|
-
list = source.puzzles
|
|
48
|
-
assert_equal 2, list.size
|
|
49
|
-
puzzle = list.first
|
|
50
|
-
assert_equal '2-3', puzzle.props[:lines]
|
|
51
|
-
assert_equal 'привет, how are you doing?',
|
|
52
|
-
puzzle.props[:body]
|
|
53
|
-
assert_equal '44', puzzle.props[:ticket]
|
|
54
|
-
assert puzzle.props[:author].nil?
|
|
55
|
-
assert puzzle.props[:email].nil?
|
|
56
|
-
assert puzzle.props[:time].nil?
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def test_parsing_leading_spaces
|
|
62
|
-
Dir.mktmpdir 'test' do |dir|
|
|
63
|
-
file = File.join(dir, 'a.txt')
|
|
64
|
-
File.write(
|
|
65
|
-
file,
|
|
66
|
-
"
|
|
67
|
-
* \x40todo #56:30min this is a
|
|
68
|
-
* multi-line
|
|
69
|
-
* comment!
|
|
70
|
-
"
|
|
71
|
-
)
|
|
72
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
73
|
-
list = source.puzzles
|
|
74
|
-
assert_equal 1, list.size
|
|
75
|
-
puzzle = list.first
|
|
76
|
-
assert_equal '2-4', puzzle.props[:lines]
|
|
77
|
-
assert_equal 'this is a multi-line comment!', puzzle.props[:body]
|
|
78
|
-
assert_equal '56', puzzle.props[:ticket]
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def test_no_prefix_multiline_puzzle_block
|
|
84
|
-
Dir.mktmpdir 'test' do |dir|
|
|
85
|
-
file = File.join(dir, 'a.txt')
|
|
86
|
-
File.write(
|
|
87
|
-
file,
|
|
88
|
-
"
|
|
89
|
-
<!--
|
|
90
|
-
\x40todo #01:30min correctly formatted multi-line puzzle, with no
|
|
91
|
-
comment prefix before todo marker
|
|
92
|
-
-->
|
|
93
|
-
"
|
|
94
|
-
)
|
|
95
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
96
|
-
PDD.opts = nil
|
|
97
|
-
assert_equal 1, source.puzzles.size
|
|
98
|
-
puzzle = source.puzzles.last
|
|
99
|
-
assert_equal '3-4', puzzle.props[:lines]
|
|
100
|
-
assert_equal 'correctly formatted multi-line puzzle, with no ' \
|
|
101
|
-
'comment prefix before todo marker', puzzle.props[:body]
|
|
102
|
-
assert_equal '01', puzzle.props[:ticket]
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def test_space_indented_multiline_puzzle_block
|
|
108
|
-
Dir.mktmpdir 'test' do |dir|
|
|
109
|
-
file = File.join(dir, 'a.txt')
|
|
110
|
-
File.write(
|
|
111
|
-
file,
|
|
112
|
-
"
|
|
113
|
-
# \x40todo #99:30min hello
|
|
114
|
-
# good bye
|
|
115
|
-
# hello again
|
|
116
|
-
"
|
|
117
|
-
)
|
|
118
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
119
|
-
PDD.opts = nil
|
|
120
|
-
assert_equal 1, source.puzzles.size
|
|
121
|
-
puzzle = source.puzzles.last
|
|
122
|
-
assert_equal '2-3', puzzle.props[:lines]
|
|
123
|
-
assert_equal 'hello good bye', puzzle.props[:body]
|
|
124
|
-
assert_equal '99', puzzle.props[:ticket]
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def test_multiple_puzzles_single_comment_block
|
|
130
|
-
Dir.mktmpdir 'test' do |dir|
|
|
131
|
-
file = File.join(dir, 'a.txt')
|
|
132
|
-
File.write(
|
|
133
|
-
file,
|
|
134
|
-
"
|
|
135
|
-
/*
|
|
136
|
-
* \x40todo #1 First one with
|
|
137
|
-
* a few lines
|
|
138
|
-
* \x40todo #1 Second one also
|
|
139
|
-
* with a few lines of text
|
|
140
|
-
*/
|
|
141
|
-
"
|
|
142
|
-
)
|
|
143
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
144
|
-
PDD.opts = nil
|
|
145
|
-
assert_equal 2, source.puzzles.size
|
|
146
|
-
puzzle = source.puzzles.last
|
|
147
|
-
assert_equal '5-6', puzzle.props[:lines]
|
|
148
|
-
assert_equal 'Second one also with a few lines of text', puzzle.props[:body]
|
|
149
|
-
assert_equal '1', puzzle.props[:ticket]
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def test_succeed_despite_bad_puzzles
|
|
155
|
-
Dir.mktmpdir 'test' do |dir|
|
|
156
|
-
file = File.join(dir, 'a.txt')
|
|
157
|
-
File.write(
|
|
158
|
-
file,
|
|
159
|
-
"
|
|
160
|
-
* \x40todo #44 this is a correctly formatted puzzle,
|
|
161
|
-
* with a second line without a leading space
|
|
162
|
-
Another badly formatted puzzle
|
|
163
|
-
* \x40todo this bad puzzle misses ticket name/number
|
|
164
|
-
Something else
|
|
165
|
-
* \x40todo #123 This puzzle is correctly formatted
|
|
166
|
-
"
|
|
167
|
-
)
|
|
168
|
-
PDD.opts = { 'skip-errors' => true }
|
|
169
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
170
|
-
list = source.puzzles
|
|
171
|
-
PDD.opts = nil
|
|
172
|
-
assert_equal 2, list.size
|
|
173
|
-
puzzle = list.first
|
|
174
|
-
assert_equal '2-3', puzzle.props[:lines]
|
|
175
|
-
assert_equal 'this is a correctly formatted puzzle, with a second ' \
|
|
176
|
-
'line without a leading space', puzzle.props[:body]
|
|
177
|
-
assert_equal '44', puzzle.props[:ticket]
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def test_succeed_utf8_encoded_body
|
|
183
|
-
Dir.mktmpdir 'test' do |dir|
|
|
184
|
-
file = File.join(dir, 'a.txt')
|
|
185
|
-
File.write(
|
|
186
|
-
file,
|
|
187
|
-
"
|
|
188
|
-
* \x40todo #44 Привет, мир, мне кофе
|
|
189
|
-
* вторая линия
|
|
190
|
-
"
|
|
191
|
-
)
|
|
192
|
-
list = PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
|
|
193
|
-
assert_equal 1, list.size
|
|
194
|
-
puzzle = list.first
|
|
195
|
-
assert_equal '2-3', puzzle.props[:lines]
|
|
196
|
-
assert_equal 'Привет, мир, мне кофе вторая линия', puzzle.props[:body]
|
|
197
|
-
assert_equal '44', puzzle.props[:ticket]
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def test_failing_on_incomplete_puzzle
|
|
202
|
-
Dir.mktmpdir 't5' do |dir|
|
|
203
|
-
file = File.join(dir, 'ff.txt')
|
|
204
|
-
File.write(
|
|
205
|
-
file,
|
|
206
|
-
"
|
|
207
|
-
* \x40todo this puzzle misses ticket name/number
|
|
208
|
-
"
|
|
209
|
-
)
|
|
210
|
-
error = assert_raises PDD::Error do
|
|
211
|
-
stub_source_find_github_user(file, 'ff', &:puzzles)
|
|
212
|
-
end
|
|
213
|
-
assert !error.to_s.index("\x40todo is not followed by").nil?
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def test_failing_on_broken_unicode
|
|
218
|
-
Dir.mktmpdir 'test' do |dir|
|
|
219
|
-
file = File.join(dir, 'xx.txt')
|
|
220
|
-
File.write(file, " * \\x40todo #44 this is a broken unicode: #{0x92.chr}")
|
|
221
|
-
assert_raises PDD::Error do
|
|
222
|
-
stub_source_find_github_user(file, 'xx', &:puzzles)
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
def test_failing_on_invalid_puzzle_without_hash_sign
|
|
228
|
-
Dir.mktmpdir 'test' do |dir|
|
|
229
|
-
file = File.join(dir, 'a.txt')
|
|
230
|
-
File.write(
|
|
231
|
-
file,
|
|
232
|
-
"
|
|
233
|
-
* \x40todo 44 this puzzle is not formatted correctly
|
|
234
|
-
"
|
|
235
|
-
)
|
|
236
|
-
error = assert_raises PDD::Error do
|
|
237
|
-
stub_source_find_github_user(file, 'hey', &:puzzles)
|
|
238
|
-
end
|
|
239
|
-
assert !error.message.index('is not followed by a puzzle marker').nil?
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def test_failing_on_puzzle_without_leading_space
|
|
244
|
-
Dir.mktmpdir 'test' do |dir|
|
|
245
|
-
file = File.join(dir, 'hey.txt')
|
|
246
|
-
File.write(
|
|
247
|
-
file,
|
|
248
|
-
"
|
|
249
|
-
*\x40todo #999 this is an incorrectly formatted puzzle!
|
|
250
|
-
"
|
|
251
|
-
)
|
|
252
|
-
error = assert_raises PDD::Error do
|
|
253
|
-
stub_source_find_github_user(file, 'x', &:puzzles)
|
|
254
|
-
end
|
|
255
|
-
assert !error.message.index("\x40todo must have a leading space").nil?
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def test_failing_on_puzzle_with_space_after_dash
|
|
260
|
-
Dir.mktmpdir 'test' do |dir|
|
|
261
|
-
file = File.join(dir, 'hey-you.txt')
|
|
262
|
-
File.write(
|
|
263
|
-
file,
|
|
264
|
-
"
|
|
265
|
-
* \x40todo # 123 This puzzle has an unnecessary space before the dash
|
|
266
|
-
"
|
|
267
|
-
)
|
|
268
|
-
error = assert_raises PDD::Error do
|
|
269
|
-
stub_source_find_github_user(file, 'x', &:puzzles)
|
|
270
|
-
end
|
|
271
|
-
assert !error.message.index('an unexpected space').nil?
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
def test_reads_git_author
|
|
276
|
-
skip if Gem.win_platform?
|
|
277
|
-
Dir.mktmpdir 'test' do |dir|
|
|
278
|
-
raise unless system("
|
|
279
|
-
set -e
|
|
280
|
-
cd '#{dir}'
|
|
281
|
-
git init --quiet .
|
|
282
|
-
git config user.email test@teamed.io
|
|
283
|
-
git config user.name test_unknown
|
|
284
|
-
echo '\x40todo #1 this is the puzzle' > a.txt
|
|
285
|
-
git add a.txt
|
|
286
|
-
git commit --quiet -am 'first version'
|
|
287
|
-
")
|
|
288
|
-
|
|
289
|
-
stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
|
|
290
|
-
list = source.puzzles
|
|
291
|
-
assert_equal 1, list.size
|
|
292
|
-
puzzle = list.first
|
|
293
|
-
assert_equal '1-de87adc8', puzzle.props[:id]
|
|
294
|
-
assert_equal '1-1', puzzle.props[:lines]
|
|
295
|
-
assert_equal 'this is the puzzle', puzzle.props[:body]
|
|
296
|
-
assert_equal 'test_unknown', puzzle.props[:author]
|
|
297
|
-
assert_equal 'test@teamed.io', puzzle.props[:email]
|
|
298
|
-
assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/,
|
|
299
|
-
puzzle.props[:time])
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
def test_skips_invalid_git_mail
|
|
305
|
-
skip if Gem.win_platform?
|
|
306
|
-
Dir.mktmpdir 'test' do |dir|
|
|
307
|
-
raise unless system("
|
|
308
|
-
set -e
|
|
309
|
-
cd '#{dir}'
|
|
310
|
-
git init --quiet .
|
|
311
|
-
git config user.email invalid-email
|
|
312
|
-
git config user.name test
|
|
313
|
-
echo '\x40todo #1 this is the puzzle' > a.txt
|
|
314
|
-
git add a.txt
|
|
315
|
-
git commit --quiet -am 'first version'
|
|
316
|
-
")
|
|
317
|
-
|
|
318
|
-
stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
|
|
319
|
-
list = source.puzzles
|
|
320
|
-
assert_equal 1, list.size
|
|
321
|
-
puzzle = list.first
|
|
322
|
-
assert_equal '1-de87adc8', puzzle.props[:id]
|
|
323
|
-
assert_equal '1-1', puzzle.props[:lines]
|
|
324
|
-
assert_equal 'this is the puzzle', puzzle.props[:body]
|
|
325
|
-
assert_equal 'test', puzzle.props[:author]
|
|
326
|
-
assert_nil puzzle.props[:email]
|
|
327
|
-
assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/,
|
|
328
|
-
puzzle.props[:time])
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
def test_uses_github_login
|
|
334
|
-
skip if Gem.win_platform?
|
|
335
|
-
Dir.mktmpdir 'test' do |dir|
|
|
336
|
-
raise unless system("
|
|
337
|
-
cd '#{dir}'
|
|
338
|
-
git init --quiet .
|
|
339
|
-
git config user.email yegor256@gmail.com
|
|
340
|
-
git config user.name test
|
|
341
|
-
echo '\x40todo #1 this is the puzzle' > a.txt
|
|
342
|
-
git add a.txt
|
|
343
|
-
git commit --quiet -am 'first version'
|
|
344
|
-
")
|
|
345
|
-
|
|
346
|
-
stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
|
|
347
|
-
list = source.puzzles
|
|
348
|
-
assert_equal 1, list.size
|
|
349
|
-
puzzle = list.first
|
|
350
|
-
assert_equal '@yegor256', puzzle.props[:author]
|
|
351
|
-
end
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
def test_skips_uncommitted_changes
|
|
356
|
-
skip if Gem.win_platform?
|
|
357
|
-
Dir.mktmpdir 'test' do |dir|
|
|
358
|
-
raise unless system("
|
|
359
|
-
cd '#{dir}'
|
|
360
|
-
git init --quiet .
|
|
361
|
-
git config user.email yegor256@gmail.com
|
|
362
|
-
git config user.name test
|
|
363
|
-
echo 'hi' > a.txt
|
|
364
|
-
git add a.txt
|
|
365
|
-
git commit --quiet -am 'first version'
|
|
366
|
-
echo '\x40todo #1 this is a puzzle uncommitted' > a.txt
|
|
367
|
-
")
|
|
368
|
-
|
|
369
|
-
stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
|
|
370
|
-
list = source.puzzles
|
|
371
|
-
assert_equal 1, list.size
|
|
372
|
-
puzzle = list.first
|
|
373
|
-
assert_nil puzzle.props[:email]
|
|
374
|
-
assert_equal 'Not Committed Yet', puzzle.props[:author]
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
def test_skips_thymeleaf_close_tag
|
|
380
|
-
Dir.mktmpdir 'test' do |dir|
|
|
381
|
-
file = File.join(dir, 'a.txt')
|
|
382
|
-
File.write(
|
|
383
|
-
file,
|
|
384
|
-
'<!--/* @todo #123 puzzle info */-->'
|
|
385
|
-
)
|
|
386
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
387
|
-
list = source.puzzles
|
|
388
|
-
assert_equal 1, list.size
|
|
389
|
-
puzzle = list.first
|
|
390
|
-
assert_equal '1-1', puzzle.props[:lines]
|
|
391
|
-
assert_equal 'puzzle info', puzzle.props[:body]
|
|
392
|
-
assert_equal '123', puzzle.props[:ticket]
|
|
393
|
-
end
|
|
394
|
-
end
|
|
395
|
-
end
|
|
396
|
-
end
|
data/test/test_source_todo.rb
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2014-2024 Yegor Bugayenko
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the 'Software'), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
# copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
-
# SOFTWARE.
|
|
20
|
-
|
|
21
|
-
require 'minitest/autorun'
|
|
22
|
-
require 'tmpdir'
|
|
23
|
-
require_relative '../lib/pdd'
|
|
24
|
-
require_relative '../lib/pdd/sources'
|
|
25
|
-
require_relative 'test__helper'
|
|
26
|
-
|
|
27
|
-
class TestSourceTodo < Minitest::Test
|
|
28
|
-
def check_valid_puzzle(text, lines, body, ticket, count = 1)
|
|
29
|
-
Dir.mktmpdir 'test' do |dir|
|
|
30
|
-
file = File.join(dir, 'a.txt')
|
|
31
|
-
File.write(file, text)
|
|
32
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
33
|
-
list = source.puzzles
|
|
34
|
-
assert_equal count, list.size
|
|
35
|
-
puzzle = list.first
|
|
36
|
-
assert_equal lines, puzzle.props[:lines]
|
|
37
|
-
assert_equal body, puzzle.props[:body]
|
|
38
|
-
assert_equal ticket, puzzle.props[:ticket]
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def check_invalid_puzzle(text, error_msg)
|
|
44
|
-
Dir.mktmpdir 'test' do |dir|
|
|
45
|
-
file = File.join(dir, 'a.txt')
|
|
46
|
-
File.write(file, text)
|
|
47
|
-
error = assert_raises PDD::Error do
|
|
48
|
-
stub_source_find_github_user(file, 'hey', &:puzzles)
|
|
49
|
-
end
|
|
50
|
-
assert !error.message.index(error_msg).nil?
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def check_missing_puzzle(text)
|
|
55
|
-
Dir.mktmpdir 'test' do |dir|
|
|
56
|
-
file = File.join(dir, 'a.txt')
|
|
57
|
-
File.write(file, text)
|
|
58
|
-
begin
|
|
59
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
60
|
-
list = source.puzzles
|
|
61
|
-
assert_equal 0, list.size
|
|
62
|
-
end
|
|
63
|
-
rescue PDD::Error => e
|
|
64
|
-
assert_nil e, "Error is raised #{e.message}"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def test_todo_parsing
|
|
70
|
-
check_valid_puzzle(
|
|
71
|
-
"
|
|
72
|
-
// @todo #45 task description
|
|
73
|
-
",
|
|
74
|
-
'2-2',
|
|
75
|
-
'task description',
|
|
76
|
-
'45'
|
|
77
|
-
)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def test_todo_parsing_multi_line
|
|
81
|
-
check_valid_puzzle(
|
|
82
|
-
"
|
|
83
|
-
// @todo #45 task description
|
|
84
|
-
// second line
|
|
85
|
-
",
|
|
86
|
-
'2-3',
|
|
87
|
-
'task description second line',
|
|
88
|
-
'45'
|
|
89
|
-
)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def test_todo_utf8_encoded_body
|
|
93
|
-
check_valid_puzzle(
|
|
94
|
-
"
|
|
95
|
-
// TODO #45 Привет, мир, мне кофе
|
|
96
|
-
// вторая линия
|
|
97
|
-
",
|
|
98
|
-
'2-3',
|
|
99
|
-
'Привет, мир, мне кофе вторая линия',
|
|
100
|
-
'45'
|
|
101
|
-
)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def test_todo_colon_parsing
|
|
105
|
-
check_valid_puzzle(
|
|
106
|
-
"
|
|
107
|
-
// TODO: #45 task description
|
|
108
|
-
",
|
|
109
|
-
'2-2',
|
|
110
|
-
'task description',
|
|
111
|
-
'45'
|
|
112
|
-
)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def test_todo_backslash_escape
|
|
116
|
-
check_valid_puzzle(
|
|
117
|
-
"
|
|
118
|
-
// TODO #45 task description with \\
|
|
119
|
-
",
|
|
120
|
-
'2-2',
|
|
121
|
-
'task description with \\',
|
|
122
|
-
'45'
|
|
123
|
-
)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def test_multiple_todo_colon
|
|
127
|
-
check_valid_puzzle(
|
|
128
|
-
"
|
|
129
|
-
// TODO: #45 task description
|
|
130
|
-
// TODO: #46 another task description
|
|
131
|
-
",
|
|
132
|
-
'2-2',
|
|
133
|
-
'task description',
|
|
134
|
-
'45',
|
|
135
|
-
2
|
|
136
|
-
)
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def test_todo_colon_parsing_multi_line
|
|
140
|
-
check_valid_puzzle(
|
|
141
|
-
"
|
|
142
|
-
// TODO: #45 task description
|
|
143
|
-
// second line
|
|
144
|
-
",
|
|
145
|
-
'2-3',
|
|
146
|
-
'task description second line',
|
|
147
|
-
'45'
|
|
148
|
-
)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def test_todo_colon_parsing_multi_line_with_empty_line
|
|
152
|
-
check_valid_puzzle(
|
|
153
|
-
"
|
|
154
|
-
// TODO: #45 task description
|
|
155
|
-
//
|
|
156
|
-
// second line after empty line is not a puzzle text
|
|
157
|
-
",
|
|
158
|
-
'2-2',
|
|
159
|
-
'task description',
|
|
160
|
-
'45'
|
|
161
|
-
)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def test_todo_colon_parsing_multi_line_with_empty_line_and_space
|
|
165
|
-
check_valid_puzzle(
|
|
166
|
-
'
|
|
167
|
-
// TODO: #46 task description
|
|
168
|
-
// \
|
|
169
|
-
// second line after empty line is a part of the puzzle in case of backslash exists
|
|
170
|
-
',
|
|
171
|
-
'2-4',
|
|
172
|
-
'task description second line after empty line is a part ' \
|
|
173
|
-
'of the puzzle in case of backslash exists',
|
|
174
|
-
'46'
|
|
175
|
-
)
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def test_todo_colon_parsing_double_puzzle_with_empty_line
|
|
179
|
-
check_valid_puzzle(
|
|
180
|
-
'
|
|
181
|
-
// TODO: #46 task description for first
|
|
182
|
-
// \
|
|
183
|
-
// TODO: #47 task description
|
|
184
|
-
',
|
|
185
|
-
'2-2',
|
|
186
|
-
'task description for first',
|
|
187
|
-
'46',
|
|
188
|
-
2
|
|
189
|
-
)
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def test_todo_parsing_puzzle_javadoc_with_empty_line
|
|
193
|
-
check_valid_puzzle(
|
|
194
|
-
'
|
|
195
|
-
/**
|
|
196
|
-
* TODO: #46 task description
|
|
197
|
-
* \
|
|
198
|
-
*/
|
|
199
|
-
* some text
|
|
200
|
-
',
|
|
201
|
-
'3-3',
|
|
202
|
-
'task description',
|
|
203
|
-
'46'
|
|
204
|
-
)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def test_todo_parsing_puzzle_last_empty_line
|
|
208
|
-
check_valid_puzzle(
|
|
209
|
-
'
|
|
210
|
-
/**
|
|
211
|
-
* TODO: #47 task description
|
|
212
|
-
* \
|
|
213
|
-
',
|
|
214
|
-
'3-3',
|
|
215
|
-
'task description',
|
|
216
|
-
'47'
|
|
217
|
-
)
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
def test_todo_colon_parsing_multi_line_random_prefix
|
|
221
|
-
check_valid_puzzle(
|
|
222
|
-
'
|
|
223
|
-
~~
|
|
224
|
-
~~ @todo #44 First
|
|
225
|
-
~~ and
|
|
226
|
-
~~ second
|
|
227
|
-
',
|
|
228
|
-
'3-4',
|
|
229
|
-
'First and',
|
|
230
|
-
'44'
|
|
231
|
-
)
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def test_todo_failing_no_ticket
|
|
235
|
-
check_invalid_puzzle(
|
|
236
|
-
"
|
|
237
|
-
* TODO this puzzle misses ticket name/number
|
|
238
|
-
",
|
|
239
|
-
'TODO is not followed by'
|
|
240
|
-
)
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def test_todo_colon_failing_no_ticket
|
|
244
|
-
check_invalid_puzzle(
|
|
245
|
-
"
|
|
246
|
-
* TODO: this puzzle misses ticket name/number
|
|
247
|
-
",
|
|
248
|
-
'TODO is not followed by'
|
|
249
|
-
)
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
def test_todo_failing_space_after_hash
|
|
253
|
-
check_invalid_puzzle(
|
|
254
|
-
"
|
|
255
|
-
* TODO # 45 this puzzle has space after hash
|
|
256
|
-
",
|
|
257
|
-
'TODO found, but there is an unexpected space after the hash sign'
|
|
258
|
-
)
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
def test_todo_colon_failing_space_after_hash
|
|
262
|
-
check_invalid_puzzle(
|
|
263
|
-
"
|
|
264
|
-
* TODO: # 45 this puzzle has space after hash
|
|
265
|
-
",
|
|
266
|
-
'TODO found, but there is an unexpected space after the hash sign'
|
|
267
|
-
)
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
def test_todo_failing_no_space_before
|
|
271
|
-
check_invalid_puzzle(
|
|
272
|
-
"
|
|
273
|
-
*TODO #45 this puzzle has no space before todo
|
|
274
|
-
",
|
|
275
|
-
'TODO must have a leading space'
|
|
276
|
-
)
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
def test_todo_colon_failing_no_space_before
|
|
280
|
-
check_invalid_puzzle(
|
|
281
|
-
"
|
|
282
|
-
*TODO: #45 this puzzle has no space before todo
|
|
283
|
-
",
|
|
284
|
-
'TODO must have a leading space'
|
|
285
|
-
)
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def test_todo_not_puzzle
|
|
289
|
-
check_missing_puzzle(
|
|
290
|
-
"
|
|
291
|
-
TODOS_DIR=$PWD
|
|
292
|
-
"
|
|
293
|
-
)
|
|
294
|
-
end
|
|
295
|
-
end
|