pdd 0.20.4 → 0.20.8
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/.gitignore +5 -4
- data/.overcommit.yml +96 -0
- data/.pdd +15 -1
- data/.rubocop.yml +3 -2
- data/.rultor.yml +14 -15
- data/.simplecov +6 -6
- data/.travis.yml +2 -2
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +72 -67
- data/Rakefile +7 -1
- data/assets/puzzles.xsd +1 -1
- data/assets/puzzles.xsl +1 -1
- data/bin/pdd +30 -19
- data/features/catches_broken_puzzles.feature +1 -16
- data/features/cli.feature +1 -1
- data/features/html_output.feature +1 -1
- data/features/rake.feature +21 -0
- data/features/step_definitions/steps.rb +11 -4
- data/features/support/env.rb +2 -1
- data/features/uses_config.feature +1 -1
- data/lib/pdd/puzzle.rb +1 -1
- data/lib/pdd/rake_task.rb +39 -0
- data/lib/pdd/rule/duplicates.rb +2 -1
- data/lib/pdd/rule/estimates.rb +1 -1
- data/lib/pdd/rule/roles.rb +2 -1
- data/lib/pdd/rule/text.rb +2 -1
- data/lib/pdd/source.rb +59 -47
- data/lib/pdd/sources.rb +34 -13
- data/lib/pdd/version.rb +3 -3
- data/lib/pdd.rb +20 -15
- data/pdd.gemspec +13 -10
- data/test/test__helper.rb +15 -2
- data/test/test_duplicates.rb +2 -2
- data/test/test_estimates.rb +2 -2
- data/test/test_pdd.rb +4 -2
- data/test/test_rake_task.rb +18 -0
- data/test/test_roles.rb +2 -2
- data/test/test_source.rb +154 -47
- data/test/test_source_todo.rb +36 -9
- data/test/test_sources.rb +18 -2
- data/test/test_text.rb +2 -2
- data/utils/glob.rb +67 -0
- metadata +51 -17
data/lib/pdd.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -30,7 +30,7 @@ require_relative 'pdd/rule/roles'
|
|
30
30
|
|
31
31
|
# PDD main module.
|
32
32
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
33
|
-
# Copyright:: Copyright (c) 2014-
|
33
|
+
# Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
|
34
34
|
# License:: MIT
|
35
35
|
module PDD
|
36
36
|
# If it breaks.
|
@@ -52,21 +52,25 @@ module PDD
|
|
52
52
|
# Get logger.
|
53
53
|
def self.log
|
54
54
|
unless defined?(@logger)
|
55
|
-
@logger = Logger.new(
|
55
|
+
@logger = Logger.new($stdout)
|
56
56
|
@logger.formatter = proc { |severity, _, _, msg|
|
57
|
-
|
57
|
+
case severity
|
58
|
+
when 'ERROR'
|
58
59
|
"#{Rainbow(severity).red}: #{msg}\n"
|
60
|
+
when 'WARN'
|
61
|
+
"#{Rainbow(severity).orange}: #{msg}\n"
|
59
62
|
else
|
60
63
|
"#{msg}\n"
|
61
64
|
end
|
62
65
|
}
|
63
|
-
@logger.level = Logger::
|
66
|
+
@logger.level = Logger::WARN
|
64
67
|
end
|
65
68
|
@logger
|
66
69
|
end
|
67
70
|
|
68
71
|
class << self
|
69
72
|
attr_writer :logger
|
73
|
+
attr_accessor :opts
|
70
74
|
end
|
71
75
|
|
72
76
|
# Code base abstraction
|
@@ -75,6 +79,7 @@ module PDD
|
|
75
79
|
# +opts+:: Options
|
76
80
|
def initialize(opts)
|
77
81
|
@opts = opts
|
82
|
+
PDD.opts = opts
|
78
83
|
PDD.log.level = Logger::INFO if @opts[:verbose]
|
79
84
|
PDD.log.level = Logger::ERROR if @opts[:quiet]
|
80
85
|
PDD.log.info "My version is #{PDD::VERSION}"
|
@@ -83,19 +88,15 @@ module PDD
|
|
83
88
|
|
84
89
|
# Generate XML.
|
85
90
|
def xml
|
86
|
-
dir = @opts[:source]
|
87
|
-
PDD.log.info "Reading #{dir}"
|
91
|
+
dir = @opts[:source] || Dir.pwd
|
92
|
+
PDD.log.info "Reading from root dir #{dir}"
|
88
93
|
require_relative 'pdd/sources'
|
89
|
-
sources = Sources.new(dir)
|
90
|
-
|
91
|
-
|
92
|
-
sources = sources.exclude(p)
|
93
|
-
PDD.log.info "Excluding #{p}"
|
94
|
-
end
|
95
|
-
end
|
94
|
+
sources = Sources.new(File.expand_path(dir))
|
95
|
+
sources.exclude((@opts[:exclude] || []) + (@opts['skip-gitignore'] || []))
|
96
|
+
sources.include(@opts[:include])
|
96
97
|
sanitize(
|
97
98
|
rules(
|
98
|
-
Nokogiri::XML::Builder.new do |xml|
|
99
|
+
Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
99
100
|
xml << "<?xml-stylesheet type='text/xsl' href='#{xsl}'?>"
|
100
101
|
xml.puzzles(attrs) do
|
101
102
|
sources.fetch.each do |source|
|
@@ -147,16 +148,19 @@ module PDD
|
|
147
148
|
unless list.select { |r| r.start_with?('max-duplicates:') }.empty?
|
148
149
|
raise PDD::Error, 'You can\'t modify max-duplicates, it\'s always 1'
|
149
150
|
end
|
151
|
+
|
150
152
|
list.push('max-duplicates:1').map do |r|
|
151
153
|
name, value = r.split(':')
|
152
154
|
rule = RULES[name]
|
153
155
|
raise "Rule '#{name}' doesn't exist" if rule.nil?
|
156
|
+
|
154
157
|
rule.new(doc, value).errors.each do |e|
|
155
158
|
PDD.log.error e
|
156
159
|
total += 1
|
157
160
|
end
|
158
161
|
end
|
159
162
|
raise PDD::Error, "#{total} errors, see log above" unless total.zero?
|
163
|
+
|
160
164
|
xml
|
161
165
|
end
|
162
166
|
|
@@ -168,6 +172,7 @@ module PDD
|
|
168
172
|
errors.each { |e| PDD.log.error e }
|
169
173
|
PDD.log.error(xml) unless errors.empty?
|
170
174
|
raise SchemaError, errors.join('; ') unless errors.empty?
|
175
|
+
|
171
176
|
xml
|
172
177
|
end
|
173
178
|
end
|
data/pdd.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -20,17 +20,18 @@
|
|
20
20
|
|
21
21
|
require 'English'
|
22
22
|
|
23
|
-
lib = File.expand_path('
|
23
|
+
lib = File.expand_path('lib', __dir__)
|
24
24
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
25
25
|
require_relative 'lib/pdd/version'
|
26
26
|
|
27
27
|
Gem::Specification.new do |s|
|
28
28
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
29
29
|
if s.respond_to? :required_rubygems_version=
|
30
|
-
s.required_rubygems_version =
|
30
|
+
s.required_rubygems_version =
|
31
|
+
Gem::Requirement.new('>= 0')
|
31
32
|
end
|
32
|
-
s.rubygems_version = '2.
|
33
|
-
s.required_ruby_version = '
|
33
|
+
s.rubygems_version = '2.3'
|
34
|
+
s.required_ruby_version = '~> 2.3'
|
34
35
|
s.name = 'pdd'
|
35
36
|
s.version = PDD::VERSION
|
36
37
|
s.license = 'MIT'
|
@@ -38,16 +39,17 @@ Gem::Specification.new do |s|
|
|
38
39
|
s.description = 'Collects PDD puzzles from a source code base'
|
39
40
|
s.authors = ['Yegor Bugayenko']
|
40
41
|
s.email = 'yegor256@gmail.com'
|
41
|
-
s.homepage = 'http://github.com/
|
42
|
+
s.homepage = 'http://github.com/cqfn/pdd'
|
42
43
|
s.files = `git ls-files`.split($RS)
|
43
44
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
44
45
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
45
46
|
s.rdoc_options = ['--charset=UTF-8']
|
46
47
|
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
47
|
-
s.add_runtime_dependency 'nokogiri', '1.
|
48
|
-
s.add_runtime_dependency 'rainbow', '~>3.0'
|
49
|
-
s.add_runtime_dependency 'slop', '4.6
|
50
|
-
s.add_development_dependency '
|
48
|
+
s.add_runtime_dependency 'nokogiri', '~> 1.10'
|
49
|
+
s.add_runtime_dependency 'rainbow', '~> 3.0'
|
50
|
+
s.add_runtime_dependency 'slop', '~> 4.6'
|
51
|
+
s.add_development_dependency 'aruba', '~> 0.14.1'
|
52
|
+
s.add_development_dependency 'codecov', '0.2.12'
|
51
53
|
s.add_development_dependency 'cucumber', '3.1.0'
|
52
54
|
s.add_development_dependency 'minitest', '5.5.0'
|
53
55
|
s.add_development_dependency 'rake', '12.0.0'
|
@@ -55,5 +57,6 @@ Gem::Specification.new do |s|
|
|
55
57
|
s.add_development_dependency 'rspec-rails', '3.1.0'
|
56
58
|
s.add_development_dependency 'rubocop', '0.52.1'
|
57
59
|
s.add_development_dependency 'rubocop-rspec', '1.15.1'
|
60
|
+
s.add_development_dependency 'slop', '4.9.1'
|
58
61
|
s.add_development_dependency 'xcop', '0.5.8'
|
59
62
|
end
|
data/test/test__helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
19
|
# SOFTWARE.
|
20
20
|
|
21
|
-
|
21
|
+
$stdout.sync = true
|
22
22
|
|
23
23
|
require 'simplecov'
|
24
24
|
SimpleCov.start
|
@@ -29,3 +29,16 @@ end
|
|
29
29
|
|
30
30
|
require 'minitest/autorun'
|
31
31
|
require_relative '../lib/pdd'
|
32
|
+
|
33
|
+
def stub_source_find_github_user(file, path = '')
|
34
|
+
source = PDD::Source.new(file, path)
|
35
|
+
verbose_source = PDD::VerboseSource.new(file, source)
|
36
|
+
fake = proc do |info = {}|
|
37
|
+
email, author = info.values_at(:email, :author)
|
38
|
+
{ 'login' => 'yegor256' } if email == 'yegor256@gmail.com' ||
|
39
|
+
author == 'Yegor Bugayenko'
|
40
|
+
end
|
41
|
+
source.stub :find_github_user, fake do
|
42
|
+
yield verbose_source
|
43
|
+
end
|
44
|
+
end
|
data/test/test_duplicates.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/duplicates'
|
|
24
24
|
|
25
25
|
# PDD::Rule::MaxDuplicates class test.
|
26
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
-
# Copyright:: Copyright (c) 2014-
|
27
|
+
# Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
|
28
28
|
# License:: MIT
|
29
29
|
class TestMaxDuplicates < Minitest::Test
|
30
30
|
def test_max_duplicates
|
data/test/test_estimates.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/estimates'
|
|
24
24
|
|
25
25
|
# PDD::Rule::Estimate module tests.
|
26
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
-
# Copyright:: Copyright (c) 2014-
|
27
|
+
# Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
|
28
28
|
# License:: MIT
|
29
29
|
class TestEstimates < Minitest::Test
|
30
30
|
def test_min
|
data/test/test_pdd.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -26,7 +26,7 @@ require_relative '../lib/pdd'
|
|
26
26
|
|
27
27
|
# PDD main module test.
|
28
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
-
# Copyright:: Copyright (c) 2014-
|
29
|
+
# Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
|
30
30
|
# License:: MIT
|
31
31
|
class TestPDD < Minitest::Test
|
32
32
|
def test_basic
|
@@ -75,6 +75,7 @@ class TestPDD < Minitest::Test
|
|
75
75
|
git add -f .
|
76
76
|
git commit --quiet -am 'first version'
|
77
77
|
")
|
78
|
+
|
78
79
|
matches(
|
79
80
|
Nokogiri::XML(PDD::Base.new(opts).xml),
|
80
81
|
[
|
@@ -95,6 +96,7 @@ class TestPDD < Minitest::Test
|
|
95
96
|
Slop.parse args do |o|
|
96
97
|
o.bool '-v', '--verbose'
|
97
98
|
o.bool '-q', '--quiet'
|
99
|
+
o.bool '--skip-errors'
|
98
100
|
o.string '-s', '--source'
|
99
101
|
o.array '-e', '--exclude'
|
100
102
|
o.array '-r', '--rule'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'rake'
|
4
|
+
require_relative '../lib/pdd/rake_task'
|
5
|
+
|
6
|
+
# Test for RakeTask
|
7
|
+
class TestRakeTask < Minitest::Test
|
8
|
+
def test_basic
|
9
|
+
Dir.mktmpdir 'test' do |dir|
|
10
|
+
file = File.join(dir, 'a.txt')
|
11
|
+
File.write(file, "\x40todo #55 hello!")
|
12
|
+
PDD::RakeTask.new(:pdd1) do |task|
|
13
|
+
task.quiet = true
|
14
|
+
end
|
15
|
+
Rake::Task['pdd1'].invoke
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/test/test_roles.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,7 +24,7 @@ require_relative '../lib/pdd/rule/roles'
|
|
24
24
|
|
25
25
|
# PDD::Rule::Role module tests.
|
26
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
-
# Copyright:: Copyright (c) 2014-
|
27
|
+
# Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
|
28
28
|
# License:: MIT
|
29
29
|
class TestRoles < Minitest::Test
|
30
30
|
def test_incorrect_role
|
data/test/test_source.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -25,7 +25,7 @@ require_relative '../lib/pdd/sources'
|
|
25
25
|
|
26
26
|
# Source test.
|
27
27
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
-
# Copyright:: Copyright (c) 2014-
|
28
|
+
# Copyright:: Copyright (c) 2014-2021 Yegor Bugayenko
|
29
29
|
# License:: MIT
|
30
30
|
class TestSource < Minitest::Test
|
31
31
|
def test_parsing
|
@@ -42,15 +42,39 @@ class TestSource < Minitest::Test
|
|
42
42
|
~~ and it also has to work
|
43
43
|
"
|
44
44
|
)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
45
|
+
stub_source_find_github_user(file, 'hey') do |source|
|
46
|
+
list = source.puzzles
|
47
|
+
assert_equal 2, list.size
|
48
|
+
puzzle = list.first
|
49
|
+
assert_equal '2-3', puzzle.props[:lines]
|
50
|
+
assert_equal 'привет, how are you doing?', puzzle.props[:body]
|
51
|
+
assert_equal '44', puzzle.props[:ticket]
|
52
|
+
assert puzzle.props[:author].nil?
|
53
|
+
assert puzzle.props[:email].nil?
|
54
|
+
assert puzzle.props[:time].nil?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_parsing_leading_spaces
|
60
|
+
Dir.mktmpdir 'test' do |dir|
|
61
|
+
file = File.join(dir, 'a.txt')
|
62
|
+
File.write(
|
63
|
+
file,
|
64
|
+
"
|
65
|
+
* \x40todo #56:30min this is a
|
66
|
+
* multi-line
|
67
|
+
* comment!
|
68
|
+
"
|
69
|
+
)
|
70
|
+
stub_source_find_github_user(file, 'hey') do |source|
|
71
|
+
list = source.puzzles
|
72
|
+
assert_equal 1, list.size
|
73
|
+
puzzle = list.first
|
74
|
+
assert_equal '2-4', puzzle.props[:lines]
|
75
|
+
assert_equal 'this is a multi-line comment!', puzzle.props[:body]
|
76
|
+
assert_equal '56', puzzle.props[:ticket]
|
77
|
+
end
|
54
78
|
end
|
55
79
|
end
|
56
80
|
|
@@ -65,12 +89,58 @@ class TestSource < Minitest::Test
|
|
65
89
|
"
|
66
90
|
)
|
67
91
|
error = assert_raises PDD::Error do
|
68
|
-
|
92
|
+
stub_source_find_github_user(file, 'hey', &:puzzles)
|
69
93
|
end
|
70
94
|
assert !error.message.index('Space expected').nil?
|
71
95
|
end
|
72
96
|
end
|
73
97
|
|
98
|
+
def test_succeed_despite_bad_puzzles
|
99
|
+
Dir.mktmpdir 'test' do |dir|
|
100
|
+
file = File.join(dir, 'a.txt')
|
101
|
+
File.write(
|
102
|
+
file,
|
103
|
+
"
|
104
|
+
* \x40todo #44 this is an incorrectly formatted puzzle,
|
105
|
+
* with a second line without a leading space
|
106
|
+
Another badly formatted puzzle
|
107
|
+
* \x40todo this puzzle misses ticket name/number
|
108
|
+
Something else
|
109
|
+
* \x40todo #123 This puzzle is correctly formatted
|
110
|
+
"
|
111
|
+
)
|
112
|
+
PDD.opts = { 'skip-errors' => true }
|
113
|
+
stub_source_find_github_user(file, 'hey') do |source|
|
114
|
+
list = source.puzzles
|
115
|
+
PDD.opts = nil
|
116
|
+
assert_equal 1, list.size
|
117
|
+
puzzle = list.first
|
118
|
+
assert_equal '7-7', puzzle.props[:lines]
|
119
|
+
assert_equal 'This puzzle is correctly formatted', puzzle.props[:body]
|
120
|
+
assert_equal '123', puzzle.props[:ticket]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_succeed_utf8_encoded_body
|
126
|
+
Dir.mktmpdir 'test' do |dir|
|
127
|
+
file = File.join(dir, 'a.txt')
|
128
|
+
File.write(
|
129
|
+
file,
|
130
|
+
"
|
131
|
+
* \x40todo #44 Привет, мир, мне кофе
|
132
|
+
* вторая линия
|
133
|
+
"
|
134
|
+
)
|
135
|
+
list = PDD::VerboseSource.new(file, PDD::Source.new(file, 'hey')).puzzles
|
136
|
+
assert_equal 1, list.size
|
137
|
+
puzzle = list.first
|
138
|
+
assert_equal '2-3', puzzle.props[:lines]
|
139
|
+
assert_equal 'Привет, мир, мне кофе вторая линия', puzzle.props[:body]
|
140
|
+
assert_equal '44', puzzle.props[:ticket]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
74
144
|
def test_failing_on_incomplete_puzzle
|
75
145
|
Dir.mktmpdir 't5' do |dir|
|
76
146
|
file = File.join(dir, 'ff.txt')
|
@@ -81,7 +151,7 @@ class TestSource < Minitest::Test
|
|
81
151
|
"
|
82
152
|
)
|
83
153
|
error = assert_raises PDD::Error do
|
84
|
-
|
154
|
+
stub_source_find_github_user(file, 'ff', &:puzzles)
|
85
155
|
end
|
86
156
|
assert !error.to_s.index("\x40todo is not followed by").nil?
|
87
157
|
end
|
@@ -90,9 +160,9 @@ class TestSource < Minitest::Test
|
|
90
160
|
def test_failing_on_broken_unicode
|
91
161
|
Dir.mktmpdir 'test' do |dir|
|
92
162
|
file = File.join(dir, 'xx.txt')
|
93
|
-
File.write(file,
|
163
|
+
File.write(file, " * \\x40todo #44 this is a broken unicode: #{0x92.chr}")
|
94
164
|
assert_raises PDD::Error do
|
95
|
-
|
165
|
+
stub_source_find_github_user(file, 'xx', &:puzzles)
|
96
166
|
end
|
97
167
|
end
|
98
168
|
end
|
@@ -107,7 +177,7 @@ class TestSource < Minitest::Test
|
|
107
177
|
"
|
108
178
|
)
|
109
179
|
error = assert_raises PDD::Error do
|
110
|
-
|
180
|
+
stub_source_find_github_user(file, 'hey', &:puzzles)
|
111
181
|
end
|
112
182
|
assert !error.message.index('is not followed by a puzzle marker').nil?
|
113
183
|
end
|
@@ -123,7 +193,7 @@ class TestSource < Minitest::Test
|
|
123
193
|
"
|
124
194
|
)
|
125
195
|
error = assert_raises PDD::Error do
|
126
|
-
|
196
|
+
stub_source_find_github_user(file, 'x', &:puzzles)
|
127
197
|
end
|
128
198
|
assert !error.message.index("\x40todo must have a leading space").nil?
|
129
199
|
end
|
@@ -139,7 +209,7 @@ class TestSource < Minitest::Test
|
|
139
209
|
"
|
140
210
|
)
|
141
211
|
error = assert_raises PDD::Error do
|
142
|
-
|
212
|
+
stub_source_find_github_user(file, 'x', &:puzzles)
|
143
213
|
end
|
144
214
|
assert !error.message.index('an unexpected space').nil?
|
145
215
|
end
|
@@ -153,20 +223,24 @@ class TestSource < Minitest::Test
|
|
153
223
|
cd '#{dir}'
|
154
224
|
git init --quiet .
|
155
225
|
git config user.email test@teamed.io
|
156
|
-
git config user.name
|
226
|
+
git config user.name test_unknown
|
157
227
|
echo '\x40todo #1 this is the puzzle' > a.txt
|
158
228
|
git add a.txt
|
159
229
|
git commit --quiet -am 'first version'
|
160
230
|
")
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
231
|
+
|
232
|
+
stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
|
233
|
+
list = source.puzzles
|
234
|
+
assert_equal 1, list.size
|
235
|
+
puzzle = list.first
|
236
|
+
assert_equal '1-de87adc8', puzzle.props[:id]
|
237
|
+
assert_equal '1-1', puzzle.props[:lines]
|
238
|
+
assert_equal 'this is the puzzle', puzzle.props[:body]
|
239
|
+
assert_equal 'test_unknown', puzzle.props[:author]
|
240
|
+
assert_equal 'test@teamed.io', puzzle.props[:email]
|
241
|
+
assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/,
|
242
|
+
puzzle.props[:time])
|
243
|
+
end
|
170
244
|
end
|
171
245
|
end
|
172
246
|
|
@@ -183,15 +257,19 @@ class TestSource < Minitest::Test
|
|
183
257
|
git add a.txt
|
184
258
|
git commit --quiet -am 'first version'
|
185
259
|
")
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
260
|
+
|
261
|
+
stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
|
262
|
+
list = source.puzzles
|
263
|
+
assert_equal 1, list.size
|
264
|
+
puzzle = list.first
|
265
|
+
assert_equal '1-de87adc8', puzzle.props[:id]
|
266
|
+
assert_equal '1-1', puzzle.props[:lines]
|
267
|
+
assert_equal 'this is the puzzle', puzzle.props[:body]
|
268
|
+
assert_equal 'test', puzzle.props[:author]
|
269
|
+
assert_nil puzzle.props[:email]
|
270
|
+
assert_match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/,
|
271
|
+
puzzle.props[:time])
|
272
|
+
end
|
195
273
|
end
|
196
274
|
end
|
197
275
|
|
@@ -207,10 +285,37 @@ class TestSource < Minitest::Test
|
|
207
285
|
git add a.txt
|
208
286
|
git commit --quiet -am 'first version'
|
209
287
|
")
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
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 '@yegor256', puzzle.props[:author]
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_skips_uncommitted_changes
|
299
|
+
skip if Gem.win_platform?
|
300
|
+
Dir.mktmpdir 'test' do |dir|
|
301
|
+
raise unless system("
|
302
|
+
cd '#{dir}'
|
303
|
+
git init --quiet .
|
304
|
+
git config user.email yegor256@gmail.com
|
305
|
+
git config user.name test
|
306
|
+
echo 'hi' > a.txt
|
307
|
+
git add a.txt
|
308
|
+
git commit --quiet -am 'first version'
|
309
|
+
echo '\x40todo #1 this is a puzzle uncommitted' > a.txt
|
310
|
+
")
|
311
|
+
|
312
|
+
stub_source_find_github_user(File.join(dir, 'a.txt')) do |source|
|
313
|
+
list = source.puzzles
|
314
|
+
assert_equal 1, list.size
|
315
|
+
puzzle = list.first
|
316
|
+
assert_nil puzzle.props[:email]
|
317
|
+
assert_equal 'Not Committed Yet', puzzle.props[:author]
|
318
|
+
end
|
214
319
|
end
|
215
320
|
end
|
216
321
|
|
@@ -221,12 +326,14 @@ class TestSource < Minitest::Test
|
|
221
326
|
file,
|
222
327
|
'<!--/* @todo #123 puzzle info */-->'
|
223
328
|
)
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
329
|
+
stub_source_find_github_user(file, 'hey') do |source|
|
330
|
+
list = source.puzzles
|
331
|
+
assert_equal 1, list.size
|
332
|
+
puzzle = list.first
|
333
|
+
assert_equal '1-1', puzzle.props[:lines]
|
334
|
+
assert_equal 'puzzle info', puzzle.props[:body]
|
335
|
+
assert_equal '123', puzzle.props[:ticket]
|
336
|
+
end
|
230
337
|
end
|
231
338
|
end
|
232
339
|
end
|
data/test/test_source_todo.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014-
|
1
|
+
# Copyright (c) 2014-2021 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,16 +24,18 @@ require_relative '../lib/pdd'
|
|
24
24
|
require_relative '../lib/pdd/sources'
|
25
25
|
|
26
26
|
class TestSourceTodo < Minitest::Test
|
27
|
-
def check_valid_puzzle(text, lines, body, ticket)
|
27
|
+
def check_valid_puzzle(text, lines, body, ticket, count = 1)
|
28
28
|
Dir.mktmpdir 'test' do |dir|
|
29
29
|
file = File.join(dir, 'a.txt')
|
30
30
|
File.write(file, text)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
stub_source_find_github_user(file, 'hey') do |source|
|
32
|
+
list = source.puzzles
|
33
|
+
assert_equal count, list.size
|
34
|
+
puzzle = list.first
|
35
|
+
assert_equal lines, puzzle.props[:lines]
|
36
|
+
assert_equal body, puzzle.props[:body]
|
37
|
+
assert_equal ticket, puzzle.props[:ticket]
|
38
|
+
end
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
@@ -42,7 +44,7 @@ class TestSourceTodo < Minitest::Test
|
|
42
44
|
file = File.join(dir, 'a.txt')
|
43
45
|
File.write(file, text)
|
44
46
|
error = assert_raises PDD::Error do
|
45
|
-
|
47
|
+
stub_source_find_github_user(file, 'hey', &:puzzles)
|
46
48
|
end
|
47
49
|
assert !error.message.index(error_msg).nil?
|
48
50
|
end
|
@@ -71,6 +73,18 @@ class TestSourceTodo < Minitest::Test
|
|
71
73
|
)
|
72
74
|
end
|
73
75
|
|
76
|
+
def test_todo_utf8_encoded_body
|
77
|
+
check_valid_puzzle(
|
78
|
+
"
|
79
|
+
// TODO #45 Привет, мир, мне кофе
|
80
|
+
// вторая линия
|
81
|
+
",
|
82
|
+
'2-3',
|
83
|
+
'Привет, мир, мне кофе вторая линия',
|
84
|
+
'45'
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
74
88
|
def test_todo_colon_parsing
|
75
89
|
check_valid_puzzle(
|
76
90
|
"
|
@@ -82,6 +96,19 @@ class TestSourceTodo < Minitest::Test
|
|
82
96
|
)
|
83
97
|
end
|
84
98
|
|
99
|
+
def test_multiple_todo_colon
|
100
|
+
check_valid_puzzle(
|
101
|
+
"
|
102
|
+
// TODO: #45 task description
|
103
|
+
// TODO: #46 another task description
|
104
|
+
",
|
105
|
+
'2-2',
|
106
|
+
'task description',
|
107
|
+
'45',
|
108
|
+
2
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
85
112
|
def test_todo_colon_parsing_multi_line
|
86
113
|
check_valid_puzzle(
|
87
114
|
"
|