pdd 0.9 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 invalid estimate
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 invalid estimate
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"
@@ -15,4 +15,4 @@ Feature: Avoiding Duplicate Puzzles
15
15
  }
16
16
  }
17
17
  """
18
- When I run pdd it fails with "Duplicate key-sequence"
18
+ When I run pdd it fails with "errors, see log above"
data/features/cli.feature CHANGED
@@ -39,6 +39,7 @@ Feature: Command Line Processing
39
39
  """
40
40
  When I run bin/pdd with "> out.xml"
41
41
  Then Exit code is zero
42
+ And Stdout is empty
42
43
  And XML file "out.xml" matches "/puzzles[count(puzzle)=1]"
43
44
 
44
45
  Scenario: Excluding unnecessary files
@@ -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} 2>&1`
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))
@@ -23,5 +23,3 @@
23
23
 
24
24
  require 'simplecov'
25
25
  require 'pdd'
26
-
27
- PDD.log = Logger.new(STDOUT)
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 @log
54
- @log = Logger.new(STDOUT)
55
- @log.formatter = proc { |severity, _, _, msg|
56
- puts "#{severity}: #{msg.dump}"
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
- @log
62
+ @logger
60
63
  end
61
64
 
62
65
  class << self
63
- attr_writer :log
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.new(File::NULL) unless @opts.verbose?
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
- rules(
86
- sanitize(
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 unless @opts[:rule].nil?
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
@@ -26,5 +26,5 @@
26
26
  # Copyright:: Copyright (c) 2014 Yegor Bugayenko
27
27
  # License:: MIT
28
28
  module PDD
29
- VERSION = '0.9'
29
+ VERSION = '0.10'
30
30
  end
@@ -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::Document.parse(PDD::Base.new(opts).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 RuntimeError do
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.9'
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-04 00:00:00.000000000 Z
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