pdd 0.24.1 → 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 +4 -2
- data/Gemfile.lock +75 -54
- data/LICENSE.txt +1 -1
- data/LICENSES/MIT.txt +1 -1
- data/README.md +46 -61
- data/REUSE.toml +0 -2
- data/Rakefile +1 -1
- data/assets/puzzles.xsd +1 -1
- data/assets/puzzles.xsl +1 -1
- data/assets/puzzles_json.xsl +1 -1
- data/bin/pdd +3 -4
- data/cucumber.yml +1 -1
- data/features/applies_rules.feature +1 -1
- data/features/avoiding_duplicates.feature +1 -1
- data/features/catches_broken_puzzles.feature +1 -1
- data/features/cli.feature +1 -1
- data/features/gem_package.feature +1 -1
- data/features/html_output.feature +1 -1
- data/features/json_output.feature +1 -1
- data/features/parsing.feature +1 -1
- data/features/rake.feature +1 -1
- data/features/remove.feature +2 -1
- data/features/step_definitions/steps.rb +1 -1
- data/features/support/env.rb +1 -1
- data/features/unicode.feature +1 -1
- data/features/uses_config.feature +1 -1
- data/lib/pdd/puzzle.rb +1 -1
- data/lib/pdd/rake_task.rb +1 -2
- data/lib/pdd/rule/duplicates.rb +1 -1
- data/lib/pdd/rule/estimates.rb +1 -1
- data/lib/pdd/rule/roles.rb +1 -1
- data/lib/pdd/rule/text.rb +1 -1
- data/lib/pdd/source.rb +1 -1
- data/lib/pdd/sources.rb +1 -1
- data/lib/pdd/version.rb +3 -3
- data/lib/pdd.rb +2 -2
- data/pdd.gemspec +2 -2
- data/utils/glob.rb +1 -1
- metadata +2 -31
- data/.0pdd.yml +0 -12
- data/.gitattributes +0 -12
- data/.github/workflows/actionlint.yml +0 -25
- data/.github/workflows/codecov.yml +0 -29
- data/.github/workflows/copyrights.yml +0 -19
- data/.github/workflows/markdown-lint.yml +0 -19
- data/.github/workflows/pdd.yml +0 -19
- data/.github/workflows/rake.yml +0 -29
- data/.github/workflows/reuse.yml +0 -19
- data/.github/workflows/typos.yml +0 -19
- data/.github/workflows/xcop.yml +0 -19
- data/.github/workflows/yamllint.yml +0 -19
- data/.gitignore +0 -15
- data/.markdownlint.yml +0 -6
- data/.pdd +0 -26
- data/.rubocop.yml +0 -42
- data/.rultor.yml +0 -26
- data/.simplecov +0 -18
- data/test/test__helper.rb +0 -44
- data/test/test_duplicates.rb +0 -31
- data/test/test_estimates.rb +0 -30
- data/test/test_many.rb +0 -25
- data/test/test_pdd.rb +0 -94
- data/test/test_rake_task.rb +0 -21
- data/test/test_roles.rb +0 -39
- data/test/test_source.rb +0 -379
- data/test/test_source_todo.rb +0 -278
- data/test/test_sources.rb +0 -120
- data/test/test_text.rb +0 -22
data/test/test_source_todo.rb
DELETED
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2014-2025 Yegor Bugayenko
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
|
|
4
|
-
require 'minitest/autorun'
|
|
5
|
-
require 'tmpdir'
|
|
6
|
-
require_relative '../lib/pdd'
|
|
7
|
-
require_relative '../lib/pdd/sources'
|
|
8
|
-
require_relative 'test__helper'
|
|
9
|
-
|
|
10
|
-
class TestSourceTodo < Minitest::Test
|
|
11
|
-
def check_valid_puzzle(text, lines, body, ticket, count = 1)
|
|
12
|
-
Dir.mktmpdir 'test' do |dir|
|
|
13
|
-
file = File.join(dir, 'a.txt')
|
|
14
|
-
File.write(file, text)
|
|
15
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
16
|
-
list = source.puzzles
|
|
17
|
-
assert_equal count, list.size
|
|
18
|
-
puzzle = list.first
|
|
19
|
-
assert_equal lines, puzzle.props[:lines]
|
|
20
|
-
assert_equal body, puzzle.props[:body]
|
|
21
|
-
assert_equal ticket, puzzle.props[:ticket]
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def check_invalid_puzzle(text, error_msg)
|
|
27
|
-
Dir.mktmpdir 'test' do |dir|
|
|
28
|
-
file = File.join(dir, 'a.txt')
|
|
29
|
-
File.write(file, text)
|
|
30
|
-
error = assert_raises PDD::Error do
|
|
31
|
-
stub_source_find_github_user(file, 'hey', &:puzzles)
|
|
32
|
-
end
|
|
33
|
-
refute_nil error.message.index(error_msg)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def check_missing_puzzle(text)
|
|
38
|
-
Dir.mktmpdir 'test' do |dir|
|
|
39
|
-
file = File.join(dir, 'a.txt')
|
|
40
|
-
File.write(file, text)
|
|
41
|
-
begin
|
|
42
|
-
stub_source_find_github_user(file, 'hey') do |source|
|
|
43
|
-
list = source.puzzles
|
|
44
|
-
assert_equal 0, list.size
|
|
45
|
-
end
|
|
46
|
-
rescue PDD::Error => e
|
|
47
|
-
assert_nil e, "Error is raised #{e.message}"
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def test_todo_parsing
|
|
53
|
-
check_valid_puzzle(
|
|
54
|
-
"
|
|
55
|
-
// @todo #45 task description
|
|
56
|
-
",
|
|
57
|
-
'2-2',
|
|
58
|
-
'task description',
|
|
59
|
-
'45'
|
|
60
|
-
)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def test_todo_parsing_multi_line
|
|
64
|
-
check_valid_puzzle(
|
|
65
|
-
"
|
|
66
|
-
// @todo #45 task description
|
|
67
|
-
// second line
|
|
68
|
-
",
|
|
69
|
-
'2-3',
|
|
70
|
-
'task description second line',
|
|
71
|
-
'45'
|
|
72
|
-
)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def test_todo_utf8_encoded_body
|
|
76
|
-
check_valid_puzzle(
|
|
77
|
-
"
|
|
78
|
-
// TODO #45 Привет, мир, мне кофе
|
|
79
|
-
// вторая линия
|
|
80
|
-
",
|
|
81
|
-
'2-3',
|
|
82
|
-
'Привет, мир, мне кофе вторая линия',
|
|
83
|
-
'45'
|
|
84
|
-
)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def test_todo_colon_parsing
|
|
88
|
-
check_valid_puzzle(
|
|
89
|
-
"
|
|
90
|
-
// TODO: #45 task description
|
|
91
|
-
",
|
|
92
|
-
'2-2',
|
|
93
|
-
'task description',
|
|
94
|
-
'45'
|
|
95
|
-
)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def test_todo_backslash_escape
|
|
99
|
-
check_valid_puzzle(
|
|
100
|
-
"
|
|
101
|
-
// TODO #45 task description with \\
|
|
102
|
-
",
|
|
103
|
-
'2-2',
|
|
104
|
-
'task description with \\',
|
|
105
|
-
'45'
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def test_multiple_todo_colon
|
|
110
|
-
check_valid_puzzle(
|
|
111
|
-
"
|
|
112
|
-
// TODO: #45 task description
|
|
113
|
-
// TODO: #46 another task description
|
|
114
|
-
",
|
|
115
|
-
'2-2',
|
|
116
|
-
'task description',
|
|
117
|
-
'45',
|
|
118
|
-
2
|
|
119
|
-
)
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def test_todo_colon_parsing_multi_line
|
|
123
|
-
check_valid_puzzle(
|
|
124
|
-
"
|
|
125
|
-
// TODO: #45 task description
|
|
126
|
-
// second line
|
|
127
|
-
",
|
|
128
|
-
'2-3',
|
|
129
|
-
'task description second line',
|
|
130
|
-
'45'
|
|
131
|
-
)
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def test_todo_colon_parsing_multi_line_with_empty_line
|
|
135
|
-
check_valid_puzzle(
|
|
136
|
-
"
|
|
137
|
-
// TODO: #45 task description
|
|
138
|
-
//
|
|
139
|
-
// second line after empty line is not a puzzle text
|
|
140
|
-
",
|
|
141
|
-
'2-2',
|
|
142
|
-
'task description',
|
|
143
|
-
'45'
|
|
144
|
-
)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def test_todo_colon_parsing_multi_line_with_empty_line_and_space
|
|
148
|
-
check_valid_puzzle(
|
|
149
|
-
'
|
|
150
|
-
// TODO: #46 task description
|
|
151
|
-
// \
|
|
152
|
-
// second line after empty line is a part of the puzzle in case of backslash exists
|
|
153
|
-
',
|
|
154
|
-
'2-4',
|
|
155
|
-
'task description second line after empty line is a part ' \
|
|
156
|
-
'of the puzzle in case of backslash exists',
|
|
157
|
-
'46'
|
|
158
|
-
)
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def test_todo_colon_parsing_double_puzzle_with_empty_line
|
|
162
|
-
check_valid_puzzle(
|
|
163
|
-
'
|
|
164
|
-
// TODO: #46 task description for first
|
|
165
|
-
// \
|
|
166
|
-
// TODO: #47 task description
|
|
167
|
-
',
|
|
168
|
-
'2-2',
|
|
169
|
-
'task description for first',
|
|
170
|
-
'46',
|
|
171
|
-
2
|
|
172
|
-
)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def test_todo_parsing_puzzle_javadoc_with_empty_line
|
|
176
|
-
check_valid_puzzle(
|
|
177
|
-
'
|
|
178
|
-
/**
|
|
179
|
-
* TODO: #46 task description
|
|
180
|
-
* \
|
|
181
|
-
*/
|
|
182
|
-
* some text
|
|
183
|
-
',
|
|
184
|
-
'3-3',
|
|
185
|
-
'task description',
|
|
186
|
-
'46'
|
|
187
|
-
)
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def test_todo_parsing_puzzle_last_empty_line
|
|
191
|
-
check_valid_puzzle(
|
|
192
|
-
'
|
|
193
|
-
/**
|
|
194
|
-
* TODO: #47 task description
|
|
195
|
-
* \
|
|
196
|
-
',
|
|
197
|
-
'3-3',
|
|
198
|
-
'task description',
|
|
199
|
-
'47'
|
|
200
|
-
)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def test_todo_colon_parsing_multi_line_random_prefix
|
|
204
|
-
check_valid_puzzle(
|
|
205
|
-
'
|
|
206
|
-
~~
|
|
207
|
-
~~ @todo #44 First
|
|
208
|
-
~~ and
|
|
209
|
-
~~ second
|
|
210
|
-
',
|
|
211
|
-
'3-4',
|
|
212
|
-
'First and',
|
|
213
|
-
'44'
|
|
214
|
-
)
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def test_todo_failing_no_ticket
|
|
218
|
-
check_invalid_puzzle(
|
|
219
|
-
"
|
|
220
|
-
* TODO this puzzle misses ticket name/number
|
|
221
|
-
",
|
|
222
|
-
'TODO is not followed by'
|
|
223
|
-
)
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
def test_todo_colon_failing_no_ticket
|
|
227
|
-
check_invalid_puzzle(
|
|
228
|
-
"
|
|
229
|
-
* TODO: this puzzle misses ticket name/number
|
|
230
|
-
",
|
|
231
|
-
'TODO is not followed by'
|
|
232
|
-
)
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def test_todo_failing_space_after_hash
|
|
236
|
-
check_invalid_puzzle(
|
|
237
|
-
"
|
|
238
|
-
* TODO # 45 this puzzle has space after hash
|
|
239
|
-
",
|
|
240
|
-
'TODO found, but there is an unexpected space after the hash sign'
|
|
241
|
-
)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def test_todo_colon_failing_space_after_hash
|
|
245
|
-
check_invalid_puzzle(
|
|
246
|
-
"
|
|
247
|
-
* TODO: # 45 this puzzle has space after hash
|
|
248
|
-
",
|
|
249
|
-
'TODO found, but there is an unexpected space after the hash sign'
|
|
250
|
-
)
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
def test_todo_failing_no_space_before
|
|
254
|
-
check_invalid_puzzle(
|
|
255
|
-
"
|
|
256
|
-
*TODO #45 this puzzle has no space before todo
|
|
257
|
-
",
|
|
258
|
-
'TODO must have a leading space'
|
|
259
|
-
)
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
def test_todo_colon_failing_no_space_before
|
|
263
|
-
check_invalid_puzzle(
|
|
264
|
-
"
|
|
265
|
-
*TODO: #45 this puzzle has no space before todo
|
|
266
|
-
",
|
|
267
|
-
'TODO must have a leading space'
|
|
268
|
-
)
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def test_todo_not_puzzle
|
|
272
|
-
check_missing_puzzle(
|
|
273
|
-
"
|
|
274
|
-
TODOS_DIR=$PWD
|
|
275
|
-
"
|
|
276
|
-
)
|
|
277
|
-
end
|
|
278
|
-
end
|
data/test/test_sources.rb
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2014-2025 Yegor Bugayenko
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
|
|
4
|
-
require 'minitest/autorun'
|
|
5
|
-
require 'fileutils'
|
|
6
|
-
require 'tmpdir'
|
|
7
|
-
require_relative '../test/test__helper'
|
|
8
|
-
require_relative '../lib/pdd/sources'
|
|
9
|
-
|
|
10
|
-
# Sources test.
|
|
11
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
12
|
-
# Copyright:: Copyright (c) 2014-2025 Yegor Bugayenko
|
|
13
|
-
# License:: MIT
|
|
14
|
-
class TestSources < Minitest::Test
|
|
15
|
-
def test_iterator
|
|
16
|
-
in_temp(['a.txt', 'b/c.txt']) do |dir|
|
|
17
|
-
list = PDD::Sources.new(dir).fetch
|
|
18
|
-
assert_equal 2, list.size
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def test_ignores_binary_files
|
|
23
|
-
in_temp([]) do |dir|
|
|
24
|
-
[
|
|
25
|
-
'README.md',
|
|
26
|
-
'.git/index',
|
|
27
|
-
'test_assets/elegant-objects.png',
|
|
28
|
-
'test_assets/aladdin.jpg',
|
|
29
|
-
'test_assets/article.pdf',
|
|
30
|
-
'test_assets/cambria.woff',
|
|
31
|
-
'test_assets/favicon.ico'
|
|
32
|
-
].each { |f| FileUtils.cp(File.join(Dir.pwd, f), dir) }
|
|
33
|
-
list = PDD::Sources.new(dir).fetch
|
|
34
|
-
assert_equal 1, list.size
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def test_detects_all_text_files
|
|
39
|
-
in_temp([]) do |dir|
|
|
40
|
-
exts = %w[(xsl java rb cpp apt js xml c go h txt)]
|
|
41
|
-
exts.each do |ext|
|
|
42
|
-
File.write(File.join(dir, "test.#{ext}"), 'text')
|
|
43
|
-
end
|
|
44
|
-
list = PDD::Sources.new(dir).fetch
|
|
45
|
-
assert_equal(
|
|
46
|
-
exts.size, list.size,
|
|
47
|
-
"Files found: #{list}"
|
|
48
|
-
)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def test_detects_xml_file
|
|
53
|
-
in_temp(['a.xml']) do |dir|
|
|
54
|
-
File.write(File.join(dir, 'a.xml'), '<?xml version="1.0"?><hello/>')
|
|
55
|
-
list = PDD::Sources.new(dir).fetch
|
|
56
|
-
assert_equal 1, list.size
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def test_detects_js_file
|
|
61
|
-
in_temp(['a.js']) do |dir|
|
|
62
|
-
File.write(File.join(dir, 'a.js'), "#!/usr/bin/env node\nconsole.log('Hi!');")
|
|
63
|
-
list = PDD::Sources.new(dir).fetch
|
|
64
|
-
assert_equal 1, list.size
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def test_excludes_by_pattern
|
|
69
|
-
in_temp(['a/first.txt', 'b/c/d/second.txt']) do |dir|
|
|
70
|
-
list = PDD::Sources.new(dir).exclude('b/c/d/second.txt').fetch
|
|
71
|
-
assert_equal 1, list.size
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def test_excludes_recursively
|
|
76
|
-
in_temp(['a/first.txt', 'b/c/second.txt', 'b/c/d/third.txt']) do |dir|
|
|
77
|
-
list = PDD::Sources.new(dir).exclude('**/*').fetch
|
|
78
|
-
assert_equal 0, list.size
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def test_includes_by_pattern
|
|
83
|
-
in_temp(['a/first.txt', 'b/c/d/second.txt']) do |dir|
|
|
84
|
-
list = PDD::Sources.new(dir).include('b/c/d/second.txt').fetch
|
|
85
|
-
assert_equal 2, list.size
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def test_includes_recursively
|
|
90
|
-
in_temp(['a/first.txt', 'b/c/second.txt', 'b/c/d/third.txt']) do |dir|
|
|
91
|
-
sources = PDD::Sources.new(dir).exclude('b/c/**')
|
|
92
|
-
sources.include('b/c/d/third.txt')
|
|
93
|
-
list = sources.fetch
|
|
94
|
-
assert_equal 2, list.size
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def test_fails_with_verbose_output
|
|
99
|
-
in_temp do |dir|
|
|
100
|
-
File.write(File.join(dir, 'z1.txt'), "\x40todobroken\n")
|
|
101
|
-
error = assert_raises PDD::Error do
|
|
102
|
-
PDD::Sources.new(dir).fetch[0].puzzles
|
|
103
|
-
end
|
|
104
|
-
assert error.message.start_with?('z1.txt; '), "here: #{error.message}"
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
private
|
|
109
|
-
|
|
110
|
-
def in_temp(files = [])
|
|
111
|
-
Dir.mktmpdir 'x' do |dir|
|
|
112
|
-
files.each do |path|
|
|
113
|
-
file = File.join(dir, path)
|
|
114
|
-
FileUtils.mkdir_p(File.dirname(file))
|
|
115
|
-
File.write(file, 'some test content')
|
|
116
|
-
end
|
|
117
|
-
yield dir
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
data/test/test_text.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText: Copyright (c) 2014-2025 Yegor Bugayenko
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
|
|
4
|
-
require 'minitest/autorun'
|
|
5
|
-
require 'nokogiri'
|
|
6
|
-
require_relative '../lib/pdd/rule/text'
|
|
7
|
-
|
|
8
|
-
# PDD::Rule::Text module tests.
|
|
9
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
10
|
-
# Copyright:: Copyright (c) 2014-2025 Yegor Bugayenko
|
|
11
|
-
# License:: MIT
|
|
12
|
-
class TestText < Minitest::Test
|
|
13
|
-
def test_min_words
|
|
14
|
-
rule = PDD::Rule::Text::MinWords.new(
|
|
15
|
-
Nokogiri::XML::Document.parse(
|
|
16
|
-
'<puzzles><puzzle><body>short text</body></puzzle>
|
|
17
|
-
<puzzle><body>body with four words</body></puzzle></puzzles>'
|
|
18
|
-
), 4
|
|
19
|
-
)
|
|
20
|
-
assert_equal 1, rule.errors.size
|
|
21
|
-
end
|
|
22
|
-
end
|