pdd 0.9 → 0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/features/applies_rules.feature +11 -2
- data/features/avoiding_duplicates.feature +1 -1
- data/features/cli.feature +1 -0
- data/features/step_definitions/steps.rb +5 -1
- data/features/support/env.rb +0 -2
- data/lib/pdd.rb +16 -14
- data/lib/pdd/rule/duplicates.rb +49 -0
- data/lib/pdd/version.rb +1 -1
- data/test/test_duplicates.rb +51 -0
- data/test/test_pdd.rb +2 -2
- metadata +5 -2
@@ -2,7 +2,7 @@ Feature: Applies Post-Parsing Rules
|
|
2
2
|
As a source code writer I want to be sure that
|
3
3
|
certain post-parsing rules are applied
|
4
4
|
|
5
|
-
Scenario: Throwing exception on
|
5
|
+
Scenario: Throwing exception on big estimates
|
6
6
|
Given I have a "Sample.java" file with content:
|
7
7
|
"""
|
8
8
|
@todo #13:180m This puzzle has too big estimate
|
@@ -11,7 +11,7 @@ Feature: Applies Post-Parsing Rules
|
|
11
11
|
Then Exit code is not zero
|
12
12
|
Then Stdout contains "bigger than 90 minutes"
|
13
13
|
|
14
|
-
Scenario: Throwing exception on
|
14
|
+
Scenario: Throwing exception on small estimates
|
15
15
|
Given I have a "Sample.java" file with content:
|
16
16
|
"""
|
17
17
|
@todo #13:15min This puzzle has too small estimate
|
@@ -20,3 +20,12 @@ Feature: Applies Post-Parsing Rules
|
|
20
20
|
Then Exit code is not zero
|
21
21
|
Then Stdout contains "lower than 30 minutes"
|
22
22
|
|
23
|
+
Scenario: Throwing exception on duplicates
|
24
|
+
Given I have a "Sample.java" file with content:
|
25
|
+
"""
|
26
|
+
@todo #13:15min The text
|
27
|
+
@todo #13:15min The text
|
28
|
+
"""
|
29
|
+
When I run bin/pdd with ""
|
30
|
+
Then Exit code is not zero
|
31
|
+
Then Stdout contains "there are 2 duplicate"
|
data/features/cli.feature
CHANGED
@@ -72,7 +72,7 @@ end
|
|
72
72
|
|
73
73
|
When(/^I run bin\/pdd with "([^"]*)"$/) do |arg|
|
74
74
|
home = File.join(File.dirname(__FILE__), '../..')
|
75
|
-
@stdout = `ruby -I#{home}/lib #{home}/bin/pdd #{arg}
|
75
|
+
@stdout = `ruby -I#{home}/lib #{home}/bin/pdd #{arg}`
|
76
76
|
@exitstatus = $CHILD_STATUS.exitstatus
|
77
77
|
end
|
78
78
|
|
@@ -82,6 +82,10 @@ Then(/^Stdout contains "([^"]*)"$/) do |txt|
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
Then(/^Stdout is empty$/) do
|
86
|
+
fail "STDOUT is not empty:\n#{@stdout}" unless @stdout == ''
|
87
|
+
end
|
88
|
+
|
85
89
|
Then(/^XML file "([^"]+)" matches "([^"]+)"$/) do |file, xpath|
|
86
90
|
fail "File #{file} doesn't exit" unless File.exist?(file)
|
87
91
|
xml = Nokogiri::XML.parse(File.read(file))
|
data/features/support/env.rb
CHANGED
data/lib/pdd.rb
CHANGED
@@ -25,6 +25,7 @@ require 'pdd/sources'
|
|
25
25
|
require 'pdd/version'
|
26
26
|
require 'pdd/rule/estimates'
|
27
27
|
require 'pdd/rule/text'
|
28
|
+
require 'pdd/rule/duplicates'
|
28
29
|
require 'nokogiri'
|
29
30
|
require 'logger'
|
30
31
|
require 'time'
|
@@ -45,22 +46,24 @@ module PDD
|
|
45
46
|
RULES = {
|
46
47
|
'min-estimate' => PDD::Rule::Estimate::Min,
|
47
48
|
'max-estimate' => PDD::Rule::Estimate::Max,
|
48
|
-
'min-words' => PDD::Rule::Text::MinWords
|
49
|
+
'min-words' => PDD::Rule::Text::MinWords,
|
50
|
+
'max-duplicates' => PDD::Rule::MaxDuplicates
|
49
51
|
}
|
50
52
|
|
51
53
|
# Get logger.
|
52
54
|
def self.log
|
53
|
-
unless @
|
54
|
-
@
|
55
|
-
@
|
56
|
-
|
55
|
+
unless @logger
|
56
|
+
@logger = Logger.new(STDOUT)
|
57
|
+
@logger.formatter = proc { |severity, _, _, msg|
|
58
|
+
"#{severity}: #{msg.dump}\n"
|
57
59
|
}
|
60
|
+
@logger.level = Logger::ERROR
|
58
61
|
end
|
59
|
-
@
|
62
|
+
@logger
|
60
63
|
end
|
61
64
|
|
62
65
|
class << self
|
63
|
-
attr_writer :
|
66
|
+
attr_writer :logger
|
64
67
|
end
|
65
68
|
|
66
69
|
# Code base abstraction
|
@@ -69,7 +72,7 @@ module PDD
|
|
69
72
|
# +opts+:: Options
|
70
73
|
def initialize(opts)
|
71
74
|
@opts = opts
|
72
|
-
PDD.log = Logger
|
75
|
+
PDD.log.level = Logger::INFO if @opts.verbose?
|
73
76
|
PDD.log.info "my version is #{PDD::VERSION}"
|
74
77
|
end
|
75
78
|
|
@@ -82,8 +85,8 @@ module PDD
|
|
82
85
|
sources = sources.exclude(p)
|
83
86
|
PDD.log.info "excluding #{p}"
|
84
87
|
end unless @opts[:exclude].nil?
|
85
|
-
|
86
|
-
|
88
|
+
sanitize(
|
89
|
+
rules(
|
87
90
|
Nokogiri::XML::Builder.new do |xml|
|
88
91
|
xml << "<?xml-stylesheet type='text/xsl' href='#{xsl}'?>"
|
89
92
|
xml.puzzles(attrs) do
|
@@ -132,17 +135,16 @@ module PDD
|
|
132
135
|
def rules(xml)
|
133
136
|
doc = Nokogiri::XML(xml)
|
134
137
|
total = 0
|
135
|
-
@opts[:rule].map do |r|
|
138
|
+
(@opts[:rule] || []).push('max-duplicates:1').map do |r|
|
136
139
|
name, value = r.split(':')
|
137
140
|
rule = RULES[name]
|
138
141
|
fail "rule '#{name}' doesn't exist" if rule.nil?
|
139
142
|
rule.new(doc, value.to_i).errors.each do |e|
|
140
|
-
puts e
|
141
143
|
PDD.log.error e
|
142
144
|
total += 1
|
143
145
|
end
|
144
|
-
end
|
145
|
-
fail "#{total} errors, see log above" unless total == 0
|
146
|
+
end
|
147
|
+
fail PDD::Error, "#{total} errors, see log above" unless total == 0
|
146
148
|
xml
|
147
149
|
end
|
148
150
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2014 TechnoPark Corp.
|
4
|
+
# Copyright (c) 2014 Yegor Bugayenko
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
module PDD
|
25
|
+
module Rule
|
26
|
+
# Rule for max duplicates.
|
27
|
+
class MaxDuplicates
|
28
|
+
# Ctor.
|
29
|
+
# +xml+:: XML with puzzles
|
30
|
+
def initialize(xml, max)
|
31
|
+
@xml = xml
|
32
|
+
@max = max
|
33
|
+
end
|
34
|
+
|
35
|
+
def errors
|
36
|
+
@xml.xpath('//puzzle')
|
37
|
+
.group_by { |p| p.xpath('body/text()').to_s }
|
38
|
+
.map do |_, puzzles|
|
39
|
+
next nil if puzzles.count <= @max
|
40
|
+
"there are #{puzzles.count} duplicate(s) of the same puzzle: " +
|
41
|
+
puzzles.map do |p|
|
42
|
+
"#{p.xpath('file/text()')}:#{p.xpath('lines/text()')}"
|
43
|
+
end.join(', ') +
|
44
|
+
", while maximum #{@max} duplicate is allowed"
|
45
|
+
end.compact
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/pdd/version.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2014 TechnoPark Corp.
|
4
|
+
# Copyright (c) 2014 Yegor Bugayenko
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
require 'minitest/autorun'
|
25
|
+
require 'nokogiri'
|
26
|
+
require 'pdd/rule/duplicates'
|
27
|
+
|
28
|
+
# PDD::Rule::MaxDuplicates class test.
|
29
|
+
# Author:: Yegor Bugayenko (yegor@teamed.io)
|
30
|
+
# Copyright:: Copyright (c) 2014 Yegor Bugayenko
|
31
|
+
# License:: MIT
|
32
|
+
class TestMaxDuplicates < Minitest::Test
|
33
|
+
def test_max_duplicates
|
34
|
+
rule = PDD::Rule::MaxDuplicates.new(
|
35
|
+
Nokogiri::XML::Document.parse(
|
36
|
+
'<puzzles><puzzle><body>test</body></puzzle>
|
37
|
+
<puzzle><body>test</body></puzzle></puzzles>'
|
38
|
+
), 1
|
39
|
+
)
|
40
|
+
assert !rule.errors.empty?, 'why it is empty?'
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_max_duplicates_without_errors
|
44
|
+
rule = PDD::Rule::MaxDuplicates.new(
|
45
|
+
Nokogiri::XML::Document.parse(
|
46
|
+
'<puzzles><puzzle><body>hello</body></puzzle></puzzles>'
|
47
|
+
), 1
|
48
|
+
)
|
49
|
+
assert rule.errors.empty?, 'it has to be empty!'
|
50
|
+
end
|
51
|
+
end
|
data/test/test_pdd.rb
CHANGED
@@ -37,7 +37,7 @@ class TestPDD < Minitest::Test
|
|
37
37
|
opts = opts(['-v', '-s', dir, '-e', '**/*.png', '-r', 'max-estimate:15'])
|
38
38
|
File.write(File.join(dir, 'a.txt'), '@todo #55 hello!')
|
39
39
|
matches(
|
40
|
-
Nokogiri::XML
|
40
|
+
Nokogiri::XML(PDD::Base.new(opts).xml),
|
41
41
|
[
|
42
42
|
'/processing-instruction("xml-stylesheet")[contains(.,".xsl")]',
|
43
43
|
'/puzzles/@version',
|
@@ -53,7 +53,7 @@ class TestPDD < Minitest::Test
|
|
53
53
|
Dir.mktmpdir 'test' do |dir|
|
54
54
|
opts = opts(['-v', '-s', dir, '-e', '**/*.png', '-r', 'min-estimate:30'])
|
55
55
|
File.write(File.join(dir, 'a.txt'), '@todo #90 hello!')
|
56
|
-
assert_raises
|
56
|
+
assert_raises PDD::Error do
|
57
57
|
PDD::Base.new(opts).xml
|
58
58
|
end
|
59
59
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pdd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.10'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-12-
|
12
|
+
date: 2014-12-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -222,6 +222,7 @@ files:
|
|
222
222
|
- features/unicode.feature
|
223
223
|
- lib/pdd.rb
|
224
224
|
- lib/pdd/puzzle.rb
|
225
|
+
- lib/pdd/rule/duplicates.rb
|
225
226
|
- lib/pdd/rule/estimates.rb
|
226
227
|
- lib/pdd/rule/text.rb
|
227
228
|
- lib/pdd/source.rb
|
@@ -229,6 +230,7 @@ files:
|
|
229
230
|
- lib/pdd/version.rb
|
230
231
|
- pdd.gemspec
|
231
232
|
- test/test__helper.rb
|
233
|
+
- test/test_duplicates.rb
|
232
234
|
- test/test_estimates.rb
|
233
235
|
- test/test_pdd.rb
|
234
236
|
- test/test_source.rb
|
@@ -272,6 +274,7 @@ test_files:
|
|
272
274
|
- features/support/env.rb
|
273
275
|
- features/unicode.feature
|
274
276
|
- test/test__helper.rb
|
277
|
+
- test/test_duplicates.rb
|
275
278
|
- test/test_estimates.rb
|
276
279
|
- test/test_pdd.rb
|
277
280
|
- test/test_source.rb
|